Changeset 3085 in subversion
- Timestamp:
- Nov 2, 2009 2:41:21 AM (4 years ago)
- Location:
- trunk/roundcubemail
- Files:
-
- 3 added
- 13 deleted
- 29 edited
-
CHANGELOG (modified) (1 diff)
-
plugins/managesieve/Changelog (modified) (1 diff)
-
plugins/managesieve/config.inc.php.dist (modified) (1 diff)
-
plugins/managesieve/lib/Net/Sieve.php (modified) (17 diffs)
-
plugins/managesieve/lib/rcube_sieve.php (modified) (3 diffs)
-
plugins/managesieve/localization/bg_BG.inc (modified) (1 diff)
-
plugins/managesieve/localization/cs_CZ.inc (modified) (1 diff)
-
plugins/managesieve/localization/de_CH.inc (modified) (1 diff)
-
plugins/managesieve/localization/de_DE.inc (modified) (1 diff)
-
plugins/managesieve/localization/en_GB.inc (modified) (1 diff)
-
plugins/managesieve/localization/en_US.inc (modified) (2 diffs)
-
plugins/managesieve/localization/es_ES.inc (modified) (1 diff)
-
plugins/managesieve/localization/et_EE.inc (modified) (1 diff)
-
plugins/managesieve/localization/fi_FI.inc (modified) (1 diff)
-
plugins/managesieve/localization/fr_FR.inc (modified) (1 diff)
-
plugins/managesieve/localization/hu_HU.inc (modified) (1 diff)
-
plugins/managesieve/localization/it_IT.inc (modified) (1 diff)
-
plugins/managesieve/localization/nl_NL.inc (modified) (1 diff)
-
plugins/managesieve/localization/pl_PL.inc (modified) (3 diffs)
-
plugins/managesieve/localization/pt_BR.inc (modified) (1 diff)
-
plugins/managesieve/localization/ru_RU.inc (modified) (2 diffs)
-
plugins/managesieve/localization/sl_SI.inc (modified) (1 diff)
-
plugins/managesieve/localization/sv_SE.inc (modified) (1 diff)
-
plugins/managesieve/localization/uk_UA.inc (modified) (1 diff)
-
plugins/managesieve/localization/zh_CN.inc (modified) (1 diff)
-
plugins/managesieve/managesieve.js (modified) (5 diffs)
-
plugins/managesieve/managesieve.php (modified) (15 diffs)
-
plugins/managesieve/skins/default/filter_add_act.png (deleted)
-
plugins/managesieve/skins/default/filter_add_pas.png (deleted)
-
plugins/managesieve/skins/default/filter_add_sel.png (deleted)
-
plugins/managesieve/skins/default/filter_del_act.png (deleted)
-
plugins/managesieve/skins/default/filter_del_pas.png (deleted)
-
plugins/managesieve/skins/default/filter_del_sel.png (deleted)
-
plugins/managesieve/skins/default/filter_down_act.png (deleted)
-
plugins/managesieve/skins/default/filter_down_pas.png (deleted)
-
plugins/managesieve/skins/default/filter_down_sel.png (deleted)
-
plugins/managesieve/skins/default/filter_up_act.png (deleted)
-
plugins/managesieve/skins/default/filter_up_pas.png (deleted)
-
plugins/managesieve/skins/default/filter_up_sel.png (deleted)
-
plugins/managesieve/skins/default/managesieve.css (modified) (4 diffs)
-
plugins/managesieve/skins/default/managesieve_toolbar.png (added)
-
plugins/managesieve/skins/default/templates/filteredit.html (added)
-
plugins/managesieve/skins/default/templates/managesieve.html (modified) (1 diff)
-
plugins/managesieve/skins/default/templates/managesieveedit.html (deleted)
-
plugins/managesieve/skins/default/templates/setedit.html (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/roundcubemail/CHANGELOG
r3084 r3085 2 2 =========================== 3 3 4 - Managesieve 2.0: multi-script support 4 5 - Fix imap_auth_type regression (#1486263) 5 6 -
trunk/roundcubemail/plugins/managesieve/Changelog
r2970 r3085 1 * version 2.0 [2009-11-02] 2 ----------------------------------------------------------- 3 - Added 'managesieve_debug' option 4 - Added multi-script support 5 - Small css improvements + sprite image buttons 6 - PEAR::NetSieve 1.2.0b1 7 1 8 * version 1.7 [2009-09-20] 2 9 ----------------------------------------------------------- -
trunk/roundcubemail/plugins/managesieve/config.inc.php.dist
r2963 r3085 32 32 $rcmail_config['managesieve_disabled_extensions'] = array(); 33 33 34 // Enables debugging of conversation with sieve server. Logs it into <log_dir>/sieve 35 $rcmail_config['managesieve_debug'] = false; 36 34 37 ?> -
trunk/roundcubemail/plugins/managesieve/lib/Net/Sieve.php
r2807 r3085 1 1 <?php 2 // +-----------------------------------------------------------------------+3 // | Copyright (c) 2002-2003, Richard Heyes |4 // | Copyright (c) 2006,2008 Anish Mistry |5 // | All rights reserved. |6 // | |7 // | Redistribution and use in source and binary forms, with or without |8 // | modification, are permitted provided that the following conditions |9 // | are met: |10 // | |11 // | o Redistributions of source code must retain the above copyright |12 // | notice, this list of conditions and the following disclaimer. |13 // | o Redistributions in binary form must reproduce the above copyright |14 // | notice, this list of conditions and the following disclaimer in the |15 // | documentation and/or other materials provided with the distribution.|16 // | o The names of the authors may not be used to endorse or promote |17 // | products derived from this software without specific prior written |18 // | permission. |19 // | |20 // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |21 // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |22 // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |23 // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |24 // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |25 // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |26 // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |27 // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |28 // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |29 // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |30 // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |31 // | |32 // +-----------------------------------------------------------------------+33 // | Author: Richard Heyes <richard@phpguru.org> |34 // | Co-Author: Damian Fernandez Sosa <damlists@cnba.uba.ar> |35 // | Co-Author: Anish Mistry <amistry@am-productions.biz> |36 // +-----------------------------------------------------------------------+37 38 require_once('Net/Socket.php');39 40 2 /** 41 * TODO 42 * 43 * o supportsAuthMech() 44 */ 3 * This file contains the Net_Sieve class. 4 * 5 * PHP version 4 6 * 7 * +-----------------------------------------------------------------------+ 8 * | All rights reserved. | 9 * | | 10 * | Redistribution and use in source and binary forms, with or without | 11 * | modification, are permitted provided that the following conditions | 12 * | are met: | 13 * | | 14 * | o Redistributions of source code must retain the above copyright | 15 * | notice, this list of conditions and the following disclaimer. | 16 * | o Redistributions in binary form must reproduce the above copyright | 17 * | notice, this list of conditions and the following disclaimer in the | 18 * | documentation and/or other materials provided with the distribution.| 19 * | | 20 * | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 21 * | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 22 * | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 23 * | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 24 * | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 25 * | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 26 * | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 27 * | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 28 * | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 29 * | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 30 * | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 31 * +-----------------------------------------------------------------------+ 32 * 33 * @category Networking 34 * @package Net_Sieve 35 * @author Richard Heyes <richard@phpguru.org> 36 * @author Damian Fernandez Sosa <damlists@cnba.uba.ar> 37 * @author Anish Mistry <amistry@am-productions.biz> 38 * @author Jan Schneider <jan@horde.org> 39 * @copyright 2002-2003 Richard Heyes 40 * @copyright 2006-2008 Anish Mistry 41 * @license http://www.opensource.org/licenses/bsd-license.php BSD 42 * @version SVN: $Id: Sieve.php 289313 2009-10-07 22:26:33Z yunosh $ 43 * @link http://pear.php.net/package/Net_Sieve 44 */ 45 46 require_once 'PEAR.php'; 47 require_once 'Net/Socket.php'; 45 48 46 49 /** 47 * Disconnected state 48 * @const NET_SIEVE_STATE_DISCONNECTED 49 */ 50 define('NET_SIEVE_STATE_DISCONNECTED', 1, true); 50 * TODO 51 * 52 * o supportsAuthMech() 53 */ 51 54 52 55 /** 53 * Authorisation state 54 * @const NET_SIEVE_STATE_AUTHORISATION 55 */ 56 * Disconnected state 57 * @const NET_SIEVE_STATE_DISCONNECTED 58 */ 59 define('NET_SIEVE_STATE_DISCONNECTED', 1, true); 60 61 /** 62 * Authorisation state 63 * @const NET_SIEVE_STATE_AUTHORISATION 64 */ 56 65 define('NET_SIEVE_STATE_AUTHORISATION', 2, true); 57 66 58 67 /** 59 * Transaction state 60 * @const NET_SIEVE_STATE_TRANSACTION 61 */ 62 define('NET_SIEVE_STATE_TRANSACTION', 3, true); 68 * Transaction state 69 * @const NET_SIEVE_STATE_TRANSACTION 70 */ 71 define('NET_SIEVE_STATE_TRANSACTION', 3, true); 72 63 73 64 74 /** 65 * A class for talking to the timsieved server which 66 * comes with Cyrus IMAP. 67 * 68 * SIEVE: RFC3028 http://www.ietf.org/rfc/rfc3028.txt 69 * MANAGE-SIEVE: http://www.ietf.org/internet-drafts/draft-martin-managesieve-07.txt 70 * 71 * @author Richard Heyes <richard@php.net> 72 * @author Damian Fernandez Sosa <damlists@cnba.uba.ar> 73 * @author Anish Mistry <amistry@am-productions.biz> 74 * @access public 75 * @version 1.2.0 76 * @package Net_Sieve 77 */ 78 75 * A class for talking to the timsieved server which comes with Cyrus IMAP. 76 * 77 * @category Networking 78 * @package Net_Sieve 79 * @author Richard Heyes <richard@phpguru.org> 80 * @author Damian Fernandez Sosa <damlists@cnba.uba.ar> 81 * @author Anish Mistry <amistry@am-productions.biz> 82 * @author Jan Schneider <jan@horde.org> 83 * @copyright 2002-2003 Richard Heyes 84 * @copyright 2006-2008 Anish Mistry 85 * @license http://www.opensource.org/licenses/bsd-license.php BSD 86 * @version Release: @package_version@ 87 * @link http://pear.php.net/package/Net_Sieve 88 * @link http://www.ietf.org/rfc/rfc3028.txt RFC 3028 (Sieve: A Mail 89 * Filtering Language) 90 * @link http://tools.ietf.org/html/draft-ietf-sieve-managesieve A 91 * Protocol for Remotely Managing Sieve Scripts 92 */ 79 93 class Net_Sieve 80 94 { 81 95 /** 82 * The socket object 83 * @var object 84 */ 96 * The authentication methods this class supports. 97 * 98 * Can be overwritten if having problems with certain methods. 99 * 100 * @var array 101 */ 102 var $supportedAuthMethods = array('DIGEST-MD5', 'CRAM-MD5', 'EXTERNAL', 103 'PLAIN' , 'LOGIN'); 104 105 /** 106 * SASL authentication methods that require Auth_SASL. 107 * 108 * @var array 109 */ 110 var $_supportedSASLAuthMethods = array('DIGEST-MD5', 'CRAM-MD5'); 111 112 /** 113 * The socket handle. 114 * 115 * @var resource 116 */ 85 117 var $_sock; 86 118 87 119 /** 88 * Info about the connect 89 * @var array 90 */ 120 * Parameters and connection information. 121 * 122 * @var array 123 */ 91 124 var $_data; 92 125 93 126 /** 94 * Current state of the connection 95 * @var integer 96 */ 127 * Current state of the connection. 128 * 129 * One of the NET_SIEVE_STATE_* constants. 130 * 131 * @var integer 132 */ 97 133 var $_state; 98 134 99 135 /** 100 * Constructor error is any 101 * @var object 102 */ 136 * Constructor error. 137 * 138 * @var PEAR_Error 139 */ 103 140 var $_error; 104 141 105 142 /** 106 * To allow class debuging 107 * @var boolean 108 */ 143 * Whether to enable debugging. 144 * 145 * @var boolean 146 */ 109 147 var $_debug = false; 110 148 111 149 /** 112 * Allows picking up of an already established connection 113 * @var boolean 114 */ 150 * Debug output handler. 151 * 152 * This has to be a valid callback. 153 * 154 * @var string|array 155 */ 156 var $_debug_handler = null; 157 158 /** 159 * Whether to pick up an already established connection. 160 * 161 * @var boolean 162 */ 115 163 var $_bypassAuth = false; 116 164 117 165 /** 118 * Whether to use TLS if available 119 * @var boolean 120 */ 166 * Whether to use TLS if available. 167 * 168 * @var boolean 169 */ 121 170 var $_useTLS = true; 122 171 123 172 /** 124 * Additional options for stream_context_create() 125 * @var array 126 */ 173 * Additional options for stream_context_create(). 174 * 175 * @var array 176 */ 127 177 var $_options = null; 128 178 129 179 /** 130 * The auth methods this class support 131 * @var array 132 */ 133 var $supportedAuthMethods=array('DIGEST-MD5', 'CRAM-MD5', 'EXTERNAL', 'PLAIN' , 'LOGIN'); 134 //if you have problems using DIGEST-MD5 authentication please comment the line above and uncomment the following line 135 //var $supportedAuthMethods=array( 'CRAM-MD5', 'PLAIN' , 'LOGIN'); 136 137 //var $supportedAuthMethods=array( 'PLAIN' , 'LOGIN'); 138 139 /** 140 * The auth methods this class support 141 * @var array 142 */ 143 var $supportedSASLAuthMethods=array('DIGEST-MD5', 'CRAM-MD5'); 144 145 /** 146 * Handles posible referral loops 147 * @var array 148 */ 180 * Maximum number of referral loops 181 * 182 * @var array 183 */ 149 184 var $_maxReferralCount = 15; 150 185 151 186 /** 152 * Constructor 153 * Sets up the object, connects to the server and logs in. stores 154 * any generated error in $this->_error, which can be retrieved 155 * using the getError() method. 156 * 157 * @param string $user Login username 158 * @param string $pass Login password 159 * @param string $host Hostname of server 160 * @param string $port Port of server 161 * @param string $logintype Type of login to perform 162 * @param string $euser Effective User (if $user=admin, login as $euser) 163 * @param string $bypassAuth Skip the authentication phase. Useful if the socket 164 is already open. 165 * @param boolean $useTLS Use TLS if available 166 * @param array $options options for stream_context_create() 167 */ 168 function Net_Sieve($user = null , $pass = null , $host = 'localhost', $port = 2000, $logintype = '', $euser = '', $debug = false, $bypassAuth = false, $useTLS = true, $options = null) 169 { 170 $this->_state = NET_SIEVE_STATE_DISCONNECTED; 171 $this->_data['user'] = $user; 172 $this->_data['pass'] = $pass; 173 $this->_data['host'] = $host; 174 $this->_data['port'] = $port; 187 * Constructor. 188 * 189 * Sets up the object, connects to the server and logs in. Stores any 190 * generated error in $this->_error, which can be retrieved using the 191 * getError() method. 192 * 193 * @param string $user Login username. 194 * @param string $pass Login password. 195 * @param string $host Hostname of server. 196 * @param string $port Port of server. 197 * @param string $logintype Type of login to perform (see 198 * $supportedAuthMethods). 199 * @param string $euser Effective user. If authenticating as an 200 * administrator, login as this user. 201 * @param boolean $debug Whether to enable debugging (@see setDebug()). 202 * @param string $bypassAuth Skip the authentication phase. Useful if the 203 * socket is already open. 204 * @param boolean $useTLS Use TLS if available. 205 * @param array $options Additional options for 206 * stream_context_create(). 207 */ 208 function Net_Sieve($user = null, $pass = null, $host = 'localhost', 209 $port = 2000, $logintype = '', $euser = '', $debug = false, 210 $bypassAuth = false, $useTLS = true, $options = null 211 ) { 212 $this->_state = NET_SIEVE_STATE_DISCONNECTED; 213 $this->_data['user'] = $user; 214 $this->_data['pass'] = $pass; 215 $this->_data['host'] = $host; 216 $this->_data['port'] = $port; 175 217 $this->_data['logintype'] = $logintype; 176 $this->_data['euser'] = $euser; 177 $this->_sock = &new Net_Socket(); 218 $this->_data['euser'] = $euser; 219 $this->_sock = new Net_Socket(); 220 $this->_debug = $debug; 221 $this->_bypassAuth = $bypassAuth; 222 $this->_useTLS = $useTLS; 223 $this->_options = $options; 224 225 /* Try to include the Auth_SASL package. If the package is not 226 * available, we disable the authentication methods that depend upon 227 * it. */ 228 if ((@include_once 'Auth/SASL.php') === false) { 229 $this->_debug('Auth_SASL not present'); 230 foreach ($this->supportedSASLAuthMethods as $SASLMethod) { 231 $pos = array_search($SASLMethod, $this->supportedAuthMethods); 232 $this->_debug('Disabling method ' . $SASLMethod); 233 unset($this->supportedAuthMethods[$pos]); 234 } 235 } 236 237 if (strlen($user) && strlen($pass)) { 238 $this->_error = $this->_handleConnectAndLogin(); 239 } 240 } 241 242 /** 243 * Returns any error that may have been generated in the constructor. 244 * 245 * @return boolean|PEAR_Error False if no error, PEAR_Error otherwise. 246 */ 247 function getError() 248 { 249 return PEAR::isError($this->_error) ? $this->_error : false; 250 } 251 252 /** 253 * Sets the debug state and handler function. 254 * 255 * @param boolean $debug Whether to enable debugging. 256 * @param string $handler A custom debug handler. Must be a valid callback. 257 * 258 * @return void 259 */ 260 function setDebug($debug = true, $handler = null) 261 { 178 262 $this->_debug = $debug; 179 $this->_bypassAuth = $bypassAuth; 180 $this->_useTLS = $useTLS; 181 $this->_options = $options; 182 /* 183 * Include the Auth_SASL package. If the package is not available, 184 * we disable the authentication methods that depend upon it. 185 */ 186 if ((@include_once 'Auth/SASL.php') === false) { 187 if($this->_debug){ 188 echo "AUTH_SASL NOT PRESENT!\n"; 189 } 190 foreach($this->supportedSASLAuthMethods as $SASLMethod){ 191 $pos = array_search( $SASLMethod, $this->supportedAuthMethods ); 192 if($this->_debug){ 193 echo "DISABLING METHOD $SASLMethod\n"; 194 } 195 unset($this->supportedAuthMethods[$pos]); 196 } 197 } 198 if( ($user != null) && ($pass != null) ){ 199 $this->_error = $this->_handleConnectAndLogin(); 200 } 201 } 202 203 /** 204 * Handles the errors the class can find 205 * on the server 206 * 207 * @access private 208 * @param mixed $msg Text error message or PEAR error object 209 * @param integer $code Numeric error code 210 * @return PEAR_Error 211 */ 212 function _raiseError($msg, $code) 213 { 214 include_once 'PEAR.php'; 215 return PEAR::raiseError($msg, $code); 216 } 217 218 /** 219 * Handles connect and login. 220 * on the server 221 * 222 * @access private 223 * @return mixed Indexed array of scriptnames or PEAR_Error on failure 224 */ 263 $this->_debug_handler = $handler; 264 } 265 266 /** 267 * Connects to the server and logs in. 268 * 269 * @return boolean True on success, PEAR_Error on failure. 270 */ 225 271 function _handleConnectAndLogin() 226 272 { 227 if (PEAR::isError($res = $this->connect($this->_data['host'] , $this->_data['port'], $this->_options, $this->_useTLS))) {273 if (PEAR::isError($res = $this->connect($this->_data['host'], $this->_data['port'], $this->_options, $this->_useTLS))) { 228 274 return $res; 229 275 } 230 if ($this->_bypassAuth === false) {231 if (PEAR::isError($res = $this->login($this->_data['user'], $this->_data['pass'], $this->_data['logintype'] , $this->_data['euser'] , $this->_bypassAuth) )) {276 if ($this->_bypassAuth === false) { 277 if (PEAR::isError($res = $this->login($this->_data['user'], $this->_data['pass'], $this->_data['logintype'], $this->_data['euser'], $this->_bypassAuth))) { 232 278 return $res; 233 279 } … … 237 283 238 284 /** 239 * Returns an indexed array of scripts currently 240 * on the server 241 * 242 * @return mixed Indexed array of scriptnames or PEAR_Error on failure 243 */ 285 * Handles connecting to the server and checks the response validity. 286 * 287 * @param string $host Hostname of server. 288 * @param string $port Port of server. 289 * @param array $options List of options to pass to 290 * stream_context_create(). 291 * @param boolean $useTLS Use TLS if available. 292 * 293 * @return boolean True on success, PEAR_Error otherwise. 294 */ 295 function connect($host, $port, $options = null, $useTLS = true) 296 { 297 if (NET_SIEVE_STATE_DISCONNECTED != $this->_state) { 298 return PEAR::raiseError('Not currently in DISCONNECTED state', 1); 299 } 300 301 if (PEAR::isError($res = $this->_sock->connect($host, $port, false, 5, $options))) { 302 return $res; 303 } 304 305 if ($this->_bypassAuth) { 306 $this->_state = NET_SIEVE_STATE_TRANSACTION; 307 } else { 308 $this->_state = NET_SIEVE_STATE_AUTHORISATION; 309 if (PEAR::isError($res = $this->_doCmd())) { 310 return $res; 311 } 312 } 313 314 // Explicitly ask for the capabilities in case the connection is 315 // picked up from an existing connection. 316 if (PEAR::isError($res = $this->_cmdCapability())) { 317 return PEAR::raiseError( 318 'Failed to connect, server said: ' . $res->getMessage(), 2 319 ); 320 } 321 322 // Check if we can enable TLS via STARTTLS. 323 if ($useTLS && !empty($this->_capability['starttls']) 324 && function_exists('stream_socket_enable_crypto') 325 ) { 326 if (PEAR::isError($res = $this->_startTLS())) { 327 return $res; 328 } 329 } 330 331 return true; 332 } 333 334 /** 335 * Disconnect from the Sieve server. 336 * 337 * @param boolean $sendLogoutCMD Whether to send LOGOUT command before 338 * disconnecting. 339 * 340 * @return boolean True on success, PEAR_Error otherwise. 341 */ 342 function disconnect($sendLogoutCMD = true) 343 { 344 return $this->_cmdLogout($sendLogoutCMD); 345 } 346 347 /** 348 * Logs into server. 349 * 350 * @param string $user Login username. 351 * @param string $pass Login password. 352 * @param string $logintype Type of login method to use. 353 * @param string $euser Effective UID (perform on behalf of $euser). 354 * @param boolean $bypassAuth Do not perform authentication. 355 * 356 * @return boolean True on success, PEAR_Error otherwise. 357 */ 358 function login($user, $pass, $logintype = null, $euser = '', $bypassAuth = false) 359 { 360 if (NET_SIEVE_STATE_AUTHORISATION != $this->_state) { 361 return PEAR::raiseError('Not currently in AUTHORISATION state', 1); 362 } 363 364 if (!$bypassAuth ) { 365 if (PEAR::isError($res = $this->_cmdAuthenticate($user, $pass, $logintype, $euser))) { 366 return $res; 367 } 368 } 369 $this->_state = NET_SIEVE_STATE_TRANSACTION; 370 371 return true; 372 } 373 374 /** 375 * Returns an indexed array of scripts currently on the server. 376 * 377 * @return array Indexed array of scriptnames. 378 */ 244 379 function listScripts() 245 380 { … … 253 388 254 389 /** 255 * Returns the active script256 *257 * @return mixed The active scriptname or PEAR_Error on failure258 */390 * Returns the active script. 391 * 392 * @return string The active scriptname. 393 */ 259 394 function getActive() 260 395 { 261 396 if (!empty($this->_active)) { 262 397 return $this->_active; 263 264 } elseif (is_array($scripts = $this->_cmdListScripts())) {398 } 399 if (is_array($scripts = $this->_cmdListScripts())) { 265 400 $this->_active = $scripts[1]; 266 401 return $scripts[1]; … … 269 404 270 405 /** 271 * Sets the active script 272 * 273 * @param string $scriptname The name of the script to be set as active 274 * @return mixed true on success, PEAR_Error on failure 275 */ 406 * Sets the active script. 407 * 408 * @param string $scriptname The name of the script to be set as active. 409 * 410 * @return boolean True on success, PEAR_Error on failure. 411 */ 276 412 function setActive($scriptname) 277 413 { … … 280 416 281 417 /** 282 * Retrieves a script 283 * 284 * @param string $scriptname The name of the script to be retrieved 285 * @return mixed The script on success, PEAR_Error on failure 418 * Retrieves a script. 419 * 420 * @param string $scriptname The name of the script to be retrieved. 421 * 422 * @return string The script on success, PEAR_Error on failure. 286 423 */ 287 424 function getScript($scriptname) … … 291 428 292 429 /** 293 * Adds a script to the server 294 * 295 * @param string $scriptname Name of the script 296 * @param string $script The script 297 * @param boolean $makeactive Whether to make this the active script 298 * @return mixed true on success, PEAR_Error on failure 299 */ 430 * Adds a script to the server. 431 * 432 * @param string $scriptname Name of the script. 433 * @param string $script The script content. 434 * @param boolean $makeactive Whether to make this the active script. 435 * 436 * @return boolean True on success, PEAR_Error on failure. 437 */ 300 438 function installScript($scriptname, $script, $makeactive = false) 301 439 { 302 440 if (PEAR::isError($res = $this->_cmdPutScript($scriptname, $script))) { 303 441 return $res; 304 305 } elseif ($makeactive) {442 } 443 if ($makeactive) { 306 444 return $this->_cmdSetActive($scriptname); 307 308 } else { 309 return true; 310 } 311 } 312 313 /** 314 * Removes a script from the server 315 * 316 * @param string $scriptname Name of the script 317 * @return mixed True on success, PEAR_Error on failure 318 */ 445 } 446 return true; 447 } 448 449 /** 450 * Removes a script from the server. 451 * 452 * @param string $scriptname Name of the script. 453 * 454 * @return boolean True on success, PEAR_Error on failure. 455 */ 319 456 function removeScript($scriptname) 320 457 { … … 323 460 324 461 /** 325 * Returns any error that may have been generated in the 326 * constructor 327 * 328 * @return mixed False if no error, PEAR_Error otherwise 329 */ 330 function getError() 331 { 332 return PEAR::isError($this->_error) ? $this->_error : false; 333 } 334 335 /** 336 * Handles connecting to the server and checking the 337 * response is valid. 338 * 339 * @access private 340 * @param string $host Hostname of server 341 * @param string $port Port of server 342 * @param array $options List of options to pass to connect 343 * @param boolean $useTLS Use TLS if available 344 * @return mixed True on success, PEAR_Error otherwise 345 */ 346 function connect($host, $port, $options = null, $useTLS = true) 347 { 348 if (NET_SIEVE_STATE_DISCONNECTED != $this->_state) { 349 $msg='Not currently in DISCONNECTED state'; 350 $code=1; 351 return $this->_raiseError($msg,$code); 352 } 353 354 if (PEAR::isError($res = $this->_sock->connect($host, $port, false, 5, $options))) { 462 * Checks if the server has space to store the script by the server. 463 * 464 * @param string $scriptname The name of the script to mark as active. 465 * @param integer $size The size of the script. 466 * 467 * @return boolean|PEAR_Error True if there is space, PEAR_Error otherwise. 468 * 469 * @todo Rename to hasSpace() 470 */ 471 function haveSpace($scriptname, $size) 472 { 473 if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { 474 return PEAR::raiseError('Not currently in TRANSACTION state', 1); 475 } 476 if (PEAR::isError($res = $this->_doCmd(sprintf('HAVESPACE "%s" %d', $scriptname, $size)))) { 355 477 return $res; 356 478 } 357 358 if($this->_bypassAuth === false) { 359 $this->_state = NET_SIEVE_STATE_AUTHORISATION; 360 if (PEAR::isError($res = $this->_doCmd())) { 361 return $res; 362 } 363 } else { 364 $this->_state = NET_SIEVE_STATE_TRANSACTION; 365 } 366 367 // Explicitly ask for the capabilities in case the connection 368 // is picked up from an existing connection. 369 if(PEAR::isError($res = $this->_cmdCapability() )) { 370 $msg='Failed to connect, server said: ' . $res->getMessage(); 371 $code=2; 372 return $this->_raiseError($msg,$code); 373 } 374 375 if($useTLS === true) { 376 // check if we can enable TLS via STARTTLS 377 if(isset($this->_capability['starttls']) && function_exists('stream_socket_enable_crypto') === true) { 378 if (PEAR::isError($res = $this->_startTLS())) { 379 return $res; 479 return true; 480 } 481 482 /** 483 * Returns the list of extensions the server supports. 484 * 485 * @return array List of extensions or PEAR_Error on failure. 486 */ 487 function getExtensions() 488 { 489 if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { 490 return PEAR::raiseError('Not currently connected', 7); 491 } 492 return $this->_capability['extensions']; 493 } 494 495 /** 496 * Returns whether the server supports an extension. 497 * 498 * @param string $extension The extension to check. 499 * 500 * @return boolean Whether the extension is supported or PEAR_Error on 501 * failure. 502 */ 503 function hasExtension($extension) 504 { 505 if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { 506 return PEAR::raiseError('Not currently connected', 7); 507 } 508 509 $extension = trim($this->_toUpper($extension)); 510 if (is_array($this->_capability['extensions'])) { 511 foreach ($this->_capability['extensions'] as $ext) { 512 if ($ext == $extension) { 513 return true; 380 514 } 381 515 } 382 516 } 383 517 518 return false; 519 } 520 521 /** 522 * Returns the list of authentication methods the server supports. 523 * 524 * @return array List of authentication methods or PEAR_Error on failure. 525 */ 526 function getAuthMechs() 527 { 528 if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { 529 return PEAR::raiseError('Not currently connected', 7); 530 } 531 return $this->_capability['sasl']; 532 } 533 534 /** 535 * Returns whether the server supports an authentication method. 536 * 537 * @param string $method The method to check. 538 * 539 * @return boolean Whether the method is supported or PEAR_Error on 540 * failure. 541 */ 542 function hasAuthMech($method) 543 { 544 if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { 545 return PEAR::raiseError('Not currently connected', 7); 546 } 547 548 $method = trim($this->_toUpper($method)); 549 if (is_array($this->_capability['sasl'])) { 550 foreach ($this->_capability['sasl'] as $sasl) { 551 if ($sasl == $method) { 552 return true; 553 } 554 } 555 } 556 557 return false; 558 } 559 560 /** 561 * Handles the authentication using any known method. 562 * 563 * @param string $uid The userid to authenticate as. 564 * @param string $pwd The password to authenticate with. 565 * @param string $userMethod The method to use. If empty, the class chooses 566 * the best (strongest) available method. 567 * @param string $euser The effective uid to authenticate as. 568 * 569 * @return void 570 */ 571 function _cmdAuthenticate($uid, $pwd, $userMethod = null, $euser = '') 572 { 573 if (PEAR::isError($method = $this->_getBestAuthMethod($userMethod))) { 574 return $method; 575 } 576 switch ($method) { 577 case 'DIGEST-MD5': 578 return $this->_authDigestMD5($uid, $pwd, $euser); 579 case 'CRAM-MD5': 580 $result = $this->_authCRAMMD5($uid, $pwd, $euser); 581 break; 582 case 'LOGIN': 583 $result = $this->_authLOGIN($uid, $pwd, $euser); 584 break; 585 case 'PLAIN': 586 $result = $this->_authPLAIN($uid, $pwd, $euser); 587 break; 588 case 'EXTERNAL': 589 $result = $this->_authEXTERNAL($uid, $pwd, $euser); 590 break; 591 default : 592 $result = PEAR::raiseError( 593 $method . ' is not a supported authentication method' 594 ); 595 break; 596 } 597 598 if (PEAR::isError($res = $this->_doCmd())) { 599 return $res; 600 } 601 602 return $result; 603 } 604 605 /** 606 * Authenticates the user using the PLAIN method. 607 * 608 * @param string $user The userid to authenticate as. 609 * @param string $pass The password to authenticate with. 610 * @param string $euser The effective uid to authenticate as. 611 * 612 * @return void 613 */ 614 function _authPLAIN($user, $pass, $euser) 615 { 616 return $this->_sendCmd( 617 sprintf( 618 'AUTHENTICATE "PLAIN" "%s"', 619 base64_encode($euser . chr(0) . $user . chr(0) . $pass) 620 ) 621 ); 622 } 623 624 /** 625 * Authenticates the user using the LOGIN method. 626 * 627 * @param string $user The userid to authenticate as. 628 * @param string $pass The password to authenticate with. 629 * @param string $euser The effective uid to authenticate as. 630 * 631 * @return void 632 */ 633 function _authLOGIN($user, $pass, $euser) 634 { 635 if (PEAR::isError($result = $this->_sendCmd('AUTHENTICATE "LOGIN"'))) { 636 return $result; 637 } 638 if (PEAR::isError($result = $this->_doCmd('"' . base64_encode($user) . '"'))) { 639 return $result; 640 } 641 return $this->_doCmd('"' . base64_encode($pass) . '"'); 642 } 643 644 /** 645 * Authenticates the user using the CRAM-MD5 method. 646 * 647 * @param string $user The userid to authenticate as. 648 * @param string $pass The password to authenticate with. 649 * @param string $euser The effective uid to authenticate as. 650 * 651 * @return void 652 */ 653 function _authCRAMMD5($user, $pass, $euser) 654 { 655 if (PEAR::isError($challenge = $this->_doCmd('AUTHENTICATE "CRAM-MD5"', true))) { 656 return $challenge; 657 } 658 659 $challenge = base64_decode(trim($challenge)); 660 $cram = Auth_SASL::factory('crammd5'); 661 if (PEAR::isError($response = $cram->getResponse($user, $pass, $challenge))) { 662 return $response; 663 } 664 665 return $this->_sendStringResponse(base64_encode($response)); 666 } 667 668 /** 669 * Authenticates the user using the DIGEST-MD5 method. 670 * 671 * @param string $user The userid to authenticate as. 672 * @param string $pass The password to authenticate with. 673 * @param string $euser The effective uid to authenticate as. 674 * 675 * @return void 676 */ 677 function _authDigestMD5($user, $pass, $euser) 678 { 679 if (PEAR::isError($challenge = $this->_doCmd('AUTHENTICATE "DIGEST-MD5"', true))) { 680 return $challenge; 681 } 682 683 $challenge = base64_decode(trim($challenge)); 684 $digest = Auth_SASL::factory('digestmd5'); 685 // @todo Really 'localhost'? 686 if (PEAR::isError($response = $digest->getResponse($user, $pass, $challenge, 'localhost', 'sieve', $euser))) { 687 return $response; 688 } 689 690 if (PEAR::isError($result = $this->_sendStringResponse(base64_encode($param)))) { 691 return $result; 692 } 693 if (PEAR::isError($result = $this->_doCmd())) { 694 return $result; 695 } 696 if ($this->_toUpper(substr($result, 0, 2)) == 'OK') { 697 return; 698 } 699 700 /* We don't use the protocol's third step because SIEVE doesn't allow 701 * subsequent authentication, so we just silently ignore it. */ 702 if (PEAR::isError($result = $this->_sendStringResponse(''))) { 703 return $result; 704 } 705 706 return $this->_doCmd(); 707 } 708 709 /** 710 * Authenticates the user using the EXTERNAL method. 711 * 712 * @param string $user The userid to authenticate as. 713 * @param string $pass The password to authenticate with. 714 * @param string $euser The effective uid to authenticate as. 715 * 716 * @return void 717 * 718 * @since 1.1.7 719 */ 720 function _authEXTERNAL($user, $pass, $euser) 721 { 722 $cmd = sprintf( 723 'AUTHENTICATE "EXTERNAL" "%s"', 724 base64_encode(strlen($euser) ? $euser : $user) 725 ); 726 return $this->_sendCmd($cmd); 727 } 728 729 /** 730 * Removes a script from the server. 731 * 732 * @param string $scriptname Name of the script to delete. 733 * 734 * @return boolean True on success, PEAR_Error otherwise. 735 */ 736 function _cmdDeleteScript($scriptname) 737 { 738 if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { 739 return PEAR::raiseError('Not currently in AUTHORISATION state', 1); 740 } 741 if (PEAR::isError($res = $this->_doCmd(sprintf('DELETESCRIPT "%s"', $scriptname)))) { 742 return $res; 743 } 384 744 return true; 385 745 } 386 746 387 747 /** 388 * Logs into server. 389 * 390 * @param string $user Login username 391 * @param string $pass Login password 392 * @param string $logintype Type of login method to use 393 * @param string $euser Effective UID (perform on behalf of $euser) 394 * @param boolean $bypassAuth Do not perform authentication 395 * @return mixed True on success, PEAR_Error otherwise 396 */ 397 function login($user, $pass, $logintype = null , $euser = '', $bypassAuth = false) 398 { 399 if (NET_SIEVE_STATE_AUTHORISATION != $this->_state) { 400 $msg='Not currently in AUTHORISATION state'; 401 $code=1; 402 return $this->_raiseError($msg,$code); 403 } 404 405 if( $bypassAuth === false ){ 406 if(PEAR::isError($res=$this->_cmdAuthenticate($user , $pass , $logintype, $euser ) ) ){ 407 return $res; 408 } 409 } 410 $this->_state = NET_SIEVE_STATE_TRANSACTION; 411 return true; 412 } 413 414 /** 415 * Handles the authentication using any known method 416 * 417 * @param string $uid The userid to authenticate as. 418 * @param string $pwd The password to authenticate with. 419 * @param string $userMethod The method to use ( if $userMethod == '' then the class chooses the best method (the stronger is the best ) ) 420 * @param string $euser The effective uid to authenticate as. 421 * 422 * @return mixed string or PEAR_Error 423 * 424 * @access private 425 * @since 1.0 426 */ 427 function _cmdAuthenticate($uid , $pwd , $userMethod = null , $euser = '' ) 428 { 429 if ( PEAR::isError( $method = $this->_getBestAuthMethod($userMethod) ) ) { 430 return $method; 431 } 432 switch ($method) { 433 case 'DIGEST-MD5': 434 $result = $this->_authDigest_MD5( $uid , $pwd , $euser ); 435 return $result; 436 break; 437 case 'CRAM-MD5': 438 $result = $this->_authCRAM_MD5( $uid , $pwd, $euser); 439 break; 440 case 'LOGIN': 441 $result = $this->_authLOGIN( $uid , $pwd , $euser ); 442 break; 443 case 'PLAIN': 444 $result = $this->_authPLAIN( $uid , $pwd , $euser ); 445 break; 446 case 'EXTERNAL': 447 $result = $this->_authEXTERNAL( $uid , $pwd , $euser ); 448 break; 449 default : 450 $result = new PEAR_Error( "$method is not a supported authentication method" ); 451 break; 452 } 453 454 if (PEAR::isError($res = $this->_doCmd() )) { 748 * Retrieves the contents of the named script. 749 * 750 * @param string $scriptname Name of the script to retrieve. 751 * 752 * @return string The script if successful, PEAR_Error otherwise. 753 */ 754 function _cmdGetScript($scriptname) 755 { 756 if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { 757 return PEAR::raiseError('Not currently in AUTHORISATION state', 1); 758 } 759 760 if (PEAR::isError($res = $this->_doCmd(sprintf('GETSCRIPT "%s"', $scriptname)))) { 455 761 return $res; 456 762 } 457 return $result;458 }459 460 /**461 * Authenticates the user using the PLAIN method.462 *463 * @param string $user The userid to authenticate as.464 * @param string $pass The password to authenticate with.465 * @param string $euser The effective uid to authenticate as.466 *467 * @return array Returns an array containing the response468 *469 * @access private470 * @since 1.0471 */472 function _authPLAIN($user, $pass , $euser )473 {474 if ($euser != '') {475 $cmd=sprintf('AUTHENTICATE "PLAIN" "%s"', base64_encode($euser . chr(0) . $user . chr(0) . $pass ) ) ;476 } else {477 $cmd=sprintf('AUTHENTICATE "PLAIN" "%s"', base64_encode( chr(0) . $user . chr(0) . $pass ) );478 }479 return $this->_sendCmd( $cmd ) ;480 }481 482 /**483 * Authenticates the user using the PLAIN method.484 *485 * @param string $user The userid to authenticate as.486 * @param string $pass The password to authenticate with.487 * @param string $euser The effective uid to authenticate as.488 *489 * @return array Returns an array containing the response490 *491 * @access private492 * @since 1.0493 */494 function _authLOGIN($user, $pass , $euser )495 {496 $this->_sendCmd('AUTHENTICATE "LOGIN"');497 $this->_doCmd(sprintf('"%s"', base64_encode($user)));498 $this->_doCmd(sprintf('"%s"', base64_encode($pass)));499 }500 501 /**502 * Authenticates the user using the CRAM-MD5 method.503 *504 * @param string $uid The userid to authenticate as.505 * @param string $pwd The password to authenticate with.506 * @param string $euser The effective uid to authenticate as.507 *508 * @return array Returns an array containing the response509 *510 * @access private511 * @since 1.0512 */513 function _authCRAM_MD5($uid, $pwd, $euser)514 {515 if ( PEAR::isError( $challenge = $this->_doCmd( 'AUTHENTICATE "CRAM-MD5"' ) ) ) {516 $this->_error=$challenge;517 return $challenge;518 }519 $challenge=trim($challenge);520 $challenge = base64_decode( trim($challenge) );521 $cram = &Auth_SASL::factory('crammd5');522 if ( PEAR::isError($resp=$cram->getResponse( $uid , $pwd , $challenge ) ) ) {523 $this->_error=$resp;524 return $resp;525 }526 $auth_str = base64_encode( $resp );527 if ( PEAR::isError($error = $this->_sendStringResponse( $auth_str ) ) ) {528 $this->_error=$error;529 return $error;530 }531 532 }533 534 /**535 * Authenticates the user using the DIGEST-MD5 method.536 *537 * @param string $uid The userid to authenticate as.538 * @param string $pwd The password to authenticate with.539 * @param string $euser The effective uid to authenticate as.540 *541 * @return array Returns an array containing the response542 *543 * @access private544 * @since 1.0545 */546 function _authDigest_MD5($uid, $pwd, $euser)547 {548 if ( PEAR::isError( $challenge = $this->_doCmd('AUTHENTICATE "DIGEST-MD5"') ) ) {549 $this->_error= $challenge;550 return $challenge;551 }552 $challenge = base64_decode( $challenge );553 $digest = &Auth_SASL::factory('digestmd5');554 555 if(PEAR::isError($param=$digest->getResponse($uid, $pwd, $challenge, "localhost", "sieve" , $euser) )) {556 return $param;557 }558 $auth_str = base64_encode($param);559 560 if ( PEAR::isError($error = $this->_sendStringResponse( $auth_str ) ) ) {561 $this->_error=$error;562 return $error;563 }564 565 if ( PEAR::isError( $challenge = $this->_doCmd() ) ) {566 $this->_error=$challenge ;567 return $challenge ;568 }569 570 if( strtoupper(substr($challenge,0,2))== 'OK' ){571 return true;572 }573 574 /**575 * We don't use the protocol's third step because SIEVE doesn't allow576 * subsequent authentication, so we just silently ignore it.577 */578 if ( PEAR::isError($error = $this->_sendStringResponse( '' ) ) ) {579 $this->_error=$error;580 return $error;581 }582 583 if (PEAR::isError($res = $this->_doCmd() )) {584 return $res;585 }586 }587 588 /**589 * Authenticates the user using the EXTERNAL method.590 *591 * @param string $user The userid to authenticate as.592 * @param string $pass The password to authenticate with.593 * @param string $euser The effective uid to authenticate as.594 *595 * @return array Returns an array containing the response596 *597 * @access private598 * @since 1.1.7599 */600 function _authEXTERNAL($user, $pass, $euser)601 {602 if ($euser != '') {603 $cmd=sprintf('AUTHENTICATE "EXTERNAL" "%s"', base64_encode($euser) ) ;604 } else {605 $cmd=sprintf('AUTHENTICATE "EXTERNAL" "%s"', base64_encode($user) );606 }607 return $this->_sendCmd( $cmd ) ;608 }609 610 /**611 * Removes a script from the server612 *613 * @access private614 * @param string $scriptname Name of the script to delete615 * @return mixed True on success, PEAR_Error otherwise616 */617 function _cmdDeleteScript($scriptname)618 {619 if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {620 $msg='Not currently in AUTHORISATION state';621 $code=1;622 return $this->_raiseError($msg,$code);623 }624 if (PEAR::isError($res = $this->_doCmd(sprintf('DELETESCRIPT "%s"', $scriptname) ) )) {625 return $res;626 }627 return true;628 }629 630 /**631 * Retrieves the contents of the named script632 *633 * @access private634 * @param string $scriptname Name of the script to retrieve635 * @return mixed The script if successful, PEAR_Error otherwise636 */637 function _cmdGetScript($scriptname)638 {639 if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {640 $msg='Not currently in AUTHORISATION state';641 $code=1;642 return $this->_raiseError($msg,$code);643 }644 645 if (PEAR::isError($res = $this->_doCmd(sprintf('GETSCRIPT "%s"', $scriptname) ) ) ) {646 return $res;647 }648 763 649 764 return preg_replace('/{[0-9]+}\r\n/', '', $res); … … 651 766 652 767 /** 653 * Sets the ACTIVE script, ie the one that gets run on new mail654 * by the server655 *656 * @access private657 * @param string $scriptname The name of the script to mark as active658 * @return mixed True on success, PEAR_Error otherwise768 * Sets the active script, i.e. the one that gets run on new mail by the 769 * server. 770 * 771 * @param string $scriptname The name of the script to mark as active. 772 * 773 * @return boolean True on success, PEAR_Error otherwise. 659 774 */ 660 775 function _cmdSetActive($scriptname) 661 776 { 662 777 if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { 663 $msg='Not currently in AUTHORISATION state'; 664 $code=1; 665 return $this->_raiseError($msg,$code); 666 } 667 668 if (PEAR::isError($res = $this->_doCmd(sprintf('SETACTIVE "%s"', $scriptname) ) ) ) { 778 return PEAR::raiseError('Not currently in AUTHORISATION state', 1); 779 } 780 if (PEAR::isError($res = $this->_doCmd(sprintf('SETACTIVE "%s"', $scriptname)))) { 669 781 return $res; 670 782 } 671 672 783 $this->_activeScript = $scriptname; 673 784 return true; … … 675 786 676 787 /** 677 * Sends the LISTSCRIPTS command678 *679 * @access private680 * @return mixed Two item array of scripts, and active script on success,681 *PEAR_Error otherwise.682 */788 * Returns the list of scripts on the server. 789 * 790 * @return array An array with the list of scripts in the first element 791 * and the active script in the second element on success, 792 * PEAR_Error otherwise. 793 */ 683 794 function _cmdListScripts() 684 795 { 685 796 if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { 686 $msg='Not currently in AUTHORISATION state'; 687 $code=1; 688 return $this->_raiseError($msg,$code); 797 return PEAR::raiseError('Not currently in AUTHORISATION state', 1); 798 } 799 800 if (PEAR::isError($res = $this->_doCmd('LISTSCRIPTS'))) { 801 return $res; 689 802 } 690 803 691 804 $scripts = array(); 692 805 $activescript = null; 693 694 if (PEAR::isError($res = $this->_doCmd('LISTSCRIPTS'))) {695 return $res;696 }697 698 806 $res = explode("\r\n", $res); 699 700 807 foreach ($res as $value) { 701 808 if (preg_match('/^"(.*)"( ACTIVE)?$/i', $value, $matches)) { … … 711 818 712 819 /** 713 * Sends the PUTSCRIPT command to add a script to 714 * the server. 715 * 716 * @access private 717 * @param string $scriptname Name of the new script 718 * @param string $scriptdata The new script 719 * @return mixed True on success, PEAR_Error otherwise 720 */ 820 * Adds a script to the server. 821 * 822 * @param string $scriptname Name of the new script. 823 * @param string $scriptdata The new script. 824 * 825 * @return boolean True on success, PEAR_Error otherwise. 826 */ 721 827 function _cmdPutScript($scriptname, $scriptdata) 722 828 { 723 829 if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { 724 $msg='Not currently in TRANSACTION state'; 725 $code=1; 726 return $this->_raiseError($msg,$code); 830 return PEAR::raiseError('Not currently in AUTHORISATION state', 1); 727 831 } 728 832 729 833 $stringLength = $this->_getLineLength($scriptdata); 730 834 731 if (PEAR::isError($res = $this->_doCmd(sprintf("PUTSCRIPT \"%s\" {%d+}\r\n%s", $scriptname, $stringLength, $scriptdata) ))) {835 if (PEAR::isError($res = $this->_doCmd(sprintf("PUTSCRIPT \"%s\" {%d+}\r\n%s", $scriptname, $stringLength, $scriptdata)))) { 732 836 return $res; 733 837 } … … 737 841 738 842 /** 739 * Sends the LOGOUT command and terminates the connection 740 * 741 * @access private 742 * @param boolean $sendLogoutCMD True to send LOGOUT command before disconnecting 743 * @return mixed True on success, PEAR_Error otherwise 744 */ 745 function _cmdLogout($sendLogoutCMD=true) 746 { 747 if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) { 748 $msg='Not currently connected'; 749 $code=1; 750 return $this->_raiseError($msg,$code); 751 //return PEAR::raiseError('Not currently connected'); 752 } 753 754 if($sendLogoutCMD){ 843 * Logs out of the server and terminates the connection. 844 * 845 * @param boolean $sendLogoutCMD Whether to send LOGOUT command before 846 * disconnecting. 847 * 848 * @return boolean True on success, PEAR_Error otherwise. 849 */ 850 function _cmdLogout($sendLogoutCMD = true) 851 { 852 if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { 853 return PEAR::raiseError('Not currently connected', 1); 854 } 855 856 if ($sendLogoutCMD) { 755 857 if (PEAR::isError($res = $this->_doCmd('LOGOUT'))) { 756 858 return $res; … … 760 862 $this->_sock->disconnect(); 761 863 $this->_state = NET_SIEVE_STATE_DISCONNECTED; 864 762 865 return true; 763 866 } 764 867 765 868 /** 766 * Sends the CAPABILITY command 767 * 768 * @access private 769 * @return mixed True on success, PEAR_Error otherwise 770 */ 869 * Sends the CAPABILITY command 870 * 871 * @return boolean True on success, PEAR_Error otherwise. 872 */ 771 873 function _cmdCapability() 772 874 { 773 if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) { 774 $msg='Not currently connected'; 775 $code=1; 776 return $this->_raiseError($msg,$code); 777 } 778 875 if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { 876 return PEAR::raiseError('Not currently connected', 1); 877 } 779 878 if (PEAR::isError($res = $this->_doCmd('CAPABILITY'))) { 780 879 return $res; … … 785 884 786 885 /** 787 * Checks if the server has space to store the script 788 * by the server 789 * 790 * @param string $scriptname The name of the script to mark as active 791 * @param integer $size The size of the script 792 * @return mixed True on success, PEAR_Error otherwise 793 */ 794 function haveSpace($scriptname,$size) 795 { 796 if (NET_SIEVE_STATE_TRANSACTION != $this->_state) { 797 $msg='Not currently in TRANSACTION state'; 798 $code=1; 799 return $this->_raiseError($msg,$code); 800 } 801 802 if (PEAR::isError($res = $this->_doCmd(sprintf('HAVESPACE "%s" %d', $scriptname, $size) ) ) ) { 803 return $res; 804 } 805 806 return true; 807 } 808 809 /** 810 * Parses the response from the capability command. Stores 811 * the result in $this->_capability 812 * 813 * @access private 814 * @param string $data The response from the capability command 815 */ 886 * Parses the response from the CAPABILITY command and stores the result 887 * in $_capability. 888 * 889 * @param string $data The response from the capability command. 890 * 891 * @return void 892 */ 816 893 function _parseCapability($data) 817 894 { 818 // clear the cached capabilities 819 $this->_capability = array(); 820 821 $data = preg_split('/\r?\n/', $data, -1, PREG_SPLIT_NO_EMPTY); 895 // Clear the cached capabilities. 896 $this->_capability = array('sasl' => array(), 897 'extensions' => array()); 898 899 $data = preg_split('/\r?\n/', $this->_toUpper($data), -1, PREG_SPLIT_NO_EMPTY); 822 900 823 901 for ($i = 0; $i < count($data); $i++) { 824 if (preg_match('/^"([a-z]+)"( "(.*)")?$/i', $data[$i], $matches)) { 825 switch (strtolower($matches[1])) { 826 case 'implementation': 827 $this->_capability['implementation'] = $matches[3]; 828 break; 829 830 case 'sasl': 831 $this->_capability['sasl'] = preg_split('/\s+/', $matches[3]); 832 break; 833 834 case 'sieve': 835 $this->_capability['extensions'] = preg_split('/\s+/', $matches[3]); 836 break; 837 838 case 'starttls': 839 $this->_capability['starttls'] = true; 840 break; 841 } 842 } 843 } 844 } 845 846 /** 847 * Sends a command to the server 848 * 849 * @access private 850 * @param string $cmd The command to send 851 */ 902 if (!preg_match('/^"([A-Z]+)"( "(.*)")?$/', $data[$i], $matches)) { 903 continue; 904 } 905 switch ($matches[1]) { 906 case 'IMPLEMENTATION': 907 $this->_capability['implementation'] = $matches[3]; 908 break; 909 910 case 'SASL': 911 $this->_capability['sasl'] = preg_split('/\s+/', $matches[3]); 912 break; 913 914 case 'SIEVE': 915 $this->_capability['extensions'] = preg_split('/\s+/', $matches[3]); 916 break; 917 918 case 'STARTTLS': 919 $this->_capability['starttls'] = true; 920 break; 921 } 922 } 923 } 924 925 /** 926 * Sends a command to the server 927 * 928 * @param string $cmd The command to send. 929 * 930 * @return void 931 */ 852 932 function _sendCmd($cmd) 853 933 { 854 934 $status = $this->_sock->getStatus(); 855 935 if (PEAR::isError($status) || $status['eof']) { 856 return new PEAR_Error( 'Failed to write to socket: (connection lost!) ' ); 857 } 858 if ( PEAR::isError( $error = $this->_sock->write( $cmd . "\r\n" ) ) ) { 859 return new PEAR_Error( 'Failed to write to socket: ' . $error->getMessage() ); 860 } 861 862 if( $this->_debug ){ 863 // C: means this data was sent by the client (this class) 864 echo "C:$cmd\n"; 865 } 866 return true; 867 } 868 869 /** 870 * Sends a string response to the server 871 * 872 * @access private 873 * @param string $cmd The command to send 874 */ 936 return PEAR::raiseError('Failed to write to socket: connection lost'); 937 } 938 if (PEAR::isError($error = $this->_sock->write($cmd . "\r\n"))) { 939 return PEAR::raiseError( 940 'Failed to write to socket: ' . $error->getMessage() 941 ); 942 } 943 $this->_debug("C: $cmd"); 944 } 945 946 /** 947 * Sends a string response to the server. 948 * 949 * @param string $str The string to send. 950 * 951 * @return void 952 */ 875 953 function _sendStringResponse($str) 876 954 { 877 $response='{' . $this->_getLineLength($str) . "+}\r\n" . $str ; 878 return $this->_sendCmd($response); 879 } 880 955 return $this->_sendCmd('{' . $this->_getLineLength($str) . "+}\r\n" . $str); 956 } 957 958 /** 959 * Receives a single line from the server. 960 * 961 * @return string The server response line. 962 */ 881 963 function _recvLn() 882 964 { 883 $lastline=''; 884 if (PEAR::isError( $lastline = $this->_sock->gets( 8192 ) ) ) { 885 return new PEAR_Error( 'Failed to write to socket: ' . $lastline->getMessage() ); 886 } 887 $lastline=rtrim($lastline); 888 if($this->_debug){ 889 // S: means this data was sent by the IMAP Server 890 echo "S:$lastline\n" ; 891 } 892 893 if( $lastline === '' ) { 894 return new PEAR_Error( 'Failed to receive from the socket' ); 965 if (PEAR::isError($lastline = $this->_sock->gets(8192))) { 966 return PEAR::raiseError( 967 'Failed to read from socket: ' . $lastline->getMessage() 968 ); 969 } 970 971 $lastline = rtrim($lastline); 972 $this->_debug("S: $lastline"); 973 974 if ($lastline === '') { 975 return PEAR::raiseError('Failed to read from socket'); 895 976 } 896 977 … … 899 980 900 981 /** 901 * Send a command and retrieves a response from the server.902 *903 *904 * @access private905 * @param string $cmd The command to send906 * @return mixed Reponse string if an OK response, PEAR_Error if a NO response907 */908 function _doCmd($cmd = '' )909 {910 $referralCount=0;911 while($referralCount < $this->_maxReferralCount ){912 913 if ($cmd != '' ){914 if (PEAR::isError($error = $this->_sendCmd($cmd))) {982 * Send a command and retrieves a response from the server. 983 * 984 * @param string $cmd The command to send. 985 * @param boolean $auth Whether this is an authentication command. 986 * 987 * @return string|PEAR_Error Reponse string if an OK response, PEAR_Error 988 * if a NO response. 989 */ 990 function _doCmd($cmd = '', $auth = false) 991 { 992 $referralCount = 0; 993 while ($referralCount < $this->_maxReferralCount) { 994 if (strlen($cmd)) { 995 if (PEAR::isError($error = $this->_sendCmd($cmd))) { 915 996 return $error; 916 997 } 917 998 } 999 918 1000 $response = ''; 919 920 1001 while (true) { 921 if(PEAR::isError( $line=$this->_recvLn() )){ 922 return $line; 1002 if (PEAR::isError($line = $this->_recvLn())) { 1003 return $line; 1004 } 1005 $uc_line = $this->_toUpper($line); 1006 1007 if ('OK' == substr($uc_line, 0, 2)) { 1008 $response .= $line; 1009 return rtrim($response); 1010 } 1011 1012 if ('NO' == substr($uc_line, 0, 2)) { 1013 // Check for string literal error message. 1014 if (preg_match('/^no {([0-9]+)\+?}/i', $line, $matches)) { 1015 $line .= str_replace( 1016 "\r\n", ' ', $this->_sock->read($matches[1] + 2) 1017 ); 1018 $this->_debug("S: $line"); 923 1019 } 924 if ('ok' === strtolower(substr($line, 0, 2))) { 925 $response .= $line; 926 return rtrim($response); 927 928 } elseif ('no' === strtolower(substr($line, 0, 2))) { 929 // Check for string literal error message 930 if (preg_match('/^no {([0-9]+)\+?}/i', $line, $matches)) { 931 $line .= str_replace("\r\n", ' ', $this->_sock->read($matches[1] + 2 )); 932 if($this->_debug){ 933 echo "S:$line\n"; 934 } 1020 return PEAR::raiseError(trim($response . substr($line, 2)), 3); 1021 } 1022 1023 if ('BYE' == substr($uc_line, 0, 3)) { 1024 if (PEAR::isError($error = $this->disconnect(false))) { 1025 return PEAR::raiseError( 1026 'Cannot handle BYE, the error was: ' 1027 . $error->getMessage(), 1028 4 1029 ); 1030 } 1031 // Check for referral, then follow it. Otherwise, carp an 1032 // error. 1033 if (preg_match('/^bye \(referral "(sieve:\/\/)?([^"]+)/i', $line, $matches)) { 1034 // Replace the old host with the referral host 1035 // preserving any protocol prefix. 1036 $this->_data['host'] = preg_replace( 1037 '/\w+(?!(\w|\:\/\/)).*/', $matches[2], 1038 $this->_data['host'] 1039 ); 1040 if (PEAR::isError($error = $this->_handleConnectAndLogin())) { 1041 return PEAR::raiseError( 1042 'Cannot follow referral to ' 1043 . $this->_data['host'] . ', the error was: ' 1044 . $error->getMessage(), 1045 5 1046 ); 935 1047 } 936 $msg=trim($response . substr($line, 2)); 937 $code=3; 938 return $this->_raiseError($msg,$code); 939 } elseif ('bye' === strtolower(substr($line, 0, 3))) { 940 941 if(PEAR::isError($error = $this->disconnect(false) ) ){ 942 $msg="Can't handle bye, The error was= " . $error->getMessage() ; 943 $code=4; 944 return $this->_raiseError($msg,$code); 945 } 946 //if (preg_match('/^bye \(referral "([^"]+)/i', $line, $matches)) { 947 if (preg_match('/^bye \(referral "(sieve:\/\/)?([^"]+)/i', $line, $matches)) { 948 // Check for referral, then follow it. Otherwise, carp an error. 949 // Replace the old host with the referral host preserving any protocol prefix 950 $this->_data['host'] = preg_replace('/\w+(?!(\w|\:\/\/)).*/',$matches[2],$this->_data['host']); 951 if (PEAR::isError($error = $this->_handleConnectAndLogin() ) ){ 952 $msg="Can't follow referral to " . $this->_data['host'] . ", The error was= " . $error->getMessage() ; 953 $code=5; 954 return $this->_raiseError($msg,$code); 955 } 956 break; 957 // Retry the command 958 if(PEAR::isError($error = $this->_sendCmd($cmd) )) { 959 return $error; 960 } 961 continue; 962 } 963 $msg=trim($response . $line); 964 $code=6; 965 return $this->_raiseError($msg,$code); 966 } elseif (preg_match('/^{([0-9]+)\+?}/i', $line, $matches)) { 967 // Matches String Responses. 968 //$line = str_replace("\r\n", ' ', $this->_sock->read($matches[1] + 2 )); 969 $str_size = $matches[1] + 2; 970 $line = ''; 971 $line_length = 0; 972 while ($line_length < $str_size) { 973 $line .= $this->_sock->read($str_size - $line_length); 974 $line_length = $this->_getLineLength($line); 975 } 976 if($this->_debug){ 977 echo "S:$line\n"; 978 } 979 if($this->_state != NET_SIEVE_STATE_AUTHORISATION) { 980 // receive the pending OK only if we aren't authenticating 981 // since string responses during authentication don't need an 982 // OK. 983 $this->_recvLn(); 984 } 985 return $line; 1048 break; 986 1049 } 987 $response .= $line . "\r\n"; 988 $referralCount++; 1050 return PEAR::raiseError(trim($response . $line), 6); 989 1051 } 990 } 991 $msg="Max referral count reached ($referralCount times) Cyrus murder loop error?"; 992 $code=7; 993 return $this->_raiseError($msg,$code); 994 } 995 996 /** 997 * Sets the debug state 998 * 999 * @param boolean $debug 1000 * @return void 1001 */ 1002 function setDebug($debug = true) 1003 { 1004 $this->_debug = $debug; 1005 } 1006 1007 /** 1008 * Disconnect from the Sieve server 1009 * 1010 * @param string $scriptname The name of the script to be set as active 1011 * @return mixed true on success, PEAR_Error on failure 1012 */ 1013 function disconnect($sendLogoutCMD=true) 1014 { 1015 return $this->_cmdLogout($sendLogoutCMD); 1052 1053 if (preg_match('/^{([0-9]+)\+?}/i', $line, $matches)) { 1054 // Matches String Responses. 1055 $str_size = $matches[1] + 2; 1056 $line = ''; 1057 $line_length = 0; 1058 while ($line_length < $str_size) { 1059 $line .= $this->_sock->read($str_size - $line_length); 1060 $line_length = $this->_getLineLength($line); 1061 } 1062 $this->_debug("S: $line"); 1063 1064 if (!$auth) { 1065 // Receive the pending OK only if we aren't 1066 // authenticating since string responses during 1067 // authentication don't need an OK. 1068 $this->_recvLn(); 1069 } 1070 return $line; 1071 } 1072 1073 if ($auth) { 1074 // String responses during authentication don't need an 1075 // OK. 1076 $response .= $line; 1077 return rtrim($response); 1078 } 1079 1080 $response .= $line . "\r\n"; 1081 $referralCount++; 1082 } 1083 } 1084 1085 return PEAR::raiseError('Max referral count (' . $referralCount . ') reached. Cyrus murder loop error?', 7); 1016 1086 } 1017 1087 … … 1020 1090 * has advertised. 1021 1091 * 1022 * @param string if !=null,authenticate with this method ($userMethod). 1023 * 1024 * @return mixed Returns a string containing the name of the best 1025 * supported authentication method or a PEAR_Error object 1026 * if a failure condition is encountered. 1027 * @access private 1028 * @since 1.0 1092 * @param string $userMethod Only consider this method as available. 1093 * 1094 * @return string The name of the best supported authentication method or 1095 * a PEAR_Error object on failure. 1029 1096 */ 1030 1097 function _getBestAuthMethod($userMethod = null) 1031 1098 { 1032 if( isset($this->_capability['sasl']) ){ 1033 $serverMethods=$this->_capability['sasl']; 1034 }else{ 1035 // if the server don't send an sasl capability fallback to login auth 1036 //return 'LOGIN'; 1037 return new PEAR_Error("This server don't support any Auth methods SASL problem?"); 1038 } 1039 1040 if($userMethod != null ){ 1041 $methods = array(); 1042 $methods[] = $userMethod; 1043 }else{ 1044 1099 if (!isset($this->_capability['sasl'])) { 1100 return PEAR::raiseError('This server doesn\'t support any authentication methods. SASL problem?'); 1101 } 1102 1103 $serverMethods = $this->_capability['sasl']; 1104 1105 if ($userMethod) { 1106 $methods = array($userMethod); 1107 } else { 1045 1108 $methods = $this->supportedAuthMethods; 1046 1109 } 1047 if( ($methods != null) && ($serverMethods != null)){ 1048 foreach ( $methods as $method ) { 1049 if ( in_array( $method , $serverMethods ) ) { 1050 return $method; 1051 } 1052 } 1053 $serverMethods=implode(',' , $serverMethods ); 1054 $myMethods=implode(',' ,$this->supportedAuthMethods); 1055 return new PEAR_Error("$method NOT supported authentication method!. This server " . 1056 "supports these methods= $serverMethods, but I support $myMethods"); 1057 }else{ 1058 return new PEAR_Error("This server don't support any Auth methods"); 1059 } 1060 } 1061 1062 /** 1063 * Return the list of extensions the server supports 1064 * 1065 * @return mixed array on success, PEAR_Error on failure 1066 */ 1067 function getExtensions() 1068 { 1069 if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) { 1070 $msg='Not currently connected'; 1071 $code=7; 1072 return $this->_raiseError($msg,$code); 1073 } 1074 1075 return $this->_capability['extensions']; 1076 } 1077 1078 /** 1079 * Return true if tyhe server has that extension 1080 * 1081 * @param string the extension to compare 1082 * @return mixed array on success, PEAR_Error on failure 1083 */ 1084 function hasExtension($extension) 1085 { 1086 if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) { 1087 $msg='Not currently connected'; 1088 $code=7; 1089 return $this->_raiseError($msg,$code); 1090 } 1091 1092 if(is_array($this->_capability['extensions'] ) ){ 1093 foreach( $this->_capability['extensions'] as $ext){ 1094 if( trim( strtolower( $ext ) ) === trim( strtolower( $extension ) ) ) 1095 return true; 1096 } 1097 } 1098 return false; 1099 } 1100 1101 /** 1102 * Return the list of auth methods the server supports 1103 * 1104 * @return mixed array on success, PEAR_Error on failure 1105 */ 1106 function getAuthMechs() 1107 { 1108 if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) { 1109 $msg='Not currently connected'; 1110 $code=7; 1111 return $this->_raiseError($msg,$code); 1112 } 1113 if(!isset($this->_capability['sasl']) ){ 1114 $this->_capability['sasl']=array(); 1115 } 1116 return $this->_capability['sasl']; 1117 } 1118 1119 /** 1120 * Return true if the server has that extension 1121 * 1122 * @param string the extension to compare 1123 * @return mixed array on success, PEAR_Error on failure 1124 */ 1125 function hasAuthMech($method) 1126 { 1127 if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) { 1128 $msg='Not currently connected'; 1129 $code=7; 1130 return $this->_raiseError($msg,$code); 1131 //return PEAR::raiseError('Not currently connected'); 1132 } 1133 1134 if(is_array($this->_capability['sasl'] ) ){ 1135 foreach( $this->_capability['sasl'] as $ext){ 1136 if( trim( strtolower( $ext ) ) === trim( strtolower( $method ) ) ) 1137 return true; 1138 } 1139 } 1140 return false; 1141 } 1142 1143 /** 1144 * Return true if the TLS negotiation was successful 1145 * 1146 * @access private 1147 * @return mixed true on success, PEAR_Error on failure 1148 */ 1110 1111 if (!$methods || !$serverMethods) { 1112 return PEAR::raiseError( 1113 'This server doesn\'t support any authentication methods.' 1114 ); 1115 } 1116 1117 foreach ($methods as $method) { 1118 if (in_array($method, $serverMethods)) { 1119 return $method; 1120 } 1121 } 1122 1123 return PEAR::raiseError( 1124 'No supported authentication method found. The server supports these methods: ' 1125 . implode(',', $serverMethods) 1126 . ', but we only support: ' 1127 . implode(',', $this->supportedAuthMethods) 1128 ); 1129 } 1130 1131 /** 1132 * Starts a TLS connection. 1133 * 1134 * @return boolean True on success, PEAR_Error on failure. 1135 */ 1149 1136 function _startTLS() 1150 1137 { 1151 if (PEAR::isError($res = $this->_doCmd( "STARTTLS"))) {1138 if (PEAR::isError($res = $this->_doCmd('STARTTLS'))) { 1152 1139 return $res; 1153 1140 } 1154 1141 1155 if(stream_socket_enable_crypto($this->_sock->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT) == false) { 1156 $msg='Failed to establish TLS connection'; 1157 $code=2; 1158 return $this->_raiseError($msg,$code); 1159 } 1160 1161 if($this->_debug === true) { 1162 echo "STARTTLS Negotiation Successful\n"; 1163 } 1142 if (!stream_socket_enable_crypto($this->_sock->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { 1143 return PEAR::raiseError('Failed to establish TLS connection', 2); 1144 } 1145 1146 $this->_debug('STARTTLS negotiation successful'); 1164 1147 1165 1148 // The server should be sending a CAPABILITY response after … … 1167 1150 $this->_doCmd(); 1168 1151 1169 // RFC says we need to query the server capabilities again now that 1170 // we are under encryption1171 if (PEAR::isError($res = $this->_cmdCapability())) {1172 $msg='Failed to connect, server said: ' . $res->getMessage();1173 $code=2;1174 return $this->_raiseError($msg,$code);1152 // RFC says we need to query the server capabilities again now that we 1153 // are under encryption. 1154 if (PEAR::isError($res = $this->_cmdCapability())) { 1155 return PEAR::raiseError( 1156 'Failed to connect, server said: ' . $res->getMessage(), 2 1157 ); 1175 1158 } 1176 1159 … … 1178 1161 } 1179 1162 1180 function _getLineLength($string) { 1181 if (extension_loaded('mbstring') || @dl(PHP_SHLIB_PREFIX.'mbstring.'.PHP_SHLIB_SUFFIX)) { 1182 return mb_strlen($string,'latin1'); 1163 /** 1164 * Returns the length of a string. 1165 * 1166 * @param string $string A string. 1167 * 1168 * @return integer The length of the string. 1169 */ 1170 function _getLineLength($string) 1171 { 1172 if (extension_loaded('mbstring') 1173 || @dl(PHP_SHLIB_PREFIX . 'mbstring.' . PHP_SHLIB_SUFFIX) 1174 ) { 1175 return mb_strlen($string, 'latin1'); 1183 1176 } else { 1184 return strlen($string); 1177 return strlen($string); 1178 } 1179 } 1180 1181 /** 1182 * Locale independant strtoupper() implementation. 1183 * 1184 * @param string $string The string to convert to lowercase. 1185 * 1186 * @return string The lowercased string, based on ASCII encoding. 1187 */ 1188 function _toUpper($string) 1189 { 1190 $language = setlocale(LC_CTYPE, 0); 1191 setlocale(LC_CTYPE, 'C'); 1192 $string = strtoupper($string); 1193 setlocale(LC_CTYPE, $language); 1194 return $string; 1195 } 1196 1197 /** 1198 * Write debug text to the current debug output handler. 1199 * 1200 * @param string $message Debug message text. 1201 * 1202 * @return void 1203 */ 1204 function _debug($message) 1205 { 1206 if ($this->_debug) { 1207 if ($this->_debug_handler) { 1208 call_user_func_array($this->_debug_handler, array(&$this, $message)); 1209 } else { 1210 echo "$message\n"; 1211 } 1185 1212 } 1186 1213 } 1187 1214 } 1188 ?> -
trunk/roundcubemail/plugins/managesieve/lib/rcube_sieve.php
r2970 r3085 17 17 define('SIEVE_ERROR_INSTALL', 4); // script installation 18 18 define('SIEVE_ERROR_ACTIVATE', 5); // script activation 19 define('SIEVE_ERROR_DELETE', 6); // script deletion 20 define('SIEVE_ERROR_INTERNAL', 7); // internal error 19 21 define('SIEVE_ERROR_OTHER', 255); // other/unknown error 20 22 … … 22 24 class rcube_sieve 23 25 { 24 var $sieve; // Net_Sieve object 25 var $error = false; // error flag 26 var $list = array(); // scripts list 27 28 public $script; // rcube_sieve_script object 29 private $disabled; // array of disabled extensions 30 31 /** 26 private $sieve; // Net_Sieve object 27 private $error = false; // error flag 28 private $list = array(); // scripts list 29 30 public $script; // rcube_sieve_script object 31 public $current; // name of currently loaded script 32 private $disabled; // array of disabled extensions 33 34 /** 32 35 * Object constructor 33 36 * … … 39 42 * @param array Disabled extensions 40 43 */ 41 public function __construct($username, $password='', $host='localhost', $port=2000, $usetls=true, $disabled=array()) 42 { 43 $this->sieve = new Net_Sieve(); 44 45 // $this->sieve->setDebug(); 46 if (PEAR::isError($this->sieve->connect($host, $port, NULL, $usetls))) 47 return $this->_set_error(SIEVE_ERROR_CONNECTION); 48 49 if (PEAR::isError($this->sieve->login($username, $password))) 50 return $this->_set_error(SIEVE_ERROR_LOGIN); 51 52 $this->disabled = $disabled; 53 $this->_get_script(); 54 } 55 56 /** 44 public function __construct($username, $password='', $host='localhost', $port=2000, 45 $usetls=true, $disabled=array(), $debug=false) 46 { 47 $this->sieve = new Net_Sieve(); 48 49 if ($debug) 50 $this->sieve->setDebug(true, array($this, 'debug_handler')); 51 52 if (PEAR::isError($this->sieve->connect($host, $port, NULL, $usetls))) 53 return $this->_set_error(SIEVE_ERROR_CONNECTION); 54 55 if (PEAR::isError($this->sieve->login($username, $password))) 56 return $this->_set_error(SIEVE_ERROR_LOGIN); 57 58 $this->disabled = $disabled; 59 } 60 61 /** 57 62 * Getter for error code 58 63 */ 59 public function error()60 { 61 return $this->error ? $this->error : false;64 public function error() 65 { 66 return $this->error ? $this->error : false; 62 67 } 63 68 64 public function save() 65 { 66 $script = $this->script->as_text(); 67 68 if (!$script) 69 $script = '/* empty script */'; 70 71 if (PEAR::isError($this->sieve->installScript('roundcube', $script))) 72 return $this->_set_error(SIEVE_ERROR_INSTALL); 73 74 if (PEAR::isError($this->sieve->setActive('roundcube'))) 75 return $this->_set_error(SIEVE_ERROR_ACTIVATE); 76 77 return true; 78 } 79 80 public function get_extensions() 81 { 82 if ($this->sieve) { 69 /** 70 * Saves current script into server 71 */ 72 public function save($name = null) 73 { 74 if (!$this->sieve) 75 return $this->_set_error(SIEVE_ERROR_INTERNAL); 76 77 if (!$this->script) 78 return $this->_set_error(SIEVE_ERROR_INTERNAL); 79 80 if (!$name) 81 $name = $this->current; 82 83 $script = $this->script->as_text(); 84 85 if (!$script) 86 $script = '/* empty script */'; 87 88 if (PEAR::isError($this->sieve->installScript($name, $script))) 89 return $this->_set_error(SIEVE_ERROR_INSTALL); 90 91 return true; 92 } 93 94 /** 95 * Saves text script into server 96 */ 97 public function save_script($name, $content = null) 98 { 99 if (!$this->sieve) 100 return $this->_set_error(SIEVE_ERROR_INTERNAL); 101 102 if (!$content) 103 $content = '/* empty script */'; 104 105 if (PEAR::isError($this->sieve->installScript($name, $content))) 106 return $this->_set_error(SIEVE_ERROR_INSTALL); 107 108 return true; 109 } 110 111 /** 112 * Activates specified script 113 */ 114 public function activate($name = null) 115 { 116 if (!$this->sieve) 117 return $this->_set_error(SIEVE_ERROR_INTERNAL); 118 119 if (!$name) 120 $name = $this->current; 121 122 if (PEAR::isError($this->sieve->setActive($name))) 123 return $this->_set_error(SIEVE_ERROR_ACTIVATE); 124 125 return true; 126 } 127 128 /** 129 * Removes specified script 130 */ 131 public function remove($name = null) 132 { 133 if (!$this->sieve) 134 return $this->_set_error(SIEVE_ERROR_INTERNAL); 135 136 if (!$name) 137 $name = $this->current; 138 139 // script must be deactivated first 140 if ($name == $this->sieve->getActive()) 141 if (PEAR::isError($this->sieve->setActive(''))) 142 return $this->_set_error(SIEVE_ERROR_DELETE); 143 144 if (PEAR::isError($this->sieve->removeScript($name))) 145 return $this->_set_error(SIEVE_ERROR_DELETE); 146 147 if ($name == $this->current) 148 $this->current = null; 149 150 return true; 151 } 152 153 /** 154 * Gets list of supported by server Sieve extensions 155 */ 156 public function get_extensions() 157 { 158 if (!$this->sieve) 159 return $this->_set_error(SIEVE_ERROR_INTERNAL); 160 83 161 $ext = $this->sieve->getExtensions(); 162 // we're working on lower-cased names 163 $ext = array_map('strtolower', (array) $ext); 84 164 85 165 if ($this->script) { 86 $supported = $this->script->get_extensions(); 87 foreach ($ext as $idx => $ext_name) 88 if (!in_array($ext_name, $supported)) 89 unset($ext[$idx]); 90 } 91 92 return array_values($ext); 93 } 94 } 95 96 private function _get_script() 97 { 98 if (!$this->sieve) 166 $supported = $this->script->get_extensions(); 167 foreach ($ext as $idx => $ext_name) 168 if (!in_array($ext_name, $supported)) 169 unset($ext[$idx]); 170 } 171 172 return array_values($ext); 173 } 174 175 /** 176 * Gets list of scripts from server 177 */ 178 public function get_scripts() 179 { 180 if (!$this->list) { 181 182 if (!$this->sieve) 183 return $this->_set_error(SIEVE_ERROR_INTERNAL); 184 185 $this->list = $this->sieve->listScripts(); 186 187 if (PEAR::isError($this->list)) 188 return $this->_set_error(SIEVE_ERROR_OTHER); 189 } 190 191 return $this->list; 192 } 193 194 /** 195 * Returns active script name 196 */ 197 public function get_active() 198 { 199 if (!$this->sieve) 200 return $this->_set_error(SIEVE_ERROR_INTERNAL); 201 202 return $this->sieve->getActive(); 203 } 204 205 /** 206 * Loads script by name 207 */ 208 public function load($name) 209 { 210 if (!$this->sieve) 211 return $this->_set_error(SIEVE_ERROR_INTERNAL); 212 213 if ($this->current == $name) 214 return true; 215 216 $script = $this->sieve->getScript($name); 217 218 if (PEAR::isError($script)) 219 return $this->_set_error(SIEVE_ERROR_OTHER); 220 221 // try to parse from Roundcube format 222 $this->script = new rcube_sieve_script($script, $this->disabled); 223 224 // ... else try Squirrelmail format 225 if (empty($this->script->content) && $name == 'phpscript') { 226 227 $script = $this->sieve->getScript('phpscript'); 228 $script = $this->_convert_from_squirrel_rules($script); 229 230 $this->script = new rcube_sieve_script($script, $this->disabled); 231 } 232 233 $this->current = $name; 234 235 return true; 236 } 237 238 /** 239 * Creates empty script or copy of other script 240 */ 241 public function copy($name, $copy) 242 { 243 if (!$this->sieve) 244 return $this->_set_error(SIEVE_ERROR_INTERNAL); 245 246 if ($copy) { 247 $content = $this->sieve->getScript($copy); 248 249 if (PEAR::isError($content)) 250 return $this->_set_error(SIEVE_ERROR_OTHER); 251 } 252 253 return $this->save_script($name, $content); 254 } 255 256 257 private function _convert_from_squirrel_rules($script) 258 { 259 $i = 0; 260 $name = array(); 261 262 // tokenize rules 263 if ($tokens = preg_split('/(#START_SIEVE_RULE.*END_SIEVE_RULE)\n/', $script, -1, PREG_SPLIT_DELIM_CAPTURE)) 264 foreach($tokens as $token) { 265 if (preg_match('/^#START_SIEVE_RULE.*/', $token, $matches)) { 266 $name[$i] = "unnamed rule ".($i+1); 267 $content .= "# rule:[".$name[$i]."]\n"; 268 } 269 elseif (isset($name[$i])) { 270 $content .= "if $token\n"; 271 $i++; 272 } 273 } 274 275 return $content; 276 } 277 278 private function _set_error($error) 279 { 280 $this->error = $error; 99 281 return false; 100 101 $this->list = $this->sieve->listScripts(); 102 103 if (PEAR::isError($this->list)) 104 return $this->_set_error(SIEVE_ERROR_OTHER); 105 106 if (in_array('roundcube', $this->list)) 107 { 108 $script = $this->sieve->getScript('roundcube'); 109 110 if (PEAR::isError($script)) 111 return $this->_set_error(SIEVE_ERROR_OTHER); 112 } 113 // import scripts from squirrelmail 114 elseif (in_array('phpscript', $this->list)) 115 { 116 $script = $this->sieve->getScript('phpscript'); 117 118 $script = $this->_convert_from_squirrel_rules($script); 119 120 $this->script = new rcube_sieve_script($script, $this->disabled); 121 122 $this->save(); 123 124 $script = $this->sieve->getScript('roundcube'); 125 126 if (PEAR::isError($script)) 127 return $this->_set_error(SIEVE_ERROR_OTHER); 128 } 129 else 130 { 131 $this->_set_error(SIEVE_ERROR_NOT_EXISTS); 132 $script = ''; 133 } 134 135 $this->script = new rcube_sieve_script($script, $this->disabled); 136 } 137 138 private function _convert_from_squirrel_rules($script) 139 { 140 $i = 0; 141 $name = array(); 142 // tokenize rules 143 if ($tokens = preg_split('/(#START_SIEVE_RULE.*END_SIEVE_RULE)\n/', $script, -1, PREG_SPLIT_DELIM_CAPTURE)) 144 foreach($tokens as $token) 145 { 146 if (preg_match('/^#START_SIEVE_RULE.*/', $token, $matches)) 147 { 148 $name[$i] = "unnamed rule ".($i+1); 149 $content .= "# rule:[".$name[$i]."]\n"; 150 } 151 elseif (isset($name[$i])) 152 { 153 $content .= "if ".$token."\n"; 154 $i++; 155 } 156 } 157 158 return $content; 159 } 160 161 162 private function _set_error($error) 163 { 164 $this->error = $error; 165 return false; 166 } 282 } 283 284 /** 285 * This is our own debug handler for connection 286 * @access public 287 */ 288 public function debug_handler(&$sieve, $message) 289 { 290 write_log('sieve', preg_replace('/\r\n$/', '', $message)); 291 } 167 292 } 168 293 169 294 class rcube_sieve_script 170 295 { 171 var$content = array(); // script rules array296 public $content = array(); // script rules array 172 297 173 298 private $supported = array( // extensions supported by class -
trunk/roundcubemail/plugins/managesieve/localization/bg_BG.inc
r2510 r3085 43 43 $messages['filterdeleteerror'] = 'ÐевÑзЌПжМПÑÑ Ð·Ð° ОзÑÑОваМе Ма ÑОлÑÑÑ. СÑÑвÑÑ Ð³ÑеÑка'; 44 44 $messages['filterdeleted'] = 'ЀОлÑÑÑÑÑ Ðµ ОзÑÑÐžÑ ÑÑпеÑМП'; 45 $messages['filter confirmdelete'] = 'ÐаОÑÑОМа лО ОÑкаÑе Ўа ОзÑÑОеÑе ОзбÑÐ°ÐœÐžÑ ÑОлÑÑÑ?';45 $messages['filterdeleteconfirm'] = 'ÐаОÑÑОМа лО ОÑкаÑе Ўа ОзÑÑОеÑе ОзбÑÐ°ÐœÐžÑ ÑОлÑÑÑ?'; 46 46 $messages['filtersaved'] = 'ЀОлÑÑÑÑÑ Ðµ запОÑаМ ÑÑпеÑМП'; 47 47 $messages['filtersaveerror'] = 'ЀОлÑÑÑÑÑ ÐœÐµ ЌПже Ўа бÑЎе запОÑаМ. СÑÑвÑÑ Ð³ÑеÑка.'; -
trunk/roundcubemail/plugins/managesieve/localization/cs_CZ.inc
r3000 r3085 51 51 $messages['filterdeleteerror'] = 'Nebylo moşné smazat filtr. Server nahlásil chybu'; 52 52 $messages['filterdeleted'] = 'Filtr byl smazán'; 53 $messages['filter confirmdelete'] = 'Opravdu chcete smazat vybranÜ filtr?';53 $messages['filterdeleteconfirm'] = 'Opravdu chcete smazat vybranÜ filtr?'; 54 54 $messages['filtersaved'] = 'Filtr byl uloşen'; 55 55 $messages['filtersaveerror'] = 'Nebylo moşné uloşit filtr. Server nahlásil chybu.'; -
trunk/roundcubemail/plugins/managesieve/localization/de_CH.inc
r2539 r3085 42 42 $messages['filterdeleteerror'] = 'Fehler beim des löschen Filters. Serverfehler'; 43 43 $messages['filterdeleted'] = 'Filter erfolgreich gelöscht'; 44 $messages['filter confirmdelete'] = 'Möchten Sie den Filter löschen ?';44 $messages['filterdeleteconfirm'] = 'Möchten Sie den Filter löschen ?'; 45 45 $messages['filtersaved'] = 'Filter gespeichert'; 46 46 $messages['filtersaveerror'] = 'Serverfehler, konnte den Filter nicht speichern.'; -
trunk/roundcubemail/plugins/managesieve/localization/de_DE.inc
r2964 r3085 43 43 $messages['filterdeleteerror'] = 'Fehler beim Löschen des Filters. Serverfehler'; 44 44 $messages['filterdeleted'] = 'Filter erfolgreich gelöscht'; 45 $messages['filter confirmdelete'] = 'Möchten Sie den Filter löschen?';45 $messages['filterdeleteconfirm'] = 'Möchten Sie den Filter löschen?'; 46 46 $messages['filtersaved'] = 'Filter gespeichert'; 47 47 $messages['filtersaveerror'] = 'Serverfehler, konnte den Filter nicht speichern.'; -
trunk/roundcubemail/plugins/managesieve/localization/en_GB.inc
r3031 r3085 43 43 $messages['filterdeleteerror'] = 'Unable to delete filter. Server error occured'; 44 44 $messages['filterdeleted'] = 'Filter deleted successfully'; 45 $messages['filter confirmdelete'] = 'Do you really want to delete selected filter?';45 $messages['filterdeleteconfirm'] = 'Do you really want to delete selected filter?'; 46 46 $messages['filtersaved'] = 'Filter saved successfully'; 47 47 $messages['filtersaveerror'] = 'Unable to save filter. Server error occured.'; -
trunk/roundcubemail/plugins/managesieve/localization/en_US.inc
r2510 r3085 37 37 $labels['vacationreason'] = 'Message body (vacation reason):'; 38 38 $labels['rulestop'] = 'Stop evaluating rules'; 39 $labels['filterset'] = 'Filters set'; 40 $labels['filtersetadd'] = 'Add filters set'; 41 $labels['filtersetdel'] = 'Delete current filters set'; 42 $labels['filtersetact'] = 'Activate current filters set'; 43 $labels['filterdef'] = 'Filter definition'; 44 $labels['filtersetname'] = 'Filters set name'; 45 $labels['newfilterset'] = 'New filters set'; 46 $labels['active'] = 'active'; 47 $labels['copyfromset'] = 'Copy filters from set'; 48 $labels['none'] = '- none -'; 39 49 40 50 $messages = array(); … … 43 53 $messages['filterdeleteerror'] = 'Unable to delete filter. Server error occured'; 44 54 $messages['filterdeleted'] = 'Filter deleted successfully'; 45 $messages['filterconfirmdelete'] = 'Do you really want to delete selected filter?';46 55 $messages['filtersaved'] = 'Filter saved successfully'; 47 $messages['filtersaveerror'] = 'Unable to save filter. Server error occured.'; 56 $messages['filtersaveerror'] = 'Unable to save filter. Server error occured'; 57 $messages['filterdeleteconfirm'] = 'Do you really want to delete selected filter?'; 48 58 $messages['ruledeleteconfirm'] = 'Are you sure, you want to delete selected rule?'; 49 59 $messages['actiondeleteconfirm'] = 'Are you sure, you want to delete selected action?'; 50 60 $messages['forbiddenchars'] = 'Forbidden characters in field'; 51 61 $messages['cannotbeempty'] = 'Field cannot be empty'; 62 $messages['setactivateerror'] = 'Unable to activate selected filters set. Server error occured'; 63 $messages['setdeleteerror'] = 'Unable to delete selected filters set. Server error occured'; 64 $messages['setactivated'] = 'Filters set activated successfully'; 65 $messages['setdeleted'] = 'Filters set deleted successfully'; 66 $messages['setdeleteconfirm'] = 'Are you sure, you want to delete selected filters set?'; 67 $messages['setcreateerror'] = 'Unable to create filters set. Server error occured'; 68 $messages['setcreated'] = 'Filters set created successfully'; 69 $messages['emptyname'] = 'Unable to create filters set. Empty set name'; 70 $messages['nametoolong'] = 'Unable to create filters set. Name too long' 52 71 53 72 ?> -
trunk/roundcubemail/plugins/managesieve/localization/es_ES.inc
r2865 r3085 44 44 $messages['filterdeleteerror'] = 'Imposible borrar filtro. Ha ocurrido un error en el servidor'; 45 45 $messages['filterdeleted'] = 'Filtro borrado satisfactoriamente'; 46 $messages['filter confirmdelete'] = '¿Realmente desea borrar el filtro seleccionado?';46 $messages['filterdeleteconfirm'] = '¿Realmente desea borrar el filtro seleccionado?'; 47 47 $messages['filtersaved'] = 'Filtro guardado satisfactoriamente'; 48 48 $messages['filtersaveerror'] = 'Imposible guardar ell filtro. Ha ocurrido un error en el servidor'; -
trunk/roundcubemail/plugins/managesieve/localization/et_EE.inc
r2827 r3085 43 43 $messages['filterdeleteerror'] = 'Filtri kustutamine nurjus. Ilmnes serveri tõrge.'; 44 44 $messages['filterdeleted'] = 'Filter edukalt kustutatud'; 45 $messages['filter confirmdelete'] = 'Soovid valitud filtri kustutada?';45 $messages['filterdeleteconfirm'] = 'Soovid valitud filtri kustutada?'; 46 46 $messages['filtersaved'] = 'Filter edukalt salvestatud'; 47 47 $messages['filtersaveerror'] = 'Filtri salvestamine nurjus. Ilmnes serveri tõrge.'; -
trunk/roundcubemail/plugins/managesieve/localization/fi_FI.inc
r2510 r3085 39 39 $messages['filterdeleteerror'] = 'Suodattimen poistaminen epÀonnistui. Palvelin virhe'; 40 40 $messages['filterdeleted'] = 'Suodatin poistettu'; 41 $messages['filter confirmdelete'] = 'Haluatko varmasti poistaa valitut suodattimet?';41 $messages['filterdeleteconfirm'] = 'Haluatko varmasti poistaa valitut suodattimet?'; 42 42 $messages['filtersaved'] = 'Suodatin tallennettu'; 43 43 $messages['filtersaveerror'] = 'Suodattimen tallennus epÀonnistui. Palvelin virhe'; -
trunk/roundcubemail/plugins/managesieve/localization/fr_FR.inc
r2510 r3085 43 43 $messages['filterdeleteerror'] = 'Suppression du filtre impossible. Le serveur à produit une erreur'; 44 44 $messages['filterdeleted'] = 'Le filtre a bien été supprimé'; 45 $messages['filter confirmdelete'] = 'Voulez-vous vraiment supprimer le filtre sélectionné?';45 $messages['filterdeleteconfirm'] = 'Voulez-vous vraiment supprimer le filtre sélectionné?'; 46 46 $messages['filtersaved'] = 'Le filtre a bien été enregistré'; 47 47 $messages['filtersaveerror'] = 'Enregistrement du filtre impossibe. Le serveur à produit une erreur'; -
trunk/roundcubemail/plugins/managesieve/localization/hu_HU.inc
r2510 r3085 44 44 $messages['filterdeleteerror'] = 'A szűrÅt nem lehet törölni, szerverhiba történt'; 45 45 $messages['filterdeleted'] = 'A szűrÅ törlése sikeres'; 46 $messages['filter confirmdelete'] = 'Biztosan törli ezt a szűrÅt?';46 $messages['filterdeleteconfirm'] = 'Biztosan törli ezt a szűrÅt?'; 47 47 $messages['filtersaved'] = 'A szűrÅ mentése sikeres'; 48 48 $messages['filtersaveerror'] = 'A szűrÅ mentése sikertelen, szerverhiba történt'; -
trunk/roundcubemail/plugins/managesieve/localization/it_IT.inc
r2641 r3085 44 44 $messages['filterdeleteerror'] = 'Eliminazione del filtro fallita. Si Ú verificato un errore nel server'; 45 45 $messages['filterdeleted'] = 'Filtro eliminato con successo'; 46 $messages['filter confirmdelete'] = 'Vuoi veramente eliminare il filtro selezionato?';46 $messages['filterdeleteconfirm'] = 'Vuoi veramente eliminare il filtro selezionato?'; 47 47 $messages['filtersaved'] = 'Filtro salvato con successo'; 48 48 $messages['filtersaveerror'] = 'Salvataggio del filtro fallito. Si Ú verificato un errore nel server'; -
trunk/roundcubemail/plugins/managesieve/localization/nl_NL.inc
r2886 r3085 39 39 $messages['filterdeleteerror'] = 'Kan filter niet verwijderen. Er is een fout opgetreden'; 40 40 $messages['filterdeleted'] = 'Filter succesvol verwijderd'; 41 $messages['filter confirmdelete'] = 'Weet je zeker dat je het geselecteerde filter wilt verwijderen?';41 $messages['filterdeleteconfirm'] = 'Weet je zeker dat je het geselecteerde filter wilt verwijderen?'; 42 42 $messages['filtersaved'] = 'Filter succesvol opgeslagen'; 43 43 $messages['filtersaveerror'] = 'Kan filter niet opslaan. Er is een fout opgetreden.'; -
trunk/roundcubemail/plugins/managesieve/localization/pl_PL.inc
r2641 r3085 45 45 $labels['vacationaddresses'] = 'Lista dodatkowych adresów odbiorców (oddzielonych przecinkami):'; 46 46 $labels['vacationreason'] = 'TreÅÄ (przyczyna nieobecnoÅci):'; 47 $labels['filterset'] = 'Zbiór filtrów'; 48 $labels['filtersetadd'] = 'Dodaj zbiór filtrów'; 49 $labels['filtersetdel'] = 'UsuÅ bierzÄ 50 cy zbiór filtrów'; 51 $labels['filtersetact'] = 'Aktywuj bierzÄ 52 cy zbiór filtrów'; 53 $labels['filterdef'] = 'Definicja filtra'; 54 $labels['filtersetname'] = 'Nazwa zbioru filtrów'; 55 $labels['newfilterset'] = 'Nowy zbiór filtrów'; 56 $labels['active'] = 'aktywny'; 57 $labels['copyfromset'] = 'Skopiuj filtry ze zbioru'; 58 $labels['none'] = '- brak -'; 47 59 48 60 $messages = array(); … … 57 69 d serwera'; 58 70 $messages['filterdeleted'] = 'Filtr zostaÅ usuniÄty pomyÅlnie'; 59 $messages['filter confirmdelete'] = 'Czy na pewno chcesz usunÄ71 $messages['filterdeleteconfirm'] = 'Czy na pewno chcesz usunÄ 60 72 Ä wybrany filtr?'; 61 73 $messages['filtersaved'] = 'Filtr zostaÅ zapisany pomyÅlnie'; … … 71 83 $messages['forbiddenchars'] = 'Pole zawiera niedozwolone znaki'; 72 84 $messages['cannotbeempty'] = 'Pole nie moÅŒe byÄ puste'; 85 $messages['setactivateerror'] = 'Nie moÅŒna aktywowaÄ wybranego zbioru filtrów. BÅÄ 86 d serwera'; 87 $messages['setdeleteerror'] = 'Nie moÅŒna usunÄ 88 Ä wybranego zbioru filtrów. BÅÄ 89 d serwera'; 90 $messages['setactivated'] = 'Zbiór filtrów zostaÅ aktywowany pomyÅlnie'; 91 $messages['setdeleted'] = 'Zbiór filtrów zostaÅ usuniÄty pomyÅlnie'; 92 $messages['setdeleteconfirm'] = 'Czy na pewno chcesz usunÄ 93 Ä wybrany zbiór filtrów?'; 94 $messages['setcreateerror'] = 'Nie moÅŒna utworzyÄ zbioru filtrów. BÅÄ 95 d serwera'; 96 $messages['setcreated'] = 'Zbiór filtrów zostaÅ utworzony pomyÅlnie'; 97 $messages['emptyname'] = 'Nie moÅŒna utworzyÄ zbioru filtrów. Pusta nazwa zbioru'; 98 $messages['nametoolong'] = 'Nie moÅŒna utworzyÄ zbioru filtrów. Nazwa zbyt dÅuga' 73 99 74 100 ?> -
trunk/roundcubemail/plugins/managesieve/localization/pt_BR.inc
r2715 r3085 43 43 $messages['filterdeleteerror'] = 'Não foi possÃvel excluir filtro. Occorreu um erro de servidor'; 44 44 $messages['filterdeleted'] = 'Filtro excluÃdo com sucesso'; 45 $messages['filter confirmdelete'] = 'Deseja realmente excluir o filtro selecionado?';45 $messages['filterdeleteconfirm'] = 'Deseja realmente excluir o filtro selecionado?'; 46 46 $messages['filtersaved'] = 'Filtro gravado com sucesso'; 47 47 $messages['filtersaveerror'] = 'Não foi possÃvel gravar filtro. Occoreu um erro de servidor.'; -
trunk/roundcubemail/plugins/managesieve/localization/ru_RU.inc
r3028 r3085 37 37 $labels['sender'] = 'ÐÑпÑавОÑелÑ'; 38 38 $labels['recipient'] = 'ÐПлÑÑаÑелÑ'; 39 $labels['vacationaddresses'] = 'СпОÑПк ЎПпПлМОÑелÑМÑÑ40 аЎÑеÑПв пПÑÑÑ (ÑазЎелÑММÑй запÑÑÑЌО):';41 $labels['vacationdays'] = 'Ðак ÑаÑÑП ПÑпÑавлÑÑÑ ÑППбÑеМОе (Ñаз в ÑкПлÑкП ЎМей):';42 $labels['vacationreason'] = 'ТекÑÑ ÑППбÑÐµÐœÐžÑ (пÑОÑÐžÐœÑ ÐŸÑÑÑÑÑÑвОÑ):';43 $labels['rulestop'] = 'Ðе ПбÑабаÑÑваÑÑ Ð¿ÐŸÑлеЎÑÑÑОе пÑавОла';44 39 45 40 $messages = array(); … … 48 43 $messages['filterdeleteerror'] = 'ÐевПзЌПжМП ÑЎалОÑÑ ÑОлÑÑÑ. ÐÑОбка ÑеÑвеÑа'; 49 44 $messages['filterdeleted'] = 'ЀОлÑÑÑ ÑÑпеÑМП ÑЎалÑМ'; 50 $messages['filter confirmdelete'] = 'ÐÑ ÐŽÐµÐ¹ÑÑвОÑелÑМП Ñ45 $messages['filterdeleteconfirm'] = 'ÐÑ ÐŽÐµÐ¹ÑÑвОÑелÑМП Ñ 51 46 ПÑОÑе ÑЎалОÑÑ ÑОлÑÑÑ?'; 52 47 $messages['filtersaved'] = 'ЀОлÑÑÑ ÑÑпеÑМП ÑÐŸÑ -
trunk/roundcubemail/plugins/managesieve/localization/sl_SI.inc
r2864 r3085 43 43 $messages['filterdeleteerror'] = 'Pravila ni bilo mogoÄe izbrisati. PriÅ¡lo je do napake.'; 44 44 $messages['filterdeleted'] = 'Pravilo je bilo uspeÅ¡no izbrisano.'; 45 $messages['filter confirmdelete'] = 'Ste prepriÄani, da ÅŸelite izbrisati izbrano pravilo?';45 $messages['filterdeleteconfirm'] = 'Ste prepriÄani, da ÅŸelite izbrisati izbrano pravilo?'; 46 46 $messages['filtersaved'] = 'Pravilo je bilo uspeÅ¡no shranjeno'; 47 47 $messages['filtersaveerror'] = 'Pravilo ni bilo shranjeno. PriÅ¡lo je do napake.'; -
trunk/roundcubemail/plugins/managesieve/localization/sv_SE.inc
r2510 r3085 44 44 $messages['filterdeleteerror'] = 'Filtret kunde inte tas bort på grund av serverfel'; 45 45 $messages['filterdeleted'] = 'Filtret Àr borttaget'; 46 $messages['filter confirmdelete'] = 'Vill du ta bort det markerade filtret?';46 $messages['filterdeleteconfirm'] = 'Vill du ta bort det markerade filtret?'; 47 47 $messages['filtersaved'] = 'Filtret har sparats'; 48 48 $messages['filtersaveerror'] = 'Filtret kunde inte sparas på grund av serverfel'; -
trunk/roundcubemail/plugins/managesieve/localization/uk_UA.inc
r2812 r3085 49 49 $messages['filterdeleteerror'] = 'ÐеЌПжлОвП вОЎалОÑО ÑÑлÑÑÑ. ÐПЌОлка ÑеÑвеÑа.'; 50 50 $messages['filterdeleted'] = 'ЀÑлÑÑÑ ÑÑпÑÑМП вОЎалеМП.'; 51 $messages['filter confirmdelete'] = 'ÐО ÐŽÑйÑМП Ñ51 $messages['filterdeleteconfirm'] = 'ÐО ÐŽÑйÑМП Ñ 52 52 ПÑеÑе вОЎалОÑО вОбÑаМОй ÑÑлÑÑÑ?'; 53 53 $messages['filtersaved'] = 'ЀÑлÑÑÑ ÑÑпÑÑМП збеÑежеМП.'; -
trunk/roundcubemail/plugins/managesieve/localization/zh_CN.inc
r2510 r3085 43 43 $messages['filterdeleteerror'] = 'æ æ³å é€è¿æ»€åšãæå¡åšé误'; 44 44 $messages['filterdeleted'] = 'è¿æ»€åšå·²æåå é€'; 45 $messages['filter confirmdelete'] = 'æšç¡®å®èŠå 逿鿩çè¿æ»€åšåïŒ';45 $messages['filterdeleteconfirm'] = 'æšç¡®å®èŠå 逿鿩çè¿æ»€åšåïŒ'; 46 46 $messages['filtersaved'] = 'è¿æ»€åšå·²æåä¿åã'; 47 47 $messages['filtersaveerror'] = 'æ æ³ä¿åè¿æ»€åšãæå¡åšé误'; -
trunk/roundcubemail/plugins/managesieve/managesieve.js
r2761 r3085 20 20 rcmail.register_command('plugin.managesieve-up', function() { rcmail.managesieve_up() }, true); 21 21 rcmail.register_command('plugin.managesieve-down', function() { rcmail.managesieve_down() }, true); 22 rcmail.register_command('plugin.managesieve-set', function() { rcmail.managesieve_set() }, true); 23 rcmail.register_command('plugin.managesieve-setadd', function() { rcmail.managesieve_setadd() }, true); 24 rcmail.register_command('plugin.managesieve-setdel', function() { rcmail.managesieve_setdel() }, true); 25 rcmail.register_command('plugin.managesieve-setact', function() { rcmail.managesieve_setact() }, true); 22 26 23 27 if (rcmail.env.action == 'plugin.managesieve') … … 26 30 rcmail.enable_command('plugin.managesieve-save', true); 27 31 else { 28 rcmail.enable_command('plugin.managesieve-del', 'plugin.managesieve-up', 'plugin.managesieve-down', false); 29 rcmail.enable_command('plugin.managesieve-add', !rcmail.env.sieveconnerror); 30 } 31 32 rcmail.enable_command('plugin.managesieve-del', 'plugin.managesieve-up', 33 'plugin.managesieve-down', false); 34 rcmail.enable_command('plugin.managesieve-add', 'plugin.managesieve-setadd', !rcmail.env.sieveconnerror); 35 rcmail.enable_command('plugin.managesieve-set', rcmail.gui_objects.filtersetslist != null); 36 rcmail.enable_command('plugin.managesieve-setact', 37 (rcmail.gui_objects.filtersetslist && rcmail.gui_objects.filtersetslist.value != rcmail.env.active_set)); 38 rcmail.enable_command('plugin.managesieve-setdel', 39 (rcmail.gui_objects.filtersetslist && rcmail.gui_objects.filtersetslist.length > 1)); 40 } 32 41 if (rcmail.gui_objects.filterslist) { 33 42 var p = rcmail; … … 54 63 var id = this.filters_list.get_single_selection(); 55 64 56 if (confirm(this.get_label('managesieve.filter confirmdelete')))65 if (confirm(this.get_label('managesieve.filterdeleteconfirm'))) 57 66 this.http_request('plugin.managesieve', 58 67 '_act=delete&_fid='+this.filters_list.rows[id].uid, true); … … 204 213 rcube_webmail.prototype.managesieve_save = function() 205 214 { 206 if (parent.rcmail && parent.rcmail.filters_list )215 if (parent.rcmail && parent.rcmail.filters_list && this.gui_objects.sieveform.name != 'filtersetform') 207 216 { 208 217 var id = parent.rcmail.filters_list.get_single_selection(); … … 379 388 } 380 389 } 390 391 // Set change 392 rcube_webmail.prototype.managesieve_set = function() 393 { 394 var script = $(this.gui_objects.filtersetslist).val(); 395 location.href = this.env.comm_path+'&_action=plugin.managesieve&_sid='+script; 396 }; 397 398 // Set activate 399 rcube_webmail.prototype.managesieve_setact = function() 400 { 401 if (!this.gui_objects.filtersetslist) 402 return false; 403 404 var script = this.gui_objects.filtersetslist.value; 405 this.http_post('plugin.managesieve', '_act=setact&_set='+script); 406 }; 407 408 // Set activate flag in sets list after set activation 409 rcube_webmail.prototype.managesieve_reset = function(name) 410 { 411 if (!this.gui_objects.filtersetslist || !name) 412 return false; 413 414 var opts = this.gui_objects.filtersetslist.getElementsByTagName('option'); 415 var regx = new RegExp(RegExp.escape(' (' + this.get_label('managesieve.active') + ')')); 416 417 for (var x=1; x<opts.length; x++) 418 if (opts[x].value != name && opts[x].innerHTML.match(regx)) 419 opts[x].innerHTML = opts[x].innerHTML.replace(regx, ''); 420 else if (opts[x].value == name) 421 opts[x].innerHTML = opts[x].innerHTML + ' (' + this.get_label('managesieve.active') + ')'; 422 }; 423 424 // Set delete 425 rcube_webmail.prototype.managesieve_setdel = function() 426 { 427 if (!this.gui_objects.filtersetslist) 428 return false; 429 430 if (!confirm(this.get_label('managesieve.setdeleteconfirm'))) 431 return false; 432 433 var script = this.gui_objects.filtersetslist.value; 434 this.http_post('plugin.managesieve', '_act=setdel&_set='+script); 435 }; 436 437 // Set add 438 rcube_webmail.prototype.managesieve_setadd = function() 439 { 440 this.filters_list.clear_selection(); 441 this.enable_command('plugin.managesieve-up', 'plugin.managesieve-down', 'plugin.managesieve-del', false); 442 443 if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) 444 { 445 target = window.frames[this.env.contentframe]; 446 this.set_busy(true, 'loading'); 447 target.location.href = this.env.comm_path+'&_action=plugin.managesieve&_framed=1&_newset=1'; 448 } 449 }; 450 451 452 rcube_webmail.prototype.managesieve_reload = function(set) 453 { 454 this.env.reload_set = set; 455 window.setTimeout(function() { 456 location.href = rcmail.env.comm_path + '&_action=plugin.managesieve' 457 + (rcmail.env.reload_set ? '&_sid=' + rcmail.env.reload_set : '') 458 }, 500); 459 }; 460 381 461 } -
trunk/roundcubemail/plugins/managesieve/managesieve.php
r3042 r3085 8 8 * with server using managesieve protocol. Adds Filters tab in Settings. 9 9 * 10 * @version 1.710 * @version 2.0 11 11 * @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl> 12 12 * … … 36 36 37 37 // register actions 38 $this->register_action('plugin.managesieve', array($this, 'managesieve_ init'));38 $this->register_action('plugin.managesieve', array($this, 'managesieve_actions')); 39 39 $this->register_action('plugin.managesieve-save', array($this, 'managesieve_save')); 40 40 … … 53 53 $this->rc->output->add_handlers(array( 54 54 'filterslist' => array($this, 'filters_list'), 55 'filtersetslist' => array($this, 'filtersets_list'), 55 56 'filterframe' => array($this, 'filter_frame'), 56 57 'filterform' => array($this, 'filter_form'), 58 'filtersetform' => array($this, 'filterset_form'), 57 59 )); 58 60 … … 66 68 $this->rc->config->get('managesieve_port', 2000), 67 69 $this->rc->config->get('managesieve_usetls', false), 68 $this->rc->config->get('managesieve_disabled_extensions')); 69 70 $error = $this->sieve->error(); 71 72 if ($error == SIEVE_ERROR_NOT_EXISTS) 70 $this->rc->config->get('managesieve_disabled_extensions'), 71 $this->rc->config->get('managesieve_debug', false) 72 ); 73 74 if (!($error = $this->sieve->error())) { 75 76 $list = $this->sieve->get_scripts(); 77 $active = $this->sieve->get_active(); 78 $_SESSION['managesieve_active'] = $active; 79 80 if (!empty($_GET['_sid'])) { 81 $script_name = get_input_value('_sid', RCUBE_INPUT_GET); 82 } else if (!empty($_SESSION['managesieve_current'])) { 83 $script_name = $_SESSION['managesieve_current']; 84 } else { 85 // get active script 86 if ($active) { 87 $script_name = $active; 88 } else if ($list) { 89 $script_name = $list[0]; 90 // create a new (initial) script 91 } else { 92 // if script not exists build default script contents 93 $script_file = $this->rc->config->get('managesieve_default'); 94 $script_name = 'roundcube'; 95 if ($script_file && is_readable($script_file)) 96 $content = file_get_contents($script_file); 97 98 // add script and set it active 99 if ($this->sieve->save_script($script_name, $content)) 100 if ($this->sieve->activate($script_name)) 101 $_SESSION['managesieve_active'] = $script_name; 102 } 103 } 104 105 if ($script_name) 106 $this->sieve->load($script_name); 107 108 $error = $this->sieve->error(); 109 } 110 111 // finally set script objects 112 if ($error) 73 113 { 74 // if script not exists build default script contents 75 $script_file = $this->rc->config->get('managesieve_default'); 76 if ($script_file && is_readable($script_file)) 77 $this->sieve->script->add_text(file_get_contents($script_file)); 78 // that's not exactly an error 79 $error = false; 80 } 81 elseif ($error) 82 { 83 switch ($error) 84 { 114 switch ($error) { 85 115 case SIEVE_ERROR_CONNECTION: 86 116 case SIEVE_ERROR_LOGIN: … … 91 121 break; 92 122 } 93 94 123 // to disable 'Add filter' button set env variable 95 124 $this->rc->output->set_env('filterconnerror', true); 96 }97 98 // finally set script objects99 if ($error)100 {101 125 $this->script = array(); 102 126 } … … 105 129 $this->script = $this->sieve->script->as_array(); 106 130 $this->exts = $this->sieve->get_extensions(); 131 $this->rc->output->set_env('active_set', $_SESSION['managesieve_active']); 132 $_SESSION['managesieve_current'] = $this->sieve->current; 107 133 } 108 134 … … 110 136 } 111 137 112 function managesieve_ init()138 function managesieve_actions() 113 139 { 114 140 // Init plugin and handle managesieve connection … … 135 161 } 136 162 } 137 else if ($action=='down' && !$error)163 else if ($action=='down' && !$error) 138 164 { 139 165 if (isset($this->script[$fid]) && isset($this->script[$fid+1])) … … 143 169 $result = $this->sieve->save(); 144 170 145 if ($result ) {171 if ($result === true) { 146 172 // $this->rc->output->show_message('managesieve.filtersaved', 'confirmation'); 147 173 $this->rc->output->command('managesieve_updatelist', 'down', '', $fid); 148 } else 174 } else { 149 175 $this->rc->output->show_message('managesieve.filtersaveerror', 'error'); 150 } 151 } 152 elseif ($action=='delete' && !$error) 176 } 177 } 178 } 179 else if ($action=='delete' && !$error) 153 180 { 154 181 if (isset($this->script[$fid])) … … 157 184 $result = $this->sieve->save(); 158 185 159 if (!$result) 160 $this->rc->output->show_message('managesieve.filterdeleteerror', 'error'); 161 else { 186 if ($result === true) { 162 187 $this->rc->output->show_message('managesieve.filterdeleted', 'confirmation'); 163 188 $this->rc->output->command('managesieve_updatelist', 'delete', '', $fid); 189 } else { 190 $this->rc->output->show_message('managesieve.filterdeleteerror', 'error'); 164 191 } 165 } 192 } 193 } 194 else if ($action=='setact' && !$error) 195 { 196 $script_name = get_input_value('_set', RCUBE_INPUT_GPC); 197 $result = $this->sieve->activate($script_name); 198 199 if ($result === true) { 200 $this->rc->output->set_env('active_set', $script_name); 201 $this->rc->output->show_message('managesieve.setactivated', 'confirmation'); 202 $this->rc->output->command('enable_command', 'plugin.managesieve-setact', false); 203 $this->rc->output->command('managesieve_reset', $script_name); 204 $_SESSION['managesieve_active'] = $script_name; 205 } else { 206 $this->rc->output->show_message('managesieve.setactivateerror', 'error'); 207 } 208 } 209 else if ($action=='setdel' && !$error) 210 { 211 $script_name = get_input_value('_set', RCUBE_INPUT_GPC); 212 $result = $this->sieve->remove($script_name); 213 214 if ($result === true) { 215 $this->rc->output->show_message('managesieve.setdeleted', 'confirmation'); 216 $this->rc->output->command('managesieve_reload'); 217 rcube_sess_unset('managesieve_current'); 218 } else { 219 $this->rc->output->show_message('managesieve.setdeleteerror', 'error'); 220 } 166 221 } 167 222 elseif ($action=='ruleadd') … … 193 248 $error = $this->managesieve_start(); 194 249 195 // add/edit action 196 if (isset($_POST['_name'])) 250 // filters set add action 251 if (!empty($_POST['_newset'])) 252 { 253 $name = get_input_value('_name', RCUBE_INPUT_GPC); 254 $copy = get_input_value('_copy', RCUBE_INPUT_GPC); 255 256 if (!$name) 257 $error = 'managesieve.emptyname'; 258 else if (mb_strlen($name)>128) 259 $error = 'managesieve.nametoolong'; 260 else if (!$this->sieve->copy($name, $copy)) 261 $error = 'managesieve.setcreateerror'; 262 263 if (!$error) { 264 $this->rc->output->show_message('managesieve.setcreated', 'confirmation'); 265 $this->rc->output->command('parent.managesieve_reload', $name); 266 // rcube_sess_unset('managesieve_current'); 267 } else { 268 $this->rc->output->show_message($error, 'error'); 269 } 270 } 271 // filter add/edit action 272 else if (isset($_POST['_name'])) 197 273 { 198 274 $name = trim(get_input_value('_name', RCUBE_INPUT_POST)); … … 423 499 { 424 500 // Handle form action 425 if (isset($_GET['_framed']) || isset($_POST['_framed'])) 426 $this->rc->output->send('managesieve.managesieveedit'); 427 else { 501 if (isset($_GET['_framed']) || isset($_POST['_framed'])) { 502 if (isset($_GET['_newset']) || isset($_POST['_newset'])) 503 $this->rc->output->send('managesieve.setedit'); 504 else 505 $this->rc->output->send('managesieve.filteredit'); 506 } else { 428 507 $this->rc->output->set_pagetitle($this->gettext('filters')); 429 508 $this->rc->output->send('managesieve.managesieve'); … … 452 531 453 532 // add some labels to client 454 $this->rc->output->add_label('managesieve.filterconfirmdelete'); 533 $this->rc->output->add_label('managesieve.filterdeleteconfirm'); 534 535 return $out; 536 } 537 538 // return the filters list as <SELECT> 539 function filtersets_list($attrib) 540 { 541 // add id to message list table if not specified 542 if (!strlen($attrib['id'])) 543 $attrib['id'] = 'rcmfiltersetslist'; 544 545 $list = $this->sieve->get_scripts(); 546 $active = $this->sieve->get_active(); 547 548 $select = new html_select(array('name' => '_set', 'id' => $attrib['id'], 'onchange' => 'rcmail.managesieve_set()')); 549 550 asort($list, SORT_LOCALE_STRING); 551 552 foreach($list as $set) 553 $select->add($set . ($set == $active ? ' ('.$this->gettext('active').')' : ''), $set); 554 555 $out = $select->show($this->sieve->current); 556 557 // set client env 558 $this->rc->output->add_gui_object('filtersetslist', $attrib['id']); 559 $this->rc->output->add_label('managesieve.setdeleteconfirm'); 560 $this->rc->output->add_label('managesieve.active'); 455 561 456 562 return $out; … … 466 572 $this->rc->output->set_env('contentframe', $attrib['name']); 467 573 $this->rc->output->set_env('blankpage', $attrib['src'] ? 468 $this->rc->output->abs_url($attrib['src']) : 'program/blank.gif');574 $this->rc->output->abs_url($attrib['src']) : 'program/blank.gif'); 469 575 470 576 return html::tag('iframe', $attrib); 577 } 578 579 580 function filterset_form($attrib) 581 { 582 if (!$attrib['id']) 583 $attrib['id'] = 'rcmfiltersetform'; 584 585 $out = '<form name="filtersetform" action="./" method="post">'."\n"; 586 587 $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $this->rc->task)); 588 $hiddenfields->add(array('name' => '_action', 'value' => 'plugin.managesieve-save')); 589 $hiddenfields->add(array('name' => '_framed', 'value' => ($_POST['_framed'] || $_GET['_framed'] ? 1 : 0))); 590 $hiddenfields->add(array('name' => '_newset', 'value' => 1)); 591 592 $out .= $hiddenfields->show(); 593 594 $name = get_input_value('_name', RCUBE_INPUT_GPC); 595 $copy = get_input_value('_copy', RCUBE_INPUT_GPC); 596 597 $table = new html_table(array('cols' => 2)); 598 599 // filter set name input 600 $input_name = new html_inputfield(array('name' => '_name', 'id' => '_name', 'size' => 30, 601 'class' => ($this->errors['name'] ? 'error' : ''))); 602 603 $table->add('title', sprintf('<label for="%s"><b>%s:</b></label>', '_name', Q($this->gettext('filtersetname')))); 604 $table->add(null, $input_name->show($name)); 605 606 // filters set list 607 $list = $this->sieve->get_scripts(); 608 $active = $this->sieve->get_active(); 609 610 $select = new html_select(array('name' => '_copy', 'id' => '_copy')); 611 612 asort($list, SORT_LOCALE_STRING); 613 614 $select->add($this->gettext('none'), ''); 615 foreach($list as $set) 616 $select->add($set . ($set == $active ? ' ('.$this->gettext('active').')' : ''), $set); 617 618 $table->add('title', '<label>'.$this->gettext('copyfromset').':</label>'); 619 $table->add(null, $select->show($copy)); 620 621 $out .= $table->show(); 622 623 $this->rc->output->add_gui_object('sieveform', 'filtersetform'); 624 625 return $out; 471 626 } 472 627 … … 819 974 private function check_email($email) 820 975 { 821 if (function_exists('check_email')); 976 if (function_exists('check_email')); 822 977 return check_email($email); 823 978 -
trunk/roundcubemail/plugins/managesieve/skins/default/managesieve.css
r2539 r3085 7 7 left: 20px; 8 8 width: 220px; 9 top: 1 30px;9 top: 120px; 10 10 bottom: 30px; 11 11 border: 1px solid #999999; … … 33 33 position: absolute; 34 34 left: 20px; 35 top: 95px; 35 top: 85px; 36 } 37 38 #filtersetsbuttons 39 { 40 position: absolute; 41 left: 250px; 42 top: 85px; 43 } 44 45 #filtersbuttons a, 46 #filtersetsbuttons a 47 { 48 display: block; 49 float: left; 50 } 51 52 #filtersbuttons a.button, 53 #filtersbuttons a.buttonPas, 54 #filtersetsbuttons a.button, 55 #filtersetsbuttons a.buttonPas 56 { 57 display: block; 58 float: left; 59 width: 32px; 60 height: 32px; 61 padding: 0; 62 margin-right: 3px; 63 overflow: hidden; 64 background: url('managesieve_toolbar.png') 0 0 no-repeat transparent; 65 opacity: 0.99; /* this is needed to make buttons appear correctly in Chrome */ 66 } 67 68 #filtersbuttons a.buttonPas, 69 #filtersetsbuttons a.buttonPas 70 { 71 filter: alpha(opacity=35); 72 opacity: 0.35; 73 } 74 75 #filtersbuttons a.add { 76 background-position: 0px 0px; 77 } 78 79 #filtersbuttons a.addsel { 80 background-position: 0 -32px; 81 } 82 83 #filtersbuttons a.del { 84 background-position: -32px 0px; 85 } 86 87 #filtersbuttons a.delsel { 88 background-position: -32px -32px; 89 } 90 91 #filtersbuttons a.up { 92 background-position: -64px 0px; 93 } 94 95 #filtersbuttons a.upsel { 96 background-position: -64px -32px; 97 } 98 99 #filtersbuttons a.down { 100 background-position: -96px 0px; 101 } 102 103 #filtersbuttons a.downsel { 104 background-position: -96px -32px; 105 } 106 107 #filtersetsbuttons a.setadd { 108 background-position: -128px 0px; 109 } 110 111 #filtersetsbuttons a.setaddsel { 112 background-position: -128px -32px; 113 } 114 115 #filtersetsbuttons a.setdel { 116 background-position: -160px 0px; 117 } 118 119 #filtersetsbuttons a.setdelsel { 120 background-position: -160px -32px; 121 } 122 123 #filtersetsbuttons a.setset { 124 background-position: -192px 0px; 125 } 126 127 #filtersetsbuttons a.setsetsel { 128 background-position: -192px -32px; 129 } 130 131 #filtersetselect 132 { 133 position: absolute; 134 left: 380px; 135 top: 90px; 36 136 } 37 137 … … 39 139 { 40 140 position: absolute; 41 top: 95px;141 top: 120px; 42 142 left: 250px; 43 143 right: 20px; … … 47 147 /* css hack for IE */ 48 148 width: expression((parseInt(document.documentElement.clientWidth)-30-parseInt(document.getElementById('filterslist').offsetLeft)-parseInt(document.getElementById('filterslist').offsetWidth))+'px'); 49 height: expression((parseInt(document.documentElement.clientHeight)-1 20)+'px');149 height: expression((parseInt(document.documentElement.clientHeight)-155)+'px'); 50 150 } 51 151 -
trunk/roundcubemail/plugins/managesieve/skins/default/templates/managesieve.html
r2552 r3085 14 14 15 15 <div id="filtersbuttons"> 16 <roundcube:button command="plugin.managesieve-add" imageSel="/this/filter_add_sel.png" imagePas="/this/filter_add_pas.png" imageAct="/this/filter_add_act.png" width="32" height="32" title="managesieve.filteradd" /> 17 <roundcube:button command="plugin.managesieve-del" imageSel="/this/filter_del_sel.png" imagePas="/this/filter_del_pas.png" imageAct="/this/filter_del_act.png" width="32" height="32" title="managesieve.filterdel" /> 18 <roundcube:button command="plugin.managesieve-up" imageSel="/this/filter_up_sel.png" imagePas="/this/filter_up_pas.png" imageAct="/this/filter_up_act.png" width="32" height="32" title="managesieve.moveup" /> 19 <roundcube:button command="plugin.managesieve-down" imageSel="/this/filter_down_sel.png" imagePas="/this/filter_down_pas.png" imageAct="/this/filter_down_act.png" width="32" height="32" title="managesieve.movedown" /> 16 <roundcube:button command="plugin.managesieve-add" type="link" class="buttonPas add" classSel="button addsel" classAct="button add" title="managesieve.filteradd" content=" " /> 17 <roundcube:button command="plugin.managesieve-del" type="link" class="buttonPas del" classSel="button delsel" classAct="button del" title="managesieve.filterdel" content=" " /> 18 <roundcube:button command="plugin.managesieve-up" type="link" class="buttonPas up" classSel="button upsel" classAct="button up" title="managesieve.moveup" content=" " /> 19 <roundcube:button command="plugin.managesieve-down" type="link" class="buttonPas down" classSel="button downsel" classAct="button down" title="managesieve.movedown" content=" " /> 20 </div> 21 22 <div id="filtersetsbuttons"> 23 <roundcube:button command="plugin.managesieve-setadd" type="link" class="buttonPas setadd" classSel="button setaddsel" classAct="button setadd" title="managesieve.filtersetadd" content=" " /> 24 <roundcube:button command="plugin.managesieve-setdel" type="link" class="buttonPas setdel" classSel="button setdelsel" classAct="button setdel" title="managesieve.filtersetdel" content=" " /> 25 <roundcube:button command="plugin.managesieve-setact" type="link" class="buttonPas setset" classSel="button setsetsel" classAct="button setset" title="managesieve.filtersetact" content=" " /> 26 </div> 27 <div id="filtersetselect"> 28 <roundcube:label name="managesieve.filterset" />: 29 <roundcube:object name="filtersetslist" id="filtersets-select" /> 20 30 </div> 21 31
Note: See TracChangeset
for help on using the changeset viewer.
