package.xml0000664000175000017500000042256213150761654011322 0ustar janjan Horde_Imap_Client pear.horde.org Horde IMAP Client Interface to access IMAP4rev1 (RFC 3501) mail servers. Also supports connections to POP3 (STD 53/RFC 1939). Michael Slusarz slusarz slusarz@horde.org yes 2017-08-28 2.29.15 2.29.0 stable stable LGPL-2.1 * [jan] Fix expunging cache entries of a certain lifetime from the DB backend. 5.3.0 8.0.0alpha1 8.0.0alpha1 1.7.0 Horde_Exception pear.horde.org 2.0.0 3.0.0alpha1 3.0.0alpha1 Horde_Mail pear.horde.org 2.0.0 3.0.0alpha1 3.0.0alpha1 Horde_Mime pear.horde.org 2.5.2 3.0.0alpha1 3.0.0alpha1 Horde_Socket_Client pear.horde.org 2.0.0 3.0.0alpha1 3.0.0alpha1 Horde_Stream pear.horde.org 1.4.0 2.0.0alpha1 2.0.0alpha1 Horde_Secret pear.horde.org 2.0.0 3.0.0alpha1 3.0.0alpha1 Horde_Stream_Filter pear.horde.org 2.0.0 3.0.0alpha1 3.0.0alpha1 Horde_Translation pear.horde.org 2.2.0 3.0.0alpha1 3.0.0alpha1 Horde_Util pear.horde.org 2.0.0 3.0.0alpha1 3.0.0alpha1 hash json Horde_Cache pear.horde.org 2.0.0 3.0.0alpha1 3.0.0alpha1 Horde_Compress_Fast pear.horde.org 1.0.0 2.0.0alpha1 2.0.0alpha1 Horde_Crypt_Blowfish pear.horde.org 1.1.0 2.0.0alpha1 2.0.0alpha1 Horde_Db pear.horde.org 2.2.0 3.0.0alpha1 3.0.0alpha1 Horde_HashTable pear.horde.org 1.0.0 2.0.0alpha1 2.0.0alpha1 Horde_Mongo pear.horde.org 1.0.0 2.0.0alpha1 2.0.0alpha1 Horde_Pack pear.horde.org 1.0.0 2.0.0alpha1 2.0.0alpha1 Horde_Stringprep pear.horde.org 1.0.0 2.0.0alpha1 2.0.0alpha1 Horde_Support pear.horde.org 2.0.0 3.0.0alpha1 3.0.0alpha1 Horde_Test pear.horde.org 2.2.7 3.0.0alpha1 3.0.0alpha1 intl mbstring 1.0.0alpha1 1.0.0 alpha alpha 2011-03-08 LGPL-2.1 * [mms] Add PHPUnit test framework. * [mms] Added constants for RFC-defined flags. * [mms] Supported finalized SPECIAL-USE capability (RFC 6154). * [mms] Add Horde_Imap_Client_Data_AclNegative object. * [mms] Add Horde_Imap_Client_Base#allAclRights(). * [mms] Add Horde_Imap_Client_Data_Acl and Horde_Imap_Client_Data_AclRights objects. * [mms] Horde_Imap_Client_Base#getNamespaces() now returns integer constants for the 'type' parameter. * [mms] Add Horde_Imap_Client_Data_Fetch data object. * [mms] Add Horde_Imap_Client_Ids data object. * [mms] Add Horde_Imap_Client_Fetch_Query data object. * [mms] Add Horde_Imap_Client_Data_Envelope data object. 1.0.0beta1 1.0.0 beta beta 2011-03-16 LGPL-2.1 * [mms] Fix client-side sorting using envelope data. * [mms] Workaround PHP < 5.2.6 (broken stream handling) (Bug #9644). * [mms] Add basic UTF7-IMAP conversion unit test. 1.0.0RC1 1.0.0 beta beta 2011-03-22 LGPL-2.1 * First release candidate for Horde 4. * [mms] Use UIDPLUS results to copy cached data to new mailbox when copying messags. * [mms] Fix fetching by sequence number when caching. 1.0.0RC2 1.0.0 beta beta 2011-03-29 LGPL-2.1 * Second release candidate for Horde 4. * [mms] Provide way to indicate mailboxes that should not have FETCH data cached. 1.0.0 1.0.0 stable stable 2011-04-06 LGPL-2.1 * First stable release for Horde 4. * [mms] Fixes for IMAP servers that support CONDSTORE but disable MODSEQs in mialboxes (Bug #9796). * [mms] Fix obtaining fetch results when searching by sequence number and using caching. * [mms] Add ability to sort mailboxes return from Horde_Imap_Client_Base#statusMultiple(). 1.0.1 1.0.0 stable stable 2011-04-20 LGPL-2.1 * [mms] Work around broken IMAP servers that send EXISTS data in EXPUNGE response (Bug #9915). * [mms] Work around broken ESEARCH on Cyrus (Bug #9842). * [mms] Parse broken date strings that contain timezone information in parantheses (Request #9847). * [mms] Fix for IMAP servers that report MODSEQ information even though CONDSTORE has not been enabled (Bug #9845). * [mms] Fix server-side sorting of subjects in Socket driver (Bug #9840). * [mms] Fix UIDVALIDITY determination for POP3 servers that support UIDL. * [mms] Added Horde_Imap_Client_Data_Fetch_Pop3 object. 1.0.2 1.0.0 stable stable 2011-04-21 LGPL-2.1 * [mms] Correct fix for Bug #9915 (Bug #9943). 1.0.3 1.0.0 stable stable 2011-04-21 LGPL-2.1 * [mms] Return cloned objects from Data results, to prevent issues when caching (Bug #9931). * [mms] Optimize listing subscribed mailboxes for certain queries. * [mms] Add support for PARTIAL search/sort results return (RFC 5267 [4.4]). * [mms] Add support for SEARCH=FUZZY (RFC 6203). 1.0.4 1.0.0 stable stable 2011-04-29 LGPL-2.1 * [mms] Filter CAPABILITY return if sent in response code (Bug #9976). * [mms] Correctly limit FETCH results when specifying changedsince or vanished options and all requested fetch data is already cached. * [mms] Fix intermittent issues retrieving FETCH results in Socket driver. * [mms] Optimize expunging in Socket driver with UIDPLUS servers. * [mms] Fix parsing NAMESPACE response in Socket driver (Bug #9970). 1.0.5 1.0.0 stable stable 2011-05-11 LGPL-2.1 * [mms] Fix OVERQUOTA Exception error constant (Bug #10068; Felipe Zipitría <fzipi@fing.edu.uy>). * [mms] Correctly return PERMANENTFLAGS information if missing in server return. * [mms] Optimizing expunging when using QRESYNC. * [mms] Optimize re-opening a mailbox R/W if using CONDSTORE/QRESYNC. * [mms] Optimize statusMultiple() for currently selected mailbox. * [mms] Optimize search()/thread() in empty mailboxes. 1.0.6 1.0.0 stable stable 2011-05-25 LGPL-2.1 * [mms] Fix changedsince FETCH results when no cacheable fields were present in query. * [mms] Fix/optimize updating Sequence -> UID list when processing EXPUNGEs (Bug #10097). * [mms] Fix UTF-8 -> UTF7-IMAP encoding of ampersands (Bug #10093). * [mms] Fix setACL() for Socket driver (was always doing replace instead of add/remove). * [mms] Fix ACL parsing on RFC 2086 server implementations (Bug #10079). * [mms] More than one SEARCH response may be sent, so don't overwrite existing values. * [mms] Disable search caching if a mailbox reports it does not support mod sequences (Bug #9833). * [mms] Fix storing IMAP flag cache info if specifying both add and remove options to store(). 1.0.7 1.0.0 stable stable 2011-06-01 LGPL-2.1 * [mms] Support response code for POP3 servers (RFC 2449/3206). * [mms] Enable cache support for POP3 Socket driver (FETCH data only). * [mms] Fix APOP authentication for POP3 Socket driver. * [mms] Fix regression with UTF7-IMAP encoding of non-ascii folder names (Bug #10093). 1.0.8 1.0.0 stable stable 2011-06-14 LGPL-2.1 * [mms] Fix re-subscribing to child mailboxes of a renamed mailbox (Bug #10212). * [mms] Fix base subject generation under RFC 5256 [2.1]. 1.0.9 1.0.0 stable stable 2011-07-05 LGPL-2.1 * [jan] Fix stripping attachments from mailboxes with non-ascii names. * [mjr] Fix incorrect method name in Pop3 Socket driver. 1.0.10 1.0.0 stable stable 2011-08-03 LGPL-2.1 * [mms] Fix OR search if first search element contains more than one search criteria (Bug #10404). * [mms] Fix invalid IMAP command being sent if a changedsince search was empty. 1.0.11 1.0.0 stable stable 2011-08-09 LGPL-2.1 * [mms] Fix regression in POP3 Socket driver that caused incorrect parsing of server data (Bug #10417). 1.0.12 1.0.0 stable stable 2011-08-17 LGPL-2.1 * [mms] Fix typo that prevented deletion of messages on POP3 servers (Bug #10424). 1.0.13 1.0.0 stable stable 2011-08-23 LGPL-2.1 * [mms] Fix rare race condition that may cause FETCH requests in the IMAP Socket driver to return empty results (Bug #10434). 1.0.14 1.0.0 stable stable 2011-08-30 LGPL-2.1 * [mms] Add support for CRAM-SHA1 and CRAM-SHA256 authentication (available in Courier SASL library). * [mms] Remove dependency on Auth_SASL for CRAM-MD5 authentication. * [mms] Ignore unknown authentication methods; otherwise, they give false positive when authenticating (Bug #10453). 1.0.15 1.0.0 stable stable 2011-08-31 LGPL-2.1 * [mms] Remove dependency on Auth_SASL. 1.1.0 1.1.0 stable stable 2011-10-08 LGPL-2.1 * [mms] Fix client-side Cc/From/To sorting (Bug #10503). * [mms] Improved IMAP debug logging. * [mms] Fix search charset determination for servers that support SORT & ESORT (Bug #10479). * [mms] Improved phpdoc documentation. * [mms] API CHANGE: Add shortcuts to get MIME decoded envelope information. * [mms] Automatically authenticate to server when using a command that requires an authenticated/selected state (Bug #10473). 1.2.0 1.2.0 stable stable 2011-11-04 LGPL-2.1 * [mms] Fixed setting data for several POP3 fetch results. * [mms] Parsing/generating sequence strings for POP3 servers has been fixed. * [mms] Removed unmaintained Mock driver. * [mms] API CHANGE: Added Horde_Imap_Client_Mailbox to provide way to accurately switch between UTF7-IMAP and UTF-8 mailbox representations. * [mms] API CHANGE: Deprecate Horde_Imap_Client_Base::parseCommandArray() - use Horde_Imap_Client_Utils::parseCommandArray() instead. * [mms] API CHANGE: Added a required parameter ('baseob') to Horde_Imap_Client_Cache constructor. * [mms] API CHANGE: Added Horde_Imap_Client_Base::writeDebug(). * [mms] API CHANGE: Added Horde_Imap_Client_Base::getIdsOb(). * [mms] API CHANGE: Deprecate Horde_Imap_Client_Cache::singleton(). 1.2.1 1.2.0 stable stable 2011-11-22 LGPL-2.1 * [mms] Workaround missing search charset support in the Socket driver (Bug #10726). * [mms] Only add CHARSET data to SEARCH queries if necessary (Bug #10726). * [mms] Fix deletion of cached message entries. 1.3.0 1.2.0 stable stable 2011-12-13 LGPL-2.1 * [mms] Work around broken headers in IMAP envelope data. * [mms] Remove Cclient drivers. 1.3.1 1.2.0 stable stable 2011-12-21 LGPL-2.1 * [mms] LIST-STATUS does not depend on LIST-EXTENDED. * [mms] Add dependency checking for capabilities. 1.3.2 1.2.0 stable stable 2012-01-17 LGPL-2.1 * [mms] Allow multiple date searches to be specified in a single AND search query. * [mms] Fix deleting cached mailbox when mailbox name is given as an object. * [mms] Fix 'changedsince' and 'vanished' parameters' in the fetch() command (Bug #10915). 1.4.0 1.4.0 stable stable 2012-01-31 LGPL-2.1 * [jan] Add German translation. * [jan] Add Spanish translation (Manuel P. Ayala <mayala@unex.es>). * [mms] Implement more efficient serialization for Thread data objects. * [mms] Move server debug information from exception error message to 'details' property of exception object. * [mms] Fix METADATA_TOOMANY and METADATA_NOPRIVATE exception codes. * [mms] All user-directed exception messages are now translated. * [mms] Added Horde_Imap_Client_Exception_NoSupportExtension. * [mms] Incorrect method calls now throw SPL errors instead of Horde_Imap_Client_Exceptions. 1.4.1 1.4.0 stable stable 2012-01-31 LGPL-2.1 * [jan] Fix translations when installed through PEAR. 1.4.2 1.4.0 stable stable 2012-02-01 LGPL-2.1 * [mms] Fix objects where the password is not being encrypted (Bug #10950). 1.4.3 1.4.0 stable stable 2012-02-06 LGPL-2.1 * [mms] Workaround non-ASCII data in bodystructure return from IMAP server. * [mms] Fix several faulty translation strings (Bug #10958). 1.4.4 1.4.0 stable stable 2012-02-12 LGPL-2.1 * [mms] Re-release of 1.4.3 due to broken PEAR .tgz package. 1.5.0 1.5.0 stable stable 2012-02-22 LGPL-2.1 * [mms] Add Horde_Imap_Client_Base#setParam() (Bug #10680). * [mms] Return correct authentication error if authentication fails after the original login (Bug #11007). * [mms] Do case-insensitive check for NIL in IMAP data. * [mms] Correctly support RFC 822 groups in envelope data. * [mms] Envelope address data now returned as Horde_Mail_Rfc822_Address objects. * [mms] Other places where bodystructure may return literals. 1.5.1 1.5.0 stable stable 2012-02-28 LGPL-2.1 * [mms] Workaround PHP bug when using serialized Envelope data created by Horde_Imap_Client < 1.5.0 (Bug #11026). * [mms] Fix accessing STATUS information for mailboxes with non 7-bit characters. * [mms] Fix 'vanished' return from fetch(). 1.5.2 1.5.0 stable stable 2012-04-09 LGPL-2.1 * [mms] Fix CHANGEDSINCE search if no FETCH attributes were specified (Bug #11132). * [mms] Fix search charset detection for servers that do not send the BADCHARSET response code (Bug #11117). * [mms] Workaround IMAP servers with broken CATENATE implementations (Bug #11111). * [jan] Fix sending ID requests. * [jan] Add Finnish translation (Leena Heino <liinu@uta.fi>). * [mms] Rewrite of caching system. Fixes a few bugs, and should be more efficient. * [mms] Clear imapproxy status when logging out. 1.5.3 1.5.0 stable stable 2012-04-11 LGPL-2.1 * [mms] Fixed PHP 5.2 incompatibility (Bug #11137). 1.5.4 1.5.0 stable stable 2012-04-12 LGPL-2.1 * [mms] Fix regression in caching code (Bug #11143). 1.5.5 1.5.0 stable stable 2012-06-29 LGPL-2.1 * [mms] Improved handling of multi-accessed mailboxes and the FETCH/STORE/SEARCH commands (RFC 2180 [2-4]). 1.5.6 1.5.0 stable stable 2012-07-28 LGPL-2.1 * [mms] Fix sorting of numeric mailboxes with leading zeros. * [mms] Optimize statusMultiple() when polling mailboxes containing wildcard characters. * [mms] Correctly handle any resource key supported by the QUOTA extension. 1.5.7 1.5.0 stable stable 2012-07-30 LGPL-2.1 * [mms] Fix determining sequence numbers when caching is active (Bug #11294). 1.5.8 1.5.0 stable stable 2012-09-19 LGPL-2.1 * [mms] Fix CRAM-MD5 authentication (Bug #11449; patrickdk@patrickdk.com). * [mms] Allow SSL version to be explicitly chosen via 'secure' configuration option (Request #11435). 1.5.9 1.5.0 stable stable 2012-09-26 LGPL-2.1 * [mms] Fix POP3 regression that broken envelope data parsing (Bug #11477). * [mms] Fix outputting the host part when using Horde_Imap_Client_Utils#createUrl(). * [mms] Fix obtaining UIDs for APPENDed messages when the server doesn't support APPENDUID. 1.5.10 1.5.0 stable stable 2012-10-15 LGPL-2.1 * [mms] Fix reinitializing a prior authenticated client object when the IMAP server subsequently becomes unavailable (Bug #11413). 1.5.11 1.5.0 stable stable LGPL-2.1 * [mms] Fix CRAM-MD5 authentication for POP3 driver (Bug #11449). * [mms] Allow SSL version to be explicitly chosen via 'secure' configuration option for POP3 driver (Request #11435). 2012-07-06 2.0.0alpha1 2.0.0alpha1 alpha alpha LGPL-2.1 * First alpha release for Horde 5. * [mms] Internally workaround IMAP servers that don't support text searches other than US-ASCII. * [mms] Horde_Imap_Client_DateTime is now a wrapper around the native PHP DateTime object (Request #11074). * [mms] Implement new 2.0 API. See UPGRADING for full details of changes. 2.0.0beta1 2.0.0beta1 beta beta 2012-07-19 LGPL-2.1 * First beta release for Horde 5. * [mms] Allow auto-escaping of mailbox names in listMailboxes(). * [mms] Add list_escape property to Horde_Imap_Client_Mailbox. * [mms] Remove public cache variable from IMAP driver. 2.0.0beta2 2.0.0beta1 beta beta 2012-08-07 2.0.0beta3 2.0.0beta1 beta beta 2012-08-29 LGPL-2.1 * [mms] Correctly handle any resource key supported by the QUOTA extension. 2.0.0beta4 2.0.0beta1 beta beta 2012-10-12 LGPL-2.1 * [jan] Add deleteACL(). * [jan] Make setACL() work more similar to the SETACL IMAP command. * [mms] Fix determination of HIGHESTMODSEQ value from FETCH data. * [mms] Store command that caused NO/BAD error in Exception, if it can be determined. * [mms] Limit FETCH ENVELOPE data sizes. * [mms] Improved parsing of incoming IMAP server stream. * [mms] Improved parsing of IMAP threading data. * [mms] Improved IMAP tokenizer of server response data using PHP temporary streams. * [mms] Add standalone IMAP command tokenizer. * [mms] Rewritten handling for processing outgoing IMAP commands. * [mms] Improved debugging efficiency. * [mms] Added data objects for the various IMAP data types. * [mms] Added the Horde_Imap_Client_Data_Format objects. 2.0.0RC1 2.0.0beta1 beta beta 2012-10-26 LGPL-2.1 * [mms] Fix CONDSTORE synchronization of deleted messages since last mailbox access. * [mms] Need to immediately synchronize mailbox on mailbox load with CONDSTORE or else we may lose flag change information. * [mms] Fixes/improvements to CONDSTORE capability sniffing and enabling. * [mms] Remove statuscache configuration option. * [mms] Optimize generation of POP3 sequence string. * [mms] Abstract forced determination of UIDNEXT value from cache method to a status() flag. * [mms] Remove Horde_Imap_Client_Base#fetchFromSectionString(). * [mms] Horde_Imap_Client_Base#listMailboxes() now supports 'status' return even if server does not server LIST-STATUS. * [mms] Remove Horde_Imap_Client_Base#fetchCacheIgnore(). * [mms] Move IMAP/POP URL parsing to new Horde_Imap_Client_Url object. * [mms] Move base subject parsing to new Horde_Imap_Client_Data_BaseSubject class. * [mms] Move IMAP sequence string generation/parsing to the Horde_Imap_Client_Ids object. * [mms] Remove Horde_Imap_Client_Utils#escape(). * [mms] Remove Horde_Imap_Client_Utils#removeBareNewlines(). * [mms] Move IMAP mailboxes sorting into new Horde_Imap_Client_Mailbox_List class. * [mms] Correctly handle determination of highestmodseq in currently selected mailbox if CONDSTORE, but not QRESYNC, is active. * [mms] Optimize APPEND so that we don't send large amounts of data to server if the server is not going to accept the data. * [mms] Don't expunge mailbox when it is labeled as read-only. * [mms] Fix regression in FETCH/COPY with sequence numbers (Bug #11521). * [mms] Fix quoting empty astrings (Bug #11505). * [jan] Fix Horde_Stream dependency. 2.0.0RC2 2.0.0beta1 beta beta 2012-10-29 LGPL-2.1 * [mms] Fix invalid class name usage (Bug #11586). * [mms] Remove STATUS_LASTMODSEQ and STATUS_LASTMODSEQUIDS return options from status(). 2.0.0 2.0.0 stable stable 2012-10-30 LGPL-2.1 * First stable release for Horde 5. * [mms] Fix regression in Horde_Imap_Client_Base#listMailboxes() return when both the 'flat' and 'sort' options are active. * [mms] Add STATUS_SYNCMODSEQ, STATUS_SYNCFLAGUIDS, and STATUS_SYNCVANISHED return options to Horde_Imap_Client_Base#status(). 2.1.0 2.1.0 stable stable 2012-11-02 LGPL-2.1 * [mms] Split debugging code from Base driver into separate object. * [mms] Fix double encoding of non-ASCII elements in listMailboxes() (Bug #11608). * [mms] Fix regression for non-cached Socket objects (Bug #11605). * [mms] Improved handling of server write errors in the Socket driver. * [mms] Add support for IMAP MOVE command. * [mms] Correctly handle FETCH results intermingled with EXPUNGE/VANISHED requests within a single request. * [mms] Correctly handle EXISTS/EXPUNGE/VANISHED untagged responses which may appear at any time. * [mms] Fix handling message sequence number actions returned from server when using CONDSTORE/QRESYNC. 2.1.1 2.1.0 stable stable 2012-11-03 LGPL-2.1 * [mms] Massive performance increase for cached FETCH queries. 2.1.2 2.1.0 stable stable 2012-11-05 LGPL-2.1 * [mms] Fix parsing empty ACL responses. 2.1.3 2.1.0 stable stable 2012-11-05 LGPL-2.1 * [mms] Allow Horde_Imap_Client_Base#vanished() to work with non-QRESYNC servers if the 'ids' option is given. * [mms] Always map UIDs to sequence numbers if resolving an all UIDs search. * [mms] Ignore empty ID search queries. 2.1.4 2.1.0 stable stable 2012-11-19 LGPL-2.1 * [jan] Add Dutch translation (Arjen de Korte <build+horde@de-korte.org>). * [mms] Fix returning UIDNEXT when using UIDNEXT_FORCE and the server does not automatically return this information. * [mms] Significant optimization to append() command. * [mms] Add abstracted syncing methods to Horde_Imap_Client_Base. 2.1.5 2.1.0 stable stable 2012-11-06 LGPL-2.1 * [mms] Correctly workaround servers that incorrectly implement the LIST-EXTENDED command. 2.1.6 2.1.0 stable stable 2012-11-10 LGPL-2.1 * [mms] Fix parsing PARSE response code associated with an OK response. * [mms] Workaround broken BINARY implementation on UW-IMAP servers. * [mms] If we have binary data, and server doesn't support BINARY extension, send data anyway since we don't have any other option. * [mms] Correctly increment UIDNEXT when an EXISTS response is issued after the mailbox is opened (Bug #11679). * [mms] Fix regression that may have caused message flags to have been improperly cached if debugging was disabled (Bug #11665). 2.2.0 2.2.0 stable stable 2012-11-10 LGPL-2.1 * [mms] Fix returning UIDNEXT when using UIDNEXT_FORCE and the server does not automatically return this information. * [mms] Significant optimization to append() command. * [mms] Add abstracted syncing methods to Horde_Imap_Client_Base. 2.2.1 2.2.0 stable stable 2012-11-22 LGPL-2.1 * [mms] Workaround broken BINARY extension on Cyrus servers. 2.2.2 2.2.0 stable stable 2012-11-27 LGPL-2.1 * [mms] Complete workaround for broken BINARY extension on Cyrus servers. 2.2.3 2.2.0 stable stable 2012-11-28 LGPL-2.1 * [mms] Another workaround for broken Cyrus APPEND behavior (Bug #11769). 2.3.0 2.3.0 stable stable 2012-12-03 LGPL-2.1 * [mms] Fix sending literal mailbox data to an IMAP server (Bug #11800). * [mms] Add Horde_Imap_Client_Data_Format_String#getStream(). * [jan] Fix Dutch translation (Arjen de Korte <build+horde@de-korte.org>). * [mms] Fix regression in POP3 driver for servers that don't support the RESP-CODES extension. 2.3.1 2.3.0 stable stable 2012-12-05 LGPL-2.1 * [mms] Fix client-side address sorting (Bug #11820). * [mms] Optimizations to IMAP token parser. * [mms] Fix setting language value when language is returned in an IMAP list. 2.3.2 2.3.0 stable stable 2012-12-06 LGPL-2.1 * [mms] Revert valid PHP changes that caused errors in broken old versions of PHP. 2.4.0 2.4.0 stable stable 2012-12-17 LGPL-2.1 * [mms] Re-add optimizations to IMAP token parser. * [jan] Add Basque translation (Ibon Igartua <ibon.igartua@ehu.es>). * [mms] Additional workarounds for IMAP servers with broken BINARY implementations (Bug #11855). * [mms] Add SORT_DISPLAYFROM_FALLBACK and SORT_DISPLAYTO_FALLBACK sorting criteria to Horde_Imap_Client_Base#search(). 2.4.1 2.4.0 stable stable 2012-12-20 LGPL-2.1 * [mms] Fix bodystructure parsing for IMAP servers that do not return full extension data (Bug #11907). 2.4.2 2.4.0 stable stable 2013-01-04 LGPL-2.1 * [mms] Fix multipart APPENDs when IMAP server does not support CATENATE. * [mms] Fix harmless PHP warning issued when IMAP server supports SORT but not SORT=DISPLAY. 2.5.0 2.5.0 stable stable 2013-01-22 LGPL-2.1 * [mms] Some IMAP servers require a mailbox to be unselected before it can be renamed. * [jan] Add French translation (Paul De Vlieger <paul.de_vlieger@moniut.univ-bpclermont.fr>). * [mms] Ignore fetch data returned from an UID FETCH command if it doesn't include UID information (Bug #11946). * [mms] Add exists option to Horde_Imap_Client_Base#fetch(). 2.6.0 2.6.0 stable stable 2013-02-08 LGPL-2.1 * [mms] Fix regression in parsing LISTRIGHTS results (Bug #11994). * [mms] Workaround QRESYNC errata that allows FETCH FLAGS results to be returned without UID information. * [mms] More robust handling of split FETCH responses. 2.7.0 2.7.0 stable stable 2013-02-24 LGPL-2.1 * [mms] More efficient implementation of Horde_Imap_Client_Ids#range_string. * [mms] Fix APPENDs on IMAP servers that do not support CATENATE. * [mms] Fix from/to searches on servers that support SORT=DISPLAY when using the *_FALLBACK sort criteria. * [mms] Ensure that a FETCH and/or SELECT/EXAMINE (w/QRESYNC) will not exceed maximum allowed command length on the IMAP server (Bug #12001). * [mms] Add Horde_Imap_Client_ids#split(). * [mms] Fix regression in the replace argument, and multiple arguments to add/delete, for the store() command. * [mms] Make sure the modseq given to the vanished() command is always at least 1 (Bug #12031). 2.7.1 2.7.0 stable stable 2013-03-04 LGPL-2.1 * [mms] Fix SETQUOTA, GETQUOTA, and GETQUOTAROOT commands on mailboxes that contain non-7bit characters (Bug #12059). * [mms] Fix returning UID data from the Horde_Imap_Client_Data_Sync object (Bug #12071). 2.7.2 2.7.0 stable stable 2013-03-08 LGPL-2.1 * [mms] Always return UID information for FETCH queries if cache is active, so we ensure that mappings are updated and any cacheable data can be cached. * [mms] Don't cache FETCH data if it does not contain UID information (Bug #12097). 2.8.0 2.8.0 stable stable 2013-03-26 LGPL-2.1 * [mms] Add properties to Sync object to allow retrieval of previous sync state status. * [mms] Only do UNCHANGEDSINCE check when storing flags if the user explicitly passes the 'unchangedsince' parameter. * [mms] Add the 'nocache' option to Horde_Imap_Client_Base#fetch(). 2.8.1 2.8.0 stable stable 2013-03-28 LGPL-2.1 * [mms] Fix regression in storing cached flags if not using debug mode. 2.8.2 2.8.0 stable stable 2013-04-18 LGPL-2.1 * [mms] Correctly parse message/rfc822 BODYSTRUCTURE responses if the server does not provide any envelope information (Bug #12190). 2.9.0 2.9.0 stable stable 2013-05-01 LGPL-2.1 * [mms] Support UID EXPUNGE command for large UID lists (Bug #12228). * [mms] Don't attempt to expunge messages if the list of UIDs to expunge is empty (Bug #12226). * [mms] Correctly use limit parameter to Horde_Imap_Client_Ids#split() (Bug #12216). * [mms] Add a MongoDB based backend for storing cached IMAP/POP data. * [mms] Add Horde_Imap_Client_Cache#clear(). * [mms] Add a Horde_Db based backend for storing cached IMAP/POP data. * [mms] Abstract the backend storage into a separate driver for the Horde_Imap_Client_Cache class. 2.9.1 2.9.0 stable stable 2013-05-14 LGPL-2.1 * [jan] Fix dependency. 2.10.0 2.10.0 stable stable 2013-05-17 LGPL-2.1 * [mms] Pipeline multiple IMAP LIST/LSUB calls. * [mms] Fix login methods that require server continutation responses. * [mms] Correctly handle enabled cached status when not using imapproxy. * [mms] Fix caching of CAPABILITY information when not using imapproxy. * [mms] Support pipelining of STORE + EXPUNGE if UIDPLUS is available. * [mms] Pipeline multiple STATUS commands if LIST-STATUS is not available. * [mms] Fold statusMultiple() functionality into base status() command. * [mms] Pipeline multiple IMAP FETCH calls. * [mms] Delay sending LANGUAGE command until we send another command to save a round-trip. * [mms] Delay sending ENABLE command until we send another command to save a round-trip. * [mms] Add internal support for IMAP command pipelining. 2.10.1 2.10.0 stable stable 2013-05-21 LGPL-2.1 * [mms] Fix returning the list of deleted messages in the POP3 driver. * [mms] Handle all additional namespace queries in a single call. 2.11.0 2.11.0 stable stable 2013-05-27 LGPL-2.1 * [mms] Workaround broken IMAP servers and prevent infinite loops (Bug #12265). * [mms] Add support for the DOWNGRADED IMAP response code (RFC 6858). 2.11.1 2.11.0 stable stable 2013-05-28 LGPL-2.1 * [mms] Fix caching MIME structure data in POP3 driver. * [mms] Enhanced parsing of POP3 data from the remote server. 2.11.2 2.11.0 stable stable 2013-05-28 LGPL-2.1 * [mms] Fix regression in Socket driver when moving messages without UIDPLUS. 2.11.3 2.11.0 stable stable 2013-06-03 LGPL-2.1 * [mms] Improved detection of client-side command errors before sending to the remote IMAP server. * [mms] Better sanity checking that we don't send binary data for mailbox entries. 2.11.4 2.11.0 stable stable 2013-06-04 LGPL-2.1 * [mms] Be more lenient about mailboxes containing null characters in Horde_Imap_Client 2.x for BC reasons. * [mms] Fix flushing debug buffer when unexpected data is returned from the remote server. 2.11.5 2.11.0 stable stable 2013-06-11 LGPL-2.1 * [mms] So many IMAP servers have issues with BINARY, that we should not send literal8 data unless we absolutely have to. * [mms] Remove read/write buffering from stream connection to remote server. * [mms] Ensure we only use literal8's in APPEND commands. * [mms] Abstract connection code into separate library, to better handle output buffering and error handling. * [mms] Fix regression in throwing exceptions when parsing POP3 server responses. 2.11.6 2.11.0 stable stable 2013-06-18 LGPL-2.1 * [mms] Fix regression in handling response codes in POP3 driver. * [mms] Fix clearing data from the MongoDB cache. 2.12.0 2.12.0 stable stable 2013-07-24 LGPL-2.1 * [mms] Added the Horde_Imap_Client::STATUS_RECENT_TOTAL return option to Horde_Imap_Client_Base#status(). * [mms] More graceful handling of servers that return broken FETCH information (Request #12441). 2.12.1 2.12.0 stable stable 2013-08-13 LGPL-2.1 * [mms] Fix returning list of expunged UIDs when expunging all messages in a mailbox that doesn't support CONDSTORE (Bug #12559). * [mms] Translate mailbox names from UTF7-IMAP -> UTF-8 in return from Horde_Imap_Client_Base#getMetadata() (Bug #12541). 2.12.2 2.12.0 stable stable 2013-08-15 LGPL-2.1 * [mms] Add remote POP3 server test. * [mms] Fix sniffing capabilities for POP3 servers that don't support the CAPA command. 2.12.3 2.12.0 stable stable 2013-08-16 LGPL-2.1 * [mms] Fix regression in caching for POP3 servers. * [mms] Cache any data returned from POP3 capability sniffing. 2.13.0 2.13.0 stable stable 2013-08-19 LGPL-2.1 * [mms] Fix regression in POP3 SASL PLAIN authentication command. * [mms] Fix regression in mapping message sequence numbers to UIDs when doing an 'all' activity in POP3. * [mms] Added support for the Google XOAUTH2 authentication mechanism for the IMAP Socket driver. * [mms] Fix regression in retrieving CAPABILITY information after we login. 2.13.1 2.13.0 stable stable 2013-08-20 LGPL-2.1 * [mms] Fix regression in setting CAPABILITY for IMAP servers that don't automatically send this information after login. 2.14.0 2.14.0 stable stable 2013-08-25 LGPL-2.1 * [mms] Added the 'statuscache' property to Horde_Imap_Client_Base (Request #12589). * [mms] The 'xoauth2_token' parameter now accepts a Horde_Imap_Client_Base_Password object. * [mms] Deprecated the 'encryptKey' parameter and instead support passing a Horde_Imap_Client_Base_Password object into the 'password' parameter. * [mms] Added the Horde_Imap_Client::STATUS_FORCE_REFRESH flag. 2.15.0 2.15.0 stable stable 2013-09-03 LGPL-2.1 * [mms] Workaround servers that don't advertise UIDL until after authentication. * [mms] Fix parsing continuation requests sent in SASL AUTH command (RFC 5034). * [mms] By default, use TLS if available and necessary to login to server. * [mms] Fix adding status information to listMailboxes() return when LIST-STATUS is not available. 2.15.1 2.15.0 stable stable 2013-09-13 LGPL-2.1 * [mms] Ensure Horde_Imap_Client_Base#search() always returns the 'count' value (Bug #12682). * [jan] Fix incorrect usage of Horde_Db API in cache backend. 2.15.2 2.15.0 stable stable 2013-09-14 LGPL-2.1 * [mms] Handle case-insensitive INBOX return from the server. * [mms] Use strict RFC-compliant workaround for servers that don't support the UNSELECT IMAP extension. 2.15.3 2.15.0 stable stable 2013-09-16 LGPL-2.1 * [mms] Fix regression where INBOX may not be recognized as subscribed, if the server doesn't list it in the subscribed list. 2.15.4 2.15.0 stable stable 2013-10-09 LGPL-2.1 * [mms] Sort UID list before sending in QRESYNC parameter. * [mms] Ensure that INBOX always appears in subscribed mailbox list when using a server that supports LIST-EXTENDED. 2.15.5 2.15.0 stable stable 2013-10-11 LGPL-2.1 * [mms] Explicitly reject XOAUTH2 as a authentication mechanism if it is not configured in the client (Bug #12756). 2.16.0 2.16.0 stable stable 2013-10-30 LGPL-2.1 * [mms] Added direct TLS v1.x connection option when connecting to remote server. * [mms] Use SHA-1 instead of MD5 for internal hashing. * [mms] Correctly handle untagged BAD IMAP responses. * [mms] Added Horde_Imap_Client_Password_Xoauth2 class. * [mms] Fix harmless PHP undefined error when using with an IMAP server that supports XOAUTH2. 2.16.1 2.16.0 stable stable 2013-11-21 LGPL-2.1 * [mms] Fix intermittent error when purging messages using a Horde_Cache caching backend (Bug #12827). * [mms] Workaround broken IMAP servers that don't support the required AUTH=PLAIN authentication method (Bug #12817). 2.16.2 2.16.0 stable stable 2013-11-27 LGPL-2.1 * [mms] Don't login to IMAP server if namespace information is already cached. 2.17.0 2.17.0 stable stable 2014-01-17 LGPL-2.1 * [mms] When determining a sequence -> UID mapping, do sanity checking to make ensure data is valid (Bug #12911). * [mms] Add a Horde_Hashtable specific cache driver. * [mms] Add remove() method to Horde_Imap_Client_Ids. 2.17.1 2.17.0 stable stable 2014-01-22 LGPL-2.1 * [mms] Fix updating message list in the hashtable cache driver when deleting. 2.18.0 2.18.0 stable stable 2014-02-11 LGPL-2.1 * [mms] Add raw error message text (in English) to Exceptions. * [mms] Add debug timing information for connection/commands. * [mms] Fix resetting capability list when internally cached authentication information becomes invalid. 2.18.1 2.18.0 stable stable 2014-02-14 LGPL-2.1 * [mms] Fix regression where Horde_Imap_Client_Exception was inheriting from a different class than before. * [mms] Use more efficient FNV1-32 hashing algorithm for internal hashtable storage, if available. * [jan] Make SQL cache backend compatible with Oracle. * [mms] Optimizations to IMAP tokenizer. 2.18.2 2.18.0 stable stable 2014-02-17 LGPL-2.1 * [mms] More correct fix for Exception construction. 2.18.3 2.18.0 stable stable 2014-02-24 LGPL-2.1 * [mms] Fix obtaining bodypart size (Bug #12992; martin@matuska.org). 2.18.4 2.18.0 stable stable 2014-02-27 LGPL-2.1 * [mms] Improved/more concise debug output. * [mms] Optimize sorting in Horde_Imap_Client_Ids object. * [mms] Workaround broken SASL capability responses from POP3 servers. * [mms] Prevent PHP error when a FETCH call is unsuccessful. * [mms] Relax type checking on cache driver object. 2.18.5 2.18.0 stable stable 2014-03-04 LGPL-2.1 * [mjr] Fix regression in obtaining bodypart size when BINARY extension is available. 2.18.6 2.18.0 stable stable 2014-03-04 LGPL-2.1 * [mms] Fix updating cached flags list on a CONDSTORE-only server. 2.19.0 2.19.0 stable stable 2014-03-10 LGPL-2.1 * [mms] The Hashtable cache driver now allows the lifetime of the message data to be specified. * [mms] Fix removing UID from cached list in Hashtable cache driver if the message data no longer exists. * [mms] Add 'force_map' option to Horde_Imap_Client_Base#copy() to guarantee that the mapping array is always returned. * [mms] More accurate way of determining appended UID on append when UIDPLUS is not available. * [mms] Fixes for stream handling in the Nstring object. * [mms] Split data format object test into individual files. 2.19.1 2.19.0 stable stable 2014-03-16 LGPL-2.1 * [mms] Fix regression in parsing empty string values in IMAP tokenizer. 2.19.2 2.19.0 stable stable 2014-04-03 LGPL-2.1 * [mms] Prevent unnecessary cache writes when list of UIDs passed to deleteMsgs() is empty. * [mms] Fix stripping non-ASCII characters in Horde_Imap_Client_Data_Format_Atom#stripNonAtomCharacters(). * [jan] Add Danish translation (Erling Preben Hansen <erling@eph.dk>). * [mms] Don't allow PREAUTH on unencrypted connection if a secure connection (e.g. STARTTLS) is requested. * [mms] Password is no longer a necessary parameter. 2.19.3 2.19.0 stable stable 2014-04-16 LGPL-2.1 * [mms] Fix parsing a reply/forward subject with no blob content. * [mms] Ensure integer value returns from Horde_Imap_Client_Base#status() are truly integers. 2.19.4 2.19.0 stable stable 2014-04-23 LGPL-2.1 * [mms] Handle IN-USE, LOGIN-DELAY, and SYS/TEMP error codes when authenticating to POP3 servers. * [mms] Fix TLS negotiation with POP3 servers. * [mms] Fix throwing authentication exception when using Digest-MD5. 2.19.5 2.19.0 stable stable 2014-05-03 LGPL-2.1 * [mms] Correctly handle partial search limiting for a single ID (Bug #13153). * [mms] Workaround bug in Dovecot where improperly encoded body part returns NIL data when using the BINARY extension. 2.19.6 2.19.0 stable stable 2014-05-14 LGPL-2.1 * [mms] Workaround broken MIME parts that cannot be binary decoded on the server. * [jan] Add Hungarian translation (Andras Galos <galosa@netinform.hu>). 2.20.0 2.20.0 stable stable 2014-05-21 LGPL-2.1 * [mms] Fix instantiating base object with an empty password. * [mms] Better error checking when writing data to the server (Bug #13187; Thomas Jarosch <thomas.jarosch@intra2net.com>). * [mms] Support partial search limitation even if the PARTIAL search return option is not available on the server (Request #13153). * [mms] Added the 'max' and 'min' properties to Horde_Imap_Client_Ids. 2.21.0 2.21.0 stable stable 2014-06-04 LGPL-2.1 * [mms] Fix working with mailboxes containing entirely integers (Bug #13157). * [mms] Horde_Imap_Client_Base#getNamespaces() can now return a Horde_Imap_Client_Namespace_List object instead of an array. * [mms] Use the new command length limitations defined in RFC 7162. * [mms] A noop() call before authentication will now correctly throw an exception on a connection issue (Bug #13205). 2.22.0 2.22.0 stable stable 2014-06-07 LGPL-2.1 * [mms] Workaround PHP DateTime regression in 5.4.29 & 5.5.13. * [mms] Fix translating error messages if they contain printf placeholders. 2.23.0 2.23.0 stable stable 2014-06-17 LGPL-2.1 * [mms] Delimiter information is now always returned from Horde_Imap_Client_Base#listMailboxes(). * [mms] Fix broken MBOX_UNSUBSCRIBED behavior on IMAP servers that support LIST-EXTENDED. * [mms] Added the MBOX_ALL_SUBSCRIBED mode to Horde_Imap_Client_Base#listMailboxes(). 2.23.1 2.23.0 stable stable 2014-06-17 LGPL-2.1 * [mms] Fix regression where INBOX subscription status was based on server status, instead of always being treated as subscribed (Bug #13261). 2.23.2 2.23.0 stable stable 2014-07-09 LGPL-2.1 * [mms] Determination of approximate part size should be done at IMAP level, not within Horde_Mime_Part. * [mms] Fix regression in handling invalid DateTime data due to a BC-incompatible change in PHP. 2.24.0 2.24.0 stable stable 2014-08-04 LGPL-2.1 * [mms] Correctly expire internal cache in POP3 when messages are deleted. * [mms] Improved determination of a pseudo-UIDNEXT value for POP3 servers. * [mms] Fix sorting of POP3 IDs. * [mms] Added the 'url' property to Horde_Imap_Client_Base. * [mms] Fix thread sort order when using the client-side ordered subject algorithm and there are messages with identical dates. * [mms] Allow multiple live IMAP/POP3 tests to be run in a single PHPUnit instance. * [mms] Add support for the IMAP UTF-8 extension (RFC 6855). * [mms] Querying of valid search charsets is now handled by the Horde_Imap_Client_Data_SearchCharset object. * [mms] IMAP extension enabled information is now stored within the capability object. * [mms] Fix regression where authetication was attempted with a non-null, empty string password. * [mms] Improved debug logging during connection failures and authentication attempts. * [mms] Fix debug logging for certain IMAP authentication actions. * [mms] Internally handle capability querying via the new Horde_Imap_Client_Data_Capability object. 2.24.1 2.24.0 stable stable 2014-08-06 LGPL-2.1 * [mms] Fix regression in reporting capabilities (Bug #13421). 2.24.2 2.24.0 stable stable 2014-08-11 LGPL-2.1 * [mms] Fix typo in Horde_Imap_Client_Data_Sync (Bug #13430; Jasper Olbrich <Jasper.Olbrich@students.uni-marburg.de>). 2.25.0 2.25.0 stable stable 2014-09-03 LGPL-2.1 * [mms] Add support for Gmail-specific WEBALERT response code. * [mms] IMAP/POP3 URL generation split into a more modular library structure. * [mms] Ignore message-specific URL parameters if a search query appears in an IMAP URL. * [mms] Fix encoding/decoding URL elements in IMAP/POP3 URLs. * [mms] Fix setting default port for POP3 URLs. * [mms] Fix client-side reverse sorting. * [mms] Fix client-side sequence sorting, when that is the only sort criteria. * [mms] Use Collator class, if present, to sort string fields on the client side. * [mms] Fix client-side sorting of display addresses. * [mms] Even more improved pseudo-UIDNEXT value for POP3 servers. * [mms] Improved sanity checking so that non-ASCII data is not sent to server in commands where it is not supported. 2.25.1 2.25.0 stable stable 2014-09-17 LGPL-2.1 * [mms] Fix IMAP search results for recent and total messages when it is the only query and the mailbox is not selected. * [mms] Fix client-side message sorting when there are multiple sort criteria and at least one tie in the first sorting criteria. * [mms] Better error handling when attempting to authenticate via IMAP LOGIN command with non-ASCII credentials (Bug #13554). * [mms] Fix sending IMAP APPEND data when the UTF-8 capability is enabled. * [mms] Fix parsing IMAP mailbox list requests when UTF-8 mode is enabled. * [mms] Ensure client sorting tests work reproducibly across systems with varying default locales. 2.25.2 2.25.0 stable stable 2014-10-14 LGPL-2.1 * [mms] Add support for UTF8 extension for POP3 servers (RFC 6856). * [mms] Add support for LANG extension for POP3 servers (RFC 6856). 2.25.3 2.25.0 stable stable 2014-11-10 LGPL-2.1 * [mms] Fix determining whether a command requires a continuation request, when the literal occurs within a nested list. * [mms] Ensure we don't use the same authentication method multiple times when logging into IMAP server. 2.25.4 2.25.0 stable stable 2014-11-23 LGPL-2.1 * [mms] Better error handling when IMAP connection is prematurely disconnected. * [mms] Fix regression in listMailboxes() for POP3 servers when 'flat' option is true. 2.25.5 2.25.0 stable stable 2014-11-24 LGPL-2.1 * [mjr] Fix broken IMAP cache behavior in the DB driver when unserialization of a cached object fails. 2.25.6 2.25.0 stable stable 2014-12-03 LGPL-2.1 * [mms] Better cache unserialization error handling for all backends. 2.26.0 2.26.0 stable stable 2015-01-07 LGPL-2.1 * [mms] Fix handling mailbox cache data when the mailbox returns NOMODSEQ. * [mms] IMAP alerts can now be handled by registering an observer with the new Horde_Imap_Client_Base_Alerts object. 2.26.1 2.26.0 stable stable 2015-01-27 LGPL-2.1 * [mms] Fix serialization of Horde_Imap_Client_Data_Fetch objects. * [mms] Workaround broken in-memory stream filter handling. 2.27.0 2.27.0 stable stable 2015-03-10 LGPL-2.1 * [jan] Add parameter for stream context settings (Request #13730). 2.28.0 2.28.0 stable stable 2015-04-27 LGPL-2.1 * [mms] Fix parsing mailbox name from STATUS response on servers that have the UTF8 extension enabled. * [jan] Fix searching with non-ASCII strings in AND/OR-combined searches. * [jan] Fix issues with certain locales like Turkish. * [mms] Pipeline ID command with other commands, if possible. 2.28.1 2.28.0 stable stable 2015-05-12 LGPL-2.1 * [mms] Directly store literal data in a separate stream when parsing IMAP tokens, so we don't have to duplicate the stream later when processing it. * [mms] Don't load literal IMAP data into a string variable when tokenizing IMAP input. * [mms] Fix search queries where ID list given is explicitly empty, indicating that a match can never be successful (Bug #13971). * [mms] Fix expunging in certain cases when UIDPLUS is not available (Bug #13970; Robin McCorkell <rmccorkell@karoshi.org.uk>). 2.29.0 2.29.0 stable stable 2015-06-18 LGPL-2.1 * [mjr] Fix detecting changes when using tokens. * [mms] Add support for SCRAM-SHA-1 authentication (RFC 5802) for both IMAP and POP3 drivers. 2.29.1 2.29.0 stable stable 2015-07-15 LGPL-2.1 * [mms] Ensure FETCH stream data is rewound before returning (Bug #14013). * [mjr] Fix detecting empty ID queries (Bug #14044). 2.29.2 2.29.0 stable stable 2015-09-01 LGPL-2.1 * [mms] Improved performance of Horde_Imap_Client_Data_Thread object when containing large number of messages (Request #14075). * [mms] Catch translation errors when creating Exceptions (PR #143; baso10dev@gmail.com). 2.29.3 2.29.0 stable stable 2015-09-07 LGPL-2.1 * [mjr] Avoid PHP warning when listing mailboxes without LIST-STATUS (Bug #14097). 2.29.4 2.29.0 stable stable 2015-11-22 LGPL-2.1 * [jan] Fix parsing IMAP responses with tilde characters. 2.29.5 2.29.0 stable stable 2016-02-01 LGPL-2.1 * [jan] Don't try LOGIN authentication over secure connections if explicitly disabled. * [jan] Mark PHP 7 as supported. * [jan] Improve Oracle compatibility. * [mjr] Fix fatal error during shutdown due to incorrect exception name. * [jan] Fix broken ID requests under certain circumstances. 2.29.6 2.29.0 stable stable 2016-03-21 LGPL-2.1 * [jan] Add Greek translation (Limperis Antonis <limperis@cti.gr>). 2.29.7 2.29.0 stable stable 2016-05-31 LGPL-2.1 * [mjr] Add sanity check for malformed offset in Date header (Bug #14381). * [mjr] Fix fatal error in certain cases when performing a BODY[HEADER.FIELDS] query. 2.29.8 2.29.0 stable stable 2016-07-01 LGPL-2.1 * [jan] Avoid notice with Horde_Mongo on PHP 7. * [mjr] Catch incorrectly localized Date headers. 2.29.9 2.29.0 stable stable 2016-09-01 LGPL-2.1 * [jan] Optimize deleting or moving a large number of messages. 2.29.10 2.29.0 stable stable 2016-11-03 LGPL-2.1 * [jan] Fix parsing GETACL responses from RFC 4314 capable IMAP servers (Bug #14466). 2.29.11 2.29.0 stable stable 2016-12-03 LGPL-2.1 * [mjr] Fix failed connections when using unix sockets (Thomas Jarosch <thomas.jarosch@intra2net.com>). 2.29.12 2.29.0 stable stable 2016-12-17 LGPL-2.1 * [mjr] Fix command syntax for CREATE-SPECIAL-USE support. 2.29.13 2.29.0 stable stable 2017-06-22 LGPL-2.1 * [jan] Add Turkish translation (İTÜ BİDB <sistemdestek@itu.edu.tr>). 2.29.14 2.29.0 stable stable 2017-08-01 LGPL-2.1 * [jan] Fix check if QRESYNC is enabled in vanished() (i.badamshin <i.badamshin@i-infinite.net>). 2.29.15 2.29.0 stable stable 2017-08-28 LGPL-2.1 * [jan] Fix expunging cache entries of a certain lifetime from the DB backend. Horde_Imap_Client-2.29.15/doc/Horde/Imap/Client/examples/tutorial.md0000664000175000017500000003400113150761652023224 0ustar janjan# Horde_Imap_Client Documentation ## General Information ### Autoloading Horde/Imap_Client does not [include()](http://php.net/include) its own files, so an autoloader must be registered that will load the Horde/Imap_Client files from its directory. If installing via Composer, use the generated include file to load the library. If using PEAR, or installing from source, [Horde's Autoloader](http://www.horde.org/libraries/Horde_Autoloader) package can be used to do this for you (or any other [PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md) compliant autoloader). ### Constructor Interaction with the mail server is handled through a ```Horde_Imap_Client_Base``` object. The object class will be either: - [```Horde_Imap_Client_Socket```](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Socket.html) - IMAP servers - [```Horde_Imap_Client_Socket_Pop3```](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Socket_Pop3.html) - POP3 servers The minimum necessary configuration needed for the Client constructor is the ```username``` and ```password```. Although default values can be used for the ```hostspec```, ```port```, and ```secure``` options, it is generally a good idea to explicitly set these values to aid in debugging connection issues. #### Debugging Debug output of the server protocol communication can be obtained by providing the ```debug``` option. Acceptable values are any PHP supported wrapper that can be opened via the [```fopen()```](http://php.net/fopen) command. A plain string is inerpreted as a filename, which is probably what most people will want to use. #### Caching Horde/Imap_Client provides transparent caching support by using the Horde_Cache package. Cached information includes the following: - Envelope information - Message structure - IMAP flags (if the IMAP [CONDSTORE](http://tools.ietf.org/html/rfc7162) capability exists on the server) - Search results for a mailbox - Threading results for a mailbox To use, a Horde_Cache backend should be configured and provided to the Horde_Imap_Client constructor in the ```cache``` option. The format of that option can be found in the [constructor API Documentation](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Base.html#method___construct). Information about how to create a Horde_Cache object can be found in the [Horde_Cache API Documentation](http://dev.horde.org/api/master/lib/Cache/). A simple cache driver configuration is illustrated in the example below. #### Example A sample constructor instantation (all further examples assume that this command has been performed and a client object is present in the ```$client``` variable): ```php try { /* Connect to an IMAP server. * - Use Horde_Imap_Client_Socket_Pop3 (and most likely port 110) to * connect to a POP3 server instead. */ $client = new Horde_Imap_Client_Socket(array( 'username' => 'foo', 'password' => 'secret', 'hostspec' => 'localhost', 'port' => '143', 'secure' => 'tls', // OPTIONAL Debugging. Will output IMAP log to the /tmp/foo file 'debug' => '/tmp/foo', // OPTIONAL Caching. Will use cache files in /tmp/hordecache. // Requires the Horde/Cache package, an optional dependency to // Horde/Imap_Client. 'cache' => array( 'backend' => new Horde_Imap_Client_Cache_Backend_Cache(array( 'cacheob' => new Horde_Cache(new Horde_Cache_Storage_File(array( 'dir' => '/tmp/hordecache' ))) )) ) )); } catch (Horde_Imap_Client_Exception $e) { // Any errors will cause an Exception. } ``` The full list of options can be found in the [API Documentation](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Base.html#method___construct). ### Error Handling/Exceptions As noted in the constructor example, all errors encountered by the library will cause exceptions of the ```Horde_Imap_Client_Exception``` class (or a subclass of that base class) to be thrown. The exception message will contain a *translated* version of the error message. If the "raw" English version of the message is needed - i.e. for logging purposes - it can be found in the ```$raw_msg``` property. Further server debug information *might* be found in the ```$details``` property, but this is not guaranteed. - [API Documentation of the base exception class](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Exception.html) - [Error Message Code Constants](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Exception.html#constant_ALREADYEXISTS) #### IMAP Alerts IMAP alerts are *REQUIRED* by the IMAP specification to be displayed to the user. These alerts should be caught/handled in the client code by observing the [```Horde_Imap_Client_Base_Alerts```](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Base_Alerts.html) object, which is available as the ```$alerts_ob``` property in the Horde_Imap_Client_Base object. Example: ```php // First, define an observer in your code: class Foo implements SplObserver { public function update(SplSubject $subject) { if ($subject instanceof Horde_Imap_Client_Base_Alerts) { // This is where your code processes the alert. $alert = $subject->getLast(); // Alert text: $alert->alert // Alert type (optional): $alert->type } } } $foo = new Foo(); // Then, register the observer with the client object. $client->alerts_ob->attach($foo); ``` ## General Function Information #### Manual Mailbox Loading Not Necessary NOTE: All mailbox arguments to methods in Horde/Imap_Client take the UTF-8 version of the mailbox name. There is no need to worry about converting from/to the internal UTF7-IMAP charset used on IMAP servers. Alternatively, you can use [Horde_Imap_Client_Mailbox](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Mailbox.html) objects as the mailbox argument. This object can automatically convert the mailbox name if in UTF7-IMAP for you. Example: ```php // This creates a mailbox object from UTF-8 data. $mbox1 = Horde_Imap_Client_Mailbox::create('Envoyé'); // This creates a mailbox object from UTF7-IMAP data. $mbox2 = Horde_Imap_Client_Mailbox::create('Envoy&AOk-', true); // $result === true $result = ($mbox1 == $mbox2); ``` #### UID Object Return Many method either require UIDs as an argument or return a list of UIDs. This is done by using the [Horde_Imap_Client_Ids](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Ids.html) object. This object implements both the ```Countable``` and ```Traversable``` classes, so it can be used directly in ```count()``` and ```foreach()``` commands. If a raw array list of ids is needed, it can be obtained from the object via the ```$ids``` property. ## Mailbox Actions The following are actions dealing with mailbox-level actions. Actions dealing with the contents of the mailboxes are discussed below in the "Message Actions" section. ### Listing Mailboxes Listing mailboxes is accomplished via the [```listMailboxes()```](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Base.html#method_listMailboxes) function. The search query (or multiple queries) is passed in via the first argument. The second argument defines which mailboxes that match the search pattern(s) are returned. Valid modes are: | Constant Value | Description | |-------------------------------------------|-------------| | Horde_Imap_Client::MBOX_SUBSCRIBED | Return subscribed mailboxes | | Horde_Imap_Client::MBOX_SUBSCRIBED_EXISTS | Return subscribed mailboxes that exist on the server | | Horde_Imap_Client::MBOX_UNSUBSCRIBED | Return unsubscribed mailboxes | | Horde_Imap_Client::MBOX_ALL | Return all mailboxes regardless of subscription status | | Horde_Imap_Client::MBOX_ALL_SUBSCRIBED | Return all mailboxes regardless of subscription status, and ensure the '\subscribed' attribute is set if mailbox is subscribed | The third argument contains additional options to modify the return values. ```listMailboxes()``` returns an array with keys as UTF-8 mailbox names and values as arrays with these keys: | Key | Value | |------------|-------| | attributes | ```(array)``` List of lower-cased attribute values (if 'attributes' option is true) | | delimiter | ```(string)``` The mailbox delimiter character | | mailbox | ```(Horde_Imap_Client_Mailbox)``` The mailbox object | | status | ```(array)``` Status information | See the [API Documentation](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Base.html#method_listMailboxes) for more detailed explanations of the options and return values. Example: ```php // This example will return status information for all subscribed mailboxes // (confirmed to exist on the server) in the base directory that begin with // "sent-mail". $list = $client->listMailboxes( 'sent-mail%', Horde_Imap_Client::MBOX_SUBSCRIBED_EXISTS ); ``` ### Mailbox Creation [```createMailbox()```](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Exception.html#method_createMailbox) will create a new mailbox or throw an Exception on error or if the mailbox already exists. Example: ```php $new_mailbox = new Horde_Imap_Client_Mailbox('NewMailboxName'); try { $client->createMailbox($new_mailbox); // Success } catch (Horde_Imap_Client_Exception $e) { // Failure } ``` ### Mailbox Deletion [```deleteMailbox()```](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Exception.html#method_deleteMailbox) will delete an existing mailbox or throw an Exception on error or if the mailbox doesn't exist. Example: ```php $existing_mailbox = new Horde_Imap_Client_Mailbox('ExistingMailboxName'); try { $client->deleteMailbox($existing_mailbox); } catch (Horde_Imap_Client_Exception $e) { // Failure } ``` ### Mailbox Rename [```renameMailbox()```](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Exception.html#method_renameMailbox) will rename an existing mailbox or throw an Exception on error or if the mailbox doesn't exist. Example: ```php $old_mailbox = new Horde_Imap_Client_Mailbox('OldMailboxName'); $new_mailbox = new Horde_Imap_Client_Mailbox('NewMailboxName'); try { $client->renameMailbox($old_mailbox, $new_mailbox); } catch (Horde_Imap_Client_Exception $e) { // Failure } ``` ### Mailbox Subscriptions [```subscribeMailbox()```](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Exception.html#method_subscribeMailbox) sets the subscription status of a mailbox or throws an Exception on error. Example: ```php $mailbox = new Horde_Imap_Client_Mailbox('MailboxName'); try { // Subscribe $client->subscribeMailbox($mailbox, true); // Unsubscribe $client->subscribeMailbox($mailbox, false); } catch (Horde_Imap_Client_Exception $e) { // Failure } ``` ### Mailbox Status [```status()```](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Exception.html#method_status) - TODO ## Message Storage Actions To store a message on the mail server, the [```append()```](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Exception.html#method_append) command is used. Example of simple usage - adding a single message with two flags set (```\Seen``` and ```OtherFlag```): ```php $mailbox = new Horde_Imap_Client_Mailbox('MailboxName'); $message_data = << Subject: Test Message This is a test message. EOT; try { $uids = $client->append( $mailbox, array( array( 'data' => $message_data, 'flags' => array('\Seen', 'OtherFlag') ) ) ); // $uids is a Horde_Imap_Client_Ids object that contains the UID(s) of // the messages that were successfully appended to the mailbox. } catch (Horde_Imap_Client_Exception $e) { // Failure } ``` ## Message Actions ### General Information For Message Actions #### Working with a Single Mailbox The following examples assume that the user wants to work with the messages contained in their INBOX. #### Loading Mailbox There is *no need* to provide commands to login and/or switch to a mailbox. These actions are handled on-demand by the library. ### Listing Messages The [```search()```](search('INBOX'); // $results['match'] contains a Horde_Imap_Client_Ids object, containing the // list of UIDs in the INBOX. $uids = $results['match']; ``` To filter the list of messages returned by ```search()```, a [Horde_Imap_Client_Search_Query](http://dev.horde.org/api/master/lib/Imap_Client/classes/Horde_Imap_Client_Search_Query.html) object can be passed as the second parameter to ```search()```. If not present, all messages in the mailbox are returned. The third argument to ```search()``` allows additional search parameters to be specified, such as the prefered sort order. ```php // Advanced example to return the list of all unseen UIDs in the INBOX // younger than a week, sorted by the From address. $query = new Horde_Imap_Client_Search_Query(); $query->flag(Horde_Imap_Client::FLAG_SEEN, false); // 604800 = 60 seconds * 60 minutes * 24 hours * 7 days (1 week) $query->intervalSearch( 604800, Horde_Imap_Client_Search_Query::INTERVAL_YOUNGER ); $results = $client->search('INBOX', $query, array( 'sort' => array( Horde_Imap_Client::SORT_FROM ) )); // $results['match'] contains a Horde_Imap_Client_Ids object, containing the // list of UIDs in the INBOX. $uids = $results['match']; ``` Horde_Imap_Client-2.29.15/doc/Horde/Imap/Client/examples/tutorial.rst0000664000175000017500000004240413150761653023443 0ustar janjanHorde\_Imap\_Client Documentation ================================= General Information ------------------- Autoloading ~~~~~~~~~~~ Horde/Imap\_Client does not `include() `__ its own files, so an autoloader must be registered that will load the Horde/Imap\_Client files from its directory. If installing via Composer, user the generated include file to load the library. If using PEAR, or installing from source, `Horde's Autoloader `__ package can be used to do this for you (or any other `PSR-0 `__ compliant autoloader). Constructor ~~~~~~~~~~~ Interaction with the mail server is handled through a ``Horde_Imap_Client_Base`` object. The object class will be either: - ```Horde_Imap_Client_Socket`` `__ - IMAP servers - ```Horde_Imap_Client_Socket_Pop3`` `__ - POP3 servers The minimum necessary configuration needed for the Client constructor is the ``username`` and ``password``. Although default values can be used for the ``hostspec``, ``port``, and ``secure`` options, it is generally a good idea to explicitly set these values to aid in debugging connection issues. Debugging ^^^^^^^^^ Debug output of the server protocol communication can be obtained by providing the ``debug`` option. Acceptable values are any PHP supported wrapper that can be opened via the ```fopen()`` `__ command. A plain string is inerpreted as a filename, which is probably what most people will want to use. Caching ^^^^^^^ Horde/Imap\_Client provides transparent caching support by using the Horde\_Cache package. Cached information includes the following: - Envelope information - Message structure - IMAP flags (if the IMAP `CONDSTORE `__ capability exists on the server) - Search results for a mailbox - Threading results for a mailbox To use, a Horde\_Cache backend should be configured and provided to the Horde\_Imap\_Client constructor in the ``cache`` option. The format of that option can be found in the `constructor API Documentation `__. Information about how to create a Horde\_Cache object can be found in the `Horde\_Cache API Documentation `__. A simple cache driver configuration is illustrated in the example below. Example ^^^^^^^ A sample constructor instantation (all further examples assume that this command has been performed and a client object is present in the ``$client`` variable): .. code:: php try { /* Connect to an IMAP server. * - Use Horde_Imap_Client_Socket_Pop3 (and most likely port 110) to * connect to a POP3 server instead. */ $client = new Horde_Imap_Client_Socket(array( 'username' => 'foo', 'password' => 'secret', 'hostspec' => 'localhost', 'port' => '143', 'secure' => 'tls', // OPTIONAL Debugging. Will output IMAP log to the /tmp/foo file 'debug' => '/tmp/foo', // OPTIONAL Caching. Will use cache files in /tmp/hordecache. // Requires the Horde/Cache package, an optional dependency to // Horde/Imap_Client. 'cache' => array( 'backend' => new Horde_Imap_Client_Cache_Backend_Cache(array( 'cacheob' => new Horde_Cache(new Horde_Cache_Storage_File(array( 'dir' => '/tmp/hordecache' ))) )) ) )); } catch (Horde_Imap_Client_Exception $e) { // Any errors will cause an Exception. } The full list of options can be found in the `API Documentation `__. Error Handling/Exceptions ~~~~~~~~~~~~~~~~~~~~~~~~~ As noted in the constructor example, all errors encountered by the library will cause exceptions of the ``Horde_Imap_Client_Exception`` class (or a subclass of that base class) to be thrown. The exception message will contain a *translated* version of the error message. If the "raw" English version of the message is needed - i.e. for logging purposes - it can be found in the ``$raw_msg`` property. Further server debug information *might* be found in the ``$details`` property, but this is not guaranteed. - `API Documentation of the base exception class `__ - `Error Message Code Constants `__ IMAP Alerts ^^^^^^^^^^^ IMAP alerts are *REQUIRED* by the IMAP specification to be displayed to the user. These alerts should be caught/handled in the client code by observing the ```Horde_Imap_Client_Base_Alerts`` `__ object, which is available as the ``$alerts_ob`` property in the Horde\_Imap\_Client\_Base object. Example: .. code:: php // First, define an observer in your code: class Foo implements SplObserver { public function update(SplSubject $subject) { if ($subject instanceof Horde_Imap_Client_Base_Alerts) { // This is where your code processes the alert. $alert = $subject->getLast(); // Alert text: $alert->alert // Alert type (optional): $alert->type } } } $foo = new Foo(); // Then, register the observer with the client object. $client->alerts_ob->attach($foo); General Function Information ---------------------------- Manual Mailbox Loading Not Necessary ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ NOTE: All mailbox arguments to methods in Horde/Imap\_Client take the UTF-8 version of the mailbox name. There is no need to worry about converting from/to the internal UTF7-IMAP charset used on IMAP servers. Alternatively, you can use `Horde\_Imap\_Client\_Mailbox `__ objects as the mailbox argument. This object can automatically convert the mailbox name if in UTF7-IMAP for you. Example: .. code:: php // This creates a mailbox object from UTF-8 data. $mbox1 = Horde_Imap_Client_Mailbox::create('Envoyé'); // This creates a mailbox object from UTF7-IMAP data. $mbox2 = Horde_Imap_Client_Mailbox::create('Envoy&AOk-', true); // $result === true $result = ($mbox1 == $mbox2); UID Object Return ^^^^^^^^^^^^^^^^^ Many method either require UIDs as an argument or return a list of UIDs. This is done by using the `Horde\_Imap\_Client\_Ids `__ object. This object implements both the ``Countable`` and ``Traversable`` classes, so it can be used directly in ``count()`` and ``foreach()`` commands. If a raw array list of ids is needed, it can be obtained from the object via the ``$ids`` property. Mailbox Actions --------------- The following are actions dealing with mailbox-level actions. Actions dealing with the contents of the mailboxes are discussed below in the "Message Actions" section. Listing Mailboxes ~~~~~~~~~~~~~~~~~ Listing mailboxes is accomplished via the ```listMailboxes()`` `__ function. The search query (or multiple queries) is passed in via the first argument. The second argument defines which mailboxes that match the search pattern(s) are returned. Valid modes are: +-------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ | Constant Value | Description | +=================================================+=======================================================================================================================+ | Horde\_Imap\_Client::MBOX\_SUBSCRIBED | Return subscribed mailboxes | +-------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ | Horde\_Imap\_Client::MBOX\_SUBSCRIBED\_EXISTS | Return subscribed mailboxes that exist on the server | +-------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ | Horde\_Imap\_Client::MBOX\_UNSUBSCRIBED | Return unsubscribed mailboxes | +-------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ | Horde\_Imap\_Client::MBOX\_ALL | Return all mailboxes regardless of subscription status | +-------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ | Horde\_Imap\_Client::MBOX\_ALL\_SUBSCRIBED | Return all mailboxes regardless of subscription status, and ensure the '' attribute is set if mailbox is subscribed | +-------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+ The third argument contains additional options to modify the return values. ``listMailboxes()`` returns an array with keys as UTF-8 mailbox names and values as arrays with these keys: +--------------+-------------------------------------------------------------------------------------+ | Key | Value | +==============+=====================================================================================+ | attributes | ``(array)`` List of lower-cased attribute values (if 'attributes' option is true) | +--------------+-------------------------------------------------------------------------------------+ | delimiter | ``(string)`` The mailbox delimiter character | +--------------+-------------------------------------------------------------------------------------+ | mailbox | ``(Horde_Imap_Client_Mailbox)`` The mailbox object | +--------------+-------------------------------------------------------------------------------------+ | status | ``(array)`` Status information | +--------------+-------------------------------------------------------------------------------------+ See the `API Documentation `__ for more detailed explanations of the options and return values. Example: .. code:: php // This example will return status information for all subscribed mailboxes // (confirmed to exist on the server) in the base directory that begin with // "sent-mail". $list = $client->listMailboxes( 'sent-mail%', Horde_Imap_Client::MBOX_SUBSCRIBED_EXISTS ); Mailbox Creation ~~~~~~~~~~~~~~~~ ```createMailbox()`` `__ will create a new mailbox or throw an Exception on error or if the mailbox already exists. Example: .. code:: php $new_mailbox = new Horde_Imap_Client_Mailbox('NewMailboxName'); try { $client->createMailbox($new_mailbox); // Success } catch (Horde_Imap_Client_Exception $e) { // Failure } Mailbox Deletion ~~~~~~~~~~~~~~~~ ```deleteMailbox()`` `__ will delete an existing mailbox or throw an Exception on error or if the mailbox doesn't exist. Example: .. code:: php $existing_mailbox = new Horde_Imap_Client_Mailbox('ExistingMailboxName'); try { $client->deleteMailbox($existing_mailbox); } catch (Horde_Imap_Client_Exception $e) { // Failure } Mailbox Rename ~~~~~~~~~~~~~~ ```renameMailbox()`` `__ will rename an existing mailbox or throw an Exception on error or if the mailbox doesn't exist. Example: .. code:: php $old_mailbox = new Horde_Imap_Client_Mailbox('OldMailboxName'); $new_mailbox = new Horde_Imap_Client_Mailbox('NewMailboxName'); try { $client->renameMailbox($old_mailbox, $new_mailbox); } catch (Horde_Imap_Client_Exception $e) { // Failure } Mailbox Subscriptions ~~~~~~~~~~~~~~~~~~~~~ ```subscribeMailbox()`` `__ sets the subscription status of a mailbox or throws an Exception on error. Example: .. code:: php $mailbox = new Horde_Imap_Client_Mailbox('MailboxName'); try { // Subscribe $client->subscribeMailbox($mailbox, true); // Unsubscribe $client->subscribeMailbox($mailbox, false); } catch (Horde_Imap_Client_Exception $e) { // Failure } Mailbox Status ~~~~~~~~~~~~~~ ```status()`` `__ - TODO Message Storage Actions ----------------------- To store a message on the mail server, the ```append()`` `__ command is used. Example of simple usage - adding a single message with two flags set (``\Seen`` and ``OtherFlag``): .. code:: php $mailbox = new Horde_Imap_Client_Mailbox('MailboxName'); $message_data = << Subject: Test Message This is a test message. EOT; try { $uids = $client->append( $mailbox, array( array( 'data' => $message_data, 'flags' => array('\Seen', 'OtherFlag') ) ) ); // $uids is a Horde_Imap_Client_Ids object that contains the UID(s) of // the messages that were successfully appended to the mailbox. } catch (Horde_Imap_Client_Exception $e) { // Failure } Message Actions --------------- General Information For Message Actions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Working with a Single Mailbox ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following examples assume that the user wants to work with the messages contained in their INBOX. Loading Mailbox ^^^^^^^^^^^^^^^ There is *no need* to provide commands to login and/or switch to a mailbox. These actions are handled on-demand by the library. Listing Messages ~~~~~~~~~~~~~~~~ The ```search()`` <`__ command is used to list the messages in a mailbox. It only requires a mailbox name for basic usage, and will return a list of unsorted UIDs in the mailbox. .. code:: php // Get a list of all UIDs in the INBOX. $results = $client->search('INBOX'); // $results['match'] contains a Horde_Imap_Client_Ids object, containing the // list of UIDs in the INBOX. $uids = $results['match']; To filter the list of messages returned by ``search()``, a `Horde\_Imap\_Client\_Search\_Query `__ object can be passed as the second parameter to ``search()``. If not present, all messages in the mailbox are returned. The third argument to ``search()`` allows additional search parameters to be specified, such as the prefered sort order. .. code:: php // Advanced example to return the list of all unseen UIDs in the INBOX // younger than a week, sorted by the From address. $query = new Horde_Imap_Client_Search_Query(); $query->flag(Horde_Imap_Client::FLAG_SEEN, false); // 604800 = 60 seconds * 60 minutes * 24 hours * 7 days (1 week) $query->intervalSearch( 604800, Horde_Imap_Client_Search_Query::INTERVAL_YOUNGER ); $results = $client->search('INBOX', $query, array( 'sort' => array( Horde_Imap_Client::SORT_FROM ) )); // $results['match'] contains a Horde_Imap_Client_Ids object, containing the // list of UIDs in the INBOX. $uids = $results['match']; Horde_Imap_Client-2.29.15/doc/Horde/Imap/Client/COPYING0000664000175000017500000005765613150761653020302 0ustar janjan GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Horde_Imap_Client-2.29.15/doc/Horde/Imap/Client/UPGRADING0000664000175000017500000005742113150761653020500 0ustar janjan============================= Upgrading Horde_Imap_Client ============================= :Contact: dev@lists.horde.org .. contents:: Contents .. section-numbering:: This lists the API changes between releases of the package. Upgrading to 2.29.0 =================== SCRAM-SHA-1 authentication is now supported by both the IMAP and POP3 drivers. - Horde_Imap_Client_Auth_Scram This class has been added. Upgrading to 2.28.0 =================== - Horde_Imap_Client_Interaction_Command Added the $on_success and $pipeline properties. If the callback defined in $on_error returns true, the command will be treated as successful. Upgrading to 2.27.0 =================== - Horde_Imap_Client_Base - Constructor Added the 'context' parameter. Upgrading to 2.26.0 =================== - Horde_Imap_Client_Base Added the $alerts_ob property. - alerts() This method has been deprecated. Add an observer to the $alerts_ob property instead. Upgrading to 2.25.0 =================== - Horde_Imap_Client_Data_Format_Astring_Nonascii - Horde_Imap_Client_Data_Format_Nstring_Nonascii - Horde_Imap_Client_Data_Format_String_Nonascii Extended base classes to indicate that IMAP data element supports non-ASCII characters. - Horde_Imap_Client_Data_Format_String_Support_Nonascii Added interface to indicate which IMAP data string elements support non-ASCII characters. - Horde_Imap_Client_Url This object has been deprecated. Use the Horde_Imap_Client_Url_* objects instead. Upgrading to 2.24.0 =================== - Horde_Imap_Client The $capabilities_deps property has been deprecated. - Horde_Imap_Client_Base Added the $capability, $search_charset, and $url properties. - capability() - queryCapability() These methods have been deprecated. Use the $capability property instead. - validSearchCharset() This method has been deprecated. Use the query() method of the $search_charset property instead. - Horde_Imap_Client_Interaction_Command Added the $on_error property. - Horde_Imap_Client_Search_Query - build() This method now expects either a Horde_Imap_Client_Base object, a Horde_Imap_Client_Data_Capability object, or null as its argument. Passing a list of extensions as the argument is deprecated. Upgrading to 2.23.0 =================== - Horde_Imap_Client_Base - listMailboxes() Added the Horde_Imap_Client::MBOX_ALL_SUBSCRIBED $mode option. Removed the 'delimiter' option (delimiter information is always returned now). Upgrading to 2.22.0 =================== - Horde_Imap_Client_Exception - messagePrintf() This method has been added. Upgrading to 2.21.0 =================== - Horde_Imap_Client These constants have been deprecated: - NS_PERSONAL - NS_OTHER - NS_SHARED - Horde_Imap_Client_Base - getNamespaces() Add optional parameter to allow a Horde_Imap_Client_Namespace_List object to be returned, instead of an array. (This will become the default action in 3.0.) Upgrading to 2.20.0 =================== - Horde_Imap_Client_Ids The 'min' and 'max' properties have been added. Upgrading to 2.19.0 =================== - Horde_Imap_Client_Base - copy() Added the 'force_map' parameter. - Horde_Imap_Client_Cache_Backend_Hashtable - Constructor Added the 'lifetime' configuration parameter. Upgrading to 2.18.0 =================== - Horde_Imap_Client_Exception Added the $raw_msg parameter. Upgrading to 2.17.0 =================== - Horde_Imap_Client_Cache_Backend_Hashtable Added a Hashtable specific caching driver. - Horde_Imap_Client_Ids - remove() This method has been added. Upgrading to 2.16.0 =================== - Horde_Imap_Client_Base - Constructor Added 'tlsv1' option for the 'secure' configuration parameter. - Horde_Imap_Client_Password_Xoauth2 Added class to abstract production of the necessary token for XOAUTH2 SASL authentication. Upgrading to 2.15.0 =================== - Horde_Imap_Client_Base - Constructor Added true as an option for the 'secure' configuration parameter. Upgrading to 2.14.0 =================== - Horde_Imap_Client_Base - Constructor The 'encryptKey' parameter is deprecated. Instead, allow a Horde_Imap_Client_Base_Password object to be passed via the 'password' parameter. - $statuscache This property has been added. - status() Added the Horde_Imap_Client::STATUS_FORCE_REFRESH flag. - Horde_Imap_Client_Socket - Constructor The 'xoauth2_token' parameter now accepts a Horde_Imap_Client_Base_Password object. Upgrading to 2.13.0 =================== - Horde_Imap_Client_Socket - Constructor Added the 'xoauth2_token' parameter. Upgrading to 2.12.0 =================== - Horde_Imap_Client_Base - status() Added the Horde_Imap_Client::STATUS_RECENT_TOTAL return value. Upgrading to 2.11.0 =================== - Horde_Imap_Client_Data_Fetch Added the setDowngraded() and isDowngraded() methods. Upgrading to 2.10.0 =================== - Horde_Imap_Client_Base - expunge() The 'delete' option was added. - status() The $mailbox argument now supports array input (and will return an array of multiple mailboxes). Additionally, the third $options parameter has been added. - statusMultiple() This method has been deprecated. Use status() instead. - Horde_Imap_Client_Interaction_Client This class is deprecated (and no longer used internally). Upgrading to 2.9.0 ================== - Horde_Imap_Client_Base The 'cacheob', 'lifetime', and 'slicesize' parameters to the 'cache' constructor option have been deprecated. Use the 'backend' parameter instead. - Horde_Imap_Client_Cache Added the clear() method. Upgrading to 2.8.0 ================== - Horde_Imap_Client_Base The 'nocache' option was added to fetch(). - Horde_Imap_Client_Data_Sync The following public properties have been added: - $highestmodseq - $map (static value) - $messages - $uidnext - $uidvalidity Upgrading to 2.7.0 ================== - Horde_Imap_Client_Ids The split() method was added. Upgrading to 2.6.0 ================== - Horde_Imap_Client_Fetch_Results The clear() method was added. Upgrading to 2.5.0 ================== - Horde_Imap_Client_Base The 'exists' option was added to fetch(). Upgrading to 2.4.0 ================== - Horde_Imap_Client_Base The following 'sort' criteria have been added to search(): - SORT_DISPLAYFROM_FALLBACK - SORT_DISPLAYTO_FALLBACK Upgrading to 2.3.0 ================== - Horde_Imap_Client_Data_Format_String The following methods have been added: - getStream() Upgrading to 2.2.0 ================== - Horde_Imap_Client_Base The following methods have been added: - getSyncToken() - sync() The following methods have been marked as deprecated and will be removed in 3.0: - getCacheId() - parseCacheId() Upgrading to 2.1.0 ================== The Horde_Imap_Client_Ids_Map class has been added. - Horde_Imap_Client_Cache The following config options have changed: - debug Now requires a Horde_Imap_Client_Base_Debug object. The previous 'true' value will be ignored. Upgrading to 2.0.0 ================== The cclient drivers have been removed. Exception logging has been removed; the calling code is now responsible for logging any errors. - Horde_Imap_Client - factory() The factory method has been removed. The client driver should instead be directly instantiated. - Horde_Imap_Client_Base The following config options have been removed: - statuscache The following properties have changed: - $cache This public member variable has been removed. Obtain the cache object by calling getCache() instead. - $utils This public member variable has been removed. The following methods have changed: - append() The $mailbox parameter can no longer be a UTF7-IMAP string. - copy() The $source and $dest parameters can no longer be UTF7-IMAP strings. - createMailbox() The $mailbox parameter can no longer be a UTF7-IMAP string. - currentMailbox() The 'mailbox' portion of the return value is always returned as a Horde_Imap_Client_Mailbox object. The $options parameter has been removed. - deleteACL() This method has been added. - deleteMailbox() The $mailbox parameter can no longer be a UTF7-IMAP string. - expunge() The $mailbox parameter can no longer be a UTF7-IMAP string. - fetch() The 'fetch_res' option has been removed. The 'vanished' option has been removed - use the vanished() method instead. The $mailbox parameter can no longer be a UTF7-IMAP string. Results are now returned as a Horde_Imap_Client_Fetch_Results object. - fetchCacheIgnore() This method has been removed. Use getParam()/setParam() to change parameter values instead. - fetchFromSectionString() This method has been removed. - getNamespaces() The array keys, 'name' key, and 'translation' key in the return array return UTF-8 strings (not UTF7-IMAP). - getACL() The $mailbox parameter can no longer be a UTF7-IMAP string. - getCacheId() The $mailbox parameter can no longer be a UTF7-IMAP string. - getMetadata() The $mailbox parameter can no longer be a UTF7-IMAP string. - getMyACLRights() The $mailbox parameter can no longer be a UTF7-IMAP string. - getQuota() The $root parameter can no longer be a UTF7-IMAP string. - getQuotaRoot() The $mailbox parameter can no longer be a UTF7-IMAP string. - listACLRights() The $mailbox parameter can no longer be a UTF7-IMAP string. - listMailboxes() The return array keys are in UTF-8 (not UTF7-IMAP). The 'mailbox' return value is returned as a Horde_Imap_Client_Mailbox object. The 'utf8' parameter has been removed. The 'pattern' parameter now handles Horde_Imap_Client_Mailbox objects differently than string patterns. - openMailbox() The $mailbox parameter can no longer be a UTF7-IMAP string. - parseCommandArray() This method has been removed. - renameMailbox() The $old and $new parameters can no longer be UTF7-IMAP strings. - search() The $mailbox parameter can no longer be a UTF7-IMAP string. The following constants for use with 'results' have been deprecated (use SEARCH_RESULTS_* constants instead): - SORT_RESULTS_COUNT - SORT_RESULTS_MATCH - SORT_RESULTS_MAX - SORT_RESULTS_MIN - SORT_RESULTS_SAVE - setACL() The $mailbox parameter can no longer be a UTF7-IMAP string. The $options['remove'] parameter has been replaced by a more flexible $options['action'] parameter. To delete all ACLs for an identifier use the new deleteACL() method. - setQuota() The $root parameter can no longer be a UTF7-IMAP string. - status() The $mailbox parameter can no longer be a UTF7-IMAP string. The STATUS_LASTMODSEQ and STATUS_LASTMODSEQUIDS return options have been removed. - statusMultiple() The return array keys are in UTF-8 (not UTF7-IMAP). The $mailboxes parameter can no longer contain UTF7-IMAP strings. - store() The $mailbox parameter can no longer be a UTF7-IMAP string. - subscribeMailbox() The $mailbox parameter can no longer be a UTF7-IMAP string. - thread() The $mailbox parameter can no longer be a UTF7-IMAP string. - Horde_Imap_Client_Cache Removed the singleton() method. The 'hostspec', 'port', and 'username' parameters to the constructor have been removed. - Horde_Imap_Client_Data_Envelope Address entries are now returned as a Horde_Mail_Rfc822_List object. The following properties have been removed: - bcc_decoded - bcc_group - cc_decoded - cc_group - from_decoded - reply_to_decoded - sender_decoded - subject_decoded - to_decoded - to_group - Horde_Imap_Client_Data_Thread - Constructor The format of the first parameter ($data) has changed. - getRawData() This method has been removed. - getThread() This method now returns a list of objects. This is now the way that individual indices of a thread are accessed. - getThreadBase() This method has been removed (see getThread() for replacement). - getThreadIndent() This method has been removed (see getThread() for replacement). - getType() This method has been added. - lastInLevel() This method has been removed (see getThread() for replacement). - messageList() This method now returns the list of IDs in a Horde_Imap_Client_Ids object. - Horde_Imap_Client_Exception These constants have been removed: - DRIVER_NOT_FOUND - POP3_NOT_SUPPORTED - NOSUPPORTIMAPEXT - CATENATE_BADURL - BADSEARCH - Horde_Imap_Client_Exception_NoSupportExtension The $extension property has been added. - Horde_Imap_Client_Mailbox get() no longer supports the null argument to the $utf7imap parameter. - Horde_Imap_Client_Search_Query The $queries argument to andSearch() and orSearch() can be a base query in addition to an array of queries. The second argument to charset() has been changed to a boolean indicating whether the current text queries should be converted to the new charset provided. - Horde_Imap_Client_Sort This class has been removed. Mailbox sorting can now be accomplished with the Horde_Imap_Client_Mailbox_List class. - Horde_Imap_Client_Utf7imap The default argument for the $force parameter to Utf8ToUtf7Imap() has changed to boolean true. - Horde_Imap_Client_Utils This class has been removed. Information on the previous methods (and their replacements, if any) can be found below. - createUrl() This method has been removed. URL creation can now be accomplished with the Horde_Imap_Client_Url object. - escape() This method has been removed. String escaping can now be accomplished via the Horde_Imap_Client_Data_Format_* objects. - fromSequenceString() This method has been removed. Sequence string parsing is now natively supported within the Horde_Imap_Client_Ids object. - getBaseSubject() This method has been removed. Bsae subject determination is now handled by the Horde_Imap_Client_Utils_BaseSubject class. - parseCommandArray() This method has been removed. - parseUrl() This method has been removed. URL parsing can now be accomplished with the Horde_Imap_Client_Url object. - removeBareNewlines() This method has been removed. - stripNonAtomChars() This method has been removed. The same functionality can now be accomplished by using the stripNonAtomCharacters() method of the Horde_Imap_Client_Data_Format_Atom object. - toSequenceString() This method has been removed. Sequence string generation is now natively supported within the Horde_Imap_Client_Ids object. - Horde_Imap_Client_Utils_Pop3 This class has been removed. Upgrading To 1.5.0 ================== The following properties have been added to the Horde_Imap_Client_Data_Envelope object: - bcc_group - cc_group - to_group Address properties (array return values) returned from Horde_Imap_Client_Data_Envelope are now Horde_Mail_Rfc822_Address objects. These objects behave identical to the arrays that were returned previously. The following methods have been added: - Horde_Imap_Client_Base#setParam() Upgrading To 1.4.0 ================== Several exception codes have been deprecated: - DRIVER_NOT_FOUND - CATENATE_BADURL - BADSEARCH These are coding errors, not run-time errors, so SPL Exceptions are thrown instead of Horde_Imap_Client_Exceptions with these codes. These exception codes have also been deprecated: - NOSUPPORTIMAPEXT - POP3_NOTSUPPORTED Instead, a Horde_Imap_Client_Exception_NoSupportExtension will be thrown. This class is an extension of Horde_Imap_Client_Exception, so current try/catch statements will automatically catch these exceptions. Horde_Imap_Client_Exception messages are now translated. Additionally, debug information from the server MAY be available in the 'details' property of the Exception object rather than being added to the error message. Upgrading To 1.3.0 ================== The Cclient drivers have been removed; they are instead mapped to the appropriate Socket drivers. No code needs to be changed for now as this will happen automatically. However, the 'Cclient' and 'Cclient_Pop3' driver names are deprecated and will be removed in 2.0.0. Upgrading To 1.2.0 ================== There has been a major change in the way mailbox names are handled in this version. Due to ambiguities with auto-detecting UTF-8 vs. UTF7-IMAP, all mailbox method parameters and return values are now Horde_Imap_Client_Mailbox objects. These objects, when cast to a string, will return the UTF-8 version of the mailbox. All other non-mailbox strings that previously could be passed in as either UTF7-IMAP or UTF-8 are now REQUIRED to be passed in as UTF-8. Auto-detection will still work, but is deprecated, will be removed in 2.0.0, and is not guaranteed to produce proper results for all mailbox names. Changed Return Values --------------------- The following return values have changed: - Horde_Imap_Client_Base#currentMailbox() If the 'utf8' parameter is true, a Horde_Imap_Client_Mailbox object will be returned (an equivalent string representation to the previous behavior of returning a UTF-8 string). - Horde_Imap_Client_Base#getNamespaces() The return array keys and the 'name' parameter are returned in UTF7-IMAP (the documentation was previously unclear as to the charset of these items). - Horde_Imap_Client_Base#listMailboxes() If both the 'flat' and 'utf8' parameters are true, the array values will be Horde_Imap_Client_Mailbox objects, instead of a string (an equivalent string representation to the previous behavior of returning a UTF-8 string). If the 'flat' parameter is false and the 'utf8' parameter is true, the 'mailbox' array key will be a Horde_Imap_Client_Mailbox object instead of a string (an equivalent string representation to the previous behavior of returning a UTF-8 string). - Horde_Imap_Client_Base#statusMultiple() The return array keys are returned in UTF7-IMAP (the documentation was previously unclear as to the charset of these keys). Deprecated Methods ------------------ The following methods are deprecated and will be removed in 2.0.0: - Horde_Imap_Client_Cache::singleton() Use Horde_Imap_Client_Cache::factory() instead. - Horde_Imap_Client_Base#parseCommandArray() Use Horde_Imap_Client_Utils#parseCommandArray() instead. Deprecated Parameters --------------------- - Horde_Imap_Client_Base#currentMailbox() The 'utf8' parameter has been deprecated. The 'mailbox' return value will exclusively return a Horde_Imap_Client_Mailbox object in 2.0.0. Drivers ------- The unmaintained Mock driver has been removed. Method Parameter Changes ------------------------ - Horde_Imap_Client_Base#append() - Horde_Imap_Client_Base#copy() - Horde_Imap_Client_Base#createMailbox() - Horde_Imap_Client_Base#deleteMailbox() - Horde_Imap_Client_Base#expunge() - Horde_Imap_Client_Base#fetch() - Horde_Imap_Client_Base#fetchFromSectionString() - Horde_Imap_Client_Base#getACL() - Horde_Imap_Client_Base#getCacheId() - Horde_Imap_Client_Base#getMetadata() - Horde_Imap_Client_Base#getMyACLRights() - Horde_Imap_Client_Base#getQuota() - Horde_Imap_Client_Base#getQuotaRoot() - Horde_Imap_Client_Base#listACLRights() - Horde_Imap_Client_Base#openMailbox() - Horde_Imap_Client_Base#renameMailbox() - Horde_Imap_Client_Base#search() - Horde_Imap_Client_Base#setACL() - Horde_Imap_Client_Base#setMetadata() - Horde_Imap_Client_Base#setQuota() - Horde_Imap_Client_Base#status() - Horde_Imap_Client_Base#statusMultiple() - Horde_Imap_Client_Base#store() - Horde_Imap_Client_Base#subscribeMailbox() - Horde_Imap_Client_Base#thread() These methods now require the mailbox parameter(s) to be passed in as either a Horde_Imap_Client_Mailbox object (RECOMMENDED) or a UTF-8 string. Passing in a UTF7-IMAP string is DEPRECATED and will be removed in 2.0.0. (The limitation of allowing UTF7-IMAP strings to be continued to be passed in for now is that auto-detection remains necessary. Passing in UTF-8 strings will thus break for certain mailbox names - the only way to guarantee proper mailbox handling for 1.2.0+ is to pass in Mailbox objects.) - Horde_Imap_Client_Base#getMetadata() The $entries parameter now requires the entries to be passed in as UTF-8 strings ONLY (UTF7-IMAP no longer allowed). Auto-detection will be removed in 2.0.0. To ensure proper mailbox handling in 1.2.0+, you can pass the entries as Horde_Imap_Client_Mailbox objects. - Horde_Imap_Client_Base#getNamespaces() The $additional parameter now requires the namespaces to be passed in as UTF-8 strings ONLY (UTF7-IMAP no longer allowed). Auto-detection will be removed in 2.0.0. To ensure proper mailbox handling in 1.2.0+, you can pass the namespace names as Horde_Imap_Client_Mailbox objects. - Horde_Imap_Client_Base#listMailboxes() The $pattern parameter now requires the patterns to be passed in as UTF-8 strings ONLY (UTF7-IMAP no longer allowed). Auto-detection will be removed in 2.0.0. To ensure proper mailbox handling in 1.2.0+, you can pass the patterns as Horde_Imap_Client_Mailbox objects. The 'utf8' parameter has been removed. - Horde_Imap_Client_Base#listACLRights() - Horde_Imap_Client_Base#setACL() The $identifier parameter now requires the identifiers to be passed in as UTF-8 strings ONLY (UTF7-IMAP no longer allowed). Auto-detection will be removed in 1.3. To ensure proper mailbox handling in 1.2.0+, you can pass the identifiers as Horde_Imap_Client_Mailbox objects. - Horde_Imap_Client_Cache#__construct() A new required parameter 'baseob' has been added. This replaces the 'hostspec', 'port', and 'username' parameters, which are deprecated and will be removed in 2.0.0. The 'debug' parameter is now a boolean indicating whether debugging is desired; debug output is now controlled via the Base object passed in through 'baseob'. The old usage - passing in a resource - is IMMEDIATELY deprecated and will be ignored. - Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap() Added the $force parameter. New Methods ----------- - Horde_Imap_Client_Base#getIdsOb() - Horde_Imap_Client_Base#writeDebug() New Objects ----------- - Horde_Imap_Client_Ids - Horde_Imap_Client_Ids_Pop3 - Horde_Imap_Client_Mailbox - Horde_Imap_Client_Utils_Pop3 Upgrading To 1.1.0 ================== New Object Properties --------------------- - Horde_Imap_Client_Data_Envelope Added properties to obtain MIME decoded envelope information. New properties: 'bcc_decoded', 'cc_decoded', 'from_decoded', 'reply_to_decoded', 'sender_decoded', 'subject_decoded', 'to_decoded' Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Auth/DigestMD5.php0000664000175000017500000001572313150761653022374 0ustar janjan * @author Michael Slusarz * @copyright 2002-2003 Richard Heyes * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Auth_DigestMD5 { /** * Digest response components. * * @var string */ protected $_response; /** * Generate the Digest-MD5 response. * * @param string $id Authentication id (username). * @param string $pass Password. * @param string $challenge The digest challenge sent by the server. * @param string $hostname The hostname of the machine connecting to. * @param string $service The service name (e.g. 'imap', 'pop3'). * * @throws Horde_Imap_Client_Exception */ public function __construct($id, $pass, $challenge, $hostname, $service) { $challenge = $this->_parseChallenge($challenge); $cnonce = $this->_getCnonce(); $digest_uri = sprintf('%s/%s', $service, $hostname); /* Get response value. */ $A1 = sprintf('%s:%s:%s', pack('H32', hash('md5', sprintf('%s:%s:%s', $id, $challenge['realm'], $pass))), $challenge['nonce'], $cnonce); $A2 = 'AUTHENTICATE:' . $digest_uri; $response_value = hash('md5', sprintf('%s:%s:00000001:%s:auth:%s', hash('md5', $A1), $challenge['nonce'], $cnonce, hash('md5', $A2))); $this->_response = array( 'cnonce' => '"' . $cnonce . '"', 'digest-uri' => '"' . $digest_uri . '"', 'maxbuf' => $challenge['maxbuf'], 'nc' => '00000001', 'nonce' => '"' . $challenge['nonce'] . '"', 'qop' => 'auth', 'response' => $response_value, 'username' => '"' . $id . '"' ); if (strlen($challenge['realm'])) { $this->_response['realm'] = '"' . $challenge['realm'] . '"'; } } /** * Cooerce to string. * * @return string The digest response (not base64 encoded). */ public function __toString() { $out = array(); foreach ($this->_response as $key => $val) { $out[] = $key . '=' . $val; } return implode(',', $out); } /** * Return specific digest response directive. * * @return mixed Requested directive, or null if it does not exist. */ public function __get($name) { return isset($this->_response[$name]) ? $this->_response[$name] : null; } /** * Parses and verifies the digest challenge. * * @param string $challenge The digest challenge * * @return array The parsed challenge as an array with directives as keys. * * @throws Horde_Imap_Client_Exception */ protected function _parseChallenge($challenge) { $tokens = array( 'maxbuf' => 65536, 'realm' => '' ); preg_match_all('/([a-z-]+)=("[^"]+(? * @category Horde * @copyright 2015-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.29.0 */ class Horde_Imap_Client_Auth_Scram { /** * AuthMessage (RFC 5802 [3]). * * @var string */ protected $_authmsg; /** * Hash name. * * @var string */ protected $_hash; /** * Number of Hi iterations (RFC 5802 [2]). * * @var integer */ protected $_iterations; /** * Nonce. * * @var string */ protected $_nonce; /** * Password. * * @var string */ protected $_pass; /** * Server salt. * * @var string */ protected $_salt; /** * Calculated server signature value. * * @var string */ protected $_serversig; /** * Username. * * @var string */ protected $_user; /** * Constructor. * * @param string $user Username. * @param string $pass Password. * @param string $hash Hash name. * * @throws Horde_Imap_Client_Exception */ public function __construct($user, $pass, $hash = 'SHA1') { $error = false; $this->_hash = $hash; try { if (!class_exists('Horde_Stringprep') || !class_exists('Horde_Crypt_Blowfish_Pbkdf2')) { throw new Exception(); } Horde_Stringprep::autoload(); $saslprep = new Znerol\Component\Stringprep\Profile\SASLprep(); $this->_user = $saslprep->apply( $user, 'UTF-8', Znerol\Component\Stringprep\Profile::MODE_QUERY ); $this->_pass = $saslprep->apply( $pass, 'UTF-8', Znerol\Component\Stringprep\Profile::MODE_STORE ); } catch (Znerol\Component\Stringprep\ProfileException $e) { $error = true; } catch (Exception $e) { $error = true; } if ($error) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Authentication failure."), Horde_Imap_Client_Exception::LOGIN_AUTHORIZATIONFAILED ); } /* Generate nonce. (Done here so this can be overwritten for * testing purposes.) */ $this->_nonce = strval(new Horde_Support_Randomid()); } /** * Return the initial client message. * * @return string Initial client message. */ public function getClientFirstMessage() { /* n: client doesn't support channel binding, * , * n=: SASLprepped username with "," and "=" escaped, * r=: Random nonce */ $this->_authmsg = 'n=' . str_replace( array(',', '='), array('=2C', '=3D'), $this->_user ) . ',r=' . $this->_nonce; return 'n,,' . $this->_authmsg; } /** * Process the initial server message response. * * @param string $msg Initial server response. * * @return boolean False if authentication failed at this stage. */ public function parseServerFirstMessage($msg) { $i = $r = $s = false; foreach (explode(',', $msg) as $val) { list($attr, $aval) = array_map('trim', explode('=', $val, 2)); switch ($attr) { case 'i': $this->_iterations = intval($aval); $i = true; break; case 'r': /* Beginning of server-provided nonce MUST be the same as the * nonce we provided. */ if (strpos($aval, $this->_nonce) !== 0) { return false; } $this->_nonce = $aval; $r = true; break; case 's': $this->_salt = base64_decode($aval); $s = true; break; } } if ($i && $r && $s) { $this->_authmsg .= ',' . $msg; return true; } return false; } /** * Return the final client message. * * @return string Final client message. */ public function getClientFinalMessage() { $final_msg = 'c=biws,r=' . $this->_nonce; /* Salted password. */ $s_pass = strval(new Horde_Crypt_Blowfish_Pbkdf2( $this->_pass, strlen(hash($this->_hash, '', true)), array( 'algo' => $this->_hash, 'i_count' => $this->_iterations, 'salt' => $this->_salt ) )); /* Client key. */ $c_key = hash_hmac($this->_hash, 'Client Key', $s_pass, true); /* Stored key. */ $s_key = hash($this->_hash, $c_key, true); /* Client signature. */ $auth_msg = $this->_authmsg . ',' . $final_msg; $c_sig = hash_hmac($this->_hash, $auth_msg, $s_key, true); /* Proof. */ $proof = $c_key ^ $c_sig; /* Server signature. */ $this->_serversig = hash_hmac( $this->_hash, $auth_msg, hash_hmac($this->_hash, 'Server Key', $s_pass, true), true ); /* c=biws: channel-binding ("biws" = base64('n,,')), * p=: base64 encoded ClientProof, * r=: Nonce as returned from the server. */ return $final_msg . ',p=' . base64_encode($proof); } /** * Process the final server message response. * * @param string $msg Final server response. * * @return boolean False if authentication failed. */ public function parseServerFinalMessage($msg) { foreach (explode(',', $msg) as $val) { list($attr, $aval) = array_map('trim', explode('=', $val, 2)); switch ($attr) { case 'e': return false; case 'v': return (base64_decode($aval) === $this->_serversig); } } return false; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Base/Alerts.php0000664000175000017500000000427013150761653022045 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.24.0 */ class Horde_Imap_Client_Base_Alerts implements SplSubject { /** * Alert data. * * @var object */ protected $_alert; /** * Observers. * * @var array */ protected $_observers = array(); /** * Add an alert. * * @param string $alert The alert string. * @param string $type The alert type. */ public function add($alert, $type = null) { $this->_alert = new stdClass; $this->_alert->alert = $alert; if (!is_null($type)) { $this->_alert->type = $type; } $this->notify(); } /** * Returns the last alert received. * * @return object Alert information. Object with these properties: *
     *   - alert: (string) Alert string.
     *   - type: (string) [OPTIONAL] Alert type.
     * 
*/ public function getLast() { return $this->_alert; } /* SplSubject methods. */ /** */ public function attach(SplObserver $observer) { $this->detach($observer); $this->_observers[] = $observer; } /** */ public function detach(SplObserver $observer) { if (($key = array_search($observer, $this->_observers, true)) !== false) { unset($this->_observers[$key]); } } /** * Notification is triggered internally whenever the object's internal * data storage is altered. */ public function notify() { foreach ($this->_observers as $val) { $val->update($this); } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Base/Debug.php0000664000175000017500000000656513150761653021652 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @internal * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Base_Debug { /** Time, in seconds, to be labeled a slow command. */ const SLOW_CMD = 5; /** * Is debugging active? * * @var boolean */ public $debug = true; /** * The debug stream. * * @var resource */ protected $_stream; /** * Timestamp of last command. * * @var integer */ protected $_time = null; /** * Constructor. * * @param mixed $debug The debug target. */ public function __construct($debug) { $this->_stream = is_resource($debug) ? $debug : @fopen($debug, 'a'); register_shutdown_function(array($this, 'shutdown')); } /** * Shutdown function. */ public function shutdown() { if (is_resource($this->_stream)) { fflush($this->_stream); fclose($this->_stream); $this->_stream = null; } } /** * Write client output to debug log. * * @param string $msg Debug message. */ public function client($msg) { $this->_write($msg . "\n", 'C: '); } /** * Write informational message to debug log. * * @param string $msg Debug message. */ public function info($msg) { $this->_write($msg . "\n", '>> '); } /** * Write server output to debug log. * * @param string $msg Debug message. */ public function raw($msg) { $this->_write($msg); } /** * Write server output to debug log. * * @param string $msg Debug message. */ public function server($msg) { $this->_write($msg . "\n", 'S: '); } /** * Write debug information to the output stream. * * @param string $msg Debug data. */ protected function _write($msg, $pre = null) { if (!$this->debug || !$this->_stream) { return; } if (!is_null($pre)) { $new_time = microtime(true); if (is_null($this->_time)) { fwrite( $this->_stream, str_repeat('-', 30) . "\n" . '>> ' . date('r') . "\n" ); } elseif (($diff = ($new_time - $this->_time)) > self::SLOW_CMD) { fwrite( $this->_stream, '>> Slow Command: ' . round($diff, 3) . " seconds\n" ); } $this->_time = $new_time; } fwrite($this->_stream, $pre . $msg); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Base/Deprecated.php0000664000175000017500000000703513150761653022655 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @internal * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Base_Deprecated { /** * Returns a unique identifier for the current mailbox status. * * @param Horde_Imap_Client_Base $base_ob The base driver object. * @param mixed $mailbox A mailbox. Either a * Horde_Imap_Client_Mailbox * object or a string (UTF-8). * @param boolean $condstore Is CONDSTORE enabled? * @param array $addl Additional cache info to add to * the cache ID string. * * @return string The cache ID string, which will change when the * composition of the mailbox changes. The uidvalidity * will always be the first element, and will be delimited * by the '|' character. * * @throws Horde_Imap_Client_Exception */ public static function getCacheId($base_ob, $mailbox, $condstore, array $addl = array()) { $query = Horde_Imap_Client::STATUS_UIDVALIDITY | Horde_Imap_Client::STATUS_MESSAGES | Horde_Imap_Client::STATUS_UIDNEXT; /* Use MODSEQ as cache ID if CONDSTORE extension is available. */ if ($condstore) { $query |= Horde_Imap_Client::STATUS_HIGHESTMODSEQ; } else { $query |= Horde_Imap_Client::STATUS_UIDNEXT_FORCE; } $status = $base_ob->status($mailbox, $query); if (empty($status['highestmodseq'])) { $parts = array( 'V' . $status['uidvalidity'], 'U' . $status['uidnext'], 'M' . $status['messages'] ); } else { $parts = array( 'V' . $status['uidvalidity'], 'H' . $status['highestmodseq'] ); } return implode('|', array_merge($parts, $addl)); } /** * Parses a cacheID created by getCacheId(). * * @param string $id The cache ID. * * @return array An array with the following information: * - highestmodseq: (integer) * - messages: (integer) * - uidnext: (integer) * - uidvalidity: (integer) Always present */ public static function parseCacheId($id) { $data = array( 'H' => 'highestmodseq', 'M' => 'messages', 'U' => 'uidnext', 'V' => 'uidvalidity' ); $info = array(); foreach (explode('|', $id) as $part) { if (isset($data[$part[0]])) { $info[$data[$part[0]]] = intval(substr($part, 1)); } } return $info; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Base/Mailbox.php0000664000175000017500000001251613150761653022210 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @internal * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Base_Mailbox { /** * Mapping object. * * @var Horde_Imap_Client_Ids_Map */ public $map; /** * Is mailbox opened? * * @var boolean */ public $open; /** * Is mailbox sync'd with remote server (via CONDSTORE/QRESYNC)? * * @var boolean */ public $sync; /** * Status information. * * @var array */ protected $_status = array(); /** * Constructor. */ public function __construct() { $this->reset(); } /** * Get status information for the mailbox. * * @param integer $entry STATUS_* constant. * * @return mixed Status information. */ public function getStatus($entry) { if (isset($this->_status[$entry])) { return $this->_status[$entry]; } switch ($entry) { case Horde_Imap_Client::STATUS_FLAGS: case Horde_Imap_Client::STATUS_SYNCFLAGUIDS: case Horde_Imap_Client::STATUS_SYNCVANISHED: return array(); case Horde_Imap_Client::STATUS_FIRSTUNSEEN: /* If we know there are no messages in the current mailbox, we * know there are no unseen messages. */ return empty($this->_status[Horde_Imap_Client::STATUS_MESSAGES]) ? false : null; case Horde_Imap_Client::STATUS_RECENT_TOTAL: case Horde_Imap_Client::STATUS_SYNCMODSEQ: return 0; case Horde_Imap_Client::STATUS_PERMFLAGS: /* If PERMFLAGS is not returned by server, must assume that all * flags can be changed permanently (RFC 3501 [6.3.1]). */ $flags = isset($this->_status[Horde_Imap_Client::STATUS_FLAGS]) ? $this->_status[Horde_Imap_Client::STATUS_FLAGS] : array(); $flags[] = "\\*"; return $flags; case Horde_Imap_Client::STATUS_UIDNOTSTICKY: /* In the absence of explicit uidnotsticky identification, assume * that UIDs are sticky. */ return false; case Horde_Imap_Client::STATUS_UNSEEN: /* If we know there are no messages in the current mailbox, we * know there are no unseen messages . */ return empty($this->_status[Horde_Imap_Client::STATUS_MESSAGES]) ? 0 : null; default: return null; } } /** * Set status information for the mailbox. * * @param integer $entry STATUS_* constant. * @param mixed $value Status information. */ public function setStatus($entry, $value) { switch ($entry) { case Horde_Imap_Client::STATUS_FIRSTUNSEEN: case Horde_Imap_Client::STATUS_HIGHESTMODSEQ: case Horde_Imap_Client::STATUS_MESSAGES: case Horde_Imap_Client::STATUS_UNSEEN: case Horde_Imap_Client::STATUS_UIDNEXT: case Horde_Imap_Client::STATUS_UIDVALIDITY: $value = intval($value); break; case Horde_Imap_Client::STATUS_RECENT: /* Keep track of RECENT_TOTAL information. */ $this->_status[Horde_Imap_Client::STATUS_RECENT_TOTAL] = isset($this->_status[Horde_Imap_Client::STATUS_RECENT_TOTAL]) ? ($this->_status[Horde_Imap_Client::STATUS_RECENT_TOTAL] + $value) : intval($value); break; case Horde_Imap_Client::STATUS_SYNCMODSEQ: /* This is only set once per access. */ if (isset($this->_status[$entry])) { return; } $value = intval($value); break; case Horde_Imap_Client::STATUS_SYNCFLAGUIDS: case Horde_Imap_Client::STATUS_SYNCVANISHED: if (!isset($this->_status[$entry])) { $this->_status[$entry] = array(); } $this->_status[$entry] = array_merge($this->_status[$entry], $value); return; } $this->_status[$entry] = $value; } /** * Reset the mailbox information. */ public function reset() { $keep = array( Horde_Imap_Client::STATUS_SYNCFLAGUIDS, Horde_Imap_Client::STATUS_SYNCMODSEQ, Horde_Imap_Client::STATUS_SYNCVANISHED ); foreach (array_diff(array_keys($this->_status), $keep) as $val) { unset($this->_status[$val]); } $this->map = new Horde_Imap_Client_Ids_Map(); $this->open = $this->sync = false; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Base/Password.php0000664000175000017500000000152013150761653022410 0ustar janjan * @category Horde * @copyright 2013-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.14.0 */ interface Horde_Imap_Client_Base_Password { /** * Return the password to use for the server connection. * * @return string The password. */ public function getPassword(); } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Cache/Backend/Cache.php0000664000175000017500000003452113150761653023300 0ustar janjan * @category Horde * @copyright 2005-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Cache_Backend_Cache extends Horde_Imap_Client_Cache_Backend { /** Cache structure version. */ const VERSION = 3; /** * The cache object. * * @var Horde_Cache */ protected $_cache; /** * The working data for the current pageload. All changes take place to * this data. * * @var array */ protected $_data = array(); /** * The list of cache slices loaded. * * @var array */ protected $_loaded = array(); /** * The mapping of UIDs to slices. * * @var array */ protected $_slicemap = array(); /** * The list of items to update: * - add: (array) List of IDs that were added. * - slice: (array) List of slices that were modified. * - slicemap: (boolean) Was slicemap info changed? * * @var array */ protected $_update = array(); /** * Constructor. * * @param array $params Configuration parameters: *
     *   - REQUIRED Parameters:
     *     - cacheob: (Horde_Cache) The cache object to use.
     *
     *   - Optional Parameters:
     *     - lifetime: (integer) The lifetime of the cache data (in seconds).
     *                 DEFAULT: 1 week (604800 seconds)
     *     - slicesize: (integer) The slicesize to use.
     *                  DEFAULT: 50
     * 
*/ public function __construct(array $params = array()) { // Default parameters. $params = array_merge(array( 'lifetime' => 604800, 'slicesize' => 50 ), array_filter($params)); if (!isset($params['cacheob'])) { throw new InvalidArgumentException('Missing cacheob parameter.'); } foreach (array('lifetime', 'slicesize') as $val) { $params[$val] = intval($params[$val]); } parent::__construct($params); } /** * Initialization tasks. */ protected function _initOb() { $this->_cache = $this->_params['cacheob']; register_shutdown_function(array($this, 'save')); } /** * Updates the cache. */ public function save() { $lifetime = $this->_params['lifetime']; foreach ($this->_update as $mbox => $val) { $s = &$this->_slicemap[$mbox]; try { if (!empty($val['add'])) { if ($s['c'] <= $this->_params['slicesize']) { $val['slice'][] = $s['i']; $this->_loadSlice($mbox, $s['i']); } $val['slicemap'] = true; foreach (array_keys(array_flip($val['add'])) as $uid) { if ($s['c']++ > $this->_params['slicesize']) { $s['c'] = 0; $val['slice'][] = ++$s['i']; $this->_loadSlice($mbox, $s['i']); } $s['s'][$uid] = $s['i']; } } if (!empty($val['slice'])) { $d = &$this->_data[$mbox]; $val['slicemap'] = true; foreach (array_keys(array_flip($val['slice'])) as $slice) { $data = array(); foreach (array_keys($s['s'], $slice) as $uid) { $data[$uid] = is_array($d[$uid]) ? serialize($d[$uid]) : $d[$uid]; } $this->_cache->set($this->_getCid($mbox, $slice), serialize($data), $lifetime); } } if (!empty($val['slicemap'])) { $this->_cache->set($this->_getCid($mbox, 'slicemap'), serialize($s), $lifetime); } } catch (Horde_Exception $e) { } } $this->_update = array(); } /** */ public function get($mailbox, $uids, $fields, $uidvalid) { $ret = array(); $this->_loadUids($mailbox, $uids, $uidvalid); if (empty($this->_data[$mailbox])) { return $ret; } if (!empty($fields)) { $fields = array_flip($fields); } $ptr = &$this->_data[$mailbox]; foreach (array_intersect($uids, array_keys($ptr)) as $val) { if (is_string($ptr[$val])) { try { $ptr[$val] = @unserialize($ptr[$val]); } catch (Exception $e) {} } $ret[$val] = (empty($fields) || empty($ptr[$val])) ? $ptr[$val] : array_intersect_key($ptr[$val], $fields); } return $ret; } /** */ public function getCachedUids($mailbox, $uidvalid) { $this->_loadSliceMap($mailbox, $uidvalid); return array_unique(array_merge( array_keys($this->_slicemap[$mailbox]['s']), (isset($this->_update[$mailbox]) ? $this->_update[$mailbox]['add'] : array()) )); } /** */ public function set($mailbox, $data, $uidvalid) { $update = array_keys($data); try { $this->_loadUids($mailbox, $update, $uidvalid); } catch (Horde_Imap_Client_Exception $e) { // Ignore invalidity - just start building the new cache } $d = &$this->_data[$mailbox]; $s = &$this->_slicemap[$mailbox]['s']; $add = $updated = array(); foreach ($data as $k => $v) { if (isset($d[$k])) { if (is_string($d[$k])) { try { $d[$k] = @unserialize($d[$k]); } catch (Exception $e) {} } $d[$k] = is_array($d[$k]) ? array_merge($d[$k], $v) : $v; if (isset($s[$k])) { $updated[$s[$k]] = true; } } else { $d[$k] = $v; $add[] = $k; } } $this->_toUpdate($mailbox, 'add', $add); $this->_toUpdate($mailbox, 'slice', array_keys($updated)); } /** */ public function getMetaData($mailbox, $uidvalid, $entries) { $this->_loadSliceMap($mailbox, $uidvalid); return empty($entries) ? $this->_slicemap[$mailbox]['d'] : array_intersect_key($this->_slicemap[$mailbox]['d'], array_flip($entries)); } /** */ public function setMetaData($mailbox, $data) { $this->_loadSliceMap($mailbox, isset($data['uidvalid']) ? $data['uidvalid'] : null); $this->_slicemap[$mailbox]['d'] = array_merge($this->_slicemap[$mailbox]['d'], $data); $this->_toUpdate($mailbox, 'slicemap', true); } /** */ public function deleteMsgs($mailbox, $uids) { if (empty($uids)) { return; } $this->_loadSliceMap($mailbox); $slicemap = &$this->_slicemap[$mailbox]; $deleted = array_intersect_key($slicemap['s'], array_flip($uids)); if (isset($this->_update[$mailbox])) { $this->_update[$mailbox]['add'] = array_diff( $this->_update[$mailbox]['add'], $uids ); } if (empty($deleted)) { return; } $this->_loadUids($mailbox, array_keys($deleted)); $d = &$this->_data[$mailbox]; foreach (array_keys($deleted) as $id) { unset($d[$id], $slicemap['s'][$id]); } foreach (array_unique($deleted) as $slice) { /* Get rid of slice if less than 10% of capacity. */ if (($slice != $slicemap['i']) && ($slice_uids = array_keys($slicemap['s'], $slice)) && ($this->_params['slicesize'] * 0.1) > count($slice_uids)) { $this->_toUpdate($mailbox, 'add', $slice_uids); $this->_cache->expire($this->_getCid($mailbox, $slice)); foreach ($slice_uids as $val) { unset($slicemap['s'][$val]); } } else { $this->_toUpdate($mailbox, 'slice', array($slice)); } } } /** */ public function deleteMailbox($mailbox) { $this->_loadSliceMap($mailbox); $this->_deleteMailbox($mailbox); } /** */ public function clear($lifetime) { $this->_cache->clear(); $this->_data = $this->_loaded = $this->_slicemap = $this->_update = array(); } /** * Create the unique ID used to store the data in the cache. * * @param string $mailbox The mailbox to cache. * @param string $slice The cache slice. * * @return string The cache ID. */ protected function _getCid($mailbox, $slice) { return implode('|', array( 'horde_imap_client', $this->_params['username'], $mailbox, $this->_params['hostspec'], $this->_params['port'], $slice, self::VERSION )); } /** * Delete a mailbox from the cache. * * @param string $mbox The mailbox to delete. */ protected function _deleteMailbox($mbox) { foreach (array_merge(array_keys(array_flip($this->_slicemap[$mbox]['s'])), array('slicemap')) as $slice) { $cid = $this->_getCid($mbox, $slice); $this->_cache->expire($cid); unset($this->_loaded[$cid]); } unset( $this->_data[$mbox], $this->_slicemap[$mbox], $this->_update[$mbox] ); } /** * Load UIDs by regenerating from the cache. * * @param string $mailbox The mailbox to load. * @param array $uids The UIDs to load. * @param integer $uidvalid The IMAP uidvalidity value of the mailbox. */ protected function _loadUids($mailbox, $uids, $uidvalid = null) { if (!isset($this->_data[$mailbox])) { $this->_data[$mailbox] = array(); } $this->_loadSliceMap($mailbox, $uidvalid); if (!empty($uids)) { foreach (array_unique(array_intersect_key($this->_slicemap[$mailbox]['s'], array_flip($uids))) as $slice) { $this->_loadSlice($mailbox, $slice); } } } /** * Load UIDs from a cache slice. * * @param string $mailbox The mailbox to load. * @param integer $slice The slice to load. */ protected function _loadSlice($mailbox, $slice) { $cache_id = $this->_getCid($mailbox, $slice); if (!empty($this->_loaded[$cache_id])) { return; } if (($data = $this->_cache->get($cache_id, 0)) !== false) { try { $data = @unserialize($data); } catch (Exception $e) {} } if (($data !== false) && is_array($data)) { $this->_data[$mailbox] += $data; $this->_loaded[$cache_id] = true; } else { $ptr = &$this->_slicemap[$mailbox]; // Slice data is corrupt; remove from slicemap. foreach (array_keys($ptr['s'], $slice) as $val) { unset($ptr['s'][$val]); } if ($slice == $ptr['i']) { $ptr['c'] = 0; } } } /** * Load the slicemap for a given mailbox. The slicemap contains * the uidvalidity information, the UIDs->slice lookup table, and any * metadata that needs to be saved for the mailbox. * * @param string $mailbox The mailbox. * @param integer $uidvalid The IMAP uidvalidity value of the mailbox. */ protected function _loadSliceMap($mailbox, $uidvalid = null) { if (!isset($this->_slicemap[$mailbox]) && (($data = $this->_cache->get($this->_getCid($mailbox, 'slicemap'), 0)) !== false)) { try { if (($slice = @unserialize($data)) && is_array($slice)) { $this->_slicemap[$mailbox] = $slice; } } catch (Exception $e) {} } if (isset($this->_slicemap[$mailbox])) { $ptr = &$this->_slicemap[$mailbox]; if (is_null($ptr['d']['uidvalid'])) { $ptr['d']['uidvalid'] = $uidvalid; return; } elseif (!is_null($uidvalid) && ($ptr['d']['uidvalid'] != $uidvalid)) { $this->_deleteMailbox($mailbox); } else { return; } } $this->_slicemap[$mailbox] = array( // Tracking count for purposes of determining slices 'c' => 0, // Metadata storage // By default includes UIDVALIDITY of mailbox. 'd' => array('uidvalid' => $uidvalid), // The ID of the last slice. 'i' => 0, // The slice list. 's' => array() ); } /** * Add update entry for a mailbox. * * @param string $mailbox The mailbox. * @param string $type 'add', 'slice', or 'slicemap'. * @param mixed $data The data to update. */ protected function _toUpdate($mailbox, $type, $data) { if (!isset($this->_update[$mailbox])) { $this->_update[$mailbox] = array( 'add' => array(), 'slice' => array() ); } $this->_update[$mailbox][$type] = ($type == 'slicemap') ? $data : array_merge($this->_update[$mailbox][$type], $data); } /* Serializable methods. */ /** */ public function serialize() { $this->save(); return parent::serialize(); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Cache/Backend/Db.php0000664000175000017500000002722413150761653022624 0ustar janjan * @category Horde * @copyright 2013-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Cache_Backend_Db extends Horde_Imap_Client_Cache_Backend { /** SQL table names. */ const BASE_TABLE = 'horde_imap_client_data'; const MD_TABLE = 'horde_imap_client_metadata'; const MSG_TABLE = 'horde_imap_client_message'; /** * Handle for the database connection. * * @var Horde_Db_Adapter */ protected $_db; /** * Constructor. * * @param array $params Configuration parameters: *
     *   - REQUIRED Parameters:
     *     - db: (Horde_Db_Adapter) DB object.
     * 
*/ public function __construct(array $params = array()) { if (!isset($params['db'])) { throw new InvalidArgumentException('Missing db parameter.'); } parent::__construct($params); } /** */ protected function _initOb() { $this->_db = $this->_params['db']; } /** */ public function get($mailbox, $uids, $fields, $uidvalid) { $this->getMetaData($mailbox, $uidvalid, array('uidvalid')); $query = $this->_baseSql($mailbox, self::MSG_TABLE); $query[0] = 'SELECT t.data, t.msguid ' . $query[0]; $uid_query = array(); foreach ($uids as $val) { $uid_query[] = 't.msguid = ?'; $query[1][] = strval($val); } $query[0] .= ' AND (' . implode(' OR ', $uid_query) . ')'; $compress = new Horde_Compress_Fast(); $out = array(); try { $columns = $this->_db->columns(self::MSG_TABLE); $res = $this->_db->select($query[0], $query[1]); foreach ($res as $row) { try { $out[$row['msguid']] = @unserialize($compress->decompress( $columns['data']->binaryToString($row['data']) )); } catch (Exception $e) {} } } catch (Horde_Db_Exception $e) {} return $out; } /** */ public function getCachedUids($mailbox, $uidvalid) { $this->getMetaData($mailbox, $uidvalid, array('uidvalid')); $query = $this->_baseSql($mailbox, self::MSG_TABLE); $query[0] = 'SELECT DISTINCT t.msguid ' . $query[0]; try { return $this->_db->selectValues($query[0], $query[1]); } catch (Horde_Db_Exception $e) { return array(); } } /** */ public function set($mailbox, $data, $uidvalid) { if ($uid = $this->_getUid($mailbox)) { $res = $this->get($mailbox, array_keys($data), array(), $uidvalid); } else { $res = array(); $uid = $this->_createUid($mailbox); } $compress = new Horde_Compress_Fast(); foreach ($data as $key => $val) { if (isset($res[$key])) { try { /* Update */ $this->_db->updateBlob( self::MSG_TABLE, array('data' => new Horde_Db_Value_Binary($compress->compress(serialize(array_merge($res[$key], $val))))), array( 'messageid = ? AND msguid = ?', array($uid, strval($key)) ) ); } catch (Horde_Db_Exception $e) {} } else { /* Insert */ try { $this->_db->insertBlob( self::MSG_TABLE, array( 'data' => new Horde_Db_Value_Binary($compress->compress(serialize($val))), 'msguid' => strval($key), 'messageid' => $uid ) ); } catch (Horde_Db_Exception $e) {} } } /* Update modified time. */ try { $this->_db->update( sprintf( 'UPDATE %s SET modified = ? WHERE messageid = ?', self::BASE_TABLE ), array(time(), $uid) ); } catch (Horde_Db_Exception $e) {} /* Update uidvalidity. */ $this->setMetaData($mailbox, array('uidvalid' => $uidvalid)); } /** */ public function getMetaData($mailbox, $uidvalid, $entries) { $query = $this->_baseSql($mailbox, self::MD_TABLE); $query[0] = 'SELECT t.field, t.data ' . $query[0]; if (!empty($entries)) { $entries[] = 'uidvalid'; $entry_query = array(); foreach (array_unique($entries) as $val) { $entry_query[] = 't.field = ?'; $query[1][] = $val; } $query[0] .= ' AND (' . implode(' OR ', $entry_query) . ')'; } try { if ($res = $this->_db->selectAssoc($query[0], $query[1])) { $columns = $this->_db->columns(self::MD_TABLE); foreach ($res as $key => $val) { switch ($key) { case 'uidvalid': $res[$key] = $columns['data']->binaryToString($val); break; default: try { $res[$key] = @unserialize( $columns['data']->binaryToString($val) ); } catch (Exception $e) {} break; } } if (is_null($uidvalid) || !isset($res['uidvalid']) || ($res['uidvalid'] == $uidvalid)) { return $res; } $this->deleteMailbox($mailbox); } } catch (Horde_Db_Exception $e) {} return array(); } /** */ public function setMetaData($mailbox, $data) { if (!($uid = $this->_getUid($mailbox))) { $uid = $this->_createUid($mailbox); } $query = sprintf('SELECT field FROM %s where messageid = ?', self::MD_TABLE); $values = array($uid); try { $fields = $this->_db->selectValues($query, $values); } catch (Horde_Db_Exception $e) { return; } foreach ($data as $key => $val) { $val = new Horde_Db_Value_Binary(($key == 'uidvalid') ? $val : serialize($val)); if (in_array($key, $fields)) { /* Update */ try { $this->_db->updateBlob( self::MD_TABLE, array('data' => $val), array('field = ? AND messageid = ?', array($key, $uid)) ); } catch (Horde_Db_Exception $e) {} } else { /* Insert */ try { $this->_db->insertBlob( self::MD_TABLE, array('data' => $val, 'field' => $key, 'messageid' => $uid) ); } catch (Horde_Db_Exception $e) {} } } } /** */ public function deleteMsgs($mailbox, $uids) { if (empty($uids)) { return; } $query = $this->_baseSql($mailbox); $query[0] = sprintf( 'DELETE FROM %s WHERE messageid IN (SELECT messageid ' . $query[0] . ')', self::MSG_TABLE ); $uid_query = array(); foreach ($uids as $val) { $uid_query[] = 'msguid = ?'; $query[1][] = strval($val); } $query[0] .= ' AND (' . implode(' OR ', $uid_query) . ')'; try { $this->_db->delete($query[0], $query[1]); } catch (Horde_Db_Exception $e) {} } /** */ public function deleteMailbox($mailbox) { if (is_null($uid = $this->_getUid($mailbox))) { return; } foreach (array(self::BASE_TABLE, self::MD_TABLE, self::MSG_TABLE) as $val) { try { $this->_db->delete( sprintf('DELETE FROM %s WHERE messageid = ?', $val), array($uid) ); } catch (Horde_Db_Exception $e) {} } } /** */ public function clear($lifetime) { if (is_null($lifetime)) { try { $this->_db->delete(sprintf('DELETE FROM %s', self::BASE_TABLE)); $this->_db->delete(sprintf('DELETE FROM %s', self::MD_TABLE)); $this->_db->delete(sprintf('DELETE FROM %s', self::MSG_TABLE)); } catch (Horde_Db_Exception $e) {} return; } $purge = time() - $lifetime; $sql = 'DELETE FROM %s WHERE messageid IN (SELECT messageid FROM %s WHERE modified < ?)'; foreach (array(self::MD_TABLE, self::MSG_TABLE) as $val) { try { $this->_db->delete( sprintf($sql, $val, self::BASE_TABLE), array($purge) ); } catch (Horde_Db_Exception $e) { } } try { $this->_db->delete( sprintf('DELETE FROM %s WHERE modified < ?', self::BASE_TABLE), array($purge) ); } catch (Horde_Db_Exception $e) { } } /** * Prepare the base SQL query. * * @param string $mailbox The mailbox. * @param string $join The table to join with the base table. * * @return array SQL query and bound parameters. */ protected function _baseSql($mailbox, $join = null) { $sql = sprintf('FROM %s d', self::BASE_TABLE); if (!is_null($join)) { $sql .= sprintf(' INNER JOIN %s t ON d.messageid = t.messageid', $join); } return array( $sql . ' WHERE d.hostspec = ? AND d.port = ? AND d.username = ? AND d.mailbox = ?', array( $this->_params['hostspec'], $this->_params['port'], $this->_params['username'], $mailbox ) ); } /** * @param string $mailbox * * @return string UID from base table. */ protected function _getUid($mailbox) { $query = $this->_baseSql($mailbox); $query[0] = 'SELECT d.messageid ' . $query[0]; try { return $this->_db->selectValue($query[0], $query[1]); } catch (Horde_Db_Exception $e) { return null; } } /** * @param string $mailbox * * @return string UID from base table. */ protected function _createUid($mailbox) { return $this->_db->insert( sprintf( 'INSERT INTO %s (hostspec, mailbox, port, username) ' . 'VALUES (?, ?, ?, ?)', self::BASE_TABLE ), array( $this->_params['hostspec'], $mailbox, $this->_params['port'], $this->_params['username'] ) ); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Cache/Backend/Hashtable.php0000664000175000017500000002631313150761653024170 0ustar janjan * @category Horde * @copyright 2013-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.17.0 */ class Horde_Imap_Client_Cache_Backend_Hashtable extends Horde_Imap_Client_Cache_Backend { /** Separator for CID between mailbox and UID. */ const CID_SEPARATOR = '|'; /** * The working data for the current pageload. All changes take place to * this data. * * @var array */ protected $_data = array(); /** * HashTable object. * * @var Horde_HashTable */ protected $_hash; /** * Mailbox level data. * * @var array */ protected $_mbox = array(); /** * Horde_Pack singleton object. * * @var Horde_Pack */ protected $_pack; /** * List of mailbox/UIDs to update. * Keys are mailboxes. Values are arrays with three possible keys: *
     *   - d: UIDs to delete
     *   - m: Was metadata updated?
     *   - u: UIDs to update
     * 
* * @var array */ protected $_update = array(); /** * Constructor. * * @param array $params Configuration parameters: *
     *   - REQUIRED parameters:
     *     - hashtable: (Horde_HashTable) A HashTable object.
     *
     *   - Optional Parameters:
     *     - lifetime: (integer) The lifetime of the cache data (in seconds).
     *                 DEFAULT: 604800 seconds (1 week) [@since 2.19.0]
     * 
*/ public function __construct(array $params = array()) { if (!isset($params['hashtable'])) { throw new InvalidArgumentException('Missing hashtable parameter.'); } parent::__construct(array_merge(array( 'lifetime' => 604800 ), $params)); } /** */ protected function _initOb() { $this->_hash = $this->_params['hashtable']; $this->_pack = new Horde_Pack(); register_shutdown_function(array($this, 'save')); } /** */ public function get($mailbox, $uids, $fields, $uidvalid) { $ret = array(); if (empty($uids)) { return $ret; } $this->_loadUids($mailbox, $uids, $uidvalid); if (empty($this->_data[$mailbox])) { return $ret; } if (!empty($fields)) { $fields = array_flip($fields); } $ptr = &$this->_data[$mailbox]; $to_delete = array(); foreach ($uids as $val) { if (isset($ptr[$val])) { if (is_string($ptr[$val])) { try { $ptr[$val] = $this->_pack->unpack($ptr[$val]); } catch (Horde_Pack_Exception $e) { $to_delete[] = $val; continue; } } $ret[$val] = (empty($fields) || empty($ptr[$val])) ? $ptr[$val] : array_intersect_key($ptr[$val], $fields); } else { $to_delete[] = $val; } } $this->deleteMsgs($mailbox, $to_delete); return $ret; } /** */ public function getCachedUids($mailbox, $uidvalid) { $this->_loadMailbox($mailbox, $uidvalid); return $this->_mbox[$mailbox]['u']->ids; } /** */ public function set($mailbox, $data, $uidvalid) { $this->_loadUids($mailbox, array_keys($data), $uidvalid); $d = &$this->_data[$mailbox]; $to_add = array(); foreach ($data as $k => $v) { if (isset($d[$k]) && is_string($d[$k])) { try { $d[$k] = $this->_pack->unpack($d[$k]); } catch (Horde_Pack_Exception $e) { continue; } } $d[$k] = (isset($d[$k]) && is_array($d[$k])) ? array_merge($d[$k], $v) : $v; $this->_update[$mailbox]['u'][$k] = true; unset($this->_update[$mailbox]['d'][$k]); $to_add[] = $k; } if (!empty($to_add)) { $this->_mbox[$mailbox]['u']->add($to_add); $this->_update[$mailbox]['m'] = true; } } /** */ public function getMetaData($mailbox, $uidvalid, $entries) { $this->_loadMailbox($mailbox, $uidvalid); return empty($entries) ? $this->_mbox[$mailbox]['d'] : array_intersect_key($this->_mbox[$mailbox]['d'], array_flip($entries)); } /** */ public function setMetaData($mailbox, $data) { $this->_loadMailbox($mailbox, isset($data['uidvalid']) ? $data['uidvalid'] : null); $this->_mbox[$mailbox]['d'] = array_merge( $this->_mbox[$mailbox]['d'], $data ); $this->_update[$mailbox]['m'] = true; } /** */ public function deleteMsgs($mailbox, $uids) { if (empty($uids)) { return; } $this->_loadMailbox($mailbox); foreach ($uids as $val) { unset( $this->_data[$mailbox][$val], $this->_update[$mailbox]['u'][$val] ); $this->_update[$mailbox]['d'][$val] = true; } $this->_mbox[$mailbox]['u']->remove($uids); $this->_update[$mailbox]['m'] = true; } /** */ public function deleteMailbox($mailbox) { /* Do this action immediately, instead of at shutdown. Makes coding * simpler. */ $this->_loadMailbox($mailbox); $this->_hash->delete(array_merge( array($this->_getCid($mailbox)), array_values($this->_getMsgCids($mailbox, $this->_mbox[$mailbox]['u'])) )); unset( $this->_data[$mailbox], $this->_mbox[$mailbox], $this->_update[$mailbox] ); } /** */ public function clear($lifetime) { /* Only can clear mailboxes we know about. */ foreach (array_keys($this->_mbox) as $val) { $this->deleteMailbox($val); } $this->_data = $this->_mbox = $this->_update = array(); } /** * Updates the cache. */ public function save() { foreach ($this->_update as $mbox => $val) { try { if (!empty($val['u'])) { $ptr = &$this->_data[$mbox]; foreach ($this->_getMsgCids($mbox, array_keys($val['u'])) as $k2 => $v2) { try { $this->_hash->set( $v2, $this->_pack->pack($ptr[$k2]), array('expire' => $this->_params['lifetime']) ); } catch (Horde_Pack_Exception $e) { $this->deleteMsgs($mbox, array($v2)); $val['d'][] = $v2; } } } if (!empty($val['d'])) { $this->_hash->delete(array_values( $this->_getMsgCids($mbox, $val['d']) )); } if (!empty($val['m'])) { try { $this->_hash->set( $this->_getCid($mbox), $this->_pack->pack($this->_mbox[$mbox]), array('expire' => $this->_params['lifetime']) ); } catch (Horde_Pack_Exception $e) {} } } catch (Horde_Exception $e) { } } $this->_update = array(); } /** * Loads basic mailbox information. * * @param string $mailbox The mailbox to load. * @param integer $uidvalid The IMAP uidvalidity value of the mailbox. */ protected function _loadMailbox($mailbox, $uidvalid = null) { if (!isset($this->_mbox[$mailbox]) && ($ob = $this->_hash->get($this->_getCid($mailbox)))) { try { $this->_mbox[$mailbox] = $this->_pack->unpack($ob); } catch (Horde_Pack_Exception $e) {} } if (isset($this->_mbox[$mailbox])) { if (is_null($uidvalid) || ($uidvalid == $this->_mbox[$mailbox]['d']['uidvalid'])) { return; } $this->deleteMailbox($mailbox); } $this->_mbox[$mailbox] = array( // Metadata storage // By default includes UIDVALIDITY of mailbox. 'd' => array('uidvalid' => $uidvalid), // List of UIDs 'u' => new Horde_Imap_Client_Ids() ); } /** * Load UIDs by regenerating from the cache. * * @param string $mailbox The mailbox to load. * @param array $uids The UIDs to load. * @param integer $uidvalid The IMAP uidvalidity value of the mailbox. */ protected function _loadUids($mailbox, $uids, $uidvalid = null) { if (!isset($this->_data[$mailbox])) { $this->_data[$mailbox] = array(); } $this->_loadMailbox($mailbox, $uidvalid); if (empty($uids)) { return; } $ptr = &$this->_data[$mailbox]; $load = array_flip( array_diff_key( $this->_getMsgCids( $mailbox, array_unique(array_intersect($this->_mbox[$mailbox]['u']->ids, $uids)) ), $this->_data[$mailbox] ) ); foreach (array_filter($this->_hash->get(array_keys($load))) as $key => $val) { $ptr[$load[$key]] = $val; } } /** * Create the unique ID used to store the mailbox data in the cache. * * @param string $mailbox The mailbox to cache. * * @return string The cache ID. */ protected function _getCid($mailbox) { return implode(self::CID_SEPARATOR, array( 'horde_imap_client', $this->_params['username'], $mailbox, $this->_params['hostspec'], $this->_params['port'] )); } /** * Return a list of cache IDs for mailbox/UID pairs. * * @param string $mailbox The mailbox to cache. * @param array $ids The UID list. * * @return array List of UIDs => cache IDs. */ protected function _getMsgCids($mailbox, $ids) { $cid = $this->_getCid($mailbox); $out = array(); foreach ($ids as $val) { $out[$val] = $cid . self::CID_SEPARATOR . $val; } return $out; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Cache/Backend/Mongo.php0000664000175000017500000002743313150761653023360 0ustar janjan * @category Horde * @copyright 2013-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Cache_Backend_Mongo extends Horde_Imap_Client_Cache_Backend implements Horde_Mongo_Collection_Index { /** Mongo collection names. */ const BASE = 'horde_imap_client_cache_data'; const MD = 'horde_imap_client_cache_metadata'; const MSG = 'horde_imap_client_cache_message'; /** Mongo field names: BASE collection. */ const BASE_HOSTSPEC = 'hostspec'; const BASE_MAILBOX = 'mailbox'; const BASE_MODIFIED = 'modified'; const BASE_PORT = 'port'; const BASE_UID = 'data'; const BASE_USERNAME = 'username'; /** Mongo field names: MD collection. */ const MD_DATA = 'data'; const MD_FIELD = 'field'; const MD_UID = 'uid'; /** Mongo field names: MSG collection. */ const MSG_DATA = 'data'; const MSG_MSGUID = 'msguid'; const MSG_UID = 'uid'; /** * The MongoDB object for the cache data. * * @var MongoDB */ protected $_db; /** * The list of indices. * * @var array */ protected $_indices = array( self::BASE => array( 'base_index_1' => array( self::BASE_HOSTSPEC => 1, self::BASE_MAILBOX => 1, self::BASE_PORT => 1, self::BASE_USERNAME => 1, ) ), self::MSG => array( 'msg_index_1' => array( self::MSG_MSGUID => 1, self::MSG_UID => 1 ) ) ); /** * Constructor. * * @param array $params Configuration parameters: *
     *   - REQUIRED parameters:
     *     - mongo_db: (Horde_Mongo_Client) A MongoDB client object.
     * 
*/ public function __construct(array $params = array()) { if (!isset($params['mongo_db'])) { throw new InvalidArgumentException('Missing mongo_db parameter.'); } parent::__construct($params); } /** */ protected function _initOb() { $this->_db = $this->_params['mongo_db']->selectDB(null); } /** */ public function get($mailbox, $uids, $fields, $uidvalid) { $this->getMetaData($mailbox, $uidvalid, array('uidvalid')); if (!($uid = $this->_getUid($mailbox))) { return array(); } $out = array(); $query = array( self::MSG_MSGUID => array('$in' => array_map('strval', $uids)), self::MSG_UID => $uid ); try { $cursor = $this->_db->selectCollection(self::MSG)->find( $query, array(self::MSG_DATA => true, self::MSG_MSGUID => true) ); foreach ($cursor as $val) { try { $out[$val[self::MSG_MSGUID]] = $this->_value($val[self::MSG_DATA]); } catch (Exception $e) {} } } catch (MongoException $e) {} return $out; } /** */ public function getCachedUids($mailbox, $uidvalid) { $this->getMetaData($mailbox, $uidvalid, array('uidvalid')); if (!($uid = $this->_getUid($mailbox))) { return array(); } $out = array(); $query = array( self::MSG_UID => $uid ); try { $cursor = $this->_db->selectCollection(self::MSG)->find( $query, array(self::MSG_MSGUID => true) ); foreach ($cursor as $val) { $out[] = $val[self::MSG_MSGUID]; } } catch (MongoException $e) {} return $out; } /** */ public function set($mailbox, $data, $uidvalid) { if ($uid = $this->_getUid($mailbox)) { $res = $this->get($mailbox, array_keys($data), array(), $uidvalid); } else { $res = array(); $uid = $this->_createUid($mailbox); } $coll = $this->_db->selectCollection(self::MSG); foreach ($data as $key => $val) { try { if (isset($res[$key])) { $coll->update(array( self::MSG_MSGUID => strval($key), self::MSG_UID => $uid ), array( self::MSG_DATA => $this->_value(array_merge($res[$key], $val)), self::MSG_MSGUID => strval($key), self::MSG_UID => $uid )); } else { $doc = array( self::MSG_DATA => $this->_value($val), self::MSG_MSGUID => strval($key), self::MSG_UID => $uid ); $coll->insert($doc); } } catch (MongoException $e) {} } /* Update modified time. */ try { $this->_db->selectCollection(self::BASE)->update( array(self::BASE_UID => $uid), array(self::BASE_MODIFIED => time()) ); } catch (MongoException $e) {} /* Update uidvalidity. */ $this->setMetaData($mailbox, array('uidvalid' => $uidvalid)); } /** */ public function getMetaData($mailbox, $uidvalid, $entries) { if (!($uid = $this->_getUid($mailbox))) { return array(); } $out = array(); $query = array( self::MD_UID => $uid ); if (!empty($entries)) { $entries[] = 'uidvalid'; $query[self::MD_FIELD] = array( '$in' => array_unique($entries) ); } try { $cursor = $this->_db->selectCollection(self::MD)->find( $query, array(self::MD_DATA => true, self::MD_FIELD => true) ); foreach ($cursor as $val) { try { $out[$val[self::MD_FIELD]] = $this->_value($val[self::MD_DATA]); } catch (Exception $e) {} } if (is_null($uidvalid) || !isset($out['uidvalid']) || ($out['uidvalid'] == $uidvalid)) { return $out; } $this->deleteMailbox($mailbox); } catch (MongoException $e) {} return array(); } /** */ public function setMetaData($mailbox, $data) { if (!($uid = $this->_getUid($mailbox))) { $uid = $this->_createUid($mailbox); } $coll = $this->_db->selectCollection(self::MD); foreach ($data as $key => $val) { try { $coll->update( array( self::MD_FIELD => $key, self::MD_UID => $uid ), array( self::MD_DATA => $this->_value($val), self::MD_FIELD => $key, self::MD_UID => $uid ), array('upsert' => true) ); } catch (MongoException $e) {} } } /** */ public function deleteMsgs($mailbox, $uids) { if (!empty($uids) && ($uid = $this->_getUid($mailbox))) { try { $this->_db->selectCollection(self::MSG)->remove(array( self::MSG_MSGUID => array( '$in' => array_map('strval', $uids) ), self::MSG_UID => $uid )); } catch (MongoException $e) {} } } /** */ public function deleteMailbox($mailbox) { if (!($uid = $this->_getUid($mailbox))) { return; } foreach (array(self::BASE, self::MD, self::MSG) as $val) { try { $this->_db->selectCollection($val) ->remove(array('uid' => $uid)); } catch (MongoException $e) {} } } /** */ public function clear($lifetime) { if (is_null($lifetime)) { foreach (array(self::BASE, self::MD, self::MSG) as $val) { $this->_db->selectCollection($val)->drop(); } return; } $query = array( self::BASE_MODIFIED => array('$lt' => (time() - $lifetime)) ); $uids = array(); try { $cursor = $this->_db->selectCollection(self::BASE)->find($query); foreach ($cursor as $val) { $uids[] = strval($val['_id']); } } catch (MongoException $e) {} if (empty($uids)) { return; } foreach (array(self::BASE, self::MD, self::MSG) as $val) { try { $this->_db->selectCollection($val) ->remove(array('uid' => array('$in' => $uids))); } catch (MongoException $e) {} } } /** * Return the UID for a mailbox/user/server combo. * * @param string $mailbox Mailbox name. * * @return string UID from base table. */ protected function _getUid($mailbox) { $query = array( self::BASE_HOSTSPEC => $this->_params['hostspec'], self::BASE_MAILBOX => $mailbox, self::BASE_PORT => $this->_params['port'], self::BASE_USERNAME => $this->_params['username'] ); try { if ($result = $this->_db->selectCollection(self::BASE)->findOne($query)) { return strval($result['_id']); } } catch (MongoException $e) {} return null; } /** * Create and return the UID for a mailbox/user/server combo. * * @param string $mailbox Mailbox name. * * @return string UID from base table. */ protected function _createUid($mailbox) { $doc = array( self::BASE_HOSTSPEC => $this->_params['hostspec'], self::BASE_MAILBOX => $mailbox, self::BASE_PORT => $this->_params['port'], self::BASE_USERNAME => $this->_params['username'] ); $this->_db->selectCollection(self::BASE)->insert($doc); return $this->_getUid($mailbox); } /** * Convert data from/to storage format. * * @param mixed|MongoBinData $data The data object. * * @return mixed|MongoBinData The converted data. */ protected function _value($data) { static $compress; if (!isset($compress)) { $compress = new Horde_Compress_Fast(); } return ($data instanceof MongoBinData) ? @unserialize($compress->decompress($data->bin)) : new MongoBinData( $compress->compress(serialize($data)), MongoBinData::BYTE_ARRAY ); } /* Horde_Mongo_Collection_Index methods. */ /** */ public function checkMongoIndices() { foreach ($this->_indices as $key => $val) { if (!$this->_params['mongo_db']->checkIndices($key, $val)) { return false; } } return true; } /** */ public function createMongoIndices() { foreach ($this->_indices as $key => $val) { $this->_params['mongo_db']->createIndices($key, $val); } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Cache/Backend/Null.php0000664000175000017500000000266213150761653023210 0ustar janjan * @category Horde * @copyright 2013-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Cache_Backend_Null extends Horde_Imap_Client_Cache_Backend { /** */ public function get($mailbox, $uids, $fields, $uidvalid) { return array(); } /** */ public function getCachedUids($mailbox, $uidvalid) { return array(); } /** */ public function set($mailbox, $data, $uidvalid) { } /** */ public function getMetaData($mailbox, $uidvalid, $entries) { return array( 'uidvalid' => 0 ); } /** */ public function setMetaData($mailbox, $data) { } /** */ public function deleteMsgs($mailbox, $uids) { } /** */ public function deleteMailbox($mailbox) { } /** */ public function clear($lifetime) { } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Cache/Backend.php0000664000175000017500000001165013150761653022273 0ustar janjan * @category Horde * @copyright 2013-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ abstract class Horde_Imap_Client_Cache_Backend implements Serializable { /** * Configuration paramters. * Values set by the base Cache object: hostspec, port, username * * @var array */ protected $_params = array(); /** * Constructor. * * @param array $params Configuration parameters. */ public function __construct(array $params = array()) { $this->setParams($params); $this->_initOb(); } /** * Initialization tasks. */ protected function _initOb() { } /** * Add configuration parameters. * * @param array $params Configuration parameters. */ public function setParams(array $params = array()) { $this->_params = array_merge($this->_params, $params); } /** * Get information from the cache for a set of UIDs. * * @param string $mailbox An IMAP mailbox string. * @param array $uids The list of message UIDs to retrieve * information for. * @param array $fields An array of fields to retrieve. If empty, * returns all cached fields. * @param integer $uidvalid The IMAP uidvalidity value of the mailbox. * * @return array An array of arrays with the UID of the message as the * key (if found) and the fields as values (will be * undefined if not found). */ abstract public function get($mailbox, $uids, $fields, $uidvalid); /** * Get the list of cached UIDs. * * @param string $mailbox An IMAP mailbox string. * @param integer $uidvalid The IMAP uidvalidity value of the mailbox. * * @return array The (unsorted) list of cached UIDs. */ abstract public function getCachedUids($mailbox, $uidvalid); /** * Store data in cache. * * @param string $mailbox An IMAP mailbox string. * @param array $data The list of data to save. The keys are the * UIDs, the values are an array of information * to save. * @param integer $uidvalid The IMAP uidvalidity value of the mailbox. */ abstract public function set($mailbox, $data, $uidvalid); /** * Get metadata information for a mailbox. * * @param string $mailbox An IMAP mailbox string. * @param integer $uidvalid The IMAP uidvalidity value of the mailbox. * @param array $entries An array of entries to return. If empty, * returns all metadata. * * @return array The requested metadata. Requested entries that do not * exist will be undefined. The following entries are * defaults and always present: * - uidvalid: (integer) The UIDVALIDITY of the mailbox. */ abstract public function getMetaData($mailbox, $uidvalid, $entries); /** * Set metadata information for a mailbox. * * @param string $mailbox An IMAP mailbox string. * @param array $data The list of data to save. The keys are the * metadata IDs, the values are the associated * data. (If present, uidvalidity appears as * the 'uidvalid' key in $data.) */ abstract public function setMetaData($mailbox, $data); /** * Delete messages in the cache. * * @param string $mailbox An IMAP mailbox string. * @param array $uids The list of message UIDs to delete. */ abstract public function deleteMsgs($mailbox, $uids); /** * Delete a mailbox from the cache. * * @param string $mailbox The mailbox to delete. */ abstract public function deleteMailbox($mailbox); /** * Clear the cache. * * @param integer $lifetime Only delete entries older than this (in * seconds). If null, deletes all entries. */ abstract public function clear($lifetime); /* Serializable methods. */ /** */ public function serialize() { return serialize($this->_params); } /** */ public function unserialize($data) { $this->_params = unserialize($data); $this->_initOb(); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Capability/Imap.php0000664000175000017500000000677413150761653023574 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.24.0 * * @property-read integer $cmdlength Allowable command length (in octets). */ class Horde_Imap_Client_Data_Capability_Imap extends Horde_Imap_Client_Data_Capability { /** * The list of enabled extensions. * * @var array */ protected $_enabled = array(); /** */ public function __get($name) { switch ($name) { case 'cmdlength': /* RFC 2683 [3.2.1.5] originally recommended that lines should * be limited to "approximately 1000 octets". However, servers * should allow a command line of at least "8000 octets". * RFC 7162 [4] updates the recommendation to 8192 octets. * As a compromise, assume all modern IMAP servers handle * ~2000 octets and, if CONDSTORE/QRESYNC is supported, assume * they can handle ~8000 octets. (Don't need dependency support * checks here - the simple presence of CONDSTORE/QRESYNC is * enough to trigger.) */ return (isset($this->_data['CONDSTORE']) || isset($this->_data['QRESYNC'])) ? 8000 : 2000; } } /** */ public function query($capability, $parameter = null) { if (parent::query($capability, $parameter)) { return true; } switch (Horde_String::upper($capability)) { case 'CONDSTORE': case 'ENABLE': /* RFC 7162 [3.2.3] - QRESYNC implies CONDSTORE and ENABLE. */ return (is_null($parameter) && $this->query('QRESYNC')); case 'UTF8': /* RFC 6855 [3] - UTF8=ONLY implies UTF8=ACCEPT. */ return ((Horde_String::upper($parameter) === 'ACCEPT') && $this->query('UTF8', 'ONLY')); } return false; } /** */ public function isEnabled($capability = null) { return is_null($capability) ? $this->_enabled : in_array(Horde_String::upper($capability), $this->_enabled); } /** * Set a capability as enabled/disabled. * * @param array $capability A capability (+ parameter). * @param boolean $enable If true, enables the capability. */ public function enable($capability, $enable = true) { $capability = Horde_String::upper($capability); $enabled = $this->isEnabled($capability); if ($enable && !$enabled) { switch ($capability) { case 'QRESYNC': /* RFC 7162 [3.2.3] - Enabling QRESYNC also implies enabling * of CONDSTORE. */ $this->enable('CONDSTORE'); break; } $this->_enabled[] = $capability; $this->notify(); } elseif (!$enable && $enabled) { $this->_enabled = array_diff($this->_enabled, array($capability)); $this->notify(); } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Fetch/Pop3.php0000664000175000017500000000167513150761653022472 0ustar janjan * @category Horde * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Fetch_Pop3 extends Horde_Imap_Client_Data_Fetch { /** * Set UID. * * @param string $uid The message UID. Unlike IMAP, this UID does not * have to be an integer. */ public function setUid($uid) { $this->_data[Horde_Imap_Client::FETCH_UID] = strval($uid); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/Astring/Nonascii.php0000664000175000017500000000145513150761653025216 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.25.0 */ class Horde_Imap_Client_Data_Format_Astring_Nonascii extends Horde_Imap_Client_Data_Format_Astring implements Horde_Imap_Client_Data_Format_String_Support_Nonascii { } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/Filter/Quote.php0000664000175000017500000000320213150761653024356 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_Filter_Quote extends php_user_filter { /** * Has the initial quote been prepended? * * @var boolean */ protected $_prepend; /** */ public function onCreate() { $this->_prepend = false; } /** * @see stream_filter_register() */ public function filter($in, $out, &$consumed, $closing) { if (!$this->_prepend) { stream_bucket_append($out, stream_bucket_new($this->stream, '"')); $this->_prepend = true; } while ($bucket = stream_bucket_make_writeable($in)) { $consumed += $bucket->datalen; $bucket->data = addcslashes($bucket->data, '"\\'); stream_bucket_append($out, $bucket); } /* feof() call needed due to: * http://news.php.net/php.internals/80363 */ if ($closing || feof($this->stream)) { stream_bucket_append($out, stream_bucket_new($this->stream, '"')); } return PSFS_PASS_ON; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/Filter/String.php0000664000175000017500000000654713150761653024546 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_Filter_String extends php_user_filter { /** * Skip status. * * @var boolean */ protected $_skip = false; /** * @see stream_filter_register() */ public function onCreate() { $this->params->binary = false; $this->params->literal = false; $this->params->nonascii = false; // no_quote_list is used below as a config option $this->params->quoted = false; return true; } /** * @see stream_filter_register() */ public function filter($in, $out, &$consumed, $closing) { $p = $this->params; while ($bucket = stream_bucket_make_writeable($in)) { if (!$this->_skip) { $len = $bucket->datalen; $str = $bucket->data; for ($i = 0; $i < $len; ++$i) { $chr = ord($str[$i]); switch ($chr) { case 0: // null $p->binary = true; $p->literal = true; // No need to scan input anymore. $this->_skip = true; break 2; case 10: // LF case 13: // CR $p->literal = true; break; case 32: // SPACE case 34: // " case 40: // ( case 41: // ) case 92: // \ case 123: // { case 127: // DEL // These are all invalid ATOM characters. $p->quoted = true; break; case 37: // % case 42: // * // These are not quoted if being used as wildcards. if (empty($p->no_quote_list)) { $p->quoted = true; } break; default: if ($chr < 32) { // CTL characters must be, at a minimum, quoted. $p->quoted = true; } elseif ($chr > 127) { $p->nonascii = true; // 8-bit chars must be in a literal. $p->literal = true; } break; } } } $consumed += $bucket->datalen; stream_bucket_append($out, $bucket); } if ($p->literal) { $p->quoted = false; } return PSFS_PASS_ON; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/ListMailbox/Utf8.php0000664000175000017500000000200113150761653025105 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_ListMailbox_Utf8 extends Horde_Imap_Client_Data_Format_Mailbox_Utf8 { /** */ protected function _filterParams() { $ob = parent::_filterParams(); /* Don't quote % or * characters. */ $ob->no_quote_list = true; return $ob; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/Mailbox/Utf8.php0000664000175000017500000000341613150761653024264 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_Mailbox_Utf8 extends Horde_Imap_Client_Data_Format_Mailbox implements Horde_Imap_Client_Data_Format_String_Support_Nonascii { /** */ protected $_encoding = 'utf8'; /** */ public function __construct($data) { parent::__construct($data); /* RFC 3501 allows any US-ASCII character, except null (\0), in * mailbox data. * RFC 6855 [3] institutes additional limitations on valid mailbox * characters, to comply with RFC 5198 [2] (Net-Unicode Definition): * "MUST NOT contain control characters (U+0000-U+001F and * U+0080-U+009F), a delete character (U+007F), a line separator * (U+2028), or a paragraph separator (U+2029)." */ if ($this->quoted() && preg_match('/[\x00-\x1f\x7f\x80-\x9f\x{2028}\x{2029}]/u', strval($this))) { throw new Horde_Imap_Client_Data_Format_Exception( 'Invalid character found in mailbox data.' ); } if ($this->literal()) { $this->forceQuoted(); } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/Nstring/Nonascii.php0000664000175000017500000000145513150761653025233 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.25.0 */ class Horde_Imap_Client_Data_Format_Nstring_Nonascii extends Horde_Imap_Client_Data_Format_Nstring implements Horde_Imap_Client_Data_Format_String_Support_Nonascii { } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/String/Support/Nonascii.php0000664000175000017500000000141413150761653026524 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.25.0 */ interface Horde_Imap_Client_Data_Format_String_Support_Nonascii { } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/String/Nonascii.php0000664000175000017500000000145213150761653025052 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.25.0 */ class Horde_Imap_Client_Data_Format_String_Nonascii extends Horde_Imap_Client_Data_Format_String implements Horde_Imap_Client_Data_Format_String_Support_Nonascii { } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/Astring.php0000664000175000017500000000153313150761653023450 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_Astring extends Horde_Imap_Client_Data_Format_String { /** */ public function quoted() { return $this->_filter->quoted || !$this->_data->length(); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/Atom.php0000664000175000017500000000273013150761653022741 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_Atom extends Horde_Imap_Client_Data_Format { /** */ public function escape() { return strlen($this->_data) ? parent::escape() : '""'; } /** */ public function verify() { if (strlen($this->_data) !== strlen($this->stripNonAtomCharacters())) { throw new Horde_Imap_Client_Data_Format_Exception('Illegal character in IMAP atom.'); } } /** * Strip out any characters that are not allowed in an IMAP atom. * * @return string The atom data disallowed characters removed. */ public function stripNonAtomCharacters() { return str_replace( array('(', ')', '{', ' ', '%', '*', '"', '\\', ']'), '', preg_replace('/[^\x20-\x7e]/', '', $this->_data) ); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/Date.php0000664000175000017500000000232413150761653022715 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_Date extends Horde_Imap_Client_Data_Format { /** * Constructor. * * @param mixed $data Either a DateTime object, or a date format that * can be converted to a DateTime object. * * @throws Exception */ public function __construct($data) { if (!($data instanceof DateTime)) { $data = new Horde_Imap_Client_DateTime($data); } parent::__construct($data); } /** */ public function __toString() { return $this->_data->format('j-M-Y'); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/DateTime.php0000664000175000017500000000165413150761653023541 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_DateTime extends Horde_Imap_Client_Data_Format_Date { /** */ public function __toString() { return $this->_data->format('j-M-Y H:i:s O'); } /** */ public function escape() { return '"' . strval($this) . '"'; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/Exception.php0000664000175000017500000000126613150761653024002 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_Exception extends Horde_Exception_Wrapped { } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/List.php0000664000175000017500000000567313150761653022765 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_List extends Horde_Imap_Client_Data_Format implements Countable, IteratorAggregate { /** * @see add() */ public function __construct($data = null) { parent::__construct(array()); if (!is_null($data)) { $this->add($data); } } /** * Add an element to the list. * * @param mixed $data The data element(s) to add. Either a * Horde_Imap_Client_Data_Format object, a string * value that will be treated as an IMAP atom, or * an array (or iterable object) of objects to add. * @param boolean $merge Merge the contents of any container objects, * instead of adding the objects themselves? * * @return Horde_Imap_Client_Data_Format_List This object to allow for * chainable calls (since * 2.10.0). */ public function add($data, $merge = false) { if (is_array($data) || ($merge && ($data instanceof Traversable))) { foreach ($data as $val) { $this->add($val); } } elseif (is_object($data)) { $this->_data[] = $data; } elseif (!is_null($data)) { $this->_data[] = new Horde_Imap_Client_Data_Format_Atom($data); } return $this; } /** */ public function __toString() { $out = ''; foreach ($this as $val) { if ($val instanceof $this) { $out .= '(' . $val->escape() . ') '; } elseif (($val instanceof Horde_Imap_Client_Data_Format_String) && $val->literal()) { /* ERROR: Requires literal output. */ return ''; } else { $out .= $val->escape() . ' '; } } return rtrim($out); } /* Countable methods. */ /** */ public function count() { return count($this->_data); } /* IteratorAggregate method. */ /** * Iterator loops through the data elements contained in this list. */ public function getIterator() { return new ArrayIterator($this->_data); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/ListMailbox.php0000664000175000017500000000166113150761653024272 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_ListMailbox extends Horde_Imap_Client_Data_Format_Mailbox { /** */ protected function _filterParams() { $ob = parent::_filterParams(); /* Don't quote % or * characters. */ $ob->no_quote_list = true; return $ob; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/Mailbox.php0000664000175000017500000000435413150761653023440 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_Mailbox extends Horde_Imap_Client_Data_Format_Astring { /** * Mailbox encoding. * * @var string */ protected $_encoding = 'utf7imap'; /** * Mailbox object. * * @var Horde_Imap_Client_Mailbox */ protected $_mailbox; /** * @param mixed $data Either a mailbox object or a UTF-8 mailbox name. */ public function __construct($data) { $this->_mailbox = Horde_Imap_Client_Mailbox::get($data); parent::__construct($this->_mailbox->{$this->_encoding}); } /** */ public function __toString() { return strval($this->_mailbox); } /** */ public function getData() { return $this->_mailbox; } /** * @throws Horde_Imap_Client_Exception */ public function binary() { if (parent::binary()) { // Mailbox data can NEVER be sent as binary. /* @todo: Disable until Horde_Imap_Client 3.0 */ // throw new Horde_Imap_Client_Exception( // 'Client error: can not send mailbox to IMAP server as binary data.' // ); // Temporary fix: send a blank mailbox string. $this->_mailbox = Horde_Imap_Client_Mailbox::get(''); } return false; } /** */ public function length() { return strlen($this->_mailbox->{$this->_encoding}); } /** */ public function getStream() { $stream = new Horde_Stream_Temp(); $stream->add($this->_mailbox->{$this->_encoding}); return $stream; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/Nil.php0000664000175000017500000000172613150761653022567 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_Nil extends Horde_Imap_Client_Data_Format { /** */ public function __construct($data = null) { // Don't store any data in object. } /** */ public function __toString() { return ''; } /** */ public function escape() { return 'NIL'; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/Nstring.php0000664000175000017500000000371713150761653023473 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_Nstring extends Horde_Imap_Client_Data_Format_String { /** */ public function __construct($data = null) { /* Data can be null (NIL) here. */ if (is_null($data)) { $this->_data = null; } else { parent::__construct($data); } } /** */ public function __toString() { return is_null($this->_data) ? '' : parent::__toString(); } /** */ public function escape() { return is_null($this->_data) ? 'NIL' : parent::escape(); } public function escapeStream() { if (is_null($this->_data)) { $stream = new Horde_Stream_Temp(); $stream->add('NIL', true); return $stream->stream; } return parent::escapeStream(); } /** */ public function quoted() { return is_null($this->_data) ? false : parent::quoted(); } /** */ public function length() { return is_null($this->_data) ? 0 : parent::length(); } /** */ public function getStream() { return is_null($this->_data) ? new Horde_Stream_Temp() : parent::getStream(); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/Number.php0000664000175000017500000000200113150761653023260 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_Number extends Horde_Imap_Client_Data_Format { /** */ public function __toString() { return strval(intval($this->_data)); } /** */ public function verify() { if (!is_numeric($this->_data)) { throw new Horde_Imap_Client_Data_Format_Exception('Illegal character in IMAP number.'); } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format/String.php0000664000175000017500000001334313150761653023311 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format_String extends Horde_Imap_Client_Data_Format { /** * String filter parameters. * * @var string */ protected $_filter; /** * @param array $opts Additional options: * - eol: (boolean) If true, normalize EOLs in input. @since 2.2.0 * - skipscan: (boolean) If true, don't scan input for * binary/literal/quoted data. @since 2.2.0 * * @throws Horde_Imap_Client_Data_Format_Exception */ public function __construct($data, array $opts = array()) { /* String data is stored in a stream. */ $this->_data = new Horde_Stream_Temp(); if (empty($opts['skipscan'])) { $this->_filter = $this->_filterParams(); stream_filter_register('horde_imap_client_string', 'Horde_Imap_Client_Data_Format_Filter_String'); $res = stream_filter_append($this->_data->stream, 'horde_imap_client_string', STREAM_FILTER_WRITE, $this->_filter); } else { $res = null; } if (empty($opts['eol'])) { $res2 = null; } else { stream_filter_register('horde_eol', 'Horde_Stream_Filter_Eol'); $res2 = stream_filter_append($this->_data->stream, 'horde_eol', STREAM_FILTER_WRITE); } $this->_data->add($data); if (!is_null($res)) { stream_filter_remove($res); } if (!is_null($res2)) { stream_filter_remove($res2); } if (isset($this->_filter) && $this->_filter->nonascii && !($this instanceof Horde_Imap_Client_Data_Format_String_Support_Nonascii)) { throw new Horde_Imap_Client_Data_Format_Exception( 'String contains non-ASCII characters.' ); } } /** * Return the base string filter parameters. * * @return object Filter parameters. */ protected function _filterParams() { return new stdClass; } /** */ public function __toString() { return $this->_data->getString(0); } /** */ public function escape() { if ($this->literal()) { throw new Horde_Imap_Client_Data_Format_Exception('String requires literal to output.'); } return $this->quoted() ? stream_get_contents($this->escapeStream()) : $this->_data->getString(0); } /** * Return the escaped string as a stream. * * @return resource The IMAP escaped stream. */ public function escapeStream() { if ($this->literal()) { throw new Horde_Imap_Client_Data_Format_Exception('String requires literal to output.'); } rewind($this->_data->stream); $stream = new Horde_Stream_Temp(); $stream->add($this->_data, true); stream_filter_register('horde_imap_client_string_quote', 'Horde_Imap_Client_Data_Format_Filter_Quote'); stream_filter_append($stream->stream, 'horde_imap_client_string_quote', STREAM_FILTER_READ); return $stream->stream; } /** * Does this data item require quoted string output? * * @return boolean True if quoted output is required. */ public function quoted() { /* IMAP strings MUST be quoted if they are not a literal. */ return (!isset($this->_filter) || !$this->_filter->literal); } /** * Force item to be output quoted. */ public function forceQuoted() { $this->_filter = $this->_filterParams(); $this->_filter->binary = false; $this->_filter->literal = false; $this->_filter->quoted = true; } /** * Does this data item require literal string output? * * @return boolean True if literal output is required. */ public function literal() { return (isset($this->_filter) && $this->_filter->literal); } /** * Force item to be output as a literal. */ public function forceLiteral() { $this->_filter = $this->_filterParams(); // Keep binary status, if set $this->_filter->literal = true; $this->_filter->quoted = false; } /** * If literal output, is the data binary? * * @return boolean True if the literal output is binary. */ public function binary() { return (isset($this->_filter) && !empty($this->_filter->binary)); } /** * Force item to be output as a binary literal. */ public function forceBinary() { $this->_filter = $this->_filterParams(); $this->_filter->binary = true; $this->_filter->literal = true; $this->_filter->quoted = false; } /** * Return the length of the data. * * @since 2.2.0 * * @return integer Data length. */ public function length() { return $this->_data->length(); } /** * Return the contents of the string as a stream object. * * @since 2.3.0 * * @return Horde_Stream The stream object. */ public function getStream() { return $this->_data; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/SearchCharset/Utf8.php0000664000175000017500000000251713150761653024161 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.24.0 */ class Horde_Imap_Client_Data_SearchCharset_Utf8 extends Horde_Imap_Client_Data_SearchCharset { /** * Charset data. * * @var array */ protected $_charsets = array( 'US-ASCII' => true, 'UTF-8' => true ); /** */ public function query($charset, $cached = false) { return isset($this->_charsets[Horde_String::upper($charset)]); } /** */ public function setValid($charset, $valid = true) { } /* Serializable methods. */ /** */ public function serialize() { return ''; } /** */ public function unserialize($data) { } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Acl.php0000664000175000017500000001006513150761653021310 0ustar janjan * @category Horde * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Acl extends Horde_Imap_Client_Data_AclCommon implements ArrayAccess, IteratorAggregate, Serializable { /** * ACL rights. * * @var array */ protected $_rights; /** * Constructor. * * @param string $rights The rights (see RFC 4314 [2.1]). */ public function __construct($rights = '') { $this->_rights = str_split($rights); $this->_normalize(); } /** * String representation of the ACL. * * @return string String representation (RFC 4314 compliant). */ public function __toString() { return implode('', $this->_rights); } /** * Computes the difference to another rights string. * Virtual rights are ignored. * * @param string $rights The rights to compute against. * * @return array Two element array: added and removed. */ public function diff($rights) { $rlist = array_diff(str_split($rights), array_keys($this->_virtual)); return array( 'added' => implode('', array_diff($rlist, $this->_rights)), 'removed' => implode('', array_diff($this->_rights, $rlist)) ); } /** * Normalize virtual rights (see RFC 4314 [2.1.1]). */ protected function _normalize() { /* Clients conforming to RFC 4314 MUST ignore the virtual ACL_CREATE * and ACL_DELETE rights. See RFC 4314 [2.1]. However, we still need * to handle these rights when dealing with RFC 2086 servers since * we are abstracting out use of ACL_CREATE/ACL_DELETE to their * component RFC 4314 rights. */ foreach ($this->_virtual as $key => $val) { foreach ($val as $right) { if ($this[$right]) { foreach (array_keys($this->_virtual) as $virtual) { unset($this[$virtual]); } return; } } } foreach ($this->_virtual as $key => $val) { if ($this[$key]) { unset($this[$key]); $this->_rights = array_unique(array_merge($this->_rights, $val)); } } } /* ArrayAccess methods. */ /** */ public function offsetExists($offset) { return $this[$offset]; } /** */ public function offsetGet($offset) { return in_array($offset, $this->_rights); } /** */ public function offsetSet($offset, $value) { if ($value) { if (!$this[$offset]) { $this->_rights[] = $offset; $this->_normalize(); } } elseif ($this[$offset]) { if (isset($this->_virtual[$offset])) { foreach ($this->_virtual[$offset] as $val) { unset($this[$val]); } } unset($this[$offset]); } } /** */ public function offsetUnset($offset) { $this->_rights = array_values(array_diff($this->_rights, array($offset))); } /* IteratorAggregate method. */ public function getIterator() { return new ArrayIterator($this->_rights); } /* Serializable methods. */ /** */ public function serialize() { return json_encode($this->_rights); } /** */ public function unserialize($data) { $this->_rights = json_decode($data); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/AclCommon.php0000664000175000017500000000401413150761653022456 0ustar janjan * @category Horde * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_AclCommon { /** Constants for getString(). */ const RFC_2086 = 1; const RFC_4314 = 2; /** * List of virtual rights (RFC 4314 [2.1.1]). * * @var array */ protected $_virtual = array( Horde_Imap_Client::ACL_CREATE => array( Horde_Imap_Client::ACL_CREATEMBOX, Horde_Imap_Client::ACL_DELETEMBOX ), Horde_Imap_Client::ACL_DELETE => array( Horde_Imap_Client::ACL_DELETEMSGS, // Don't put this first - we do checks on the existence of the // first element in this array to determine the RFC type, and this // is duplicate of right contained in ACL_CREATE. Horde_Imap_Client::ACL_DELETEMBOX, Horde_Imap_Client::ACL_EXPUNGE ) ); /** * Returns the raw string to use in IMAP server calls. * * @param integer $type The RFC type to use (RFC_* constant). * * @return string The string representation of the ACL. */ public function getString($type = self::RFC_4314) { $acl = strval($this); if ($type == self::RFC_2086) { foreach ($this->_virtual as $key => $val) { $acl = str_replace($val, '', $acl, $count); if ($count) { $acl .= $key; } } } return $acl; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/AclNegative.php0000664000175000017500000000130313150761653022766 0ustar janjan * @category Horde * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_AclNegative extends Horde_Imap_Client_Data_Acl { } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/AclRights.php0000664000175000017500000001161413150761653022472 0ustar janjan * @category Horde * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_AclRights extends Horde_Imap_Client_Data_AclCommon implements ArrayAccess, Iterator, Serializable { /** * ACL optional rights. * * @var array */ protected $_optional = array(); /** * ACL required rights. * * @var array */ protected $_required = array(); /** * Constructor. * * @param array $required The required rights (see RFC 4314 [2.1]). * @param array $optional The optional rights (see RFC 4314 [2.1]). */ public function __construct(array $required = array(), array $optional = array()) { $this->_required = $required; foreach ($optional as $val) { foreach (str_split($val) as $right) { $this->_optional[$right] = $val; } } $this->_normalize(); } /** * String representation of the ACL. * * @return string String representation (RFC 4314 compliant). * */ public function __toString() { return implode('', array_keys(array_flip(array_merge(array_values($this->_required), array_keys($this->_optional))))); } /** * Normalize virtual rights (see RFC 4314 [2.1.1]). */ protected function _normalize() { /* Clients conforming to RFC 4314 MUST ignore the virtual ACL_CREATE * and ACL_DELETE rights. See RFC 4314 [2.1]. However, we still need * to handle these rights when dealing with RFC 2086 servers since * we are abstracting out use of ACL_CREATE/ACL_DELETE to their * component RFC 4314 rights. */ foreach ($this->_virtual as $key => $val) { if (isset($this->_optional[$key])) { unset($this->_optional[$key]); foreach ($val as $val2) { $this->_optional[$val2] = implode('', $val); } } elseif (($pos = array_search($key, $this->_required)) !== false) { unset($this->_required[$pos]); $this->_required = array_unique(array_merge($this->_required, $val)); } } } /* ArrayAccess methods. */ /** */ public function offsetExists($offset) { return (bool)$this[$offset]; } /** */ public function offsetGet($offset) { if (isset($this->_optional[$offset])) { return $this->_optional[$offset]; } $pos = array_search($offset, $this->_required); return ($pos === false) ? null : $this->_required[$pos]; } /** */ public function offsetSet($offset, $value) { $this->_optional[$offset] = $value; $this->_normalize(); } /** */ public function offsetUnset($offset) { unset($this->_optional[$offset]); $this->_required = array_values(array_diff($this->_required, array($offset))); if (isset($this->_virtual[$offset])) { foreach ($this->_virtual[$offset] as $val) { unset($this[$val]); } } } /* Iterator methods. */ /** */ public function current() { $val = current($this->_required); return is_null($val) ? current($this->_optional) : $val; } /** */ public function key() { $key = key($this->_required); return is_null($key) ? key($this->_optional) : $key; } /** */ public function next() { if (key($this->_required) === null) { next($this->_optional); } else { next($this->_required); } } /** */ public function rewind() { reset($this->_required); reset($this->_optional); } /** */ public function valid() { return ((key($this->_required) !== null) || (key($this->_optional) !== null)); } /* Serializable methods. */ /** */ public function serialize() { return json_encode(array( $this->_required, $this->_optional )); } /** */ public function unserialize($data) { list($this->_required, $this->_optional) = json_decode($data); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/BaseSubject.php0000664000175000017500000001422013150761653023000 0ustar janjan * * See the enclosed file COPYING for license information (LGPL). If you * did not receive this file, see http://www.horde.org/licenses/lgpl21. * * @category Horde * @copyright 2002-2008 Timo Sirainen * @copyright 2008-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ /** * Determines the "base subject" of a string (RFC 5256 [2.1]). * * @author Timo Sirainen * @author Michael Slusarz * @category Horde * @copyright 2002-2008 Timo Sirainen * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_BaseSubject { /** * The base subject. * * @var string */ protected $_subject; /** * Constructor. * * @param string $str The subject string. * @param array $opts Additional options: * - keepblob: (boolean) Don't remove any "blob" information (i.e. text * leading text between square brackets) from string. * * @return string The cleaned up subject string. */ public function __construct($str, array $opts = array()) { // Rule 1a: MIME decode. $str = Horde_Mime::decode($str); // Rule 1b: Remove superfluous whitespace. $str = preg_replace("/[\t\r\n ]+/", ' ', $str); do { /* (2) Remove all trailing text of the subject that matches the * the subj-trailer ABNF, repeat until no more matches are * possible. */ $str = preg_replace("/(?:\s*\(fwd\)\s*)+$/i", '', $str); do { /* (3) Remove all prefix text of the subject that matches the * subj-leader ABNF. */ $found = $this->_removeSubjLeader($str, !empty($opts['keepblob'])); /* (4) If there is prefix text of the subject that matches * the subj-blob ABNF, and removing that prefix leaves a * non-empty subj-base, then remove the prefix text. */ $found = (empty($opts['keepblob']) && $this->_removeBlobWhenNonempty($str)) || $found; /* (5) Repeat (3) and (4) until no matches remain. */ } while ($found); /* (6) If the resulting text begins with the subj-fwd-hdr ABNF and * ends with the subj-fwd-trl ABNF, remove the subj-fwd-hdr and * subj-fwd-trl and repeat from step (2). */ } while ($this->_removeSubjFwdHdr($str)); $this->_subject = strval($str); } /** * Return the "base subject" defined in RFC 5256 [2.1]. * * @return string The base subject. */ public function __toString() { return $this->_subject; } /** * Remove all prefix text of the subject that matches the subj-leader * ABNF. * * @param string &$str The subject string. * @param boolean $keepblob Remove blob information? * * @return boolean True if string was altered. */ protected function _removeSubjLeader(&$str, $keepblob = false) { $ret = false; if (!strlen($str)) { return $ret; } if ($len = strspn($str, " \t")) { $str = substr($str, $len); $ret = true; } $i = 0; if (!$keepblob) { while (isset($str[$i]) && ($str[$i] === '[')) { if (($i = $this->_removeBlob($str, $i)) === false) { return $ret; } } } if (stripos($str, 're', $i) === 0) { $i += 2; } elseif (stripos($str, 'fw', $i) === 0) { $i += (stripos($str, 'fwd', $i) === 0) ? 3 : 2; } else { return $ret; } $i += strspn($str, " \t", $i); if (!$keepblob) { while (isset($str[$i]) && ($str[$i] === '[')) { if (($i = $this->_removeBlob($str, $i)) === false) { return $ret; } } } if (!isset($str[$i]) || ($str[$i] !== ':')) { return $ret; } $str = substr($str, ++$i); return true; } /** * Remove "[...]" text. * * @param string $str The subject string. * @param integer $i Current position. * * @return boolean|integer False if blob was not found, otherwise the * string position of the first non-blob char. */ protected function _removeBlob($str, $i) { if ($str[$i] !== '[') { return false; } ++$i; for ($cnt = strlen($str); $i < $cnt; ++$i) { if ($str[$i] === ']') { break; } if ($str[$i] === '[') { return false; } } if ($i === ($cnt - 1)) { return false; } ++$i; if ($str[$i] === ' ') { ++$i; } return $i; } /** * Remove "[...]" text if it doesn't result in the subject becoming * empty. * * @param string &$str The subject string. * * @return boolean True if string was altered. */ protected function _removeBlobWhenNonempty(&$str) { if ($str && ($str[0] === '[') && (($i = $this->_removeBlob($str, 0)) !== false) && ($i !== strlen($str))) { $str = substr($str, $i); return true; } return false; } /** * Remove a "[fwd: ... ]" string. * * @param string &$str The subject string. * * @return boolean True if string was altered. */ protected function _removeSubjFwdHdr(&$str) { if ((stripos($str, '[fwd:') !== 0) || (substr($str, -1) !== ']')) { return false; } $str = substr($str, 5, -1); return true; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Capability.php0000664000175000017500000001302413150761653022670 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.24.0 */ class Horde_Imap_Client_Data_Capability implements Serializable, SplSubject { /** * Capability data. * * @var array */ protected $_data = array(); /** * Observers. * * @var array */ protected $_observers = array(); /** * Add a capability (and optional parameters). * * @param string $capability The capability to add. * @param mixed $params A parameter (or array of parameters) to add. */ public function add($capability, $params = null) { $capability = Horde_String::upper($capability); if (is_null($params)) { if (isset($this->_data[$capability])) { return; } $params = true; } else { if (!is_array($params)) { $params = array($params); } $params = array_map('Horde_String::upper', $params); if (isset($this->_data[$capability]) && is_array($this->_data[$capability])) { $params = array_merge($this->_data[$capability], $params); } } $this->_data[$capability] = $params; $this->notify(); } /** * Remove a capability. * * @param string $capability The capability to remove. * @param string $params A parameter (or array of parameters) to * remove from the capability. */ public function remove($capability, $params = null) { $capability = Horde_String::upper($capability); if (is_null($params)) { unset($this->_data[$capability]); } elseif (isset($this->_data[$capability])) { if (!is_array($params)) { $params = array($params); } $params = array_map('Horde_String::upper', $params); $this->_data[$capability] = is_array($this->_data[$capability]) ? array_diff($this->_data[$capability], $params) : array(); if (empty($this->_data[$capability])) { unset($this->_data[$capability]); } } $this->notify(); } /** * Returns whether the server supports the given capability. * * @param string $capability The capability string to query. * @param string $parameter If set, require the parameter to exist. * * @return boolean True if the capability (and parameter) exist. */ public function query($capability, $parameter = null) { $capability = Horde_String::upper($capability); if (!isset($this->_data[$capability])) { return false; } return is_null($parameter) ?: (is_array($this->_data[$capability]) && in_array(Horde_String::upper($parameter), $this->_data[$capability])); } /** * Return the list of parameters for an extension. * * @param string $capability The capability string to query. * * @return array An array of parameters if the extension exists and * supports parameters. Otherwise, an empty array. */ public function getParams($capability) { return ($this->query($capability) && is_array($out = $this->_data[Horde_String::upper($capability)])) ? $out : array(); } /** * Is the extension enabled? * * @param string $capability The extension (+ parameter) to query. If * null, returns all enabled extensions. * * @return mixed If $capability is null, return all enabled extensions. * Otherwise, true if the extension (+ parameter) is * enabled. */ public function isEnabled($capability = null) { return is_null($capability) ? array() : false; } /** * Returns the raw data. * * @deprecated * * @return array Capability data. */ public function toArray() { return $this->_data; } /* SplSubject methods. */ /** */ public function attach(SplObserver $observer) { $this->detach($observer); $this->_observers[] = $observer; } /** */ public function detach(SplObserver $observer) { if (($key = array_search($observer, $this->_observers, true)) !== false) { unset($this->_observers[$key]); } } /** * Notification is triggered internally whenever the object's internal * data storage is altered. */ public function notify() { foreach ($this->_observers as $val) { $val->update($this); } } /* Serializable methods. */ /** */ public function serialize() { return json_encode($this->_data); } /** */ public function unserialize($data) { $this->_data = json_decode($data, true); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Envelope.php0000664000175000017500000001242713150761653022372 0ustar janjan * @category Horde * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * * @todo $date should return null if it doesn't exist. * * @property Horde_Mail_Rfc822_List $bcc Bcc address(es). * @property Horde_Mail_Rfc822_List $cc Cc address(es). * @property Horde_Imap_Client_DateTime $date Message date. * @property Horde_Mail_Rfc822_List $from From address(es). * @property string $in_reply_to Message-ID of the message replied to. * @property string $message_id Message-ID of the message. * @property Horde_Mail_Rfc822_List $reply_to Reply-to address(es). * @property Horde_Mail_Rfc822_List $sender Sender address. * @property string $subject Subject. * @property Horde_Mail_Rfc822_List $to To address(es). */ class Horde_Imap_Client_Data_Envelope implements Serializable { /* Serializable version. */ const VERSION = 3; /** * Data object. * * @var Horde_Mime_Headers */ protected $_data; /** * Constructor. * * @var array $data An array of property names (keys) and values to set * in this object. */ public function __construct(array $data = array()) { $this->_data = new Horde_Mime_Headers(); foreach ($data as $key => $val) { $this->$key = $val; } } /** */ public function __get($name) { $name = $this->_normalizeProperty($name); switch ($name) { case 'bcc': case 'cc': case 'from': case 'reply-to': case 'sender': case 'to': if ($h = $this->_data[$name]) { return $h->getAddressList(true); } if (in_array($name, array('sender', 'reply-to'))) { return $this->from; } break; case 'date': if ($val = $this->_data['date']) { return new Horde_Imap_Client_DateTime($val->value); } break; case 'in-reply-to': case 'message-id': case 'subject': if ($val = $this->_data[$name]) { return $val->value; } break; } // Default values. switch ($name) { case 'bcc': case 'cc': case 'from': case 'to': return new Horde_Mail_Rfc822_List(); case 'date': return new Horde_Imap_Client_DateTime(); case 'in-reply-to': case 'message-id': case 'subject': return ''; } return null; } /** */ public function __set($name, $value) { if (!strlen($value)) { return; } $name = $this->_normalizeProperty($name); switch ($name) { case 'bcc': case 'cc': case 'date': case 'from': case 'in-reply-to': case 'message-id': case 'reply-to': case 'sender': case 'subject': case 'to': switch ($name) { case 'from': if ($this->reply_to->match($value)) { unset($this->_data['reply-to']); } if ($this->sender->match($value)) { unset($this->_data['sender']); } break; case 'reply-to': case 'sender': if ($this->from->match($value)) { unset($this->_data[$name]); return; } break; } $this->_data->addHeader($name, $value); break; } } /** */ public function __isset($name) { $name = $this->_normalizeProperty($name); switch ($name) { case 'reply-to': case 'sender': if (isset($this->_data[$name])) { return true; } $name = 'from'; break; } return isset($this->_data[$name]); } /** */ protected function _normalizeProperty($name) { switch ($name) { case 'in_reply_to': return 'in-reply-to'; case 'message_id': return 'message-id'; case 'reply_to': return 'reply-to'; } return $name; } /* Serializable methods. */ /** */ public function serialize() { return serialize(array( 'd' => $this->_data, 'v' => self::VERSION )); } /** */ public function unserialize($data) { $data = @unserialize($data); if (empty($data['v']) || ($data['v'] != self::VERSION)) { throw new Exception('Cache version change'); } $this->_data = $data['d']; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Fetch.php0000664000175000017500000004427013150761653021647 0ustar janjan * @category Horde * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Fetch { /** Header formatting constants. */ const HEADER_PARSE = 1; const HEADER_STREAM = 2; /** * Internal data array. * * @var array */ protected $_data = array(); /** */ public function __clone() { $this->_data = unserialize(serialize($this->_data)); } /** * Set the full message property. * * @param mixed $msg The full message text, as either a string or stream * resource. */ public function setFullMsg($msg) { $this->_data[Horde_Imap_Client::FETCH_FULLMSG] = $this->_setMixed($msg); } /** * Returns the full message. * * @param boolean $stream Return as a stream? * * @return mixed The full text of the entire message. */ public function getFullMsg($stream = false) { return $this->_msgText( $stream, isset($this->_data[Horde_Imap_Client::FETCH_FULLMSG]) ? $this->_data[Horde_Imap_Client::FETCH_FULLMSG] : null ); } /** * Set the message structure. * * @param Horde_Mime_Part $structure The base MIME part of the message. */ public function setStructure(Horde_Mime_Part $structure) { $this->_data[Horde_Imap_Client::FETCH_STRUCTURE] = $structure; } /** * Get the message structure. * * @return Horde_Mime_Part $structure The base MIME part of the message. */ public function getStructure() { return isset($this->_data[Horde_Imap_Client::FETCH_STRUCTURE]) ? clone $this->_data[Horde_Imap_Client::FETCH_STRUCTURE] : new Horde_Mime_Part(); } /** * Set a header entry. * * @param string $label The search label. * @param mixed $data Either a Horde_Mime_Headers object or the raw * header text. */ public function setHeaders($label, $data) { if ($data instanceof Horde_Stream) { $data = $data->stream; } $this->_data[Horde_Imap_Client::FETCH_HEADERS][$label] = $data; } /** * Get a header entry. * * @param string $label The search label. * @param integer $format The return format. If self::HEADER_PARSE, * returns a Horde_Mime_Headers object. If * self::HEADER_STREAM, returns a stream. * Otherwise, returns header text. * * @return mixed See $format. */ public function getHeaders($label, $format = 0) { return $this->_getHeaders( $label, $format, Horde_Imap_Client::FETCH_HEADERS ); } /** * Set a header text entry. * * @param string $id The MIME ID. * @param mixed $text The header text, as either a string or stream * resource. */ public function setHeaderText($id, $text) { $this->_data[Horde_Imap_Client::FETCH_HEADERTEXT][$id] = $this->_setMixed($text); } /** * Get a header text entry. * * @param string $id The MIME ID. * @param integer $format The return format. If self::HEADER_PARSE, * returns a Horde_Mime_Headers object. If * self::HEADER_STREAM, returns a stream. * Otherwise, returns header text. * * @return mixed See $format. */ public function getHeaderText($id = 0, $format = 0) { return $this->_getHeaders( $id, $format, Horde_Imap_Client::FETCH_HEADERTEXT ); } /** * Set a MIME header entry. * * @param string $id The MIME ID. * @param mixed $text The header text, as either a string or stream * resource. */ public function setMimeHeader($id, $text) { $this->_data[Horde_Imap_Client::FETCH_MIMEHEADER][$id] = $this->_setMixed($text); } /** * Get a MIME header entry. * * @param string $id The MIME ID. * @param integer $format The return format. If self::HEADER_PARSE, * returns a Horde_Mime_Headers object. If * self::HEADER_STREAM, returns a stream. * Otherwise, returns header text. * * @return mixed See $format. */ public function getMimeHeader($id, $format = 0) { return $this->_getHeaders( $id, $format, Horde_Imap_Client::FETCH_MIMEHEADER ); } /** * Set a body part entry. * * @param string $id The MIME ID. * @param mixed $text The body part text, as either a string or stream * resource. * @param string $decode Either '8bit', 'binary', or null. */ public function setBodyPart($id, $text, $decode = null) { $this->_data[Horde_Imap_Client::FETCH_BODYPART][$id] = array( 'd' => $decode, 't' => $this->_setMixed($text) ); } /** * Get a body part entry. * * @param string $id The MIME ID. * @param boolean $stream Return as a stream? * * @return mixed The full text of the body part. */ public function getBodyPart($id, $stream = false) { return $this->_msgText( $stream, isset($this->_data[Horde_Imap_Client::FETCH_BODYPART][$id]) ? $this->_data[Horde_Imap_Client::FETCH_BODYPART][$id]['t'] : null ); } /** * Determines if/how a body part was MIME decoded on the server. * * @param string $id The MIME ID. * * @return string Either '8bit', 'binary', or null. */ public function getBodyPartDecode($id) { return isset($this->_data[Horde_Imap_Client::FETCH_BODYPART][$id]) ? $this->_data[Horde_Imap_Client::FETCH_BODYPART][$id]['d'] : null; } /** * Set the body part size for a body part. * * @param string $id The MIME ID. * @param integer $size The size (in bytes). */ public function setBodyPartSize($id, $size) { $this->_data[Horde_Imap_Client::FETCH_BODYPARTSIZE][$id] = intval($size); } /** * Returns the body part size, if returned by the server. * * @param string $id The MIME ID. * * @return integer The body part size, in bytes. */ public function getBodyPartSize($id) { return isset($this->_data[Horde_Imap_Client::FETCH_BODYPARTSIZE][$id]) ? $this->_data[Horde_Imap_Client::FETCH_BODYPARTSIZE][$id] : null; } /** * Set a body text entry. * * @param string $id The MIME ID. * @param mixed $text The body part text, as either a string or stream * resource. */ public function setBodyText($id, $text) { $this->_data[Horde_Imap_Client::FETCH_BODYTEXT][$id] = $this->_setMixed($text); } /** * Get a body text entry. * * @param string $id The MIME ID. * @param boolean $stream Return as a stream? * * @return mixed The full text of the body text. */ public function getBodyText($id = 0, $stream = false) { return $this->_msgText( $stream, isset($this->_data[Horde_Imap_Client::FETCH_BODYTEXT][$id]) ? $this->_data[Horde_Imap_Client::FETCH_BODYTEXT][$id] : null ); } /** * Set envelope data. * * @param array $data The envelope data to pass to the Envelope object * constructor, or an Envelope object. */ public function setEnvelope($data) { $this->_data[Horde_Imap_Client::FETCH_ENVELOPE] = is_array($data) ? new Horde_Imap_Client_Data_Envelope($data) : $data; } /** * Get envelope data. * * @return Horde_Imap_Client_Data_Envelope An envelope object. */ public function getEnvelope() { return isset($this->_data[Horde_Imap_Client::FETCH_ENVELOPE]) ? clone $this->_data[Horde_Imap_Client::FETCH_ENVELOPE] : new Horde_Imap_Client_Data_Envelope(); } /** * Set IMAP flags. * * @param array $flags An array of IMAP flags. */ public function setFlags(array $flags) { $this->_data[Horde_Imap_Client::FETCH_FLAGS] = array_map( 'Horde_String::lower', array_map('trim', $flags) ); } /** * Get IMAP flags. * * @return array An array of IMAP flags (all flags in lowercase). */ public function getFlags() { return isset($this->_data[Horde_Imap_Client::FETCH_FLAGS]) ? $this->_data[Horde_Imap_Client::FETCH_FLAGS] : array(); } /** * Set IMAP internal date. * * @param mixed $date Either a Horde_Imap_Client_DateTime object or a * date string. */ public function setImapDate($date) { $this->_data[Horde_Imap_Client::FETCH_IMAPDATE] = is_object($date) ? $date : new Horde_Imap_Client_DateTime($date); } /** * Get internal IMAP date. * * @return Horde_Imap_Client_DateTime A date object. */ public function getImapDate() { return isset($this->_data[Horde_Imap_Client::FETCH_IMAPDATE]) ? clone $this->_data[Horde_Imap_Client::FETCH_IMAPDATE] : new Horde_Imap_Client_DateTime(); } /** * Set message size. * * @param integer $size The size of the message, in bytes. */ public function setSize($size) { $this->_data[Horde_Imap_Client::FETCH_SIZE] = intval($size); } /** * Get message size. * * @return integer The size of the message, in bytes. */ public function getSize() { return isset($this->_data[Horde_Imap_Client::FETCH_SIZE]) ? $this->_data[Horde_Imap_Client::FETCH_SIZE] : 0; } /** * Set UID. * * @param integer $uid The message UID. */ public function setUid($uid) { $this->_data[Horde_Imap_Client::FETCH_UID] = intval($uid); } /** * Get UID. * * @return integer The message UID. */ public function getUid() { return isset($this->_data[Horde_Imap_Client::FETCH_UID]) ? $this->_data[Horde_Imap_Client::FETCH_UID] : null; } /** * Set message sequence number. * * @param integer $seq The message sequence number. */ public function setSeq($seq) { $this->_data[Horde_Imap_Client::FETCH_SEQ] = intval($seq); } /** * Get message sequence number. * * @return integer The message sequence number. */ public function getSeq() { return isset($this->_data[Horde_Imap_Client::FETCH_SEQ]) ? $this->_data[Horde_Imap_Client::FETCH_SEQ] : null; } /** * Set the modified sequence value for the message. * * @param integer $modseq The modseq value. */ public function setModSeq($modseq) { $this->_data[Horde_Imap_Client::FETCH_MODSEQ] = intval($modseq); } /** * Get the modified sequence value for the message. * * @return integer The modseq value. */ public function getModSeq() { return isset($this->_data[Horde_Imap_Client::FETCH_MODSEQ]) ? $this->_data[Horde_Imap_Client::FETCH_MODSEQ] : null; } /** * Set the internationalized downgraded status for the message. * * @since 2.11.0 * * @param boolean $downgraded True if at least one message component has * been downgraded. */ public function setDowngraded($downgraded) { if ($downgraded) { $this->_data[Horde_Imap_Client::FETCH_DOWNGRADED] = true; } else { unset($this->_data[Horde_Imap_Client::FETCH_DOWNGRADED]); } } /** * Does the message contain internationalized downgraded data (i.e. it * is a "surrogate" message)? * * @since 2.11.0 * * @return boolean True if at least one message components has been * downgraded. */ public function isDowngraded() { return !empty($this->_data[Horde_Imap_Client::FETCH_DOWNGRADED]); } /** * Return the internal representation of the data. * * @return array The data array. */ public function getRawData() { return $this->_data; } /** * Merge a fetch object into this one. * * @param Horde_Imap_Client_Data_Fetch $data A fetch object. */ public function merge(Horde_Imap_Client_Data_Fetch $data) { $this->_data = array_replace_recursive( $this->_data, $data->getRawData() ); } /** * Does this object containing cacheable data of the given type? * * @param integer $type The type to query. * * @return boolean True if the type is cacheable. */ public function exists($type) { return isset($this->_data[$type]); } /** * Does this object contain only default values for all fields? * * @return boolean True if object contains default data. */ public function isDefault() { return empty($this->_data); } /** * Return text representation of a field. * * @param boolean $stream Return as a stream? * @param mixed $data The field data (string or resource) or null if * field does not exist. * * @return mixed Requested text representation. */ protected function _msgText($stream, $data) { if ($data instanceof Horde_Stream) { if ($stream) { $data->rewind(); return $data->stream; } return strval($data); } if (is_resource($data)) { rewind($data); return $stream ? $data : stream_get_contents($data); } if (!$stream) { return strval($data); } $tmp = fopen('php://temp', 'w+'); if (!is_null($data)) { fwrite($tmp, $data); rewind($tmp); } return $tmp; } /** * Return representation of a header field. * * @param string $id The header id. * @param integer $format The return format. If self::HEADER_PARSE, * returns a Horde_Mime_Headers object. If * self::HEADER_STREAM, returns a stream. * Otherwise, returns header text. * @param integer $key The array key where the data is stored in the * internal array. * * @return mixed The data in the format specified by $format. */ protected function _getHeaders($id, $format, $key) { switch ($format) { case self::HEADER_STREAM: if (!isset($this->_data[$key][$id])) { $data = null; } elseif (is_object($this->_data[$key][$id])) { switch ($key) { case Horde_Imap_Client::FETCH_HEADERS: $data = $this->_getHeaders($id, 0, $key); break; case Horde_Imap_Client::FETCH_HEADERTEXT: case Horde_Imap_Client::FETCH_MIMEHEADER: $data = $this->_data[$key][$id]; break; } } else { $data = $this->_data[$key][$id]; } return $this->_msgText(true, $data); case self::HEADER_PARSE: if (!isset($this->_data[$key][$id])) { return new Horde_Mime_Headers(); } elseif (is_object($this->_data[$key][$id])) { switch ($key) { case Horde_Imap_Client::FETCH_HEADERS: return clone $this->_data[$key][$id]; case Horde_Imap_Client::FETCH_HEADERTEXT: case Horde_Imap_Client::FETCH_MIMEHEADER: $hdrs = $this->_data[$key][$id]; break; } } else { $hdrs = $this->_getHeaders($id, self::HEADER_STREAM, $key); } return Horde_Mime_Headers::parseHeaders($hdrs); } if (!isset($this->_data[$key][$id])) { return ''; } if (is_object($this->_data[$key][$id])) { switch ($key) { case Horde_Imap_Client::FETCH_HEADERS: return $this->_data[$key][$id]->toString( array('nowrap' => true) ); case Horde_Imap_Client::FETCH_HEADERTEXT: case Horde_Imap_Client::FETCH_MIMEHEADER: return strval($this->_data[$key][$id]); } } return $this->_msgText(false, $this->_data[$key][$id]); } /** * Converts mixed input (string or resource) to the correct internal * representation. * * @param mixed $data Mixed data (string, resource, Horde_Stream object). * * @return mixed The internal representation of that data. */ protected function _setMixed($data) { return is_resource($data) ? new Horde_Stream_Existing(array('stream' => $data)) : $data; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Format.php0000664000175000017500000000321713150761653022042 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Format { /** * Data. * * @var mixed */ protected $_data; /** * Constructor. * * @param mixed $data Data. */ public function __construct($data) { $this->_data = is_resource($data) ? stream_get_contents($data, -1, 0) : $data; } /** * Returns the string value of the raw data. * * @return string String value. */ public function __toString() { return strval($this->_data); } /** * Returns the raw data. * * @return mixed Raw data. */ public function getData() { return $this->_data; } /** * Returns the data formatted for output to the IMAP server. * * @return string IMAP escaped string. */ public function escape() { return strval($this); } /** * Verify the data. * * @throws Horde_Imap_Client_Data_Format_Exception */ public function verify() { } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Namespace.php0000664000175000017500000000630113150761653022503 0ustar janjan * @category Horde * @copyright 2013-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.21.0 * * @property-read string $base The namespace base ($name without trailing * delimiter) (UTF-8). * @property string $delimiter The namespace delimiter. * @property boolean $hidden Is this a hidden namespace? * @property string $name The namespace name (UTF-8). * @property string $translation Returns the translated name of the namespace * (UTF-8). * @property integer $type The namespace type. Either self::NS_PERSONAL, * self::NS_OTHER, or self::NS_SHARED. */ class Horde_Imap_Client_Data_Namespace implements Serializable { /* Namespace type constants. */ const NS_PERSONAL = 1; const NS_OTHER = 2; const NS_SHARED = 3; /** * Data object. * * @var array */ protected $_data = array(); /** * Strips namespace information from the given mailbox name. * * @param string $mbox Mailbox name. * * @return string Mailbox name with namespace prefix stripped. */ public function stripNamespace($mbox) { $mbox = strval($mbox); $name = $this->name; return (strlen($name) && (strpos($mbox, $name) === 0)) ? substr($mbox, strlen($name)) : $mbox; } /** */ public function __get($name) { if (isset($this->_data[$name])) { return $this->_data[$name]; } switch ($name) { case 'base': return rtrim($this->name, $this->delimiter); case 'delimiter': case 'name': case 'translation': return ''; case 'hidden': return false; case 'type': return self::NS_PERSONAL; } return null; } /** */ public function __set($name, $value) { switch ($name) { case 'delimiter': case 'name': case 'translation': $this->_data[$name] = strval($value); break; case 'hidden': $this->_data[$name] = (bool)$value; break; case 'type': $this->_data[$name] = intval($value); break; } } /** */ public function __isset($name) { return isset($this->_data[$name]); } /** */ public function __toString() { return $this->name; } /* Serializable methods. */ /** */ public function serialize() { return json_encode($this->_data); } /** */ public function unserialize($data) { $this->_data = json_decode($data, true); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/SearchCharset.php0000664000175000017500000001033413150761653023327 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.24.0 * * @property-read array $charsets The list of valid charsets that have been * discovered on the server. */ class Horde_Imap_Client_Data_SearchCharset implements Serializable, SplSubject { /** * Base client object. * * @var Horde_Imap_Client_Base */ protected $_baseob; /** * Charset data. * * @var array */ protected $_charsets = array( 'US-ASCII' => true ); /** * Observers. * * @var array */ protected $_observers = array(); /** */ public function __get($name) { switch ($name) { case 'charsets': return array_keys(array_filter($this->_charsets)); } } /** */ public function setBaseOb(Horde_Imap_Client_Base $ob) { $this->_baseob = $ob; } /** * Query the validity of a charset. * * @param string $charset The charset to query. * @param boolean $cached If true, only query cached values. * * @return boolean True if the charset is valid for searching. */ public function query($charset, $cached = false) { $charset = Horde_String::upper($charset); if (isset($this->_charsets[$charset])) { return $this->_charsets[$charset]; } elseif ($cached) { return null; } if (!$this->_baseob) { throw new RuntimeException( 'Base object needs to be defined to query for charset.' ); } /* Use a dummy search query and search for BADCHARSET response. */ $query = new Horde_Imap_Client_Search_Query(); $query->charset($charset, false); $query->ids($this->_baseob->getIdsOb(1, true)); $query->text('a'); try { $this->_baseob->search('INBOX', $query, array( 'nocache' => true, 'sequence' => true )); $this->_charsets[$charset] = true; } catch (Horde_Imap_Client_Exception $e) { $this->_charsets[$charset] = ($e->getCode() !== Horde_Imap_Client_Exception::BADCHARSET); } $this->notify(); return $this->_charsets[$charset]; } /** * Set the validity of a given charset. * * @param string $charset The charset. * @param boolean $valid Is charset valid? */ public function setValid($charset, $valid = true) { $charset = Horde_String::upper($charset); $valid = (bool)$valid; if (!isset($this->_charsets[$charset]) || ($this->_charsets[$charset] !== $valid)) { $this->_charsets[$charset] = $valid; $this->notify(); } } /* SplSubject methods. */ /** */ public function attach(SplObserver $observer) { $this->detach($observer); $this->_observers[] = $observer; } /** */ public function detach(SplObserver $observer) { if (($key = array_search($observer, $this->_observers, true)) !== false) { unset($this->_observers[$key]); } } /** * Notification is triggered internally whenever the object's internal * data storage is altered. */ public function notify() { foreach ($this->_observers as $val) { $val->update($this); } } /* Serializable methods. */ /** */ public function serialize() { return json_encode($this->_charsets); } /** */ public function unserialize($data) { $this->_charsets = json_decode($data, true); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Sync.php0000664000175000017500000002001013150761653021514 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.2.0 * * @property-read Horde_Imap_Client_Ids $flagsuids List of messages with flag * changes. * @property-read Horde_Imap_Client_Ids $newmsgsuids List of new messages. * @property-read Horde_Imap_Client_Ids $vanisheduids List of messages that * have vanished. */ class Horde_Imap_Client_Data_Sync { /** * Mappings of status() values to sync keys. * * @since 2.8.0 * * @var array */ public static $map = array( 'H' => 'highestmodseq', 'M' => 'messages', 'U' => 'uidnext', 'V' => 'uidvalidity' ); /** * Are there messages that have had flag changes? * * @var boolean */ public $flags = null; /** * The previous value of HIGHESTMODSEQ. * * @since 2.8.0 * * @var integer */ public $highestmodseq = null; /** * The synchronized mailbox. * * @var Horde_Imap_Client_Mailbox */ public $mailbox; /** * The previous number of messages in the mailbox. * * @since 2.8.0 * * @var integer */ public $messages = null; /** * Are there new messages? * * @var boolean */ public $newmsgs = null; /** * The previous value of UIDNEXT. * * @since 2.8.0 * * @var integer */ public $uidnext = null; /** * The previous value of UIDVALIDITY. * * @since 2.8.0 * * @var integer */ public $uidvalidity = null; /** * The UIDs of messages that are guaranteed to have vanished. This list is * only guaranteed to be available if the server supports QRESYNC or a * list of known UIDs is passed to the sync() method. * * @var Horde_Imap_Client_Ids */ public $vanished = null; /** * UIDs of messages that have had flag changes. * * @var Horde_Imap_Client_Ids */ protected $_flagsuids; /** * UIDs of new messages. * * @var Horde_Imap_Client_Ids */ protected $_newmsgsuids; /** * UIDs of messages that have vanished. * * @var Horde_Imap_Client_Ids */ protected $_vanisheduids; /** * Constructor. * * @param Horde_Imap_Client_Base $base_ob Base driver object. * @param mixed $mailbox Mailbox to sync. * @param array $sync Token sync data. * @param array $curr Current sync data. * @param integer $criteria Mask of criteria to return. * @param Horde_Imap_Client_Ids $ids List of known UIDs. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_Sync */ public function __construct(Horde_Imap_Client_Base $base_ob, $mailbox, $sync, $curr, $criteria, $ids) { foreach (self::$map as $key => $val) { if (isset($sync[$key])) { $this->$val = $sync[$key]; } } /* Check uidvalidity. */ if (!$this->uidvalidity || ($curr['V'] != $this->uidvalidity)) { throw new Horde_Imap_Client_Exception_Sync('UIDs in cached mailbox have changed.', Horde_Imap_Client_Exception_Sync::UIDVALIDITY_CHANGED); } $this->mailbox = $mailbox; /* This was a UIDVALIDITY check only. */ if (!$criteria) { return; } $sync_all = ($criteria & Horde_Imap_Client::SYNC_ALL); /* New messages. */ if ($sync_all || ($criteria & Horde_Imap_Client::SYNC_NEWMSGS) || ($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS)) { $this->newmsgs = empty($this->uidnext) ? !empty($curr['U']) : (!empty($curr['U']) && ($curr['U'] > $this->uidnext)); if ($this->newmsgs && ($sync_all || ($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS))) { $new_ids = empty($this->uidnext) ? Horde_Imap_Client_Ids::ALL : ($this->uidnext . ':' . $curr['U']); $squery = new Horde_Imap_Client_Search_Query(); $squery->ids(new Horde_Imap_Client_Ids($new_ids)); $sres = $base_ob->search($mailbox, $squery); $this->_newmsgsuids = $sres['match']; } } /* Do single status call to get all necessary data. */ if ($this->highestmodseq && ($sync_all || ($criteria & Horde_Imap_Client::SYNC_FLAGS) || ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS) || ($criteria & Horde_Imap_Client::SYNC_VANISHED) || ($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS))) { $status_sync = $base_ob->status($mailbox, Horde_Imap_Client::STATUS_SYNCMODSEQ | Horde_Imap_Client::STATUS_SYNCFLAGUIDS | Horde_Imap_Client::STATUS_SYNCVANISHED); if (!is_null($ids)) { $ids = $base_ob->resolveIds($mailbox, $ids); } } /* Flag changes. */ if ($sync_all || ($criteria & Horde_Imap_Client::SYNC_FLAGS)) { $this->flags = $this->highestmodseq ? ($this->highestmodseq != $curr['H']) : true; } if ($sync_all || ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS)) { if ($this->highestmodseq) { if ($this->highestmodseq == $status_sync['syncmodseq']) { $this->_flagsuids = is_null($ids) ? $status_sync['syncflaguids'] : $base_ob->getIdsOb(array_intersect($ids->ids, $status_sync['syncflaguids']->ids)); } else { $squery = new Horde_Imap_Client_Search_Query(); $squery->modseq($this->highestmodseq + 1); $sres = $base_ob->search($mailbox, $squery, array( 'ids' => $ids )); $this->_flagsuids = $sres['match']; } } else { /* Without MODSEQ, need to mark all FLAGS as changed. */ $this->_flagsuids = $base_ob->resolveIds($mailbox, is_null($ids) ? $base_ob->getIdsOb(Horde_Imap_Client_Ids::ALL) : $ids); } } /* Vanished messages. */ if ($sync_all || ($criteria & Horde_Imap_Client::SYNC_VANISHED) || ($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS)) { if ($this->highestmodseq && ($this->highestmodseq == $status_sync['syncmodseq'])) { $vanished = is_null($ids) ? $status_sync['syncvanished'] : $base_ob->getIdsOb(array_intersect($ids->ids, $status_sync['syncvanished']->ids)); } else { $vanished = $base_ob->vanished($mailbox, $this->highestmodseq ? $this->highestmodseq : 1, array( 'ids' => $ids )); } $this->vanished = (bool)count($vanished); $this->_vanisheduids = $vanished; } } /** */ public function __get($name) { switch ($name) { case 'flagsuids': case 'newmsgsuids': case 'vanisheduids': return empty($this->{'_' . $name}) ? new Horde_Imap_Client_Ids() : $this->{'_' . $name}; } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Data/Thread.php0000664000175000017500000000767613150761653022036 0ustar janjan * @category Horde * @copyright 2008-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Data_Thread implements Countable, Serializable { /** * Internal thread data structure. Keys are base values, values are arrays * with keys as the ID and values as the level. * * @var array */ protected $_thread = array(); /** * The index type. * * @var string */ protected $_type; /** * Constructor. * * @param array $data See $_thread. * @param string $type Either 'sequence' or 'uid'. */ public function __construct($data, $type) { $this->_thread = $data; $this->_type = $type; } /** * Return the ID type. * * @return string Either 'sequence' or 'uid'. */ public function getType() { return $this->_type; } /** * Return the sorted list of messages indices. * * @return Horde_Imap_Client_Ids The sorted list of messages. */ public function messageList() { return new Horde_Imap_Client_Ids($this->_getAllIndices(), $this->getType() == 'sequence'); } /** * Returns the list of messages in a thread. * * @param integer $index An index contained in the thread. * * @return array Keys are indices, values are objects with the following * properties: * - base: (integer) Base ID of the thread. If null, thread is a single * message. * - last: (boolean) If true, this is the last index in the sublevel. * - level: (integer) The sublevel of the index. */ public function getThread($index) { foreach ($this->_thread as $v) { if (isset($v[$index])) { reset($v); $ob = new stdClass; $ob->base = (count($v) > 1) ? key($v) : null; $ob->last = false; $levels = $out = array(); $last = 0; while (($v2 = current($v)) !== false) { $k2 = key($v); $ob2 = clone $ob; $ob2->level = $v2; $out[$k2] = $ob2; if (($last < $v2) && isset($levels[$v2])) { $out[$levels[$v2]]->last = true; } $levels[$v2] = $k2; $last = $v2; next($v); } foreach ($levels as $v) { $out[$v]->last = true; } return $out; } } return array(); } /* Countable methods. */ /** */ public function count() { return count($this->_getAllIndices()); } /* Serializable methods. */ /** */ public function serialize() { return json_encode(array( $this->_thread, $this->_type )); } /** */ public function unserialize($data) { list($this->_thread, $this->_type) = json_decode($data, true); } /* Protected methods. */ /** * Return all indices. * * @return array An array of indices. */ protected function _getAllIndices() { $out = array(); foreach ($this->_thread as $val) { $out += $val; } return array_keys($out); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Exception/NoSupportExtension.php0000664000175000017500000000265113150761653025546 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Exception_NoSupportExtension extends Horde_Imap_Client_Exception { /** * The extension not supported on the server. * * @var string */ public $extension; /** * Constructor. * * @param string $extension The extension not supported on the server. * @param string $msg A non-standard error message to use instead * of the default. */ public function __construct($extension, $msg = null) { $this->extension = $extension; if (is_null($msg)) { $msg = sprintf( Horde_Imap_Client_Translation::r("The server does not support the %s extension."), $extension ); } parent::__construct($msg, self::NOT_SUPPORTED); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Exception/NoSupportPop3.php0000664000175000017500000000207613150761653024414 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Exception_NoSupportPop3 extends Horde_Imap_Client_Exception { /** * Constructor. * * @param string $feature The feature not supported in POP3. */ public function __construct($feature) { parent::__construct( Horde_Imap_Client_Translation::r("%s not supported on POP3 servers."), self::NOT_SUPPORTED ); $this->messagePrintf(array($feature)); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Exception/SearchCharset.php0000664000175000017500000000236413150761653024420 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Exception_SearchCharset extends Horde_Imap_Client_Exception { /** * Charset that was attempted to be converted to. * * @var string */ public $charset; /** * Constructor. * * @param string $charset The charset that was attempted to be converted * to. */ public function __construct($charset) { $this->charset = $charset; parent::__construct( Horde_Imap_Client_Translation::r("Cannot convert search query text to new charset"), self::BADCHARSET ); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Exception/ServerResponse.php0000664000175000017500000000456413150761653024672 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * * @property-read string $command The command that caused the BAD/NO error * status. * @property-read array $resp_data The response data array. * @property-read integer $status Server error status. */ class Horde_Imap_Client_Exception_ServerResponse extends Horde_Imap_Client_Exception { /** * Pipeline object. * * @var Horde_Imap_Client_Interaction_Pipeline */ protected $_pipeline; /** * Server response object. * * @var Horde_Imap_Client_Interaction_Server */ protected $_server; /** * Constructor. * * @param string $msg Error message. * @param integer $code Error code. * @param Horde_Imap_Client_Interaction_Server $server Server ob. * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline ob. */ public function __construct( $msg = null, $code = 0, Horde_Imap_Client_Interaction_Server $server, Horde_Imap_Client_Interaction_Pipeline $pipeline ) { $this->details = strval($server->token); $this->_pipeline = $pipeline; $this->_server = $server; parent::__construct($msg, $code); } /** */ public function __get($name) { switch ($name) { case 'command': return ($this->_server instanceof Horde_Imap_Client_Interaction_Server_Tagged) ? $this->_pipeline->getCmd($this->_server->tag)->getCommand() : null; case 'resp_data': return $this->_pipeline->data; case 'status': return $this->_server->status; default: return parent::__get($name); } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Exception/Sync.php0000664000175000017500000000160113150761653022606 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Exception_Sync extends Horde_Exception_Wrapped { /* Error message codes. */ /** * Token could not be parsed. */ const BAD_TOKEN = 1; /** * UIDVALIDITY of the mailbox changed. */ const UIDVALIDITY_CHANGED = 2; } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Fetch/Query.php0000664000175000017500000002566013150761653022105 0ustar janjan * @category Horde * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Fetch_Query implements ArrayAccess, Countable, Iterator { /** * Internal data array. * * @var array */ protected $_data = array(); /** * Get the full text of the message. * * @param array $opts The following options are available: * - length: (integer) The length of the substring to return. * DEFAULT: The entire text is returned. * - peek: (boolean) If set, does not set the '\Seen' flag on the * message. * DEFAULT: The seen flag is set. * - start: (integer) If a portion of the full text is desired to be * returned, the starting position is identified here. * DEFAULT: The entire text is returned. */ public function fullText(array $opts = array()) { $this->_data[Horde_Imap_Client::FETCH_FULLMSG] = $opts; } /** * Return header text. * * Header text is defined only for the base RFC 2822 message or * message/rfc822 parts. * * @param array $opts The following options are available: * - id: (string) The MIME ID to obtain the header text for. * DEFAULT: The header text for the base message will be * returned. * - length: (integer) The length of the substring to return. * DEFAULT: The entire text is returned. * - peek: (boolean) If set, does not set the '\Seen' flag on the * message. * DEFAULT: The seen flag is set. * - start: (integer) If a portion of the full text is desired to be * returned, the starting position is identified here. * DEFAULT: The entire text is returned. */ public function headerText(array $opts = array()) { $id = isset($opts['id']) ? $opts['id'] : 0; $this->_data[Horde_Imap_Client::FETCH_HEADERTEXT][$id] = $opts; } /** * Return body text. * * Body text is defined only for the base RFC 2822 message or * message/rfc822 parts. * * @param array $opts The following options are available: * - id: (string) The MIME ID to obtain the body text for. * DEFAULT: The body text for the entire message will be * returned. * - length: (integer) The length of the substring to return. * DEFAULT: The entire text is returned. * - peek: (boolean) If set, does not set the '\Seen' flag on the * message. * DEFAULT: The seen flag is set. * - start: (integer) If a portion of the full text is desired to be * returned, the starting position is identified here. * DEFAULT: The entire text is returned. */ public function bodyText(array $opts = array()) { $id = isset($opts['id']) ? $opts['id'] : 0; $this->_data[Horde_Imap_Client::FETCH_BODYTEXT][$id] = $opts; } /** * Return MIME header text. * * MIME header text is defined only for non-RFC 2822 messages and * non-message/rfc822 parts. * * @param string $id The MIME ID to obtain the MIME header text for. * @param array $opts The following options are available: * - length: (integer) The length of the substring to return. * DEFAULT: The entire text is returned. * - peek: (boolean) If set, does not set the '\Seen' flag on the * message. * DEFAULT: The seen flag is set. * - start: (integer) If a portion of the full text is desired to be * returned, the starting position is identified here. * DEFAULT: The entire text is returned. */ public function mimeHeader($id, array $opts = array()) { $this->_data[Horde_Imap_Client::FETCH_MIMEHEADER][$id] = $opts; } /** * Return the body part data for a MIME ID. * * @param string $id The MIME ID to obtain the body part text for. * @param array $opts The following options are available: * - decode: (boolean) Attempt to server-side decode the bodypart data * if it is MIME transfer encoded. * DEFAULT: false * - length: (integer) The length of the substring to return. * DEFAULT: The entire text is returned. * - peek: (boolean) If set, does not set the '\Seen' flag on the * message. * DEFAULT: The seen flag is set. * - start: (integer) If a portion of the full text is desired to be * returned, the starting position is identified here. * DEFAULT: The entire text is returned. */ public function bodyPart($id, array $opts = array()) { $this->_data[Horde_Imap_Client::FETCH_BODYPART][$id] = $opts; } /** * Returns the decoded body part size for a MIME ID. * * @param string $id The MIME ID to obtain the decoded body part size * for. */ public function bodyPartSize($id) { $this->_data[Horde_Imap_Client::FETCH_BODYPARTSIZE][$id] = true; } /** * Returns RFC 2822 header text that matches a search string. * * This header search work only with the base RFC 2822 message or * message/rfc822 parts. * * @param string $label A unique label associated with this particular * search. This is how the results are stored. * @param array $search The search string(s) (case-insensitive). * @param array $opts The following options are available: * - cache: (boolean) If true, and 'peek' is also true, will cache * the result of this call. * DEFAULT: false * - id: (string) The MIME ID to search. * DEFAULT: The base message part * - length: (integer) The length of the substring to return. * DEFAULT: The entire text is returned. * - notsearch: (boolean) Do a 'NOT' search on the headers. * DEFAULT: false * - peek: (boolean) If set, does not set the '\Seen' flag on the * message. * DEFAULT: The seen flag is set. * - start: (integer) If a portion of the full text is desired to be * returned, the starting position is identified here. * DEFAULT: The entire text is returned. */ public function headers($label, $search, array $opts = array()) { $this->_data[Horde_Imap_Client::FETCH_HEADERS][$label] = array_merge( $opts, array( 'headers' => array_map('strval', $search) ) ); } /** * Return MIME structure information. */ public function structure() { $this->_data[Horde_Imap_Client::FETCH_STRUCTURE] = true; } /** * Return envelope header data. */ public function envelope() { $this->_data[Horde_Imap_Client::FETCH_ENVELOPE] = true; } /** * Return flags set for the message. */ public function flags() { $this->_data[Horde_Imap_Client::FETCH_FLAGS] = true; } /** * Return the internal (IMAP) date of the message. */ public function imapDate() { $this->_data[Horde_Imap_Client::FETCH_IMAPDATE] = true; } /** * Return the size (in bytes) of the message. */ public function size() { $this->_data[Horde_Imap_Client::FETCH_SIZE] = true; } /** * Return the unique ID of the message. */ public function uid() { $this->_data[Horde_Imap_Client::FETCH_UID] = true; } /** * Return the sequence number of the message. */ public function seq() { $this->_data[Horde_Imap_Client::FETCH_SEQ] = true; } /** * Return the mod-sequence value for the message. * * The server must support the CONDSTORE IMAP extension, and the mailbox * must support mod-sequences. */ public function modseq() { $this->_data[Horde_Imap_Client::FETCH_MODSEQ] = true; } /** * Does the query contain the given criteria? * * @param integer $criteria The criteria to remove. * * @return boolean True if the query contains the given criteria. */ public function contains($criteria) { return isset($this->_data[$criteria]); } /** * Remove an entry under a given criteria. * * @param integer $criteria Criteria ID. * @param string $key The key to remove. */ public function remove($criteria, $key) { if (isset($this->_data[$criteria]) && is_array($this->_data[$criteria])) { unset($this->_data[$criteria][$key]); if (empty($this->_data[$criteria])) { unset($this->_data[$criteria]); } } } /** * Returns a hash of the current query object. * * @return string Hash. */ public function hash() { return hash('md5', serialize($this)); } /* ArrayAccess methods. */ /** */ public function offsetExists($offset) { return isset($this->_data[$offset]); } /** */ public function offsetGet($offset) { return isset($this->_data[$offset]) ? $this->_data[$offset] : null; } /** */ public function offsetSet($offset, $value) { $this->_data[$offset] = $value; } /** */ public function offsetUnset($offset) { unset($this->_data[$offset]); } /* Countable methods. */ /** */ public function count() { return count($this->_data); } /* Iterator methods. */ /** */ public function current() { $opts = current($this->_data); return (!empty($opts) && ($this->key() == Horde_Imap_Client::FETCH_BODYPARTSIZE)) ? array_keys($opts) : $opts; } /** */ public function key() { return key($this->_data); } /** */ public function next() { next($this->_data); } /** */ public function rewind() { reset($this->_data); } /** */ public function valid() { return !is_null($this->key()); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Fetch/Results.php0000664000175000017500000000734413150761653022440 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * * @property-read integer $key_type The key type (sequence or UID). */ class Horde_Imap_Client_Fetch_Results implements ArrayAccess, Countable, IteratorAggregate { /** * Key type constants. */ const SEQUENCE = 1; const UID = 2; /** * Internal data array. * * @var array */ protected $_data = array(); /** * Key type. * * @var integer */ protected $_keyType; /** * Class to use when creating a new fetch object. * * @var string */ protected $_obClass; /** * Constructor. * * @param string $ob_class Class to use when creating a new fetch * object. * @param integer $key_type Key type. */ public function __construct($ob_class = 'Horde_Imap_Client_Data_Fetch', $key_type = self::UID) { $this->_obClass = $ob_class; $this->_keyType = $key_type; } /** */ public function __get($name) { switch ($name) { case 'key_type': return $this->_keyType; } } /** * Return a fetch object, creating and storing an empty object in the * results set if it doesn't currently exist. * * @param string $key The key to retrieve. * * @return Horde_Imap_Client_Data_Fetch The fetch object. */ public function get($key) { if (!isset($this->_data[$key])) { $this->_data[$key] = new $this->_obClass(); } return $this->_data[$key]; } /** * Return the list of IDs. * * @return array ID list. */ public function ids() { ksort($this->_data); return array_keys($this->_data); } /** * Return the first fetch object in the results, if there is only one * object. * * @return null|Horde_Imap_Client_Data_Fetch The fetch object if there is * only one object, or null. */ public function first() { return (count($this->_data) === 1) ? reset($this->_data) : null; } /** * Clears all fetch results. * * @since 2.6.0 */ public function clear() { $this->_data = array(); } /* ArrayAccess methods. */ /** */ public function offsetExists($offset) { return isset($this->_data[$offset]); } /** */ public function offsetGet($offset) { return isset($this->_data[$offset]) ? $this->_data[$offset] : null; } /** */ public function offsetSet($offset, $value) { $this->_data[$offset] = $value; } /** */ public function offsetUnset($offset) { unset($this->_data[$offset]); } /* Countable methods. */ /** */ public function count() { return count($this->_data); } /* IteratorAggregate methods. */ /** */ public function getIterator() { ksort($this->_data); return new ArrayIterator($this->_data); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Ids/Map.php0000664000175000017500000001414013150761653021172 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.1.0 * * @property-read array $map The raw ID mapping data. * @property-read Horde_Imap_Client_Ids $seq The sorted sequence values. * @property-read Horde_Imap_Client_Ids $uids The sorted UIDs. */ class Horde_Imap_Client_Ids_Map implements Countable, IteratorAggregate, Serializable { /** * Sequence -> UID mapping. * * @var array */ protected $_ids = array(); /** * Is the array sorted? * * @var boolean */ protected $_sorted = true; /** * Constructor. * * @param array $ids Array of sequence -> UID mapping. */ public function __construct(array $ids = array()) { $this->update($ids); } /** */ public function __get($name) { switch ($name) { case 'map': return $this->_ids; case 'seq': $this->sort(); return new Horde_Imap_Client_Ids(array_keys($this->_ids), true); case 'uids': $this->sort(); return new Horde_Imap_Client_Ids($this->_ids); } } /** * Updates the mapping. * * @param array $ids Array of sequence -> UID mapping. * * @return boolean True if the mapping changed. */ public function update($ids) { if (empty($ids)) { return false; } elseif (empty($this->_ids)) { $this->_ids = $ids; $change = true; } else { $change = false; foreach ($ids as $k => $v) { if (!isset($this->_ids[$k]) || ($this->_ids[$k] != $v)) { $this->_ids[$k] = $v; $change = true; } } } if ($change) { $this->_sorted = false; } return $change; } /** * Create a Sequence <-> UID lookup table. * * @param Horde_Imap_Client_Ids $ids IDs to lookup. * * @return array Keys are sequence numbers, values are UIDs. */ public function lookup(Horde_Imap_Client_Ids $ids) { if ($ids->all) { return $this->_ids; } elseif ($ids->sequence) { return array_intersect_key($this->_ids, array_flip($ids->ids)); } return array_intersect($this->_ids, $ids->ids); } /** * Removes messages from the ID mapping. * * @param Horde_Imap_Client_Ids $ids IDs to remove. */ public function remove(Horde_Imap_Client_Ids $ids) { /* For sequence numbers, we need to reindex anytime we have an index * that appears equal to or after a previously seen index. If an IMAP * server is smart, it will expunge in reverse order instead. */ if ($ids->sequence) { $remove = $ids->ids; } else { $ids->sort(); $remove = array_reverse(array_keys($this->lookup($ids))); } if (empty($remove)) { return; } $this->sort(); if (count($remove) == count($this->_ids) && !array_diff($remove, array_keys($this->_ids))) { $this->_ids = array(); return; } /* Find the minimum sequence number to remove. We know entries before * this are untouched so no need to process them multiple times. */ $first = min($remove); $edit = $newids = array(); foreach (array_keys($this->_ids) as $i => $seq) { if ($seq >= $first) { $i += (($seq == $first) ? 0 : 1); $newids = array_slice($this->_ids, 0, $i, true); $edit = array_slice($this->_ids, $i + (($seq == $first) ? 0 : 1), null, true); break; } } if (!empty($edit)) { foreach ($remove as $val) { $found = false; $tmp = array(); foreach (array_keys($edit) as $i => $seq) { if ($found) { $tmp[$seq - 1] = $edit[$seq]; } elseif ($seq >= $val) { $tmp = array_slice($edit, 0, ($seq == $val) ? $i : $i + 1, true); $found = true; } } $edit = $tmp; } } $this->_ids = $newids + $edit; } /** * Sort the map. */ public function sort() { if (!$this->_sorted) { ksort($this->_ids, SORT_NUMERIC); $this->_sorted = true; } } /* Countable methods. */ /** */ public function count() { return count($this->_ids); } /* IteratorAggregate method. */ /** */ public function getIterator() { return new ArrayIterator($this->_ids); } /* Serializable methods. */ /** */ public function serialize() { /* Sort before storing; provides more compressible representation. */ $this->sort(); return json_encode(array( strval(new Horde_Imap_Client_Ids(array_keys($this->_ids))), strval(new Horde_Imap_Client_Ids(array_values($this->_ids))) )); } /** */ public function unserialize($data) { $data = json_decode($data, true); $keys = new Horde_Imap_Client_Ids($data[0]); $vals = new Horde_Imap_Client_Ids($data[1]); $this->_ids = array_combine($keys->ids, $vals->ids); /* Guaranteed to be sorted if unserializing. */ $this->_sorted = true; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Ids/Pop3.php0000664000175000017500000000347613150761653021310 0ustar janjan * @category Horde * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Ids_Pop3 extends Horde_Imap_Client_Ids { /** */ protected function _sort(&$ids) { /* There is no guarantee of POP3 UIDL order - IDs need to be unique, * but there is no requirement they need be incrementing. RFC * 1939[7] */ } /** * Create a POP3 message sequence string. * * Index Format: UID1[SPACE]UID2... * * @param boolean $sort Not used in this class. * * @return string The POP3 message sequence string. */ protected function _toSequenceString($sort = true) { /* $sort is ignored - see _sort(). */ /* Use space as delimiter as it is the only printable ASCII character * that is not allowed as part of the UID (RFC 1939 [7]). */ return implode(' ', count($this->_ids) > 25000 ? array_unique($this->_ids) : array_keys(array_flip($this->_ids))); } /** * Parse a POP3 message sequence string into a list of indices. * * @param string $str The POP3 message sequence string. * * @return array An array of UIDs. */ protected function _fromSequenceString($str) { return explode(' ', trim($str)); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Interaction/Command/Continuation.php0000664000175000017500000000414013150761653026244 0ustar janjan * @category Horde * @copyright 2013-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.10.0 */ class Horde_Imap_Client_Interaction_Command_Continuation { /** * Is this an optional continuation request? * * @since 2.13.0 * @var boolean */ public $optional = false; /** * Closure function to run after continuation response. * * @var Closure */ protected $_closure; /** * Constructor. * * @param Closure $closure A function to run after the continuation * response is received. It receives one * argument - a Continuation object - and should * return a list of arguments to send to the * server (via a * Horde_Imap_Client_Data_Format_List object). */ public function __construct($closure) { $this->_closure = $closure; } /** * Calls the closure object. * * @param Horde_Imap_Client_Interaction_Server_Continuation $ob Continuation * object. * * @return Horde_Imap_Client_Data_Format_List Further commands to issue * to the server. */ public function getCommands( Horde_Imap_Client_Interaction_Server_Continuation $ob ) { $closure = $this->_closure; return $closure($ob); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Interaction/Server/Continuation.php0000664000175000017500000000135013150761653026134 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Interaction_Server_Continuation extends Horde_Imap_Client_Interaction_Server { } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Interaction/Server/Tagged.php0000664000175000017500000000226013150761653024656 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Interaction_Server_Tagged extends Horde_Imap_Client_Interaction_Server { /** * Tag. * * @var string */ public $tag; /** * @param string $tag Response tag. */ public function __construct(Horde_Imap_Client_Tokenize $token, $tag) { $this->tag = $tag; parent::__construct($token); if (is_null($this->status)) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Bad tagged response.") ); } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Interaction/Server/Untagged.php0000664000175000017500000000134013150761653025217 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Interaction_Server_Untagged extends Horde_Imap_Client_Interaction_Server { } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Interaction/Client.php0000664000175000017500000000264513150761653023442 0ustar janjan * @category Horde * @copyright 2012-2016 Horde LLC * @deprecated * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Interaction_Client extends Horde_Imap_Client_Data_Format_List { /** * The command tag. * * @var string */ public $tag; /** * Constructor. * * @param string $tag The tag to use. If not set, will be automatically * generated. */ public function __construct($tag = null) { $this->tag = is_null($tag) ? substr(strval(new Horde_Support_Randomid()), 0, 10) : strval($tag); parent::__construct($this->tag); } /** * Get the command. * * @return string The command. */ public function getCommand() { return isset($this->_data[1]) ? $this->_data[1] : null; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Interaction/Command.php0000664000175000017500000000771113150761653023601 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.10.0 * * @property-read boolean $continuation True if the command requires a server * continuation response. */ class Horde_Imap_Client_Interaction_Command extends Horde_Imap_Client_Data_Format_List { /** * Debug string(s) to use instead of command text. * * Multiple entries refer to the various steps in a continuation command. * * @var array */ public $debug = array(); /** * Use LITERAL+ if available * * @var boolean */ public $literalplus = true; /** * Are literal8's available? * * @var boolean */ public $literal8 = false; /** * A callback to run on error. * * If callback returns true, the command will be treated as successful. * * @since 2.24.0 * * @var callback */ public $on_error = null; /** * A callback to run on success. * * @since 2.28.0 * * @var callback */ public $on_success = null; /** * Pipeline object associated with this command. * * @since 2.28.0 * * @var Horde_Imap_Client_Interaction_Pipeline */ public $pipeline; /** * Server response. * * @var Horde_Imap_Client_Interaction_Server */ public $response; /** * The command tag. * * @var string */ public $tag; /** * Command timer. * * @var Horde_Support_Timer */ protected $_timer; /** * Constructor. * * @param string $cmd The IMAP command. * @param string $tag The tag to use. If not set, will be automatically * generated. */ public function __construct($cmd, $tag = null) { $this->tag = is_null($tag) ? substr(new Horde_Support_Randomid(), 0, 10) : strval($tag); parent::__construct($this->tag); $this->add($cmd); } /** */ public function __get($name) { switch ($name) { case 'continuation': return $this->_continuationCheck($this); } } /** * Get the command. * * @return string The command. */ public function getCommand() { return $this->_data[1]; } /** * Start the command timer. */ public function startTimer() { $this->_timer = new Horde_Support_Timer(); $this->_timer->push(); } /** * Return the timer data. * * @return mixed Null if timer wasn't started, or a float containing * elapsed command time. */ public function getTimer() { return $this->_timer ? round($this->_timer->pop(), 4) : null; } /** * Recursive check for continuation functions. */ protected function _continuationCheck($list) { foreach ($list as $val) { if (($val instanceof Horde_Imap_Client_Interaction_Command_Continuation) || (($val instanceof Horde_Imap_Client_Data_Format_String) && $val->literal())) { return true; } if (($val instanceof Horde_Imap_Client_Data_Format_List) && $this->_continuationCheck($val)) { return true; } } return false; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Interaction/Pipeline.php0000664000175000017500000001025613150761653023766 0ustar janjan * @category Horde * @copyright 2013-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.10.0 * * @property-read boolean $finished True if all commands have finished. */ class Horde_Imap_Client_Interaction_Pipeline implements Countable, IteratorAggregate { /** * Data storage from server responses. * * @var array */ public $data = array( 'modseqs' => array(), 'modseqs_nouid' => array() ); /** * Fetch results. * * @var Horde_Imap_Client_Fetch_Results */ public $fetch; /** * The list of commands. * * @var array */ protected $_commands = array(); /** * The list of commands to complete. * * @var array */ protected $_todo = array(); /** * Constructor. * * @param Horde_Imap_Client_Fetch_Results $fetch Fetch results object. */ public function __construct(Horde_Imap_Client_Fetch_Results $fetch) { $this->fetch = $fetch; } /** */ public function __get($name) { switch ($name) { case 'finished': return empty($this->_todo); } } /** * Add a command to the pipeline. * * @param Horde_Imap_Client_Interaction_Command $cmd Command object. * @param boolean $top Add command to top * of queue? */ public function add(Horde_Imap_Client_Interaction_Command $cmd, $top = false) { if ($top) { // This won't re-index keys, which may be numerical. $this->_commands = array($cmd->tag => $cmd) + $this->_commands; } else { $this->_commands[$cmd->tag] = $cmd; } $this->_todo[$cmd->tag] = true; } /** * Mark a command as completed. * * @param Horde_Imap_Client_Interaction_Server_Tagged $resp Tagged server * response. * * @return Horde_Imap_Client_Interaction_Command Command that was * completed. Returns null * if tagged response * is not contained in this * pipeline object. */ public function complete(Horde_Imap_Client_Interaction_Server_Tagged $resp) { if (isset($this->_commands[$resp->tag])) { $cmd = $this->_commands[$resp->tag]; $cmd->response = $resp; unset($this->_todo[$resp->tag]); } else { /* This can be reached if a previous pipeline action was aborted, * e.g. via an Exception. */ $cmd = null; } return $cmd; } /** * Return the command for a given tag. * * @param string $tag The command tag. * * @return Horde_Imap_Client_Interaction_Command A command object (or * null if the tag does * not exist). */ public function getCmd($tag) { return isset($this->_commands[$tag]) ? $this->_commands[$tag] : null; } /* Countable methods. */ /** */ public function count() { return count($this->_commands); } /* IteratorAggregate methods. */ /** */ public function getIterator() { return new ArrayIterator($this->_commands); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Interaction/Server.php0000664000175000017500000000744213150761653023472 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Interaction_Server { /** * Response codes (RFC 3501 [7.1]). */ const BAD = 1; const BYE = 2; const NO = 3; const OK = 4; const PREAUTH = 5; /** * Check for status response? * * @var boolean */ protected $_checkStatus = true; /** * Response code (RFC 3501 [7.1]). Properties: * - code: (string) Response code. * - data: (array) Data associated with response. * * @var object */ public $responseCode = null; /** * Status response from the server. * * @var string */ public $status = null; /** * IMAP server data. * * @var Horde_Imap_Client_Tokenize */ public $token; /** * Auto-scan an incoming line to determine the response type. * * @param Horde_Imap_Client_Tokenize $t Tokenized data returned from the * server. * * @return Horde_Imap_Client_Interaction_Server A server response object. */ public static function create(Horde_Imap_Client_Tokenize $t) { $t->rewind(); $tag = $t->next(); $t->next(); switch ($tag) { case '+': return new Horde_Imap_Client_Interaction_Server_Continuation($t); case '*': return new Horde_Imap_Client_Interaction_Server_Untagged($t); default: return new Horde_Imap_Client_Interaction_Server_Tagged($t, $tag); } } /** * Constructor. * * @param Horde_Imap_Client_Tokenize $token Tokenized data returned from * the server. */ public function __construct(Horde_Imap_Client_Tokenize $token) { $this->token = $token; /* Check for response status. */ $status = $token->current(); $valid = array('BAD', 'BYE', 'NO', 'OK', 'PREAUTH'); if (in_array($status, $valid)) { $this->status = constant(__CLASS__ . '::' . $status); $resp_text = $token->next(); /* Check for response code. Only occurs if there is a response * status. */ if (is_string($resp_text) && ($resp_text[0] === '[')) { $resp = new stdClass; $resp->data = array(); if ($resp_text[strlen($resp_text) - 1] === ']') { $resp->code = substr($resp_text, 1, -1); } else { $resp->code = substr($resp_text, 1); while (($elt = $token->next()) !== false) { if (is_string($elt) && $elt[strlen($elt) - 1] === ']') { $resp->data[] = substr($elt, 0, -1); break; } $resp->data[] = is_string($elt) ? $elt : $token->flushIterator(); } } $token->next(); $this->responseCode = $resp; } } } /** */ public function __toString() { return strval($this->token); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Mailbox/List.php0000664000175000017500000001017513150761653022250 0ustar janjan * @category Horde * @copyright 2004-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Mailbox_List implements Countable, IteratorAggregate { /** * The delimiter character to use. * * @var string */ protected $_delimiter; /** * Mailbox list. * * @var array */ protected $_mboxes = array(); /** * Should we sort with INBOX at the front of the list? * * @var boolean */ protected $_sortinbox; /** * Constructor. * * @param mixed $mboxes A mailbox or list of mailboxes. */ public function __construct($mboxes) { $this->_mboxes = is_array($mboxes) ? $mboxes : array($mboxes); } /** * Sort the list of mailboxes. * * @param array $opts Options: * - delimiter: (string) The delimiter to use. * DEFAULT: '.' * - inbox: (boolean) Always put INBOX at the head of the list? * DEFAULT: Yes * - noupdate: (boolean) Do not update the object's mailbox list? * DEFAULT: true * * @return array List of sorted mailboxes (index association is kept). */ public function sort(array $opts = array()) { $this->_delimiter = isset($opts['delimiter']) ? $opts['delimiter'] : '.'; $this->_sortinbox = (!isset($opts['inbox']) || !empty($opts['inbox'])); if (empty($opts['noupdate'])) { $mboxes = &$this->_mboxes; } else { $mboxes = $this->_mboxes; } uasort($mboxes, array($this, '_mboxCompare')); return $mboxes; } /** * Hierarchical folder sorting function (used with usort()). * * @param string $a Comparison item 1. * @param string $b Comparison item 2. * * @return integer See usort(). */ final protected function _mboxCompare($a, $b) { /* Always return INBOX as "smaller". */ if ($this->_sortinbox) { if (strcasecmp($a, 'INBOX') === 0) { return -1; } elseif (strcasecmp($b, 'INBOX') === 0) { return 1; } } $a_parts = explode($this->_delimiter, $a); $b_parts = explode($this->_delimiter, $b); $a_count = count($a_parts); $b_count = count($b_parts); for ($i = 0, $iMax = min($a_count, $b_count); $i < $iMax; ++$i) { if ($a_parts[$i] != $b_parts[$i]) { /* If only one of the folders is under INBOX, return it as * "smaller". */ if ($this->_sortinbox && ($i === 0)) { $a_base = (strcasecmp($a_parts[0], 'INBOX') === 0); $b_base = (strcasecmp($b_parts[0], 'INBOX') === 0); if ($a_base && !$b_base) { return -1; } elseif (!$a_base && $b_base) { return 1; } } $cmp = strnatcasecmp($a_parts[$i], $b_parts[$i]); return ($cmp === 0) ? strcmp($a_parts[$i], $b_parts[$i]) : $cmp; } elseif ($a_parts[$i] !== $b_parts[$i]) { return strlen($a_parts[$i]) - strlen($b_parts[$i]); } } return ($a_count - $b_count); } /* Countable methods. */ /** */ public function count() { return count($this->_mboxes); } /* IteratorAggregate methods. */ /** */ public function getIterator() { return new ArrayIterator($this->_mboxes); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Namespace/List.php0000664000175000017500000000555713150761653022561 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.21.0 */ class Horde_Imap_Client_Namespace_List implements ArrayAccess, Countable, IteratorAggregate { /** * The list of namespace objects. * * @var array */ protected $_ns = array(); /** * Constructor. * * @param array $ns The list of namespace objects. */ public function __construct($ns = array()) { foreach ($ns as $val) { $this->_ns[strval($val)] = $val; } } /** * Get namespace info for a full mailbox path. * * @param string $mbox The mailbox path. * @param boolean $personal If true, will return the empty namespace only * if it is a personal namespace. * * @return mixed The Horde_Imap_Client_Data_Namespace object for the * mailbox path, or null if the path doesn't exist. */ public function getNamespace($mbox, $personal = false) { $mbox = strval($mbox); if ($ns = $this[$mbox]) { return $ns; } foreach ($this->_ns as $val) { $mbox = $mbox . $val->delimiter; if (strlen($val->name) && (strpos($mbox, $val->name) === 0)) { return $val; } } return (($ns = $this['']) && (!$personal || ($ns->type === $ns::NS_PERSONAL))) ? $ns : null; } /* ArrayAccess methods. */ /** */ public function offsetExists($offset) { return isset($this->_ns[strval($offset)]); } /** */ public function offsetGet($offset) { $offset = strval($offset); return isset($this->_ns[$offset]) ? $this->_ns[$offset] : null; } /** */ public function offsetSet($offset, $value) { if ($value instanceof Horde_Imap_Client_Data_Namespace) { $this->_ns[strval($value)] = $value; } } /** */ public function offsetUnset($offset) { unset($this->_ns[strval($offset)]); } /* Countable methods. */ /** */ public function count() { return count($this->_ns); } /* IteratorAggregate methods. */ /** */ public function getIterator() { return new ArrayIterator($this->_ns); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Password/Xoauth2.php0000664000175000017500000000332013150761653023070 0ustar janjan * @category Horde * @copyright 2013-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.16.0 */ class Horde_Imap_Client_Password_Xoauth2 implements Horde_Imap_Client_Base_Password { /** * Access token. * * @var string */ public $access_token; /** * Username. * * @var string */ public $username; /** * Constructor. * * @param string $username The username. * @param string $access_token The access token. */ public function __construct($username, $access_token) { $this->username = $username; $this->access_token = $access_token; } /** * Return the password to use for the server connection. * * @return string The password. */ public function getPassword() { // base64("user=" {User} "^Aauth=Bearer " {Access Token} "^A^A") // ^A represents a Control+A (\001) return base64_encode( 'user=' . $this->username . "\1" . 'auth=Bearer ' . $this->access_token . "\1\1" ); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Search/Query.php0000664000175000017500000007212513150761653022257 0ustar janjan * @category Horde * @copyright 2008-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Search_Query implements Serializable { /** * Serialized version. */ const VERSION = 3; /** * Constants for dateSearch() */ const DATE_BEFORE = 'BEFORE'; const DATE_ON = 'ON'; const DATE_SINCE = 'SINCE'; /** * Constants for intervalSearch() */ const INTERVAL_OLDER = 'OLDER'; const INTERVAL_YOUNGER = 'YOUNGER'; /** * The charset of the search strings. All text strings must be in * this charset. By default, this is 'US-ASCII' (see RFC 3501 [6.4.4]). * * @var string */ protected $_charset = null; /** * The list of search params. * * @var array */ protected $_search = array(); /** * String representation: The IMAP search string. */ public function __toString() { try { $res = $this->build(null); return $res['query']->escape(); } catch (Exception $e) { return ''; } } /** * Sets the charset of the search text. * * @param string $charset The charset to use for the search. * @param boolean $convert Convert existing text values? * * @throws Horde_Imap_Client_Exception_SearchCharset */ public function charset($charset, $convert = true) { $oldcharset = $this->_charset; $this->_charset = Horde_String::upper($charset); if (!$convert || ($oldcharset == $this->_charset)) { return; } foreach (array('and', 'or') as $item) { if (isset($this->_search[$item])) { foreach ($this->_search[$item] as &$val) { $val->charset($charset, $convert); } } } foreach (array('header', 'text') as $item) { if (isset($this->_search[$item])) { foreach ($this->_search[$item] as $key => $val) { $new_val = Horde_String::convertCharset($val['text'], $oldcharset, $this->_charset); if (Horde_String::convertCharset($new_val, $this->_charset, $oldcharset) != $val['text']) { throw new Horde_Imap_Client_Exception_SearchCharset($this->_charset); } $this->_search[$item][$key]['text'] = $new_val; } } } } /** * Builds an IMAP4rev1 compliant search string. * * @todo Change default of $exts to null. * * @param Horde_Imap_Client_Base $exts The server object this query will * be run on (@since 2.24.0), a * Horde_Imap_Client_Data_Capability * object (@since 2.24.0), or the * list of extensions present * on the server (@deprecated). * If null, all extensions are * assumed to be available. * * @return array An array with these elements: * - charset: (string) The charset of the search string. If null, no * text strings appear in query. * - exts: (array) The list of IMAP extensions used to create the * string. * - query: (Horde_Imap_Client_Data_Format_List) The IMAP search * command. * * @throws Horde_Imap_Client_Data_Format_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function build($exts = array()) { /* @todo: BC */ if (is_array($exts)) { $tmp = new Horde_Imap_Client_Data_Capability_Imap(); foreach ($exts as $key => $val) { $tmp->add($key, is_array($val) ? $val : null); } $exts = $tmp; } elseif (!is_null($exts)) { if ($exts instanceof Horde_Imap_Client_Base) { $exts = $exts->capability; } elseif (!($exts instanceof Horde_Imap_Client_Data_Capability)) { throw new InvalidArgumentException('Incorrect $exts parameter'); } } $temp = array( 'cmds' => new Horde_Imap_Client_Data_Format_List(), 'exts' => $exts, 'exts_used' => array() ); $cmds = &$temp['cmds']; $charset = $charset_cname = null; $default_search = true; $exts_used = &$temp['exts_used']; $ptr = &$this->_search; $charset_get = function ($c) use (&$charset, &$charset_cname) { $charset = is_null($c) ? 'US-ASCII' : strval($c); $charset_cname = ($charset === 'US-ASCII') ? 'Horde_Imap_Client_Data_Format_Astring' : 'Horde_Imap_Client_Data_Format_Astring_Nonascii'; }; $create_return = function ($charset, $exts_used, $cmds) { return array( 'charset' => $charset, 'exts' => array_keys(array_flip($exts_used)), 'query' => $cmds ); }; /* Do IDs check first. If there is an empty ID query (without a NOT * qualifier), the rest of this query is irrelevant since we already * know the search will return no results. */ if (isset($ptr['ids'])) { if (!count($ptr['ids']['ids']) && !$ptr['ids']['ids']->special) { if (empty($ptr['ids']['not'])) { /* This is a match on an empty list of IDs. We do need to * process any OR queries that may exist, since they are * independent of this result. */ if (isset($ptr['or'])) { $this->_buildAndOr( 'OR', $ptr['or'], $charset, $exts_used, $cmds ); } return $create_return($charset, $exts_used, $cmds); } /* If reached here, this a NOT search of an empty list. We can * safely discard this from the output. */ } else { $this->_addFuzzy(!empty($ptr['ids']['fuzzy']), $temp); if (!empty($ptr['ids']['not'])) { $cmds->add('NOT'); } if (!$ptr['ids']['ids']->sequence) { $cmds->add('UID'); } $cmds->add(strval($ptr['ids']['ids'])); } } if (isset($ptr['new'])) { $this->_addFuzzy(!empty($ptr['newfuzzy']), $temp); if ($ptr['new']) { $cmds->add('NEW'); unset($ptr['flag']['UNSEEN']); } else { $cmds->add('OLD'); } unset($ptr['flag']['RECENT']); } if (!empty($ptr['flag'])) { foreach ($ptr['flag'] as $key => $val) { $this->_addFuzzy(!empty($val['fuzzy']), $temp); $tmp = ''; if (empty($val['set'])) { // This is a 'NOT' search. All system flags but \Recent // have 'UN' equivalents. if ($key == 'RECENT') { $cmds->add('NOT'); } else { $tmp = 'UN'; } } if ($val['type'] == 'keyword') { $cmds->add(array( $tmp . 'KEYWORD', $key )); } else { $cmds->add($tmp . $key); } } } if (!empty($ptr['header'])) { /* The list of 'system' headers that have a specific search * query. */ $systemheaders = array( 'BCC', 'CC', 'FROM', 'SUBJECT', 'TO' ); foreach ($ptr['header'] as $val) { $this->_addFuzzy(!empty($val['fuzzy']), $temp); if (!empty($val['not'])) { $cmds->add('NOT'); } if (in_array($val['header'], $systemheaders)) { $cmds->add($val['header']); } else { $cmds->add(array( 'HEADER', new Horde_Imap_Client_Data_Format_Astring($val['header']) )); } $charset_get($this->_charset); $cmds->add( new $charset_cname(isset($val['text']) ? $val['text'] : '') ); } } if (!empty($ptr['text'])) { foreach ($ptr['text'] as $val) { $this->_addFuzzy(!empty($val['fuzzy']), $temp); if (!empty($val['not'])) { $cmds->add('NOT'); } $charset_get($this->_charset); $cmds->add(array( $val['type'], new $charset_cname($val['text']) )); } } if (!empty($ptr['size'])) { foreach ($ptr['size'] as $key => $val) { $this->_addFuzzy(!empty($val['fuzzy']), $temp); if (!empty($val['not'])) { $cmds->add('NOT'); } $cmds->add(array( $key, new Horde_Imap_Client_Data_Format_Number( empty($val['size']) ? 0 : $val['size'] ) )); } } if (!empty($ptr['date'])) { foreach ($ptr['date'] as $val) { $this->_addFuzzy(!empty($val['fuzzy']), $temp); if (!empty($val['not'])) { $cmds->add('NOT'); } if (empty($val['header'])) { $cmds->add($val['range']); } else { $cmds->add('SENT' . $val['range']); } $cmds->add($val['date']); } } if (!empty($ptr['within'])) { if (is_null($exts) || $exts->query('WITHIN')) { $exts_used[] = 'WITHIN'; } foreach ($ptr['within'] as $key => $val) { $this->_addFuzzy(!empty($val['fuzzy']), $temp); if (!empty($val['not'])) { $cmds->add('NOT'); } if (is_null($exts) || $exts->query('WITHIN')) { $cmds->add(array( $key, new Horde_Imap_Client_Data_Format_Number($val['interval']) )); } else { // This workaround is only accurate to within 1 day, due // to limitations with the IMAP4rev1 search commands. $cmds->add(array( ($key == self::INTERVAL_OLDER) ? self::DATE_BEFORE : self::DATE_SINCE, new Horde_Imap_Client_Data_Format_Date('now -' . $val['interval'] . ' seconds') )); } } } if (!empty($ptr['modseq'])) { if (!is_null($exts) && !$exts->query('CONDSTORE')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('CONDSTORE'); } $exts_used[] = 'CONDSTORE'; $this->_addFuzzy(!empty($ptr['modseq']['fuzzy']), $temp); if (!empty($ptr['modseq']['not'])) { $cmds->add('NOT'); } $cmds->add('MODSEQ'); if (isset($ptr['modseq']['name'])) { $cmds->add(array( new Horde_Imap_Client_Data_Format_String($ptr['modseq']['name']), $ptr['modseq']['type'] )); } $cmds->add(new Horde_Imap_Client_Data_Format_Number($ptr['modseq']['value'])); } if (isset($ptr['prevsearch'])) { if (!is_null($exts) && !$exts->query('SEARCHRES')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('SEARCHRES'); } $exts_used[] = 'SEARCHRES'; $this->_addFuzzy(!empty($ptr['prevsearchfuzzy']), $temp); if (!$ptr['prevsearch']) { $cmds->add('NOT'); } $cmds->add('$'); } // Add AND'ed queries if (!empty($ptr['and'])) { $default_search = $this->_buildAndOr( 'AND', $ptr['and'], $charset, $exts_used, $cmds ); } // Add OR'ed queries if (!empty($ptr['or'])) { $default_search = $this->_buildAndOr( 'OR', $ptr['or'], $charset, $exts_used, $cmds ); } // Default search is 'ALL' if ($default_search && !count($cmds)) { $cmds->add('ALL'); } return $create_return($charset, $exts_used, $cmds); } /** * Builds the AND/OR query. * * @param string $type 'AND' or 'OR'. * @param array $data Query data. * @param string &$charset Search charset. * @param array &$exts_used IMAP extensions used. * @param Horde_Imap_Client_Data_Format_List &$cmds Command list. * * @return boolean True if query might return results. */ protected function _buildAndOr($type, $data, &$charset, &$exts_used, &$cmds) { $results = false; foreach ($data as $val) { $ret = $val->build(); /* Empty sub-query. */ if (!count($ret['query'])) { switch ($type) { case 'AND': /* Any empty sub-query means that the query MUST return * no results. */ $cmds = new Horde_Imap_Client_Data_Format_List(); $exts_used = array(); return false; case 'OR': /* Skip this query. */ continue 2; } } $results = true; if (!is_null($ret['charset']) && ($ret['charset'] != 'US-ASCII')) { if (!is_null($charset) && ($charset != 'US-ASCII') && ($charset != $ret['charset'])) { throw new InvalidArgumentException( 'AND/OR queries must all have the same charset.' ); } $charset = $ret['charset']; } $exts_used = array_merge($exts_used, $ret['exts']); switch ($type) { case 'AND': $cmds->add($ret['query'], true); break; case 'OR': // First OR'd query if (count($cmds)) { $new_cmds = new Horde_Imap_Client_Data_Format_List(); $new_cmds->add(array( 'OR', $ret['query'], $cmds )); $cmds = $new_cmds; } else { $cmds = $ret['query']; } break; } } return $results; } /** * Adds fuzzy modifier to search keys. * * @param boolean $add Add the fuzzy modifier? * @param array $temp Temporary build data. * * @throws Horde_Imap_Client_Exception_NoSupport_Extension */ protected function _addFuzzy($add, &$temp) { if ($add) { if (!$temp['exts']->query('SEARCH', 'FUZZY')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('SEARCH=FUZZY'); } $temp['cmds']->add('FUZZY'); $temp['exts_used'][] = 'SEARCH=FUZZY'; } } /** * Search for a flag/keywords. * * @param string $name The flag or keyword name. * @param boolean $set If true, search for messages that have the flag * set. If false, search for messages that do not * have the flag set. * @param array $opts Additional options: * - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server * MUST support RFC 6203. */ public function flag($name, $set = true, array $opts = array()) { $name = Horde_String::upper(ltrim($name, '\\')); if (!isset($this->_search['flag'])) { $this->_search['flag'] = array(); } /* The list of defined system flags (see RFC 3501 [2.3.2]). */ $systemflags = array( 'ANSWERED', 'DELETED', 'DRAFT', 'FLAGGED', 'RECENT', 'SEEN' ); $this->_search['flag'][$name] = array_filter(array( 'fuzzy' => !empty($opts['fuzzy']), 'set' => $set, 'type' => in_array($name, $systemflags) ? 'flag' : 'keyword' )); } /** * Determines if flags are a part of the search. * * @return boolean True if search query involves flags. */ public function flagSearch() { return !empty($this->_search['flag']); } /** * Search for either new messages (messages that have the '\Recent' flag * but not the '\Seen' flag) or old messages (messages that do not have * the '\Recent' flag). If new messages are searched, this will clear * any '\Recent' or '\Unseen' flag searches. If old messages are searched, * this will clear any '\Recent' flag search. * * @param boolean $newmsgs If true, searches for new messages. Else, * search for old messages. * @param array $opts Additional options: * - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server * MUST support RFC 6203. */ public function newMsgs($newmsgs = true, array $opts = array()) { $this->_search['new'] = $newmsgs; if (!empty($opts['fuzzy'])) { $this->_search['newfuzzy'] = true; } } /** * Search for text in the header of a message. * * @param string $header The header field. * @param string $text The search text. * @param boolean $not If true, do a 'NOT' search of $text. * @param array $opts Additional options: * - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server * MUST support RFC 6203. */ public function headerText($header, $text, $not = false, array $opts = array()) { if (!isset($this->_search['header'])) { $this->_search['header'] = array(); } $this->_search['header'][] = array_filter(array( 'fuzzy' => !empty($opts['fuzzy']), 'header' => Horde_String::upper($header), 'text' => $text, 'not' => $not )); } /** * Search for text in either the entire message, or just the body. * * @param string $text The search text. * @param string $bodyonly If true, only search in the body of the * message. If false, also search in the headers. * @param boolean $not If true, do a 'NOT' search of $text. * @param array $opts Additional options: * - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server * MUST support RFC 6203. */ public function text($text, $bodyonly = true, $not = false, array $opts = array()) { if (!isset($this->_search['text'])) { $this->_search['text'] = array(); } $this->_search['text'][] = array_filter(array( 'fuzzy' => !empty($opts['fuzzy']), 'not' => $not, 'text' => $text, 'type' => $bodyonly ? 'BODY' : 'TEXT' )); } /** * Search for messages smaller/larger than a certain size. * * @todo: Remove $not for 3.0 * * @param integer $size The size (in bytes). * @param boolean $larger Search for messages larger than $size? * @param boolean $not If true, do a 'NOT' search of $text. * @param array $opts Additional options: * - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server * MUST support RFC 6203. */ public function size($size, $larger = false, $not = false, array $opts = array()) { if (!isset($this->_search['size'])) { $this->_search['size'] = array(); } $this->_search['size'][$larger ? 'LARGER' : 'SMALLER'] = array_filter(array( 'fuzzy' => !empty($opts['fuzzy']), 'not' => $not, 'size' => (float)$size )); } /** * Search for messages within a given UID range. Only one message range * can be specified per query. * * @param Horde_Imap_Client_Ids $ids The list of UIDs to search. * @param boolean $not If true, do a 'NOT' search of the * UIDs. * @param array $opts Additional options: * - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server * MUST support RFC 6203. */ public function ids(Horde_Imap_Client_Ids $ids, $not = false, array $opts = array()) { $this->_search['ids'] = array_filter(array( 'fuzzy' => !empty($opts['fuzzy']), 'ids' => $ids, 'not' => $not )); } /** * Search for messages within a date range. * * @param mixed $date DateTime or Horde_Date object. * @param string $range Either: * - Horde_Imap_Client_Search_Query::DATE_BEFORE * - Horde_Imap_Client_Search_Query::DATE_ON * - Horde_Imap_Client_Search_Query::DATE_SINCE * @param boolean $header If true, search using the date in the message * headers. If false, search using the internal * IMAP date (usually arrival time). * @param boolean $not If true, do a 'NOT' search of the range. * @param array $opts Additional options: * - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server * MUST support RFC 6203. */ public function dateSearch($date, $range, $header = true, $not = false, array $opts = array()) { if (!isset($this->_search['date'])) { $this->_search['date'] = array(); } // We should really be storing the raw DateTime object as data, // but all versions of the query object have converted at this stage. $ob = new Horde_Imap_Client_Data_Format_Date($date); $this->_search['date'][] = array_filter(array( 'date' => $ob->escape(), 'fuzzy' => !empty($opts['fuzzy']), 'header' => $header, 'range' => $range, 'not' => $not )); } /** * Search for messages within a given interval. Only one interval of each * type can be specified per search query. If the IMAP server supports * the WITHIN extension (RFC 5032), it will be used. Otherwise, the * search query will be dynamically created using IMAP4rev1 search * terms. * * @param integer $interval Seconds from the present. * @param string $range Either: * - Horde_Imap_Client_Search_Query::INTERVAL_OLDER * - Horde_Imap_Client_Search_Query::INTERVAL_YOUNGER * @param boolean $not If true, do a 'NOT' search. * @param array $opts Additional options: * - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server * MUST support RFC 6203. */ public function intervalSearch($interval, $range, $not = false, array $opts = array()) { if (!isset($this->_search['within'])) { $this->_search['within'] = array(); } $this->_search['within'][$range] = array( 'fuzzy' => !empty($opts['fuzzy']), 'interval' => $interval, 'not' => $not ); } /** * AND queries - the contents of this query will be AND'ed (in its * entirety) with the contents of EACH of the queries passed in. All * AND'd queries must share the same charset as this query. * * @param mixed $queries A query, or an array of queries, to AND with the * current query. */ public function andSearch($queries) { if (!isset($this->_search['and'])) { $this->_search['and'] = array(); } if ($queries instanceof Horde_Imap_Client_Search_Query) { $queries = array($queries); } $this->_search['and'] = array_merge($this->_search['and'], $queries); } /** * OR a query - the contents of this query will be OR'ed (in its entirety) * with the contents of EACH of the queries passed in. All OR'd queries * must share the same charset as this query. All contents of any single * query will be AND'ed together. * * @param mixed $queries A query, or an array of queries, to OR with the * current query. */ public function orSearch($queries) { if (!isset($this->_search['or'])) { $this->_search['or'] = array(); } if ($queries instanceof Horde_Imap_Client_Search_Query) { $queries = array($queries); } $this->_search['or'] = array_merge($this->_search['or'], $queries); } /** * Search for messages modified since a specific moment. The IMAP server * must support the CONDSTORE extension (RFC 7162) for this query to be * used. * * @param integer $value The mod-sequence value. * @param string $name The entry-name string. * @param string $type Either 'shared', 'priv', or 'all'. Defaults to * 'all' * @param boolean $not If true, do a 'NOT' search. * @param array $opts Additional options: * - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server * MUST support RFC 6203. */ public function modseq($value, $name = null, $type = null, $not = false, array $opts = array()) { if (!is_null($type)) { $type = Horde_String::lower($type); if (!in_array($type, array('shared', 'priv', 'all'))) { $type = 'all'; } } $this->_search['modseq'] = array_filter(array( 'fuzzy' => !empty($opts['fuzzy']), 'name' => $name, 'not' => $not, 'type' => (!is_null($name) && is_null($type)) ? 'all' : $type, 'value' => $value )); } /** * Use the results from the previous SEARCH command. The IMAP server must * support the SEARCHRES extension (RFC 5182) for this query to be used. * * @param boolean $not If true, don't match the previous query. * @param array $opts Additional options: * - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server * MUST support RFC 6203. */ public function previousSearch($not = false, array $opts = array()) { $this->_search['prevsearch'] = $not; if (!empty($opts['fuzzy'])) { $this->_search['prevsearchfuzzy'] = true; } } /* Serializable methods. */ /** * Serialization. * * @return string Serialized data. */ public function serialize() { $data = array( // Serialized data ID. self::VERSION, $this->_search ); if (!is_null($this->_charset)) { $data[] = $this->_charset; } return serialize($data); } /** * Unserialization. * * @param string $data Serialized data. * * @throws Exception */ public function unserialize($data) { $data = @unserialize($data); if (!is_array($data) || !isset($data[0]) || ($data[0] != self::VERSION)) { throw new Exception('Cache version change'); } $this->_search = $data[1]; if (isset($data[2])) { $this->_charset = $data[2]; } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Socket/Connection/Base.php0000664000175000017500000000415313150761653024142 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @internal * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Socket_Connection_Base extends Horde\Socket\Client { /** * Protocol type. * * @var string */ protected $_protocol = 'imap'; /** */ protected function _connect($host, $port, $timeout, $secure, $context, $retries = 0) { if ($retries || !$this->_params['debug']->debug) { $timer = null; } else { $url = ($this->_protocol == 'imap') ? new Horde_Imap_Client_Url_Imap() : new Horde_Imap_Client_Url_Pop3(); $url->host = $host; $url->port = $port; $this->_params['debug']->info(sprintf( 'Connection to: %s', strval($url) )); $timer = new Horde_Support_Timer(); $timer->push(); } try { parent::_connect($host, $port, $timeout, $secure, $context, $retries); } catch (Horde\Socket\Client\Exception $e) { $this->_params['debug']->info(sprintf( 'Connection failed: %s', $e->getMessage() )); throw $e; } if ($timer) { $this->_params['debug']->info(sprintf( 'Server connection took %s seconds.', round($timer->pop(), 4) )); } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Socket/Connection/Pop3.php0000664000175000017500000000531113150761653024106 0ustar janjan * @category Horde * @copyright 2013-2017 Horde LLC * @internal * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Socket_Connection_Pop3 extends Horde_Imap_Client_Socket_Connection_Base { /** */ protected $_protocol = 'pop3'; /** * Writes data to the POP3 output stream. * * @param string $data String data. * @param boolean $debug Output line to debug? * * @throws Horde_Imap_Client_Exception */ public function write($data, $debug = true) { if (fwrite($this->_stream, $data . "\r\n") === false) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Server write error."), Horde_Imap_Client_Exception::SERVER_WRITEERROR ); } if ($debug) { $this->_params['debug']->client($data); } } /** * Read data from incoming POP3 stream. * * @param integer $size UNUSED: The number of bytes to read from the * socket. * * @return string Line of data. * * @throws Horde_Imap_Client_Exception */ public function read($size = null) { if (feof($this->_stream)) { $this->close(); $this->_params['debug']->info( 'ERROR: Server closed the connection.' ); throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Server closed the connection unexpectedly."), Horde_Imap_Client_Exception::DISCONNECT ); } if (($read = fgets($this->_stream)) === false) { $this->_params['debug']->info('ERROR: read/timeout error.'); throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error when communicating with the mail server."), Horde_Imap_Client_Exception::SERVER_READERROR ); } $this->_params['debug']->server(rtrim($read, "\r\n")); return $read; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Socket/Connection/Socket.php0000664000175000017500000001521013150761653024514 0ustar janjan * @category Horde * @copyright 2013-2017 Horde LLC * @internal * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Socket_Connection_Socket extends Horde_Imap_Client_Socket_Connection_Base { /** * If false, does not outpt the current line of client output to debug. * * @var boolean */ public $client_debug = true; /** * Sending buffer. * * @var string */ protected $_buffer = ''; /** * Writes data to the IMAP output stream. * * @param string $data String data. * @param boolean $eol Append EOL? * * @throws Horde_Imap_Client_Exception */ public function write($data, $eol = false) { if ($eol) { $buffer = $this->_buffer; $debug = $this->client_debug; $this->_buffer = ''; $this->client_debug = true; if (fwrite($this->_stream, $buffer . $data . ($eol ? "\r\n" : '')) === false) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Server write error."), Horde_Imap_Client_Exception::SERVER_WRITEERROR ); } if ($debug) { $this->_params['debug']->client($buffer . $data); } } else { $this->_buffer .= $data; } } /** * Writes literal data to the IMAP output stream. * * @param mixed $data Either a stream resource, or Horde_Stream * object. * @param integer $length The literal length. * @param boolean $binary If true, this is binary data. * * @throws Horde_Imap_Client_Exception */ public function writeLiteral($data, $length, $binary = false) { $this->_buffer = ''; $success = false; if ($data instanceof Horde_Stream) { $data = $data->stream; } if (rewind($data)) { $success = true; while (!feof($data)) { if ((($read_data = fread($data, 8192)) === false) || (fwrite($this->_stream, $read_data) === false)) { $success = false; break; } } } if (!$success) { $this->client_debug = true; throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Server write error."), Horde_Imap_Client_Exception::SERVER_WRITEERROR ); } if ($this->client_debug && !empty($this->_params['debugliteral'])) { rewind($data); while (!feof($data)) { $this->_params['debug']->raw(fread($data, 8192)); } } else { $this->_params['debug']->client('[' . ($binary ? 'BINARY' : 'LITERAL') . ' DATA: ' . $length . ' bytes]'); } } /** * Read data from incoming IMAP stream. * * @param integer $size UNUSED: The number of bytes to read from the * socket. * * @return Horde_Imap_Client_Tokenize The tokenized data. * * @throws Horde_Imap_Client_Exception */ public function read($size = null) { $got_data = false; $literal_len = null; $token = new Horde_Imap_Client_Tokenize(); do { if (feof($this->_stream)) { $this->close(); $this->_params['debug']->info( 'ERROR: Server closed the connection.' ); throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Mail server closed the connection unexpectedly."), Horde_Imap_Client_Exception::DISCONNECT ); } if (is_null($literal_len)) { $buffer = ''; while (($in = fgets($this->_stream)) !== false) { $got_data = true; if (substr($in, -1) === "\n") { $in = rtrim($in); $this->_params['debug']->server($buffer . $in); $token->add($in); break; } $buffer .= $in; $token->add($in); } /* Check for literal data. */ if (is_null($len = $token->getLiteralLength())) { break; } // Skip 0-length literal data. if ($len['length']) { $binary = $len['binary']; $literal_len = $len['length']; } continue; } $old_len = $literal_len; while (($literal_len > 0) && !feof($this->_stream)) { $in = fread($this->_stream, min($literal_len, 8192)); /* Only store in stream if this is something more than a * nominal number of bytes. */ if ($old_len > 256) { $token->addLiteralStream($in); } else { $token->add($in); } if (!empty($this->_params['debugliteral'])) { $this->_params['debug']->raw($in); } $got_data = true; $literal_len -= strlen($in); } $literal_len = null; if (empty($this->_params['debugliteral'])) { $this->_params['debug']->server('[' . ($binary ? 'BINARY' : 'LITERAL') . ' DATA: ' . $old_len . ' bytes]'); } } while (true); if (!$got_data) { $this->_params['debug']->info('ERROR: read/timeout error.'); throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error when communicating with the mail server."), Horde_Imap_Client_Exception::SERVER_READERROR ); } return $token; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Socket/Catenate.php0000664000175000017500000001176313150761653022722 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @internal * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Socket_Catenate { /** * Socket object. * * @var Horde_Imap_Client_Socket */ protected $_socket; /** * Constructor. * * @param Horde_Imap_Client_Socket $socket Socket object. */ public function __construct(Horde_Imap_Client_Socket $socket) { $this->_socket = $socket; } /** * Given an IMAP URL, fetches the corresponding part. * * @param Horde_Imap_Client_Url_Imap $url An IMAP URL. * * @return resource The section contents in a stream. Returns null if * the part could not be found. * * @throws Horde_Imap_Client_Exception */ public function fetchFromUrl(Horde_Imap_Client_Url_Imap $url) { $ids_ob = $this->_socket->getIdsOb($url->uid); // BODY[] if (is_null($url->section)) { $query = new Horde_Imap_Client_Fetch_Query(); $query->fullText(array( 'peek' => true )); $fetch = $this->_socket->fetch($url->mailbox, $query, array( 'ids' => $ids_ob )); return $fetch[$url->uid]->getFullMsg(true); } $section = trim($url->section); // BODY[<#.>HEADER.FIELDS<.NOT>()] if (($pos = stripos($section, 'HEADER.FIELDS')) !== false) { $hdr_pos = strpos($section, '('); $cmd = substr($section, 0, $hdr_pos); $query = new Horde_Imap_Client_Fetch_Query(); $query->headers( 'section', explode(' ', substr($section, $hdr_pos + 1, strrpos($section, ')') - $hdr_pos)), array( 'id' => ($pos ? substr($section, 0, $pos - 1) : 0), 'notsearch' => (stripos($cmd, '.NOT') !== false), 'peek' => true ) ); $fetch = $this->_socket->fetch($url->mailbox, $query, array( 'ids' => $ids_ob )); return $fetch[$url->uid]->getHeaders('section', Horde_Imap_Client_Data_Fetch::HEADER_STREAM); } // BODY[#] if (is_numeric(substr($section, -1))) { $query = new Horde_Imap_Client_Fetch_Query(); $query->bodyPart($section, array( 'peek' => true )); $fetch = $this->_socket->fetch($url->mailbox, $query, array( 'ids' => $ids_ob )); return $fetch[$url->uid]->getBodyPart($section, true); } // BODY[<#.>HEADER] if (($pos = stripos($section, 'HEADER')) !== false) { $id = $pos ? substr($section, 0, $pos - 1) : 0; $query = new Horde_Imap_Client_Fetch_Query(); $query->headerText(array( 'id' => $id, 'peek' => true )); $fetch = $this->_socket->fetch($url->mailbox, $query, array( 'ids' => $ids_ob )); return $fetch[$url->uid]->getHeaderText($id, Horde_Imap_Client_Data_Fetch::HEADER_STREAM); } // BODY[<#.>TEXT] if (($pos = stripos($section, 'TEXT')) !== false) { $id = $pos ? substr($section, 0, $pos - 1) : 0; $query = new Horde_Imap_Client_Fetch_Query(); $query->bodyText(array( 'id' => $id, 'peek' => true )); $fetch = $this->_socket->fetch($url->mailbox, $query, array( 'ids' => $ids_ob )); return $fetch[$url->uid]->getBodyText($id, true); } // BODY[<#.>MIMEHEADER] if (($pos = stripos($section, 'MIME')) !== false) { $id = $pos ? substr($section, 0, $pos - 1) : 0; $query = new Horde_Imap_Client_Fetch_Query(); $query->mimeHeader($id, array( 'peek' => true )); $fetch = $this->_socket->fetch($url->mailbox, $query, array( 'ids' => $ids_ob )); return $fetch[$url->uid]->getMimeHeader($id, Horde_Imap_Client_Data_Fetch::HEADER_STREAM); } return null; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Socket/ClientSort.php0000664000175000017500000002767613150761653023276 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @internal * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Socket_ClientSort { /** * Collator object to use for sotring. * * @var Collator */ protected $_collator; /** * Socket object. * * @var Horde_Imap_Client_Socket */ protected $_socket; /** * Constructor. * * @param Horde_Imap_Client_Socket $socket Socket object. */ public function __construct(Horde_Imap_Client_Socket $socket) { $this->_socket = $socket; if (class_exists('Collator')) { $this->_collator = new Collator(null); } } /** * Sort search results client side if the server does not support the SORT * IMAP extension (RFC 5256). * * @param Horde_Imap_Client_Ids $res The search results. * @param array $opts The options to _search(). * * @return array The sort results. * * @throws Horde_Imap_Client_Exception */ public function clientSort($res, $opts) { if (!count($res)) { return $res; } /* Generate the FETCH command needed. */ $query = new Horde_Imap_Client_Fetch_Query(); foreach ($opts['sort'] as $val) { switch ($val) { case Horde_Imap_Client::SORT_ARRIVAL: $query->imapDate(); break; case Horde_Imap_Client::SORT_DATE: $query->imapDate(); $query->envelope(); break; case Horde_Imap_Client::SORT_CC: case Horde_Imap_Client::SORT_DISPLAYFROM: case Horde_Imap_Client::SORT_DISPLAYTO: case Horde_Imap_Client::SORT_FROM: case Horde_Imap_Client::SORT_SUBJECT: case Horde_Imap_Client::SORT_TO: $query->envelope(); break; case Horde_Imap_Client::SORT_SEQUENCE: $query->seq(); break; case Horde_Imap_Client::SORT_SIZE: $query->size(); break; } } if (!count($query)) { return $res; } $mbox = $this->_socket->currentMailbox(); $fetch_res = $this->_socket->fetch($mbox['mailbox'], $query, array( 'ids' => $res )); return $this->_clientSortProcess($res->ids, $fetch_res, $opts['sort']); } /** * If server does not support the THREAD IMAP extension (RFC 5256), do * ORDEREDSUBJECT threading on the client side. * * @param Horde_Imap_Client_Fetch_Results $data Fetch results. * @param boolean $uids Are IDs UIDs? * * @return array The thread sort results. */ public function threadOrderedSubject(Horde_Imap_Client_Fetch_Results $data, $uids) { $dates = $this->_getSentDates($data, $data->ids()); $out = $sorted = $tsort = array(); foreach ($data as $k => $v) { $subject = strval(new Horde_Imap_Client_Data_BaseSubject($v->getEnvelope()->subject)); $sorted[$subject][$k] = $dates[$k]; } /* Step 1: Sort by base subject (already done). * Step 2: Sort by sent date within each thread. */ foreach (array_keys($sorted) as $key) { $this->_stableAsort($sorted[$key]); $tsort[$key] = reset($sorted[$key]); } /* Step 3: Sort by the sent date of the first message in the * thread. */ $this->_stableAsort($tsort); /* Now, $tsort contains the order of the threads, and each thread * is sorted in $sorted. */ foreach (array_keys($tsort) as $key) { $keys = array_keys($sorted[$key]); $out[$keys[0]] = array( $keys[0] => 0 ) + array_fill_keys(array_slice($keys, 1) , 1); } return new Horde_Imap_Client_Data_Thread( $out, $uids ? 'uid' : 'sequence' ); } /** */ protected function _clientSortProcess($res, $fetch_res, $sort) { /* The initial sort is on the entire set. */ $slices = array(0 => $res); $reverse = false; foreach ($sort as $val) { if ($val == Horde_Imap_Client::SORT_REVERSE) { $reverse = true; continue; } $slices_list = $slices; $slices = array(); foreach ($slices_list as $slice_start => $slice) { $sorted = array(); switch ($val) { case Horde_Imap_Client::SORT_SEQUENCE: /* There is no requirement that IDs be returned in * sequence order (see RFC 4549 [4.3.1]). So we must sort * ourselves. */ $sorted = array_flip($slice); ksort($sorted, SORT_NUMERIC); break; case Horde_Imap_Client::SORT_SIZE: foreach ($slice as $num) { $sorted[$num] = $fetch_res[$num]->getSize(); } asort($sorted, SORT_NUMERIC); break; case Horde_Imap_Client::SORT_DISPLAYFROM: case Horde_Imap_Client::SORT_DISPLAYTO: $field = ($val == Horde_Imap_Client::SORT_DISPLAYFROM) ? 'from' : 'to'; foreach ($slice as $num) { $ob = $fetch_res[$num]->getEnvelope()->$field; $sorted[$num] = ($addr_ob = $ob[0]) ? $addr_ob->personal ?: $addr_ob->mailbox : null; } $this->_sortString($sorted); break; case Horde_Imap_Client::SORT_CC: case Horde_Imap_Client::SORT_FROM: case Horde_Imap_Client::SORT_TO: if ($val == Horde_Imap_Client::SORT_CC) { $field = 'cc'; } elseif ($val == Horde_Imap_Client::SORT_FROM) { $field = 'from'; } else { $field = 'to'; } foreach ($slice as $num) { $tmp = $fetch_res[$num]->getEnvelope()->$field; $sorted[$num] = count($tmp) ? $tmp[0]->mailbox : null; } $this->_sortString($sorted); break; case Horde_Imap_Client::SORT_ARRIVAL: $sorted = $this->_getSentDates($fetch_res, $slice, true); asort($sorted, SORT_NUMERIC); break; case Horde_Imap_Client::SORT_DATE: // Date sorting rules in RFC 5256 [2.2] $sorted = $this->_getSentDates($fetch_res, $slice); asort($sorted, SORT_NUMERIC); break; case Horde_Imap_Client::SORT_SUBJECT: // Subject sorting rules in RFC 5256 [2.1] foreach ($slice as $num) { $sorted[$num] = strval(new Horde_Imap_Client_Data_BaseSubject($fetch_res[$num]->getEnvelope()->subject)); } $this->_sortString($sorted); break; } // At this point, keys of $sorted are sequence/UID and values // are the sort strings if (!empty($sorted)) { if ($reverse) { $sorted = array_reverse($sorted, true); } if (count($sorted) === count($res)) { $res = array_keys($sorted); } else { array_splice($res, $slice_start, count($slice), array_keys($sorted)); } // Check for ties. $last = $start = null; $i = 0; $todo = array(); foreach ($sorted as $k => $v) { if (is_null($last) || ($last != $v)) { if ($i) { $todo[] = array($start, $i); $i = 0; } $last = $v; $start = $k; } else { ++$i; } } if ($i) { $todo[] = array($start, $i); } foreach ($todo as $v) { $slices[array_search($v[0], $res)] = array_keys( array_slice( $sorted, array_search($v[0], $sorted), $v[1] + 1, true ) ); } } } $reverse = false; } return $res; } /** * Get the sent dates for purposes of SORT/THREAD sorting under RFC 5256 * [2.2]. * * @param Horde_Imap_Client_Fetch_Results $data Data returned from * fetch() that includes * both date and envelope * items. * @param array $ids The IDs to process. * @param boolean $internal Only use internal date? * * @return array A mapping of IDs -> UNIX timestamps. */ protected function _getSentDates(Horde_Imap_Client_Fetch_Results $data, $ids, $internal = false) { $dates = array(); foreach ($ids as $num) { $dt = ($internal || !isset($data[$num]->getEnvelope()->date)) // RFC 5256 [3] & 3501 [6.4.4]: disregard timezone when // using internaldate. ? $data[$num]->getImapDate() : $data[$num]->getEnvelope()->date; $dates[$num] = $dt->format('U'); } return $dates; } /** * Stable asort() function. * * PHP's asort() (BWT) is not a stable sort - identical values have no * guarantee of key order. Use Schwartzian Transform instead. See: * http://notmysock.org/blog/php/schwartzian-transform.html * * @param array &$a Array to sort. */ protected function _stableAsort(&$a) { array_walk($a, function(&$v, $k) { $v = array($v, $k); }); asort($a); array_walk($a, function(&$v, $k) { $v = $v[0]; }); } /** * Sort an array of strings based on current locale. * * @param array &$sorted Array of strings. */ protected function _sortString(&$sorted) { if (empty($this->_collator)) { asort($sorted, SORT_LOCALE_STRING); } else { $this->_collator->asort($sorted, Collator::SORT_STRING); } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Socket/Pop3.php0000664000175000017500000014475013150761653022022 0ustar janjan * Damian Fernandez Sosa * * Copyright (c) 2002, Richard Heyes * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * o Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * o Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * o The names of the authors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * --------------------------------------------------------------------------- * * @category Horde * @copyright 2002 Richard Heyes * @copyright 2009-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ /** * An interface to a POP3 server using PHP functions. * * It is an abstraction layer allowing POP3 commands to be used based on * IMAP equivalents. * * This driver implements the following POP3-related RFCs: *
 *   - STD 53/RFC 1939: POP3 specification
 *   - RFC 2195: CRAM-MD5 authentication
 *   - RFC 2449: POP3 extension mechanism
 *   - RFC 2595/4616: PLAIN authentication
 *   - RFC 2831: DIGEST-MD5 SASL Authentication (obsoleted by RFC 6331)
 *   - RFC 3206: AUTH/SYS response codes
 *   - RFC 4616: AUTH=PLAIN
 *   - RFC 5034: POP3 SASL
 *   - RFC 5802: AUTH=SCRAM-SHA-1
 *   - RFC 6856: UTF8, LANG
 * 
* * @author Richard Heyes * @author Michael Slusarz * @category Horde * @copyright 2002 Richard Heyes * @copyright 2009-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Socket_Pop3 extends Horde_Imap_Client_Base { /* Internal key used to store mailbox level cache data. \1 is not a valid * ID in POP3, so it should be safe to use. */ const MBOX_CACHE = "\1mbox"; /** * The default ports to use for a connection. * * @var array */ protected $_defaultPorts = array(110, 995); /** * The list of deleted messages. * * @var array */ protected $_deleted = array(); /** * This object returns POP3 Fetch data objects. * * @var string */ protected $_fetchDataClass = 'Horde_Imap_Client_Data_Fetch_Pop3'; /** */ public function __get($name) { $out = parent::__get($name); switch ($name) { case 'url': $out->protocol = 'pop3'; break; } return $out; } /** */ protected function _initCache($current = false) { return parent::_initCache($current) && $this->_capability('UIDL'); } /** */ public function getIdsOb($ids = null, $sequence = false) { return new Horde_Imap_Client_Ids_Pop3($ids, $sequence); } /** */ protected function _initCapability() { $this->_connect(); $c = new Horde_Imap_Client_Data_Capability(); try { $res = $this->_sendLine('CAPA', array( 'multiline' => 'array' )); foreach ($res['data'] as $val) { $prefix = explode(' ', $val); $c->add($prefix[0], array_slice($prefix, 1)); } } catch (Horde_Imap_Client_Exception $e) { $this->_temp['no_capa'] = true; /* Need to probe for capabilities if CAPA command is not * available. */ $c->add('USER'); /* Capability sniffing only guaranteed after authentication is * completed (if any). */ if (!empty($this->_init['authmethod'])) { $this->_pop3Cache('uidl'); if (empty($this->_temp['no_uidl'])) { $c->add('UIDL'); } $this->_pop3Cache('top', 1); if (empty($this->_temp['no_top'])) { $c->add('TOP'); } } } $this->_setInit('capability', $c); } /** */ protected function _noop() { $this->_sendLine('NOOP'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _getNamespaces() { throw new Horde_Imap_Client_Exception_NoSupportPop3('Namespaces'); } /** */ protected function _login() { /* Blank passwords are not allowed, so no need to even try * authentication to determine this. */ if (!strlen($this->getParam('password'))) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("No password provided."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED ); } $this->_connect(); $first_login = empty($this->_init['authmethod']); // Switch to secure channel if using TLS. if (!$this->isSecureConnection()) { $secure = $this->getParam('secure'); if (($secure === 'tls') || $secure === true) { // Switch over to a TLS connection. if ($first_login && !$this->_capability('STLS')) { if ($secure === 'tls') { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Could not open secure connection to the POP3 server.") . ' ' . Horde_Imap_Client_Translation::r("Server does not support secure connections."), Horde_Imap_Client_Exception::LOGIN_TLSFAILURE ); } else { $this->setParam('secure', false); } } else { $this->_sendLine('STLS'); $this->setParam('secure', 'tls'); if (!$this->_connection->startTls()) { $this->logout(); throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Could not open secure connection to the POP3 server."), Horde_Imap_Client_Exception::LOGIN_TLSFAILURE ); } $this->_debug->info('Successfully completed TLS negotiation.'); } // Expire cached CAPABILITY information $this->_setInit('capability'); } else { $this->setParam('secure', false); } } if ($first_login) { /* At least one server (Dovecot 1.x) may return SASL capability * with no arguments. */ $auth_mech = $this->_capability()->getParams('SASL'); if (isset($this->_temp['pop3timestamp'])) { $auth_mech[] = 'APOP'; } $auth_mech[] = 'USER'; /* Enable UTF-8 mode (RFC 6856). MUST occur after STLS is * issued. */ if ($this->_capability('UTF8')) { try { $this->_sendLine('UTF8'); $this->_temp['utf8'] = true; } catch (Horde_Imap_Client_Exception $e) { /* If server responds to UTF8 command with error, * fallback to legacy non-UTF8 behavior. */ } } } else { $auth_mech = array($this->_init['authmethod']); } foreach ($auth_mech as $method) { try { $this->_tryLogin($method); $this->_setInit('authmethod', $method); if (!empty($this->_temp['no_capa']) || !$this->_capability('UIDL')) { $this->_setInit('capability'); } return true; } catch (Horde_Imap_Client_Exception $e) { if (!empty($this->_init['authmethod']) && ($e->getCode() != $e::LOGIN_UNAVAILABLE) && ($e->getCode() != $e::POP3_TEMP_ERROR)) { $this->_setInit(); return $this->login(); } } } throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("POP3 server denied authentication."), $e->getCode() ?: $e::LOGIN_AUTHENTICATIONFAILED ); } /** * Connects to the server. * * @throws Horde_Imap_Client_Exception */ protected function _connect() { if (!is_null($this->_connection)) { return; } try { $this->_connection = new Horde_Imap_Client_Socket_Connection_Pop3( $this->getParam('hostspec'), $this->getParam('port'), $this->getParam('timeout'), $this->getParam('secure'), $this->getParam('context'), array( 'debug' => $this->_debug ) ); } catch (Horde\Socket\Client\Exception $e) { $e2 = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error connecting to mail server."), Horde_Imap_Client_Exception::SERVER_CONNECT ); $e2->details = $e->details; throw $e2; } $line = $this->_getResponse(); // Check for string matching APOP timestamp if (preg_match('/<.+@.+>/U', $line['resp'], $matches)) { $this->_temp['pop3timestamp'] = $matches[0]; } } /** * Authenticate to the POP3 server. * * @param string $method POP3 login method. * * @throws Horde_Imap_Client_Exception */ protected function _tryLogin($method) { $username = $this->getParam('username'); $password = $this->getParam('password'); switch ($method) { case 'CRAM-MD5': case 'CRAM-SHA1': case 'CRAM-SHA256': // RFC 5034: CRAM-MD5 // CRAM-SHA1 & CRAM-SHA256 supported by Courier SASL library $challenge = $this->_sendLine('AUTH ' . $method); $response = base64_encode($username . ' ' . hash_hmac(Horde_String::lower(substr($method, 5)), base64_decode(substr($challenge['resp'], 2)), $password, true)); $this->_sendLine($response, array( 'debug' => sprintf('[AUTH Response (username: %s)]', $username) )); break; case 'DIGEST-MD5': // RFC 2831; Obsoleted by RFC 6331 $challenge = $this->_sendLine('AUTH DIGEST-MD5'); $response = base64_encode(new Horde_Imap_Client_Auth_DigestMD5( $username, $password, base64_decode(substr($challenge['resp'], 2)), $this->getParam('hostspec'), 'pop3' )); $sresponse = $this->_sendLine($response, array( 'debug' => sprintf('[AUTH Response (username: %s)]', $username) )); if (stripos(base64_decode(substr($sresponse['resp'], 2)), 'rspauth=') === false) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Unexpected response from server when authenticating."), Horde_Imap_Client_Exception::SERVER_CONNECT ); } /* POP3 doesn't use protocol's third step. */ $this->_sendLine(''); break; case 'LOGIN': // RFC 4616 (AUTH=PLAIN) & 5034 (POP3 SASL) $this->_sendLine('AUTH LOGIN'); $this->_sendLine(base64_encode($username)); $this->_sendLine(base64_encode($password), array( 'debug' => sprintf('[AUTH Password (username: %s)]', $username) )); break; case 'PLAIN': // RFC 5034 $this->_sendLine('AUTH PLAIN ' . base64_encode(implode("\0", array( $username, $username, $password ))), array( 'debug' => sprintf('AUTH PLAIN [Auth Response (username: %s)]', $username) )); break; case 'APOP': /* If UTF8 (+ USER) is active, and non-ASCII exists, need to apply * SASLprep to username/password. RFC 6856[2.2]. Reject if * UTF8 (+ USER) is not supported and 8-bit characters exist. */ if (Horde_Mime::is8bit($username) || Horde_Mime::is8bit($password)) { if (empty($this->_temp['utf8']) || !$this->_capability('UTF8', 'USER') || !class_exists('Horde_Stringprep')) { $error = true; } else { Horde_Stringprep::autoload(); $saslprep = new Znerol\Component\Stringprep\Profile\SASLprep(); try { $username = $saslprep->apply( $username, 'UTF-8', Znerol\Compnonent\Stringprep\Profile::MODE_QUERY ); $password = $saslprep->apply( $password, 'UTF-8', Znerol\Compnonent\Stringprep\Profile::MODE_STORE ); $error = false; } catch (Znerol\Component\Stringprep\ProfileException $e) { $error = true; } } if ($error) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Authentication failed."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED ); } } // RFC 1939 [7] $this->_sendLine('APOP ' . $username . ' ' . hash('md5', $this->_temp['pop3timestamp'] . $password)); break; case 'USER': /* POP3 servers without UTF8 (+ USER) does not accept non-ASCII * in USER/PASS. RFC 6856[2.2] */ if ((empty($this->_temp['utf8']) || !$this->_capability('UTF8', 'USER')) && (Horde_Mime::is8bit($username) || Horde_Mime::is8bit($password))) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Authentication failed."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED ); } // RFC 1939 [7] $this->_sendLine('USER ' . $username); $this->_sendLine('PASS ' . $password, array( 'debug' => 'PASS [Password]' )); break; case 'SCRAM-SHA-1': $scram = new Horde_Imap_Client_Auth_Scram( $username, $password, 'SHA1' ); $c1 = $this->_sendLine( 'AUTH ' . $method . ' ' . base64_encode($scram->getClientFirstMessage()) ); $sr1 = base64_decode(substr($c1['resp'], 2)); if (!$scram->parseServerFirstMessage($sr1)) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Authentication failed."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED ); } $c2 = $this->_sendLine( base64_encode($scram->getClientFinalMessage()) ); $sr2 = base64_decode(substr($c2['resp'], 2)); if (!$scram->parseServerFirstMessage($sr)) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Authentication failed."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED ); /* This means authentication passed, according to the server, * but the server signature is incorrect. This indicates that * server verification has failed. Immediately disconnect from * the server, since this is a possible security issue. */ $this->logout(); throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Server failed verification check."), Horde_Imap_Client_Exception::LOGIN_SERVER_VERIFICATION_FAILED ); } $this->_sendLine(''); break; default: $e = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Unknown authentication method: %s"), Horde_Imap_Client_Exception::SERVER_CONNECT ); $e->messagePrintf(array($method)); throw $e; } } /** */ protected function _logout() { try { $this->_sendLine('QUIT'); } catch (Horde_Imap_Client_Exception $e) {} $this->_deleted = array(); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _sendID($info) { throw new Horde_Imap_Client_Exception_NoSupportPop3('ID command'); } /** * Return implementation information from the POP3 server (RFC 2449 [6.9]). */ protected function _getID() { return ($id = $this->_capability()->getParams('IMPLEMENTATION')) ? array('implementation' => reset($id)) : array(); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _setLanguage($langs) { // RFC 6856 [3] if (!$this->_capability('LANG')) { throw new Horde_Imap_Client_Exception_NoSupportPop3('LANGUAGE extension'); } foreach ($langs as $val) { try { $this->_sendLine('LANG ' . $val); $this->_temp['lang'] = $val; } catch (Horde_Imap_Client_Exception $e) { // Setting language failed - move on to next one. } } return $this->_getLanguage(false); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _getLanguage($list) { // RFC 6856 [3] if (!$this->_capability('LANG')) { throw new Horde_Imap_Client_Exception_NoSupportPop3('LANGUAGE extension'); } if (!$list) { return isset($this->_temp['lang']) ? $this->_temp['lang'] : null; } $langs = array(); try { $res = $this->_sendLine('LANG', array( 'multiline' => 'array' )); foreach ($res['data'] as $val) { $parts = explode(' ', $val); $langs[] = $parts[0]; // $parts[1] - lanuage description (not used) } } catch (Horde_Imap_Client_Exception $e) { // Ignore: language listing might fail. RFC 6856 [3.3] } return $langs; } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _openMailbox(Horde_Imap_Client_Mailbox $mailbox, $mode) { if ($mailbox != 'INBOX') { throw new Horde_Imap_Client_Exception_NoSupportPop3('Mailboxes other than INBOX'); } $this->_changeSelected($mailbox, $mode); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _createMailbox(Horde_Imap_Client_Mailbox $mailbox, $opts) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Creating mailboxes'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _deleteMailbox(Horde_Imap_Client_Mailbox $mailbox) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Deleting mailboxes'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _renameMailbox(Horde_Imap_Client_Mailbox $old, Horde_Imap_Client_Mailbox $new) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Renaming mailboxes'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _subscribeMailbox(Horde_Imap_Client_Mailbox $mailbox, $subscribe) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Mailboxes other than INBOX'); } /** */ protected function _listMailboxes($pattern, $mode, $options) { if (empty($options['flat'])) { return array( 'INBOX' => array( 'attributes' => array(), 'delimiter' => '', 'mailbox' => Horde_Imap_Client_Mailbox::get('INBOX') ) ); } return array('INBOX' => Horde_Imap_Client_Mailbox::get('INBOX')); } /** * @param integer $flags This driver only supports the options listed * under Horde_Imap_Client::STATUS_ALL. * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _status($mboxes, $flags) { if ((count($mboxes) > 1) || (reset($mboxes) != 'INBOX')) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Mailboxes other than INBOX'); } $this->openMailbox('INBOX'); $ret = array(); if ($flags & Horde_Imap_Client::STATUS_MESSAGES) { $res = $this->_pop3Cache('stat'); $ret['messages'] = $res['msgs']; } if ($flags & Horde_Imap_Client::STATUS_RECENT) { $res = $this->_pop3Cache('stat'); $ret['recent'] = $res['msgs']; } // No need for STATUS_UIDNEXT_FORCE handling since STATUS_UIDNEXT will // always return a value. $uidl = $this->_capability('UIDL'); if ($flags & Horde_Imap_Client::STATUS_UIDNEXT) { if ($uidl) { $ctx = hash_init('md5'); foreach ($this->_pop3Cache('uidl') as $key => $val) { hash_update($ctx, '|' . $key . '|' . $val); } $ret['uidnext'] = hash_final($ctx); } else { $res = $this->_pop3Cache('stat'); $ret['uidnext'] = $res['msgs'] + 1; } } if ($flags & Horde_Imap_Client::STATUS_UIDVALIDITY) { $ret['uidvalidity'] = $uidl ? 1 : microtime(true); } if ($flags & Horde_Imap_Client::STATUS_UNSEEN) { $ret['unseen'] = 0; } return array('INBOX' => $ret); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _append(Horde_Imap_Client_Mailbox $mailbox, $data, $options) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Appending messages'); } /** */ protected function _check() { $this->noop(); } /** */ protected function _close($options) { if (!empty($options['expunge'])) { $this->logout(); } } /** * @param array $options Additional options. 'ids' has no effect in this * driver. */ protected function _expunge($options) { $msg_list = $this->_deleted; $this->logout(); return empty($options['list']) ? null : $msg_list; } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _search($query, $options) { $sort = empty($options['sort']) ? null : reset($options['sort']); // Only support a single query: an ALL search sorted by sequence. if ((strval($options['_query']['query']) != 'ALL') || ($sort && ((count($options['sort']) > 1) || ($sort != Horde_Imap_Client::SORT_SEQUENCE)))) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Server search'); } $status = $this->status($this->_selected, Horde_Imap_Client::STATUS_MESSAGES); $res = range(1, $status['messages']); if (empty($options['sequence'])) { $tmp = array(); $uidllist = $this->_pop3Cache('uidl'); foreach ($res as $val) { $tmp[] = $uidllist[$val]; } $res = $tmp; } if (!empty($options['partial'])) { $partial = $this->getIdsOb($options['partial'], true); $min = $partial->min - 1; $res = array_slice($res, $min, $partial->max - $min); } $ret = array(); foreach ($options['results'] as $val) { switch ($val) { case Horde_Imap_Client::SEARCH_RESULTS_COUNT: $ret['count'] = count($res); break; case Horde_Imap_Client::SEARCH_RESULTS_MATCH: $ret['match'] = $this->getIdsOb($res); break; case Horde_Imap_Client::SEARCH_RESULTS_MAX: $ret['max'] = empty($res) ? null : max($res); break; case Horde_Imap_Client::SEARCH_RESULTS_MIN: $ret['min'] = empty($res) ? null : min($res); break; } } return $ret; } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _setComparator($comparator) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Search comparators'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _getComparator() { throw new Horde_Imap_Client_Exception_NoSupportPop3('Search comparators'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _thread($options) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Server threading'); } /** */ protected function _fetch(Horde_Imap_Client_Fetch_Results $results, $queries) { foreach ($queries as $options) { $this->_fetchCmd($results, $options); } $this->_updateCache($results); } /** * Fetch data for a given fetch query. * * @param Horde_Imap_Client_Fetch_Results $results Fetch results. * @param array $options Fetch query options. */ protected function _fetchCmd(Horde_Imap_Client_Fetch_Results $results, $options) { // Grab sequence IDs - IDs will always be the message number for // POP3 fetch commands. $seq_ids = $this->_getSeqIds($options['ids']); if (empty($seq_ids)) { return; } $lookup = $options['ids']->sequence ? array_combine($seq_ids, $seq_ids) : $this->_pop3Cache('uidl'); foreach ($options['_query'] as $type => $c_val) { switch ($type) { case Horde_Imap_Client::FETCH_FULLMSG: foreach ($seq_ids as $id) { $tmp = $this->_pop3Cache('msg', $id); if (empty($c_val['start']) && empty($c_val['length'])) { $tmp2 = fopen('php://temp', 'r+'); stream_copy_to_stream($tmp, $tmp2, empty($c_val['length']) ? -1 : $c_val['length'], empty($c_val['start']) ? 0 : $c_val['start']); $results->get($lookup[$id])->setFullMsg($tmp2); } else { $results->get($lookup[$id])->setFullMsg($tmp); } } break; case Horde_Imap_Client::FETCH_HEADERTEXT: // Ignore 'peek' option foreach ($c_val as $key => $val) { foreach ($seq_ids as $id) { /* Message header can be retrieved via TOP, if the * command is available. */ try { $tmp = ($key == 0) ? $this->_pop3Cache('hdr', $id) : Horde_Mime_Part::getRawPartText(stream_get_contents($this->_pop3Cache('msg', $id)), 'header', $key); $results->get($lookup[$id])->setHeaderText($key, $this->_processString($tmp, $c_val)); } catch (Horde_Mime_Exception $e) {} } } break; case Horde_Imap_Client::FETCH_BODYTEXT: // Ignore 'peek' option foreach ($c_val as $key => $val) { foreach ($seq_ids as $id) { try { $results->get($lookup[$id])->setBodyText($key, $this->_processString(Horde_Mime_Part::getRawPartText(stream_get_contents($this->_pop3Cache('msg', $id)), 'body', $key), $val)); } catch (Horde_Mime_Exception $e) {} } } break; case Horde_Imap_Client::FETCH_MIMEHEADER: // Ignore 'peek' option foreach ($c_val as $key => $val) { foreach ($seq_ids as $id) { try { $results->get($lookup[$id])->setMimeHeader($key, $this->_processString(Horde_Mime_Part::getRawPartText(stream_get_contents($this->_pop3Cache('msg', $id)), 'header', $key), $val)); } catch (Horde_Mime_Exception $e) {} } } break; case Horde_Imap_Client::FETCH_BODYPART: // Ignore 'decode', 'peek' foreach ($c_val as $key => $val) { foreach ($seq_ids as $id) { try { $results->get($lookup[$id])->setBodyPart($key, $this->_processString(Horde_Mime_Part::getRawPartText(stream_get_contents($this->_pop3Cache('msg', $id)), 'body', $key), $val)); } catch (Horde_Mime_Exception $e) {} } } break; case Horde_Imap_Client::FETCH_HEADERS: // Ignore 'length', 'peek' foreach ($seq_ids as $id) { $ob = $this->_pop3Cache('hdrob', $id); foreach ($c_val as $key => $val) { $tmp = $ob; if (empty($val['notsearch'])) { $tmp2 = $tmp->toArray(array('nowrap' => true)); foreach (array_keys($tmp2) as $hdr) { if (!in_array($hdr, $val['headers'])) { unset($tmp[$hdr]); } } } else { foreach ($val['headers'] as $hdr) { unset($tmp[$hdr]); } } $results->get($lookup[$id])->setHeaders($key, $tmp); } } break; case Horde_Imap_Client::FETCH_STRUCTURE: foreach ($seq_ids as $id) { if ($ptr = $this->_pop3Cache('msg', $id)) { try { $results->get($lookup[$id])->setStructure(Horde_Mime_Part::parseMessage(stream_get_contents($ptr), array('no_body' => true))); } catch (Horde_Exception $e) {} } } break; case Horde_Imap_Client::FETCH_ENVELOPE: foreach ($seq_ids as $id) { $tmp = $this->_pop3Cache('hdrob', $id); $results->get($lookup[$id])->setEnvelope(array( 'date' => $tmp['Date'], 'subject' => $tmp['Subject'], 'from' => ($h = $tmp['From']) ? $h->getAddressList(true) : null, 'sender' => ($h = $tmp['Sender']) ? $h->getAddressList(true) : null, 'reply_to' => ($h = $tmp['Reply-to']) ? $h->getAddressList(true) : null, 'to' => ($h = $tmp['To']) ? $h->getAddressList(true) : null, 'cc' => ($h = $tmp['Cc']) ? $h->getAddressList(true) : null, 'bcc' => ($h = $tmp['Bcc']) ? $h->getAddressList(true) : null, 'in_reply_to' => $tmp['In-Reply-To'], 'message_id' => $tmp['Message-ID'] )); } break; case Horde_Imap_Client::FETCH_IMAPDATE: foreach ($seq_ids as $id) { $tmp = $this->_pop3Cache('hdrob', $id); $results->get($lookup[$id])->setImapDate($tmp['Date']); } break; case Horde_Imap_Client::FETCH_SIZE: $sizelist = $this->_pop3Cache('size'); foreach ($seq_ids as $id) { $results->get($lookup[$id])->setSize($sizelist[$id]); } break; case Horde_Imap_Client::FETCH_SEQ: foreach ($seq_ids as $id) { $results->get($lookup[$id])->setSeq($id); } break; case Horde_Imap_Client::FETCH_UID: $uidllist = $this->_pop3Cache('uidl'); foreach ($seq_ids as $id) { if (isset($uidllist[$id])) { $results->get($lookup[$id])->setUid($uidllist[$id]); } } break; } } } /** * Retrieve locally cached message data. * * @param string $type Either 'hdr', 'hdrob', 'msg', 'size', 'stat', * 'top', or 'uidl'. * @param integer $index The message index. * @param mixed $data Additional information needed. * * @return mixed The cached data. 'msg' returns a stream resource. All * other types return strings. * * @throws Horde_Imap_Client_Exception */ protected function _pop3Cache( $type, $index = self::MBOX_CACHE, $data = null ) { if (isset($this->_temp['pop3cache'][$index][$type])) { if ($type == 'msg') { rewind($this->_temp['pop3cache'][$index][$type]); } return $this->_temp['pop3cache'][$index][$type]; } switch ($type) { case 'hdr': case 'top': $data = null; if (($type == 'top') || $this->_capability('TOP')) { try { $res = $this->_sendLine('TOP ' . $index . ' 0', array( 'multiline' => 'stream' )); rewind($res['data']); $data = stream_get_contents($res['data']); fclose($res['data']); } catch (Horde_Imap_Client_Exception $e) { $this->_temp['no_top'] = true; if ($type == 'top') { return null; } } } if (is_null($data)) { $data = Horde_Mime_Part::getRawPartText(stream_get_contents($this->_pop3Cache('msg', $index)), 'header', 0); } break; case 'hdrob': $data = Horde_Mime_Headers::parseHeaders($this->_pop3Cache('hdr', $index)); break; case 'msg': $res = $this->_sendLine('RETR ' . $index, array( 'multiline' => 'stream' )); $data = $res['data']; rewind($data); break; case 'size': case 'uidl': $data = array(); try { $res = $this->_sendLine(($type == 'size') ? 'LIST' : 'UIDL', array( 'multiline' => 'array' )); foreach ($res['data'] as $val) { $resp_data = explode(' ', $val, 2); $data[$resp_data[0]] = $resp_data[1]; } } catch (Horde_Imap_Client_Exception $e) { if ($type == 'uidl') { $this->_temp['no_uidl'] = true; } } break; case 'stat': $resp = $this->_sendLine('STAT'); $resp_data = explode(' ', $resp['resp'], 2); $data = array('msgs' => $resp_data[0], 'size' => $resp_data[1]); break; } $this->_temp['pop3cache'][$index][$type] = $data; return $data; } /** * Process a string response based on criteria options. * * @param string $str The original string. * @param array $opts The criteria options. * * @return string The requested string. */ protected function _processString($str, $opts) { if (!empty($opts['length'])) { return substr($str, empty($opts['start']) ? 0 : $opts['start'], $opts['length']); } elseif (!empty($opts['start'])) { return substr($str, $opts['start']); } return $str; } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _vanished($modseq, Horde_Imap_Client_Ids $ids) { throw new Horde_Imap_Client_Exception_NoSupportPop3('QRESYNC commands'); } /** * @param array $options Additional options. This driver does not support * 'unchangedsince'. */ protected function _store($options) { $delete = $reset = false; /* Only support deleting/undeleting messages. */ if (isset($options['replace'])) { $delete = (bool)(count(array_intersect($options['replace'], array( Horde_Imap_Client::FLAG_DELETED )))); $reset = !$delete; } else { if (!empty($options['add'])) { $delete = (bool)(count(array_intersect($options['add'], array( Horde_Imap_Client::FLAG_DELETED )))); } if (!empty($options['remove'])) { $reset = !(bool)(count(array_intersect($options['remove'], array( Horde_Imap_Client::FLAG_DELETED )))); } } if ($reset) { $this->_sendLine('RSET'); } elseif ($delete) { foreach ($this->_getSeqIds($options['ids']) as $id) { try { $this->_sendLine('DELE ' . $id); $this->_deleted[] = $id; unset( $this->_temp['pop3cache'][self::MBOX_CACHE], $this->_temp['pop3cache'][$id] ); } catch (Horde_Imap_Client_Exception $e) {} } } return $this->getIdsOb(); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _copy(Horde_Imap_Client_Mailbox $dest, $options) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Copying messages'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _setQuota(Horde_Imap_Client_Mailbox $root, $options) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Quotas'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _getQuota(Horde_Imap_Client_Mailbox $root) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Quotas'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _getQuotaRoot(Horde_Imap_Client_Mailbox $mailbox) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Quotas'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _setACL(Horde_Imap_Client_Mailbox $mailbox, $identifier, $options) { throw new Horde_Imap_Client_Exception_NoSupportPop3('ACLs'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _deleteACL(Horde_Imap_Client_Mailbox $mailbox, $identifier) { throw new Horde_Imap_Client_Exception_NoSupportPop3('ACLs'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _getACL(Horde_Imap_Client_Mailbox $mailbox) { throw new Horde_Imap_Client_Exception_NoSupportPop3('ACLs'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _listACLRights(Horde_Imap_Client_Mailbox $mailbox, $identifier) { throw new Horde_Imap_Client_Exception_NoSupportPop3('ACLs'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _getMyACLRights(Horde_Imap_Client_Mailbox $mailbox) { throw new Horde_Imap_Client_Exception_NoSupportPop3('ACLs'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _getMetadata(Horde_Imap_Client_Mailbox $mailbox, $entries, $options) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Metadata'); } /** * @throws Horde_Imap_Client_Exception_NoSupportPop3 */ protected function _setMetadata(Horde_Imap_Client_Mailbox $mailbox, $data) { throw new Horde_Imap_Client_Exception_NoSupportPop3('Metadata'); } /** */ protected function _getSearchCache($type, $options) { /* POP3 does not support search caching. */ return null; } /** */ public function resolveIds(Horde_Imap_Client_Mailbox $mailbox, Horde_Imap_Client_Ids $ids, $convert = 0) { if (!$ids->special && (!$convert || (!$ids->sequence && ($convert == 1)) || $ids->isEmpty())) { return clone $ids; } $uids = $this->_pop3Cache('uidl'); return $this->getIdsOb( $ids->all ? array_values($uids) : array_intersect_keys($uids, $ids->ids) ); } /* Internal functions. */ /** * Perform a command on the server. A connection to the server must have * already been made. * * @param string $cmd The command to execute. * @param array $options Additional options: *
     *   - debug: (string) When debugging, send this string instead of the
     *            actual command/data sent.
     *            DEFAULT: Raw data output to debug stream.
     *   - multiline: (mixed) 'array', 'none', or 'stream'.
     * 
* * @return array See _getResponse(). * * @throws Horde_Imap_Client_Exception */ protected function _sendLine($cmd, $options = array()) { if (!empty($options['debug'])) { $this->_debug->client($options['debug']); } if ($this->_debug->debug) { $timer = new Horde_Support_Timer(); $timer->push(); } try { $this->_connection->write($cmd, empty($options['debug'])); } catch (Horde_Imap_Client_Exception $e) { throw $e; } $resp = $this->_getResponse( empty($options['multiline']) ? false : $options['multiline'] ); if ($this->_debug->debug) { $this->_debug->info(sprintf( 'Command took %s seconds.', round($timer->pop(), 4) )); } return $resp; } /** * Gets a line from the stream and parses it. * * @param mixed $multiline 'array', 'none', 'stream', or null. * * @return array An array with the following keys: * - data: (mixed) Stream, array, or null. * - resp: (string) The server response text. * * @throws Horde_Imap_Client_Exception */ protected function _getResponse($multiline = false) { $ob = array('resp' => ''); $read = explode(' ', rtrim($this->_connection->read(), "\r\n"), 2); if (!in_array($read[0], array('+OK', '-ERR', '+'))) { $this->_debug->info('ERROR: IMAP read/timeout error.'); throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error when communicating with the mail server."), Horde_Imap_Client_Exception::SERVER_READERROR ); } $respcode = null; if (isset($read[1]) && isset($this->_init['capability']) && $this->_capability('RESP-CODES')) { $respcode = $this->_parseResponseCode($read[1]); } switch ($read[0]) { case '+OK': case '+': if ($respcode) { $ob['resp'] = $respcode->text; } elseif (isset($read[1])) { $ob['resp'] = $read[1]; } break; case '-ERR': $errcode = 0; if ($respcode) { $errtext = $respcode->text; if (isset($respcode->code)) { switch ($respcode->code) { // RFC 2449 [8.1.1] case 'IN-USE': // RFC 2449 [8.1.2] case 'LOGIN-DELAY': $errcode = Horde_Imap_Client_Exception::LOGIN_UNAVAILABLE; break; // RFC 3206 [4] case 'SYS/TEMP': $errcode = Horde_Imap_Client_Exception::POP3_TEMP_ERROR; break; // RFC 3206 [4] case 'SYS/PERM': $errcode = Horde_Imap_Client_Exception::POP3_PERM_ERROR; break; // RFC 3206 [5] case 'AUTH': $errcode = Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED; break; // RFC 6856 [5] case 'UTF8': /* This code can only be issued if we (as client) are * broken, so no need to handle since we should never * be broken. */ break; } } } elseif (isset($read[1])) { $errtext = $read[1]; } else { $errtext = '[No error message provided by server]'; } $e = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("POP3 error reported by server."), $errcode ); $e->details = $errtext; throw $e; } switch ($multiline) { case 'array': $ob['data'] = array(); break; case 'none': $ob['data'] = null; break; case 'stream': $ob['data'] = fopen('php://temp', 'r+'); break; default: return $ob; } do { $orig_read = $this->_connection->read(); $read = rtrim($orig_read, "\r\n"); if ($read === '.') { break; } elseif (substr($read, 0, 2) === '..') { $read = substr($read, 1); } if (is_array($ob['data'])) { $ob['data'][] = $read; } elseif (!is_null($ob['data'])) { fwrite($ob['data'], $orig_read); } } while (true); return $ob; } /** * Returns a list of sequence IDs. * * @param Horde_Imap_Client_Ids $ids The ID list. * * @return array A list of sequence IDs. */ protected function _getSeqIds(Horde_Imap_Client_Ids $ids) { if (!count($ids)) { $status = $this->status($this->_selected, Horde_Imap_Client::STATUS_MESSAGES); return range(1, $status['messages']); } elseif ($ids->sequence) { return $ids->ids; } return array_keys(array_intersect($this->_pop3Cache('uidl'), $ids->ids)); } /** * Parses response text for response codes (RFC 2449 [8]). * * @param string $text The response text. * * @return object An object with the following properties: * - code: (string) The response code, if it exists. * - data: (string) The response code data, if it exists. * - text: (string) The human-readable response text. */ protected function _parseResponseCode($text) { $ret = new stdClass; $text = trim($text); if ($text[0] === '[') { $pos = strpos($text, ' ', 2); $end_pos = strpos($text, ']', 2); if ($pos > $end_pos) { $ret->code = Horde_String::upper(substr($text, 1, $end_pos - 1)); } else { $ret->code = Horde_String::upper(substr($text, 1, $pos - 1)); $ret->data = substr($text, $pos + 1, $end_pos - $pos - 1); } $ret->text = trim(substr($text, $end_pos + 1)); } else { $ret->text = $text; } return $ret; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Url/Imap/Relative.php0000664000175000017500000000216513150761653023145 0ustar janjan * @category Horde * @copyright 2008-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.25.0 */ class Horde_Imap_Client_Url_Imap_Relative extends Horde_Imap_Client_Url_Imap { /** * Create a relative IMAP URL (RFC 5092/5593). * * @return string A URL string. */ public function __toString() { if ($out = $this->_toImapString()) { if (substr($out, 0, 2) === '/;') { $out = substr($out, 1); } elseif ($out[0] !== ';') { $out = '/' . $out; } } return $out; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Url/Base.php0000664000175000017500000000704113150761653021354 0ustar janjan * @category Horde * @copyright 2008-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.25.0 * * @property string $auth The authentication method. * @property string $host The server. * @property integer $port The port. * @property string $username The username. */ abstract class Horde_Imap_Client_Url_Base implements Serializable { /** * The authentication method to use. * * @var string */ protected $_auth = null; /** * The server name. * * @var string */ protected $_host = null; /** * The port. * * @var integer */ protected $_port = null; /** * The username. * * @var string */ protected $_username = null; /** * Constructor. * * @param string $url A URL string. */ public function __construct($url = null) { if (!is_null($url)) { $this->_parse($url); } } /** */ public function __get($name) { switch ($name) { case 'auth': case 'host': case 'port': case 'username': return $this->{'_' . $name}; } } /** */ public function __set($name, $value) { switch ($name) { case 'auth': case 'host': case 'port': case 'username': $this->{'_' . $name} = $value; break; } } /** * Create a POP3 (RFC 2384) or IMAP (RFC 5092/5593) URL. * * @return string A URL string. */ public function __toString() { $url = ''; if (!is_null($this->username)) { $url .= $this->username; if (!is_null($this->auth)) { $url .= ';AUTH=' . $this->auth; } $url .= '@'; } $url .= $this->host; return $url; } /** */ protected function _parse($url) { $data = parse_url(trim($url)); if (isset($data['scheme'])) { if (isset($data['host'])) { $this->host = $data['host']; } if (isset($data['port'])) { $this->port = $data['port']; } } /* Check for username/auth information. */ if (isset($data['user'])) { if (($pos = stripos($data['user'], ';AUTH=')) !== false) { $auth = substr($data['user'], $pos + 6); if ($auth !== '*') { $this->auth = $auth; } $data['user'] = substr($data['user'], 0, $pos); } if (strlen($data['user'])) { $this->username = $data['user']; } } $this->_parseUrl($data); } /** */ abstract protected function _parseUrl(array $data); /* Serializable methods. */ /** */ public function serialize() { return strval($this); } /** */ public function unserialize($data) { $this->_parse($data); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Url/Imap.php0000664000175000017500000001256313150761653021375 0ustar janjan[/] * - imap:///[][?] * - imap:///[][][][] * * @author Michael Slusarz * @category Horde * @copyright 2008-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.25.0 * * @property Horde_Imap_Client_Mailbox $mailbox IMAP Mailbox. * @property string $partial Byte range for use with IMAP FETCH command. * @property string $search Search query to be run with IMAP SEARCH. * @property string $section MIME part ID. * @property string $uid IMAP UID. * @property string $uidvalidity IMAP UIDVALIDITY for the mailbox. * @property string $urlauth URLAUTH info. */ class Horde_Imap_Client_Url_Imap extends Horde_Imap_Client_Url_Base { /** * IMAP mailbox. * * @var Horde_Imap_Client_Mailbox */ protected $_mailbox; /** * Byte range for use with IMAP FETCH command. * * @var string */ protected $_partial; /** * Search query to be run with IMAP SEARCH. * * @var string */ protected $_search; /** * MIME part ID. * * @var string */ protected $_section; /** * IMAP UID. * * @var string */ protected $_uid; /** * IMAP UIDVALIDITY for the given mailbox. * * @var integer */ protected $_uidvalidity; /** * URLAUTH info (not parsed). * * @var string */ protected $_urlauth; /** */ public function __get($name) { switch ($name) { case 'mailbox': return $this->_mailbox; case 'partial': case 'search': case 'section': case 'uid': case 'uidvalidity': case 'urlauth': return isset($this->{'_' . $name}) ? $this->{'_' . $name} : null; case 'port': return parent::__get($name) ?: 143; default: return parent::__get($name); } } /** */ public function __set($name, $value) { switch ($name) { case 'mailbox': $this->_mailbox = Horde_Imap_Client_Mailbox::get($value); break; case 'partial': case 'search': case 'section': case 'uid': case 'uidvalidity': case 'urlauth': $this->{'_' . $name} = $value; break; default: parent::__set($name, $value); break; } } /** * Create an IMAP URL (RFC 5092/5593). * * @return string A URL string. */ public function __toString() { $url = 'imap://' . parent::__toString(); if (($port = $this->port) != 143) { $url .= ':' . $port; } return $url . '/' . $this->_toImapString(); } /** */ protected function _toImapString() { $url = ''; if ($mbox = $this->mailbox) { $url .= rawurlencode($mbox->utf7imap); } if ($uidvalid = $this->uidvalidity) { $url .= ';UIDVALIDITY=' . $uidvalid; } if ($search = $this->search) { $url .= '?' . rawurlencode($search); } else { if ($uid = $this->uid) { $url .= '/;UID=' . $uid; } if ($section = $this->section) { $url .= '/;SECTION=' . $section; } if ($partial = $this->partial) { $url .= '/;PARTIAL=' . $partial; } if ($urlauth = $this->urlauth) { $url .= '/;URLAUTH=' . $urlauth; } } return $url; } /** */ protected function _parseUrl(array $data) { if (isset($data['path']) && strlen($path = ltrim($data['path'], '/'))) { $parts = explode('/;', $path); $mbox = array_shift($parts); if (($pos = stripos($mbox, ';UIDVALIDITY=')) !== false) { $this->uidvalidity = intval(substr($mbox, $pos + 13)); $mbox = substr($mbox, 0, $pos); } if ($mbox[0] === ';') { array_unshift($parts, substr($mbox, 1)); } elseif (strlen($mbox)) { $this->_mailbox = Horde_Imap_Client_Mailbox::get( rawurldecode($mbox), true ); } if (isset($data['query'])) { $this->search = rawurldecode($data['query']); $parts = array(); } } else { $parts = array(); } if (count($parts)) { foreach ($parts as $val) { list($k, $v) = explode('=', $val); $this->{Horde_String::lower($k)} = $v; } } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Url/Pop3.php0000664000175000017500000000260313150761653021322 0ustar janjan;auth=@: * * @author Michael Slusarz * @category Horde * @copyright 2014-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @since 2.25.0 */ class Horde_Imap_Client_Url_Pop3 extends Horde_Imap_Client_Url_Base { /** */ public function __get($name) { switch ($name) { case 'port': return parent::__get($name) ?: 110; default: return parent::__get($name); } } /** * Create a POP3 URL (RFC 2384). * * @return string A URL string. */ public function __toString() { $url = 'pop://' . parent::__toString(); if (($port = $this->port) != 110) { $url .= ':' . $port; } return $url . '/'; } /** */ protected function _parseUrl(array $data) { } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Base.php0000664000175000017500000044230513150761653020620 0ustar janjan * @category Horde * @copyright 2008-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * * @property-read Horde_Imap_Client_Base_Alert $alerts_ob The alert reporting object (@since 2.26.0) * @property-read Horde_Imap_Client_Data_Capability $capability * A capability object. (@since 2.24.0) * @property-read Horde_Imap_Client_Data_SearchCharset $search_charset * A search charset object. (@since 2.24.0) * @property-read Horde_Imap_Client_Url $url The URL object for the current * connection parameters (@since 2.24.0) */ abstract class Horde_Imap_Client_Base implements Serializable, SplObserver { /** Serialized version. */ const VERSION = 3; /** Cache names for miscellaneous data. */ const CACHE_MODSEQ = '_m'; const CACHE_SEARCH = '_s'; /* @since 2.9.0 */ const CACHE_SEARCHID = '_i'; /** Cache names used exclusively within this class. @since 2.11.0 */ const CACHE_DOWNGRADED = 'HICdg'; /** * The list of fetch fields that can be cached, and their cache names. * * @var array */ public $cacheFields = array( Horde_Imap_Client::FETCH_ENVELOPE => 'HICenv', Horde_Imap_Client::FETCH_FLAGS => 'HICflags', Horde_Imap_Client::FETCH_HEADERS => 'HIChdrs', Horde_Imap_Client::FETCH_IMAPDATE => 'HICdate', Horde_Imap_Client::FETCH_SIZE => 'HICsize', Horde_Imap_Client::FETCH_STRUCTURE => 'HICstruct' ); /** * Has the internal configuration changed? * * @var boolean */ public $changed = false; /** * Horde_Imap_Client is optimized for short (i.e. 1 seconds) scripts. It * makes heavy use of mailbox caching to save on server accesses. This * property should be set to false for long-running scripts, or else * status() data may not reflect the current state of the mailbox on the * server. * * @since 2.14.0 * * @var boolean */ public $statuscache = true; /** * Alerts reporting object. * * @var Horde_Imap_Client_Base_Alerts */ protected $_alerts; /** * The Horde_Imap_Client_Cache object. * * @var Horde_Imap_Client_Cache */ protected $_cache = null; /** * Connection to the IMAP server. * * @var Horde\Socket\Client */ protected $_connection = null; /** * The debug object. * * @var Horde_Imap_Client_Base_Debug */ protected $_debug = null; /** * The default ports to use for a connection. * First element is non-secure, second is SSL. * * @var array */ protected $_defaultPorts = array(); /** * The fetch data object type to return. * * @var string */ protected $_fetchDataClass = 'Horde_Imap_Client_Data_Fetch'; /** * Cached server data. * * @var array */ protected $_init; /** * Is there an active authenticated connection to the IMAP Server? * * @var boolean */ protected $_isAuthenticated = false; /** * The current mailbox selection mode. * * @var integer */ protected $_mode = 0; /** * Hash containing connection parameters. * This hash never changes. * * @var array */ protected $_params = array(); /** * The currently selected mailbox. * * @var Horde_Imap_Client_Mailbox */ protected $_selected = null; /** * Temp array (destroyed at end of process). * * @var array */ protected $_temp = array(); /** * Constructor. * * @param array $params Configuration parameters: *
     * - cache: (array) If set, caches data from fetch(), search(), and
     *          thread() calls. Requires the horde/Cache package to be
     *          installed. The array can contain the following keys (see
     *          Horde_Imap_Client_Cache for default values):
     *   - backend: [REQUIRED (or cacheob)] (Horde_Imap_Client_Cache_Backend)
     *              Backend cache driver [@since 2.9.0].
     *   - fetch_ignore: (array) A list of mailboxes to ignore when storing
     *                   fetch data.
     *   - fields: (array) The fetch criteria to cache. If not defined, all
     *             cacheable data is cached. The following is a list of
     *             criteria that can be cached:
     *     - Horde_Imap_Client::FETCH_ENVELOPE
     *     - Horde_Imap_Client::FETCH_FLAGS
     *       Only if server supports CONDSTORE extension
     *     - Horde_Imap_Client::FETCH_HEADERS
     *       Only for queries that specifically request caching
     *     - Horde_Imap_Client::FETCH_IMAPDATE
     *     - Horde_Imap_Client::FETCH_SIZE
     *     - Horde_Imap_Client::FETCH_STRUCTURE
     * - capability_ignore: (array) A list of IMAP capabilites to ignore, even
     *                      if they are supported on the server.
     *                      DEFAULT: No supported capabilities are ignored.
     * - comparator: (string) The search comparator to use instead of the
     *               default server comparator. See setComparator() for
     *               format.
     *               DEFAULT: Use the server default
     * - context: (array) Any context parameters passed to
     *            stream_create_context(). @since 2.27.0
     * - debug: (string) If set, will output debug information to the stream
     *          provided. The value can be any PHP supported wrapper that can
     *          be opened via PHP's fopen() function.
     *          DEFAULT: No debug output
     * - hostspec: (string) The hostname or IP address of the server.
     *             DEFAULT: 'localhost'
     * - id: (array) Send ID information to the server (only if server
     *       supports the ID extension). An array with the keys as the fields
     *       to send and the values being the associated values. See RFC 2971
     *       [3.3] for a list of standard field values.
     *       DEFAULT: No info sent to server
     * - lang: (array) A list of languages (in priority order) to be used to
     *         display human readable messages.
     *         DEFAULT: Messages output in IMAP server default language
     * - password: (mixed) The user password. Either a string or a
     *             Horde_Imap_Client_Base_Password object [@since 2.14.0].
     * - port: (integer) The server port to which we will connect.
     *         DEFAULT: 143 (imap or imap w/TLS) or 993 (imaps)
     * - secure: (string) Use SSL or TLS to connect. Values:
     *   - false (No encryption)
     *   - 'ssl' (Auto-detect SSL version)
     *   - 'sslv2' (Force SSL version 3)
     *   - 'sslv3' (Force SSL version 2)
     *   - 'tls' (TLS; started via protocol-level negotation over
     *     unencrypted channel; RECOMMENDED way of initiating secure
     *     connection)
     *   - 'tlsv1' (TLS direct version 1.x connection to server) [@since
     *     2.16.0]
     *   - true (TLS if available/necessary) [@since 2.15.0]
     *     DEFAULT: false
     * - timeout: (integer)  Connection timeout, in seconds.
     *            DEFAULT: 30 seconds
     * - username: (string) [REQUIRED] The username.
     * 
*/ public function __construct(array $params = array()) { if (!isset($params['username'])) { throw new InvalidArgumentException('Horde_Imap_Client requires a username.'); } $this->_setInit(); // Default values. $params = array_merge(array( 'context' => array(), 'hostspec' => 'localhost', 'secure' => false, 'timeout' => 30 ), array_filter($params)); if (!isset($params['port']) && strpos($params['hostspec'], 'unix://') !== 0) { $params['port'] = (!empty($params['secure']) && in_array($params['secure'], array('ssl', 'sslv2', 'sslv3'), true)) ? $this->_defaultPorts[1] : $this->_defaultPorts[0]; } if (empty($params['cache'])) { $params['cache'] = array('fields' => array()); } elseif (empty($params['cache']['fields'])) { $params['cache']['fields'] = $this->cacheFields; } else { $params['cache']['fields'] = array_flip($params['cache']['fields']); } if (empty($params['cache']['fetch_ignore'])) { $params['cache']['fetch_ignore'] = array(); } $this->_params = $params; if (isset($params['password'])) { $this->setParam('password', $params['password']); } $this->changed = true; $this->_initOb(); } /** * Get encryption key. * * @deprecated Pass callable into 'password' parameter instead. * * @return string The encryption key. */ protected function _getEncryptKey() { if (is_callable($ekey = $this->getParam('encryptKey'))) { return call_user_func($ekey); } throw new InvalidArgumentException('encryptKey parameter is not a valid callback.'); } /** * Do initialization tasks. */ protected function _initOb() { register_shutdown_function(array($this, 'shutdown')); $this->_alerts = new Horde_Imap_Client_Base_Alerts(); // @todo: Remove (BC) $this->_alerts->attach($this); $this->_debug = ($debug = $this->getParam('debug')) ? new Horde_Imap_Client_Base_Debug($debug) : new Horde_Support_Stub(); // @todo: Remove (BC purposes) if (isset($this->_init['capability']) && !is_object($this->_init['capability'])) { $this->_setInit('capability'); } foreach (array('capability', 'search_charset') as $val) { if (isset($this->_init[$val])) { $this->_init[$val]->attach($this); } } } /** * Shutdown actions. */ public function shutdown() { try { $this->logout(); } catch (Horde_Imap_Client_Exception $e) { } } /** * This object can not be cloned. */ public function __clone() { throw new LogicException('Object cannot be cloned.'); } /** */ public function update(SplSubject $subject) { if (($subject instanceof Horde_Imap_Client_Data_Capability) || ($subject instanceof Horde_Imap_Client_Data_SearchCharset)) { $this->changed = true; } /* @todo: BC - remove */ if ($subject instanceof Horde_Imap_Client_Base_Alerts) { $this->_temp['alerts'][] = $subject->getLast()->alert; } } /** */ public function serialize() { return serialize(array( 'i' => $this->_init, 'p' => $this->_params, 'v' => self::VERSION )); } /** */ public function unserialize($data) { $data = @unserialize($data); if (!is_array($data) || !isset($data['v']) || ($data['v'] != self::VERSION)) { throw new Exception('Cache version change'); } $this->_init = $data['i']; $this->_params = $data['p']; $this->_initOb(); } /** */ public function __get($name) { switch ($name) { case 'alerts_ob': return $this->_alerts; case 'capability': return $this->_capability(); case 'search_charset': if (!isset($this->_init['search_charset'])) { $this->_init['search_charset'] = new Horde_Imap_Client_Data_SearchCharset(); $this->_init['search_charset']->attach($this); } $this->_init['search_charset']->setBaseOb($this); return $this->_init['search_charset']; case 'url': $url = new Horde_Imap_Client_Url(); $url->hostspec = $this->getParam('hostspec'); $url->port = $this->getParam('port'); $url->protocol = 'imap'; return $url; } } /** * Set an initialization value. * * @param string $key The initialization key. If null, resets all keys. * @param mixed $val The cached value. If null, removes the key. */ public function _setInit($key = null, $val = null) { if (is_null($key)) { $this->_init = array(); } elseif (is_null($val)) { unset($this->_init[$key]); } else { switch ($key) { case 'capability': if ($ci = $this->getParam('capability_ignore')) { $ignored = array(); foreach ($ci as $val2) { $c = explode('=', $val2); if ($val->query($c[0], isset($c[1]) ? $c[1] : null)) { $ignored[] = $val2; $val->remove($c[0], isset($c[1]) ? $c[1] : null); } } if ($this->_debug->debug && !empty($ignored)) { $this->_debug->info(sprintf( 'CONFIG: IGNORING these IMAP capabilities: %s', implode(', ', $ignored) )); } } $val->attach($this); break; } /* Nothing has changed. */ if (isset($this->_init[$key]) && ($this->_init[$key] === $val)) { return; } $this->_init[$key] = $val; } $this->changed = true; } /** * Initialize the Horde_Imap_Client_Cache object, if necessary. * * @param boolean $current If true, we are going to update the currently * selected mailbox. Add an additional check to * see if caching is available in current * mailbox. * * @return boolean Returns true if caching is enabled. */ protected function _initCache($current = false) { $c = $this->getParam('cache'); if (empty($c['fields'])) { return false; } if (is_null($this->_cache)) { if (isset($c['backend'])) { $backend = $c['backend']; } elseif (isset($c['cacheob'])) { /* Deprecated */ $backend = new Horde_Imap_Client_Cache_Backend_Cache($c); } else { return false; } $this->_cache = new Horde_Imap_Client_Cache(array( 'backend' => $backend, 'baseob' => $this, 'debug' => $this->_debug )); } return $current /* If UIDs are labeled as not sticky, don't cache since UIDs will * change on every access. */ ? !($this->_mailboxOb()->getStatus(Horde_Imap_Client::STATUS_UIDNOTSTICKY)) : true; } /** * Returns a value from the internal params array. * * @param string $key The param key. * * @return mixed The param value, or null if not found. */ public function getParam($key) { /* Passwords may be stored encrypted. */ switch ($key) { case 'password': if (isset($this->_params[$key]) && ($this->_params[$key] instanceof Horde_Imap_Client_Base_Password)) { return $this->_params[$key]->getPassword(); } // DEPRECATED if (!empty($this->_params['_passencrypt'])) { try { $secret = new Horde_Secret(); return $secret->read($this->_getEncryptKey(), $this->_params['password']); } catch (Exception $e) { return null; } } break; } return isset($this->_params[$key]) ? $this->_params[$key] : null; } /** * Sets a configuration parameter value. * * @param string $key The param key. * @param mixed $val The param value. */ public function setParam($key, $val) { switch ($key) { case 'password': if ($val instanceof Horde_Imap_Client_Base_Password) { break; } // DEPRECATED: Encrypt password. try { $encrypt_key = $this->_getEncryptKey(); if (strlen($encrypt_key)) { $secret = new Horde_Secret(); $val = $secret->write($encrypt_key, $val); $this->_params['_passencrypt'] = true; } } catch (Exception $e) {} break; } $this->_params[$key] = $val; $this->changed = true; } /** * Returns the Horde_Imap_Client_Cache object used, if available. * * @return mixed Either the cache object or null. */ public function getCache() { $this->_initCache(); return $this->_cache; } /** * Returns the correct IDs object for use with this driver. * * @param mixed $ids Either self::ALL, self::SEARCH_RES, self::LARGEST, * Horde_Imap_Client_Ids object, array, or sequence * string. * @param boolean $sequence Are $ids message sequence numbers? * * @return Horde_Imap_Client_Ids The IDs object. */ public function getIdsOb($ids = null, $sequence = false) { return new Horde_Imap_Client_Ids($ids, $sequence); } /** * Returns whether the IMAP server supports the given capability * (See RFC 3501 [6.1.1]). * * @deprecated Use $capability property instead. * * @param string $capability The capability string to query. * * @return mixed True if the server supports the queried capability, * false if it doesn't, or an array if the capability can * contain multiple values. */ public function queryCapability($capability) { try { $c = $this->_capability(); return ($out = $c->getParams($capability)) ? $out : $c->query($capability); } catch (Horde_Imap_Client_Exception $e) { return false; } } /** * Get CAPABILITY information from the IMAP server. * * @deprecated Use $capability property instead. * * @return array The capability array. * * @throws Horde_Imap_Client_Exception */ public function capability() { return $this->_capability()->toArray(); } /** * Query server capability. * * Required because internal code can't call capability via magic method * directly - it may not exist yet, the creation code may call capability * recursively, and __get() doesn't allow recursive calls to the same * property (chicken/egg issue). * * @return mixed The capability object if no arguments provided. If * arguments are provided, they are passed to the query() * method and this value is returned. * @throws Horde_Imap_Client_Exception */ protected function _capability() { if (!isset($this->_init['capability'])) { $this->_initCapability(); } return ($args = func_num_args()) ? $this->_init['capability']->query(func_get_arg(0), ($args > 1) ? func_get_arg(1) : null) : $this->_init['capability']; } /** * Retrieve capability information from the IMAP server. * * @throws Horde_Imap_Client_Exception */ abstract protected function _initCapability(); /** * Send a NOOP command (RFC 3501 [6.1.2]). * * @throws Horde_Imap_Client_Exception */ public function noop() { if (!$this->_connection) { // NOOP can be called in the unauthenticated state. $this->_connect(); } $this->_noop(); } /** * Send a NOOP command. * * @throws Horde_Imap_Client_Exception */ abstract protected function _noop(); /** * Get the NAMESPACE information from the IMAP server (RFC 2342). * * @param array $additional If the server supports namespaces, any * additional namespaces to add to the * namespace list that are not broadcast by * the server. The namespaces must be UTF-8 * strings. * @param array $opts Additional options: * - ob_return: (boolean) If true, returns a * Horde_Imap_Client_Namespace_List object instead of an * array. * * @return mixed A Horde_Imap_Client_Namespace_List object if * 'ob_return', is true. Otherwise, an array of namespace * objects (@deprecated) with the name as the key (UTF-8) * and the following values: *
     *  - delimiter: (string) The namespace delimiter.
     *  - hidden: (boolean) Is this a hidden namespace?
     *  - name: (string) The namespace name (UTF-8).
     *  - translation: (string) Returns the translated name of the namespace
     *                 (UTF-8). Requires RFC 5255 and a previous call to
     *                 setLanguage().
     *  - type: (integer) The namespace type. Either:
     *    - Horde_Imap_Client::NS_PERSONAL
     *    - Horde_Imap_Client::NS_OTHER
     *    - Horde_Imap_Client::NS_SHARED
     * 
* * @throws Horde_Imap_Client_Exception */ public function getNamespaces( array $additional = array(), array $opts = array() ) { $additional = array_map('strval', $additional); $sig = hash( 'md5', json_encode($additional) . intval(empty($opts['ob_return'])) ); if (isset($this->_init['namespace'][$sig])) { $ns = $this->_init['namespace'][$sig]; } else { $this->login(); $ns = $this->_getNamespaces(); /* Skip namespaces if we have already auto-detected them. Also, * hidden namespaces cannot be empty. */ $to_process = array_diff(array_filter($additional, 'strlen'), array_map('strlen', iterator_to_array($ns))); if (!empty($to_process)) { foreach ($this->listMailboxes($to_process, Horde_Imap_Client::MBOX_ALL, array('delimiter' => true)) as $key => $val) { $ob = new Horde_Imap_Client_Data_Namespace(); $ob->delimiter = $val['delimiter']; $ob->hidden = true; $ob->name = $key; $ob->type = $ob::NS_SHARED; $ns[$val] = $ob; } } if (!count($ns)) { /* This accurately determines the namespace information of the * base namespace if the NAMESPACE command is not supported. * See: RFC 3501 [6.3.8] */ $mbox = $this->listMailboxes('', Horde_Imap_Client::MBOX_ALL, array('delimiter' => true)); $first = reset($mbox); $ob = new Horde_Imap_Client_Data_Namespace(); $ob->delimiter = $first['delimiter']; $ns[''] = $ob; } $this->_init['namespace'][$sig] = $ns; $this->_setInit('namespace', $this->_init['namespace']); } if (!empty($opts['ob_return'])) { return $ns; } /* @todo Remove for 3.0 */ $out = array(); foreach ($ns as $key => $val) { $out[$key] = array( 'delimiter' => $val->delimiter, 'hidden' => $val->hidden, 'name' => $val->name, 'translation' => $val->translation, 'type' => $val->type ); } return $out; } /** * Get the NAMESPACE information from the IMAP server. * * @return Horde_Imap_Client_Namespace_List Namespace list object. * * @throws Horde_Imap_Client_Exception */ abstract protected function _getNamespaces(); /** * Display if connection to the server has been secured via TLS or SSL. * * @return boolean True if the IMAP connection is secured. */ public function isSecureConnection() { return ($this->_connection && $this->_connection->secure); } /** * Connect to the remote server. * * @throws Horde_Imap_Client_Exception */ abstract protected function _connect(); /** * Return a list of alerts that MUST be presented to the user (RFC 3501 * [7.1]). * * @deprecated Add an observer to the $alerts_ob property instead. * * @return array An array of alert messages. */ public function alerts() { $alerts = isset($this->_temp['alerts']) ? $this->_temp['alerts'] : array(); unset($this->_temp['alerts']); return $alerts; } /** * Login to the IMAP server. * * @throws Horde_Imap_Client_Exception */ public function login() { if (!$this->_isAuthenticated && $this->_login()) { if ($this->getParam('id')) { try { $this->sendID(); /* ID is queued - force sending the queued command. */ $this->_sendCmd($this->_pipeline()); } catch (Horde_Imap_Client_Exception_NoSupportExtension $e) { // Ignore if server doesn't support ID extension. } } if ($this->getParam('comparator')) { try { $this->setComparator(); } catch (Horde_Imap_Client_Exception_NoSupportExtension $e) { // Ignore if server doesn't support I18NLEVEL=2 } } } $this->_isAuthenticated = true; } /** * Login to the IMAP server. * * @return boolean Return true if global login tasks should be run. * * @throws Horde_Imap_Client_Exception */ abstract protected function _login(); /** * Logout from the IMAP server (see RFC 3501 [6.1.3]). */ public function logout() { if ($this->_isAuthenticated && $this->_connection->connected) { $this->_logout(); $this->_connection->close(); } $this->_connection = $this->_selected = null; $this->_isAuthenticated = false; $this->_mode = 0; } /** * Logout from the IMAP server (see RFC 3501 [6.1.3]). */ abstract protected function _logout(); /** * Send ID information to the IMAP server (RFC 2971). * * @param array $info Overrides the value of the 'id' param and sends * this information instead. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function sendID($info = null) { if (!$this->_capability('ID')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('ID'); } $this->_sendID(is_null($info) ? ($this->getParam('id') ?: array()) : $info); } /** * Send ID information to the IMAP server (RFC 2971). * * @param array $info The information to send to the server. * * @throws Horde_Imap_Client_Exception */ abstract protected function _sendID($info); /** * Return ID information from the IMAP server (RFC 2971). * * @return array An array of information returned, with the keys as the * 'field' and the values as the 'value'. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function getID() { if (!$this->_capability('ID')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('ID'); } return $this->_getID(); } /** * Return ID information from the IMAP server (RFC 2971). * * @return array An array of information returned, with the keys as the * 'field' and the values as the 'value'. * * @throws Horde_Imap_Client_Exception */ abstract protected function _getID(); /** * Sets the preferred language for server response messages (RFC 5255). * * @param array $langs Overrides the value of the 'lang' param and sends * this list of preferred languages instead. The * special string 'i-default' can be used to restore * the language to the server default. * * @return string The language accepted by the server, or null if the * default language is used. * * @throws Horde_Imap_Client_Exception */ public function setLanguage($langs = null) { $lang = null; if ($this->_capability('LANGUAGE')) { $lang = is_null($langs) ? $this->getParam('lang') : $langs; } return is_null($lang) ? null : $this->_setLanguage($lang); } /** * Sets the preferred language for server response messages (RFC 5255). * * @param array $langs The preferred list of languages. * * @return string The language accepted by the server, or null if the * default language is used. * * @throws Horde_Imap_Client_Exception */ abstract protected function _setLanguage($langs); /** * Gets the preferred language for server response messages (RFC 5255). * * @param array $list If true, return the list of available languages. * * @return mixed If $list is true, the list of languages available on the * server (may be empty). If false, the language used by * the server, or null if the default language is used. * * @throws Horde_Imap_Client_Exception */ public function getLanguage($list = false) { if (!$this->_capability('LANGUAGE')) { return $list ? array() : null; } return $this->_getLanguage($list); } /** * Gets the preferred language for server response messages (RFC 5255). * * @param array $list If true, return the list of available languages. * * @return mixed If $list is true, the list of languages available on the * server (may be empty). If false, the language used by * the server, or null if the default language is used. * * @throws Horde_Imap_Client_Exception */ abstract protected function _getLanguage($list); /** * Open a mailbox. * * @param mixed $mailbox The mailbox to open. Either a * Horde_Imap_Client_Mailbox object or a string * (UTF-8). * @param integer $mode The access mode. Either * - Horde_Imap_Client::OPEN_READONLY * - Horde_Imap_Client::OPEN_READWRITE * - Horde_Imap_Client::OPEN_AUTO * * @throws Horde_Imap_Client_Exception */ public function openMailbox($mailbox, $mode = Horde_Imap_Client::OPEN_AUTO) { $this->login(); $change = false; $mailbox = Horde_Imap_Client_Mailbox::get($mailbox); if ($mode == Horde_Imap_Client::OPEN_AUTO) { if (is_null($this->_selected) || !$mailbox->equals($this->_selected)) { $mode = Horde_Imap_Client::OPEN_READONLY; $change = true; } } else { $change = (is_null($this->_selected) || !$mailbox->equals($this->_selected) || ($mode != $this->_mode)); } if ($change) { $this->_openMailbox($mailbox, $mode); $this->_mailboxOb()->open = true; if ($this->_initCache(true)) { $this->_condstoreSync(); } } } /** * Open a mailbox. * * @param Horde_Imap_Client_Mailbox $mailbox The mailbox to open. * @param integer $mode The access mode. * * @throws Horde_Imap_Client_Exception */ abstract protected function _openMailbox(Horde_Imap_Client_Mailbox $mailbox, $mode); /** * Called when the selected mailbox is changed. * * @param mixed $mailbox The selected mailbox or null. * @param integer $mode The access mode. */ protected function _changeSelected($mailbox = null, $mode = null) { $this->_mode = $mode; if (is_null($mailbox)) { $this->_selected = null; } else { $this->_selected = clone $mailbox; $this->_mailboxOb()->reset(); } } /** * Return the Horde_Imap_Client_Base_Mailbox object. * * @param string $mailbox The mailbox name. Defaults to currently * selected mailbox. * * @return Horde_Imap_Client_Base_Mailbox Mailbox object. */ protected function _mailboxOb($mailbox = null) { $name = is_null($mailbox) ? strval($this->_selected) : strval($mailbox); if (!isset($this->_temp['mailbox_ob'][$name])) { $this->_temp['mailbox_ob'][$name] = new Horde_Imap_Client_Base_Mailbox(); } return $this->_temp['mailbox_ob'][$name]; } /** * Return the currently opened mailbox and access mode. * * @return mixed Null if no mailbox selected, or an array with two * elements: * - mailbox: (Horde_Imap_Client_Mailbox) The mailbox object. * - mode: (integer) Current mode. * * @throws Horde_Imap_Client_Exception */ public function currentMailbox() { return is_null($this->_selected) ? null : array( 'mailbox' => clone $this->_selected, 'mode' => $this->_mode ); } /** * Create a mailbox. * * @param mixed $mailbox The mailbox to create. Either a * Horde_Imap_Client_Mailbox object or a string * (UTF-8). * @param array $opts Additional options: * - special_use: (array) An array of special-use flags to mark the * mailbox with. The server MUST support RFC 6154. * * @throws Horde_Imap_Client_Exception */ public function createMailbox($mailbox, array $opts = array()) { $this->login(); if (!$this->_capability('CREATE-SPECIAL-USE')) { unset($opts['special_use']); } $this->_createMailbox(Horde_Imap_Client_Mailbox::get($mailbox), $opts); } /** * Create a mailbox. * * @param Horde_Imap_Client_Mailbox $mailbox The mailbox to create. * @param array $opts Additional options. See * createMailbox(). * * @throws Horde_Imap_Client_Exception */ abstract protected function _createMailbox(Horde_Imap_Client_Mailbox $mailbox, $opts); /** * Delete a mailbox. * * @param mixed $mailbox The mailbox to delete. Either a * Horde_Imap_Client_Mailbox object or a string * (UTF-8). * * @throws Horde_Imap_Client_Exception */ public function deleteMailbox($mailbox) { $this->login(); $mailbox = Horde_Imap_Client_Mailbox::get($mailbox); $this->_deleteMailbox($mailbox); $this->_deleteMailboxPost($mailbox); } /** * Delete a mailbox. * * @param Horde_Imap_Client_Mailbox $mailbox The mailbox to delete. * * @throws Horde_Imap_Client_Exception */ abstract protected function _deleteMailbox(Horde_Imap_Client_Mailbox $mailbox); /** * Actions to perform after a mailbox delete. * * @param Horde_Imap_Client_Mailbox $mailbox The deleted mailbox. */ protected function _deleteMailboxPost(Horde_Imap_Client_Mailbox $mailbox) { /* Delete mailbox caches. */ if ($this->_initCache()) { $this->_cache->deleteMailbox($mailbox); } unset($this->_temp['mailbox_ob'][strval($mailbox)]); /* Unsubscribe from mailbox. */ try { $this->subscribeMailbox($mailbox, false); } catch (Horde_Imap_Client_Exception $e) { // Ignore failed unsubscribe request } } /** * Rename a mailbox. * * @param mixed $old The old mailbox name. Either a * Horde_Imap_Client_Mailbox object or a string (UTF-8). * @param mixed $new The new mailbox name. Either a * Horde_Imap_Client_Mailbox object or a string (UTF-8). * * @throws Horde_Imap_Client_Exception */ public function renameMailbox($old, $new) { // Login will be handled by first listMailboxes() call. $old = Horde_Imap_Client_Mailbox::get($old); $new = Horde_Imap_Client_Mailbox::get($new); /* Check if old mailbox(es) were subscribed to. */ $base = $this->listMailboxes($old, Horde_Imap_Client::MBOX_SUBSCRIBED, array('delimiter' => true)); if (empty($base)) { $base = $this->listMailboxes($old, Horde_Imap_Client::MBOX_ALL, array('delimiter' => true)); $base = reset($base); $subscribed = array(); } else { $base = reset($base); $subscribed = array($base['mailbox']); } $all_mboxes = array($base['mailbox']); if (strlen($base['delimiter'])) { $search = $old->list_escape . $base['delimiter'] . '*'; $all_mboxes = array_merge($all_mboxes, $this->listMailboxes($search, Horde_Imap_Client::MBOX_ALL, array('flat' => true))); $subscribed = array_merge($subscribed, $this->listMailboxes($search, Horde_Imap_Client::MBOX_SUBSCRIBED, array('flat' => true))); } $this->_renameMailbox($old, $new); /* Delete mailbox actions. */ foreach ($all_mboxes as $val) { $this->_deleteMailboxPost($val); } foreach ($subscribed as $val) { try { $this->subscribeMailbox(new Horde_Imap_Client_Mailbox(substr_replace($val, $new, 0, strlen($old)))); } catch (Horde_Imap_Client_Exception $e) { // Ignore failed subscription requests } } } /** * Rename a mailbox. * * @param Horde_Imap_Client_Mailbox $old The old mailbox name. * @param Horde_Imap_Client_Mailbox $new The new mailbox name. * * @throws Horde_Imap_Client_Exception */ abstract protected function _renameMailbox(Horde_Imap_Client_Mailbox $old, Horde_Imap_Client_Mailbox $new); /** * Manage subscription status for a mailbox. * * @param mixed $mailbox The mailbox to [un]subscribe to. Either a * Horde_Imap_Client_Mailbox object or a string * (UTF-8). * @param boolean $subscribe True to subscribe, false to unsubscribe. * * @throws Horde_Imap_Client_Exception */ public function subscribeMailbox($mailbox, $subscribe = true) { $this->login(); $this->_subscribeMailbox(Horde_Imap_Client_Mailbox::get($mailbox), (bool)$subscribe); } /** * Manage subscription status for a mailbox. * * @param Horde_Imap_Client_Mailbox $mailbox The mailbox to [un]subscribe * to. * @param boolean $subscribe True to subscribe, false to * unsubscribe. * * @throws Horde_Imap_Client_Exception */ abstract protected function _subscribeMailbox(Horde_Imap_Client_Mailbox $mailbox, $subscribe); /** * Obtain a list of mailboxes matching a pattern. * * @param mixed $pattern The mailbox search pattern(s) (see RFC 3501 * [6.3.8] for the format). A UTF-8 string or an * array of strings. If a Horde_Imap_Client_Mailbox * object is given, it is escaped (i.e. wildcard * patterns are converted to return the miminal * number of matches possible). * @param integer $mode Which mailboxes to return. Either: * - Horde_Imap_Client::MBOX_SUBSCRIBED * Return subscribed mailboxes. * - Horde_Imap_Client::MBOX_SUBSCRIBED_EXISTS * Return subscribed mailboxes that exist on the server. * - Horde_Imap_Client::MBOX_UNSUBSCRIBED * Return unsubscribed mailboxes. * - Horde_Imap_Client::MBOX_ALL * Return all mailboxes regardless of subscription status. * - Horde_Imap_Client::MBOX_ALL_SUBSCRIBED (@since 2.23.0) * Return all mailboxes regardless of subscription status, and ensure * the '\subscribed' attribute is set if mailbox is subscribed * (implies 'attributes' option is true). * @param array $options Additional options: *
     *   - attributes: (boolean) If true, return attribute information under
     *                 the 'attributes' key.
     *                 DEFAULT: Do not return this information.
     *   - children: (boolean) Tell server to return children attribute
     *               information (\HasChildren, \HasNoChildren). Requires the
     *               LIST-EXTENDED extension to guarantee this information is
     *               returned. Server MAY return this attribute without this
     *               option, or if the CHILDREN extension is available, but it
     *               is not guaranteed.
     *               DEFAULT: false
     *   - flat: (boolean) If true, return a flat list of mailbox names only.
     *           Overrides the 'attributes' option.
     *           DEFAULT: Do not return flat list.
     *   - recursivematch: (boolean) Force the server to return information
     *                     about parent mailboxes that don't match other
     *                     selection options, but have some sub-mailboxes that
     *                     do. Information about children is returned in the
     *                     CHILDINFO extended data item ('extended'). Requires
     *                     the LIST-EXTENDED extension.
     *                     DEFAULT: false
     *   - remote: (boolean) Tell server to return mailboxes that reside on
     *             another server. Requires the LIST-EXTENDED extension.
     *             DEFAULT: false
     *   - special_use: (boolean) Tell server to return special-use attribute
     *                  information (see Horde_Imap_Client SPECIALUSE_*
     *                  constants). Server must support the SPECIAL-USE return
     *                  option for this setting to have any effect.
     *                  DEFAULT: false
     *   - status: (integer) Tell server to return status information. The
     *             value is a bitmask that may contain any of:
     *     - Horde_Imap_Client::STATUS_MESSAGES
     *     - Horde_Imap_Client::STATUS_RECENT
     *     - Horde_Imap_Client::STATUS_UIDNEXT
     *     - Horde_Imap_Client::STATUS_UIDVALIDITY
     *     - Horde_Imap_Client::STATUS_UNSEEN
     *     - Horde_Imap_Client::STATUS_HIGHESTMODSEQ
     *     DEFAULT: 0
     *   - sort: (boolean) If true, return a sorted list of mailboxes?
     *           DEFAULT: Do not sort the list.
     *   - sort_delimiter: (string) If 'sort' is true, this is the delimiter
     *                     used to sort the mailboxes.
     *                     DEFAULT: '.'
     * 
* * @return array If 'flat' option is true, the array values are a list * of Horde_Imap_Client_Mailbox objects. Otherwise, the * keys are UTF-8 mailbox names and the values are arrays * with these keys: * - attributes: (array) List of lower-cased attributes [only if * 'attributes' option is true]. * - delimiter: (string) The delimiter for the mailbox. * - extended: (TODO) TODO [only if 'recursivematch' option is true and * LIST-EXTENDED extension is supported on the server]. * - mailbox: (Horde_Imap_Client_Mailbox) The mailbox object. * - status: (array) See status() [only if 'status' option is true]. * * @throws Horde_Imap_Client_Exception */ public function listMailboxes($pattern, $mode = Horde_Imap_Client::MBOX_ALL, array $options = array()) { $this->login(); $pattern = is_array($pattern) ? array_unique($pattern) : array($pattern); /* Prepare patterns. */ $plist = array(); foreach ($pattern as $val) { if ($val instanceof Horde_Imap_Client_Mailbox) { $val = $val->list_escape; } $plist[] = Horde_Imap_Client_Mailbox::get(preg_replace( array("/\*{2,}/", "/\%{2,}/"), array('*', '%'), Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($val) ), true); } if (isset($options['special_use']) && !$this->_capability('SPECIAL-USE')) { unset($options['special_use']); } $ret = $this->_listMailboxes($plist, $mode, $options); if (!empty($options['status']) && !$this->_capability('LIST-STATUS')) { foreach ($this->status(array_keys($ret), $options['status']) as $key => $val) { $ret[$key]['status'] = $val; } } if (empty($options['sort'])) { return $ret; } $list_ob = new Horde_Imap_Client_Mailbox_List(empty($options['flat']) ? array_keys($ret) : $ret); $sorted = $list_ob->sort(array( 'delimiter' => empty($options['sort_delimiter']) ? '.' : $options['sort_delimiter'] )); if (!empty($options['flat'])) { return $sorted; } $out = array(); foreach ($sorted as $val) { $out[$val] = $ret[$val]; } return $out; } /** * Obtain a list of mailboxes matching a pattern. * * @param array $pattern The mailbox search patterns * (Horde_Imap_Client_Mailbox objects). * @param integer $mode Which mailboxes to return. * @param array $options Additional options. * * @return array See listMailboxes(). * * @throws Horde_Imap_Client_Exception */ abstract protected function _listMailboxes($pattern, $mode, $options); /** * Obtain status information for a mailbox. * * @param mixed $mailbox The mailbox(es) to query. Either a * Horde_Imap_Client_Mailbox object, a string * (UTF-8), or an array of objects/strings (since * 2.10.0). * @param integer $flags A bitmask of information requested from the * server. Allowed flags: *
     *   - Horde_Imap_Client::STATUS_MESSAGES
     *     Return key: messages
     *     Return format: (integer) The number of messages in the mailbox.
     *
     *   - Horde_Imap_Client::STATUS_RECENT
     *     Return key: recent
     *     Return format: (integer) The number of messages with the \Recent
     *                    flag set as currently reported in the mailbox
     *
     *   - Horde_Imap_Client::STATUS_RECENT_TOTAL
     *     Return key: recent_total
     *     Return format: (integer) The number of messages with the \Recent
     *                    flag set. This returns the total number of messages
     *                    that have been marked as recent in this mailbox
     *                    since the PHP process began. (since 2.12.0)
     *
     *   - Horde_Imap_Client::STATUS_UIDNEXT
     *     Return key: uidnext
     *     Return format: (integer) The next UID to be assigned in the
     *                    mailbox. Only returned if the server automatically
     *                    provides the data.
     *
     *   - Horde_Imap_Client::STATUS_UIDNEXT_FORCE
     *     Return key: uidnext
     *     Return format: (integer) The next UID to be assigned in the
     *                    mailbox. This option will always determine this
     *                    value, even if the server does not automatically
     *                    provide this data.
     *
     *   - Horde_Imap_Client::STATUS_UIDVALIDITY
     *     Return key: uidvalidity
     *     Return format: (integer) The unique identifier validity of the
     *                    mailbox.
     *
     *   - Horde_Imap_Client::STATUS_UNSEEN
     *     Return key: unseen
     *     Return format: (integer) The number of messages which do not have
     *                    the \Seen flag set.
     *
     *   - Horde_Imap_Client::STATUS_FIRSTUNSEEN
     *     Return key: firstunseen
     *     Return format: (integer) The sequence number of the first unseen
     *                    message in the mailbox.
     *
     *   - Horde_Imap_Client::STATUS_FLAGS
     *     Return key: flags
     *     Return format: (array) The list of defined flags in the mailbox
     *                    (all flags are in lowercase).
     *
     *   - Horde_Imap_Client::STATUS_PERMFLAGS
     *     Return key: permflags
     *     Return format: (array) The list of flags that a client can change
     *                    permanently (all flags are in lowercase).
     *
     *   - Horde_Imap_Client::STATUS_HIGHESTMODSEQ
     *     Return key: highestmodseq
     *     Return format: (integer) If the server supports the CONDSTORE
     *                    IMAP extension, this will be the highest
     *                    mod-sequence value of all messages in the mailbox.
     *                    Else 0 if CONDSTORE not available or the mailbox
     *                    does not support mod-sequences.
     *
     *   - Horde_Imap_Client::STATUS_SYNCMODSEQ
     *     Return key: syncmodseq
     *     Return format: (integer) If caching, and the server supports the
     *                    CONDSTORE IMAP extension, this is the cached
     *                    mod-sequence value of the mailbox when it was opened
     *                    for the first time in this access. Will be null if
     *                    not caching, CONDSTORE not available, or the mailbox
     *                    does not support mod-sequences.
     *
     *   - Horde_Imap_Client::STATUS_SYNCFLAGUIDS
     *     Return key: syncflaguids
     *     Return format: (Horde_Imap_Client_Ids) If caching, the server
     *                    supports the CONDSTORE IMAP extension, and the
     *                    mailbox contained cached data when opened for the
     *                    first time in this access, this is the list of UIDs
     *                    in which flags have changed since STATUS_SYNCMODSEQ.
     *
     *   - Horde_Imap_Client::STATUS_SYNCVANISHED
     *     Return key: syncvanished
     *     Return format: (Horde_Imap_Client_Ids) If caching, the server
     *                    supports the CONDSTORE IMAP extension, and the
     *                    mailbox contained cached data when opened for the
     *                    first time in this access, this is the list of UIDs
     *                    which have been deleted since STATUS_SYNCMODSEQ.
     *
     *   - Horde_Imap_Client::STATUS_UIDNOTSTICKY
     *     Return key: uidnotsticky
     *     Return format: (boolean) If the server supports the UIDPLUS IMAP
     *                    extension, and the queried mailbox does not support
     *                    persistent UIDs, this value will be true. In all
     *                    other cases, this value will be false.
     *
     *   - Horde_Imap_Client::STATUS_FORCE_REFRESH
     *     Normally, the status information will be cached for a given
     *     mailbox. Since most PHP requests are generally less than a second,
     *     this is fine. However, if your script is long running, the status
     *     information may not be up-to-date. Specifying this flag will ensure
     *     that the server is always polled for the current mailbox status
     *     before results are returned. (since 2.14.0)
     *
     *   - Horde_Imap_Client::STATUS_ALL (DEFAULT)
     *     Shortcut to return 'messages', 'recent', 'uidnext', 'uidvalidity',
     *     and 'unseen' values.
     * 
     * @param array $opts     Additional options:
     * 
     *   - sort: (boolean) If true, sort the list of mailboxes? (since 2.10.0)
     *           DEFAULT: Do not sort the list.
     *   - sort_delimiter: (string) If 'sort' is true, this is the delimiter
     *                     used to sort the mailboxes. (since 2.10.0)
     *                     DEFAULT: '.'
     * 
* * @return array If $mailbox contains multiple mailboxes, an array with * keys being the UTF-8 mailbox name and values as arrays * containing the requested keys (see above). * Otherwise, an array with keys as the requested keys (see * above) and values as the key data. * * @throws Horde_Imap_Client_Exception */ public function status($mailbox, $flags = Horde_Imap_Client::STATUS_ALL, array $opts = array()) { $opts = array_merge(array( 'sort' => false, 'sort_delimiter' => '.' ), $opts); $this->login(); if (is_array($mailbox)) { if (empty($mailbox)) { return array(); } $ret_array = true; } else { $mailbox = array($mailbox); $ret_array = false; } $mlist = array_map(array('Horde_Imap_Client_Mailbox', 'get'), $mailbox); $unselected_flags = array( 'messages' => Horde_Imap_Client::STATUS_MESSAGES, 'recent' => Horde_Imap_Client::STATUS_RECENT, 'uidnext' => Horde_Imap_Client::STATUS_UIDNEXT, 'uidvalidity' => Horde_Imap_Client::STATUS_UIDVALIDITY, 'unseen' => Horde_Imap_Client::STATUS_UNSEEN ); if (!$this->statuscache) { $flags |= Horde_Imap_Client::STATUS_FORCE_REFRESH; } if ($flags & Horde_Imap_Client::STATUS_ALL) { foreach ($unselected_flags as $val) { $flags |= $val; } } $master = $ret = array(); /* Catch flags that are not supported. */ if (($flags & Horde_Imap_Client::STATUS_HIGHESTMODSEQ) && !$this->_capability()->isEnabled('CONDSTORE')) { $master['highestmodseq'] = 0; $flags &= ~Horde_Imap_Client::STATUS_HIGHESTMODSEQ; } if (($flags & Horde_Imap_Client::STATUS_UIDNOTSTICKY) && !$this->_capability('UIDPLUS')) { $master['uidnotsticky'] = false; $flags &= ~Horde_Imap_Client::STATUS_UIDNOTSTICKY; } /* UIDNEXT return options. */ if ($flags & Horde_Imap_Client::STATUS_UIDNEXT_FORCE) { $flags |= Horde_Imap_Client::STATUS_UIDNEXT; } foreach ($mlist as $val) { $name = strval($val); $tmp_flags = $flags; if ($val->equals($this->_selected)) { /* Check if already in mailbox. */ $opened = true; if ($flags & Horde_Imap_Client::STATUS_FORCE_REFRESH) { $this->noop(); } } else { /* A list of STATUS options (other than those handled directly * below) that require the mailbox to be explicitly opened. */ $opened = ($flags & Horde_Imap_Client::STATUS_FIRSTUNSEEN) || ($flags & Horde_Imap_Client::STATUS_FLAGS) || ($flags & Horde_Imap_Client::STATUS_PERMFLAGS) || ($flags & Horde_Imap_Client::STATUS_UIDNOTSTICKY) || /* Force mailboxes containing wildcards to be accessed via * STATUS so that wildcards do not return a bunch of * mailboxes in the LIST-STATUS response. */ (strpbrk($name, '*%') !== false); } $ret[$name] = $master; $ptr = &$ret[$name]; /* STATUS_PERMFLAGS requires a read/write mailbox. */ if ($flags & Horde_Imap_Client::STATUS_PERMFLAGS) { $this->openMailbox($val, Horde_Imap_Client::OPEN_READWRITE); $opened = true; } /* Handle SYNC related return options. These require the mailbox * to be opened at least once. */ if ($flags & Horde_Imap_Client::STATUS_SYNCMODSEQ) { $this->openMailbox($val); $ptr['syncmodseq'] = $this->_mailboxOb($val)->getStatus(Horde_Imap_Client::STATUS_SYNCMODSEQ); $tmp_flags &= ~Horde_Imap_Client::STATUS_SYNCMODSEQ; $opened = true; } if ($flags & Horde_Imap_Client::STATUS_SYNCFLAGUIDS) { $this->openMailbox($val); $ptr['syncflaguids'] = $this->getIdsOb($this->_mailboxOb($val)->getStatus(Horde_Imap_Client::STATUS_SYNCFLAGUIDS)); $tmp_flags &= ~Horde_Imap_Client::STATUS_SYNCFLAGUIDS; $opened = true; } if ($flags & Horde_Imap_Client::STATUS_SYNCVANISHED) { $this->openMailbox($val); $ptr['syncvanished'] = $this->getIdsOb($this->_mailboxOb($val)->getStatus(Horde_Imap_Client::STATUS_SYNCVANISHED)); $tmp_flags &= ~Horde_Imap_Client::STATUS_SYNCVANISHED; $opened = true; } /* Handle RECENT_TOTAL option. */ if ($flags & Horde_Imap_Client::STATUS_RECENT_TOTAL) { $this->openMailbox($val); $ptr['recent_total'] = $this->_mailboxOb($val)->getStatus(Horde_Imap_Client::STATUS_RECENT_TOTAL); $tmp_flags &= ~Horde_Imap_Client::STATUS_RECENT_TOTAL; $opened = true; } if ($opened) { if ($tmp_flags) { $tmp = $this->_status(array($val), $tmp_flags); $ptr += reset($tmp); } } else { $to_process[] = $val; } } if ($flags && !empty($to_process)) { if ((count($to_process) > 1) && $this->_capability('LIST-STATUS')) { foreach ($this->listMailboxes($to_process, Horde_Imap_Client::MBOX_ALL, array('status' => $flags)) as $key => $val) { if (isset($val['status'])) { $ret[$key] += $val['status']; } } } else { foreach ($this->_status($to_process, $flags) as $key => $val) { $ret[$key] += $val; } } } if (!$opts['sort'] || (count($ret) === 1)) { return $ret_array ? $ret : reset($ret); } $list_ob = new Horde_Imap_Client_Mailbox_List(array_keys($ret)); $sorted = $list_ob->sort(array( 'delimiter' => $opts['sort_delimiter'] )); $out = array(); foreach ($sorted as $val) { $out[$val] = $ret[$val]; } return $out; } /** * Obtain status information for mailboxes. * * @param array $mboxes The list of mailbox objects to query. * @param integer $flags A bitmask of information requested from the * server. * * @return array See array return for status(). * * @throws Horde_Imap_Client_Exception */ abstract protected function _status($mboxes, $flags); /** * Perform a STATUS call on multiple mailboxes at the same time. * * This method leverages the LIST-EXTENDED and LIST-STATUS extensions on * the IMAP server to improve the efficiency of this operation. * * @deprecated Use status() instead. * * @param array $mailboxes The mailboxes to query. Either * Horde_Imap_Client_Mailbox objects, strings * (UTF-8), or a combination of the two. * @param integer $flags See status(). * @param array $opts Additional options: * - sort: (boolean) If true, sort the list of mailboxes? * DEFAULT: Do not sort the list. * - sort_delimiter: (string) If 'sort' is true, this is the delimiter * used to sort the mailboxes. * DEFAULT: '.' * * @return array An array with the keys as the mailbox names (UTF-8) and * the values as arrays with the requested keys (from the * mask given in $flags). */ public function statusMultiple($mailboxes, $flags = Horde_Imap_Client::STATUS_ALL, array $opts = array()) { return $this->status($mailboxes, $flags, $opts); } /** * Append message(s) to a mailbox. * * @param mixed $mailbox The mailbox to append the message(s) to. Either * a Horde_Imap_Client_Mailbox object or a string * (UTF-8). * @param array $data The message data to append, along with * additional options. An array of arrays with * each embedded array having the following * entries: *
     *   - data: (mixed) The data to append. If a string or a stream resource,
     *           this will be used as the entire contents of a single message.
     *           If an array, will catenate all given parts into a single
     *           message. This array contains one or more arrays with
     *           two keys:
     *     - t: (string) Either 'url' or 'text'.
     *     - v: (mixed) If 't' is 'url', this is the IMAP URL to the message
     *          part to append. If 't' is 'text', this is either a string or
     *          resource representation of the message part data.
     *     DEFAULT: NONE (entry is MANDATORY)
     *   - flags: (array) An array of flags/keywords to set on the appended
     *            message.
     *            DEFAULT: Only the \Recent flag is set.
     *   - internaldate: (DateTime) The internaldate to set for the appended
     *                   message.
     *                   DEFAULT: internaldate will be the same date as when
     *                   the message was appended.
     * 
* @param array $options Additonal options: *
     *   - create: (boolean) Try to create $mailbox if it does not exist?
     *             DEFAULT: No.
     * 
* * @return Horde_Imap_Client_Ids The UIDs of the appended messages. * * @throws Horde_Imap_Client_Exception */ public function append($mailbox, $data, array $options = array()) { $this->login(); $mailbox = Horde_Imap_Client_Mailbox::get($mailbox); $ret = $this->_append($mailbox, $data, $options); if ($ret instanceof Horde_Imap_Client_Ids) { return $ret; } $uids = $this->getIdsOb(); foreach ($data as $val) { if (is_resource($val['data'])) { rewind($val['data']); } $uids->add($this->_getUidByMessageId( $mailbox, Horde_Mime_Headers::parseHeaders($val['data'])->getHeader('Message-ID') )); } return $uids; } /** * Append message(s) to a mailbox. * * @param Horde_Imap_Client_Mailbox $mailbox The mailbox to append the * message(s) to. * @param array $data The message data. * @param array $options Additional options. * * @return mixed A Horde_Imap_Client_Ids object containing the UIDs of * the appended messages (if server supports UIDPLUS * extension) or true. * * @throws Horde_Imap_Client_Exception */ abstract protected function _append(Horde_Imap_Client_Mailbox $mailbox, $data, $options); /** * Request a checkpoint of the currently selected mailbox (RFC 3501 * [6.4.1]). * * @throws Horde_Imap_Client_Exception */ public function check() { // CHECK only useful if we are already authenticated. if ($this->_isAuthenticated) { $this->_check(); } } /** * Request a checkpoint of the currently selected mailbox. * * @throws Horde_Imap_Client_Exception */ abstract protected function _check(); /** * Close the connection to the currently selected mailbox, optionally * expunging all deleted messages (RFC 3501 [6.4.2]). * * @param array $options Additional options: * - expunge: (boolean) Expunge all messages flagged as deleted? * DEFAULT: No * * @throws Horde_Imap_Client_Exception */ public function close(array $options = array()) { // This check catches the non-logged in case. if (is_null($this->_selected)) { return; } /* If we are caching, search for deleted messages. */ if (!empty($options['expunge']) && $this->_initCache(true)) { /* Make sure mailbox is read-write to expunge. */ $this->openMailbox($this->_selected, Horde_Imap_Client::OPEN_READWRITE); if ($this->_mode == Horde_Imap_Client::OPEN_READONLY) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Cannot expunge read-only mailbox."), Horde_Imap_Client_Exception::MAILBOX_READONLY ); } $search_query = new Horde_Imap_Client_Search_Query(); $search_query->flag(Horde_Imap_Client::FLAG_DELETED, true); $search_res = $this->search($this->_selected, $search_query); $mbox = $this->_selected; } else { $search_res = null; } $this->_close($options); $this->_selected = null; $this->_mode = 0; if (!is_null($search_res)) { $this->_deleteMsgs($mbox, $search_res['match']); } } /** * Close the connection to the currently selected mailbox, optionally * expunging all deleted messages (RFC 3501 [6.4.2]). * * @param array $options Additional options. * * @throws Horde_Imap_Client_Exception */ abstract protected function _close($options); /** * Expunge deleted messages from the given mailbox. * * @param mixed $mailbox The mailbox to expunge. Either a * Horde_Imap_Client_Mailbox object or a string * (UTF-8). * @param array $options Additional options: * - delete: (boolean) If true, will flag all messages in 'ids' as * deleted (since 2.10.0). * DEFAULT: false * - ids: (Horde_Imap_Client_Ids) A list of messages to expunge. These * messages must already be flagged as deleted (unless 'delete' * is true). * DEFAULT: All messages marked as deleted will be expunged. * - list: (boolean) If true, returns the list of expunged messages * (UIDs only). * DEFAULT: false * * @return Horde_Imap_Client_Ids If 'list' option is true, returns the * UID list of expunged messages. * * @throws Horde_Imap_Client_Exception */ public function expunge($mailbox, array $options = array()) { // Open mailbox call will handle the login. $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_READWRITE); /* Don't expunge if the mailbox is readonly. */ if ($this->_mode == Horde_Imap_Client::OPEN_READONLY) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Cannot expunge read-only mailbox."), Horde_Imap_Client_Exception::MAILBOX_READONLY ); } if (empty($options['ids'])) { $options['ids'] = $this->getIdsOb(Horde_Imap_Client_Ids::ALL); } elseif ($options['ids']->isEmpty()) { return $this->getIdsOb(); } return $this->_expunge($options); } /** * Expunge all deleted messages from the given mailbox. * * @param array $options Additional options. * * @return Horde_Imap_Client_Ids If 'list' option is true, returns the * list of expunged messages. * * @throws Horde_Imap_Client_Exception */ abstract protected function _expunge($options); /** * Search a mailbox. * * @param mixed $mailbox The mailbox to search. * Either a * Horde_Imap_Client_Mailbox * object or a string * (UTF-8). * @param Horde_Imap_Client_Search_Query $query The search query. * Defaults to an ALL * search. * @param array $options Additional options: *
     *   - nocache: (boolean) Don't cache the results.
     *              DEFAULT: false (results cached, if possible)
     *   - partial: (mixed) The range of results to return (message sequence
     *              numbers) Only a single range is supported (represented by
     *              the minimum and maximum values contained in the range
     *              given).
     *              DEFAULT: All messages are returned.
     *   - results: (array) The data to return. Consists of zero or more of
     *              the following flags:
     *     - Horde_Imap_Client::SEARCH_RESULTS_COUNT
     *     - Horde_Imap_Client::SEARCH_RESULTS_MATCH (DEFAULT)
     *     - Horde_Imap_Client::SEARCH_RESULTS_MAX
     *     - Horde_Imap_Client::SEARCH_RESULTS_MIN
     *     - Horde_Imap_Client::SEARCH_RESULTS_SAVE
     *     - Horde_Imap_Client::SEARCH_RESULTS_RELEVANCY
     *   - sequence: (boolean) If true, returns an array of sequence numbers.
     *               DEFAULT: Returns an array of UIDs
     *   - sort: (array) Sort the returned list of messages. Multiple sort
     *           criteria can be specified. Any sort criteria can be sorted in
     *           reverse order (instead of the default ascending order) by
     *           adding a Horde_Imap_Client::SORT_REVERSE element to the array
     *           directly before adding the sort element. The following sort
     *           criteria are available:
     *     - Horde_Imap_Client::SORT_ARRIVAL
     *     - Horde_Imap_Client::SORT_CC
     *     - Horde_Imap_Client::SORT_DATE
     *     - Horde_Imap_Client::SORT_DISPLAYFROM
     *       On servers that don't support SORT=DISPLAY, this criteria will
     *       fallback to doing client-side sorting.
     *     - Horde_Imap_Client::SORT_DISPLAYFROM_FALLBACK
     *       On servers that don't support SORT=DISPLAY, this criteria will
     *       fallback to Horde_Imap_Client::SORT_FROM [since 2.4.0].
     *     - Horde_Imap_Client::SORT_DISPLAYTO
     *       On servers that don't support SORT=DISPLAY, this criteria will
     *       fallback to doing client-side sorting.
     *     - Horde_Imap_Client::SORT_DISPLAYTO_FALLBACK
     *       On servers that don't support SORT=DISPLAY, this criteria will
     *       fallback to Horde_Imap_Client::SORT_TO [since 2.4.0].
     *     - Horde_Imap_Client::SORT_FROM
     *     - Horde_Imap_Client::SORT_SEQUENCE
     *     - Horde_Imap_Client::SORT_SIZE
     *     - Horde_Imap_Client::SORT_SUBJECT
     *     - Horde_Imap_Client::SORT_TO
     *
     *     [On servers that support SEARCH=FUZZY, this criteria is also
     *     available:]
     *     - Horde_Imap_Client::SORT_RELEVANCY
     * 
* * @return array An array with the following keys: *
     *   - count: (integer) The number of messages that match the search
     *            criteria. Always returned.
     *   - match: (Horde_Imap_Client_Ids) The IDs that match $criteria, sorted
     *            if the 'sort' modifier was set. Returned if
     *            Horde_Imap_Client::SEARCH_RESULTS_MATCH is set.
     *   - max: (integer) The UID (default) or message sequence number (if
     *          'sequence' is true) of the highest message that satisifies
     *          $criteria. Returns null if no matches found. Returned if
     *          Horde_Imap_Client::SEARCH_RESULTS_MAX is set.
     *   - min: (integer) The UID (default) or message sequence number (if
     *          'sequence' is true) of the lowest message that satisifies
     *          $criteria. Returns null if no matches found. Returned if
     *          Horde_Imap_Client::SEARCH_RESULTS_MIN is set.
     *   - modseq: (integer) The highest mod-sequence for all messages being
     *            returned. Returned if 'sort' is false, the search query
     *            includes a MODSEQ command, and the server supports the
     *            CONDSTORE IMAP extension.
     *   - relevancy: (array) The list of relevancy scores. Returned if
     *                Horde_Imap_Client::SEARCH_RESULTS_RELEVANCY is set and
     *                the server supports FUZZY search matching.
     *   - save: (boolean) Whether the search results were saved. Returned if
     *           Horde_Imap_Client::SEARCH_RESULTS_SAVE is set.
     * 
* * @throws Horde_Imap_Client_Exception */ public function search($mailbox, $query = null, array $options = array()) { $this->login(); if (empty($options['results'])) { $options['results'] = array( Horde_Imap_Client::SEARCH_RESULTS_MATCH, Horde_Imap_Client::SEARCH_RESULTS_COUNT ); } elseif (!in_array(Horde_Imap_Client::SEARCH_RESULTS_COUNT, $options['results'])) { $options['results'][] = Horde_Imap_Client::SEARCH_RESULTS_COUNT; } // Default to an ALL search. if (is_null($query)) { $query = new Horde_Imap_Client_Search_Query(); } // Check for SEARCHRES support. if ((($pos = array_search(Horde_Imap_Client::SEARCH_RESULTS_SAVE, $options['results'])) !== false) && !$this->_capability('SEARCHRES')) { unset($options['results'][$pos]); } // Check for SORT-related options. if (!empty($options['sort'])) { foreach ($options['sort'] as $key => $val) { switch ($val) { case Horde_Imap_Client::SORT_DISPLAYFROM_FALLBACK: $options['sort'][$key] = $this->_capability('SORT', 'DISPLAY') ? Horde_Imap_Client::SORT_DISPLAYFROM : Horde_Imap_Client::SORT_FROM; break; case Horde_Imap_Client::SORT_DISPLAYTO_FALLBACK: $options['sort'][$key] = $this->_capability('SORT', 'DISPLAY') ? Horde_Imap_Client::SORT_DISPLAYTO : Horde_Imap_Client::SORT_TO; break; } } } /* Default search results. */ $default_ret = array( 'count' => 0, 'match' => $this->getIdsOb(), 'max' => null, 'min' => null, 'relevancy' => array() ); /* Build search query. */ $squery = $query->build($this); /* Check for query contents. If empty, this means that the query * object has identified that this query can NEVER return any results. * Immediately return now. */ if (!count($squery['query'])) { return $default_ret; } // Check for supported charset. if (!is_null($squery['charset']) && ($this->search_charset->query($squery['charset'], true) === false)) { foreach ($this->search_charset->charsets as $val) { try { $new_query = clone $query; $new_query->charset($val); break; } catch (Horde_Imap_Client_Exception_SearchCharset $e) { unset($new_query); } } if (!isset($new_query)) { throw $e; } $query = $new_query; $squery = $query->build($this); } // Store query in $options array to pass to child method. $options['_query'] = $squery; /* RFC 6203: MUST NOT request relevancy results if we are not using * FUZZY searching. */ if (in_array(Horde_Imap_Client::SEARCH_RESULTS_RELEVANCY, $options['results']) && !in_array('SEARCH=FUZZY', $squery['exts_used'])) { throw new InvalidArgumentException('Cannot specify RELEVANCY results if not doing a FUZZY search.'); } /* Check for partial matching. */ if (!empty($options['partial'])) { $pids = $this->getIdsOb($options['partial'], true)->range_string; if (!strlen($pids)) { throw new InvalidArgumentException('Cannot specify empty sequence range for a PARTIAL search.'); } if (strpos($pids, ':') === false) { $pids .= ':' . $pids; } $options['partial'] = $pids; } /* Optimization - if query is just for a count of either RECENT or * ALL messages, we can send status information instead. Can't * optimize with unseen queries because we may cause an infinite loop * between here and the status() call. */ if ((count($options['results']) === 1) && (reset($options['results']) == Horde_Imap_Client::SEARCH_RESULTS_COUNT)) { switch ($squery['query']) { case 'ALL': $ret = $this->status($mailbox, Horde_Imap_Client::STATUS_MESSAGES); return array('count' => $ret['messages']); case 'RECENT': $ret = $this->status($mailbox, Horde_Imap_Client::STATUS_RECENT); return array('count' => $ret['recent']); } } $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO); /* Take advantage of search result caching. If CONDSTORE available, * we can cache all queries and invalidate the cache when the MODSEQ * changes. If CONDSTORE not available, we can only store queries * that don't involve flags. We store results by hashing the options * array. */ $cache = null; if (empty($options['nocache']) && $this->_initCache(true) && ($this->_capability()->isEnabled('CONDSTORE') || !$query->flagSearch())) { $cache = $this->_getSearchCache('search', $options); if (isset($cache['data'])) { if (isset($cache['data']['match'])) { $cache['data']['match'] = $this->getIdsOb($cache['data']['match']); } return $cache['data']; } } /* Optimization: Catch when there are no messages in a mailbox. */ $status_res = $this->status($this->_selected, Horde_Imap_Client::STATUS_MESSAGES | Horde_Imap_Client::STATUS_HIGHESTMODSEQ); if ($status_res['messages'] || in_array(Horde_Imap_Client::SEARCH_RESULTS_SAVE, $options['results'])) { /* RFC 7162 [3.1.2.2] - trying to do a MODSEQ SEARCH on a mailbox * that doesn't support it will return BAD. */ if (in_array('CONDSTORE', $squery['exts']) && !$this->_mailboxOb()->getStatus(Horde_Imap_Client::STATUS_HIGHESTMODSEQ)) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Mailbox does not support mod-sequences."), Horde_Imap_Client_Exception::MBOXNOMODSEQ ); } $ret = $this->_search($query, $options); } else { $ret = $default_ret; if (isset($status_res['highestmodseq'])) { $ret['modseq'] = $status_res['highestmodseq']; } } if ($cache) { $save = $ret; if (isset($save['match'])) { $save['match'] = strval($ret['match']); } $this->_setSearchCache($save, $cache); } return $ret; } /** * Search a mailbox. * * @param object $query The search query. * @param array $options Additional options. The '_query' key contains * the value of $query->build(). * * @return Horde_Imap_Client_Ids An array of IDs. * * @throws Horde_Imap_Client_Exception */ abstract protected function _search($query, $options); /** * Set the comparator to use for searching/sorting (RFC 5255). * * @param string $comparator The comparator string (see RFC 4790 [3.1] - * "collation-id" - for format). The reserved * string 'default' can be used to select * the default comparator. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function setComparator($comparator = null) { $comp = is_null($comparator) ? $this->getParam('comparator') : $comparator; if (is_null($comp)) { return; } $this->login(); if (!$this->_capability('I18NLEVEL', '2')) { throw new Horde_Imap_Client_Exception_NoSupportExtension( 'I18NLEVEL', 'The IMAP server does not support changing SEARCH/SORT comparators.' ); } $this->_setComparator($comp); } /** * Set the comparator to use for searching/sorting (RFC 5255). * * @param string $comparator The comparator string (see RFC 4790 [3.1] - * "collation-id" - for format). The reserved * string 'default' can be used to select * the default comparator. * * @throws Horde_Imap_Client_Exception */ abstract protected function _setComparator($comparator); /** * Get the comparator used for searching/sorting (RFC 5255). * * @return mixed Null if the default comparator is being used, or an * array of comparator information (see RFC 5255 [4.8]). * * @throws Horde_Imap_Client_Exception */ public function getComparator() { $this->login(); return $this->_capability('I18NLEVEL', '2') ? $this->_getComparator() : null; } /** * Get the comparator used for searching/sorting (RFC 5255). * * @return mixed Null if the default comparator is being used, or an * array of comparator information (see RFC 5255 [4.8]). * * @throws Horde_Imap_Client_Exception */ abstract protected function _getComparator(); /** * Thread sort a given list of messages (RFC 5256). * * @param mixed $mailbox The mailbox to query. Either a * Horde_Imap_Client_Mailbox object or a string * (UTF-8). * @param array $options Additional options: *
     *   - criteria: (mixed) The following thread criteria are available:
     *     - Horde_Imap_Client::THREAD_ORDEREDSUBJECT
     *     - Horde_Imap_Client::THREAD_REFERENCES
     *     - Horde_Imap_Client::THREAD_REFS
     *       Other algorithms can be explicitly specified by passing the IMAP
     *       thread algorithm in as a string value.
     *     DEFAULT: Horde_Imap_Client::THREAD_ORDEREDSUBJECT
     *   - search: (Horde_Imap_Client_Search_Query) The search query.
     *             DEFAULT: All messages in mailbox included in thread sort.
     *   - sequence: (boolean) If true, each message is stored and referred to
     *               by its message sequence number.
     *               DEFAULT: Stored/referred to by UID.
     * 
* * @return Horde_Imap_Client_Data_Thread A thread data object. * * @throws Horde_Imap_Client_Exception */ public function thread($mailbox, array $options = array()) { // Open mailbox call will handle the login. $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO); /* Take advantage of search result caching. If CONDSTORE available, * we can cache all queries and invalidate the cache when the MODSEQ * changes. If CONDSTORE not available, we can only store queries * that don't involve flags. See search() for similar caching. */ $cache = null; if ($this->_initCache(true) && ($this->_capability()->isEnabled('CONDSTORE') || empty($options['search']) || !$options['search']->flagSearch())) { $cache = $this->_getSearchCache('thread', $options); if (isset($cache['data']) && ($cache['data'] instanceof Horde_Imap_Client_Data_Thread)) { return $cache['data']; } } $status_res = $this->status($this->_selected, Horde_Imap_Client::STATUS_MESSAGES); $ob = $status_res['messages'] ? $this->_thread($options) : new Horde_Imap_Client_Data_Thread(array(), empty($options['sequence']) ? 'uid' : 'sequence'); if ($cache) { $this->_setSearchCache($ob, $cache); } return $ob; } /** * Thread sort a given list of messages (RFC 5256). * * @param array $options Additional options. See thread(). * * @return Horde_Imap_Client_Data_Thread A thread data object. * * @throws Horde_Imap_Client_Exception */ abstract protected function _thread($options); /** * Fetch message data (see RFC 3501 [6.4.5]). * * @param mixed $mailbox The mailbox to search. * Either a * Horde_Imap_Client_Mailbox * object or a string (UTF-8). * @param Horde_Imap_Client_Fetch_Query $query Fetch query object. * @param array $options Additional options: * - changedsince: (integer) Only return messages that have a * mod-sequence larger than this value. This option * requires the CONDSTORE IMAP extension (if not present, * this value is ignored). Additionally, the mailbox * must support mod-sequences or an exception will be * thrown. If valid, this option implicity adds the * mod-sequence fetch criteria to the fetch command. * DEFAULT: Mod-sequence values are ignored. * - exists: (boolean) Ensure that all ids returned exist on the server. * If false, the list of ids returned in the results object * is not guaranteed to reflect the current state of the * remote mailbox. * DEFAULT: false * - ids: (Horde_Imap_Client_Ids) A list of messages to fetch data from. * DEFAULT: All messages in $mailbox will be fetched. * - nocache: (boolean) If true, will not cache the results (previously * cached data will still be used to generate results) [since * 2.8.0]. * DEFAULT: false * * @return Horde_Imap_Client_Fetch_Results A results object. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function fetch($mailbox, $query, array $options = array()) { try { $ret = $this->_fetchWrapper($mailbox, $query, $options); unset($this->_temp['fetch_nocache']); return $ret; } catch (Exception $e) { unset($this->_temp['fetch_nocache']); throw $e; } } /** * Wrapper for fetch() to allow internal state to be reset on exception. * * @internal * @see fetch() */ private function _fetchWrapper($mailbox, $query, $options) { $this->login(); $query = clone $query; $cache_array = $header_cache = $new_query = array(); if (empty($options['ids'])) { $options['ids'] = $this->getIdsOb(Horde_Imap_Client_Ids::ALL); } elseif ($options['ids']->isEmpty()) { return new Horde_Imap_Client_Fetch_Results($this->_fetchDataClass); } elseif ($options['ids']->search_res && !$this->_capability('SEARCHRES')) { /* SEARCHRES requires server support. */ throw new Horde_Imap_Client_Exception_NoSupportExtension('SEARCHRES'); } $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO); $mbox_ob = $this->_mailboxOb(); if (!empty($options['nocache'])) { $this->_temp['fetch_nocache'] = true; } $cf = $this->_initCache(true) ? $this->_cacheFields() : array(); if (!empty($cf)) { /* If using cache, we store by UID so we need to return UIDs. */ $query->uid(); } $modseq_check = !empty($options['changedsince']); if ($query->contains(Horde_Imap_Client::FETCH_MODSEQ)) { if (!$this->_capability()->isEnabled('CONDSTORE')) { unset($query[Horde_Imap_Client::FETCH_MODSEQ]); } elseif (empty($options['changedsince'])) { $modseq_check = true; } } if ($modseq_check && !$mbox_ob->getStatus(Horde_Imap_Client::STATUS_HIGHESTMODSEQ)) { /* RFC 7162 [3.1.2.2] - trying to do a MODSEQ FETCH on a mailbox * that doesn't support it will return BAD. */ throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Mailbox does not support mod-sequences."), Horde_Imap_Client_Exception::MBOXNOMODSEQ ); } /* Determine if caching is available and if anything in $query is * cacheable. */ foreach ($cf as $k => $v) { if (isset($query[$k])) { switch ($k) { case Horde_Imap_Client::FETCH_ENVELOPE: case Horde_Imap_Client::FETCH_FLAGS: case Horde_Imap_Client::FETCH_IMAPDATE: case Horde_Imap_Client::FETCH_SIZE: case Horde_Imap_Client::FETCH_STRUCTURE: $cache_array[$k] = $v; break; case Horde_Imap_Client::FETCH_HEADERS: $this->_temp['headers_caching'] = array(); foreach ($query[$k] as $key => $val) { /* Only cache if directly requested. Iterate through * requests to ensure at least one can be cached. */ if (!empty($val['cache']) && !empty($val['peek'])) { $cache_array[$k] = $v; ksort($val); $header_cache[$key] = hash('md5', serialize($val)); } } break; } } } $ret = new Horde_Imap_Client_Fetch_Results( $this->_fetchDataClass, $options['ids']->sequence ? Horde_Imap_Client_Fetch_Results::SEQUENCE : Horde_Imap_Client_Fetch_Results::UID ); /* If nothing is cacheable, we can do a straight search. */ if (empty($cache_array)) { $options['_query'] = $query; $this->_fetch($ret, array($options)); return $ret; } $cs_ret = empty($options['changedsince']) ? null : clone $ret; /* Convert special searches to UID lists and create mapping. */ $ids = $this->resolveIds( $this->_selected, $options['ids'], empty($options['exists']) ? 1 : 2 ); /* Add non-user settable cache fields. */ $cache_array[Horde_Imap_Client::FETCH_DOWNGRADED] = self::CACHE_DOWNGRADED; /* Get the cached values. */ $data = $this->_cache->get( $this->_selected, $ids->ids, array_values($cache_array), $mbox_ob->getStatus(Horde_Imap_Client::STATUS_UIDVALIDITY) ); /* Build a list of what we still need. */ $map = array_flip($mbox_ob->map->map); $sequence = $options['ids']->sequence; foreach ($ids as $uid) { $crit = clone $query; if ($sequence) { if (!isset($map[$uid])) { continue; } $entry_idx = $map[$uid]; } else { $entry_idx = $uid; unset($crit[Horde_Imap_Client::FETCH_UID]); } $entry = $ret->get($entry_idx); if (isset($map[$uid])) { $entry->setSeq($map[$uid]); unset($crit[Horde_Imap_Client::FETCH_SEQ]); } $entry->setUid($uid); foreach ($cache_array as $key => $cid) { switch ($key) { case Horde_Imap_Client::FETCH_DOWNGRADED: if (!empty($data[$uid][$cid])) { $entry->setDowngraded(true); } break; case Horde_Imap_Client::FETCH_ENVELOPE: if (isset($data[$uid][$cid]) && ($data[$uid][$cid] instanceof Horde_Imap_Client_Data_Envelope)) { $entry->setEnvelope($data[$uid][$cid]); unset($crit[$key]); } break; case Horde_Imap_Client::FETCH_FLAGS: if (isset($data[$uid][$cid]) && is_array($data[$uid][$cid])) { $entry->setFlags($data[$uid][$cid]); unset($crit[$key]); } break; case Horde_Imap_Client::FETCH_HEADERS: foreach ($header_cache as $hkey => $hval) { if (isset($data[$uid][$cid][$hval])) { /* We have found a cached entry with the same * MD5 sum. */ $entry->setHeaders($hkey, $data[$uid][$cid][$hval]); $crit->remove($key, $hkey); } else { $this->_temp['headers_caching'][$hkey] = $hval; } } break; case Horde_Imap_Client::FETCH_IMAPDATE: if (isset($data[$uid][$cid]) && ($data[$uid][$cid] instanceof Horde_Imap_Client_DateTime)) { $entry->setImapDate($data[$uid][$cid]); unset($crit[$key]); } break; case Horde_Imap_Client::FETCH_SIZE: if (isset($data[$uid][$cid])) { $entry->setSize($data[$uid][$cid]); unset($crit[$key]); } break; case Horde_Imap_Client::FETCH_STRUCTURE: if (isset($data[$uid][$cid]) && ($data[$uid][$cid] instanceof Horde_Mime_Part)) { $entry->setStructure($data[$uid][$cid]); unset($crit[$key]); } break; } } if (count($crit)) { $sig = $crit->hash(); if (isset($new_query[$sig])) { $new_query[$sig]['i'][] = $entry_idx; } else { $new_query[$sig] = array( 'c' => $crit, 'i' => array($entry_idx) ); } } } $to_fetch = array(); foreach ($new_query as $val) { $ids_ob = $this->getIdsOb(null, $sequence); $ids_ob->duplicates = true; $ids_ob->add($val['i']); $to_fetch[] = array_merge($options, array( '_query' => $val['c'], 'ids' => $ids_ob )); } if (!empty($to_fetch)) { $this->_fetch(is_null($cs_ret) ? $ret : $cs_ret, $to_fetch); } if (is_null($cs_ret)) { return $ret; } /* If doing changedsince query, and all other data is cached, we still * need to hit IMAP server to determine proper results set. */ if (empty($new_query)) { $squery = new Horde_Imap_Client_Search_Query(); $squery->modseq($options['changedsince'] + 1); $squery->ids($options['ids']); $cs = $this->search($this->_selected, $squery, array( 'sequence' => $sequence )); foreach ($cs['match'] as $val) { $entry = $ret->get($val); if ($sequence) { $entry->setSeq($val); } else { $entry->setUid($val); } $cs_ret[$val] = $entry; } } else { foreach ($cs_ret as $key => $val) { $val->merge($ret->get($key)); } } return $cs_ret; } /** * Fetch message data. * * Fetch queries should be grouped in the $queries argument. Each value * is an array of fetch options, with the fetch query stored in the * '_query' parameter. IMPORTANT: All queries must have the same ID * type (either sequence or UID). * * @param Horde_Imap_Client_Fetch_Results $results Fetch results. * @param array $queries The list of queries. * * @throws Horde_Imap_Client_Exception */ abstract protected function _fetch(Horde_Imap_Client_Fetch_Results $results, $queries); /** * Get the list of vanished messages (UIDs that have been expunged since a * given mod-sequence value). * * @param mixed $mailbox The mailbox to query. Either a * Horde_Imap_Client_Mailbox object or a string * (UTF-8). * @param integer $modseq Search for expunged messages after this * mod-sequence value. * @param array $opts Additional options: * - ids: (Horde_Imap_Client_Ids) Restrict to these UIDs. * DEFAULT: Returns full list of UIDs vanished (QRESYNC only). * This option is REQUIRED for non-QRESYNC servers or * else an empty list will be returned. * * @return Horde_Imap_Client_Ids List of UIDs that have vanished. * * @throws Horde_Imap_Client_NoSupportExtension */ public function vanished($mailbox, $modseq, array $opts = array()) { $this->login(); if (empty($opts['ids'])) { if (!$this->_capability()->isEnabled('QRESYNC')) { return $this->getIdsOb(); } $opts['ids'] = $this->getIdsOb(Horde_Imap_Client_Ids::ALL); } elseif ($opts['ids']->isEmpty()) { return $this->getIdsOb(); } elseif ($opts['ids']->sequence) { throw new InvalidArgumentException('Vanished requires UIDs.'); } $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO); if ($this->_capability()->isEnabled('QRESYNC')) { if (!$this->_mailboxOb()->getStatus(Horde_Imap_Client::STATUS_HIGHESTMODSEQ)) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Mailbox does not support mod-sequences."), Horde_Imap_Client_Exception::MBOXNOMODSEQ ); } return $this->_vanished(max(1, $modseq), $opts['ids']); } $ids = $this->resolveIds($mailbox, $opts['ids']); $squery = new Horde_Imap_Client_Search_Query(); $squery->ids($ids); $search = $this->search($mailbox, $squery, array( 'nocache' => true )); return $this->getIdsOb(array_diff($ids->ids, $search['match']->ids)); } /** * Get the list of vanished messages. * * @param integer $modseq Mod-sequence value. * @param Horde_Imap_Client_Ids $ids UIDs. * * @return Horde_Imap_Client_Ids List of UIDs that have vanished. */ abstract protected function _vanished($modseq, Horde_Imap_Client_Ids $ids); /** * Store message flag data (see RFC 3501 [6.4.6]). * * @param mixed $mailbox The mailbox containing the messages to modify. * Either a Horde_Imap_Client_Mailbox object or a * string (UTF-8). * @param array $options Additional options: * - add: (array) An array of flags to add. * DEFAULT: No flags added. * - ids: (Horde_Imap_Client_Ids) The list of messages to modify. * DEFAULT: All messages in $mailbox will be modified. * - remove: (array) An array of flags to remove. * DEFAULT: No flags removed. * - replace: (array) Replace the current flags with this set * of flags. Overrides both the 'add' and 'remove' options. * DEFAULT: No replace is performed. * - unchangedsince: (integer) Only changes flags if the mod-sequence ID * of the message is equal or less than this value. * Requires the CONDSTORE IMAP extension on the server. * Also requires the mailbox to support mod-sequences. * Will throw an exception if either condition is not * met. * DEFAULT: mod-sequence is ignored when applying * changes * * @return Horde_Imap_Client_Ids A Horde_Imap_Client_Ids object * containing the list of IDs that failed * the 'unchangedsince' test. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function store($mailbox, array $options = array()) { // Open mailbox call will handle the login. $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_READWRITE); /* SEARCHRES requires server support. */ if (empty($options['ids'])) { $options['ids'] = $this->getIdsOb(Horde_Imap_Client_Ids::ALL); } elseif ($options['ids']->isEmpty()) { return $this->getIdsOb(); } elseif ($options['ids']->search_res && !$this->_capability('SEARCHRES')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('SEARCHRES'); } if (!empty($options['unchangedsince'])) { if (!$this->_capability()->isEnabled('CONDSTORE')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('CONDSTORE'); } /* RFC 7162 [3.1.2.2] - trying to do a UNCHANGEDSINCE STORE on a * mailbox that doesn't support it will return BAD. */ if (!$this->_mailboxOb()->getStatus(Horde_Imap_Client::STATUS_HIGHESTMODSEQ)) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Mailbox does not support mod-sequences."), Horde_Imap_Client_Exception::MBOXNOMODSEQ ); } } return $this->_store($options); } /** * Store message flag data. * * @param array $options Additional options. * * @return Horde_Imap_Client_Ids A Horde_Imap_Client_Ids object * containing the list of IDs that failed * the 'unchangedsince' test. * * @throws Horde_Imap_Client_Exception */ abstract protected function _store($options); /** * Copy messages to another mailbox. * * @param mixed $source The source mailbox. Either a * Horde_Imap_Client_Mailbox object or a string * (UTF-8). * @param mixed $dest The destination mailbox. Either a * Horde_Imap_Client_Mailbox object or a string * (UTF-8). * @param array $options Additional options: * - create: (boolean) Try to create $dest if it does not exist? * DEFAULT: No. * - force_map: (boolean) Forces the array mapping to always be * returned. [@since 2.19.0] * - ids: (Horde_Imap_Client_Ids) The list of messages to copy. * DEFAULT: All messages in $mailbox will be copied. * - move: (boolean) If true, delete the original messages. * DEFAULT: Original messages are not deleted. * * @return mixed An array mapping old UIDs (keys) to new UIDs (values) on * success (only guaranteed if 'force_map' is true) or * true. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function copy($source, $dest, array $options = array()) { // Open mailbox call will handle the login. $this->openMailbox($source, empty($options['move']) ? Horde_Imap_Client::OPEN_AUTO : Horde_Imap_Client::OPEN_READWRITE); /* SEARCHRES requires server support. */ if (empty($options['ids'])) { $options['ids'] = $this->getIdsOb(Horde_Imap_Client_Ids::ALL); } elseif ($options['ids']->isEmpty()) { return array(); } elseif ($options['ids']->search_res && !$this->_capability('SEARCHRES')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('SEARCHRES'); } $dest = Horde_Imap_Client_Mailbox::get($dest); $res = $this->_copy($dest, $options); if (($res === true) && !empty($options['force_map'])) { /* Need to manually create mapping from Message-ID data. */ $query = new Horde_Imap_Client_Fetch_Query(); $query->envelope(); $fetch = $this->fetch($source, $query, array( 'ids' => $options['ids'] )); $res = array(); foreach ($fetch as $val) { if ($uid = $this->_getUidByMessageId($dest, $val->getEnvelope()->message_id)) { $res[$val->getUid()] = $uid; } } } return $res; } /** * Copy messages to another mailbox. * * @param Horde_Imap_Client_Mailbox $dest The destination mailbox. * @param array $options Additional options. * * @return mixed An array mapping old UIDs (keys) to new UIDs (values) on * success (if the IMAP server and/or driver support the * UIDPLUS extension) or true. * * @throws Horde_Imap_Client_Exception */ abstract protected function _copy(Horde_Imap_Client_Mailbox $dest, $options); /** * Set quota limits. The server must support the IMAP QUOTA extension * (RFC 2087). * * @param mixed $root The quota root. Either a * Horde_Imap_Client_Mailbox object or a string * (UTF-8). * @param array $resources The resource values to set. Keys are the * resource atom name; value is the resource * value. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function setQuota($root, array $resources = array()) { $this->login(); if (!$this->_capability('QUOTA')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('QUOTA'); } if (!empty($resources)) { $this->_setQuota(Horde_Imap_Client_Mailbox::get($root), $resources); } } /** * Set quota limits. * * @param Horde_Imap_Client_Mailbox $root The quota root. * @param array $resources The resource values to set. * * @return boolean True on success. * * @throws Horde_Imap_Client_Exception */ abstract protected function _setQuota(Horde_Imap_Client_Mailbox $root, $resources); /** * Get quota limits. The server must support the IMAP QUOTA extension * (RFC 2087). * * @param mixed $root The quota root. Either a Horde_Imap_Client_Mailbox * object or a string (UTF-8). * * @return mixed An array with resource keys. Each key holds an array * with 2 values: 'limit' and 'usage'. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function getQuota($root) { $this->login(); if (!$this->_capability('QUOTA')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('QUOTA'); } return $this->_getQuota(Horde_Imap_Client_Mailbox::get($root)); } /** * Get quota limits. * * @param Horde_Imap_Client_Mailbox $root The quota root. * * @return mixed An array with resource keys. Each key holds an array * with 2 values: 'limit' and 'usage'. * * @throws Horde_Imap_Client_Exception */ abstract protected function _getQuota(Horde_Imap_Client_Mailbox $root); /** * Get quota limits for a mailbox. The server must support the IMAP QUOTA * extension (RFC 2087). * * @param mixed $mailbox A mailbox. Either a Horde_Imap_Client_Mailbox * object or a string (UTF-8). * * @return mixed An array with the keys being the quota roots. Each key * holds an array with resource keys: each of these keys * holds an array with 2 values: 'limit' and 'usage'. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function getQuotaRoot($mailbox) { $this->login(); if (!$this->_capability('QUOTA')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('QUOTA'); } return $this->_getQuotaRoot(Horde_Imap_Client_Mailbox::get($mailbox)); } /** * Get quota limits for a mailbox. * * @param Horde_Imap_Client_Mailbox $mailbox A mailbox. * * @return mixed An array with the keys being the quota roots. Each key * holds an array with resource keys: each of these keys * holds an array with 2 values: 'limit' and 'usage'. * * @throws Horde_Imap_Client_Exception */ abstract protected function _getQuotaRoot(Horde_Imap_Client_Mailbox $mailbox); /** * Get the ACL rights for a given mailbox. The server must support the * IMAP ACL extension (RFC 2086/4314). * * @param mixed $mailbox A mailbox. Either a Horde_Imap_Client_Mailbox * object or a string (UTF-8). * * @return array An array with identifiers as the keys and * Horde_Imap_Client_Data_Acl objects as the values. * * @throws Horde_Imap_Client_Exception */ public function getACL($mailbox) { $this->login(); return $this->_getACL(Horde_Imap_Client_Mailbox::get($mailbox)); } /** * Get ACL rights for a given mailbox. * * @param Horde_Imap_Client_Mailbox $mailbox A mailbox. * * @return array An array with identifiers as the keys and * Horde_Imap_Client_Data_Acl objects as the values. * * @throws Horde_Imap_Client_Exception */ abstract protected function _getACL(Horde_Imap_Client_Mailbox $mailbox); /** * Set ACL rights for a given mailbox/identifier. * * @param mixed $mailbox A mailbox. Either a Horde_Imap_Client_Mailbox * object or a string (UTF-8). * @param string $identifier The identifier to alter (UTF-8). * @param array $options Additional options: * - rights: (string) The rights to alter or set. * - action: (string, optional) If 'add' or 'remove', adds or removes the * specified rights. Sets the rights otherwise. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function setACL($mailbox, $identifier, $options) { $this->login(); if (!$this->_capability('ACL')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('ACL'); } if (empty($options['rights'])) { if (!isset($options['action']) || (($options['action'] != 'add') && $options['action'] != 'remove')) { $this->_deleteACL( Horde_Imap_Client_Mailbox::get($mailbox), Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($identifier) ); } return; } $acl = ($options['rights'] instanceof Horde_Imap_Client_Data_Acl) ? $options['rights'] : new Horde_Imap_Client_Data_Acl(strval($options['rights'])); $options['rights'] = $acl->getString( $this->_capability('RIGHTS') ? Horde_Imap_Client_Data_AclCommon::RFC_4314 : Horde_Imap_Client_Data_AclCommon::RFC_2086 ); if (isset($options['action'])) { switch ($options['action']) { case 'add': $options['rights'] = '+' . $options['rights']; break; case 'remove': $options['rights'] = '-' . $options['rights']; break; } } $this->_setACL( Horde_Imap_Client_Mailbox::get($mailbox), Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($identifier), $options ); } /** * Set ACL rights for a given mailbox/identifier. * * @param Horde_Imap_Client_Mailbox $mailbox A mailbox. * @param string $identifier The identifier to alter * (UTF7-IMAP). * @param array $options Additional options. 'rights' * contains the string of * rights to set on the server. * * @throws Horde_Imap_Client_Exception */ abstract protected function _setACL(Horde_Imap_Client_Mailbox $mailbox, $identifier, $options); /** * Deletes ACL rights for a given mailbox/identifier. * * @param mixed $mailbox A mailbox. Either a Horde_Imap_Client_Mailbox * object or a string (UTF-8). * @param string $identifier The identifier to delete (UTF-8). * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function deleteACL($mailbox, $identifier) { $this->login(); if (!$this->_capability('ACL')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('ACL'); } $this->_deleteACL( Horde_Imap_Client_Mailbox::get($mailbox), Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($identifier) ); } /** * Deletes ACL rights for a given mailbox/identifier. * * @param Horde_Imap_Client_Mailbox $mailbox A mailbox. * @param string $identifier The identifier to delete * (UTF7-IMAP). * * @throws Horde_Imap_Client_Exception */ abstract protected function _deleteACL(Horde_Imap_Client_Mailbox $mailbox, $identifier); /** * List the ACL rights for a given mailbox/identifier. The server must * support the IMAP ACL extension (RFC 2086/4314). * * @param mixed $mailbox A mailbox. Either a Horde_Imap_Client_Mailbox * object or a string (UTF-8). * @param string $identifier The identifier to query (UTF-8). * * @return Horde_Imap_Client_Data_AclRights An ACL data rights object. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function listACLRights($mailbox, $identifier) { $this->login(); if (!$this->_capability('ACL')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('ACL'); } return $this->_listACLRights( Horde_Imap_Client_Mailbox::get($mailbox), Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($identifier) ); } /** * Get ACL rights for a given mailbox/identifier. * * @param Horde_Imap_Client_Mailbox $mailbox A mailbox. * @param string $identifier The identifier to query * (UTF7-IMAP). * * @return Horde_Imap_Client_Data_AclRights An ACL data rights object. * * @throws Horde_Imap_Client_Exception */ abstract protected function _listACLRights(Horde_Imap_Client_Mailbox $mailbox, $identifier); /** * Get the ACL rights for the current user for a given mailbox. The * server must support the IMAP ACL extension (RFC 2086/4314). * * @param mixed $mailbox A mailbox. Either a Horde_Imap_Client_Mailbox * object or a string (UTF-8). * * @return Horde_Imap_Client_Data_Acl An ACL data object. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupportExtension */ public function getMyACLRights($mailbox) { $this->login(); if (!$this->_capability('ACL')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('ACL'); } return $this->_getMyACLRights(Horde_Imap_Client_Mailbox::get($mailbox)); } /** * Get the ACL rights for the current user for a given mailbox. * * @param Horde_Imap_Client_Mailbox $mailbox A mailbox. * * @return Horde_Imap_Client_Data_Acl An ACL data object. * * @throws Horde_Imap_Client_Exception */ abstract protected function _getMyACLRights(Horde_Imap_Client_Mailbox $mailbox); /** * Return master list of ACL rights available on the server. * * @return array A list of ACL rights. */ public function allAclRights() { $this->login(); $rights = array( Horde_Imap_Client::ACL_LOOKUP, Horde_Imap_Client::ACL_READ, Horde_Imap_Client::ACL_SEEN, Horde_Imap_Client::ACL_WRITE, Horde_Imap_Client::ACL_INSERT, Horde_Imap_Client::ACL_POST, Horde_Imap_Client::ACL_ADMINISTER ); if ($capability = $this->_capability()->getParams('RIGHTS')) { // Add rights defined in CAPABILITY string (RFC 4314). return array_merge($rights, str_split(reset($capability))); } // Add RFC 2086 rights (deprecated by RFC 4314, but need to keep for // compatibility with old servers). return array_merge($rights, array( Horde_Imap_Client::ACL_CREATE, Horde_Imap_Client::ACL_DELETE )); } /** * Get metadata for a given mailbox. The server must support either the * IMAP METADATA extension (RFC 5464) or the ANNOTATEMORE extension * (http://ietfreport.isoc.org/idref/draft-daboo-imap-annotatemore/). * * @param mixed $mailbox A mailbox. Either a Horde_Imap_Client_Mailbox * object or a string (UTF-8). * @param array $entries The entries to fetch (UTF-8 strings). * @param array $options Additional options: * - depth: (string) Either "0", "1" or "infinity". Returns only the * given value (0), only values one level below the specified * value (1) or all entries below the specified value * (infinity). * - maxsize: (integer) The maximal size the returned values may have. * DEFAULT: No maximal size. * * @return array An array with metadata names as the keys and metadata * values as the values. If 'maxsize' is set, and entries * exist on the server larger than this size, the size will * be returned in the key '*longentries'. * * @throws Horde_Imap_Client_Exception */ public function getMetadata($mailbox, $entries, array $options = array()) { $this->login(); if (!is_array($entries)) { $entries = array($entries); } return $this->_getMetadata(Horde_Imap_Client_Mailbox::get($mailbox), array_map(array('Horde_Imap_Client_Utf7imap', 'Utf8ToUtf7Imap'), $entries), $options); } /** * Get metadata for a given mailbox. * * @param Horde_Imap_Client_Mailbox $mailbox A mailbox. * @param array $entries The entries to fetch * (UTF7-IMAP strings). * @param array $options Additional options. * * @return array An array with metadata names as the keys and metadata * values as the values. * * @throws Horde_Imap_Client_Exception */ abstract protected function _getMetadata(Horde_Imap_Client_Mailbox $mailbox, $entries, $options); /** * Set metadata for a given mailbox/identifier. * * @param mixed $mailbox A mailbox. Either a Horde_Imap_Client_Mailbox * object or a string (UTF-8). If empty, sets a * server annotation. * @param array $data A set of data values. The metadata values * corresponding to the keys of the array will * be set to the values in the array. * * @throws Horde_Imap_Client_Exception */ public function setMetadata($mailbox, $data) { $this->login(); $this->_setMetadata(Horde_Imap_Client_Mailbox::get($mailbox), $data); } /** * Set metadata for a given mailbox/identifier. * * @param Horde_Imap_Client_Mailbox $mailbox A mailbox. * @param array $data A set of data values. See * setMetadata() for format. * * @throws Horde_Imap_Client_Exception */ abstract protected function _setMetadata(Horde_Imap_Client_Mailbox $mailbox, $data); /* Public utility functions. */ /** * Returns a unique identifier for the current mailbox status. * * @deprecated * * @param mixed $mailbox A mailbox. Either a Horde_Imap_Client_Mailbox * object or a string (UTF-8). * @param array $addl Additional cache info to add to the cache ID * string. * * @return string The cache ID string, which will change when the * composition of the mailbox changes. The uidvalidity * will always be the first element, and will be delimited * by the '|' character. * * @throws Horde_Imap_Client_Exception */ public function getCacheId($mailbox, array $addl = array()) { return Horde_Imap_Client_Base_Deprecated::getCacheId($this, $mailbox, $this->_capability()->isEnabled('CONDSTORE'), $addl); } /** * Parses a cacheID created by getCacheId(). * * @deprecated * * @param string $id The cache ID. * * @return array An array with the following information: * - highestmodseq: (integer) * - messages: (integer) * - uidnext: (integer) * - uidvalidity: (integer) Always present */ public function parseCacheId($id) { return Horde_Imap_Client_Base_Deprecated::parseCacheId($id); } /** * Resolves an IDs object into a list of IDs. * * @param Horde_Imap_Client_Mailbox $mailbox The mailbox. * @param Horde_Imap_Client_Ids $ids The Ids object. * @param integer $convert Convert to UIDs? * - 0: No * - 1: Only if $ids is not already a UIDs object * - 2: Always * * @return Horde_Imap_Client_Ids The list of IDs. */ public function resolveIds(Horde_Imap_Client_Mailbox $mailbox, Horde_Imap_Client_Ids $ids, $convert = 0) { $map = $this->_mailboxOb($mailbox)->map; if ($ids->special) { /* Optimization for ALL sequence searches. */ if (!$convert && $ids->all && $ids->sequence) { $res = $this->status($mailbox, Horde_Imap_Client::STATUS_MESSAGES); return $this->getIdsOb($res['messages'] ? ('1:' . $res['messages']) : array(), true); } $convert = 2; } elseif (!$convert || (!$ids->sequence && ($convert == 1)) || $ids->isEmpty()) { return clone $ids; } else { /* Do an all or nothing: either we have all the numbers/UIDs in * memory and can return, or just send the whole ID query to the * server. Any advantage we would get by a partial search are * outweighed by the complexities needed to make the search and * then merge back into the original results. */ $lookup = $map->lookup($ids); if (count($lookup) === count($ids)) { return $this->getIdsOb(array_values($lookup)); } } $query = new Horde_Imap_Client_Search_Query(); $query->ids($ids); $res = $this->search($mailbox, $query, array( 'results' => array( Horde_Imap_Client::SEARCH_RESULTS_MATCH, Horde_Imap_Client::SEARCH_RESULTS_SAVE ), 'sequence' => (!$convert && $ids->sequence), 'sort' => array(Horde_Imap_Client::SORT_SEQUENCE) )); /* Update mapping. */ if ($convert) { if ($ids->all) { $ids = $this->getIdsOb('1:' . count($res['match'])); } elseif ($ids->special) { return $res['match']; } /* Sanity checking (Bug #12911). */ $list1 = array_slice($ids->ids, 0, count($res['match'])); $list2 = $res['match']->ids; if (!empty($list1) && !empty($list2) && (count($list1) === count($list2))) { $map->update(array_combine($list1, $list2)); } } return $res['match']; } /** * Determines if the given charset is valid for search-related queries. * This check pertains just to the basic IMAP SEARCH command. * * @deprecated Use $search_charset property instead. * * @param string $charset The query charset. * * @return boolean True if server supports this charset. */ public function validSearchCharset($charset) { return $this->search_charset->query($charset); } /* Mailbox syncing functions. */ /** * Returns a unique token for the current mailbox synchronization status. * * @since 2.2.0 * * @param mixed $mailbox A mailbox. Either a Horde_Imap_Client_Mailbox * object or a string (UTF-8). * * @return string The sync token. * * @throws Horde_Imap_Client_Exception */ public function getSyncToken($mailbox) { $out = array(); foreach ($this->_syncStatus($mailbox) as $key => $val) { $out[] = $key . $val; } return base64_encode(implode(',', $out)); } /** * Synchronize a mailbox from a sync token. * * @since 2.2.0 * * @param mixed $mailbox A mailbox. Either a Horde_Imap_Client_Mailbox * object or a string (UTF-8). * @param string $token A sync token generated by getSyncToken(). * @param array $opts Additional options: * - criteria: (integer) Mask of Horde_Imap_Client::SYNC_* criteria to * return. Defaults to SYNC_ALL. * - ids: (Horde_Imap_Client_Ids) A cached list of UIDs. Unless QRESYNC * is available on the server, failure to specify this option * means SYNC_VANISHEDUIDS information cannot be returned. * * @return Horde_Imap_Client_Data_Sync A sync object. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_Sync */ public function sync($mailbox, $token, array $opts = array()) { if (($token = base64_decode($token, true)) === false) { throw new Horde_Imap_Client_Exception_Sync('Bad token.', Horde_Imap_Client_Exception_Sync::BAD_TOKEN); } $sync = array(); foreach (explode(',', $token) as $val) { $sync[substr($val, 0, 1)] = substr($val, 1); } return new Horde_Imap_Client_Data_Sync( $this, $mailbox, $sync, $this->_syncStatus($mailbox), (isset($opts['criteria']) ? $opts['criteria'] : Horde_Imap_Client::SYNC_ALL), (isset($opts['ids']) ? $opts['ids'] : null) ); } /* Private utility functions. */ /** * Store FETCH data in cache. * * @param Horde_Imap_Client_Fetch_Results $data The fetch results. * * @throws Horde_Imap_Client_Exception */ protected function _updateCache(Horde_Imap_Client_Fetch_Results $data) { if (!empty($this->_temp['fetch_nocache']) || empty($this->_selected) || !count($data) || !$this->_initCache(true)) { return; } $c = $this->getParam('cache'); if (in_array(strval($this->_selected), $c['fetch_ignore'])) { $this->_debug->info(sprintf( 'CACHE: Ignoring FETCH data [%s]', $this->_selected )); return; } /* Optimization: we can directly use getStatus() here since we know * these values are initialized. */ $mbox_ob = $this->_mailboxOb(); $highestmodseq = $mbox_ob->getStatus(Horde_Imap_Client::STATUS_HIGHESTMODSEQ); $uidvalidity = $mbox_ob->getStatus(Horde_Imap_Client::STATUS_UIDVALIDITY); $mapping = $modseq = $tocache = array(); if (count($data)) { $cf = $this->_cacheFields(); } foreach ($data as $v) { /* It is possible that we received FETCH information that doesn't * contain UID data. This is uncacheable so don't process. */ if (!($uid = $v->getUid())) { return; } $tmp = array(); if ($v->isDowngraded()) { $tmp[self::CACHE_DOWNGRADED] = true; } foreach ($cf as $key => $val) { if ($v->exists($key)) { switch ($key) { case Horde_Imap_Client::FETCH_ENVELOPE: $tmp[$val] = $v->getEnvelope(); break; case Horde_Imap_Client::FETCH_FLAGS: if ($highestmodseq) { $modseq[$uid] = $v->getModSeq(); $tmp[$val] = $v->getFlags(); } break; case Horde_Imap_Client::FETCH_HEADERS: foreach ($this->_temp['headers_caching'] as $label => $hash) { if ($hdr = $v->getHeaders($label)) { $tmp[$val][$hash] = $hdr; } } break; case Horde_Imap_Client::FETCH_IMAPDATE: $tmp[$val] = $v->getImapDate(); break; case Horde_Imap_Client::FETCH_SIZE: $tmp[$val] = $v->getSize(); break; case Horde_Imap_Client::FETCH_STRUCTURE: $tmp[$val] = clone $v->getStructure(); break; } } } if (!empty($tmp)) { $tocache[$uid] = $tmp; } $mapping[$v->getSeq()] = $uid; } if (!empty($mapping)) { if (!empty($tocache)) { $this->_cache->set($this->_selected, $tocache, $uidvalidity); } $this->_mailboxOb()->map->update($mapping); } if (!empty($modseq)) { $this->_updateModSeq(max(array_merge($modseq, array($highestmodseq)))); $mbox_ob->setStatus(Horde_Imap_Client::STATUS_SYNCFLAGUIDS, array_keys($modseq)); } } /** * Moves cache entries from the current mailbox to another mailbox. * * @param Horde_Imap_Client_Mailbox $to The destination mailbox. * @param array $map Mapping of source UIDs (keys) to * destination UIDs (values). * @param string $uidvalid UIDVALIDITY of destination * mailbox. * * @throws Horde_Imap_Client_Exception */ protected function _moveCache(Horde_Imap_Client_Mailbox $to, $map, $uidvalid) { if (!$this->_initCache()) { return; } $c = $this->getParam('cache'); if (in_array(strval($to), $c['fetch_ignore'])) { $this->_debug->info(sprintf( 'CACHE: Ignoring moving FETCH data (%s => %s)', $this->_selected, $to )); return; } $old = $this->_cache->get($this->_selected, array_keys($map), null); $new = array(); foreach ($map as $key => $val) { if (!empty($old[$key])) { $new[$val] = $old[$key]; } } if (!empty($new)) { $this->_cache->set($to, $new, $uidvalid); } } /** * Delete messages in the cache. * * @param Horde_Imap_Client_Mailbox $mailbox The mailbox. * @param Horde_Imap_Client_Ids $ids The list of IDs to delete in * $mailbox. * @param array $opts Additional options (not used * in base class). * * @return Horde_Imap_Client_Ids UIDs that were deleted. * @throws Horde_Imap_Client_Exception */ protected function _deleteMsgs(Horde_Imap_Client_Mailbox $mailbox, Horde_Imap_Client_Ids $ids, array $opts = array()) { if (!$this->_initCache()) { return $ids; } $mbox_ob = $this->_mailboxOb(); $ids_ob = $ids->sequence ? $this->getIdsOb($mbox_ob->map->lookup($ids)) : $ids; $this->_cache->deleteMsgs($mailbox, $ids_ob->ids); $mbox_ob->setStatus(Horde_Imap_Client::STATUS_SYNCVANISHED, $ids_ob->ids); $mbox_ob->map->remove($ids); return $ids_ob; } /** * Retrieve data from the search cache. * * @param string $type The cache type ('search' or 'thread'). * @param array $options The options array of the calling function. * * @return mixed Returns search cache metadata. If search was retrieved, * data is in key 'data'. * Returns null if caching is not available. */ protected function _getSearchCache($type, $options) { $status = $this->status($this->_selected, Horde_Imap_Client::STATUS_HIGHESTMODSEQ | Horde_Imap_Client::STATUS_UIDVALIDITY); /* Search caching requires MODSEQ, which may not be active for a * mailbox. */ if (empty($status['highestmodseq'])) { return null; } ksort($options); $cache = hash('md5', $type . serialize($options)); $cacheid = $this->getSyncToken($this->_selected); $ret = array(); $md = $this->_cache->getMetaData( $this->_selected, $status['uidvalidity'], array(self::CACHE_SEARCH, self::CACHE_SEARCHID) ); if (!isset($md[self::CACHE_SEARCHID]) || ($md[self::CACHE_SEARCHID] != $cacheid)) { $md[self::CACHE_SEARCH] = array(); $md[self::CACHE_SEARCHID] = $cacheid; if ($this->_debug->debug && !isset($this->_temp['searchcacheexpire'][strval($this->_selected)])) { $this->_debug->info(sprintf( 'SEARCH: Expired from cache [%s]', $this->_selected )); $this->_temp['searchcacheexpire'][strval($this->_selected)] = true; } } elseif (isset($md[self::CACHE_SEARCH][$cache])) { $this->_debug->info(sprintf( 'SEARCH: Retrieved %s from cache (%s [%s])', $type, $cache, $this->_selected )); $ret['data'] = $md[self::CACHE_SEARCH][$cache]; unset($md[self::CACHE_SEARCHID]); } return array_merge($ret, array( 'id' => $cache, 'metadata' => $md, 'type' => $type )); } /** * Set data in the search cache. * * @param mixed $data The cache data to store. * @param string $sdata The search data returned from _getSearchCache(). */ protected function _setSearchCache($data, $sdata) { $sdata['metadata'][self::CACHE_SEARCH][$sdata['id']] = $data; $this->_cache->setMetaData($this->_selected, null, $sdata['metadata']); if ($this->_debug->debug) { $this->_debug->info(sprintf( 'SEARCH: Saved %s to cache (%s [%s])', $sdata['type'], $sdata['id'], $this->_selected )); unset($this->_temp['searchcacheexpire'][strval($this->_selected)]); } } /** * Updates the cached MODSEQ value. * * @param integer $modseq MODSEQ value to store. * * @return mixed The MODSEQ of the old value if it was replaced (or false * if it didn't exist or is the same). */ protected function _updateModSeq($modseq) { if (!$this->_initCache(true)) { return false; } $mbox_ob = $this->_mailboxOb(); $uidvalid = $mbox_ob->getStatus(Horde_Imap_Client::STATUS_UIDVALIDITY); $md = $this->_cache->getMetaData($this->_selected, $uidvalid, array(self::CACHE_MODSEQ)); if (isset($md[self::CACHE_MODSEQ])) { if ($md[self::CACHE_MODSEQ] < $modseq) { $set = true; $sync = $md[self::CACHE_MODSEQ]; } else { $set = false; $sync = 0; } $mbox_ob->setStatus(Horde_Imap_Client::STATUS_SYNCMODSEQ, $md[self::CACHE_MODSEQ]); } else { $set = true; $sync = 0; } /* $modseq can be 0 - NOMODSEQ - so don't store in that case. */ if ($set && $modseq) { $this->_cache->setMetaData($this->_selected, $uidvalid, array( self::CACHE_MODSEQ => $modseq )); } return $sync; } /** * Synchronizes the current mailbox cache with the server (using CONDSTORE * or QRESYNC). */ protected function _condstoreSync() { $mbox_ob = $this->_mailboxOb(); /* Check that modseqs are available in mailbox. */ if (!($highestmodseq = $mbox_ob->getStatus(Horde_Imap_Client::STATUS_HIGHESTMODSEQ)) || !($modseq = $this->_updateModSeq($highestmodseq))) { $mbox_ob->sync = true; } if ($mbox_ob->sync) { return; } $uids_ob = $this->getIdsOb($this->_cache->get( $this->_selected, array(), array(), $mbox_ob->getStatus(Horde_Imap_Client::STATUS_UIDVALIDITY) )); if (!count($uids_ob)) { $mbox_ob->sync = true; return; } /* Are we caching flags? */ if (array_key_exists(Horde_Imap_Client::FETCH_FLAGS, $this->_cacheFields())) { $fquery = new Horde_Imap_Client_Fetch_Query(); $fquery->flags(); /* Update flags in cache. Cache will be updated in _fetch(). */ $this->_fetch(new Horde_Imap_Client_Fetch_Results(), array( array( '_query' => $fquery, 'changedsince' => $modseq, 'ids' => $uids_ob ) )); } /* Search for deleted messages, and remove from cache. */ $vanished = $this->vanished($this->_selected, $modseq, array( 'ids' => $uids_ob )); $disappear = array_diff($uids_ob->ids, $vanished->ids); if (!empty($disappear)) { $this->_deleteMsgs($this->_selected, $this->getIdsOb($disappear)); } $mbox_ob->sync = true; } /** * Provide the list of available caching fields. * * @return array The list of available caching fields (fields are in the * key). */ protected function _cacheFields() { $c = $this->getParam('cache'); $out = $c['fields']; if (!$this->_capability()->isEnabled('CONDSTORE')) { unset($out[Horde_Imap_Client::FETCH_FLAGS]); } return $out; } /** * Return the current mailbox synchronization status. * * @param mixed $mailbox A mailbox. Either a Horde_Imap_Client_Mailbox * object or a string (UTF-8). * * @return array An array with status data. (This data is not guaranteed * to have any specific format). */ protected function _syncStatus($mailbox) { $status = $this->status( $mailbox, Horde_Imap_Client::STATUS_HIGHESTMODSEQ | Horde_Imap_Client::STATUS_MESSAGES | Horde_Imap_Client::STATUS_UIDNEXT_FORCE | Horde_Imap_Client::STATUS_UIDVALIDITY ); $fields = array('uidnext', 'uidvalidity'); if (empty($status['highestmodseq'])) { $fields[] = 'messages'; } else { $fields[] = 'highestmodseq'; } $out = array(); $sync_map = array_flip(Horde_Imap_Client_Data_Sync::$map); foreach ($fields as $val) { $out[$sync_map[$val]] = $status[$val]; } return array_filter($out); } /** * Get a message UID by the Message-ID. Returns the last message in a * mailbox that matches. * * @param Horde_Imap_Client_Mailbox $mailbox The mailbox to search * @param string $msgid Message-ID. * * @return string UID (null if not found). */ protected function _getUidByMessageId($mailbox, $msgid) { if (!$msgid) { return null; } $query = new Horde_Imap_Client_Search_Query(); $query->headerText('Message-ID', $msgid); $res = $this->search($mailbox, $query, array( 'results' => array(Horde_Imap_Client::SEARCH_RESULTS_MAX) )); return $res['max']; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Cache.php0000664000175000017500000002001113150761653020733 0ustar janjan * @category Horde * @copyright 2005-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Cache { /** * Base client object. * * @var Horde_Imap_Client_Base */ protected $_baseob; /** * Storage backend. * * @var Horde_Imap_Client_Cache_Backend */ protected $_backend; /** * Debug output. * * @var Horde_Imap_Client_Base_Debug */ protected $_debug = false; /** * The configuration params. * * @var array */ protected $_params = array(); /** * Constructor. * * @param array $params Configuration parameters: *
     *   - REQUIRED Parameters:
     *     - backend: (Horde_Imap_Client_Cache_Backend) The cache backend.
     *     - baseob: (Horde_Imap_Client_Base) The base client object.
     *
     *   - Optional Parameters:
     *     - debug: (Horde_Imap_Client_Base_Debug) Debug object.
     *              DEFAULT: No debug output
     * 
*/ public function __construct(array $params = array()) { $this->_backend = $params['backend']; $this->_baseob = $params['baseob']; $this->_backend->setParams(array( 'hostspec' => $this->_baseob->getParam('hostspec'), 'port' => $this->_baseob->getParam('port'), 'username' => $this->_baseob->getParam('username') )); if (isset($params['debug']) && ($params['debug'] instanceof Horde_Imap_Client_Base_Debug)) { $this->_debug = $params['debug']; $this->_debug->info(sprintf( 'CACHE: Using the %s storage driver.', get_class($this->_backend) )); } } /** * Get information from the cache. * * @param string $mailbox An IMAP mailbox string. * @param array $uids The list of message UIDs to retrieve * information for. If empty, returns the list * of cached UIDs. * @param array $fields An array of fields to retrieve. If empty, * returns all cached fields. * @param integer $uidvalid The IMAP uidvalidity value of the mailbox. * * @return array An array of arrays with the UID of the message as the * key (if found) and the fields as values (will be * undefined if not found). If $uids is empty, returns the * full (unsorted) list of cached UIDs. */ public function get($mailbox, array $uids = array(), $fields = array(), $uidvalid = null) { $mailbox = strval($mailbox); if (empty($uids)) { $ret = $this->_backend->getCachedUids($mailbox, $uidvalid); } else { $ret = $this->_backend->get($mailbox, $uids, $fields, $uidvalid); if ($this->_debug && !empty($ret)) { $this->_debug->info(sprintf( 'CACHE: Retrieved messages (%s [%s; %s])', empty($fields) ? 'ALL' : implode(',', $fields), $mailbox, $this->_baseob->getIdsOb(array_keys($ret))->tostring_sort )); } } return $ret; } /** * Store information in cache. * * @param string $mailbox An IMAP mailbox string. * @param array $data The list of data to save. The keys are the * UIDs, the values are an array of information * to save. If empty, do a check to make sure * the uidvalidity is still valid. * @param integer $uidvalid The IMAP uidvalidity value of the mailbox. */ public function set($mailbox, $data, $uidvalid) { $mailbox = strval($mailbox); if (empty($data)) { $this->_backend->getMetaData($mailbox, $uidvalid, array('uidvalid')); } else { $this->_backend->set($mailbox, $data, $uidvalid); if ($this->_debug) { $this->_debug->info(sprintf( 'CACHE: Stored messages [%s; %s]', $mailbox, $this->_baseob->getIdsOb(array_keys($data))->tostring_sort )); } } } /** * Get metadata information for a mailbox. * * @param string $mailbox An IMAP mailbox string. * @param integer $uidvalid The IMAP uidvalidity value of the mailbox. * @param array $entries An array of entries to return. If empty, * returns all metadata. * * @return array The requested metadata. Requested entries that do not * exist will be undefined. The following entries are * defaults and always present: * - uidvalid: (integer) The UIDVALIDITY of the mailbox. */ public function getMetaData($mailbox, $uidvalid = null, array $entries = array()) { return $this->_backend->getMetaData(strval($mailbox), $uidvalid, $entries); } /** * Set metadata information for a mailbox. * * @param string $mailbox An IMAP mailbox string. * @param integer $uidvalid The IMAP uidvalidity value of the mailbox. * @param array $data The list of data to save. The keys are the * metadata IDs, the values are the associated * data. The following labels are reserved: * 'uidvalid'. */ public function setMetaData($mailbox, $uidvalid, array $data = array()) { unset($data['uidvalid']); if (!empty($data)) { if (!empty($uidvalid)) { $data['uidvalid'] = $uidvalid; } $mailbox = strval($mailbox); $this->_backend->setMetaData($mailbox, $data); if ($this->_debug) { $this->_debug->info(sprintf( 'CACHE: Stored metadata (%s [%s])', implode(',', array_keys($data)), $mailbox )); } } } /** * Delete messages in the cache. * * @param string $mailbox An IMAP mailbox string. * @param array $uids The list of message UIDs to delete. */ public function deleteMsgs($mailbox, $uids) { if (empty($uids)) { return; } $mailbox = strval($mailbox); $this->_backend->deleteMsgs($mailbox, $uids); if ($this->_debug) { $this->_debug->info(sprintf( 'CACHE: Deleted messages [%s; %s]', $mailbox, $this->_baseob->getIdsOb($uids)->tostring_sort )); } } /** * Delete a mailbox from the cache. * * @param string $mbox The mailbox to delete. */ public function deleteMailbox($mbox) { $mbox = strval($mbox); $this->_backend->deleteMailbox($mbox); if ($this->_debug) { $this->_debug->info(sprintf( 'CACHE: Deleted mailbox [%s]', $mbox )); } } /** * Clear the cache. * * @since 2.9.0 * * @param integer $lifetime Only delete entries older than this (in * seconds). If null, deletes all entries. */ public function clear($lifetime = null) { $this->_backend->clear($lifetime); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/DateTime.php0000664000175000017500000000702513150761653021436 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_DateTime extends DateTime { /** */ public function __construct($time = null, $tz = null) { /* See https://bugs.php.net/bug.php?id=67118 */ $bug_67118 = (version_compare(PHP_VERSION, '5.6', '>=')) || in_array(PHP_VERSION, array('5.4.29', '5.5.13')); $tz = new DateTimeZone('UTC'); /* Bug #14381 Catch malformed offset - which doesn't cause DateTime to throw exception. */ if (substr(rtrim($time), -5) === ' 0000') { $time = substr(trim($time), 0, strlen(trim($time)) - 5) . ' +0000'; try { if ($bug_67118) { new DateTime($time, $tz); } parent::__construct($time, $tz); return; } catch (Exception $e) {} } try { if ($bug_67118) { new DateTime($time, $tz); } parent::__construct($time, $tz); return; } catch (Exception $e) {} /* Check for malformed day-of-week parts, usually incorrectly * localized. E.g. Fr, 15 Apr 2016 15:15:09 +0000 */ if (!preg_match("/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun),/", $time)) { $time = preg_replace("/^(\S*,)/", '', $time, 1, $i); if ($i) { try { if ($bug_67118) { new DateTime($time, $tz); } parent::__construct($time, $tz); return; } catch (Exception $e) {} } } /* Bug #5717 - Check for UT vs. UTC. */ if (substr(rtrim($time), -3) === ' UT') { try { if ($bug_67118) { new DateTime($time . 'C', $tz); } parent::__construct($time . 'C', $tz); return; } catch (Exception $e) {} } /* Bug #9847 - Catch paranthesized timezone information at end of date * string. */ $date = preg_replace("/\s*\([^\)]+\)\s*$/", '', $time, -1, $i); if ($i) { try { if ($bug_67118) { new DateTime($date, $tz); } parent::__construct($date, $tz); return; } catch (Exception $e) {} } parent::__construct('@-1', $tz); } /** * String representation: UNIX timestamp. */ public function __toString() { return $this->error() ? '0' : strval($this->getTimestamp()); } /** * Was this an unparseable date? * * @return boolean True if unparseable. */ public function error() { return ($this->getTimestamp() === -1); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Exception.php0000664000175000017500000001527613150761653021707 0ustar janjan * @category Horde * @copyright 2008-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Exception extends Horde_Exception_Wrapped { /* Error message codes. */ /** * Unspecified error (DEFAULT). */ const UNSPECIFIED = 0; /** * There was an unrecoverable error in UTF7IMAP -> UTF8 conversion. */ const UTF7IMAP_CONVERSION = 3; /** * The server ended the connection. */ const DISCONNECT = 4; /** * The charset used in the search query is not supported on the * server. */ const BADCHARSET = 5; /** * There were errors parsing the MIME/RFC 2822 header of the part. */ const PARSEERROR = 6; /** * The server could not decode the MIME part (see RFC 3516). */ const UNKNOWNCTE = 7; /** * The comparator specified by setComparator() was not recognized by the * IMAP server */ const BADCOMPARATOR = 9; /** * RFC 7162 [3.1.2.2] - All mailboxes are not required to support * mod-sequences. */ const MBOXNOMODSEQ = 10; /** * Thrown if server denies the network connection. */ const SERVER_CONNECT = 11; /** * Thrown if read error for server response. */ const SERVER_READERROR = 12; /** * Thrown if write error in server interaction. */ const SERVER_WRITEERROR = 16; /** * Thrown on CATENATE if the URL is invalid. */ const CATENATE_BADURL = 13; /** * Thrown on CATENATE if the message was too big. */ const CATENATE_TOOBIG = 14; /** * Thrown on CREATE if special-use attribute is not supported. */ const USEATTR = 15; /** * The user did not have permissions to carry out the operation. */ const NOPERM = 17; /** * The operation was not successful because another user is holding * a necessary resource. The operation may succeed if attempted later. */ const INUSE = 18; /** * The operation failed because data on the server was corrupt. */ const CORRUPTION = 19; /** * The operation failed because it exceeded some limit on the server. */ const LIMIT = 20; /** * The operation failed because the user is over their quota. */ const OVERQUOTA = 21; /** * The operation failed because the requested creation object already * exists. */ const ALREADYEXISTS = 22; /** * The operation failed because the requested deletion object did not * exist. */ const NONEXISTENT = 23; /** * Setting metadata failed because the size of its value is too large. * The maximum octet count the server is willing to accept will be * in the exception message string. */ const METADATA_MAXSIZE = 24; /** * Setting metadata failed because the maximum number of allowed * annotations has already been reached. */ const METADATA_TOOMANY = 25; /** * Setting metadata failed because the server does not support private * annotations on one of the specified mailboxes. */ const METADATA_NOPRIVATE = 26; /** * Invalid metadata entry. */ const METADATA_INVALID = 27; // Login failures /** * Could not start mandatory TLS connection. */ const LOGIN_TLSFAILURE = 100; /** * Could not find an available authentication method. */ const LOGIN_NOAUTHMETHOD = 101; /** * Generic authentication failure. */ const LOGIN_AUTHENTICATIONFAILED = 102; /** * Remote server is unavailable. */ const LOGIN_UNAVAILABLE = 103; /** * Authentication succeeded, but authorization failed. */ const LOGIN_AUTHORIZATIONFAILED = 104; /** * Authentication is no longer permitted with this passphrase. */ const LOGIN_EXPIRED = 105; /** * Login requires privacy. */ const LOGIN_PRIVACYREQUIRED = 106; /** * Server verification failed (SCRAM authentication). */ const LOGIN_SERVER_VERIFICATION_FAILED = 107; // Mailbox access failures /** * Could not open/access mailbox */ const MAILBOX_NOOPEN = 200; /** * Could not complete the command because the mailbox is read-only */ const MAILBOX_READONLY = 201; // POP3 specific error codes /** * Temporary issue. Generally, there is no need to alarm the user for * errors of this type. */ const POP3_TEMP_ERROR = 300; /** * Permanent error indicated by server. */ const POP3_PERM_ERROR = 301; // Unsupported feature error codes /** * Function/feature is not supported on this server. */ const NOT_SUPPORTED = 400; /** * Raw error message (in English). * * @since 2.18.0 * * @var string */ public $raw_msg = ''; /** * Constructor. * * @param string $message Error message (non-translated). * @param code $code Error code. */ public function __construct($message = null, $code = null) { parent::__construct($message, $code); $this->raw_msg = $this->message; try { $this->message = Horde_Imap_Client_Translation::t($this->message); } catch (Horde_Translation_Exception $e) {} } /** * Allow the error message to be altered. * * @param string $msg Error message. */ public function setMessage($msg) { $this->message = strval($msg); } /** * Allow the error code to be altered. * * @param integer $code Error code. */ public function setCode($code) { $this->code = intval($code); } /** * Perform substitution of variables in the error message. * * Needed to allow for correct translation of error message. * * @since 2.22.0 * * @param array $args Arguments used for substitution. */ public function messagePrintf(array $args = array()) { $this->raw_msg = vsprintf($this->raw_msg, $args); $this->message = vsprintf($this->message, $args); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Ids.php0000664000175000017500000002737213150761653020470 0ustar janjan * @category Horde * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * * @property-read boolean $all Does this represent an ALL message set? * @property-read array $ids The list of IDs. * @property-read boolean $largest Does this represent the largest ID in use? * @property-read string $max The largest ID (@since 2.20.0). * @property-read string $min The smallest ID (@since 2.20.0). * @property-read string $range_string Generates a range string consisting of * all messages between begin and end of * ID list. * @property-read boolean $search_res Does this represent a search result? * @property-read boolean $sequence Are these sequence IDs? If false, these * are UIDs. * @property-read boolean $special True if this is a "special" ID * representation. * @property-read string $tostring Return the non-sorted string * representation. * @property-read string $tostring_sort Return the sorted string * representation. */ class Horde_Imap_Client_Ids implements Countable, Iterator, Serializable { /** * "Special" representation constants. */ const ALL = "\01"; const SEARCH_RES = "\02"; const LARGEST = "\03"; /** * Allow duplicate IDs? * * @var boolean */ public $duplicates = false; /** * List of IDs. * * @var mixed */ protected $_ids = array(); /** * Are IDs message sequence numbers? * * @var boolean */ protected $_sequence = false; /** * Are IDs sorted? * * @var boolean */ protected $_sorted = false; /** * Constructor. * * @param mixed $ids See self::add(). * @param boolean $sequence Are $ids message sequence numbers? */ public function __construct($ids = null, $sequence = false) { $this->add($ids); $this->_sequence = $sequence; } /** */ public function __get($name) { switch ($name) { case 'all': return ($this->_ids === self::ALL); case 'ids': return is_array($this->_ids) ? $this->_ids : array(); case 'largest': return ($this->_ids === self::LARGEST); case 'max': $this->sort(); return end($this->_ids); case 'min': $this->sort(); return reset($this->_ids); case 'range_string': if (!count($this)) { return ''; } $min = $this->min; $max = $this->max; return ($min == $max) ? $min : $min . ':' . $max; case 'search_res': return ($this->_ids === self::SEARCH_RES); case 'sequence': return (bool)$this->_sequence; case 'special': return is_string($this->_ids); case 'tostring': case 'tostring_sort': if ($this->all) { return '1:*'; } elseif ($this->largest) { return '*'; } elseif ($this->search_res) { return '$'; } return strval($this->_toSequenceString($name == 'tostring_sort')); } } /** */ public function __toString() { return $this->tostring; } /** * Add IDs to the current object. * * @param mixed $ids Either self::ALL, self::SEARCH_RES, self::LARGEST, * Horde_Imap_Client_Ids object, array, or sequence * string. */ public function add($ids) { if (!is_null($ids)) { if (is_string($ids) && in_array($ids, array(self::ALL, self::SEARCH_RES, self::LARGEST))) { $this->_ids = $ids; } elseif ($add = $this->_resolveIds($ids)) { if (is_array($this->_ids) && !empty($this->_ids)) { foreach ($add as $val) { $this->_ids[] = $val; } } else { $this->_ids = $add; } if (!$this->duplicates) { $this->_ids = (count($this->_ids) > 25000) ? array_unique($this->_ids) : array_keys(array_flip($this->_ids)); } } $this->_sorted = is_array($this->_ids) && (count($this->_ids) === 1); } } /** * Removed IDs from the current object. * * @since 2.17.0 * * @param mixed $ids Either Horde_Imap_Client_Ids object, array, or * sequence string. */ public function remove($ids) { if (!$this->isEmpty() && ($remove = $this->_resolveIds($ids))) { $this->_ids = array_diff($this->_ids, array_unique($remove)); } } /** * Is this object empty (i.e. does not contain IDs)? * * @return boolean True if object is empty. */ public function isEmpty() { return (is_array($this->_ids) && !count($this->_ids)); } /** * Reverses the order of the IDs. */ public function reverse() { if (is_array($this->_ids)) { $this->_ids = array_reverse($this->_ids); } } /** * Sorts the IDs. */ public function sort() { if (!$this->_sorted && is_array($this->_ids)) { $this->_sort($this->_ids); $this->_sorted = true; } } /** * Sorts the IDs numerically. * * @param array $ids The array list. */ protected function _sort(&$ids) { sort($ids, SORT_NUMERIC); } /** * Split the sequence string at an approximate length. * * @since 2.7.0 * * @param integer $length Length to split. * * @return array A list containing individual sequence strings. */ public function split($length) { $id = new Horde_Stream_Temp(); $id->add($this->tostring_sort, true); $out = array(); do { $out[] = $id->substring(0, $length) . $id->getToChar(','); } while (!$id->eof()); return $out; } /** * Resolve the $ids input to add() and remove(). * * @param mixed $ids Either Horde_Imap_Client_Ids object, array, or * sequence string. * * @return array An array of IDs. */ protected function _resolveIds($ids) { if ($ids instanceof Horde_Imap_Client_Ids) { return $ids->ids; } elseif (is_array($ids)) { return $ids; } elseif (is_string($ids) || is_integer($ids)) { return is_numeric($ids) ? array($ids) : $this->_fromSequenceString($ids); } return array(); } /** * Create an IMAP message sequence string from a list of indices. * * Index Format: range_start:range_end,uid,uid2,... * * @param boolean $sort Numerically sort the IDs before creating the * range? * * @return string The IMAP message sequence string. */ protected function _toSequenceString($sort = true) { if (empty($this->_ids)) { return ''; } $in = $this->_ids; if ($sort && !$this->_sorted) { $this->_sort($in); } $first = $last = array_shift($in); $i = count($in) - 1; $out = array(); foreach ($in as $key => $val) { if (($last + 1) == $val) { $last = $val; } if (($i == $key) || ($last != $val)) { if ($last == $first) { $out[] = $first; if ($i == $key) { $out[] = $val; } } else { $out[] = $first . ':' . $last; if (($i == $key) && ($last != $val)) { $out[] = $val; } } $first = $last = $val; } } return empty($out) ? $first : implode(',', $out); } /** * Parse an IMAP message sequence string into a list of indices. * * @see _toSequenceString() * * @param string $str The IMAP message sequence string. * * @return array An array of indices. */ protected function _fromSequenceString($str) { $ids = array(); $str = trim($str); if (!strlen($str)) { return $ids; } $idarray = explode(',', $str); foreach ($idarray as $val) { $range = explode(':', $val); if (isset($range[1])) { for ($i = min($range), $j = max($range); $i <= $j; ++$i) { $ids[] = $i; } } else { $ids[] = $val; } } return $ids; } /* Countable methods. */ /** */ public function count() { return is_array($this->_ids) ? count($this->_ids) : 0; } /* Iterator methods. */ /** */ public function current() { return is_array($this->_ids) ? current($this->_ids) : null; } /** */ public function key() { return is_array($this->_ids) ? key($this->_ids) : null; } /** */ public function next() { if (is_array($this->_ids)) { next($this->_ids); } } /** */ public function rewind() { if (is_array($this->_ids)) { reset($this->_ids); } } /** */ public function valid() { return !is_null($this->key()); } /* Serializable methods. */ /** */ public function serialize() { $save = array(); if ($this->duplicates) { $save['d'] = 1; } if ($this->_sequence) { $save['s'] = 1; } if ($this->_sorted) { $save['is'] = 1; } switch ($this->_ids) { case self::ALL: $save['a'] = true; break; case self::LARGEST: $save['l'] = true; break; case self::SEARCH_RES: $save['sr'] = true; break; default: $save['i'] = strval($this); break; } return serialize($save); } /** */ public function unserialize($data) { $save = @unserialize($data); $this->duplicates = !empty($save['d']); $this->_sequence = !empty($save['s']); $this->_sorted = !empty($save['is']); if (isset($save['a'])) { $this->_ids = self::ALL; } elseif (isset($save['l'])) { $this->_ids = self::LARGEST; } elseif (isset($save['sr'])) { $this->_ids = self::SEARCH_RES; } elseif (isset($save['i'])) { $this->add($save['i']); } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Mailbox.php0000664000175000017500000000744113150761653021337 0ustar janjan * @category Horde * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * * @property-read string $list_escape Escapes mailbox for use in LIST * command (UTF-8). * @property-read string $utf7imap Mailbox in UTF7-IMAP. * @property-read string $utf8 Mailbox in UTF-8. */ class Horde_Imap_Client_Mailbox implements Serializable { /** * UTF7-IMAP representation of mailbox. * If boolean true, it is identical to UTF-8 representation. * * @var mixed */ protected $_utf7imap; /** * UTF8 representation of mailbox. * * @var string */ protected $_utf8; /** * Shortcut to obtaining mailbox object. * * @param string $mbox The mailbox name. * @param boolean $utf7imap Is mailbox UTF7-IMAP encoded? Otherwise, * mailbox is assumed to be UTF-8. * * @return Horde_Imap_Client_Mailbox A mailbox object. */ public static function get($mbox, $utf7imap = false) { return ($mbox instanceof Horde_Imap_Client_Mailbox) ? $mbox : new Horde_Imap_Client_Mailbox($mbox, $utf7imap); } /** * Constructor. * * @param string $mbox The mailbox name. * @param boolean $utf7imap Is mailbox UTF7-IMAP encoded (true). * Otherwise, mailbox is assumed to be UTF-8 * encoded. */ public function __construct($mbox, $utf7imap = false) { if (strcasecmp($mbox, 'INBOX') === 0) { $mbox = 'INBOX'; } if ($utf7imap) { $this->_utf7imap = $mbox; } else { $this->_utf8 = $mbox; } } /** */ public function __get($name) { switch ($name) { case 'list_escape': return preg_replace("/\*+/", '%', $this->utf8); case 'utf7imap': if (!isset($this->_utf7imap)) { $n = Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($this->_utf8); $this->_utf7imap = ($n == $this->_utf8) ? true : $n; } return ($this->_utf7imap === true) ? $this->_utf8 : $this->_utf7imap; case 'utf8': if (!isset($this->_utf8)) { $this->_utf8 = Horde_Imap_Client_Utf7imap::Utf7ImapToUtf8($this->_utf7imap); if ($this->_utf8 == $this->_utf7imap) { $this->_utf7imap = true; } } return (string)$this->_utf8; } } /** */ public function __toString() { return $this->utf8; } /** * Compares this mailbox to another mailbox string. * * @return boolean True if the items are equal. */ public function equals($mbox) { return ($this->utf8 == $mbox); } /* Serializable methods. */ /** */ public function serialize() { return json_encode(array($this->_utf7imap, $this->_utf8)); } /** */ public function unserialize($data) { list($this->_utf7imap, $this->_utf8) = json_decode($data, true); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Socket.php0000664000175000017500000054732513150761653021206 0ustar janjan * - RFC 2086/4314: ACL * - RFC 2087: QUOTA * - RFC 2088: LITERAL+ * - RFC 2195: AUTH=CRAM-MD5 * - RFC 2221: LOGIN-REFERRALS * - RFC 2342: NAMESPACE * - RFC 2595/4616: TLS & AUTH=PLAIN * - RFC 2831: DIGEST-MD5 authentication mechanism (obsoleted by RFC 6331) * - RFC 2971: ID * - RFC 3348: CHILDREN * - RFC 3501: IMAP4rev1 specification * - RFC 3502: MULTIAPPEND * - RFC 3516: BINARY * - RFC 3691: UNSELECT * - RFC 4315: UIDPLUS * - RFC 4422: SASL Authentication (for DIGEST-MD5) * - RFC 4466: Collected extensions (updates RFCs 2088, 3501, 3502, 3516) * - RFC 4469/5550: CATENATE * - RFC 4731: ESEARCH * - RFC 4959: SASL-IR * - RFC 5032: WITHIN * - RFC 5161: ENABLE * - RFC 5182: SEARCHRES * - RFC 5255: LANGUAGE/I18NLEVEL * - RFC 5256: THREAD/SORT * - RFC 5258: LIST-EXTENDED * - RFC 5267: ESORT; PARTIAL search return option * - RFC 5464: METADATA * - RFC 5530: IMAP Response Codes * - RFC 5802: AUTH=SCRAM-SHA-1 * - RFC 5819: LIST-STATUS * - RFC 5957: SORT=DISPLAY * - RFC 6154: SPECIAL-USE/CREATE-SPECIAL-USE * - RFC 6203: SEARCH=FUZZY * - RFC 6851: MOVE * - RFC 6855: UTF8=ACCEPT/UTF8=ONLY * - RFC 6858: DOWNGRADED response code * - RFC 7162: CONDSTORE/QRESYNC *
* * Implements the following non-RFC extensions: *
 *   - draft-ietf-morg-inthread-01: THREAD=REFS
 *   - draft-daboo-imap-annotatemore-07: ANNOTATEMORE
 *   - draft-daboo-imap-annotatemore-08: ANNOTATEMORE2
 *   - XIMAPPROXY
 *     Requires imapproxy v1.2.7-rc1 or later
 *     See https://squirrelmail.svn.sourceforge.net/svnroot/squirrelmail/trunk/imap_proxy/README
 *   - AUTH=XOAUTH2
 *     https://developers.google.com/gmail/xoauth2_protocol
 * 
* * TODO (or not necessary?): *
 *   - RFC 2177: IDLE
 *   - RFC 2193: MAILBOX-REFERRALS
 *   - RFC 4467/5092/5524/5550/5593: URLAUTH, URLAUTH=BINARY, URL-PARTIAL
 *   - RFC 4978: COMPRESS=DEFLATE
 *     See: http://bugs.php.net/bug.php?id=48725
 *   - RFC 5257: ANNOTATE (Experimental)
 *   - RFC 5259: CONVERT
 *   - RFC 5267: CONTEXT=SEARCH; CONTEXT=SORT
 *   - RFC 5465: NOTIFY
 *   - RFC 5466: FILTERS
 *   - RFC 6785: IMAPSIEVE
 *   - RFC 7377: MULTISEARCH
 * 
* * @author Michael Slusarz * @category Horde * @copyright 1999-2007 The SquirrelMail Project Team * @copyright 2005-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Socket extends Horde_Imap_Client_Base { /** * Cache names used exclusively within this class. */ const CACHE_FLAGS = 'HICflags'; /** * Queued commands to send to the server. * * @var array */ protected $_cmdQueue = array(); /** * The default ports to use for a connection. * * @var array */ protected $_defaultPorts = array(143, 993); /** * Mapping of status fields to IMAP names. * * @var array */ protected $_statusFields = array( 'messages' => Horde_Imap_Client::STATUS_MESSAGES, 'recent' => Horde_Imap_Client::STATUS_RECENT, 'uidnext' => Horde_Imap_Client::STATUS_UIDNEXT, 'uidvalidity' => Horde_Imap_Client::STATUS_UIDVALIDITY, 'unseen' => Horde_Imap_Client::STATUS_UNSEEN, 'firstunseen' => Horde_Imap_Client::STATUS_FIRSTUNSEEN, 'flags' => Horde_Imap_Client::STATUS_FLAGS, 'permflags' => Horde_Imap_Client::STATUS_PERMFLAGS, 'uidnotsticky' => Horde_Imap_Client::STATUS_UIDNOTSTICKY, 'highestmodseq' => Horde_Imap_Client::STATUS_HIGHESTMODSEQ ); /** * The unique tag to use when making an IMAP query. * * @var integer */ protected $_tag = 0; /** * @param array $params A hash containing configuration parameters. * Additional parameters to base driver: * - debug_literal: (boolean) If true, will output the raw text of * literal responses to the debug stream. Otherwise, * outputs a summary of the literal response. * - envelope_addrs: (integer) The maximum number of address entries to * read for FETCH ENVELOPE address fields. * DEFAULT: 1000 * - envelope_string: (integer) The maximum length of string fields * returned by the FETCH ENVELOPE command. * DEFAULT: 2048 * - xoauth2_token: (mixed) If set, will authenticate via the XOAUTH2 * mechanism (if available) with this token. Either a * string (since 2.13.0) or a * Horde_Imap_Client_Base_Password object (since * 2.14.0). */ public function __construct(array $params = array()) { parent::__construct(array_merge(array( 'debug_literal' => false, 'envelope_addrs' => 1000, 'envelope_string' => 2048 ), $params)); } /** */ public function __get($name) { switch ($name) { case 'search_charset': if (!isset($this->_init['search_charset']) && $this->_capability()->isEnabled('UTF8=ACCEPT')) { $this->_init['search_charset'] = new Horde_Imap_Client_Data_SearchCharset_Utf8(); } break; } return parent::__get($name); } /** */ public function getParam($key) { switch ($key) { case 'xoauth2_token': if (isset($this->_params[$key]) && ($this->_params[$key] instanceof Horde_Imap_Client_Base_Password)) { return $this->_params[$key]->getPassword(); } break; } return parent::getParam($key); } /** */ public function update(SplSubject $subject) { if (!empty($this->_init['imapproxy']) && ($subject instanceof Horde_Imap_Client_Data_Capability_Imap)) { $this->_setInit('enabled', $subject->isEnabled()); } return parent::update($subject); } /** */ protected function _initCapability() { // Need to use connect call here or else we run into loop issues // because _connect() can generate the capability object internally. $this->_connect(); // It is possible the server provided capability information on // connect, so check for it now. if (!isset($this->_init['capability'])) { $this->_sendCmd($this->_command('CAPABILITY')); } } /** * Parse a CAPABILITY Response (RFC 3501 [7.2.1]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param array $data An array of CAPABILITY strings. */ protected function _parseCapability( Horde_Imap_Client_Interaction_Pipeline $pipeline, $data ) { if (!empty($this->_temp['no_cap'])) { return; } $pipeline->data['capability_set'] = true; $c = new Horde_Imap_Client_Data_Capability_Imap(); foreach ($data as $val) { $cap_list = explode('=', $val); $c->add( $cap_list[0], isset($cap_list[1]) ? array($cap_list[1]) : null ); } $this->_setInit('capability', $c); } /** */ protected function _noop() { // NOOP doesn't return any specific response $this->_sendCmd($this->_command('NOOP')); } /** */ protected function _getNamespaces() { if ($this->_capability('NAMESPACE')) { $data = $this->_sendCmd($this->_command('NAMESPACE'))->data; if (isset($data['namespace'])) { return $data['namespace']; } } return new Horde_Imap_Client_Namespace_List(); } /** * Parse a NAMESPACE response (RFC 2342 [5] & RFC 5255 [3.4]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Tokenize $data The NAMESPACE data. */ protected function _parseNamespace( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Tokenize $data ) { $namespace_array = array( Horde_Imap_Client_Data_Namespace::NS_PERSONAL, Horde_Imap_Client_Data_Namespace::NS_OTHER, Horde_Imap_Client_Data_Namespace::NS_SHARED ); $c = array(); // Per RFC 2342, response from NAMESPACE command is: // (PERSONAL NAMESPACES) (OTHER_USERS NAMESPACE) (SHARED NAMESPACES) foreach ($namespace_array as $val) { $entry = $data->next(); if (is_null($entry)) { continue; } while ($data->next() !== false) { $ob = Horde_Imap_Client_Mailbox::get($data->next(), true); $ns = new Horde_Imap_Client_Data_Namespace(); $ns->delimiter = $data->next(); $ns->name = strval($ob); $ns->type = $val; $c[strval($ob)] = $ns; // RFC 4466: NAMESPACE extensions while (($ext = $data->next()) !== false) { switch (Horde_String::upper($ext)) { case 'TRANSLATION': // RFC 5255 [3.4] - TRANSLATION extension $data->next(); $ns->translation = $data->next(); $data->next(); break; } } } } $pipeline->data['namespace'] = new Horde_Imap_Client_Namespace_List($c); } /** */ protected function _login() { $secure = $this->getParam('secure'); if (!empty($this->_temp['preauth'])) { unset($this->_temp['preauth']); /* Don't allow PREAUTH if we are requring secure access, since * PREAUTH cannot provide secure access. */ if (!$this->isSecureConnection() && ($secure !== false)) { $this->logout(); throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Could not open secure TLS connection to the IMAP server."), Horde_Imap_Client_Exception::LOGIN_TLSFAILURE ); } return $this->_loginTasks(); } /* Blank passwords are not allowed, so no need to even try * authentication to determine this. */ if (!strlen($this->getParam('password'))) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("No password provided."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED ); } $this->_connect(); $first_login = empty($this->_init['authmethod']); // Switch to secure channel if using TLS. if (!$this->isSecureConnection() && (($secure === 'tls') || (($secure === true) && $this->_capability('LOGINDISABLED')))) { if ($first_login && !$this->_capability('STARTTLS')) { /* We should never hit this - STARTTLS is required pursuant to * RFC 3501 [6.2.1]. */ throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Server does not support TLS connections."), Horde_Imap_Client_Exception::LOGIN_TLSFAILURE ); } // Switch over to a TLS connection. // STARTTLS returns no untagged response. $this->_sendCmd($this->_command('STARTTLS')); if (!$this->_connection->startTls()) { $this->logout(); throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Could not open secure TLS connection to the IMAP server."), Horde_Imap_Client_Exception::LOGIN_TLSFAILURE ); } $this->_debug->info('Successfully completed TLS negotiation.'); $this->setParam('secure', 'tls'); $secure = 'tls'; if ($first_login) { // Expire cached CAPABILITY information (RFC 3501 [6.2.1]) $this->_setInit('capability'); // Reset language (RFC 5255 [3.1]) $this->_setInit('lang'); } // Set language if using imapproxy if (!empty($this->_init['imapproxy'])) { $this->setLanguage(); } } /* If we reached this point and don't have a secure connection, then * a secure connections is not available. */ if (($secure === true) && !$this->isSecureConnection()) { $this->setParam('secure', false); $secure = false; } if ($first_login) { // Add authentication methods. $auth_mech = array(); $auth = array_flip($this->_capability()->getParams('AUTH')); // XOAUTH2 if (isset($auth['XOAUTH2']) && $this->getParam('xoauth2_token')) { $auth_mech[] = 'XOAUTH2'; } unset($auth['XOAUTH2']); /* 'AUTH=PLAIN' authentication always exists if under TLS (RFC 3501 * [7.2.1]; RFC 2595), even though we might get here with a * non-TLS secure connection too. Use it over all other * authentication methods, although we need to do sanity checking * since broken IMAP servers may not support as required - * fallback to LOGIN instead, if not explicitly disabled. */ if ($secure) { if (isset($auth['PLAIN'])) { $auth_mech[] = 'PLAIN'; unset($auth['PLAIN']); } elseif (!$this->_capability('LOGINDISABLED')) { $auth_mech[] = 'LOGIN'; } } // Check for supported SCRAM AUTH mechanisms. Preferred because it // provides verification of server authenticity. foreach (array_keys($auth) as $key) { switch ($key) { case 'SCRAM-SHA-1': $auth_mech[] = $key; unset($auth[$key]); break; } } // Check for supported CRAM AUTH mechanisms. foreach (array_keys($auth) as $key) { switch ($key) { case 'CRAM-SHA1': case 'CRAM-SHA256': $auth_mech[] = $key; unset($auth[$key]); break; } } // Prefer CRAM-MD5 over DIGEST-MD5, as the latter has been // obsoleted (RFC 6331). if (isset($auth['CRAM-MD5'])) { $auth_mech[] = 'CRAM-MD5'; } elseif (isset($auth['DIGEST-MD5'])) { $auth_mech[] = 'DIGEST-MD5'; } unset($auth['CRAM-MD5'], $auth['DIGEST-MD5']); // Add other auth mechanisms. $auth_mech = array_merge($auth_mech, array_keys($auth)); // Fall back to 'LOGIN' if available. if (!$secure && !$this->_capability('LOGINDISABLED')) { $auth_mech[] = 'LOGIN'; } if (empty($auth_mech)) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("No supported IMAP authentication method could be found."), Horde_Imap_Client_Exception::LOGIN_NOAUTHMETHOD ); } $auth_mech = array_unique($auth_mech); } else { $auth_mech = array($this->_init['authmethod']); } $login_err = null; foreach ($auth_mech as $method) { try { $resp = $this->_tryLogin($method); $data = $resp->data; $this->_setInit('authmethod', $method); unset($this->_temp['referralcount']); } catch (Horde_Imap_Client_Exception_ServerResponse $e) { $data = $e->resp_data; if (isset($data['loginerr'])) { $login_err = $data['loginerr']; } $resp = false; } catch (Horde_Imap_Client_Exception $e) { $resp = false; } // Check for login referral (RFC 2221) response - can happen for // an OK, NO, or BYE response. if (isset($data['referral'])) { foreach (array('host', 'port', 'username') as $val) { if (!is_null($data['referral']->$val)) { $this->setParam($val, $data['referral']->$val); } } if (!is_null($data['referral']->auth)) { $this->_setInit('authmethod', $data['referral']->auth); } if (!isset($this->_temp['referralcount'])) { $this->_temp['referralcount'] = 0; } // RFC 2221 [3] - Don't follow more than 10 levels of referral // without consulting the user. if (++$this->_temp['referralcount'] < 10) { $this->logout(); $this->_setInit('capability'); $this->_setInit('namespace'); return $this->login(); } unset($this->_temp['referralcount']); } if ($resp) { return $this->_loginTasks($first_login, $resp->data); } } /* Try again from scratch if authentication failed in an established, * previously-authenticated object. */ if (!empty($this->_init['authmethod'])) { $this->_setInit(); unset($this->_temp['no_cap']); try { return $this->_login(); } catch (Horde_Imap_Client_Exception $e) {} } /* Default to AUTHENTICATIONFAILED error (see RFC 5530[3]). */ if (is_null($login_err)) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Mail server denied authentication."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED ); } throw $login_err; } /** * Connects to the IMAP server. * * @throws Horde_Imap_Client_Exception */ protected function _connect() { if (!is_null($this->_connection)) { return; } try { $this->_connection = new Horde_Imap_Client_Socket_Connection_Socket( $this->getParam('hostspec'), $this->getParam('port'), $this->getParam('timeout'), $this->getParam('secure'), $this->getParam('context'), array( 'debug' => $this->_debug, 'debugliteral' => $this->getParam('debug_literal') ) ); } catch (Horde\Socket\Client\Exception $e) { $e2 = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error connecting to mail server."), Horde_Imap_Client_Exception::SERVER_CONNECT ); $e2->details = $e->details; throw $e2; } // If we already have capability information, don't re-set with // (possibly) limited information sent in the initial banner. if (isset($this->_init['capability'])) { $this->_temp['no_cap'] = true; } /* Get greeting information (untagged response). */ try { $this->_getLine($this->_pipeline()); } catch (Horde_Imap_Client_Exception_ServerResponse $e) { if ($e->status === Horde_Imap_Client_Interaction_Server::BYE) { /* Server is explicitly rejecting our connection (RFC 3501 * [7.1.5]). */ $e->setMessage(Horde_Imap_Client_Translation::r("Server rejected connection.")); $e->setCode(Horde_Imap_Client_Exception::SERVER_CONNECT); } throw $e; } // Check for IMAP4rev1 support if (!$this->_capability('IMAP4REV1')) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("The mail server does not support IMAP4rev1 (RFC 3501)."), Horde_Imap_Client_Exception::SERVER_CONNECT ); } // Set language if NOT using imapproxy if (empty($this->_init['imapproxy'])) { if ($this->_capability('XIMAPPROXY')) { $this->_setInit('imapproxy', true); } else { $this->setLanguage(); } } // If pre-authenticated, we need to do all login tasks now. if (!empty($this->_temp['preauth'])) { $this->login(); } } /** * Authenticate to the IMAP server. * * @param string $method IMAP login method. * * @return Horde_Imap_Client_Interaction_Pipeline Pipeline object. * * @throws Horde_Imap_Client_Exception */ protected function _tryLogin($method) { $username = $this->getParam('username'); $password = $this->getParam('password'); switch ($method) { case 'CRAM-MD5': case 'CRAM-SHA1': case 'CRAM-SHA256': // RFC 2195: CRAM-MD5 // CRAM-SHA1 & CRAM-SHA256 supported by Courier SASL library $args = array( $username, Horde_String::lower(substr($method, 5)), $password ); $cmd = $this->_command('AUTHENTICATE')->add(array( $method, new Horde_Imap_Client_Interaction_Command_Continuation(function($ob) use ($args) { return new Horde_Imap_Client_Data_Format_List( base64_encode($args[0] . ' ' . hash_hmac($args[1], base64_decode($ob->token->current()), $args[2], false)) ); }) )); $cmd->debug = array( null, sprintf('[AUTHENTICATE response (username: %s)]', $username) ); break; case 'DIGEST-MD5': // RFC 2831/4422; obsoleted by RFC 6331 // Need $args because PHP 5.3 doesn't allow access to $this in // anonymous functions. $args = array( $username, $password, $this->getParam('hostspec') ); $cmd = $this->_command('AUTHENTICATE')->add(array( $method, new Horde_Imap_Client_Interaction_Command_Continuation(function($ob) use ($args) { return new Horde_Imap_Client_Data_Format_List( base64_encode(new Horde_Imap_Client_Auth_DigestMD5( $args[0], $args[1], base64_decode($ob->token->current()), $args[2], 'imap' )) ); }), new Horde_Imap_Client_Interaction_Command_Continuation(function($ob) { if (strpos(base64_decode($ob->token->current()), 'rspauth=') === false) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Unexpected response from server when authenticating."), Horde_Imap_Client_Exception::SERVER_CONNECT ); } return new Horde_Imap_Client_Data_Format_List(); }) )); $cmd->debug = array( null, sprintf('[AUTHENTICATE Response (username: %s)]', $username), null ); break; case 'LOGIN': /* See, e.g., RFC 6855 [5] - LOGIN command does not support * non-ASCII characters. If we reach this point, treat as an * authentication failure. */ try { $username = new Horde_Imap_Client_Data_Format_Astring($username); $password = new Horde_Imap_Client_Data_Format_Astring($password); } catch (Horde_Imap_Client_Data_Format_Exception $e) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Authentication failed."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED ); } $cmd = $this->_command('LOGIN')->add(array( $username, $password )); $cmd->debug = array( sprintf('LOGIN %s [PASSWORD]', $username) ); break; case 'PLAIN': // RFC 2595/4616 - PLAIN SASL mechanism $cmd = $this->_authInitialResponse( $method, base64_encode(implode("\0", array( $username, $username, $password ))), $username ); break; case 'SCRAM-SHA-1': $scram = new Horde_Imap_Client_Auth_Scram( $username, $password, 'SHA1' ); $cmd = $this->_authInitialResponse( $method, base64_encode($scram->getClientFirstMessage()) ); $cmd->add( new Horde_Imap_Client_Interaction_Command_Continuation(function($ob) use ($scram) { $sr1 = base64_decode($ob->token->current()); return new Horde_Imap_Client_Data_Format_List( $scram->parseServerFirstMessage($sr1) ? base64_encode($scram->getClientFinalMessage()) : '*' ); }) ); $self = $this; $cmd->add( new Horde_Imap_Client_Interaction_Command_Continuation(function($ob) use ($scram, $self) { $sr2 = base64_decode($ob->token->current()); if (!$scram->parseServerFinalMessage($sr2)) { /* This means authentication passed, according to the * server, but the server signature is incorrect. * This indicates that server verification has failed. * Immediately disconnect from the server, since this * is a possible security issue. */ $self->logout(); throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Server failed verification check."), Horde_Imap_Client_Exception::LOGIN_SERVER_VERIFICATION_FAILED ); } return new Horde_Imap_Client_Data_Format_List(); }) ); break; case 'XOAUTH2': // Google XOAUTH2 $cmd = $this->_authInitialResponse( $method, $this->getParam('xoauth2_token') ); /* This is an optional command continuation. XOAUTH2 will return * error information in continuation response. */ $error_continuation = new Horde_Imap_Client_Interaction_Command_Continuation( function($ob) { return new Horde_Imap_Client_Data_Format_List(); } ); $error_continuation->optional = true; $cmd->add($error_continuation); break; default: $e = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Unknown authentication method: %s"), Horde_Imap_Client_Exception::SERVER_CONNECT ); $e->messagePrintf(array($method)); throw $e; } return $this->_sendCmd($this->_pipeline($cmd)); } /** * Create the AUTHENTICATE command for the initial client response. * * @param string $method AUTHENTICATE SASL method. * @param string $ir Initial client response. * @param string $username If set, log a username message in debug log * instead of raw data. * * @return Horde_Imap_Client_Interaction_Command A command object. */ protected function _authInitialResponse($method, $ir, $username = null) { $cmd = $this->_command('AUTHENTICATE')->add($method); if ($this->_capability('SASL-IR')) { // IMAP Extension for SASL Initial Client Response (RFC 4959) $cmd->add($ir); if ($username) { $cmd->debug = array( sprintf('AUTHENTICATE %s [INITIAL CLIENT RESPONSE (username: %s)]', $method, $username) ); } } else { $cmd->add( new Horde_Imap_Client_Interaction_Command_Continuation(function($ob) use ($ir) { return new Horde_Imap_Client_Data_Format_List($ir); }) ); if ($username) { $cmd->debug = array( null, sprintf('[INITIAL CLIENT RESPONSE (username: %s)]', $username) ); } } return $cmd; } /** * Perform login tasks. * * @param boolean $firstlogin Is this the first login? * @param array $resp The data response from the login command. * May include: * - capability_set: (boolean) True if CAPABILITY was set after login. * - proxyreuse: (boolean) True if re-used connection via imapproxy. * * @return boolean True if global login tasks should be performed. */ protected function _loginTasks($firstlogin = true, array $resp = array()) { /* If reusing an imapproxy connection, no need to do any of these * login tasks again. */ if (!$firstlogin && !empty($resp['proxyreuse'])) { if (isset($this->_init['enabled'])) { foreach ($this->_init['enabled'] as $val) { $this->_capability()->enable($val); } } // If we have not yet set the language, set it now. if (!isset($this->_init['lang'])) { $this->_temp['lang_queue'] = true; $this->setLanguage(); unset($this->_temp['lang_queue']); } return false; } /* If we logged in for first time, and server did not return * capability information, we need to mark for retrieval. */ if ($firstlogin && empty($resp['capability_set'])) { $this->_setInit('capability'); } $this->_temp['lang_queue'] = true; $this->setLanguage(); unset($this->_temp['lang_queue']); /* Only active QRESYNC/CONDSTORE if caching is enabled. */ $enable = array(); if ($this->_initCache()) { if ($this->_capability('QRESYNC')) { $enable[] = 'QRESYNC'; } elseif ($this->_capability('CONDSTORE')) { $enable[] = 'CONDSTORE'; } } /* Use UTF8=ACCEPT, if available. */ if ($this->_capability('UTF8', 'ACCEPT')) { $enable[] = 'UTF8=ACCEPT'; } $this->_enable($enable); return true; } /** */ protected function _logout() { if (empty($this->_temp['logout'])) { /* If using imapproxy, force sending these commands, since they * may not be sent again if they are (likely) initialization * commands. */ if (!empty($this->_cmdQueue) && !empty($this->_init['imapproxy'])) { $this->_sendCmd($this->_pipeline()); } $this->_temp['logout'] = true; try { $this->_sendCmd($this->_command('LOGOUT')); } catch (Horde_Imap_Client_Exception_ServerResponse $e) { // Ignore server errors } unset($this->_temp['logout']); } } /** */ protected function _sendID($info) { $cmd = $this->_command('ID'); if (empty($info)) { $cmd->add(new Horde_Imap_Client_Data_Format_Nil()); } else { $tmp = new Horde_Imap_Client_Data_Format_List(); foreach ($info as $key => $val) { $tmp->add(array( new Horde_Imap_Client_Data_Format_String(Horde_String::lower($key)), new Horde_Imap_Client_Data_Format_Nstring($val) )); } $cmd->add($tmp); } $temp = &$this->_temp; /* Add to queue - this doesn't need to be sent immediately. */ $cmd->on_error = function() use (&$temp) { /* Ignore server errors. E.g. Cyrus returns this: * 001 NO Only one Id allowed in non-authenticated state * even though NO is not allowed in RFC 2971[3.1]. */ $temp['id'] = array(); return true; }; $cmd->on_success = function() use ($cmd, &$temp) { $temp['id'] = $cmd->pipeline->data['id']; }; $this->_cmdQueue[] = $cmd; } /** * Parse an ID response (RFC 2971 [3.2]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Tokenize $data The server response. */ protected function _parseID( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Tokenize $data ) { if (!isset($pipeline->data['id'])) { $pipeline->data['id'] = array(); } if (!is_null($data->next())) { while (($curr = $data->next()) !== false) { if (!is_null($id = $data->next())) { $pipeline->data['id'][$curr] = $id; } } } } /** */ protected function _getID() { if (!isset($this->_temp['id'])) { $this->sendID(); /* ID is queued - force sending the queued command. */ $this->_sendCmd($this->_pipeline()); } return $this->_temp['id']; } /** */ protected function _setLanguage($langs) { $cmd = $this->_command('LANGUAGE'); foreach ($langs as $lang) { $cmd->add(new Horde_Imap_Client_Data_Format_Astring($lang)); } if (!empty($this->_temp['lang_queue'])) { $this->_cmdQueue[] = $cmd; return array(); } try { $this->_sendCmd($cmd); } catch (Horde_Imap_Client_Exception $e) { $this->_setInit('lang', false); return null; } return $this->_init['lang']; } /** */ protected function _getLanguage($list) { if (!$list) { return empty($this->_init['lang']) ? null : $this->_init['lang']; } if (!isset($this->_init['langavail'])) { try { $this->_sendCmd($this->_command('LANGUAGE')); } catch (Horde_Imap_Client_Exception $e) { $this->_setInit('langavail', array()); } } return $this->_init['langavail']; } /** * Parse a LANGUAGE response (RFC 5255 [3.3]). * * @param Horde_Imap_Client_Tokenize $data The server response. */ protected function _parseLanguage(Horde_Imap_Client_Tokenize $data) { $lang_list = $data->flushIterator(); if (count($lang_list) === 1) { // This is the language that was set. $this->_setInit('lang', reset($lang_list)); } else { // These are the languages that are available. $this->_setInit('langavail', $lang_list); } } /** * Enable an IMAP extension (see RFC 5161). * * @param array $exts The extensions to enable. * * @throws Horde_Imap_Client_Exception */ protected function _enable($exts) { if (!empty($exts) && $this->_capability('ENABLE')) { $c = $this->_capability(); $todo = array(); // Only enable non-enabled extensions. foreach ($exts as $val) { if (!$c->isEnabled($val)) { $c->enable($val); $todo[] = $val; } } if (!empty($todo)) { $cmd = $this->_command('ENABLE')->add($todo); $cmd->on_error = function() use ($todo, $c) { /* Something went wrong... disable the extensions. */ foreach ($todo as $val) { $c->enable($val, false); } }; $this->_cmdQueue[] = $cmd; } } } /** * Parse an ENABLED response (RFC 5161 [3.2]). * * @param Horde_Imap_Client_Tokenize $data The server response. */ protected function _parseEnabled(Horde_Imap_Client_Tokenize $data) { $c = $this->_capability(); foreach ($data->flushIterator() as $val) { $c->enable($val); } } /** */ protected function _openMailbox(Horde_Imap_Client_Mailbox $mailbox, $mode) { $c = $this->_capability(); $qresync = $c->isEnabled('QRESYNC'); $cmd = $this->_command( ($mode == Horde_Imap_Client::OPEN_READONLY) ? 'EXAMINE' : 'SELECT' )->add( $this->_getMboxFormatOb($mailbox) ); $pipeline = $this->_pipeline($cmd); /* If QRESYNC is available, synchronize the mailbox. */ if ($qresync) { $this->_initCache(); $md = $this->_cache->getMetaData($mailbox, null, array(self::CACHE_MODSEQ, 'uidvalid')); /* CACHE_MODSEQ can be set but 0 (NOMODSEQ was returned). */ if (!empty($md[self::CACHE_MODSEQ])) { if ($uids = $this->_cache->get($mailbox)) { $uids = $this->getIdsOb($uids); /* Check for extra long UID string. Assume that any * server that can handle QRESYNC can also handle long * input strings (at least 8 KB), so 7 KB is as good as * any guess as to an upper limit. If this occurs, provide * a range string (min -> max) instead. */ if (strlen($uid_str = $uids->tostring_sort) > 7000) { $uid_str = $uids->range_string; } } else { $uid_str = null; } /* Several things can happen with a QRESYNC: * 1. UIDVALIDITY may have changed. If so, we need to expire * the cache immediately (done below). * 2. NOMODSEQ may have been returned. We can keep current * message cache data but won't be able to do flag caching. * 3. VANISHED/FETCH information was returned. These responses * will have already been handled by those response handlers. * 4. We are already synced with the local server in which * case it acts like a normal EXAMINE/SELECT. */ $cmd->add(new Horde_Imap_Client_Data_Format_List(array( 'QRESYNC', new Horde_Imap_Client_Data_Format_List(array_filter(array( $md['uidvalid'], $md[self::CACHE_MODSEQ], $uid_str ))) ))); } /* Let the 'CLOSED' response code handle mailbox switching if * QRESYNC is active. */ if ($this->_selected) { $pipeline->data['qresyncmbox'] = array($mailbox, $mode); } else { $this->_changeSelected($mailbox, $mode); } } else { if (!$c->isEnabled('CONDSTORE') && $this->_initCache() && $c->query('CONDSTORE')) { /* Activate CONDSTORE now if ENABLE is not available. */ $cmd->add(new Horde_Imap_Client_Data_Format_List('CONDSTORE')); $c->enable('CONDSTORE'); } $this->_changeSelected($mailbox, $mode); } try { $this->_sendCmd($pipeline); } catch (Horde_Imap_Client_Exception_ServerResponse $e) { // An EXAMINE/SELECT failure with a return of 'NO' will cause the // current mailbox to be unselected. if ($e->status === Horde_Imap_Client_Interaction_Server::NO) { $this->_changeSelected(null); $this->_mode = 0; if (!$e->getCode()) { $e = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Could not open mailbox \"%s\"."), Horde_Imap_Client_Exception::MAILBOX_NOOPEN ); $e->messagePrintf(array($mailbox)); } } throw $e; } if ($qresync) { /* Mailbox is fully sync'd. */ $this->_mailboxOb()->sync = true; } } /** */ protected function _createMailbox(Horde_Imap_Client_Mailbox $mailbox, $opts) { $cmd = $this->_command('CREATE')->add( $this->_getMboxFormatOb($mailbox) ); // RFC 6154 Sec. 3 if (!empty($opts['special_use'])) { $use = new Horde_Imap_Client_Data_Format_List('USE'); $use->add( new Horde_Imap_Client_Data_Format_List($opts['special_use']) ); $cmd->add($use); } // CREATE returns no untagged information (RFC 3501 [6.3.3]) $this->_sendCmd($cmd); } /** */ protected function _deleteMailbox(Horde_Imap_Client_Mailbox $mailbox) { // Some IMAP servers will not allow a delete of a currently open // mailbox. if ($mailbox->equals($this->_selected)) { $this->close(); } $cmd = $this->_command('DELETE')->add( $this->_getMboxFormatOb($mailbox) ); try { // DELETE returns no untagged information (RFC 3501 [6.3.4]) $this->_sendCmd($cmd); } catch (Horde_Imap_Client_Exception $e) { // Some IMAP servers won't allow a mailbox delete unless all // messages in that mailbox are deleted. $this->expunge($mailbox, array( 'delete' => true )); $this->_sendCmd($cmd); } } /** */ protected function _renameMailbox(Horde_Imap_Client_Mailbox $old, Horde_Imap_Client_Mailbox $new) { // Some IMAP servers will not allow a rename of a currently open // mailbox. if ($old->equals($this->_selected)) { $this->close(); } // RENAME returns no untagged information (RFC 3501 [6.3.5]) $this->_sendCmd( $this->_command('RENAME')->add(array( $this->_getMboxFormatOb($old), $this->_getMboxFormatOb($new) )) ); } /** */ protected function _subscribeMailbox(Horde_Imap_Client_Mailbox $mailbox, $subscribe) { // SUBSCRIBE/UNSUBSCRIBE returns no untagged information (RFC 3501 // [6.3.6 & 6.3.7]) $this->_sendCmd( $this->_command( $subscribe ? 'SUBSCRIBE' : 'UNSUBSCRIBE' )->add( $this->_getMboxFormatOb($mailbox) ) ); } /** */ protected function _listMailboxes($pattern, $mode, $options) { // RFC 5258 [3.1]: Use LSUB for MBOX_SUBSCRIBED if no other server // return options are specified. if (($mode == Horde_Imap_Client::MBOX_SUBSCRIBED) && !array_intersect(array_keys($options), array('attributes', 'children', 'recursivematch', 'remote', 'special_use', 'status'))) { return $this->_getMailboxList( $pattern, Horde_Imap_Client::MBOX_SUBSCRIBED, array( 'flat' => !empty($options['flat']), 'no_listext' => true ) ); } // Get the list of subscribed/unsubscribed mailboxes. Since LSUB is // not guaranteed to have correct attributes, we must use LIST to // ensure we receive the correct information. if (($mode != Horde_Imap_Client::MBOX_ALL) && !$this->_capability('LIST-EXTENDED')) { $subscribed = $this->_getMailboxList( $pattern, Horde_Imap_Client::MBOX_SUBSCRIBED, array('flat' => true) ); // If mode is subscribed, and 'flat' option is true, we can // return now. if (($mode == Horde_Imap_Client::MBOX_SUBSCRIBED) && !empty($options['flat'])) { return $subscribed; } } else { $subscribed = null; } return $this->_getMailboxList($pattern, $mode, $options, $subscribed); } /** * Obtain a list of mailboxes. * * @param array $pattern The mailbox search pattern(s). * @param integer $mode Which mailboxes to return. * @param array $options Additional options. 'no_listext' will skip * using the LIST-EXTENDED capability. * @param array $subscribed A list of subscribed mailboxes. * * @return array See listMailboxes((). * * @throws Horde_Imap_Client_Exception */ protected function _getMailboxList($pattern, $mode, $options, $subscribed = null) { // Setup entry for use in _parseList(). $pipeline = $this->_pipeline(); $pipeline->data['mailboxlist'] = array( 'ext' => false, 'mode' => $mode, 'opts' => $options, /* Can't use array_merge here because it will destroy any mailbox * name (key) that is "numeric". */ 'sub' => (is_null($subscribed) ? null : array_flip(array_map('strval', $subscribed)) + array('INBOX' => true)) ); $pipeline->data['listresponse'] = array(); $cmds = array(); $return_opts = new Horde_Imap_Client_Data_Format_List(); if ($this->_capability('LIST-EXTENDED') && empty($options['no_listext'])) { $cmd = $this->_command('LIST'); $pipeline->data['mailboxlist']['ext'] = true; $select_opts = new Horde_Imap_Client_Data_Format_List(); $subscribed = false; switch ($mode) { case Horde_Imap_Client::MBOX_ALL_SUBSCRIBED: case Horde_Imap_Client::MBOX_UNSUBSCRIBED: $return_opts->add('SUBSCRIBED'); break; case Horde_Imap_Client::MBOX_SUBSCRIBED: case Horde_Imap_Client::MBOX_SUBSCRIBED_EXISTS: $select_opts->add('SUBSCRIBED'); $return_opts->add('SUBSCRIBED'); $subscribed = true; break; } if (!empty($options['remote'])) { $select_opts->add('REMOTE'); } if (!empty($options['recursivematch'])) { $select_opts->add('RECURSIVEMATCH'); } if (!empty($select_opts)) { $cmd->add($select_opts); } $cmd->add(''); $tmp = new Horde_Imap_Client_Data_Format_List(); foreach ($pattern as $val) { if ($subscribed && (strcasecmp($val, 'INBOX') === 0)) { $cmds[] = $this->_command('LIST')->add(array( '', 'INBOX' )); } else { $tmp->add($this->_getMboxFormatOb($val, true)); } } if (count($tmp)) { $cmd->add($tmp); $cmds[] = $cmd; } if (!empty($options['children'])) { $return_opts->add('CHILDREN'); } if (!empty($options['special_use'])) { $return_opts->add('SPECIAL-USE'); } } else { foreach ($pattern as $val) { $cmds[] = $this->_command( ($mode == Horde_Imap_Client::MBOX_SUBSCRIBED) ? 'LSUB' : 'LIST' )->add(array( '', $this->_getMboxFormatOb($val, true) )); } } /* LIST-STATUS does NOT depend on LIST-EXTENDED. */ if (!empty($options['status']) && $this->_capability('LIST-STATUS')) { $available_status = array( Horde_Imap_Client::STATUS_MESSAGES, Horde_Imap_Client::STATUS_RECENT, Horde_Imap_Client::STATUS_UIDNEXT, Horde_Imap_Client::STATUS_UIDVALIDITY, Horde_Imap_Client::STATUS_UNSEEN, Horde_Imap_Client::STATUS_HIGHESTMODSEQ ); $status_opts = array(); foreach (array_intersect($this->_statusFields, $available_status) as $key => $val) { if ($options['status'] & $val) { $status_opts[] = $key; } } if (count($status_opts)) { $return_opts->add(array( 'STATUS', new Horde_Imap_Client_Data_Format_List( array_map('Horde_String::upper', $status_opts) ) )); } } foreach ($cmds as $val) { if (count($return_opts)) { $val->add(array( 'RETURN', $return_opts )); } $pipeline->add($val); } try { $lr = $this->_sendCmd($pipeline)->data['listresponse']; } catch (Horde_Imap_Client_Exception_ServerResponse $e) { /* Archiveopteryx 3.1.3 can't process empty list-select-opts list. * Retry using base IMAP4rev1 functionality. */ if (($e->status === Horde_Imap_Client_Interaction_Server::BAD) && $this->_capability('LIST-EXTENDED')) { $this->_capability()->remove('LIST-EXTENDED'); return $this->_listMailboxes($pattern, $mode, $options); } throw $e; } if (!empty($options['flat'])) { return array_values($lr); } /* Add in STATUS return, if needed. */ if (!empty($options['status']) && $this->_capability('LIST-STATUS')) { foreach ($pattern as $val) { $val_utf8 = Horde_Imap_Client_Utf7imap::Utf7ImapToUtf8($val); if (isset($lr[$val_utf8])) { $lr[$val_utf8]['status'] = $this->_prepareStatusResponse($status_opts, $val_utf8); } } } return $lr; } /** * Parse a LIST/LSUB response (RFC 3501 [7.2.2 & 7.2.3]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Tokenize $data The server response (includes * type as first token). * * @throws Horde_Imap_Client_Exception */ protected function _parseList( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Tokenize $data ) { $data->next(); $attr = null; $attr_raw = $data->flushIterator(); $delimiter = $data->next(); $mbox = Horde_Imap_Client_Mailbox::get( $data->next(), !$this->_capability()->isEnabled('UTF8=ACCEPT') ); $ml = $pipeline->data['mailboxlist']; switch ($ml['mode']) { case Horde_Imap_Client::MBOX_ALL_SUBSCRIBED: case Horde_Imap_Client::MBOX_SUBSCRIBED_EXISTS: case Horde_Imap_Client::MBOX_UNSUBSCRIBED: $attr = array_flip(array_map('Horde_String::lower', $attr_raw)); /* Subscribed list is in UTF-8. */ if (is_null($ml['sub']) && !isset($attr['\\subscribed']) && (strcasecmp($mbox, 'INBOX') === 0)) { $attr['\\subscribed'] = 1; } elseif (isset($ml['sub'][strval($mbox)])) { $attr['\\subscribed'] = 1; } break; } switch ($ml['mode']) { case Horde_Imap_Client::MBOX_SUBSCRIBED_EXISTS: if (isset($attr['\\nonexistent']) || !isset($attr['\\subscribed'])) { return; } break; case Horde_Imap_Client::MBOX_UNSUBSCRIBED: if (isset($attr['\\subscribed'])) { return; } break; } if (!empty($ml['opts']['flat'])) { $pipeline->data['listresponse'][] = $mbox; return; } $tmp = array( 'delimiter' => $delimiter, 'mailbox' => $mbox ); if ($attr || !empty($ml['opts']['attributes'])) { if (is_null($attr)) { $attr = array_flip(array_map('Horde_String::lower', $attr_raw)); } /* RFC 5258 [3.4]: inferred attributes. */ if ($ml['ext']) { if (isset($attr['\\noinferiors'])) { $attr['\\hasnochildren'] = 1; } if (isset($attr['\\nonexistent'])) { $attr['\\noselect'] = 1; } } $tmp['attributes'] = array_keys($attr); } if ($data->next() !== false) { $tmp['extended'] = $data->flushIterator(); } $pipeline->data['listresponse'][strval($mbox)] = $tmp; } /** */ protected function _status($mboxes, $flags) { $on_error = null; $out = $to_process = array(); $pipeline = $this->_pipeline(); $unseen_flags = array( Horde_Imap_Client::STATUS_FIRSTUNSEEN, Horde_Imap_Client::STATUS_UNSEEN ); foreach ($mboxes as $mailbox) { /* If FLAGS/PERMFLAGS/UIDNOTSTICKY/FIRSTUNSEEN are needed, we must * do a SELECT/EXAMINE to get this information (data will be * caught in the code below). */ if (($flags & Horde_Imap_Client::STATUS_FIRSTUNSEEN) || ($flags & Horde_Imap_Client::STATUS_FLAGS) || ($flags & Horde_Imap_Client::STATUS_PERMFLAGS) || ($flags & Horde_Imap_Client::STATUS_UIDNOTSTICKY)) { $this->openMailbox($mailbox); } $mbox_ob = $this->_mailboxOb($mailbox); $data = $query = array(); foreach ($this->_statusFields as $key => $val) { if (!($val & $flags)) { continue; } if ($val == Horde_Imap_Client::STATUS_HIGHESTMODSEQ) { $c = $this->_capability(); /* Don't include modseq returns if server does not support * it. */ if (!$c->query('CONDSTORE')) { continue; } /* Even though CONDSTORE is available, it may not yet have * been enabled. */ $c->enable('CONDSTORE'); $on_error = function() use ($c) { $c->enable('CONDSTORE', false); }; } if ($mailbox->equals($this->_selected)) { if (!is_null($tmp = $mbox_ob->getStatus($val))) { $data[$key] = $tmp; } elseif (($val == Horde_Imap_Client::STATUS_UIDNEXT) && ($flags & Horde_Imap_Client::STATUS_UIDNEXT_FORCE)) { /* UIDNEXT is not mandatory. */ if ($mbox_ob->getStatus(Horde_Imap_Client::STATUS_MESSAGES) == 0) { $data[$key] = 0; } else { $fquery = new Horde_Imap_Client_Fetch_Query(); $fquery->uid(); $fetch_res = $this->fetch($this->_selected, $fquery, array( 'ids' => $this->getIdsOb(Horde_Imap_Client_Ids::LARGEST) )); $data[$key] = $fetch_res->first()->getUid() + 1; } } elseif (in_array($val, $unseen_flags)) { /* RFC 3501 [6.3.1] - FIRSTUNSEEN information is not * mandatory. If missing in EXAMINE/SELECT results, we * need to do a search. An UNSEEN count also requires * a search. */ $squery = new Horde_Imap_Client_Search_Query(); $squery->flag(Horde_Imap_Client::FLAG_SEEN, false); $search = $this->search($mailbox, $squery, array( 'results' => array( Horde_Imap_Client::SEARCH_RESULTS_MIN, Horde_Imap_Client::SEARCH_RESULTS_COUNT ), 'sequence' => true )); $mbox_ob->setStatus(Horde_Imap_Client::STATUS_FIRSTUNSEEN, $search['min']); $mbox_ob->setStatus(Horde_Imap_Client::STATUS_UNSEEN, $search['count']); $data[$key] = $mbox_ob->getStatus($val); } } else { $query[] = $key; } } $out[strval($mailbox)] = $data; if (count($query)) { $cmd = $this->_command('STATUS')->add(array( $this->_getMboxFormatOb($mailbox), new Horde_Imap_Client_Data_Format_List( array_map('Horde_String::upper', $query) ) )); $cmd->on_error = $on_error; $pipeline->add($cmd); $to_process[] = array($query, $mailbox); } } if (count($pipeline)) { $this->_sendCmd($pipeline); foreach ($to_process as $val) { $out[strval($val[1])] += $this->_prepareStatusResponse($val[0], $val[1]); } } return $out; } /** * Parse a STATUS response (RFC 3501 [7.2.4]). * * @param Horde_Imap_Client_Tokenize $data Token data */ protected function _parseStatus(Horde_Imap_Client_Tokenize $data) { // Mailbox name is in UTF7-IMAP (unless UTF8 has been enabled). $mbox_ob = $this->_mailboxOb( Horde_Imap_Client_Mailbox::get( $data->next(), !$this->_capability()->isEnabled('UTF8=ACCEPT') ) ); $data->next(); while (($k = $data->next()) !== false) { $mbox_ob->setStatus( $this->_statusFields[Horde_String::lower($k)], $data->next() ); } } /** * Prepares a status response for a mailbox. * * @param array $request The status keys to return. * @param string $mailbox The mailbox to query. */ protected function _prepareStatusResponse($request, $mailbox) { $mbox_ob = $this->_mailboxOb($mailbox); $out = array(); foreach ($request as $val) { $out[$val] = $mbox_ob->getStatus($this->_statusFields[$val]); } return $out; } /** */ protected function _append(Horde_Imap_Client_Mailbox $mailbox, $data, $options) { $c = $this->_capability(); // Check for MULTIAPPEND extension (RFC 3502) if ((count($data) > 1) && !$c->query('MULTIAPPEND')) { $result = $this->getIdsOb(); foreach (array_keys($data) as $key) { $res = $this->_append($mailbox, array($data[$key]), $options); if (($res === true) || ($result === true)) { $result = true; } else { $result->add($res); } } return $result; } // Check for extensions. $binary = $c->query('BINARY'); $catenate = $c->query('CATENATE'); $utf8 = $c->isEnabled('UTF8=ACCEPT'); $asize = 0; $cmd = $this->_command('APPEND')->add( $this->_getMboxFormatOb($mailbox) ); $cmd->literal8 = true; foreach (array_keys($data) as $key) { if (!empty($data[$key]['flags'])) { $tmp = new Horde_Imap_Client_Data_Format_List(); foreach ($data[$key]['flags'] as $val) { /* Ignore recent flag. RFC 3501 [9]: flag definition */ if (strcasecmp($val, Horde_Imap_Client::FLAG_RECENT) !== 0) { $tmp->add($val); } } $cmd->add($tmp); } if (!empty($data[$key]['internaldate'])) { $cmd->add(new Horde_Imap_Client_Data_Format_DateTime($data[$key]['internaldate'])); } $adata = null; if (is_array($data[$key]['data'])) { if ($catenate) { $cmd->add('CATENATE'); $tmp = new Horde_Imap_Client_Data_Format_List(); } else { $data_stream = new Horde_Stream_Temp(); } foreach ($data[$key]['data'] as $v) { switch ($v['t']) { case 'text': if ($catenate) { $tdata = $this->_appendData($v['v'], $asize); if ($utf8) { /* RFC 6855 [4]: CATENATE UTF8 extension. */ $tdata->forceBinary(); $tmp->add(array( 'UTF8', new Horde_Imap_Client_Data_Format_List($tdata) )); } else { $tmp->add(array( 'TEXT', $tdata )); } } else { if (is_resource($v['v'])) { rewind($v['v']); } $data_stream->add($v['v']); } break; case 'url': if ($catenate) { $tmp->add(array( 'URL', new Horde_Imap_Client_Data_Format_Astring($v['v']) )); } else { $data_stream->add($this->_convertCatenateUrl($v['v'])); } break; } } if ($catenate) { $cmd->add($tmp); } else { $adata = $this->_appendData($data_stream->stream, $asize); } } else { $adata = $this->_appendData($data[$key]['data'], $asize); } if (!is_null($adata)) { if ($utf8) { /* RFC 6855 [4]: APPEND UTF8 extension. */ $adata->forceBinary(); $cmd->add(array( 'UTF8', new Horde_Imap_Client_Data_Format_List($adata) )); } else { $cmd->add($adata); } } } /* Although it is normally more efficient to use LITERAL+, disable if * payload is over 50 KB because it allows the server to throw error * before we potentially push a lot of data to server that would * otherwise be ignored (see RFC 4549 [4.2.2.3]). * Additionally, since so many IMAP servers have issues with APPEND * + BINARY, don't use LITERAL+ since servers may send BAD * (incorrectly) after initial command. */ $cmd->literalplus = (($asize < (1024 * 50)) && !$binary); // If the mailbox is currently selected read-only, we need to close // because some IMAP implementations won't allow an append. And some // implementations don't support append on ANY open mailbox. Be safe // and always make sure we are in a non-selected state. $this->close(); try { $resp = $this->_sendCmd($cmd); } catch (Horde_Imap_Client_Exception $e) { switch ($e->getCode()) { case $e::CATENATE_BADURL: case $e::CATENATE_TOOBIG: /* Cyrus 2.4 (at least as of .14) has a broken CATENATE (see * Bug #11111). Regardless, if CATENATE is broken, we can try * to fallback to APPEND. */ $c->remove('CATENATE'); return $this->_append($mailbox, $data, $options); case $e::DISCONNECT: /* Workaround broken literal8 on Cyrus. */ if ($binary) { // Need to re-login first before removing capability. $this->login(); $c->remove('BINARY'); return $this->_append($mailbox, $data, $options); } break; } if (!empty($options['create']) && !empty($e->resp_data['trycreate'])) { $this->createMailbox($mailbox); unset($options['create']); return $this->_append($mailbox, $data, $options); } /* RFC 3516/4466 says we should be able to append binary data * using literal8 "~{#} format", but it doesn't seem to work on * all servers tried (UW-IMAP/Cyrus). Do a last-ditch check for * broken BINARY and attempt to fix here. */ if ($c->query('BINARY') && ($e instanceof Horde_Imap_Client_Exception_ServerResponse)) { switch ($e->status) { case Horde_Imap_Client_Interaction_Server::BAD: case Horde_Imap_Client_Interaction_Server::NO: $c->remove('BINARY'); return $this->_append($mailbox, $data, $options); } } throw $e; } /* If we reach this point and have data in 'appenduid', UIDPLUS (RFC * 4315) has done the dirty work for us. */ return isset($resp->data['appenduid']) ? $resp->data['appenduid'] : true; } /** * Prepares append message data for insertion into the IMAP command * string. * * @param mixed $data Either a resource or a string. * @param integer &$asize Total append size. * * @return Horde_Imap_Client_Data_Format_String_Nonascii The data object. */ protected function _appendData($data, &$asize) { if (is_resource($data)) { rewind($data); } /* Since this is body text, with possible embedded charset * information, non-ASCII characters are supported. */ $ob = new Horde_Imap_Client_Data_Format_String_Nonascii($data, array( 'eol' => true, 'skipscan' => true )); // APPEND data MUST be sent in a literal (RFC 3501 [6.3.11]). $ob->forceLiteral(); $asize += $ob->length(); return $ob; } /** * Converts a CATENATE URL to stream data. * * @param string $url The CATENATE URL. * * @return resource A stream containing the data. */ protected function _convertCatenateUrl($url) { $e = $part = null; $url = new Horde_Imap_Client_Url_Imap($url); if (!is_null($url->mailbox) && !is_null($url->uid)) { try { $status_res = is_null($url->uidvalidity) ? null : $this->status($url->mailbox, Horde_Imap_Client::STATUS_UIDVALIDITY); if (is_null($status_res) || ($status_res['uidvalidity'] == $url->uidvalidity)) { if (!isset($this->_temp['catenate_ob'])) { $this->_temp['catenate_ob'] = new Horde_Imap_Client_Socket_Catenate($this); } $part = $this->_temp['catenate_ob']->fetchFromUrl($url); } } catch (Horde_Imap_Client_Exception $e) {} } if (is_null($part)) { $message = 'Bad IMAP URL given in CATENATE data: ' . strval($url); if ($e) { $message .= ' ' . $e->getMessage(); } throw new InvalidArgumentException($message); } return $part; } /** */ protected function _check() { // CHECK returns no untagged information (RFC 3501 [6.4.1]) $this->_sendCmd($this->_command('CHECK')); } /** */ protected function _close($options) { if (empty($options['expunge'])) { if ($this->_capability('UNSELECT')) { // RFC 3691 defines 'UNSELECT' for precisely this purpose $this->_sendCmd($this->_command('UNSELECT')); } else { /* RFC 3501 [6.4.2]: to close a mailbox without expunge, * select a non-existent mailbox. */ try { $this->_sendCmd($this->_command('EXAMINE')->add( $this->_getMboxFormatOb("\24nonexist\24") )); /* Not pipelining, since the odds that this CLOSE is even * needed is tiny; and it returns BAD, which should be * avoided, if possible. */ $this->_sendCmd($this->_command('CLOSE')); } catch (Horde_Imap_Client_Exception_ServerResponse $e) { // Ignore error; it is expected. } } } else { // If caching, we need to know the UIDs being deleted, so call // expunge() before calling close(). if ($this->_initCache(true)) { $this->expunge($this->_selected); } // CLOSE returns no untagged information (RFC 3501 [6.4.2]) $this->_sendCmd($this->_command('CLOSE')); } } /** */ protected function _expunge($options) { $expunged_ob = $modseq = null; $ids = $options['ids']; $list_msgs = !empty($options['list']); $mailbox = $this->_selected; $uidplus = $this->_capability('UIDPLUS'); $unflag = array(); $use_cache = $this->_initCache(true); if ($ids->all) { if (!$uidplus || $list_msgs || $use_cache) { $ids = $this->resolveIds($mailbox, $ids, 2); } } elseif ($uidplus) { /* If QRESYNC is not available, and we are returning the list of * expunged messages (or we are caching), we have to make sure we * have a mapping of Sequence -> UIDs. If we have QRESYNC, the * server SHOULD return a VANISHED response with UIDs. However, * even if the server returns EXPUNGEs instead, we can use * vanished() to grab the list. */ unset($this->_temp['search_save']); if ($this->_capability()->isEnabled('QRESYNC')) { $ids = $this->resolveIds($mailbox, $ids, 1); if ($list_msgs) { $modseq = $this->_mailboxOb()->getStatus(Horde_Imap_Client::STATUS_HIGHESTMODSEQ); } } else { $ids = $this->resolveIds($mailbox, $ids, ($list_msgs || $use_cache) ? 2 : 1); } if (!empty($this->_temp['search_save'])) { $ids = $this->getIdsOb(Horde_Imap_Client_Ids::SEARCH_RES); } } else { /* Without UIDPLUS, need to temporarily unflag all messages marked * as deleted but not a part of requested IDs to delete. Use NOT * searches to accomplish this goal. */ $squery = new Horde_Imap_Client_Search_Query(); $squery->flag(Horde_Imap_Client::FLAG_DELETED, true); $squery->ids($ids, true); $s_res = $this->search($mailbox, $squery, array( 'results' => array( Horde_Imap_Client::SEARCH_RESULTS_MATCH, Horde_Imap_Client::SEARCH_RESULTS_SAVE ) )); $this->store($mailbox, array( 'ids' => empty($s_res['save']) ? $s_res['match'] : $this->getIdsOb(Horde_Imap_Client_Ids::SEARCH_RES), 'remove' => array(Horde_Imap_Client::FLAG_DELETED) )); $unflag = $s_res['match']; } if ($list_msgs) { $expunged_ob = $this->getIdsOb(); $this->_temp['expunged'] = $expunged_ob; } /* Always use UID EXPUNGE if available. */ if ($uidplus) { /* We can only pipeline STORE w/ EXPUNGE if using UIDs and UIDPLUS * is available. */ if (empty($options['delete'])) { $pipeline = $this->_pipeline(); } else { $pipeline = $this->_storeCmd(array( 'add' => array( Horde_Imap_Client::FLAG_DELETED ), 'ids' => $ids )); } foreach ($ids->split(2000) as $val) { $pipeline->add( $this->_command('UID EXPUNGE')->add($val) ); } $resp = $this->_sendCmd($pipeline); } else { if (!empty($options['delete'])) { $this->store($mailbox, array( 'add' => array(Horde_Imap_Client::FLAG_DELETED), 'ids' => $ids )); } if ($use_cache || $list_msgs) { $this->_sendCmd($this->_command('EXPUNGE')); } else { /* This is faster than an EXPUNGE because the server will not * return untagged EXPUNGE responses. We can only do this if * we are not updating cache information. */ $this->close(array('expunge' => true)); } } unset($this->_temp['expunged']); if (!empty($unflag)) { $this->store($mailbox, array( 'add' => array(Horde_Imap_Client::FLAG_DELETED), 'ids' => $unflag )); } if (!is_null($modseq) && !empty($resp->data['expunge_seen'])) { /* There's a chance we actually did a full map of sequence -> UID, * but this code should never be reached in the first place so * be ultra-safe and just do a full VANISHED search. */ $expunged_ob = $this->vanished($mailbox, $modseq, array( 'ids' => $ids )); $this->_deleteMsgs($mailbox, $expunged_ob, array( 'pipeline' => $resp )); } return $expunged_ob; } /** * Parse a VANISHED response (RFC 7162 [3.2.10]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Tokenize $data The response data. */ protected function _parseVanished( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Tokenize $data ) { /* There are two forms of VANISHED. VANISHED (EARLIER) will be sent * in a FETCH (VANISHED) or SELECT/EXAMINE (QRESYNC) call. * If this is the case, we can go ahead and update the cache * immediately (we know we are caching or else QRESYNC would not be * enabled). HIGHESTMODSEQ information will be updated via the tagged * response. */ if (($curr = $data->next()) === true) { if (Horde_String::upper($data->next()) === 'EARLIER') { /* Caching is guaranteed to be active if we are using * QRESYNC. */ $data->next(); $vanished = $this->getIdsOb($data->next()); if (isset($pipeline->data['vanished'])) { $pipeline->data['vanished']->add($vanished); } else { $this->_deleteMsgs($this->_selected, $vanished, array( 'pipeline' => $pipeline )); } } } else { /* The second form is just VANISHED. This is analogous to EXPUNGE * and requires the message count to decrement. */ $this->_deleteMsgs($this->_selected, $this->getIdsOb($curr), array( 'decrement' => true, 'pipeline' => $pipeline )); } } /** * Search a mailbox. This driver supports all IMAP4rev1 search criteria * as defined in RFC 3501. */ protected function _search($query, $options) { $sort_criteria = array( Horde_Imap_Client::SORT_ARRIVAL => 'ARRIVAL', Horde_Imap_Client::SORT_CC => 'CC', Horde_Imap_Client::SORT_DATE => 'DATE', Horde_Imap_Client::SORT_DISPLAYFROM => 'DISPLAYFROM', Horde_Imap_Client::SORT_DISPLAYTO => 'DISPLAYTO', Horde_Imap_Client::SORT_FROM => 'FROM', Horde_Imap_Client::SORT_REVERSE => 'REVERSE', Horde_Imap_Client::SORT_RELEVANCY => 'RELEVANCY', // This is a bogus entry to allow the sort options check to // correctly work below. Horde_Imap_Client::SORT_SEQUENCE => 'SEQUENCE', Horde_Imap_Client::SORT_SIZE => 'SIZE', Horde_Imap_Client::SORT_SUBJECT => 'SUBJECT', Horde_Imap_Client::SORT_TO => 'TO' ); $results_criteria = array( Horde_Imap_Client::SEARCH_RESULTS_COUNT => 'COUNT', Horde_Imap_Client::SEARCH_RESULTS_MATCH => 'ALL', Horde_Imap_Client::SEARCH_RESULTS_MAX => 'MAX', Horde_Imap_Client::SEARCH_RESULTS_MIN => 'MIN', Horde_Imap_Client::SEARCH_RESULTS_RELEVANCY => 'RELEVANCY', Horde_Imap_Client::SEARCH_RESULTS_SAVE => 'SAVE' ); // Check if the server supports sorting (RFC 5256). $esearch = $return_sort = $server_seq_sort = $server_sort = false; if (!empty($options['sort'])) { /* Make sure sort options are correct. If not, default to no * sort. */ if (count(array_intersect($options['sort'], array_keys($sort_criteria))) === 0) { unset($options['sort']); } else { $return_sort = true; if ($this->_capability('SORT')) { /* Make sure server supports DISPLAYFROM & DISPLAYTO. */ $server_sort = !array_intersect($options['sort'], array(Horde_Imap_Client::SORT_DISPLAYFROM, Horde_Imap_Client::SORT_DISPLAYTO)) || $this->_capability('SORT', 'DISPLAY'); } /* If doing a sequence sort, need to do this on the client * side. */ if ($server_sort && in_array(Horde_Imap_Client::SORT_SEQUENCE, $options['sort'])) { $server_sort = false; /* Optimization: If doing only a sequence sort, just do a * simple search and sort UIDs/sequences on client side. */ switch (count($options['sort'])) { case 1: $server_seq_sort = true; break; case 2: $server_seq_sort = (reset($options['sort']) == Horde_Imap_Client::SORT_REVERSE); break; } } } } $charset = is_null($options['_query']['charset']) ? 'US-ASCII' : $options['_query']['charset']; $partial = false; if ($server_sort) { $cmd = $this->_command( empty($options['sequence']) ? 'UID SORT' : 'SORT' ); $results = array(); // Use ESEARCH (RFC 4466) response if server supports. $esearch = false; // Check for ESORT capability (RFC 5267) if ($this->_capability('ESORT')) { foreach ($options['results'] as $val) { if (isset($results_criteria[$val]) && ($val != Horde_Imap_Client::SEARCH_RESULTS_SAVE)) { $results[] = $results_criteria[$val]; } } $esearch = true; } // Add PARTIAL limiting (RFC 5267 [4.4]) if ((!$esearch || !empty($options['partial'])) && $this->_capability('CONTEXT', 'SORT')) { /* RFC 5267 indicates RFC 4466 ESEARCH-like support, * notwithstanding "real" RFC 4731 support. */ $esearch = true; if (!empty($options['partial'])) { /* Can't have both ALL and PARTIAL returns. */ $results = array_diff($results, array('ALL')); $results[] = 'PARTIAL'; $results[] = $options['partial']; $partial = true; } } if ($esearch && empty($this->_init['noesearch'])) { $cmd->add(array( 'RETURN', new Horde_Imap_Client_Data_Format_List($results) )); } $tmp = new Horde_Imap_Client_Data_Format_List(); foreach ($options['sort'] as $val) { if (isset($sort_criteria[$val])) { $tmp->add($sort_criteria[$val]); } } $cmd->add($tmp); /* Charset is mandatory for SORT (RFC 5256 [3]). * However, if UTF-8 support is activated, a client MUST NOT * send the charset specification (RFC 6855 [3]; Errata 4029). */ if (!$this->_capability()->isEnabled('UTF8=ACCEPT')) { $cmd->add($charset); } } else { $cmd = $this->_command( empty($options['sequence']) ? 'UID SEARCH' : 'SEARCH' ); $esearch = false; $results = array(); // Check if the server supports ESEARCH (RFC 4731). if ($this->_capability('ESEARCH')) { foreach ($options['results'] as $val) { if (isset($results_criteria[$val])) { $results[] = $results_criteria[$val]; } } $esearch = true; } // Add PARTIAL limiting (RFC 5267 [4.4]). if ((!$esearch || !empty($options['partial'])) && $this->_capability('CONTEXT', 'SEARCH')) { /* RFC 5267 indicates RFC 4466 ESEARCH-like support, * notwithstanding "real" RFC 4731 support. */ $esearch = true; if (!empty($options['partial'])) { // Can't have both ALL and PARTIAL returns. $results = array_diff($results, array('ALL')); $results[] = 'PARTIAL'; $results[] = $options['partial']; $partial = true; } } if ($esearch && empty($this->_init['noesearch'])) { // Always use ESEARCH if available because it returns results // in a more compact sequence-set list $cmd->add(array( 'RETURN', new Horde_Imap_Client_Data_Format_List($results) )); } /* Charset is optional for SEARCH (RFC 3501 [6.4.4]). * If UTF-8 support is activated, a client MUST NOT * send the charset specification (RFC 6855 [3]; Errata 4029). */ if (($charset != 'US-ASCII') && !$this->_capability()->isEnabled('UTF8=ACCEPT')) { $cmd->add(array( 'CHARSET', $options['_query']['charset'] )); } } $cmd->add($options['_query']['query'], true); $pipeline = $this->_pipeline($cmd); $pipeline->data['esearchresp'] = array(); $er = &$pipeline->data['esearchresp']; $pipeline->data['searchresp'] = $this->getIdsOb(array(), !empty($options['sequence'])); $sr = &$pipeline->data['searchresp']; try { $resp = $this->_sendCmd($pipeline); } catch (Horde_Imap_Client_Exception $e) { if (($e instanceof Horde_Imap_Client_Exception_ServerResponse) && ($e->status === Horde_Imap_Client_Interaction_Server::NO) && ($charset != 'US-ASCII')) { /* RFC 3501 [6.4.4]: BADCHARSET response code is only a * SHOULD return. If it doesn't exist, need to check for * command status of 'NO'. List of supported charsets in * the BADCHARSET response has already been parsed and stored * at this point. */ $this->search_charset->setValid($charset, false); $e->setCode(Horde_Imap_Client_Exception::BADCHARSET); } if (empty($this->_temp['search_retry'])) { $this->_temp['search_retry'] = true; /* Bug #9842: Workaround broken Cyrus servers (as of * 2.4.7). */ if ($esearch && ($charset != 'US-ASCII')) { $this->_capability()->remove('ESEARCH'); $this->_setInit('noesearch', true); try { return $this->_search($query, $options); } catch (Horde_Imap_Client_Exception $e) {} } /* Try to convert charset. */ if (($e->getCode() === Horde_Imap_Client_Exception::BADCHARSET) && ($charset != 'US-ASCII')) { foreach ($this->search_charset->charsets as $val) { $this->_temp['search_retry'] = 1; $new_query = clone($query); try { $new_query->charset($val); $options['_query'] = $new_query->build($this); return $this->_search($new_query, $options); } catch (Horde_Imap_Client_Exception $e) {} } } unset($this->_temp['search_retry']); } throw $e; } if ($return_sort && !$server_sort) { if ($server_seq_sort) { $sr->sort(); if (reset($options['sort']) == Horde_Imap_Client::SORT_REVERSE) { $sr->reverse(); } } else { if (!isset($this->_temp['clientsort'])) { $this->_temp['clientsort'] = new Horde_Imap_Client_Socket_ClientSort($this); } $sr = $this->getIdsOb($this->_temp['clientsort']->clientSort($sr, $options), !empty($options['sequence'])); } } if (!$partial && !empty($options['partial'])) { $partial = $this->getIdsOb($options['partial'], true); $min = $partial->min - 1; $sr = $this->getIdsOb( array_slice($sr->ids, $min, $partial->max - $min), !empty($options['sequence']) ); } $ret = array(); foreach ($options['results'] as $val) { switch ($val) { case Horde_Imap_Client::SEARCH_RESULTS_COUNT: $ret['count'] = ($esearch && !$partial) ? $er['count'] : count($sr); break; case Horde_Imap_Client::SEARCH_RESULTS_MATCH: $ret['match'] = $sr; break; case Horde_Imap_Client::SEARCH_RESULTS_MAX: $ret['max'] = $esearch ? (!$partial && isset($er['max']) ? $er['max'] : null) : (count($sr) ? max($sr->ids) : null); break; case Horde_Imap_Client::SEARCH_RESULTS_MIN: $ret['min'] = $esearch ? (!$partial && isset($er['min']) ? $er['min'] : null) : (count($sr) ? min($sr->ids) : null); break; case Horde_Imap_Client::SEARCH_RESULTS_RELEVANCY: $ret['relevancy'] = ($esearch && isset($er['relevancy'])) ? $er['relevancy'] : array(); break; case Horde_Imap_Client::SEARCH_RESULTS_SAVE: $this->_temp['search_save'] = $ret['save'] = $esearch ? empty($resp->data['searchnotsaved']) : false; break; } } // Add modseq data, if needed. if (!empty($er['modseq'])) { $ret['modseq'] = $er['modseq']; } unset($this->_temp['search_retry']); /* Check for EXPUNGEISSUED (RFC 2180 [4.3]/RFC 5530 [3]). */ if (!empty($resp->data['expungeissued'])) { $this->noop(); } return $ret; } /** * Parse a SEARCH/SORT response (RFC 3501 [7.2.5]; RFC 4466 [3]; * RFC 5256 [4]; RFC 5267 [3]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param array $data A list of IDs (message sequence numbers or UIDs). */ protected function _parseSearch( Horde_Imap_Client_Interaction_Pipeline $pipeline, $data ) { /* More than one search response may be sent. */ $pipeline->data['searchresp']->add($data); } /** * Parse an ESEARCH response (RFC 4466 [2.6.2]) * Format: (TAG "a567") UID COUNT 5 ALL 4:19,21,28 * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Tokenize $data The server response. */ protected function _parseEsearch( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Tokenize $data ) { // Ignore search correlator information if ($data->next() === true) { $data->flushIterator(false); } // Ignore UID tag $current = $data->next(); if (Horde_String::upper($current) === 'UID') { $current = $data->next(); } do { $val = $data->next(); $tag = Horde_String::upper($current); switch ($tag) { case 'ALL': $this->_parseSearch($pipeline, $val); break; case 'COUNT': case 'MAX': case 'MIN': case 'MODSEQ': case 'RELEVANCY': $pipeline->data['esearchresp'][Horde_String::lower($tag)] = $val; break; case 'PARTIAL': // RFC 5267 [4.4] $partial = $val->flushIterator(); $this->_parseSearch($pipeline, end($partial)); break; } } while (($current = $data->next()) !== false); } /** */ protected function _setComparator($comparator) { $cmd = $this->_command('COMPARATOR'); foreach ($comparator as $val) { $cmd->add(new Horde_Imap_Client_Data_Format_Astring($val)); } $this->_sendCmd($cmd); } /** */ protected function _getComparator() { $resp = $this->_sendCmd($this->_command('COMPARATOR')); return isset($resp->data['comparator']) ? $resp->data['comparator'] : null; } /** * Parse a COMPARATOR response (RFC 5255 [4.8]) * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Tokenize $data The server response. */ protected function _parseComparator( Horde_Imap_Client_Interaction_Pipeline $pipeline, $data ) { $pipeline->data['comparator'] = $data->next(); // Ignore optional matching comparator list } /** * @throws Horde_Imap_Client_Exception_NoSupportExtension */ protected function _thread($options) { $thread_criteria = array( Horde_Imap_Client::THREAD_ORDEREDSUBJECT => 'ORDEREDSUBJECT', Horde_Imap_Client::THREAD_REFERENCES => 'REFERENCES', Horde_Imap_Client::THREAD_REFS => 'REFS' ); $tsort = (isset($options['criteria'])) ? (is_string($options['criteria']) ? Horde_String::upper($options['criteria']) : $thread_criteria[$options['criteria']]) : 'ORDEREDSUBJECT'; if (!$this->_capability('THREAD', $tsort)) { switch ($tsort) { case 'ORDEREDSUBJECT': if (empty($options['search'])) { $ids = $this->getIdsOb(Horde_Imap_Client_Ids::ALL, !empty($options['sequence'])); } else { $search_res = $this->search($this->_selected, $options['search'], array('sequence' => !empty($options['sequence']))); $ids = $search_res['match']; } /* Do client-side ORDEREDSUBJECT threading. */ $query = new Horde_Imap_Client_Fetch_Query(); $query->envelope(); $query->imapDate(); $fetch_res = $this->fetch($this->_selected, $query, array( 'ids' => $ids )); if (!isset($this->_temp['clientsort'])) { $this->_temp['clientsort'] = new Horde_Imap_Client_Socket_ClientSort($this); } return $this->_temp['clientsort']->threadOrderedSubject($fetch_res, empty($options['sequence'])); case 'REFERENCES': case 'REFS': throw new Horde_Imap_Client_Exception_NoSupportExtension( 'THREAD', sprintf('Server does not support "%s" thread sort.', $tsort) ); } } $cmd = $this->_command( empty($options['sequence']) ? 'UID THREAD' : 'THREAD' )->add($tsort); /* If UTF-8 support is activated, a client MUST NOT * send the charset specification (RFC 6855 [3]; Errata 4029). */ if (empty($options['search'])) { if (!$this->_capability()->isEnabled('UTF8=ACCEPT')) { $cmd->add('US-ASCII'); } $cmd->add('ALL'); } else { $search_query = $options['search']->build(); if (!$this->_capability()->isEnabled('UTF8=ACCEPT')) { $cmd->add(is_null($search_query['charset']) ? 'US-ASCII' : $search_query['charset']); } $cmd->add($search_query['query'], true); } return new Horde_Imap_Client_Data_Thread( $this->_sendCmd($cmd)->data['threadparse'], empty($options['sequence']) ? 'uid' : 'sequence' ); } /** * Parse a THREAD response (RFC 5256 [4]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Tokenize $data Thread data. */ protected function _parseThread( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Tokenize $data ) { $out = array(); while ($data->next() !== false) { $thread = array(); $this->_parseThreadLevel($thread, $data); $out[] = $thread; } $pipeline->data['threadparse'] = $out; } /** * Parse a level of a THREAD response (RFC 5256 [4]). * * @param array $thread Results. * @param Horde_Imap_Client_Tokenize $data Thread data. * @param integer $level The current tree level. */ protected function _parseThreadLevel(&$thread, Horde_Imap_Client_Tokenize $data, $level = 0) { while (($curr = $data->next()) !== false) { if ($curr === true) { $this->_parseThreadLevel($thread, $data, $level); } elseif (!is_bool($curr)) { $thread[$curr] = $level++; } } } /** */ protected function _fetch(Horde_Imap_Client_Fetch_Results $results, $queries) { $pipeline = $this->_pipeline(); $pipeline->data['fetch_lookup'] = array(); $pipeline->data['fetch_followup'] = array(); foreach ($queries as $options) { $this->_fetchCmd($pipeline, $options); $sequence = $options['ids']->sequence; } try { $resp = $this->_sendCmd($pipeline); /* Check for EXPUNGEISSUED (RFC 2180 [4.1]/RFC 5530 [3]). */ if (!empty($resp->data['expungeissued'])) { $this->noop(); } foreach ($resp->fetch as $k => $v) { $results->get($sequence ? $k : $v->getUid())->merge($v); } } catch (Horde_Imap_Client_Exception_ServerResponse $e) { if ($e->status === Horde_Imap_Client_Interaction_Server::NO) { if ($e->getCode() === $e::UNKNOWNCTE) { /* UNKNOWN-CTE error. Redo the query without the BINARY * elements. */ $bq = $pipeline->data['binaryquery']; foreach ($queries as $val) { foreach ($bq as $key2 => $val2) { unset($val2['decode']); $val['_query']->bodyPart($key2, $val2); $val['_query']->remove(Horde_Imap_Client::FETCH_BODYPARTSIZE, $key2); } $pipeline->data['fetch_followup'][] = $val; } } elseif ($sequence) { /* A NO response, when coupled with a sequence FETCH, most * likely means that messages were expunged. (RFC 2180 * [4.1]) */ $this->noop(); } } } catch (Exception $e) { // For any other error, ignore the Exception - fetch() is nice in // that the return value explicitly handles missing data for any // given message. } if (!empty($pipeline->data['fetch_followup'])) { $this->_fetch($results, $pipeline->data['fetch_followup']); } } /** * Add a FETCH command to the given pipeline. * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param array $options Fetch query * options */ protected function _fetchCmd( Horde_Imap_Client_Interaction_Pipeline $pipeline, $options ) { $fetch = new Horde_Imap_Client_Data_Format_List(); $sequence = $options['ids']->sequence; /* Build an IMAP4rev1 compliant FETCH query. We handle the following * criteria: * BINARY[.PEEK][
]<> (RFC 3516) * see BODY[] response * BINARY.SIZE[
] (RFC 3516) * BODY[.PEEK][
]<> *
= HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, * TEXT, empty * <> = 0.# (# of bytes) * BODYSTRUCTURE * ENVELOPE * FLAGS * INTERNALDATE * MODSEQ (RFC 7162) * RFC822.SIZE * UID * * No need to support these (can be built from other queries): * =========================================================== * ALL macro => (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE) * BODY => Use BODYSTRUCTURE instead * FAST macro => (FLAGS INTERNALDATE RFC822.SIZE) * FULL macro => (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY) * RFC822 => BODY[] * RFC822.HEADER => BODY[HEADER] * RFC822.TEXT => BODY[TEXT] */ foreach ($options['_query'] as $type => $c_val) { switch ($type) { case Horde_Imap_Client::FETCH_STRUCTURE: $fetch->add('BODYSTRUCTURE'); break; case Horde_Imap_Client::FETCH_FULLMSG: if (empty($c_val['peek'])) { $this->openMailbox($this->_selected, Horde_Imap_Client::OPEN_READWRITE); } $fetch->add( 'BODY' . (!empty($c_val['peek']) ? '.PEEK' : '') . '[]' . $this->_partialAtom($c_val) ); break; case Horde_Imap_Client::FETCH_HEADERTEXT: case Horde_Imap_Client::FETCH_BODYTEXT: case Horde_Imap_Client::FETCH_MIMEHEADER: case Horde_Imap_Client::FETCH_BODYPART: case Horde_Imap_Client::FETCH_HEADERS: foreach ($c_val as $key => $val) { $cmd = ($key == 0) ? '' : $key . '.'; $main_cmd = 'BODY'; switch ($type) { case Horde_Imap_Client::FETCH_HEADERTEXT: $cmd .= 'HEADER'; break; case Horde_Imap_Client::FETCH_BODYTEXT: $cmd .= 'TEXT'; break; case Horde_Imap_Client::FETCH_MIMEHEADER: $cmd .= 'MIME'; break; case Horde_Imap_Client::FETCH_BODYPART: // Remove the last dot from the string. $cmd = substr($cmd, 0, -1); if (!empty($val['decode']) && $this->_capability('BINARY')) { $main_cmd = 'BINARY'; $pipeline->data['binaryquery'][$key] = $val; } break; case Horde_Imap_Client::FETCH_HEADERS: $cmd .= 'HEADER.FIELDS'; if (!empty($val['notsearch'])) { $cmd .= '.NOT'; } $cmd .= ' (' . implode(' ', array_map('Horde_String::upper', $val['headers'])) . ')'; // Maintain a command -> label lookup so we can put // the results in the proper location. $pipeline->data['fetch_lookup'][$cmd] = $key; } if (empty($val['peek'])) { $this->openMailbox($this->_selected, Horde_Imap_Client::OPEN_READWRITE); } $fetch->add( $main_cmd . (!empty($val['peek']) ? '.PEEK' : '') . '[' . $cmd . ']' . $this->_partialAtom($val) ); } break; case Horde_Imap_Client::FETCH_BODYPARTSIZE: if ($this->_capability('BINARY')) { foreach ($c_val as $val) { $fetch->add('BINARY.SIZE[' . $val . ']'); } } break; case Horde_Imap_Client::FETCH_ENVELOPE: $fetch->add('ENVELOPE'); break; case Horde_Imap_Client::FETCH_FLAGS: $fetch->add('FLAGS'); break; case Horde_Imap_Client::FETCH_IMAPDATE: $fetch->add('INTERNALDATE'); break; case Horde_Imap_Client::FETCH_SIZE: $fetch->add('RFC822.SIZE'); break; case Horde_Imap_Client::FETCH_UID: /* A UID FETCH will always return UID information (RFC 3501 * [6.4.8]). Don't add to query as it just creates a longer * FETCH command. */ if ($sequence) { $fetch->add('UID'); } break; case Horde_Imap_Client::FETCH_SEQ: /* Nothing we need to add to fetch request unless sequence is * the only criteria (see below). */ break; case Horde_Imap_Client::FETCH_MODSEQ: /* The 'changedsince' modifier implicitly adds the MODSEQ * FETCH item (RFC 7162 [3.1.4.1]). Don't add to query as it * just creates a longer FETCH command. */ if (empty($options['changedsince'])) { $fetch->add('MODSEQ'); } break; } } /* If empty fetch, add UID to make command valid. */ if (!count($fetch)) { $fetch->add('UID'); } /* Add changedsince parameters. */ if (empty($options['changedsince'])) { $fetch_cmd = $fetch; } else { /* We might just want the list of UIDs changed since a given * modseq. In that case, we don't have any other FETCH attributes, * but RFC 3501 requires at least one specified attribute. */ $fetch_cmd = array( $fetch, new Horde_Imap_Client_Data_Format_List(array( 'CHANGEDSINCE', new Horde_Imap_Client_Data_Format_Number($options['changedsince']) )) ); } /* The FETCH command should be the only command issued by this library * that should ever approach the command length limit. * @todo Move this check to a more centralized location (_command()?). * For simplification, assume that the UID list is the limiting factor * and split this list at a sequence comma delimiter if it exceeds * the character limit. */ foreach ($options['ids']->split($this->_capability()->cmdlength) as $val) { $cmd = $this->_command( $sequence ? 'FETCH' : 'UID FETCH' )->add(array( $val, $fetch_cmd )); $pipeline->add($cmd); } } /** * Add a partial atom to an IMAP command based on the criteria options. * * @param array $opts Criteria options. * * @return string The partial atom. */ protected function _partialAtom($opts) { if (!empty($opts['length'])) { return '<' . (empty($opts['start']) ? 0 : intval($opts['start'])) . '.' . intval($opts['length']) . '>'; } return empty($opts['start']) ? '' : ('<' . intval($opts['start']) . '>'); } /** * Parse a FETCH response (RFC 3501 [7.4.2]). A FETCH response may occur * due to a FETCH command, or due to a change in a message's state (i.e. * the flags change). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param integer $id The message sequence number. * @param Horde_Imap_Client_Tokenize $data The server response. */ protected function _parseFetch( Horde_Imap_Client_Interaction_Pipeline $pipeline, $id, Horde_Imap_Client_Tokenize $data ) { if ($data->next() !== true) { return; } $ob = $pipeline->fetch->get($id); $ob->setSeq($id); $flags = $modseq = $uid = false; while (($tag = $data->next()) !== false) { $tag = Horde_String::upper($tag); /* Catch equivalent RFC822 tags, in case server returns them * (in error, since we only use BODY in FETCH requests). */ switch ($tag) { case 'RFC822': $tag = 'BODY[]'; break; case 'RFC822.HEADER': $tag = 'BODY[HEADER]'; break; case 'RFC822.TEXT': $tag = 'BODY[TEXT]'; break; } switch ($tag) { case 'BODYSTRUCTURE': $data->next(); $structure = $this->_parseBodystructure($data); $structure->buildMimeIds(); $ob->setStructure($structure); break; case 'ENVELOPE': $data->next(); $ob->setEnvelope($this->_parseEnvelope($data)); break; case 'FLAGS': $data->next(); $ob->setFlags($data->flushIterator()); $flags = true; break; case 'INTERNALDATE': $ob->setImapDate($data->next()); break; case 'RFC822.SIZE': $ob->setSize($data->next()); break; case 'UID': $ob->setUid($data->next()); $uid = true; break; case 'MODSEQ': $data->next(); $modseq = $data->next(); $data->next(); /* MODSEQ must be greater than 0, so do sanity checking. */ if ($modseq > 0) { $ob->setModSeq($modseq); /* Store MODSEQ value. It may be used as the highestmodseq * once a tagged response is received (RFC 7162 [6]). */ $pipeline->data['modseqs'][] = $modseq; } break; default: // Catch BODY[*]<#> responses if (strpos($tag, 'BODY[') === 0) { // Remove the beginning 'BODY[' $tag = substr($tag, 5); // BODY[HEADER.FIELDS] request if (!empty($pipeline->data['fetch_lookup']) && (strpos($tag, 'HEADER.FIELDS') !== false)) { $data->next(); $sig = $tag . ' (' . implode(' ', array_map('Horde_String::upper', $data->flushIterator())) . ')'; // Ignore the trailing bracket $data->next(); $ob->setHeaders($pipeline->data['fetch_lookup'][$sig], $data->next()); } else { // Remove trailing bracket and octet start info $tag = substr($tag, 0, strrpos($tag, ']')); if (!strlen($tag)) { // BODY[] request if (!is_null($tmp = $data->nextStream())) { $ob->setFullMsg($tmp); } } elseif (is_numeric(substr($tag, -1))) { // BODY[MIMEID] request if (!is_null($tmp = $data->nextStream())) { $ob->setBodyPart($tag, $tmp); } } else { // BODY[HEADER|TEXT|MIME] request if (($last_dot = strrpos($tag, '.')) === false) { $mime_id = 0; } else { $mime_id = substr($tag, 0, $last_dot); $tag = substr($tag, $last_dot + 1); } if (!is_null($tmp = $data->nextStream())) { switch ($tag) { case 'HEADER': $ob->setHeaderText($mime_id, $tmp); break; case 'TEXT': $ob->setBodyText($mime_id, $tmp); break; case 'MIME': $ob->setMimeHeader($mime_id, $tmp); break; } } } } } elseif (strpos($tag, 'BINARY[') === 0) { // Catch BINARY[*]<#> responses // Remove the beginning 'BINARY[' and the trailing bracket // and octet start info $tag = substr($tag, 7, strrpos($tag, ']') - 7); $body = $data->nextStream(); if (is_null($body)) { /* Dovecot bug (as of 2.2.12): binary fetch of body * part may fail with NIL return if decoding failed on * server. Try again with non-decoded body. */ $bq = $pipeline->data['binaryquery'][$tag]; unset($bq['decode']); $query = new Horde_Imap_Client_Fetch_Query(); $query->bodyPart($tag, $bq); $qids = ($quid = $ob->getUid()) ? new Horde_Imap_Client_Ids($quid) : new Horde_Imap_Client_Ids($id, true); $pipeline->data['fetch_followup'][] = array( '_query' => $query, 'ids' => $qids ); } else { $ob->setBodyPart( $tag, $body, empty($this->_temp['literal8']) ? '8bit' : 'binary' ); } } elseif (strpos($tag, 'BINARY.SIZE[') === 0) { // Catch BINARY.SIZE[*] responses // Remove the beginning 'BINARY.SIZE[' and the trailing // bracket and octet start info $tag = substr($tag, 12, strrpos($tag, ']') - 12); $ob->setBodyPartSize($tag, $data->next()); } break; } } /* MODSEQ issue: Oh joy. Per RFC 5162 (see Errata #1807), FETCH FLAGS * responses are NOT required to provide UID information, even if * QRESYNC is explicitly enabled. Caveat: the FLAGS information * returned during a SELECT/EXAMINE MUST contain UIDs so we are OK * there. * The good news: all decent IMAP servers (Cyrus, Dovecot) will always * provide UID information, so this is not normally an issue. * The bad news: spec-wise, this behavior cannot be 100% guaranteed. * Compromise: We will watch for a FLAGS response with a MODSEQ and * check if a UID exists also. If not, put the sequence number in a * queue - it is possible the UID information may appear later in an * untagged response. When the command is over, double check to make * sure there are none of these MODSEQ/FLAGS that are still UID-less. * In the (rare) event that there is, don't cache anything and * immediately close the mailbox: flags will be correctly sync'd next * mailbox open so we only lose a bit of caching efficiency. * Otherwise, we could end up with an inconsistent cached state. * This Errata has been fixed in 7162 [3.2.4]. */ if ($flags && $modseq && !$uid) { $pipeline->data['modseqs_nouid'][] = $id; } } /** * Recursively parse BODYSTRUCTURE data from a FETCH return (see * RFC 3501 [7.4.2]). * * @param Horde_Imap_Client_Tokenize $data Data returned from the server. * * @return Horde_Mime_Part Mime part object. */ protected function _parseBodystructure(Horde_Imap_Client_Tokenize $data) { $ob = new Horde_Mime_Part(); // If index 0 is an array, this is a multipart part. if (($entry = $data->next()) === true) { do { $ob->addPart($this->_parseBodystructure($data)); } while (($entry = $data->next()) === true); // The subpart type. $ob->setType('multipart/' . $entry); // After the subtype is further extension information. This // information MAY appear for BODYSTRUCTURE requests. // This is parameter information. if (($tmp = $data->next()) === false) { return $ob; } elseif ($tmp === true) { foreach ($this->_parseStructureParams($data) as $key => $val) { $ob->setContentTypeParameter($key, $val); } } } else { $ob->setType($entry . '/' . $data->next()); if ($data->next() === true) { foreach ($this->_parseStructureParams($data) as $key => $val) { $ob->setContentTypeParameter($key, $val); } } if (!is_null($tmp = $data->next())) { $ob->setContentId($tmp); } if (!is_null($tmp = $data->next())) { $ob->setDescription(Horde_Mime::decode($tmp)); } $te = $data->next(); $bytes = $data->next(); if (!is_null($te)) { $ob->setTransferEncoding($te); /* Base64 transfer encoding is approx. 33% larger than * original data size (RFC 2045 [6.8]). Return from * BODYSTRUCTURE is the size of the ENCODED data (RFC 3501 * [7.4.2]). */ if (strcasecmp($te, 'base64') === 0) { $bytes *= 0.75; } } $ob->setBytes($bytes); // If the type is 'message/rfc822' or 'text/*', several extra // fields are included switch ($ob->getPrimaryType()) { case 'message': if ($ob->getSubType() == 'rfc822') { if ($data->next() === true) { // Ignore: envelope $data->flushIterator(false); } if ($data->next() === true) { $ob->addPart($this->_parseBodystructure($data)); } $data->next(); // Ignore: lines } break; case 'text': $data->next(); // Ignore: lines break; } // After the subtype is further extension information. This // information MAY appear for BODYSTRUCTURE requests. // Ignore: MD5 if ($data->next() === false) { return $ob; } } // This is disposition information if (($tmp = $data->next()) === false) { return $ob; } elseif ($tmp === true) { $ob->setDisposition($data->next()); if ($data->next() === true) { foreach ($this->_parseStructureParams($data) as $key => $val) { $ob->setDispositionParameter($key, $val); } } $data->next(); } // This is language information. It is either a single value or a list // of values. if (($tmp = $data->next()) === false) { return $ob; } elseif (!is_null($tmp)) { $ob->setLanguage(($tmp === true) ? $data->flushIterator() : $tmp); } // Ignore location (RFC 2557) and consume closing paren. $data->flushIterator(false); return $ob; } /** * Helper function to parse a parameters-like tokenized array. * * @param mixed $data Message data. Either a Horde_Imap_Client_Tokenize * object or null. * * @return array The parameter array. */ protected function _parseStructureParams($data) { $params = array(); if (is_null($data)) { return $params; } while (($name = $data->next()) !== false) { $params[Horde_String::lower($name)] = $data->next(); } $cp = new Horde_Mime_Headers_ContentParam('Unused', $params); return $cp->params; } /** * Parse ENVELOPE data from a FETCH return (see RFC 3501 [7.4.2]). * * @param Horde_Imap_Client_Tokenize $data Data returned from the server. * * @return Horde_Imap_Client_Data_Envelope An envelope object. */ protected function _parseEnvelope(Horde_Imap_Client_Tokenize $data) { // 'route', the 2nd element, is deprecated by RFC 2822. $addr_structure = array( 0 => 'personal', 2 => 'mailbox', 3 => 'host' ); $env_data = array( 0 => 'date', 1 => 'subject', 2 => 'from', 3 => 'sender', 4 => 'reply_to', 5 => 'to', 6 => 'cc', 7 => 'bcc', 8 => 'in_reply_to', 9 => 'message_id' ); $addr_ob = new Horde_Mail_Rfc822_Address(); $env_addrs = $this->getParam('envelope_addrs'); $env_str = $this->getParam('envelope_string'); $key = 0; $ret = new Horde_Imap_Client_Data_Envelope(); while (($val = $data->next()) !== false) { if (!isset($env_data[$key]) || is_null($val)) { ++$key; continue; } if (is_string($val)) { // These entries are text fields. $ret->{$env_data[$key]} = substr($val, 0, $env_str); } else { // These entries are address structures. $group = null; $key2 = 0; $tmp = new Horde_Mail_Rfc822_List(); while ($data->next() !== false) { $a_val = $data->flushIterator(); // RFC 3501 [7.4.2]: Group entry when host is NIL. // Group end when mailbox is NIL; otherwise, this is // mailbox name. if (is_null($a_val[3])) { if (is_null($a_val[2])) { $group = null; } else { $group = new Horde_Mail_Rfc822_Group($a_val[2]); $tmp->add($group); } } else { $addr = clone $addr_ob; foreach ($addr_structure as $add_key => $add_val) { if (!is_null($a_val[$add_key])) { $addr->$add_val = $a_val[$add_key]; } } if ($group) { $group->addresses->add($addr); } else { $tmp->add($addr); } } if (++$key2 >= $env_addrs) { $data->flushIterator(false); break; } } $ret->{$env_data[$key]} = $tmp; } ++$key; } return $ret; } /** */ protected function _vanished($modseq, Horde_Imap_Client_Ids $ids) { $pipeline = $this->_pipeline( $this->_command('UID FETCH')->add(array( strval($ids), 'UID', new Horde_Imap_Client_Data_Format_List(array( 'VANISHED', 'CHANGEDSINCE', new Horde_Imap_Client_Data_Format_Number($modseq) )) )) ); $pipeline->data['vanished'] = $this->getIdsOb(); return $this->_sendCmd($pipeline)->data['vanished']; } /** */ protected function _store($options) { $pipeline = $this->_storeCmd($options); $pipeline->data['modified'] = $this->getIdsOb(); try { $resp = $this->_sendCmd($pipeline); /* Check for EXPUNGEISSUED (RFC 2180 [4.2]/RFC 5530 [3]). */ if (!empty($resp->data['expungeissued'])) { $this->noop(); } return $resp->data['modified']; } catch (Horde_Imap_Client_Exception_ServerResponse $e) { /* A NO response, when coupled with a sequence STORE and * non-SILENT behavior, most likely means that messages were * expunged. RFC 2180 [4.2] */ if (empty($pipeline->data['store_silent']) && !empty($options['sequence']) && ($e->status === Horde_Imap_Client_Interaction_Server::NO)) { $this->noop(); } return $pipeline->data['modified']; } } /** * Create a store command. * * @param array $options See Horde_Imap_Client_Base#_store(). * * @return Horde_Imap_Client_Interaction_Pipeline Pipeline object. */ protected function _storeCmd($options) { $cmds = array(); $silent = empty($options['unchangedsince']) ? !($this->_debug->debug || $this->_initCache(true)) : false; if (!empty($options['replace'])) { $cmds[] = array( 'FLAGS' . ($silent ? '.SILENT' : ''), $options['replace'] ); } else { foreach (array('add' => '+', 'remove' => '-') as $k => $v) { if (!empty($options[$k])) { $cmds[] = array( $v . 'FLAGS' . ($silent ? '.SILENT' : ''), $options[$k] ); } } } $pipeline = $this->_pipeline(); $pipeline->data['store_silent'] = $silent; foreach ($cmds as $val) { $cmd = $this->_command( empty($options['sequence']) ? 'UID STORE' : 'STORE' )->add(strval($options['ids'])); if (!empty($options['unchangedsince'])) { $cmd->add(new Horde_Imap_Client_Data_Format_List(array( 'UNCHANGEDSINCE', new Horde_Imap_Client_Data_Format_Number(intval($options['unchangedsince'])) ))); } $cmd->add($val); $pipeline->add($cmd); } return $pipeline; } /** */ protected function _copy(Horde_Imap_Client_Mailbox $dest, $options) { /* Check for MOVE command (RFC 6851). */ $move_cmd = (!empty($options['move']) && $this->_capability('MOVE')); $cmd = $this->_pipeline( $this->_command( ($options['ids']->sequence ? '' : 'UID ') . ($move_cmd ? 'MOVE' : 'COPY') )->add(array( strval($options['ids']), $this->_getMboxFormatOb($dest) )) ); $cmd->data['copydest'] = $dest; // COPY returns no untagged information (RFC 3501 [6.4.7]) try { $resp = $this->_sendCmd($cmd); } catch (Horde_Imap_Client_Exception $e) { if (!empty($options['create']) && !empty($e->resp_data['trycreate'])) { $this->createMailbox($dest); unset($options['create']); return $this->_copy($dest, $options); } throw $e; } // If moving, delete the old messages now. Short-circuit if nothing // was moved. if (!$move_cmd && !empty($options['move']) && (isset($resp->data['copyuid']) || !$this->_capability('UIDPLUS'))) { $this->expunge($this->_selected, array( 'delete' => true, 'ids' => $options['ids'] )); } return isset($resp->data['copyuid']) ? $resp->data['copyuid'] : true; } /** */ protected function _setQuota(Horde_Imap_Client_Mailbox $root, $resources) { $limits = new Horde_Imap_Client_Data_Format_List(); foreach ($resources as $key => $val) { $limits->add(array( Horde_String::upper($key), new Horde_Imap_Client_Data_Format_Number($val) )); } $this->_sendCmd( $this->_command('SETQUOTA')->add(array( $this->_getMboxFormatOb($root), $limits )) ); } /** */ protected function _getQuota(Horde_Imap_Client_Mailbox $root) { $pipeline = $this->_pipeline( $this->_command('GETQUOTA')->add( $this->_getMboxFormatOb($root) ) ); $pipeline->data['quotaresp'] = array(); return reset($this->_sendCmd($pipeline)->data['quotaresp']); } /** * Parse a QUOTA response (RFC 2087 [5.1]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Tokenize $data The server response. */ protected function _parseQuota( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Tokenize $data ) { $c = &$pipeline->data['quotaresp']; $root = $data->next(); $c[$root] = array(); $data->next(); while (($curr = $data->next()) !== false) { $c[$root][Horde_String::lower($curr)] = array( 'usage' => $data->next(), 'limit' => $data->next() ); } } /** */ protected function _getQuotaRoot(Horde_Imap_Client_Mailbox $mailbox) { $pipeline = $this->_pipeline( $this->_command('GETQUOTAROOT')->add( $this->_getMboxFormatOb($mailbox) ) ); $pipeline->data['quotaresp'] = array(); return $this->_sendCmd($pipeline)->data['quotaresp']; } /** */ protected function _setACL(Horde_Imap_Client_Mailbox $mailbox, $identifier, $options) { // SETACL returns no untagged information (RFC 4314 [3.1]). $this->_sendCmd( $this->_command('SETACL')->add(array( $this->_getMboxFormatOb($mailbox), new Horde_Imap_Client_Data_Format_Astring($identifier), new Horde_Imap_Client_Data_Format_Astring($options['rights']) )) ); } /** */ protected function _deleteACL(Horde_Imap_Client_Mailbox $mailbox, $identifier) { // DELETEACL returns no untagged information (RFC 4314 [3.2]). $this->_sendCmd( $this->_command('DELETEACL')->add(array( $this->_getMboxFormatOb($mailbox), new Horde_Imap_Client_Data_Format_Astring($identifier) )) ); } /** */ protected function _getACL(Horde_Imap_Client_Mailbox $mailbox) { return $this->_sendCmd( $this->_command('GETACL')->add( $this->_getMboxFormatOb($mailbox) ) )->data['getacl']; } /** * Parse an ACL response (RFC 4314 [3.6]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Tokenize $data The server response. */ protected function _parseACL( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Tokenize $data ) { $acl = array(); // Ignore mailbox argument -> index 1 $data->next(); while (($curr = $data->next()) !== false) { $acl[$curr] = ($curr[0] === '-') ? new Horde_Imap_Client_Data_AclNegative($data->next()) : new Horde_Imap_Client_Data_Acl($data->next()); } $pipeline->data['getacl'] = $acl; } /** */ protected function _listACLRights(Horde_Imap_Client_Mailbox $mailbox, $identifier) { $resp = $this->_sendCmd( $this->_command('LISTRIGHTS')->add(array( $this->_getMboxFormatOb($mailbox), new Horde_Imap_Client_Data_Format_Astring($identifier) )) ); return isset($resp->data['listaclrights']) ? $resp->data['listaclrights'] : new Horde_Imap_Client_Data_AclRights(); } /** * Parse a LISTRIGHTS response (RFC 4314 [3.7]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Tokenize $data The server response. */ protected function _parseListRights( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Tokenize $data ) { // Ignore mailbox and identifier arguments $data->next(); $data->next(); $pipeline->data['listaclrights'] = new Horde_Imap_Client_Data_AclRights( str_split($data->next()), $data->flushIterator() ); } /** */ protected function _getMyACLRights(Horde_Imap_Client_Mailbox $mailbox) { $resp = $this->_sendCmd( $this->_command('MYRIGHTS')->add( $this->_getMboxFormatOb($mailbox) ) ); return isset($resp->data['myrights']) ? $resp->data['myrights'] : new Horde_Imap_Client_Data_Acl(); } /** * Parse a MYRIGHTS response (RFC 4314 [3.8]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Tokenize $data The server response. */ protected function _parseMyRights( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Tokenize $data ) { // Ignore 1st token (mailbox name) $data->next(); $pipeline->data['myrights'] = new Horde_Imap_Client_Data_Acl($data->next()); } /** */ protected function _getMetadata(Horde_Imap_Client_Mailbox $mailbox, $entries, $options) { $pipeline = $this->_pipeline(); $pipeline->data['metadata'] = array(); if ($this->_capability('METADATA') || (strlen($mailbox) && $this->_capability('METADATA-SERVER'))) { $cmd_options = new Horde_Imap_Client_Data_Format_List(); if (!empty($options['maxsize'])) { $cmd_options->add(array( 'MAXSIZE', new Horde_Imap_Client_Data_Format_Number($options['maxsize']) )); } if (!empty($options['depth'])) { $cmd_options->add(array( 'DEPTH', new Horde_Imap_Client_Data_Format_Number($options['depth']) )); } $queries = new Horde_Imap_Client_Data_Format_List(); foreach ($entries as $md_entry) { $queries->add(new Horde_Imap_Client_Data_Format_Astring($md_entry)); } $cmd = $this->_command('GETMETADATA')->add( $this->_getMboxFormatOb($mailbox) ); if (count($cmd_options)) { $cmd->add($cmd_options); } $cmd->add($queries); $pipeline->add($cmd); } else { if (!$this->_capability('ANNOTATEMORE') && !$this->_capability('ANNOTATEMORE2')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('METADATA'); } $queries = array(); foreach ($entries as $md_entry) { list($entry, $type) = $this->_getAnnotateMoreEntry($md_entry); if (!isset($queries[$type])) { $queries[$type] = new Horde_Imap_Client_Data_Format_List(); } $queries[$type]->add(new Horde_Imap_Client_Data_Format_String($entry)); } foreach ($queries as $key => $val) { // TODO: Honor maxsize and depth options. $pipeline->add( $this->_command('GETANNOTATION')->add(array( $this->_getMboxFormatOb($mailbox), $val, new Horde_Imap_Client_Data_Format_String($key) )) ); } } return $this->_sendCmd($pipeline)->data['metadata']; } /** * Split a name for the METADATA extension into the correct syntax for the * older ANNOTATEMORE version. * * @param string $name A name for a metadata entry. * * @return array A list of two elements: The entry name and the value * type. * * @throws Horde_Imap_Client_Exception */ protected function _getAnnotateMoreEntry($name) { if (substr($name, 0, 7) === '/shared') { return array(substr($name, 7), 'value.shared'); } else if (substr($name, 0, 8) === '/private') { return array(substr($name, 8), 'value.priv'); } $e = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Invalid METADATA entry: \"%s\"."), Horde_Imap_Client_Exception::METADATA_INVALID ); $e->messagePrintf(array($name)); throw $e; } /** */ protected function _setMetadata(Horde_Imap_Client_Mailbox $mailbox, $data) { if ($this->_capability('METADATA') || (strlen($mailbox) && $this->_capability('METADATA-SERVER'))) { $data_elts = new Horde_Imap_Client_Data_Format_List(); foreach ($data as $key => $value) { $data_elts->add(array( new Horde_Imap_Client_Data_Format_Astring($key), /* METADATA supports literal8 - thus, it implicitly * supports non-ASCII characters in the data. */ new Horde_Imap_Client_Data_Format_Nstring_Nonascii($value) )); } $cmd = $this->_command('SETMETADATA')->add(array( $this->_getMboxFormatOb($mailbox), $data_elts )); } else { if (!$this->_capability('ANNOTATEMORE') && !$this->_capability('ANNOTATEMORE2')) { throw new Horde_Imap_Client_Exception_NoSupportExtension('METADATA'); } $cmd = $this->_pipeline(); foreach ($data as $md_entry => $value) { list($entry, $type) = $this->_getAnnotateMoreEntry($md_entry); $cmd->add( $this->_command('SETANNOTATION')->add(array( $this->_getMboxFormatOb($mailbox), new Horde_Imap_Client_Data_Format_String($entry), new Horde_Imap_Client_Data_Format_List(array( new Horde_Imap_Client_Data_Format_String($type), /* ANNOTATEMORE supports literal8 - thus, it * implicitly supports non-ASCII characters in the * data. */ new Horde_Imap_Client_Data_Format_Nstring_Nonascii($value) )) )) ); } } $this->_sendCmd($cmd); } /** * Parse an ANNOTATION response (ANNOTATEMORE/ANNOTATEMORE2). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Tokenize $data The server response. * * @throws Horde_Imap_Client_Exception */ protected function _parseAnnotation( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Tokenize $data ) { // Mailbox name is in UTF7-IMAP. $mbox = Horde_Imap_Client_Mailbox::get($data->next(), true); $entry = $data->next(); // Ignore unsolicited responses. if ($data->next() !== true) { return; } while (($type = $data->next()) !== false) { switch ($type) { case 'value.priv': $pipeline->data['metadata'][strval($mbox)]['/private' . $entry] = $data->next(); break; case 'value.shared': $pipeline->data['metadata'][strval($mbox)]['/shared' . $entry] = $data->next(); break; default: $e = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Invalid METADATA value type \"%s\"."), Horde_Imap_Client_Exception::METADATA_INVALID ); $e->messagePrintf(array($type)); throw $e; } } } /** * Parse a METADATA response (RFC 5464 [4.4]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Tokenize $data The server response. * * @throws Horde_Imap_Client_Exception */ protected function _parseMetadata( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Tokenize $data ) { // Mailbox name is in UTF7-IMAP. $mbox = Horde_Imap_Client_Mailbox::get($data->next(), true); // Ignore unsolicited responses. if ($data->next() === true) { while (($entry = $data->next()) !== false) { $pipeline->data['metadata'][strval($mbox)][$entry] = $data->next(); } } } /* Overriden methods. */ /** * @param array $opts Options: * - decrement: (boolean) If true, decrement the message count. * - pipeline: (Horde_Imap_Client_Interaction_Pipeline) Pipeline object. */ protected function _deleteMsgs(Horde_Imap_Client_Mailbox $mailbox, Horde_Imap_Client_Ids $ids, array $opts = array()) { /* If there are pending FETCH cache writes, we need to write them * before the UID -> sequence number mapping changes. */ if (isset($opts['pipeline'])) { $this->_updateCache($opts['pipeline']->fetch); } $res = parent::_deleteMsgs($mailbox, $ids); if (isset($this->_temp['expunged'])) { $this->_temp['expunged']->add($res); } if (!empty($opts['decrement'])) { $mbox_ob = $this->_mailboxOb(); $mbox_ob->setStatus( Horde_Imap_Client::STATUS_MESSAGES, $mbox_ob->getStatus(Horde_Imap_Client::STATUS_MESSAGES) - count($ids) ); } } /* Internal functions. */ /** * Return the proper mailbox format object based on the server's * capabilities. * * @param string $mailbox The mailbox. * @param boolean $list Is this object used in a LIST command? * * @return Horde_Imap_Client_Data_Format_Mailbox A mailbox format object. */ protected function _getMboxFormatOb($mailbox, $list = false) { if ($this->_capability()->isEnabled('UTF8=ACCEPT')) { try { return $list ? new Horde_Imap_Client_Data_Format_ListMailbox_Utf8($mailbox) : new Horde_Imap_Client_Data_Format_Mailbox_Utf8($mailbox); } catch (Horde_Imap_Client_Data_Format_Exception $e) {} } return $list ? new Horde_Imap_Client_Data_Format_ListMailbox($mailbox) : new Horde_Imap_Client_Data_Format_Mailbox($mailbox); } /** * Sends command(s) to the IMAP server. A connection to the server must * have already been made. * * @param mixed $cmd Either a Command object or a Pipeline object. * * @return Horde_Imap_Client_Interaction_Pipeline A pipeline object. * @throws Horde_Imap_Client_Exception */ protected function _sendCmd($cmd) { $pipeline = ($cmd instanceof Horde_Imap_Client_Interaction_Command) ? $this->_pipeline($cmd) : $cmd; if (!empty($this->_cmdQueue)) { /* Add commands in reverse order. */ foreach (array_reverse($this->_cmdQueue) as $val) { $pipeline->add($val, true); } $this->_cmdQueue = array(); } $cmd_list = array(); foreach ($pipeline as $val) { if ($val->continuation) { $this->_sendCmdChunk($pipeline, $cmd_list); $this->_sendCmdChunk($pipeline, array($val)); $cmd_list = array(); } else { $cmd_list[] = $val; } } $this->_sendCmdChunk($pipeline, $cmd_list); /* If any FLAGS responses contain MODSEQs but not UIDs, don't * cache any data and immediately close the mailbox. */ foreach ($pipeline->data['modseqs_nouid'] as $val) { if (!$pipeline->fetch[$val]->getUid()) { $this->_debug->info( 'Server provided FLAGS MODSEQ without providing UID.' ); $this->close(); return $pipeline; } } /* Update HIGHESTMODSEQ value. */ if (!empty($pipeline->data['modseqs'])) { $modseq = max($pipeline->data['modseqs']); $this->_mailboxOb()->setStatus(Horde_Imap_Client::STATUS_HIGHESTMODSEQ, $modseq); /* CONDSTORE has not yet updated flag information, so don't update * modseq yet. */ if ($this->_capability()->isEnabled('QRESYNC')) { $this->_updateModSeq($modseq); } } /* Update cache items. */ $this->_updateCache($pipeline->fetch); return $pipeline; } /** * Send a chunk of commands and/or continuation fragments to the server. * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline The pipeline * object. * @param array $chunk List of commands to send. * * @throws Horde_Imap_Client_Exception */ protected function _sendCmdChunk($pipeline, $chunk) { if (empty($chunk)) { return; } $cmd_count = count($chunk); $exception = null; foreach ($chunk as $val) { $val->pipeline = $pipeline; try { if ($this->_processCmd($pipeline, $val, $val)) { $this->_connection->write('', true); } else { $cmd_count = 0; } } catch (Horde_Imap_Client_Exception $e) { switch ($e->getCode()) { case Horde_Imap_Client_Exception::SERVER_WRITEERROR: $this->_temp['logout'] = true; $this->logout(); break; } throw $e; } } while ($cmd_count) { try { if ($this->_getLine($pipeline) instanceof Horde_Imap_Client_Interaction_Server_Tagged) { --$cmd_count; } } catch (Horde_Imap_Client_Exception $e) { switch ($e->getCode()) { case $e::DISCONNECT: /* Guaranteed to have no more data incoming, so we can * immediately logout. */ $this->_temp['logout'] = true; $this->logout(); throw $e; } /* For all other issues, catch and store exception; don't * throw until all input is read since we need to clear * incoming queue. (For now, only store first exception.) */ if (is_null($exception)) { $exception = $e; } if (($e instanceof Horde_Imap_Client_Exception_ServerResponse) && $e->command) { --$cmd_count; } } } if (!is_null($exception)) { throw $exception; } } /** * Process/send a command to the remote server. * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline The pipeline * object. * @param Horde_Imap_Client_Interaction_Command $cmd The master command. * @param Horde_Imap_Client_Data_Format_List $data Commands to send. * * @return boolean True if EOL needed to finish command. * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_NoSupport */ protected function _processCmd($pipeline, $cmd, $data) { if ($this->_debug->debug && ($data instanceof Horde_Imap_Client_Interaction_Command)) { $data->startTimer(); } foreach ($data as $key => $val) { if ($val instanceof Horde_Imap_Client_Interaction_Command_Continuation) { $this->_connection->write('', true); /* Check for optional continuation responses when the command * has already finished. */ if (!$cmd_continuation = $this->_processCmdContinuation($pipeline, $val->optional)) { return false; } $this->_processCmd( $pipeline, $cmd, $val->getCommands($cmd_continuation) ); continue; } if (!is_null($debug_msg = array_shift($cmd->debug))) { $this->_debug->client( (($cmd == $data) ? $cmd->tag . ' ' : '') . $debug_msg ); $this->_connection->client_debug = false; } if ($key) { $this->_connection->write(' '); } if ($val instanceof Horde_Imap_Client_Data_Format_List) { $this->_connection->write('('); $this->_processCmd($pipeline, $cmd, $val); $this->_connection->write(')'); } elseif (($val instanceof Horde_Imap_Client_Data_Format_String) && $val->literal()) { $c = $this->_capability(); /* RFC 6855: If UTF8 extension is available, quote short * strings instead of sending as literal. */ if ($c->isEnabled('UTF8=ACCEPT') && ($val->length() < 100)) { $val->forceQuoted(); $this->_connection->write($val->escape()); } else { /* RFC 3516/4466: Send literal8 if we have binary data. */ if ($cmd->literal8 && $val->binary() && ($c->query('BINARY') || $c->isEnabled('UTF8=ACCEPT'))) { $binary = true; $this->_connection->write('~'); } else { $binary = false; } $literal_len = $val->length(); $this->_connection->write('{' . $literal_len); /* RFC 2088 - If LITERAL+ is available, saves a roundtrip * from the server. */ if ($cmd->literalplus && $c->query('LITERAL+')) { $this->_connection->write('+}', true); } else { $this->_connection->write('}', true); $this->_processCmdContinuation($pipeline); } if ($debug_msg) { $this->_connection->client_debug = false; } $this->_connection->writeLiteral( $val->getStream(), $literal_len, $binary ); } } else { $this->_connection->write($val->escape()); } } return true; } /** * Process a command continuation response. * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline The pipeline * object. * @param boolean $noexception Don't throw * exception if * continuation * does not occur. * * @return mixed A Horde_Imap_Client_Interaction_Server_Continuation * object or false. * * @throws Horde_Imap_Client_Exception */ protected function _processCmdContinuation($pipeline, $noexception = false) { do { $ob = $this->_getLine($pipeline); } while ($ob instanceof Horde_Imap_Client_Interaction_Server_Untagged); if ($ob instanceof Horde_Imap_Client_Interaction_Server_Continuation) { return $ob; } elseif ($noexception) { return false; } $this->_debug->info( 'ERROR: Unexpected response from server while waiting for a continuation request.' ); $e = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error when communicating with the mail server."), Horde_Imap_Client_Exception::SERVER_READERROR ); $e->details = strval($ob); throw $e; } /** * Shortcut to creating a new IMAP client command object. * * @param string $cmd The IMAP command. * * @return Horde_Imap_Client_Interaction_Command A command object. */ protected function _command($cmd) { return new Horde_Imap_Client_Interaction_Command($cmd, ++$this->_tag); } /** * Shortcut to creating a new pipeline object. * * @param Horde_Imap_Client_Interaction_Command $cmd An IMAP command to * add. * * @return Horde_Imap_Client_Interaction_Pipeline A pipeline object. */ protected function _pipeline($cmd = null) { if (!isset($this->_temp['fetchob'])) { $this->_temp['fetchob'] = new Horde_Imap_Client_Fetch_Results( $this->_fetchDataClass, Horde_Imap_Client_Fetch_Results::SEQUENCE ); } $ob = new Horde_Imap_Client_Interaction_Pipeline( clone $this->_temp['fetchob'] ); if (!is_null($cmd)) { $ob->add($cmd); } return $ob; } /** * Gets data from the IMAP server stream and parses it. * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * * @return Horde_Imap_Client_Interaction_Server Server object. * * @throws Horde_Imap_Client_Exception */ protected function _getLine( Horde_Imap_Client_Interaction_Pipeline $pipeline ) { $server = Horde_Imap_Client_Interaction_Server::create( $this->_connection->read() ); switch (get_class($server)) { case 'Horde_Imap_Client_Interaction_Server_Continuation': $this->_responseCode($pipeline, $server); break; case 'Horde_Imap_Client_Interaction_Server_Tagged': $cmd = $pipeline->complete($server); if (is_null($cmd)) { /* This indicates a "dangling" tagged response - it was either * generated by an aborted previous pipeline object or is the * result of spurious output by the server. Ignore. */ return $this->_getLine($pipeline); } if ($timer = $cmd->getTimer()) { $this->_debug->info(sprintf( 'Command %s took %s seconds.', $cmd->tag, $timer )); } $this->_responseCode($pipeline, $server); if (is_callable($cmd->on_success)) { call_user_func($cmd->on_success); } break; case 'Horde_Imap_Client_Interaction_Server_Untagged': if (is_null($server->status)) { $this->_serverResponse($pipeline, $server); } else { $this->_responseCode($pipeline, $server); } break; } switch ($server->status) { case $server::BAD: case $server::NO: /* A tagged BAD response indicates that the tagged command caused * the error. This information is unknown if untagged (RFC 3501 * [7.1.3]) - ignore these untagged responses. * An untagged NO response indicates a warning; ignore and assume * that it also included response text code that is handled * elsewhere. Throw exception if tagged; command handlers can * catch this if able to workaround this issue (RFC 3501 * [7.1.2]). */ if ($server instanceof Horde_Imap_Client_Interaction_Server_Tagged) { /* Check for a on_error callback. If function returns true, * ignore the error. */ if (($cmd = $pipeline->getCmd($server->tag)) && is_callable($cmd->on_error) && call_user_func($cmd->on_error)) { break; } throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("IMAP error reported by server."), 0, $server, $pipeline ); } break; case $server::BYE: /* A BYE response received as part of a logout command should be * be treated like a regular command: a client MUST process the * entire command until logging out (RFC 3501 [3.4; 7.1.5]). */ if (empty($this->_temp['logout'])) { $e = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("IMAP Server closed the connection."), Horde_Imap_Client_Exception::DISCONNECT ); $e->details = strval($server); throw $e; } break; case $server::PREAUTH: /* The user was pre-authenticated. (RFC 3501 [7.1.4]) */ $this->_temp['preauth'] = true; break; } return $server; } /** * Handle untagged server responses (see RFC 3501 [2.2.2]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Interaction_Server $ob Server * response. */ protected function _serverResponse( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Interaction_Server $ob ) { $token = $ob->token; /* First, catch untagged responses where the name appears first on the * line. */ switch ($first = Horde_String::upper($token->current())) { case 'CAPABILITY': $this->_parseCapability($pipeline, $token->flushIterator()); break; case 'LIST': case 'LSUB': $this->_parseList($pipeline, $token); break; case 'STATUS': // Parse a STATUS response (RFC 3501 [7.2.4]). $this->_parseStatus($token); break; case 'SEARCH': case 'SORT': // Parse a SEARCH/SORT response (RFC 3501 [7.2.5] & RFC 5256 [4]). $this->_parseSearch($pipeline, $token->flushIterator()); break; case 'ESEARCH': // Parse an ESEARCH response (RFC 4466 [2.6.2]). $this->_parseEsearch($pipeline, $token); break; case 'FLAGS': $token->next(); $this->_mailboxOb()->setStatus(Horde_Imap_Client::STATUS_FLAGS, array_map('Horde_String::lower', $token->flushIterator())); break; case 'QUOTA': $this->_parseQuota($pipeline, $token); break; case 'QUOTAROOT': // Ignore this line - we can get this information from // the untagged QUOTA responses. break; case 'NAMESPACE': $this->_parseNamespace($pipeline, $token); break; case 'THREAD': $this->_parseThread($pipeline, $token); break; case 'ACL': $this->_parseACL($pipeline, $token); break; case 'LISTRIGHTS': $this->_parseListRights($pipeline, $token); break; case 'MYRIGHTS': $this->_parseMyRights($pipeline, $token); break; case 'ID': // ID extension (RFC 2971) $this->_parseID($pipeline, $token); break; case 'ENABLED': // ENABLE extension (RFC 5161) $this->_parseEnabled($token); break; case 'LANGUAGE': // LANGUAGE extension (RFC 5255 [3.2]) $this->_parseLanguage($token); break; case 'COMPARATOR': // I18NLEVEL=2 extension (RFC 5255 [4.7]) $this->_parseComparator($pipeline, $token); break; case 'VANISHED': // QRESYNC extension (RFC 7162 [3.2.10]) $this->_parseVanished($pipeline, $token); break; case 'ANNOTATION': // Parse an ANNOTATION response. $this->_parseAnnotation($pipeline, $token); break; case 'METADATA': // Parse a METADATA response. $this->_parseMetadata($pipeline, $token); break; default: // Next, look for responses where the keywords occur second. switch (Horde_String::upper($token->next())) { case 'EXISTS': // EXISTS response - RFC 3501 [7.3.2] $mbox_ob = $this->_mailboxOb(); // Increment UIDNEXT if it is set. if ($mbox_ob->open && ($uidnext = $mbox_ob->getStatus(Horde_Imap_Client::STATUS_UIDNEXT))) { $mbox_ob->setStatus(Horde_Imap_Client::STATUS_UIDNEXT, $uidnext + $first - $mbox_ob->getStatus(Horde_Imap_Client::STATUS_MESSAGES)); } $mbox_ob->setStatus(Horde_Imap_Client::STATUS_MESSAGES, $first); break; case 'RECENT': // RECENT response - RFC 3501 [7.3.1] $this->_mailboxOb()->setStatus(Horde_Imap_Client::STATUS_RECENT, $first); break; case 'EXPUNGE': // EXPUNGE response - RFC 3501 [7.4.1] $this->_deleteMsgs($this->_selected, $this->getIdsOb($first, true), array( 'decrement' => true, 'pipeline' => $pipeline )); $pipeline->data['expunge_seen'] = true; break; case 'FETCH': // FETCH response - RFC 3501 [7.4.2] $this->_parseFetch($pipeline, $first, $token); break; } break; } } /** * Handle status responses (see RFC 3501 [7.1]). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param Horde_Imap_Client_Interaction_Server $ob Server object. * * @throws Horde_Imap_Client_Exception_ServerResponse */ protected function _responseCode( Horde_Imap_Client_Interaction_Pipeline $pipeline, Horde_Imap_Client_Interaction_Server $ob ) { if (is_null($ob->responseCode)) { return; } $rc = $ob->responseCode; switch ($rc->code) { case 'ALERT': // Defined by RFC 5530 [3] - Treat as an alert for now. case 'CONTACTADMIN': // Used by Gmail - Treat as an alert for now. // http://mailman13.u.washington.edu/pipermail/imap-protocol/2014-September/002324.html case 'WEBALERT': $this->_alerts->add(strval($ob->token), $rc->code); break; case 'BADCHARSET': /* Store valid search charsets if returned by server. */ $s = $this->search_charset; foreach ($rc->data[0] as $val) { $s->setValid($val, true); } throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("Charset used in search query is not supported on the mail server."), Horde_Imap_Client_Exception::BADCHARSET, $ob, $pipeline ); case 'CAPABILITY': $this->_parseCapability($pipeline, $rc->data); break; case 'PARSE': /* Only throw error on NO/BAD. Message is human readable. */ switch ($ob->status) { case Horde_Imap_Client_Interaction_Server::BAD: case Horde_Imap_Client_Interaction_Server::NO: $e = new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("The mail server was unable to parse the contents of the mail message: %s"), Horde_Imap_Client_Exception::PARSEERROR, $ob, $pipeline ); $e->messagePrintf(strval($ob->token)); throw $e; } break; case 'READ-ONLY': $this->_mode = Horde_Imap_Client::OPEN_READONLY; break; case 'READ-WRITE': $this->_mode = Horde_Imap_Client::OPEN_READWRITE; break; case 'TRYCREATE': // RFC 3501 [7.1] $pipeline->data['trycreate'] = true; break; case 'PERMANENTFLAGS': $this->_mailboxOb()->setStatus(Horde_Imap_Client::STATUS_PERMFLAGS, array_map('Horde_String::lower', $rc->data[0])); break; case 'UIDNEXT': $this->_mailboxOb()->setStatus(Horde_Imap_Client::STATUS_UIDNEXT, $rc->data[0]); break; case 'UIDVALIDITY': $this->_mailboxOb()->setStatus(Horde_Imap_Client::STATUS_UIDVALIDITY, $rc->data[0]); break; case 'UNSEEN': /* This is different from the STATUS UNSEEN response - this item, * if defined, returns the first UNSEEN message in the mailbox. */ $this->_mailboxOb()->setStatus(Horde_Imap_Client::STATUS_FIRSTUNSEEN, $rc->data[0]); break; case 'REFERRAL': // Defined by RFC 2221 $pipeline->data['referral'] = new Horde_Imap_Client_Url_Imap($rc->data[0]); break; case 'UNKNOWN-CTE': // Defined by RFC 3516 throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("The mail server was unable to parse the contents of the mail message."), Horde_Imap_Client_Exception::UNKNOWNCTE, $ob, $pipeline ); case 'APPENDUID': // Defined by RFC 4315 // APPENDUID: [0] = UIDVALIDITY, [1] = UID(s) $pipeline->data['appenduid'] = $this->getIdsOb($rc->data[1]); break; case 'COPYUID': // Defined by RFC 4315 // COPYUID: [0] = UIDVALIDITY, [1] = UIDFROM, [2] = UIDTO $pipeline->data['copyuid'] = array_combine( $this->getIdsOb($rc->data[1])->ids, $this->getIdsOb($rc->data[2])->ids ); /* Use UIDPLUS information to move cached data to new mailbox (see * RFC 4549 [4.2.2.1]). Need to move now, because a MOVE might * EXPUNGE immediately afterwards. */ $this->_moveCache($pipeline->data['copydest'], $pipeline->data['copyuid'], $rc->data[0]); break; case 'UIDNOTSTICKY': // Defined by RFC 4315 [3] $this->_mailboxOb()->setStatus(Horde_Imap_Client::STATUS_UIDNOTSTICKY, true); break; case 'BADURL': // Defined by RFC 4469 [4.1] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("Could not save message on server."), Horde_Imap_Client_Exception::CATENATE_BADURL, $ob, $pipeline ); case 'TOOBIG': // Defined by RFC 4469 [4.2] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("Could not save message data because it is too large."), Horde_Imap_Client_Exception::CATENATE_TOOBIG, $ob, $pipeline ); case 'HIGHESTMODSEQ': // Defined by RFC 7162 [3.1.2.1] $pipeline->data['modseqs'][] = $rc->data[0]; break; case 'NOMODSEQ': // Defined by RFC 7162 [3.1.2.2] $pipeline->data['modseqs'][] = 0; break; case 'MODIFIED': // Defined by RFC 7162 [3.1.3] $pipeline->data['modified']->add($rc->data[0]); break; case 'CLOSED': // Defined by RFC 7162 [3.2.11] if (isset($pipeline->data['qresyncmbox'])) { /* If there is any pending FETCH cache entries, flush them * now before changing mailboxes. */ $this->_updateCache($pipeline->fetch); $pipeline->fetch->clear(); $this->_changeSelected( $pipeline->data['qresyncmbox'][0], $pipeline->data['qresyncmbox'][1] ); unset($pipeline->data['qresyncmbox']); } break; case 'NOTSAVED': // Defined by RFC 5182 [2.5] $pipeline->data['searchnotsaved'] = true; break; case 'BADCOMPARATOR': // Defined by RFC 5255 [4.9] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("The comparison algorithm was not recognized by the server."), Horde_Imap_Client_Exception::BADCOMPARATOR, $ob, $pipeline ); case 'METADATA': $md = $rc->data[0]; switch ($md[0]) { case 'LONGENTRIES': // Defined by RFC 5464 [4.2.1] $pipeline->data['metadata']['*longentries'] = intval($md[1]); break; case 'MAXSIZE': // Defined by RFC 5464 [4.3] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("The metadata item could not be saved because it is too large."), Horde_Imap_Client_Exception::METADATA_MAXSIZE, $ob, $pipeline ); case 'NOPRIVATE': // Defined by RFC 5464 [4.3] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("The metadata item could not be saved because the server does not support private annotations."), Horde_Imap_Client_Exception::METADATA_NOPRIVATE, $ob, $pipeline ); case 'TOOMANY': // Defined by RFC 5464 [4.3] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("The metadata item could not be saved because the maximum number of annotations has been exceeded."), Horde_Imap_Client_Exception::METADATA_TOOMANY, $ob, $pipeline ); } break; case 'UNAVAILABLE': // Defined by RFC 5530 [3] $pipeline->data['loginerr'] = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Remote server is temporarily unavailable."), Horde_Imap_Client_Exception::LOGIN_UNAVAILABLE ); break; case 'AUTHENTICATIONFAILED': // Defined by RFC 5530 [3] $pipeline->data['loginerr'] = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Authentication failed."), Horde_Imap_Client_Exception::LOGIN_AUTHENTICATIONFAILED ); break; case 'AUTHORIZATIONFAILED': // Defined by RFC 5530 [3] $pipeline->data['loginerr'] = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Authentication was successful, but authorization failed."), Horde_Imap_Client_Exception::LOGIN_AUTHORIZATIONFAILED ); break; case 'EXPIRED': // Defined by RFC 5530 [3] $pipeline->data['loginerr'] = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Authentication credentials have expired."), Horde_Imap_Client_Exception::LOGIN_EXPIRED ); break; case 'PRIVACYREQUIRED': // Defined by RFC 5530 [3] $pipeline->data['loginerr'] = new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Operation failed due to a lack of a secure connection."), Horde_Imap_Client_Exception::LOGIN_PRIVACYREQUIRED ); break; case 'NOPERM': // Defined by RFC 5530 [3] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("You do not have adequate permissions to carry out this operation."), Horde_Imap_Client_Exception::NOPERM, $ob, $pipeline ); case 'INUSE': // Defined by RFC 5530 [3] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("There was a temporary issue when attempting this operation. Please try again later."), Horde_Imap_Client_Exception::INUSE, $ob, $pipeline ); case 'EXPUNGEISSUED': // Defined by RFC 5530 [3] $pipeline->data['expungeissued'] = true; break; case 'CORRUPTION': // Defined by RFC 5530 [3] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("The mail server is reporting corrupt data in your mailbox."), Horde_Imap_Client_Exception::CORRUPTION, $ob, $pipeline ); case 'SERVERBUG': case 'CLIENTBUG': case 'CANNOT': // Defined by RFC 5530 [3] $this->_debug->info( 'ERROR: mail server explicitly reporting an error.' ); break; case 'LIMIT': // Defined by RFC 5530 [3] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("The mail server has denied the request."), Horde_Imap_Client_Exception::LIMIT, $ob, $pipeline ); case 'OVERQUOTA': // Defined by RFC 5530 [3] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("The operation failed because the quota has been exceeded on the mail server."), Horde_Imap_Client_Exception::OVERQUOTA, $ob, $pipeline ); case 'ALREADYEXISTS': // Defined by RFC 5530 [3] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("The object could not be created because it already exists."), Horde_Imap_Client_Exception::ALREADYEXISTS, $ob, $pipeline ); case 'NONEXISTENT': // Defined by RFC 5530 [3] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("The object could not be deleted because it does not exist."), Horde_Imap_Client_Exception::NONEXISTENT, $ob, $pipeline ); case 'USEATTR': // Defined by RFC 6154 [3] throw new Horde_Imap_Client_Exception_ServerResponse( Horde_Imap_Client_Translation::r("The special-use attribute requested for the mailbox is not supported."), Horde_Imap_Client_Exception::USEATTR, $ob, $pipeline ); case 'DOWNGRADED': // Defined by RFC 6858 [3] $downgraded = $this->getIdsOb($rc->data[0]); foreach ($pipeline->fetch as $val) { if (in_array($val->getUid(), $downgraded)) { $val->setDowngraded(true); } } break; case 'XPROXYREUSE': // The proxy connection was reused, so no need to do login tasks. $pipeline->data['proxyreuse'] = true; break; default: // Unknown response codes SHOULD be ignored - RFC 3501 [7.1] break; } } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Tokenize.php0000664000175000017500000002520013150761653021525 0ustar janjan * @category Horde * @copyright 2012-2017 Horde LLC * @internal * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * * @property-read boolean $eos Has the end of the stream been reached? */ class Horde_Imap_Client_Tokenize implements Iterator { /** * Current data. * * @var mixed */ protected $_current = false; /** * Current key. * * @var integer */ protected $_key = false; /** * Sublevel. * * @var integer */ protected $_level = false; /** * Array of literal stream objects. * * @var array */ protected $_literals = array(); /** * Return Horde_Stream object for literal tokens? * * @var boolean */ protected $_literalStream = false; /** * next() modifiers. * * @var array */ protected $_nextModify = array(); /** * Data stream. * * @var Horde_Stream */ protected $_stream; /** * Constructor. * * @param mixed $data Data to add (string, resource, or Horde_Stream * object). */ public function __construct($data = null) { $this->_stream = new Horde_Stream_Temp(); if (!is_null($data)) { $this->add($data); } } /** */ public function __clone() { throw new LogicException('Object can not be cloned.'); } /** */ public function __get($name) { switch ($name) { case 'eos': return $this->_stream->eof(); } } /** */ public function __sleep() { throw new LogicException('Object can not be serialized.'); } /** */ public function __toString() { $pos = $this->_stream->pos(); $out = $this->_current . ' ' . $this->_stream->getString(); $this->_stream->seek($pos, false); return $out; } /** * Add data to buffer. * * @param mixed $data Data to add (string, resource, or Horde_Stream * object). */ public function add($data) { $this->_stream->add($data); } /** * Add data to literal stream at the current position. * * @param mixed $data Data to add (string, resource, or Horde_Stream * object). */ public function addLiteralStream($data) { $pos = $this->_stream->pos(); if (!isset($this->_literals[$pos])) { $this->_literals[$pos] = new Horde_Stream_Temp(); } $this->_literals[$pos]->add($data); } /** * Flush the remaining entries left in the iterator. * * @param boolean $return If true, return entries. Only returns entries * on the current level. * @param boolean $sublevel Only flush items in current sublevel? * * @return array The entries if $return is true. */ public function flushIterator($return = true, $sublevel = true) { $out = array(); if ($return) { $this->_nextModify = array( 'level' => $sublevel ? $this->_level : 0, 'out' => array() ); $this->next(); $out = $this->_nextModify['out']; $this->_nextModify = array(); } elseif ($sublevel && $this->_level) { $this->_nextModify = array( 'level' => $this->_level ); $this->next(); $this->_nextModify = array(); } else { $this->_stream->end(); $this->_stream->getChar(); $this->_current = $this->_key = $this->_level = false; } return $out; } /** * Return literal length data located at the end of the stream. * * @return mixed Null if no literal data found, or an array with these * keys: * - binary: (boolean) True if this is a literal8. * - length: (integer) Length of the literal. */ public function getLiteralLength() { if ($this->_stream->substring(-1, 1) === '}') { $literal_data = $this->_stream->getString( $this->_stream->search('{', true) - 1 ); $literal_len = substr($literal_data, 2, -1); if (is_numeric($literal_len)) { return array( 'binary' => ($literal_data[0] === '~'), 'length' => intval($literal_len) ); } } return null; } /* Iterator methods. */ /** */ public function current() { return $this->_current; } /** */ public function key() { return $this->_key; } /** * @return mixed Either a string, boolean (true for open paren, false for * close paren/EOS), Horde_Stream object, or null. */ public function next() { $level = isset($this->_nextModify['level']) ? $this->_nextModify['level'] : null; /* Directly access stream here to drastically reduce the number of * getChar() calls we would have to make. */ $stream = $this->_stream->stream; do { $check_len = true; $in_quote = $text = $binary = false; while (($c = fgetc($stream)) !== false) { switch ($c) { case '\\': $text .= $in_quote ? fgetc($stream) : $c; break; case '"': if ($in_quote) { $check_len = false; break 2; } $in_quote = true; /* Set $text to non-false (could be empty string). */ $text = ''; break; default: if ($in_quote) { $text .= $c; break; } switch ($c) { case '(': ++$this->_level; $check_len = false; $text = true; break 3; case ')': if ($text === false) { --$this->_level; $check_len = $text = false; } else { $this->_stream->seek(-1); } break 3; case '~': // Ignore binary string identifier. PHP strings are // binary-safe. But keep it if it is not used as string // identifier. $binary = true; $text .= $c; continue; case '{': if ($binary) { $text = substr($text, 0, -1); } $literal_len = intval($this->_stream->getToChar('}')); $pos = $this->_stream->pos(); if (isset($this->_literals[$pos])) { $text = $this->_literals[$pos]; if (!$this->_literalStream) { $text = strval($text); } } elseif ($this->_literalStream) { $text = new Horde_Stream_Temp(); while (($literal_len > 0) && !feof($stream)) { $part = $this->_stream->substring( 0, min($literal_len, 8192) ); $text->add($part); $literal_len -= strlen($part); } } else { $text = $this->_stream->substring(0, $literal_len); } $check_len = false; break 3; case ' ': if ($text !== false) { break 3; } break; default: $text .= $c; break; } break; } $binary = false; } if ($check_len) { switch (strlen($text)) { case 0: $text = false; break; case 3: if (strcasecmp($text, 'NIL') === 0) { $text = null; } break; } } if (($text === false) && feof($stream)) { $this->_key = $this->_level = false; break; } ++$this->_key; if (is_null($level) || ($level > $this->_level)) { break; } if (($level === $this->_level) && !is_bool($text)) { $this->_nextModify['out'][] = $text; } } while (true); $this->_current = $text; return $text; } /** * Force return of literal data as stream, if next token. * * @see next() */ public function nextStream() { $changed = $this->_literalStream; $this->_literalStream = true; $out = $this->next(); if ($changed) { $this->_literalStream = false; } return $out; } /** */ public function rewind() { $this->_stream->rewind(); $this->_current = false; $this->_key = -1; $this->_level = 0; } /** */ public function valid() { return ($this->_level !== false); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Translation.php0000664000175000017500000000173413150761653022241 0ustar janjan * @category Horde * @copyright 2010-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL * @package Imap_Client */ class Horde_Imap_Client_Translation extends Horde_Translation_Autodetect { /** * The translation domain * * @var string */ protected static $_domain = 'Horde_Imap_Client'; /** * The absolute PEAR path to the translations for the default gettext handler. * * @var string */ protected static $_pearDirectory = '@data_dir@'; } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Url.php0000664000175000017500000001650713150761653020511 0ustar janjan * @category Horde * @copyright 2008-2016 Horde LLC * @deprecated Use Horde_Imap_Client_Url_Base instead * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * * @property-read boolean $relative Is this a relative URL? */ class Horde_Imap_Client_Url implements Serializable { /** * The authentication method to use. * * @var string */ public $auth = null; /** * The remote server (not present for relative URLs). * * @var string */ public $hostspec = null; /** * The IMAP mailbox. * * @todo Make this a Horde_Imap_Client_Mailbox object. * * @var string */ public $mailbox = null; /** * A byte range for use with IMAP FETCH. * * @var string */ public $partial = null; /** * The remote port (not present for relative URLs). * * @var integer */ public $port = null; /** * The protocol type. Either 'imap' or 'pop' (not present for relative * URLs). * * @var string */ public $protocol = null; /** * A search query to be run with IMAP SEARCH. * * @var string */ public $search = null; /** * A MIME part ID. * * @var string */ public $section = null; /** * The username to use on the remote server. * * @var string */ public $username = null; /** * The IMAP UID. * * @var string */ public $uid = null; /** * The IMAP UIDVALIDITY for the given mailbox. * * @var integer */ public $uidvalidity = null; /** * URLAUTH info (not parsed). * * @var string */ public $urlauth = null; /** * Constructor. * * Absolute IMAP URLs takes one of the following forms: * - imap://[/] * - imap:///[][?] * - imap:///[][][][] * * POP URLs take one of the following forms: * - pop://;auth=@: * * @param string $url A URL string. */ public function __construct($url = null) { if (!is_null($url)) { $this->_parse($url); } } /** * Create a POP3 (RFC 2384) or IMAP (RFC 5092/5593) URL. * * @return string A URL string. */ public function __toString() { $url = ''; if (!is_null($this->protocol)) { $url = $this->protocol . '://'; if (!is_null($this->username)) { $url .= $this->username; if (!is_null($this->auth)) { $url .= ';AUTH=' . $this->auth; } $url .= '@'; } $url .= $this->hostspec; if (!is_null($this->port)) { switch ($this->protocol) { case 'imap': if ($this->port != 143) { $url .= ':' . $this->port; } break; case 'pop': if ($this->port != 110) { $url .= ':' . $this->port; } break; } } } $url .= '/'; if (is_null($this->protocol) || ($this->protocol == 'imap')) { $url .= rawurlencode($this->mailbox); if (!empty($this->uidvalidity)) { $url .= ';UIDVALIDITY=' . $this->uidvalidity; } if (!is_null($this->search)) { $url .= '?' . rawurlencode($this->search); } else { if (!is_null($this->uid)) { $url .= '/;UID=' . $this->uid; } if (!is_null($this->section)) { $url .= '/;SECTION=' . $this->section; } if (!is_null($this->partial)) { $url .= '/;PARTIAL=' . $this->partial; } if (!is_null($this->urlauth)) { $url .= '/;URLAUTH=' . $this->urlauth; } } } return $url; } /** */ public function __get($name) { switch ($name) { case 'relative': return (is_null($this->hostspec) && is_null($this->port) && is_null($this->protocol)); } } /** */ protected function _parse($url) { $data = parse_url(trim($url)); if (isset($data['scheme'])) { $protocol = Horde_String::lower($data['scheme']); if (!in_array($protocol, array('imap', 'pop'))) { return; } if (isset($data['host'])) { $this->hostspec = $data['host']; } $this->port = isset($data['port']) ? $data['port'] : (($protocol === 'imap') ? 143 : 110); $this->protocol = $protocol; } /* Check for username/auth information. */ if (isset($data['user'])) { if (($pos = stripos($data['user'], ';AUTH=')) !== false) { $auth = substr($data['user'], $pos + 6); if ($auth !== '*') { $this->auth = $auth; } $data['user'] = substr($data['user'], 0, $pos); } if (strlen($data['user'])) { $this->username = $data['user']; } } /* IMAP-only information. */ if (is_null($this->protocol) || ($this->protocol == 'imap')) { if (isset($data['path'])) { $data['path'] = ltrim($data['path'], '/'); $parts = explode('/;', $data['path']); $mbox = array_shift($parts); if (($pos = stripos($mbox, ';UIDVALIDITY=')) !== false) { $this->uidvalidity = intval(substr($mbox, $pos + 13)); $mbox = substr($mbox, 0, $pos); } $this->mailbox = rawurldecode($mbox); if (isset($data['query'])) { $this->search = rawurldecode($data['query']); $parts = array(); } } else { $parts = array(); } if (count($parts)) { foreach ($parts as $val) { list($k, $v) = explode('=', $val); $property = Horde_String::lower($k); $this->$property = $v; } } } } /* Serializable methods. */ /** */ public function serialize() { return strval($this); } /** */ public function unserialize($data) { $this->_parse($data); } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client/Utf7imap.php0000664000175000017500000002550113150761653021435 0ustar janjan * Released under the GPL (version 2) * * Translated from C to PHP by Thomas Bruederli * Code extracted from the RoundCube Webmail (http://roundcube.net) project, * SVN revision 1757 * The RoundCube project is released under the GPL (version 2) * * Copyright 2008-2017 Horde LLC (http://www.horde.org/) * * See the enclosed file COPYING for license information (LGPL). If you * did not receive this file, see http://www.horde.org/licenses/lgpl21. * * @category Horde * @copyright 2000 Edmund Grimley Evans * @copyright 2008-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ /** * Allows conversions between UTF-8 and UTF7-IMAP (RFC 3501 [5.1.3]). * * @author Michael Slusarz * @category Horde * @copyright 2000 Edmund Grimley Evans * @copyright 2008-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Utf7imap { /** * Lookup table for conversion. * * @var array */ private static $_index64 = array( -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, 63, -1, -1, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 ); /** * Lookup table for conversion. * * @var array */ private static $_base64 = array( 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', ',' ); /** * Is mbstring extension available? * * @var array */ protected static $_mbstring = null; /** * Convert a string from UTF7-IMAP to UTF-8. * * @param string $str The UTF7-IMAP string. * * @return string The converted UTF-8 string. * @throws Horde_Imap_Client_Exception */ public static function Utf7ImapToUtf8($str) { if ($str instanceof Horde_Imap_Client_Mailbox) { return $str->utf8; } $str = strval($str); /* Try mbstring, if available, which should be faster. Don't use the * IMAP utf7_* functions because they are known to be buggy. */ if (is_null(self::$_mbstring)) { self::$_mbstring = extension_loaded('mbstring'); } if (self::$_mbstring) { return @mb_convert_encoding($str, 'UTF-8', 'UTF7-IMAP'); } $p = ''; $ptr = &self::$_index64; for ($i = 0, $u7len = strlen($str); $u7len > 0; ++$i, --$u7len) { $u7 = $str[$i]; if ($u7 === '&') { $u7 = $str[++$i]; if (--$u7len && ($u7 === '-')) { $p .= '&'; continue; } $ch = 0; $k = 10; for (; $u7len > 0; ++$i, --$u7len) { $u7 = $str[$i]; if ((ord($u7) & 0x80) || ($b = $ptr[ord($u7)]) === -1) { break; } if ($k > 0) { $ch |= $b << $k; $k -= 6; } else { $ch |= $b >> (-$k); if ($ch < 0x80) { /* Printable US-ASCII */ if ((0x20 <= $ch) && ($ch < 0x7f)) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION ); } $p .= chr($ch); } else if ($ch < 0x800) { $p .= chr(0xc0 | ($ch >> 6)) . chr(0x80 | ($ch & 0x3f)); } else { $p .= chr(0xe0 | ($ch >> 12)) . chr(0x80 | (($ch >> 6) & 0x3f)) . chr(0x80 | ($ch & 0x3f)); } $ch = ($b << (16 + $k)) & 0xffff; $k += 10; } } /* Non-zero or too many extra bits -OR- * Base64 not properly terminated -OR- * Adjacent Base64 sections. */ if (($ch || ($k < 6)) || (!$u7len || $u7 !== '-') || (($u7len > 2) && ($str[$i + 1] === '&') && ($str[$i + 2] !== '-'))) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION ); } } elseif ((ord($u7) < 0x20) || (ord($u7) >= 0x7f)) { /* Not printable US-ASCII */ throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION ); } else { $p .= $u7; } } return $p; } /** * Convert a string from UTF-8 to UTF7-IMAP. * * @param string $str The UTF-8 string. * @param boolean $force Assume $str is UTF-8 (no-autodetection)? If * false, attempts to auto-detect if string is * already in UTF7-IMAP. * * @return string The converted UTF7-IMAP string. * @throws Horde_Imap_Client_Exception */ public static function Utf8ToUtf7Imap($str, $force = true) { if ($str instanceof Horde_Imap_Client_Mailbox) { return $str->utf7imap; } $str = strval($str); /* No need to do conversion if all chars are in US-ASCII range or if * no ampersand is present. But will assume that an already encoded * ampersand means string is in UTF7-IMAP already. */ if (!$force && !preg_match('/[\x80-\xff]|&$|&(?![,+A-Za-z0-9]*-)/', $str)) { return $str; } /* Try mbstring, if available, which should be faster. Don't use the * IMAP utf7_* functions because they are known to be buggy. */ if (is_null(self::$_mbstring)) { self::$_mbstring = extension_loaded('mbstring'); } if (self::$_mbstring) { return @mb_convert_encoding($str, 'UTF7-IMAP', 'UTF-8'); } $u8len = strlen($str); $i = 0; $base64 = false; $p = ''; $ptr = &self::$_base64; while ($u8len) { $u8 = $str[$i]; $c = ord($u8); if ($c < 0x80) { $ch = $c; $n = 0; } elseif ($c < 0xc2) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION ); } elseif ($c < 0xe0) { $ch = $c & 0x1f; $n = 1; } elseif ($c < 0xf0) { $ch = $c & 0x0f; $n = 2; } elseif ($c < 0xf8) { $ch = $c & 0x07; $n = 3; } elseif ($c < 0xfc) { $ch = $c & 0x03; $n = 4; } elseif ($c < 0xfe) { $ch = $c & 0x01; $n = 5; } else { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION ); } if ($n > --$u8len) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION ); } ++$i; for ($j = 0; $j < $n; ++$j) { $o = ord($str[$i + $j]); if (($o & 0xc0) !== 0x80) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION ); } $ch = ($ch << 6) | ($o & 0x3f); } if (($n > 1) && !($ch >> ($n * 5 + 1))) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION ); } $i += $n; $u8len -= $n; if (($ch < 0x20) || ($ch >= 0x7f)) { if (!$base64) { $p .= '&'; $base64 = true; $b = 0; $k = 10; } if ($ch & ~0xffff) { $ch = 0xfffe; } $p .= $ptr[($b | $ch >> $k)]; $k -= 6; for (; $k >= 0; $k -= 6) { $p .= $ptr[(($ch >> $k) & 0x3f)]; } $b = ($ch << (-$k)) & 0x3f; $k += 16; } else { if ($base64) { if ($k > 10) { $p .= $ptr[$b]; } $p .= '-'; $base64 = false; } $p .= chr($ch); if (chr($ch) === '&') { $p .= '-'; } } } if ($base64) { if ($k > 10) { $p .= $ptr[$b]; } $p .= '-'; } return $p; } } Horde_Imap_Client-2.29.15/lib/Horde/Imap/Client.php0000664000175000017500000001341413150761653017741 0ustar janjan * @category Horde * @copyright 2008-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client { /* Constants for openMailbox() */ const OPEN_READONLY = 1; const OPEN_READWRITE = 2; const OPEN_AUTO = 3; /* Constants for listMailboxes() */ const MBOX_SUBSCRIBED = 1; const MBOX_SUBSCRIBED_EXISTS = 2; const MBOX_UNSUBSCRIBED = 3; const MBOX_ALL = 4; /* @since 2.23.0 */ const MBOX_ALL_SUBSCRIBED = 5; /* Constants for status() */ const STATUS_MESSAGES = 1; const STATUS_RECENT = 2; const STATUS_UIDNEXT = 4; const STATUS_UIDVALIDITY = 8; const STATUS_UNSEEN = 16; const STATUS_ALL = 32; const STATUS_FIRSTUNSEEN = 64; const STATUS_FLAGS = 128; const STATUS_PERMFLAGS = 256; const STATUS_HIGHESTMODSEQ = 512; const STATUS_SYNCMODSEQ = 1024; const STATUS_SYNCFLAGUIDS = 2048; const STATUS_UIDNOTSTICKY = 4096; const STATUS_UIDNEXT_FORCE = 8192; const STATUS_SYNCVANISHED = 16384; /* @since 2.12.0 */ const STATUS_RECENT_TOTAL = 32768; /* @since 2.14.0 */ const STATUS_FORCE_REFRESH = 65536; /* Constants for search() */ const SORT_ARRIVAL = 1; const SORT_CC = 2; const SORT_DATE = 3; const SORT_FROM = 4; const SORT_REVERSE = 5; const SORT_SIZE = 6; const SORT_SUBJECT = 7; const SORT_TO = 8; /* SORT_THREAD provided for completeness - it is not a valid sort criteria * for search() (use thread() instead). */ const SORT_THREAD = 9; /* Sort criteria defined in RFC 5957 */ const SORT_DISPLAYFROM = 10; const SORT_DISPLAYTO = 11; /* SORT_SEQUENCE does a simple numerical sort on the returned * UIDs/sequence numbers. */ const SORT_SEQUENCE = 12; /* Fuzzy sort criteria defined in RFC 6203 */ const SORT_RELEVANCY = 13; /* @since 2.4.0 */ const SORT_DISPLAYFROM_FALLBACK = 14; /* @since 2.4.0 */ const SORT_DISPLAYTO_FALLBACK = 15; /* Search results constants */ const SEARCH_RESULTS_COUNT = 1; const SEARCH_RESULTS_MATCH = 2; const SEARCH_RESULTS_MAX = 3; const SEARCH_RESULTS_MIN = 4; const SEARCH_RESULTS_SAVE = 5; /* Fuzzy sort criteria defined in RFC 6203 */ const SEARCH_RESULTS_RELEVANCY = 6; /* Constants for thread() */ const THREAD_ORDEREDSUBJECT = 1; const THREAD_REFERENCES = 2; const THREAD_REFS = 3; /* Fetch criteria constants. */ const FETCH_STRUCTURE = 1; const FETCH_FULLMSG = 2; const FETCH_HEADERTEXT = 3; const FETCH_BODYTEXT = 4; const FETCH_MIMEHEADER = 5; const FETCH_BODYPART = 6; const FETCH_BODYPARTSIZE = 7; const FETCH_HEADERS = 8; const FETCH_ENVELOPE = 9; const FETCH_FLAGS = 10; const FETCH_IMAPDATE = 11; const FETCH_SIZE = 12; const FETCH_UID = 13; const FETCH_SEQ = 14; const FETCH_MODSEQ = 15; /* @since 2.11.0 */ const FETCH_DOWNGRADED = 16; /* Namespace constants. @deprecated */ const NS_PERSONAL = 1; const NS_OTHER = 2; const NS_SHARED = 3; /* ACL constants (RFC 4314 [2.1]). */ const ACL_LOOKUP = 'l'; const ACL_READ = 'r'; const ACL_SEEN = 's'; const ACL_WRITE = 'w'; const ACL_INSERT = 'i'; const ACL_POST = 'p'; const ACL_CREATEMBOX = 'k'; const ACL_DELETEMBOX = 'x'; const ACL_DELETEMSGS = 't'; const ACL_EXPUNGE = 'e'; const ACL_ADMINISTER = 'a'; // Old constants (RFC 2086 [3]; RFC 4314 [2.1.1]) const ACL_CREATE = 'c'; const ACL_DELETE = 'd'; /* System flags. */ // RFC 3501 [2.3.2] const FLAG_ANSWERED = '\\answered'; const FLAG_DELETED = '\\deleted'; const FLAG_DRAFT = '\\draft'; const FLAG_FLAGGED = '\\flagged'; const FLAG_RECENT = '\\recent'; const FLAG_SEEN = '\\seen'; // RFC 3503 [3.3] const FLAG_MDNSENT = '$mdnsent'; // RFC 5550 [2.8] const FLAG_FORWARDED = '$forwarded'; // RFC 5788 registered keywords: // http://www.ietf.org/mail-archive/web/morg/current/msg00441.html const FLAG_JUNK = '$junk'; const FLAG_NOTJUNK = '$notjunk'; /* Special-use mailbox attributes (RFC 6154 [2]). */ const SPECIALUSE_ALL = '\\All'; const SPECIALUSE_ARCHIVE = '\\Archive'; const SPECIALUSE_DRAFTS = '\\Drafts'; const SPECIALUSE_FLAGGED = '\\Flagged'; const SPECIALUSE_JUNK = '\\Junk'; const SPECIALUSE_SENT = '\\Sent'; const SPECIALUSE_TRASH = '\\Trash'; /* Constants for sync(). */ const SYNC_UIDVALIDITY = 0; const SYNC_FLAGS = 1; const SYNC_FLAGSUIDS = 2; const SYNC_NEWMSGS = 4; const SYNC_NEWMSGSUIDS = 8; const SYNC_VANISHED = 16; const SYNC_VANISHEDUIDS = 32; const SYNC_ALL = 64; /** * Capability dependencies. * * @deprecated * * @var array */ public static $capability_deps = array( // RFC 7162 [3.2] 'QRESYNC' => array( // QRESYNC requires CONDSTORE, but the latter is implied and is // not required to be listed. 'ENABLE' ), // RFC 5182 [2.1] 'SEARCHRES' => array( 'ESEARCH' ), // RFC 5255 [3.1] 'LANGUAGE' => array( 'NAMESPACE' ), // RFC 5957 [1] 'SORT=DISPLAY' => array( 'SORT' ) ); } Horde_Imap_Client-2.29.15/locale/da/LC_MESSAGES/Horde_Imap_Client.mo0000664000175000017500000001463713150761653022577 0ustar janjan5Gl!(8</Q!A84;4p! ". ":]|!/"'776o")* (= +f   : 6 '4 :\ E H =& ad ] :$ :_ L - E S[ 4 ! ALH)'2C5Y&I"=#9a0'29':a# "+!I,k6=" #01T&-/ *>>6}"8JM[5WX776B*BImP1:EY.,$/ 3(  "4 '*-!0)+1%2#5 &%s not supported on POP3 servers.Authentication credentials have expired.Authentication failed.Authentication failure.Authentication was successful, but authorization failed.Bad tagged response.Cannot convert search query text to new charsetCannot expunge read-only mailbox.Charset used in search query is not supported on the mail server.Could not open mailbox "%s".Could not open secure TLS connection to the IMAP server.Could not open secure connection to the POP3 server.Could not save message data because it is too large.Could not save message on server.Error connecting to mail server.Error converting UTF7-IMAP string.Error when communicating with the mail server.IMAP Server closed the connection.IMAP error reported by server.Invalid METADATA entry: "%s".Invalid METADATA value type "%s".Mail server closed the connection unexpectedly.Mail server denied authentication.Mailbox does not support mod-sequences.No supported IMAP authentication method could be found.Operation failed due to a lack of a secure connection.POP3 error reported by server.POP3 server denied authentication.Remote server is temporarily unavailable.Server closed the connection unexpectedly.Server does not support TLS connections.Server does not support secure connections.Server rejected connection.Server write error.The comparison algorithm was not recognized by the server.The mail server does not support IMAP4rev1 (RFC 3501).The mail server has denied the request.The mail server is reporting corrupt data in your mailbox.The mail server was unable to parse the contents of the mail message.The mail server was unable to parse the contents of the mail message: %sThe metadata item could not be saved because it is too large.The metadata item could not be saved because the maximum number of annotations has been exceeded.The metadata item could not be saved because the server does not support private annotations.The object could not be created because it already exists.The object could not be deleted because it does not exist.The operation failed because the quota has been exceeded on the mail server.The server does not support the %s extension.The special-use attribute requested for the mailbox is not supported.There was a temporary issue when attempting this operation. Please try again later.Unexpected response from server when authenticating.Unknown authentication method: %sYou do not have adequate permissions to carry out this operation.Project-Id-Version: Horde_Imap_Client Report-Msgid-Bugs-To: dev@lists.horde.org POT-Creation-Date: 2014-03-20 00:26+0100 PO-Revision-Date: 2014-03-20 20:08+0100 Last-Translator: Erling Preben Hansen Language-Team: Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit %s er ikke understøttet på pop3 servereGodkendelses rettighederne er udløbet.Godkendelsen fejlede.Godkendelses fejl.Godkendelsen lykkedes, men autorisationen fejlede.Forkert mærket svar.Kan ikke konvertere søgeteksten til det nye tegnsætKan ikke rense en Læs kun mail mappe.Tegnsættet brugt i søgeteksten er ikke understøttet på mail serveren.Kunne ikke åbne mail mappen "%s".Kunne ikke åbne en sikker TLS forbindelse til IMAP serveren.Kunne ikke åbne en sikker forbindelse til POP3 serveren.Kunne ikke gemme besked data da den er for stor.Kunne ikke gemme beskeden på serveren.Der optod en fejl under forbindelsen til serveren.Der opstod en fejl under konverteringen af UTF7 strengen.Der opstod en fejl under kommunikationen med mail serverenIMAP serveren lukkede forbindelsen.IMAP Fejl rapporterede serveren.Ugyldig METADATA : "%s".Ugyldig METADATA værdi type "%s".Mail serveren lukkede forbindelsen uventet.Mail serveren afviste godkendelseMailmappen understøtter ikke mod-sequences.Der kunne ikke findes nogen IMAP godkendelses metoder.Handlingen fejlede på grund af manglende sikre forbindelser.POP3 fejl rapporteret af serveren.POP3 serveren afviste godkendelsen.Fjernserveren er midlertidigt ikke til rådighed.Serveren lukkede forbindelsen uventet.Serveren understøtter ikke TLS forbindelser.Serveren understøtter ikke sikker forbindelse.Serveren afviste forbindelsen.Server skrive fejl.DEnne sammenlignings algoritme blev ikke genkendt af serveren.Mail serveren understøtter ikke IMAP4rev1 (RFC 3501).Mail serveren afviste anmodningen.Mail serveren rapporterer ødelagt data i din mailmappe.Mail serveren var ude af stand til at behandle indholdet af mail beskeden.Mail serveren var ude af stand til at behandle indholdet af mail beskeden: %sMetadata delen kunne ikke gemmes, da den er for stor.Metadata delen kunne ikke gemmes fordi det maksimale antal annotationer er overskredet.Metadata delen kunne ikke gemmes fordi serveren ikke understøtter private annotationer.Objektet kunne ikke oprettes fordi det allerede findes.Objektet kunne ikke slettes fordi det ikke eksisterer.Handlingen fejlede fordi pladsen på mail serveren er overskredet.Serveren understøtter ikke %s udvidelsen.Den specielle attribut for mail mappen som er anmodet understøttes ikke.Der opstod en midlertidig fejl under denne handling. Prøv venligts igen senere.Uventet reaktion fra serveren under godkendelsen.Ukendt godkendelses metode: %sDu har ikke de nødvendige tilladelser til at udføre denn handlling.Horde_Imap_Client-2.29.15/locale/da/LC_MESSAGES/Horde_Imap_Client.po0000664000175000017500000002331713150761653022575 0ustar janjan# Danish translations for Horde_Imap_Client package. # Copyright (C) 2014 Horde LLC (http://www.horde.org/) # This file is distributed under the same license as the Horde_Imap_Client package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: Horde_Imap_Client\n" "Report-Msgid-Bugs-To: dev@lists.horde.org\n" "POT-Creation-Date: 2014-03-20 00:26+0100\n" "PO-Revision-Date: 2014-03-20 20:08+0100\n" "Last-Translator: Erling Preben Hansen \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: lib/Horde/Imap/Client/Exception/NoSupportPop3.php:34 #, php-format msgid "%s not supported on POP3 servers." msgstr "%s er ikke understøttet på pop3 servere" #: lib/Horde/Imap/Client/Socket.php:4635 msgid "Authentication credentials have expired." msgstr "Godkendelses rettighederne er udløbet." #: lib/Horde/Imap/Client/Socket.php:4619 msgid "Authentication failed." msgstr "Godkendelsen fejlede." #: lib/Horde/Imap/Client/Auth/DigestMD5.php:158 msgid "Authentication failure." msgstr "Godkendelses fejl." #: lib/Horde/Imap/Client/Socket.php:4627 msgid "Authentication was successful, but authorization failed." msgstr "Godkendelsen lykkedes, men autorisationen fejlede." #: lib/Horde/Imap/Client/Interaction/Server/Tagged.php:44 msgid "Bad tagged response." msgstr "Forkert mærket svar." #: lib/Horde/Imap/Client/Exception/SearchCharset.php:45 msgid "Cannot convert search query text to new charset" msgstr "Kan ikke konvertere søgeteksten til det nye tegnsæt" #: lib/Horde/Imap/Client/Base.php:2032 lib/Horde/Imap/Client/Base.php:2095 msgid "Cannot expunge read-only mailbox." msgstr "Kan ikke rense en Læs kun mail mappe." #: lib/Horde/Imap/Client/Socket.php:4413 msgid "Charset used in search query is not supported on the mail server." msgstr "Tegnsættet brugt i søgeteksten er ikke understøttet på mail serveren." #: lib/Horde/Imap/Client/Socket.php:1077 #, php-format msgid "Could not open mailbox \"%s\"." msgstr "Kunne ikke åbne mail mappen \"%s\"." #: lib/Horde/Imap/Client/Socket.php:393 msgid "Could not open secure TLS connection to the IMAP server." msgstr "Kunne ikke åbne en sikker TLS forbindelse til IMAP serveren." #: lib/Horde/Imap/Client/Socket/Pop3.php:194 #: lib/Horde/Imap/Client/Socket/Pop3.php:208 msgid "Could not open secure connection to the POP3 server." msgstr "Kunne ikke åbne en sikker forbindelse til POP3 serveren." #: lib/Horde/Imap/Client/Socket.php:4519 msgid "Could not save message data because it is too large." msgstr "Kunne ikke gemme besked data da den er for stor." #: lib/Horde/Imap/Client/Socket.php:4510 msgid "Could not save message on server." msgstr "Kunne ikke gemme beskeden på serveren." #: lib/Horde/Imap/Client/Socket.php:574 #: lib/Horde/Imap/Client/Socket/Pop3.php:284 msgid "Error connecting to mail server." msgstr "Der optod en fejl under forbindelsen til serveren." #: lib/Horde/Imap/Client/Utf7imap.php:128 #: lib/Horde/Imap/Client/Utf7imap.php:156 #: lib/Horde/Imap/Client/Utf7imap.php:163 #: lib/Horde/Imap/Client/Utf7imap.php:225 #: lib/Horde/Imap/Client/Utf7imap.php:245 #: lib/Horde/Imap/Client/Utf7imap.php:252 #: lib/Horde/Imap/Client/Utf7imap.php:263 #: lib/Horde/Imap/Client/Utf7imap.php:272 msgid "Error converting UTF7-IMAP string." msgstr "Der opstod en fejl under konverteringen af UTF7 strengen." #: lib/Horde/Imap/Client/Socket.php:4081 #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:71 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:180 #: lib/Horde/Imap/Client/Socket/Pop3.php:1191 msgid "Error when communicating with the mail server." msgstr "Der opstod en fejl under kommunikationen med mail serveren" #: lib/Horde/Imap/Client/Socket.php:4200 msgid "IMAP Server closed the connection." msgstr "IMAP serveren lukkede forbindelsen." #: lib/Horde/Imap/Client/Socket.php:4186 msgid "IMAP error reported by server." msgstr "IMAP Fejl rapporterede serveren." #: lib/Horde/Imap/Client/Socket.php:3682 #, php-format msgid "Invalid METADATA entry: \"%s\"." msgstr "Ugyldig METADATA : \"%s\"." #: lib/Horde/Imap/Client/Socket.php:3768 #, php-format msgid "Invalid METADATA value type \"%s\"." msgstr "Ugyldig METADATA værdi type \"%s\"." #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:121 msgid "Mail server closed the connection unexpectedly." msgstr "Mail serveren lukkede forbindelsen uventet." #: lib/Horde/Imap/Client/Socket.php:542 msgid "Mail server denied authentication." msgstr "Mail serveren afviste godkendelse" #: lib/Horde/Imap/Client/Base.php:2365 lib/Horde/Imap/Client/Base.php:2685 #: lib/Horde/Imap/Client/Base.php:2950 lib/Horde/Imap/Client/Base.php:3035 msgid "Mailbox does not support mod-sequences." msgstr "Mailmappen understøtter ikke mod-sequences." #: lib/Horde/Imap/Client/Socket.php:469 msgid "No supported IMAP authentication method could be found." msgstr "Der kunne ikke findes nogen IMAP godkendelses metoder." #: lib/Horde/Imap/Client/Socket.php:4643 msgid "Operation failed due to a lack of a secure connection." msgstr "Handlingen fejlede på grund af manglende sikre forbindelser." #: lib/Horde/Imap/Client/Socket/Pop3.php:1250 msgid "POP3 error reported by server." msgstr "POP3 fejl rapporteret af serveren." #: lib/Horde/Imap/Client/Socket/Pop3.php:253 msgid "POP3 server denied authentication." msgstr "POP3 serveren afviste godkendelsen." #: lib/Horde/Imap/Client/Socket.php:4611 msgid "Remote server is temporarily unavailable." msgstr "Fjernserveren er midlertidigt ikke til rådighed." #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:63 msgid "Server closed the connection unexpectedly." msgstr "Serveren lukkede forbindelsen uventet." #: lib/Horde/Imap/Client/Socket.php:381 msgid "Server does not support TLS connections." msgstr "Serveren understøtter ikke TLS forbindelser." #: lib/Horde/Imap/Client/Socket/Pop3.php:194 msgid "Server does not support secure connections." msgstr "Serveren understøtter ikke sikker forbindelse." #: lib/Horde/Imap/Client/Socket.php:594 msgid "Server rejected connection." msgstr "Serveren afviste forbindelsen." #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:42 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:54 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:87 msgid "Server write error." msgstr "Server skrive fejl." #: lib/Horde/Imap/Client/Socket.php:4564 msgid "The comparison algorithm was not recognized by the server." msgstr "DEnne sammenlignings algoritme blev ikke genkendt af serveren." #: lib/Horde/Imap/Client/Socket.php:603 msgid "The mail server does not support IMAP4rev1 (RFC 3501)." msgstr "Mail serveren understøtter ikke IMAP4rev1 (RFC 3501)." #: lib/Horde/Imap/Client/Socket.php:4690 msgid "The mail server has denied the request." msgstr "Mail serveren afviste anmodningen." #: lib/Horde/Imap/Client/Socket.php:4674 msgid "The mail server is reporting corrupt data in your mailbox." msgstr "Mail serveren rapporterer ødelagt data i din mailmappe." #: lib/Horde/Imap/Client/Socket.php:4476 msgid "The mail server was unable to parse the contents of the mail message." msgstr "" "Mail serveren var ude af stand til at behandle indholdet af mail beskeden." #: lib/Horde/Imap/Client/Socket.php:4429 #, php-format msgid "" "The mail server was unable to parse the contents of the mail message: %s" msgstr "" "Mail serveren var ude af stand til at behandle indholdet af mail beskeden: %s" #: lib/Horde/Imap/Client/Socket.php:4582 msgid "The metadata item could not be saved because it is too large." msgstr "Metadata delen kunne ikke gemmes, da den er for stor." #: lib/Horde/Imap/Client/Socket.php:4600 msgid "" "The metadata item could not be saved because the maximum number of " "annotations has been exceeded." msgstr "" "Metadata delen kunne ikke gemmes fordi det maksimale antal annotationer er " "overskredet." #: lib/Horde/Imap/Client/Socket.php:4591 msgid "" "The metadata item could not be saved because the server does not support " "private annotations." msgstr "" "Metadata delen kunne ikke gemmes fordi serveren ikke understøtter private " "annotationer." #: lib/Horde/Imap/Client/Socket.php:4708 msgid "The object could not be created because it already exists." msgstr "Objektet kunne ikke oprettes fordi det allerede findes." #: lib/Horde/Imap/Client/Socket.php:4717 msgid "The object could not be deleted because it does not exist." msgstr "Objektet kunne ikke slettes fordi det ikke eksisterer." #: lib/Horde/Imap/Client/Socket.php:4699 msgid "" "The operation failed because the quota has been exceeded on the mail server." msgstr "Handlingen fejlede fordi pladsen på mail serveren er overskredet." #: lib/Horde/Imap/Client/Exception/NoSupportExtension.php:46 #, php-format msgid "The server does not support the %s extension." msgstr "Serveren understøtter ikke %s udvidelsen." #: lib/Horde/Imap/Client/Socket.php:4726 msgid "The special-use attribute requested for the mailbox is not supported." msgstr "" "Den specielle attribut for mail mappen som er anmodet understøttes ikke." #: lib/Horde/Imap/Client/Socket.php:4660 msgid "" "There was a temporary issue when attempting this operation. Please try again " "later." msgstr "" "Der opstod en midlertidig fejl under denne handling. Prøv venligts igen " "senere." #: lib/Horde/Imap/Client/Socket.php:692 #: lib/Horde/Imap/Client/Socket/Pop3.php:339 msgid "Unexpected response from server when authenticating." msgstr "Uventet reaktion fra serveren under godkendelsen." #: lib/Horde/Imap/Client/Socket.php:729 #: lib/Horde/Imap/Client/Socket/Pop3.php:385 #, php-format msgid "Unknown authentication method: %s" msgstr "Ukendt godkendelses metode: %s" #: lib/Horde/Imap/Client/Socket.php:4651 msgid "You do not have adequate permissions to carry out this operation." msgstr "Du har ikke de nødvendige tilladelser til at udføre denn handlling." Horde_Imap_Client-2.29.15/locale/de/LC_MESSAGES/Horde_Imap_Client.mo0000664000175000017500000001631313150761653022574 0ustar janjan7I!(8+d/y!A 8*4c4! ".3"b!/"'7_7u6" )& *P ({ + !   :" 6] ' : E H= = a ]& : : L -G Eu S 4!DAf,/)\HK 2le*E0AvJD,H.u801"@#c=7,*JCK1: 0G=x6;/)/Y@9,BGBELl`sGACh16Khj=(]D+6(-4% $ /5",03#!&1  '2.*7 ) %s not supported on POP3 servers.Authentication credentials have expired.Authentication failed.Authentication failure.Authentication was successful, but authorization failed.Bad tagged response.Cannot convert search query text to new charsetCannot expunge read-only mailbox.Charset used in search query is not supported on the mail server.Could not open mailbox "%s".Could not open secure TLS connection to the IMAP server.Could not open secure connection to the POP3 server.Could not save message data because it is too large.Could not save message on server.Error connecting to mail server.Error converting UTF7-IMAP string.Error when communicating with the mail server.IMAP Server closed the connection.IMAP error reported by server.Invalid METADATA entry: "%s".Invalid METADATA value type "%s".Mail server closed the connection unexpectedly.Mail server denied authentication.Mailbox does not support mod-sequences.No password provided.No supported IMAP authentication method could be found.Operation failed due to a lack of a secure connection.POP3 error reported by server.POP3 server denied authentication.Remote server is temporarily unavailable.Server closed the connection unexpectedly.Server does not support TLS connections.Server does not support secure connections.Server failed verification check.Server rejected connection.Server write error.The comparison algorithm was not recognized by the server.The mail server does not support IMAP4rev1 (RFC 3501).The mail server has denied the request.The mail server is reporting corrupt data in your mailbox.The mail server was unable to parse the contents of the mail message.The mail server was unable to parse the contents of the mail message: %sThe metadata item could not be saved because it is too large.The metadata item could not be saved because the maximum number of annotations has been exceeded.The metadata item could not be saved because the server does not support private annotations.The object could not be created because it already exists.The object could not be deleted because it does not exist.The operation failed because the quota has been exceeded on the mail server.The server does not support the %s extension.The special-use attribute requested for the mailbox is not supported.There was a temporary issue when attempting this operation. Please try again later.Unexpected response from server when authenticating.Unknown authentication method: %sYou do not have adequate permissions to carry out this operation.Project-Id-Version: Horde_Imap_Client Report-Msgid-Bugs-To: dev@lists.horde.org POT-Creation-Date: 2017-07-26 12:13+0200 PO-Revision-Date: 2015-12-29 17:59+0100 Last-Translator: Jan Schneider Language-Team: i18n@lists.horde.org Language: de MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); %s wird auf POP3-Servern nicht unterstützt.Die Anmeldedaten sind nicht mehr gültig.Anmeldung fehlgeschlagen.Anmeldung fehlgeschlagen.Die Anmeldung war erfolgreich aber die Autorisierung ist fehlgeschlagen.Ungültige getaggte Antwort.Der Suchtext konnte nicht in den benötigten Zeichensatz übersetzt werden.Nur-Lesen-Ordner können nicht aufgeräumt werden.Der Zeichensatz, der in der Suchanfrage benutzt wurde, wird von dem E-Mail-Server nicht unterstützt.Ordner "%s" konnte nicht geöffnet werden.Sichere TLS-Verbindung zum IMAP-Server kann nicht hergestellt werden.Sichere Verbindung zum POP3-Server kann nicht hergestellt werden.Nachrichtendaten konnten nicht gespeichert werden, weil sie zu groß sind.Die Nachricht konnte nicht auf dem E-Mail-Server gespeichert werden.Verbindung zum E-Mail-Server fehlgeschlagen.Fehler beim Umwandeln eines UTF7-IMAP-Strings.Fehler während der Kommunikation mit dem E-Mail-Server.Der IMAP-Server hat die Verbindung unterbrochen.Der E-Mail-Server hat einen IMAP-Fehler gemeldet.Ungültiger METADATA-Eintrag: "%s"Ungültiger METADATA-Wertetyp "%s".Der E-Mail-Server hat die Verbindung unerwartet unterbrochen.Der E-Mail-Server hat die Authentifizierung verweigert.Der Ordner unterstützt keine Mod-Sequences.Kein Passwort angegeben.Es wurde keine unterstützte Authentifizierungsmethode für IMAP gefunden.Die Operation ist wegen einer fehlenden sicheren Verbindung fehlgeschlagen.Der E-Mail-Server hat einen POP3-Fehler gemeldet.Der POP3-Server hat die Authentifizierung zurückgewiesen.Der E-Mail-Server ist zur Zeit nicht verfügbar.Der E-Mail-Server hat die Verbindung unerwartet unterbrochen.Der E-Mail-Server unterstützt keine TLS-Verbindungen.Der E-Mail-Server unterstützt keine sicheren Verbindungen.Bestätigung des E-Mail-Servers fehlgeschlagen.Der E-Mail-Server hat die Verbindung abgelehnt.Server-Schreibfehler.Der Vergleichsalgorithmus wurde vom E-Mail-Server nicht erkannt.Der E-Mail-Server unterstützt kein IMAP4rev1 (RFC 3501).Der E-Mail-Server hat die Anfrage abgelehnt.Der E-Mail-Server hat beschädigte Daten in Ihrem Ordner gemeldet.Der E-Mail-Server konnte den Inhalt der Nachricht nicht auswerten.Der E-Mail-Server konnte den Inhalt der Nachricht nicht auswerten: %sDer Metadaten-Eintrag konnte nicht gespeichert werden, weil er zu groß ist.Der Metadaten-Eintrag konnte nicht gespeichert werden, weil die maximale Anzahl an Vermerken erschöpft ist.Der Metadaten-Eintrag konnte nicht gespeichert werden, weil der E-Mail-Server keine privaten Vermerke unterstützt.Das Element konnte nicht gespeichert werden, weil es bereits existiert.Das Element konnte nicht gelöscht werden, weil es nicht existiert.Die Operation ist fehlgeschlagen, weil das Speicherplatzkontingent auf dem E-Mail-Server erschöpft ist.Der Server unterstützt die %s-Erweiterung nicht.Das Attribut für spezielle Nutzung wird von dem Ordner nicht unterstützt.Bei dieser Aktion ist ein vorübergehender Fehler aufgetreten. Bitte versuchen Sie es später noch einmal.Unerwartete Antwort vom E-Mail-Server während der Anmeldung.Unbekannte Authentifizierungsmethode: %sSie haben nicht die nötigen Rechte, um diese Aktion durchzuführen.Horde_Imap_Client-2.29.15/locale/de/LC_MESSAGES/Horde_Imap_Client.po0000664000175000017500000002576213150761653022607 0ustar janjan# German translations for Horde_Imap_Client package. # Copyright 2012-2017 Horde LLC (http://www.horde.org/) # This file is distributed under the same license as the Horde_Imap_Client package. # Jan Schneider , 2012-2015. # msgid "" msgstr "" "Project-Id-Version: Horde_Imap_Client\n" "Report-Msgid-Bugs-To: dev@lists.horde.org\n" "POT-Creation-Date: 2017-07-26 12:13+0200\n" "PO-Revision-Date: 2015-12-29 17:59+0100\n" "Last-Translator: Jan Schneider \n" "Language-Team: i18n@lists.horde.org\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: lib/Horde/Imap/Client/Exception/NoSupportPop3.php:34 #, php-format msgid "%s not supported on POP3 servers." msgstr "%s wird auf POP3-Servern nicht unterstützt." #: lib/Horde/Imap/Client/Socket.php:5035 msgid "Authentication credentials have expired." msgstr "Die Anmeldedaten sind nicht mehr gültig." #: lib/Horde/Imap/Client/Socket.php:747 lib/Horde/Imap/Client/Socket.php:5019 #: lib/Horde/Imap/Client/Socket/Pop3.php:441 #: lib/Horde/Imap/Client/Socket/Pop3.php:460 #: lib/Horde/Imap/Client/Socket/Pop3.php:486 #: lib/Horde/Imap/Client/Socket/Pop3.php:498 msgid "Authentication failed." msgstr "Anmeldung fehlgeschlagen." #: lib/Horde/Imap/Client/Auth/DigestMD5.php:158 #: lib/Horde/Imap/Client/Auth/Scram.php:124 msgid "Authentication failure." msgstr "Anmeldung fehlgeschlagen." #: lib/Horde/Imap/Client/Socket.php:5027 msgid "Authentication was successful, but authorization failed." msgstr "" "Die Anmeldung war erfolgreich aber die Autorisierung ist fehlgeschlagen." #: lib/Horde/Imap/Client/Interaction/Server/Tagged.php:44 msgid "Bad tagged response." msgstr "Ungültige getaggte Antwort." #: lib/Horde/Imap/Client/Exception/SearchCharset.php:45 msgid "Cannot convert search query text to new charset" msgstr "" "Der Suchtext konnte nicht in den benötigten Zeichensatz übersetzt werden." #: lib/Horde/Imap/Client/Base.php:1924 lib/Horde/Imap/Client/Base.php:1987 msgid "Cannot expunge read-only mailbox." msgstr "Nur-Lesen-Ordner können nicht aufgeräumt werden." #: lib/Horde/Imap/Client/Socket.php:4811 msgid "Charset used in search query is not supported on the mail server." msgstr "" "Der Zeichensatz, der in der Suchanfrage benutzt wurde, wird von dem E-Mail-" "Server nicht unterstützt." #: lib/Horde/Imap/Client/Socket.php:1240 #, php-format msgid "Could not open mailbox \"%s\"." msgstr "Ordner \"%s\" konnte nicht geöffnet werden." #: lib/Horde/Imap/Client/Socket.php:358 lib/Horde/Imap/Client/Socket.php:400 msgid "Could not open secure TLS connection to the IMAP server." msgstr "Sichere TLS-Verbindung zum IMAP-Server kann nicht hergestellt werden." #: lib/Horde/Imap/Client/Socket/Pop3.php:219 #: lib/Horde/Imap/Client/Socket/Pop3.php:233 msgid "Could not open secure connection to the POP3 server." msgstr "Sichere Verbindung zum POP3-Server kann nicht hergestellt werden." #: lib/Horde/Imap/Client/Socket.php:4919 msgid "Could not save message data because it is too large." msgstr "" "Nachrichtendaten konnten nicht gespeichert werden, weil sie zu groß sind." #: lib/Horde/Imap/Client/Socket.php:4910 msgid "Could not save message on server." msgstr "Die Nachricht konnte nicht auf dem E-Mail-Server gespeichert werden." #: lib/Horde/Imap/Client/Socket.php:606 #: lib/Horde/Imap/Client/Socket/Pop3.php:324 msgid "Error connecting to mail server." msgstr "Verbindung zum E-Mail-Server fehlgeschlagen." #: lib/Horde/Imap/Client/Utf7imap.php:128 #: lib/Horde/Imap/Client/Utf7imap.php:156 #: lib/Horde/Imap/Client/Utf7imap.php:163 #: lib/Horde/Imap/Client/Utf7imap.php:225 #: lib/Horde/Imap/Client/Utf7imap.php:245 #: lib/Horde/Imap/Client/Utf7imap.php:252 #: lib/Horde/Imap/Client/Utf7imap.php:263 #: lib/Horde/Imap/Client/Utf7imap.php:272 msgid "Error converting UTF7-IMAP string." msgstr "Fehler beim Umwandeln eines UTF7-IMAP-Strings." #: lib/Horde/Imap/Client/Socket.php:4467 #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:83 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:214 #: lib/Horde/Imap/Client/Socket/Pop3.php:1382 msgid "Error when communicating with the mail server." msgstr "Fehler während der Kommunikation mit dem E-Mail-Server." #: lib/Horde/Imap/Client/Socket.php:4605 msgid "IMAP Server closed the connection." msgstr "Der IMAP-Server hat die Verbindung unterbrochen." #: lib/Horde/Imap/Client/Socket.php:4591 msgid "IMAP error reported by server." msgstr "Der E-Mail-Server hat einen IMAP-Fehler gemeldet." #: lib/Horde/Imap/Client/Socket.php:4009 #, php-format msgid "Invalid METADATA entry: \"%s\"." msgstr "Ungültiger METADATA-Eintrag: \"%s\"" #: lib/Horde/Imap/Client/Socket.php:4102 #, php-format msgid "Invalid METADATA value type \"%s\"." msgstr "Ungültiger METADATA-Wertetyp \"%s\"." #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:148 msgid "Mail server closed the connection unexpectedly." msgstr "Der E-Mail-Server hat die Verbindung unerwartet unterbrochen." #: lib/Horde/Imap/Client/Socket.php:573 msgid "Mail server denied authentication." msgstr "Der E-Mail-Server hat die Authentifizierung verweigert." #: lib/Horde/Imap/Client/Base.php:2257 lib/Horde/Imap/Client/Base.php:2536 #: lib/Horde/Imap/Client/Base.php:2808 lib/Horde/Imap/Client/Base.php:2893 msgid "Mailbox does not support mod-sequences." msgstr "Der Ordner unterstützt keine Mod-Sequences." #: lib/Horde/Imap/Client/Socket.php:370 #: lib/Horde/Imap/Client/Socket/Pop3.php:201 msgid "No password provided." msgstr "Kein Passwort angegeben." #: lib/Horde/Imap/Client/Socket.php:498 msgid "No supported IMAP authentication method could be found." msgstr "" "Es wurde keine unterstützte Authentifizierungsmethode für IMAP gefunden." #: lib/Horde/Imap/Client/Socket.php:5043 msgid "Operation failed due to a lack of a secure connection." msgstr "" "Die Operation ist wegen einer fehlenden sicheren Verbindung fehlgeschlagen." #: lib/Horde/Imap/Client/Socket/Pop3.php:1448 msgid "POP3 error reported by server." msgstr "Der E-Mail-Server hat einen POP3-Fehler gemeldet." #: lib/Horde/Imap/Client/Socket/Pop3.php:295 msgid "POP3 server denied authentication." msgstr "Der POP3-Server hat die Authentifizierung zurückgewiesen." #: lib/Horde/Imap/Client/Socket.php:5011 msgid "Remote server is temporarily unavailable." msgstr "Der E-Mail-Server ist zur Zeit nicht verfügbar." #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:75 msgid "Server closed the connection unexpectedly." msgstr "Der E-Mail-Server hat die Verbindung unerwartet unterbrochen." #: lib/Horde/Imap/Client/Socket.php:388 msgid "Server does not support TLS connections." msgstr "Der E-Mail-Server unterstützt keine TLS-Verbindungen." #: lib/Horde/Imap/Client/Socket/Pop3.php:219 msgid "Server does not support secure connections." msgstr "Der E-Mail-Server unterstützt keine sicheren Verbindungen." #: lib/Horde/Imap/Client/Socket.php:809 #: lib/Horde/Imap/Client/Socket/Pop3.php:508 msgid "Server failed verification check." msgstr "Bestätigung des E-Mail-Servers fehlgeschlagen." #: lib/Horde/Imap/Client/Socket.php:626 msgid "Server rejected connection." msgstr "Der E-Mail-Server hat die Verbindung abgelehnt." #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:47 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:64 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:110 msgid "Server write error." msgstr "Server-Schreibfehler." #: lib/Horde/Imap/Client/Socket.php:4964 msgid "The comparison algorithm was not recognized by the server." msgstr "Der Vergleichsalgorithmus wurde vom E-Mail-Server nicht erkannt." #: lib/Horde/Imap/Client/Socket.php:635 msgid "The mail server does not support IMAP4rev1 (RFC 3501)." msgstr "Der E-Mail-Server unterstützt kein IMAP4rev1 (RFC 3501)." #: lib/Horde/Imap/Client/Socket.php:5092 msgid "The mail server has denied the request." msgstr "Der E-Mail-Server hat die Anfrage abgelehnt." #: lib/Horde/Imap/Client/Socket.php:5074 msgid "The mail server is reporting corrupt data in your mailbox." msgstr "Der E-Mail-Server hat beschädigte Daten in Ihrem Ordner gemeldet." #: lib/Horde/Imap/Client/Socket.php:4876 msgid "The mail server was unable to parse the contents of the mail message." msgstr "Der E-Mail-Server konnte den Inhalt der Nachricht nicht auswerten." #: lib/Horde/Imap/Client/Socket.php:4827 #, php-format msgid "" "The mail server was unable to parse the contents of the mail message: %s" msgstr "Der E-Mail-Server konnte den Inhalt der Nachricht nicht auswerten: %s" #: lib/Horde/Imap/Client/Socket.php:4982 msgid "The metadata item could not be saved because it is too large." msgstr "" "Der Metadaten-Eintrag konnte nicht gespeichert werden, weil er zu groß ist." #: lib/Horde/Imap/Client/Socket.php:5000 msgid "" "The metadata item could not be saved because the maximum number of " "annotations has been exceeded." msgstr "" "Der Metadaten-Eintrag konnte nicht gespeichert werden, weil die maximale " "Anzahl an Vermerken erschöpft ist." #: lib/Horde/Imap/Client/Socket.php:4991 msgid "" "The metadata item could not be saved because the server does not support " "private annotations." msgstr "" "Der Metadaten-Eintrag konnte nicht gespeichert werden, weil der E-Mail-" "Server keine privaten Vermerke unterstützt." #: lib/Horde/Imap/Client/Socket.php:5110 msgid "The object could not be created because it already exists." msgstr "" "Das Element konnte nicht gespeichert werden, weil es bereits existiert." #: lib/Horde/Imap/Client/Socket.php:5119 msgid "The object could not be deleted because it does not exist." msgstr "Das Element konnte nicht gelöscht werden, weil es nicht existiert." #: lib/Horde/Imap/Client/Socket.php:5101 msgid "" "The operation failed because the quota has been exceeded on the mail server." msgstr "" "Die Operation ist fehlgeschlagen, weil das Speicherplatzkontingent auf dem E-" "Mail-Server erschöpft ist." #: lib/Horde/Imap/Client/Exception/NoSupportExtension.php:46 #, php-format msgid "The server does not support the %s extension." msgstr "Der Server unterstützt die %s-Erweiterung nicht." #: lib/Horde/Imap/Client/Socket.php:5128 msgid "The special-use attribute requested for the mailbox is not supported." msgstr "" "Das Attribut für spezielle Nutzung wird von dem Ordner nicht unterstützt." #: lib/Horde/Imap/Client/Socket.php:5060 msgid "" "There was a temporary issue when attempting this operation. Please try again " "later." msgstr "" "Bei dieser Aktion ist ein vorübergehender Fehler aufgetreten. Bitte " "versuchen Sie es später noch einmal." #: lib/Horde/Imap/Client/Socket.php:723 #: lib/Horde/Imap/Client/Socket/Pop3.php:379 msgid "Unexpected response from server when authenticating." msgstr "Unerwartete Antwort vom E-Mail-Server während der Anmeldung." #: lib/Horde/Imap/Client/Socket.php:839 #: lib/Horde/Imap/Client/Socket/Pop3.php:518 #, php-format msgid "Unknown authentication method: %s" msgstr "Unbekannte Authentifizierungsmethode: %s" #: lib/Horde/Imap/Client/Socket.php:5051 msgid "You do not have adequate permissions to carry out this operation." msgstr "Sie haben nicht die nötigen Rechte, um diese Aktion durchzuführen." Horde_Imap_Client-2.29.15/locale/el/LC_MESSAGES/Horde_Imap_Client.mo0000664000175000017500000002250513150761653022604 0ustar janjan5Gl!(8</Q!A84;4p! ". ":]|!/"'77M6")*( (S +|   : 6 'J :r E H =< ]z : : LN - E S 4c ! A  F[)E)ol-4?_gA0kO5[n0P;C=o?dW6l|s ;NnTO\3?:n hzY=* t.!!RT""K#u$:$|$.,%/ 3) !#4 (+-"*01&2$5 '%s not supported on POP3 servers.Authentication credentials have expired.Authentication failed.Authentication failure.Authentication was successful, but authorization failed.Bad tagged response.Cannot convert search query text to new charsetCannot expunge read-only mailbox.Charset used in search query is not supported on the mail server.Could not open mailbox "%s".Could not open secure TLS connection to the IMAP server.Could not open secure connection to the POP3 server.Could not save message data because it is too large.Could not save message on server.Error connecting to mail server.Error converting UTF7-IMAP string.Error when communicating with the mail server.IMAP Server closed the connection.IMAP error reported by server.Invalid METADATA entry: "%s".Invalid METADATA value type "%s".Mail server closed the connection unexpectedly.Mail server denied authentication.Mailbox does not support mod-sequences.No password provided.No supported IMAP authentication method could be found.Operation failed due to a lack of a secure connection.POP3 error reported by server.POP3 server denied authentication.Remote server is temporarily unavailable.Server closed the connection unexpectedly.Server does not support TLS connections.Server does not support secure connections.Server rejected connection.Server write error.The comparison algorithm was not recognized by the server.The mail server does not support IMAP4rev1 (RFC 3501).The mail server has denied the request.The mail server is reporting corrupt data in your mailbox.The mail server was unable to parse the contents of the mail message.The mail server was unable to parse the contents of the mail message: %sThe metadata item could not be saved because it is too large.The metadata item could not be saved because the server does not support private annotations.The object could not be created because it already exists.The object could not be deleted because it does not exist.The operation failed because the quota has been exceeded on the mail server.The server does not support the %s extension.The special-use attribute requested for the mailbox is not supported.There was a temporary issue when attempting this operation. Please try again later.Unexpected response from server when authenticating.Unknown authentication method: %sYou do not have adequate permissions to carry out this operation.Project-Id-Version: Horde_Imap_Client Report-Msgid-Bugs-To: dev@lists.horde.org POT-Creation-Date: 2015-03-24 10:40+0100 PO-Revision-Date: 2015-10-02 15:23+0200 Last-Translator: Antonis Limperis Language-Team: i18n@lists.horde.org Language: de MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Generator: Poedit 1.7.1 %s δεν υποστηρίζεται σε διακομιστές POP3.Tα διαπιστευτήρια ελέγχου ταυτότητας έχουν λήξει.Η πιστοποίηση απέτυχε.Αποτυχία πιστοποίησηςΗ πιστοποίηση ήταν επιτυχής, αλλά απέτυχε η εξουσιοδότηση.Απάντηση κακής ετικέτας.Αδυναμία μετατροπής του κειμένου αναζήτησης στο νέο σύνολο χαρακτήρωνΔεν είναι δυνατή η οριστική διαγραφή σε γραμματοθυρίδα μόνο για ανάγνωσηΤο σύνολο χαρακτήρων που χρησιμοποιείται στην αναζήτηση δεν υποστηρίζεται από το διακομιστή αλληλογραφίας.Δεν ήταν δυνατό το άνοιγμα της γραμματοθυρίδας "% s ".Δεν θα ήταν δυνατό το άνοιγμα ασφαλούς σύνδεσης TLS προς τον διακομιστή IMAP.Sichere Verbindung zum POP3-Server kann nicht hergestellt werden.Δεν ήταν δυνατή η αποθήκευση των δεδομένων του μηνύματος, επειδή είναι πολύ μεγάλο.Δεν ήταν δυνατή η αποθήκευση του μηνύματος στο διακομιστή.Σφάλμα κατά τη σύνδεση στον διακομιστή e-mail.Σφάλμα κατά τη μετατροπή της συμβολοσειράς UTF7-IMAP .Σφάλμα κατά την επικοινωνία με το διακομιστή αλληλογραφίας.Der IMAP-Server hat die Verbindung unterbrochen.Ο διακομιστής ανέφερε σφάλμα IMAP.Άκυρη καταχώρηση μεταδεδομένων: "% s ".Μη έγκυρη τιμή μεταδεδομένων "% s ".Ο Διακομιστής αλληλογραφίας έκλεισε τη σύνδεση απροσδόκητα.Ο διακομιστής αλληλογραφίας αρνήθηκε την πιστοποίηση.Η γραμματοθυρίδα δεν υποστηρίζει mod-ακολουθίες.Δεν δόθηκε κωδικός πρόσβασης.Δεν μπορεί να εντοπιστεί η υποστηριζόμενη IMAP μέθοδος πιστοποίησης.Η λειτουργία απέτυχε λόγω της έλλειψης μιας ασφαλούς σύνδεσης.Ο διακομιστής ανέφερε σφάλμα POP3.Ο διακομιστής POP3 αρνήθηκε την πιστοποίηση.O απομακρυσμένο διακομιστής δεν είναι διαθέσιμος προσωρινά.Ο διακομιστής έκλεισε τη σύνδεση απροσδόκητα.Ο διακομιστής δεν υποστηρίζει συνδέσεις TLS.Ο διακομιστής δεν υποστηρίζει ασφαλείς συνδέσεις.Ο διακομιστής απέρριψε τη σύνδεση.Σφάλμα εγγραφής στο διακομιστή.Ο αλγόριθμος σύγκρισης δεν αναγνωρίζεται από το διακομιστή.Ο διακομιστής αλληλογραφίας δεν υποστηρίζει IMAP4rev1 (RFC 3501).Ο διακομιστής αλληλογραφίας αρνήθηκε το αίτημα.Ο διακομιστής αλληλογραφίας η ανέφερε κατεστραμένα δεδομένα στη γραμματοθυρίδα σας.Ο διακομιστής αλληλογραφίας δεν ήταν σε θέση να αναλύσει το περιεχόμενο του μηνύματος e-mailΟ διακομιστής αλληλογραφίας δεν ήταν σε θέση να αναλύσει το περιεχόμενο του μηνύματος e-mail: %sΤο στοιχείο μεταδεδομένων δεν ήταν δυνατό να αποθηκευτεί επειδή είναι πολύ μεγάλο.Το στοιχείο μεταδεδομένων δεν ήταν δυνατό να αποθηκευτεί επειδή ο διακομιστής δεν υποστηρίζει ιδιωτικούς σχολιασμούς.Το στοιχείο μεταδεδομένων δεν ήταν δυνατό να δημιουργηθεί επειδή υπάρχει ήδηΤο αντικείμενο δεν θα μπορούσε να διαγραφεί επειδή δεν υπάρχει.Η λειτουργία απέτυχε επειδή ο χώρος έχει ξεπεραστεί στον διακομιστή ηλεκτρονικού ταχυδρομείου.Ο διακομιστής δεν υποστηρίζει την επέκταση%s.Το χαρακτηριστικό ειδικής χρήσης που ζητήθηκε για το γραμματοκιβώτιο δεν υποστηρίζεται.Υπήρξε ένα προσωρινό πρόβλημα κατά την προσπάθεια αυτής της λειτουργίας. Παρακαλώ προσπαθείστε ξανά αργότερα.Μη αναμενόμενη απόκριση από το διακομιστή κατά την πιστοποίηση.Άγνωστη μέθοδος πιστοποίησης: %sΔεν έχετε επαρκή δικαιώματα για την εκτέλεση αυτής της λειτουργίας.Horde_Imap_Client-2.29.15/locale/el/LC_MESSAGES/Horde_Imap_Client.po0000664000175000017500000003157113150761653022612 0ustar janjan# German translations for Horde_Imap_Client package. # Copyright 2012-2015 Horde LLC (http://www.horde.org/) # This file is distributed under the same license as the Horde_Imap_Client package. # Jan Schneider , 2012-2014. # msgid "" msgstr "" "Project-Id-Version: Horde_Imap_Client\n" "Report-Msgid-Bugs-To: dev@lists.horde.org\n" "POT-Creation-Date: 2015-03-24 10:40+0100\n" "PO-Revision-Date: 2015-10-02 15:23+0200\n" "Last-Translator: Antonis Limperis \n" "Language-Team: i18n@lists.horde.org\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 1.7.1\n" #: lib/Horde/Imap/Client/Exception/NoSupportPop3.php:34 #, php-format msgid "%s not supported on POP3 servers." msgstr "%s δεν υποστηρίζεται σε διακομιστές POP3." #: lib/Horde/Imap/Client/Socket.php:4922 msgid "Authentication credentials have expired." msgstr "Tα διαπιστευτήρια ελέγχου ταυτότητας έχουν λήξει." #: lib/Horde/Imap/Client/Socket.php:725 lib/Horde/Imap/Client/Socket.php:4906 #: lib/Horde/Imap/Client/Socket/Pop3.php:440 #: lib/Horde/Imap/Client/Socket/Pop3.php:459 msgid "Authentication failed." msgstr "Η πιστοποίηση απέτυχε." #: lib/Horde/Imap/Client/Auth/DigestMD5.php:158 msgid "Authentication failure." msgstr "Αποτυχία πιστοποίησης" #: lib/Horde/Imap/Client/Socket.php:4914 msgid "Authentication was successful, but authorization failed." msgstr "Η πιστοποίηση ήταν επιτυχής, αλλά απέτυχε η εξουσιοδότηση." #: lib/Horde/Imap/Client/Interaction/Server/Tagged.php:44 msgid "Bad tagged response." msgstr "Απάντηση κακής ετικέτας." #: lib/Horde/Imap/Client/Exception/SearchCharset.php:45 msgid "Cannot convert search query text to new charset" msgstr "Αδυναμία μετατροπής του κειμένου αναζήτησης στο νέο σύνολο χαρακτήρων" #: lib/Horde/Imap/Client/Base.php:1920 lib/Horde/Imap/Client/Base.php:1983 msgid "Cannot expunge read-only mailbox." msgstr "" "Δεν είναι δυνατή η οριστική διαγραφή σε γραμματοθυρίδα μόνο για ανάγνωση" #: lib/Horde/Imap/Client/Socket.php:4698 msgid "Charset used in search query is not supported on the mail server." msgstr "" "Το σύνολο χαρακτήρων που χρησιμοποιείται στην αναζήτηση δεν υποστηρίζεται " "από το διακομιστή αλληλογραφίας." #: lib/Horde/Imap/Client/Socket.php:1139 #, php-format msgid "Could not open mailbox \"%s\"." msgstr "Δεν ήταν δυνατό το άνοιγμα της γραμματοθυρίδας \"% s \"." #: lib/Horde/Imap/Client/Socket.php:357 lib/Horde/Imap/Client/Socket.php:399 msgid "Could not open secure TLS connection to the IMAP server." msgstr "" "Δεν θα ήταν δυνατό το άνοιγμα ασφαλούς σύνδεσης TLS προς τον διακομιστή IMAP." #: lib/Horde/Imap/Client/Socket/Pop3.php:218 #: lib/Horde/Imap/Client/Socket/Pop3.php:232 msgid "Could not open secure connection to the POP3 server." msgstr "Sichere Verbindung zum POP3-Server kann nicht hergestellt werden." #: lib/Horde/Imap/Client/Socket.php:4806 msgid "Could not save message data because it is too large." msgstr "" "Δεν ήταν δυνατή η αποθήκευση των δεδομένων του μηνύματος, επειδή είναι πολύ " "μεγάλο." #: lib/Horde/Imap/Client/Socket.php:4797 msgid "Could not save message on server." msgstr "Δεν ήταν δυνατή η αποθήκευση του μηνύματος στο διακομιστή." #: lib/Horde/Imap/Client/Socket.php:580 #: lib/Horde/Imap/Client/Socket/Pop3.php:323 msgid "Error connecting to mail server." msgstr "Σφάλμα κατά τη σύνδεση στον διακομιστή e-mail." #: lib/Horde/Imap/Client/Utf7imap.php:128 #: lib/Horde/Imap/Client/Utf7imap.php:156 #: lib/Horde/Imap/Client/Utf7imap.php:163 #: lib/Horde/Imap/Client/Utf7imap.php:225 #: lib/Horde/Imap/Client/Utf7imap.php:245 #: lib/Horde/Imap/Client/Utf7imap.php:252 #: lib/Horde/Imap/Client/Utf7imap.php:263 #: lib/Horde/Imap/Client/Utf7imap.php:272 msgid "Error converting UTF7-IMAP string." msgstr "Σφάλμα κατά τη μετατροπή της συμβολοσειράς UTF7-IMAP ." #: lib/Horde/Imap/Client/Socket.php:4360 #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:83 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:207 #: lib/Horde/Imap/Client/Socket/Pop3.php:1337 msgid "Error when communicating with the mail server." msgstr "Σφάλμα κατά την επικοινωνία με το διακομιστή αλληλογραφίας." #: lib/Horde/Imap/Client/Socket.php:4492 msgid "IMAP Server closed the connection." msgstr "Der IMAP-Server hat die Verbindung unterbrochen." #: lib/Horde/Imap/Client/Socket.php:4478 msgid "IMAP error reported by server." msgstr "Ο διακομιστής ανέφερε σφάλμα IMAP." #: lib/Horde/Imap/Client/Socket.php:3904 #, php-format msgid "Invalid METADATA entry: \"%s\"." msgstr "Άκυρη καταχώρηση μεταδεδομένων: \"% s \"." #: lib/Horde/Imap/Client/Socket.php:3997 #, php-format msgid "Invalid METADATA value type \"%s\"." msgstr "Μη έγκυρη τιμή μεταδεδομένων \"% s \"." #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:148 msgid "Mail server closed the connection unexpectedly." msgstr "Ο Διακομιστής αλληλογραφίας έκλεισε τη σύνδεση απροσδόκητα." #: lib/Horde/Imap/Client/Socket.php:547 msgid "Mail server denied authentication." msgstr "Ο διακομιστής αλληλογραφίας αρνήθηκε την πιστοποίηση." #: lib/Horde/Imap/Client/Base.php:2233 lib/Horde/Imap/Client/Base.php:2518 #: lib/Horde/Imap/Client/Base.php:2790 lib/Horde/Imap/Client/Base.php:2875 msgid "Mailbox does not support mod-sequences." msgstr "Η γραμματοθυρίδα δεν υποστηρίζει mod-ακολουθίες." #: lib/Horde/Imap/Client/Socket.php:369 #: lib/Horde/Imap/Client/Socket/Pop3.php:200 msgid "No password provided." msgstr "Δεν δόθηκε κωδικός πρόσβασης." #: lib/Horde/Imap/Client/Socket.php:472 msgid "No supported IMAP authentication method could be found." msgstr "Δεν μπορεί να εντοπιστεί η υποστηριζόμενη IMAP μέθοδος πιστοποίησης." #: lib/Horde/Imap/Client/Socket.php:4930 msgid "Operation failed due to a lack of a secure connection." msgstr "Η λειτουργία απέτυχε λόγω της έλλειψης μιας ασφαλούς σύνδεσης." #: lib/Horde/Imap/Client/Socket/Pop3.php:1403 msgid "POP3 error reported by server." msgstr "Ο διακομιστής ανέφερε σφάλμα POP3." #: lib/Horde/Imap/Client/Socket/Pop3.php:294 msgid "POP3 server denied authentication." msgstr "Ο διακομιστής POP3 αρνήθηκε την πιστοποίηση." #: lib/Horde/Imap/Client/Socket.php:4898 msgid "Remote server is temporarily unavailable." msgstr "O απομακρυσμένο διακομιστής δεν είναι διαθέσιμος προσωρινά." #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:75 msgid "Server closed the connection unexpectedly." msgstr "Ο διακομιστής έκλεισε τη σύνδεση απροσδόκητα." #: lib/Horde/Imap/Client/Socket.php:387 msgid "Server does not support TLS connections." msgstr "Ο διακομιστής δεν υποστηρίζει συνδέσεις TLS." #: lib/Horde/Imap/Client/Socket/Pop3.php:218 msgid "Server does not support secure connections." msgstr "Ο διακομιστής δεν υποστηρίζει ασφαλείς συνδέσεις." #: lib/Horde/Imap/Client/Socket.php:600 msgid "Server rejected connection." msgstr "Ο διακομιστής απέρριψε τη σύνδεση." #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:47 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:64 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:110 msgid "Server write error." msgstr "Σφάλμα εγγραφής στο διακομιστή." #: lib/Horde/Imap/Client/Socket.php:4851 msgid "The comparison algorithm was not recognized by the server." msgstr "Ο αλγόριθμος σύγκρισης δεν αναγνωρίζεται από το διακομιστή." #: lib/Horde/Imap/Client/Socket.php:609 msgid "The mail server does not support IMAP4rev1 (RFC 3501)." msgstr "Ο διακομιστής αλληλογραφίας δεν υποστηρίζει IMAP4rev1 (RFC 3501)." #: lib/Horde/Imap/Client/Socket.php:4979 msgid "The mail server has denied the request." msgstr "Ο διακομιστής αλληλογραφίας αρνήθηκε το αίτημα." #: lib/Horde/Imap/Client/Socket.php:4961 msgid "The mail server is reporting corrupt data in your mailbox." msgstr "" "Ο διακομιστής αλληλογραφίας η ανέφερε κατεστραμένα δεδομένα στη " "γραμματοθυρίδα σας." #: lib/Horde/Imap/Client/Socket.php:4763 msgid "The mail server was unable to parse the contents of the mail message." msgstr "" "Ο διακομιστής αλληλογραφίας δεν ήταν σε θέση να αναλύσει το περιεχόμενο του " "μηνύματος e-mail" #: lib/Horde/Imap/Client/Socket.php:4714 #, php-format msgid "" "The mail server was unable to parse the contents of the mail message: %s" msgstr "" "Ο διακομιστής αλληλογραφίας δεν ήταν σε θέση να αναλύσει το περιεχόμενο του " "μηνύματος e-mail: %s" #: lib/Horde/Imap/Client/Socket.php:4869 msgid "The metadata item could not be saved because it is too large." msgstr "" "Το στοιχείο μεταδεδομένων δεν ήταν δυνατό να αποθηκευτεί επειδή είναι πολύ " "μεγάλο." #: lib/Horde/Imap/Client/Socket.php:4878 msgid "" "The metadata item could not be saved because the server does not support " "private annotations." msgstr "" "Το στοιχείο μεταδεδομένων δεν ήταν δυνατό να αποθηκευτεί επειδή ο " "διακομιστής δεν υποστηρίζει ιδιωτικούς σχολιασμούς." #: lib/Horde/Imap/Client/Socket.php:4997 msgid "The object could not be created because it already exists." msgstr "" "Το στοιχείο μεταδεδομένων δεν ήταν δυνατό να δημιουργηθεί επειδή υπάρχει ήδη" #: lib/Horde/Imap/Client/Socket.php:5006 msgid "The object could not be deleted because it does not exist." msgstr "Το αντικείμενο δεν θα μπορούσε να διαγραφεί επειδή δεν υπάρχει." #: lib/Horde/Imap/Client/Socket.php:4988 msgid "" "The operation failed because the quota has been exceeded on the mail server." msgstr "" "Η λειτουργία απέτυχε επειδή ο χώρος έχει ξεπεραστεί στον διακομιστή " "ηλεκτρονικού ταχυδρομείου." #: lib/Horde/Imap/Client/Exception/NoSupportExtension.php:46 #, php-format msgid "The server does not support the %s extension." msgstr "Ο διακομιστής δεν υποστηρίζει την επέκταση%s." #: lib/Horde/Imap/Client/Socket.php:5015 msgid "The special-use attribute requested for the mailbox is not supported." msgstr "" "Το χαρακτηριστικό ειδικής χρήσης που ζητήθηκε για το γραμματοκιβώτιο δεν " "υποστηρίζεται." #: lib/Horde/Imap/Client/Socket.php:4947 msgid "" "There was a temporary issue when attempting this operation. Please try again " "later." msgstr "" "Υπήρξε ένα προσωρινό πρόβλημα κατά την προσπάθεια αυτής της λειτουργίας. " "Παρακαλώ προσπαθείστε ξανά αργότερα." #: lib/Horde/Imap/Client/Socket.php:701 #: lib/Horde/Imap/Client/Socket/Pop3.php:378 msgid "Unexpected response from server when authenticating." msgstr "Μη αναμενόμενη απόκριση από το διακομιστή κατά την πιστοποίηση." #: lib/Horde/Imap/Client/Socket.php:757 #: lib/Horde/Imap/Client/Socket/Pop3.php:473 #, php-format msgid "Unknown authentication method: %s" msgstr "Άγνωστη μέθοδος πιστοποίησης: %s" #: lib/Horde/Imap/Client/Socket.php:4938 msgid "You do not have adequate permissions to carry out this operation." msgstr "Δεν έχετε επαρκή δικαιώματα για την εκτέλεση αυτής της λειτουργίας." Horde_Imap_Client-2.29.15/locale/es/LC_MESSAGES/Horde_Imap_Client.mo0000664000175000017500000001550113150761653022611 0ustar janjan6I|!(8T/i!A84S4! ".#"Ru!/"''O7e6") *@ (k +   : 6+ 'b : E H =T a ] :R : L - EC S 4 !A4v)N2x> !HB.S =/9mE.'$D-i%$%*:3(n""BA $b-50%)B"l"7+/CFBEFdZ^-.LN{'Ck62+?*5',3$ # .4"+/2!%0  &1-)6 ( %s not supported on POP3 servers.Authentication credentials have expired.Authentication failed.Authentication failure.Authentication was successful, but authorization failed.Bad tagged response.Cannot convert search query text to new charsetCannot expunge read-only mailbox.Charset used in search query is not supported on the mail server.Could not open mailbox "%s".Could not open secure TLS connection to the IMAP server.Could not open secure connection to the POP3 server.Could not save message data because it is too large.Could not save message on server.Error connecting to mail server.Error converting UTF7-IMAP string.Error when communicating with the mail server.IMAP Server closed the connection.IMAP error reported by server.Invalid METADATA entry: "%s".Invalid METADATA value type "%s".Mail server closed the connection unexpectedly.Mail server denied authentication.Mailbox does not support mod-sequences.No password provided.No supported IMAP authentication method could be found.Operation failed due to a lack of a secure connection.POP3 error reported by server.POP3 server denied authentication.Remote server is temporarily unavailable.Server closed the connection unexpectedly.Server does not support TLS connections.Server does not support secure connections.Server rejected connection.Server write error.The comparison algorithm was not recognized by the server.The mail server does not support IMAP4rev1 (RFC 3501).The mail server has denied the request.The mail server is reporting corrupt data in your mailbox.The mail server was unable to parse the contents of the mail message.The mail server was unable to parse the contents of the mail message: %sThe metadata item could not be saved because it is too large.The metadata item could not be saved because the maximum number of annotations has been exceeded.The metadata item could not be saved because the server does not support private annotations.The object could not be created because it already exists.The object could not be deleted because it does not exist.The operation failed because the quota has been exceeded on the mail server.The server does not support the %s extension.The special-use attribute requested for the mailbox is not supported.There was a temporary issue when attempting this operation. Please try again later.Unexpected response from server when authenticating.Unknown authentication method: %sYou do not have adequate permissions to carry out this operation.Project-Id-Version: Horde_Imap_Client Report-Msgid-Bugs-To: dev@lists.horde.org POT-Creation-Date: 2014-06-12 16:24+0200 PO-Revision-Date: 2014-06-16 09:05+0100 Last-Translator: Manuel P. Ayala , Juan C. Blanco Last-Translator: Automatically generated Language-Team: i18n@lists.horde.org Language: es MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); %s no está soportado en servidores POP3.Las credenciales de autentificación han caducado.Falló la autentificación.Fallo de autentificación.La autentificación fue correcta pero falló la autorización.Respuesta etiquetada incorrecta.No se puede convertir el texto de búsqueda al nuevo juego de caracteresNo se puede borrar un buzón de sólo lectura.El servidor de correo no admite el juego de caracteres de la consulta de búsqueda.No se pudo abrir el buzón "%s".No se puede iniciar una conexión TLS segura al servidor IMAPNo se puede iniciar una conexión segura al servidor POP3No se pueden guardar los datos del mensaje ya que es demasiado largo.No se puede guardar el mensaje en el servidor.Error conectando al servidor de correo.Error convirtiendo cadena UTF7-IMAP.Error al comunicar con el servidor de correo.El servidor IMAP cerró la conexión.Error IMAP indicado por el servidor.Entrada de METADATOS inválida: "%s".Tipo de valor de METADATOS inválido "%s".El servidor de correo cerró la conexión inesperadamente.El servidor denegó la autentificación.El buzón no admite mod-sequences.No se ha indicado una contraseña.No se pudo encontrar un método de autentificación IMAP admitido.La operación falló por la inexistencia de una conexión segura.Error POP3 indicado por el servidor.El servidor POP3 denegó la autentificación.El servidor remoto no está disponible temporalmente.El servidor cerró la conexión inesperadamente.El servidor no admite conexiones TLS.El servidor no admite conexiones seguras.El servidor rechazó la conexión.Error de escritura en el servidor.El servidor no reconoció el algoritmo de comparación.El servidor no admite IMAP4rev1 (RFC 3501).El servidor de correo ha denegado la petición.El servidor de correo informa que hay datos corruptos en su buzón.El servidor no pudo procesar los contenidos del mensaje de correo.El servidor no pudo procesar los contenidos del mensaje de correo: %sEl elemento de metadatos no se pudo guardar ya que es demasiado largo.El elemento de metadatos no se pudo guardar ya que se ha superado el número máximo de anotaciones.El elemento de metadatos no se pudo guardar ya que el servidor no admite anotaciones privadas.No se puede crear el objeto porque ya existe.No se puede borrar el objeto porque no existe.La operación ha fallado porque ha excedido su cuota en el servidor de correo.El servidor no admite la extensión %s.El atributo de uso-especial solicitado para el buzón no se admite.Se ha producido un error temporal al intentar esta operación. Por favor, vuelva a intentarlo mas adelante.Respuesta inesperada del servidor al autentificar.Método de autentificación desconocido: %sCarece de los permisos adecuados para ejecutar esta operación.Horde_Imap_Client-2.29.15/locale/es/LC_MESSAGES/Horde_Imap_Client.po0000664000175000017500000002445013150761653022617 0ustar janjan# Spanish translations for Horde_Imap_Client package. # Copyright (C) 2014 Horde LLC (http://www.horde.org/) # This file is distributed under the same license as the Horde_Imap_Client package. # Automatically generated, 2014. # msgid "" msgstr "" "Project-Id-Version: Horde_Imap_Client\n" "Report-Msgid-Bugs-To: dev@lists.horde.org\n" "POT-Creation-Date: 2014-06-12 16:24+0200\n" "PO-Revision-Date: 2014-06-16 09:05+0100\n" "Last-Translator: Manuel P. Ayala , Juan C. Blanco " "\n" "Last-Translator: Automatically generated\n" "Language-Team: i18n@lists.horde.org\n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: lib/Horde/Imap/Client/Exception/NoSupportPop3.php:34 #, php-format msgid "%s not supported on POP3 servers." msgstr "%s no está soportado en servidores POP3." #: lib/Horde/Imap/Client/Socket.php:4742 msgid "Authentication credentials have expired." msgstr "Las credenciales de autentificación han caducado." #: lib/Horde/Imap/Client/Socket.php:4726 msgid "Authentication failed." msgstr "Falló la autentificación." #: lib/Horde/Imap/Client/Auth/DigestMD5.php:158 msgid "Authentication failure." msgstr "Fallo de autentificación." #: lib/Horde/Imap/Client/Socket.php:4734 msgid "Authentication was successful, but authorization failed." msgstr "La autentificación fue correcta pero falló la autorización." #: lib/Horde/Imap/Client/Interaction/Server/Tagged.php:44 msgid "Bad tagged response." msgstr "Respuesta etiquetada incorrecta." #: lib/Horde/Imap/Client/Exception/SearchCharset.php:45 msgid "Cannot convert search query text to new charset" msgstr "" "No se puede convertir el texto de búsqueda al nuevo juego de caracteres" #: lib/Horde/Imap/Client/Base.php:1873 lib/Horde/Imap/Client/Base.php:1936 msgid "Cannot expunge read-only mailbox." msgstr "No se puede borrar un buzón de sólo lectura." #: lib/Horde/Imap/Client/Socket.php:4518 msgid "Charset used in search query is not supported on the mail server." msgstr "" "El servidor de correo no admite el juego de caracteres de la consulta de " "búsqueda." #: lib/Horde/Imap/Client/Socket.php:1084 #, php-format msgid "Could not open mailbox \"%s\"." msgstr "No se pudo abrir el buzón \"%s\"." #: lib/Horde/Imap/Client/Socket.php:357 lib/Horde/Imap/Client/Socket.php:398 msgid "Could not open secure TLS connection to the IMAP server." msgstr "No se puede iniciar una conexión TLS segura al servidor IMAP" #: lib/Horde/Imap/Client/Socket/Pop3.php:207 #: lib/Horde/Imap/Client/Socket/Pop3.php:221 msgid "Could not open secure connection to the POP3 server." msgstr "No se puede iniciar una conexión segura al servidor POP3" #: lib/Horde/Imap/Client/Socket.php:4626 msgid "Could not save message data because it is too large." msgstr "No se pueden guardar los datos del mensaje ya que es demasiado largo." #: lib/Horde/Imap/Client/Socket.php:4617 msgid "Could not save message on server." msgstr "No se puede guardar el mensaje en el servidor." #: lib/Horde/Imap/Client/Socket.php:579 #: lib/Horde/Imap/Client/Socket/Pop3.php:301 msgid "Error connecting to mail server." msgstr "Error conectando al servidor de correo." #: lib/Horde/Imap/Client/Utf7imap.php:128 #: lib/Horde/Imap/Client/Utf7imap.php:156 #: lib/Horde/Imap/Client/Utf7imap.php:163 #: lib/Horde/Imap/Client/Utf7imap.php:225 #: lib/Horde/Imap/Client/Utf7imap.php:245 #: lib/Horde/Imap/Client/Utf7imap.php:252 #: lib/Horde/Imap/Client/Utf7imap.php:263 #: lib/Horde/Imap/Client/Utf7imap.php:272 msgid "Error converting UTF7-IMAP string." msgstr "Error convirtiendo cadena UTF7-IMAP." #: lib/Horde/Imap/Client/Socket.php:4186 #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:77 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:189 #: lib/Horde/Imap/Client/Socket/Pop3.php:1211 msgid "Error when communicating with the mail server." msgstr "Error al comunicar con el servidor de correo." #: lib/Horde/Imap/Client/Socket.php:4305 msgid "IMAP Server closed the connection." msgstr "El servidor IMAP cerró la conexión." #: lib/Horde/Imap/Client/Socket.php:4291 msgid "IMAP error reported by server." msgstr "Error IMAP indicado por el servidor." #: lib/Horde/Imap/Client/Socket.php:3775 #, php-format msgid "Invalid METADATA entry: \"%s\"." msgstr "Entrada de METADATOS inválida: \"%s\"." #: lib/Horde/Imap/Client/Socket.php:3863 #, php-format msgid "Invalid METADATA value type \"%s\"." msgstr "Tipo de valor de METADATOS inválido \"%s\"." #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:130 msgid "Mail server closed the connection unexpectedly." msgstr "El servidor de correo cerró la conexión inesperadamente." #: lib/Horde/Imap/Client/Socket.php:547 msgid "Mail server denied authentication." msgstr "El servidor denegó la autentificación." #: lib/Horde/Imap/Client/Base.php:2188 lib/Horde/Imap/Client/Base.php:2477 #: lib/Horde/Imap/Client/Base.php:2745 lib/Horde/Imap/Client/Base.php:2830 msgid "Mailbox does not support mod-sequences." msgstr "El buzón no admite mod-sequences." #: lib/Horde/Imap/Client/Socket.php:369 #: lib/Horde/Imap/Client/Socket/Pop3.php:189 msgid "No password provided." msgstr "No se ha indicado una contraseña." #: lib/Horde/Imap/Client/Socket.php:474 msgid "No supported IMAP authentication method could be found." msgstr "No se pudo encontrar un método de autentificación IMAP admitido." #: lib/Horde/Imap/Client/Socket.php:4750 msgid "Operation failed due to a lack of a secure connection." msgstr "La operación falló por la inexistencia de una conexión segura." #: lib/Horde/Imap/Client/Socket/Pop3.php:1270 msgid "POP3 error reported by server." msgstr "Error POP3 indicado por el servidor." #: lib/Horde/Imap/Client/Socket/Pop3.php:273 msgid "POP3 server denied authentication." msgstr "El servidor POP3 denegó la autentificación." #: lib/Horde/Imap/Client/Socket.php:4718 msgid "Remote server is temporarily unavailable." msgstr "El servidor remoto no está disponible temporalmente." #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:69 msgid "Server closed the connection unexpectedly." msgstr "El servidor cerró la conexión inesperadamente." #: lib/Horde/Imap/Client/Socket.php:386 msgid "Server does not support TLS connections." msgstr "El servidor no admite conexiones TLS." #: lib/Horde/Imap/Client/Socket/Pop3.php:207 msgid "Server does not support secure connections." msgstr "El servidor no admite conexiones seguras." #: lib/Horde/Imap/Client/Socket.php:599 msgid "Server rejected connection." msgstr "El servidor rechazó la conexión." #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:46 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:54 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:85 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:94 msgid "Server write error." msgstr "Error de escritura en el servidor." #: lib/Horde/Imap/Client/Socket.php:4671 msgid "The comparison algorithm was not recognized by the server." msgstr "El servidor no reconoció el algoritmo de comparación." #: lib/Horde/Imap/Client/Socket.php:608 msgid "The mail server does not support IMAP4rev1 (RFC 3501)." msgstr "El servidor no admite IMAP4rev1 (RFC 3501)." #: lib/Horde/Imap/Client/Socket.php:4799 msgid "The mail server has denied the request." msgstr "El servidor de correo ha denegado la petición." #: lib/Horde/Imap/Client/Socket.php:4781 msgid "The mail server is reporting corrupt data in your mailbox." msgstr "El servidor de correo informa que hay datos corruptos en su buzón." #: lib/Horde/Imap/Client/Socket.php:4583 msgid "The mail server was unable to parse the contents of the mail message." msgstr "El servidor no pudo procesar los contenidos del mensaje de correo." #: lib/Horde/Imap/Client/Socket.php:4534 #, php-format msgid "" "The mail server was unable to parse the contents of the mail message: %s" msgstr "El servidor no pudo procesar los contenidos del mensaje de correo: %s" #: lib/Horde/Imap/Client/Socket.php:4689 msgid "The metadata item could not be saved because it is too large." msgstr "El elemento de metadatos no se pudo guardar ya que es demasiado largo." #: lib/Horde/Imap/Client/Socket.php:4707 msgid "" "The metadata item could not be saved because the maximum number of " "annotations has been exceeded." msgstr "" "El elemento de metadatos no se pudo guardar ya que se ha superado el número " "máximo de anotaciones." #: lib/Horde/Imap/Client/Socket.php:4698 msgid "" "The metadata item could not be saved because the server does not support " "private annotations." msgstr "" "El elemento de metadatos no se pudo guardar ya que el servidor no admite " "anotaciones privadas." #: lib/Horde/Imap/Client/Socket.php:4817 msgid "The object could not be created because it already exists." msgstr "No se puede crear el objeto porque ya existe." #: lib/Horde/Imap/Client/Socket.php:4826 msgid "The object could not be deleted because it does not exist." msgstr "No se puede borrar el objeto porque no existe." #: lib/Horde/Imap/Client/Socket.php:4808 msgid "" "The operation failed because the quota has been exceeded on the mail server." msgstr "" "La operación ha fallado porque ha excedido su cuota en el servidor de correo." #: lib/Horde/Imap/Client/Exception/NoSupportExtension.php:46 #, php-format msgid "The server does not support the %s extension." msgstr "El servidor no admite la extensión %s." #: lib/Horde/Imap/Client/Socket.php:4835 msgid "The special-use attribute requested for the mailbox is not supported." msgstr "El atributo de uso-especial solicitado para el buzón no se admite." #: lib/Horde/Imap/Client/Socket.php:4767 msgid "" "There was a temporary issue when attempting this operation. Please try again " "later." msgstr "" "Se ha producido un error temporal al intentar esta operación. Por favor, " "vuelva a intentarlo mas adelante." #: lib/Horde/Imap/Client/Socket.php:697 #: lib/Horde/Imap/Client/Socket/Pop3.php:356 msgid "Unexpected response from server when authenticating." msgstr "Respuesta inesperada del servidor al autentificar." #: lib/Horde/Imap/Client/Socket.php:734 #: lib/Horde/Imap/Client/Socket/Pop3.php:402 #, php-format msgid "Unknown authentication method: %s" msgstr "Método de autentificación desconocido: %s" #: lib/Horde/Imap/Client/Socket.php:4758 msgid "You do not have adequate permissions to carry out this operation." msgstr "Carece de los permisos adecuados para ejecutar esta operación." Horde_Imap_Client-2.29.15/locale/eu/LC_MESSAGES/Horde_Imap_Client.mo0000664000175000017500000000377413150761653022624 0ustar janjan hi4  .,[z::S!cA#7+ ,L-y""25 LV#4   Authentication failed.Authentication failure.Could not open mailbox "%s".Could not save message data because it is too large.Error connecting to POP3 server.Error connecting to mail server.Error when communicating with the mail server.IMAP error reported by server.POP3 error reported by server.The object could not be created because it already exists.The object could not be deleted because it does not exist.There was a temporary issue when attempting this operation. Please try again later.Unknown authentication method: %sYou do not have adequate permissions to carry out this operation.Project-Id-Version: Horde_Imap_Client Report-Msgid-Bugs-To: dev@lists.horde.org POT-Creation-Date: 2012-11-06 16:40+0100 PO-Revision-Date: 2013-01-16 10:32+0100 Last-Translator: Ibon Igartua Language-Team: Euskal Herriko Unibertsitatea Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Poedit-Language: Basque Autentifikazioak huts egin du.Huts egitea autentifikazioan.Ezin izan da ireki "%s" postontzia.Ezin izan dira gorde mezuaren datuak, handiegia delako.Errorea POP3 zerbitzariarekin konektatzean.Errorea posta-zerbitzariarekin konektatzean.Errorea posta-zerbitzariarekin komunikatzean.Zerbitzariak IMAP errorea eman du.Zerbitzariak POP3 errorea eman du.Ezin izan da objektua sortu, lehendik badagoelako.Ezin izan da objektua ezabatu, lehendik ez dagoelako.Uneko arazoren bat gertatu da eragiketa hau egitean. Saiatu berriro geroago.Autentifikazio metodo ezezaguna: %sEz daukazu eragiketa hau egiteko behar den baimenik.Horde_Imap_Client-2.29.15/locale/eu/LC_MESSAGES/Horde_Imap_Client.po0000664000175000017500000001547113150761653022624 0ustar janjan# Basque translations for Horde_Imap_Client package. # Copyright 2012-2017 Horde LLC (http://www.horde.org/) # This file is distributed under the same license as the Horde_Imap_Client package. # Automatically generated, 2012. # msgid "" msgstr "" "Project-Id-Version: Horde_Imap_Client\n" "Report-Msgid-Bugs-To: dev@lists.horde.org\n" "POT-Creation-Date: 2012-11-06 16:40+0100\n" "PO-Revision-Date: 2013-01-16 10:32+0100\n" "Last-Translator: Ibon Igartua \n" "Language-Team: Euskal Herriko Unibertsitatea \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-Language: Basque\n" #: lib/Horde/Imap/Client/Exception/NoSupportPop3.php:25 #, fuzzy, php-format msgid "%s not supported on POP3 servers." msgstr "ACL ez dago konfiguratuta zerbitzari honetarako." #: lib/Horde/Imap/Client/Socket.php:4364 msgid "Authentication failed." msgstr "Autentifikazioak huts egin du." #: lib/Horde/Imap/Client/Auth/DigestMD5.php:149 msgid "Authentication failure." msgstr "Huts egitea autentifikazioan." #: lib/Horde/Imap/Client/Socket.php:931 #, php-format msgid "Could not open mailbox \"%s\"." msgstr "Ezin izan da ireki \"%s\" postontzia." #: lib/Horde/Imap/Client/Socket.php:335 #, fuzzy msgid "Could not open secure TLS connection to the IMAP server." msgstr "Ezin izan da PGP gako-zerbitzari publikora konektatu" #: lib/Horde/Imap/Client/Socket/Pop3.php:189 #: lib/Horde/Imap/Client/Socket/Pop3.php:201 #, fuzzy msgid "Could not open secure connection to the POP3 server." msgstr "Ezin izan da PGP gako-zerbitzari publikora konektatu" #: lib/Horde/Imap/Client/Socket.php:4265 msgid "Could not save message data because it is too large." msgstr "Ezin izan dira gorde mezuaren datuak, handiegia delako." #: lib/Horde/Imap/Client/Socket.php:4256 #, fuzzy msgid "Could not save message on server." msgstr "Ezin izan da mezu-daturik eskuratu posta-zerbitzaritik." #: lib/Horde/Imap/Client/Socket/Pop3.php:280 msgid "Error connecting to POP3 server." msgstr "Errorea POP3 zerbitzariarekin konektatzean." #: lib/Horde/Imap/Client/Socket.php:504 msgid "Error connecting to mail server." msgstr "Errorea posta-zerbitzariarekin konektatzean." #: lib/Horde/Imap/Client/Socket.php:3683 lib/Horde/Imap/Client/Socket.php:3964 msgid "Error when communicating with the mail server." msgstr "Errorea posta-zerbitzariarekin komunikatzean." #: lib/Horde/Imap/Client/Socket.php:3823 lib/Horde/Imap/Client/Socket.php:3854 msgid "IMAP error reported by server." msgstr "Zerbitzariak IMAP errorea eman du." #: lib/Horde/Imap/Client/Socket.php:3389 #, fuzzy, php-format msgid "Invalid METADATA entry: \"%s\"." msgstr "Sarrera ez da baliozkoa" #: lib/Horde/Imap/Client/Socket.php:395 #, fuzzy msgid "Mail server denied authentication." msgstr "Erabiltzailea ez dago autentifikatuta." #: lib/Horde/Imap/Client/Socket.php:1812 lib/Horde/Imap/Client/Socket.php:2483 #: lib/Horde/Imap/Client/Socket.php:2504 lib/Horde/Imap/Client/Socket.php:2933 #: lib/Horde/Imap/Client/Socket.php:2988 #, fuzzy msgid "Mailbox does not support mod-sequences." msgstr "Ez dago %s postontzirik." #: lib/Horde/Imap/Client/Socket/Pop3.php:1156 msgid "POP3 error reported by server." msgstr "Zerbitzariak POP3 errorea eman du." #: lib/Horde/Imap/Client/Socket/Pop3.php:240 #, fuzzy msgid "POP3 server denied authentication." msgstr "Erabiltzailea ez dago autentifikatuta." #: lib/Horde/Imap/Client/Socket.php:4356 #, fuzzy msgid "Remote server is temporarily unavailable." msgstr "Urruneko zerbitzaria erorita dago. Saiatu berriro geroago." #: lib/Horde/Imap/Client/Socket.php:323 #, fuzzy msgid "Server does not support TLS connections." msgstr "Zerbitzariak ez du onartzen ACLrik." #: lib/Horde/Imap/Client/Socket/Pop3.php:189 #, fuzzy msgid "Server does not support secure connections." msgstr "Zerbitzariak ez du onartzen ACLrik." #: lib/Horde/Imap/Client/Socket.php:536 #, fuzzy msgid "The mail server does not support IMAP4rev1 (RFC 3501)." msgstr "Zerbitzariak ez du onartzen ACLrik." #: lib/Horde/Imap/Client/Socket.php:4435 #, fuzzy msgid "The mail server has denied the request." msgstr "" "Posta-zerbitzariak eskaera ukatu du. Errorearen xehetasunak erregistratu " "dira administratzailearentzat." #: lib/Horde/Imap/Client/Socket.php:4419 #, fuzzy msgid "The mail server is reporting corrupt data in your mailbox." msgstr "" "Zure postontzian hondatutako datuak daudela jakinarazi du posta-" "zerbitzariak. Errorearen xehetasunak erregistratu dira " "administratzailearentzat." #: lib/Horde/Imap/Client/Socket.php:4177 lib/Horde/Imap/Client/Socket.php:4222 #, fuzzy msgid "The mail server was unable to parse the contents of the mail message." msgstr "Zerbitzariak ezin izan du mezu-zerrenda sortu." #: lib/Horde/Imap/Client/Socket.php:4327 #, fuzzy msgid "The metadata item could not be saved because it is too large." msgstr "Mezu-zati hau ezin da bistaratu, handiegia delako." #: lib/Horde/Imap/Client/Socket.php:4336 #, fuzzy msgid "" "The metadata item could not be saved because the server does not support " "private annotations." msgstr "Ezin izan da objektua ezabatu, lehendik ez dagoelako." #: lib/Horde/Imap/Client/Socket.php:4453 msgid "The object could not be created because it already exists." msgstr "Ezin izan da objektua sortu, lehendik badagoelako." #: lib/Horde/Imap/Client/Socket.php:4462 msgid "The object could not be deleted because it does not exist." msgstr "Ezin izan da objektua ezabatu, lehendik ez dagoelako." #: lib/Horde/Imap/Client/Socket.php:4444 #, fuzzy msgid "" "The operation failed because the quota has been exceeded on the mail server." msgstr "Huts egin du eragiketak, posta-zerbitzariko kuota gainditu duzulako." #: lib/Horde/Imap/Client/Exception/NoSupportExtension.php:36 #, fuzzy, php-format msgid "The server does not support the %s extension." msgstr "Arakatzaileak ez du eginbide hori onartzen." #: lib/Horde/Imap/Client/Socket.php:4471 #, fuzzy msgid "The special-use attribute requested for the mailbox is not supported." msgstr "Fitxategi-formatu hau ez da onartzen." #: lib/Horde/Imap/Client/Socket.php:4405 msgid "" "There was a temporary issue when attempting this operation. Please try again " "later." msgstr "" "Uneko arazoren bat gertatu da eragiketa hau egitean. Saiatu berriro geroago." #: lib/Horde/Imap/Client/Socket.php:604 #: lib/Horde/Imap/Client/Socket/Pop3.php:334 #, fuzzy msgid "Unexpected response from server when authenticating." msgstr "Ustekabeko erantzuna urruneko zerbitzaritik." #: lib/Horde/Imap/Client/Socket.php:648 #: lib/Horde/Imap/Client/Socket/Pop3.php:374 #, php-format msgid "Unknown authentication method: %s" msgstr "Autentifikazio metodo ezezaguna: %s" #: lib/Horde/Imap/Client/Socket.php:4396 msgid "You do not have adequate permissions to carry out this operation." msgstr "Ez daukazu eragiketa hau egiteko behar den baimenik." Horde_Imap_Client-2.29.15/locale/fi/LC_MESSAGES/Horde_Imap_Client.mo0000664000175000017500000001465613150761653022612 0ustar janjan5Gl!(8</Q!A84;4p!  " .,"[~!/" '07X6/" )9 (c +   : 6# 'Z : E = aA ] : :< Lw - E S8 4 ! A %#&<2o9J/&C;j6D'"0J0{12/M$m)"/-C=,"2"%Bh)4J;f>\g>17FW7w\7 "DFg.,%/ 3*) 0# 4 (-"+1&2$5 !'%s not supported on POP3 servers.Authentication credentials have expired.Authentication failed.Authentication failure.Authentication was successful, but authorization failed.Bad tagged response.Cannot convert search query text to new charsetCannot expunge read-only mailbox.Charset used in search query is not supported on the mail server.Could not open mailbox "%s".Could not open secure TLS connection to the IMAP server.Could not open secure connection to the POP3 server.Could not save message data because it is too large.Could not save message on server.Error connecting to POP3 server.Error connecting to mail server.Error converting UTF7-IMAP string.Error when communicating with the mail server.IMAP Server closed the connection.IMAP error reported by server.Invalid METADATA entry: "%s".Invalid METADATA value type "%s".Mail server closed the connection unexpectedly.Mail server denied authentication.Mailbox does not support mod-sequences.No supported IMAP authentication method could be found.Operation failed due to a lack of a secure connection.POP3 Server closed the connection unexpectedly.POP3 error reported by server.POP3 server denied authentication.Remote server is temporarily unavailable.Server does not support TLS connections.Server does not support secure connections.Server rejected connection.Server write error.The comparison algorithm was not recognized by the server.The mail server does not support IMAP4rev1 (RFC 3501).The mail server has denied the request.The mail server is reporting corrupt data in your mailbox.The mail server was unable to parse the contents of the mail message.The metadata item could not be saved because it is too large.The metadata item could not be saved because the maximum number of annotations has been exceeded.The metadata item could not be saved because the server does not support private annotations.The object could not be created because it already exists.The object could not be deleted because it does not exist.The operation failed because the quota has been exceeded on the mail server.The server does not support the %s extension.The special-use attribute requested for the mailbox is not supported.There was a temporary issue when attempting this operation. Please try again later.Unexpected response from server when authenticating.Unknown authentication method: %sYou do not have adequate permissions to carry out this operation.Project-Id-Version: Horde_Imap_Client Report-Msgid-Bugs-To: dev@lists.horde.org POT-Creation-Date: 2012-11-06 16:40+0100 PO-Revision-Date: 2012-11-07 17:24:08+0200 Last-Translator: Leena Heino Language-Team: Finnish Language: fi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); %s ei ole tuettu POP3-palvelimille.Autentikointitiedot ovat vanhentuneet.Autentikointi epäonnistui.Autentikointivirhe.Autentikointi epäonnistui, mutta autorisointi epäonnistui.Virheellinen tagätty vastaus.Ei voida muuntaa hakulauseen tekstiä uuteen merkistöönEi voida tyhjentää poistetuja vain lukuun tarkoitetusta postilaatikosta.Palvelin ei tue haussa käytettyä merkistöä.Ei voitu aukaista postilaatikkoa "%s".Ei voitu aukaista salattua TLS-yhteyttä IMAP-palvelimelle.Ei voitu aukaista salattua yhteyttä POP3-palvelimelleLiian suuren tietomäärän takia viestin tietoja ei voitu talentaa.Viestiä ei voi tallentaa palvelimelle.Virhetilanne yhdistettäessä POP3-palvelimelle.Virhetilanne yhdistettäessä postipalvelimelle.Virhetilanne muunnettaessa UTF7-IMAP merkkijonoa.Virhetilanne liikennöinnissä postipalvelimelle. IMAP-palvelin sulki yhteyden.IMAP-palvelimen antama virhe.Epäkelpo METADATA tieto: "%s".Epäkelpo METADATA arvotyyppi: "%s".Postipalvelin sulki yhteyden odottamatta.Postipalvelin esti autentikoinnin.Postilaatikko ei tue mod-sequences -piirrettä.Tuettua IMAP-autentikointitapaa ei löytynyt.Toiminto epäonnistui salatut yhteydet eivät ole käytettävissä.POP3-palvelin katkaisi yhteyden yllättäen.POP3-palvelimen antama virhe.POP3-palvelin esti autentikoinnin.Etäpalvelin on väliakaisesti saavuttamattomissa.Palvelin ei tue TLS-yhteyksiä.Palvelin ei tue salattuja yhteyksiä.Palvelin hylkäsi yhteyden.Palvelimen kirjoitusvirhe.Palvelin ei tunnista vertailualgoritmiä.Postipalvelin ei tue toimintoa IMAP4rev1 (RFC 3501).Postipalvelin esti pyynnön.Postipalvelin raportoi, että postilaatikossa on korruptoituneita tietoja.Postipalvelin ei pystynyt käsittelemään viestin tietoja.Metadata tietoja ei voitu tallentaa, koska se oli liian suuri.Metadata tietoa ei voi tallentaa, koska lisätietojen suurin sallittu määrä on ylittynyt.Metadata tietoja ei voitu tallentaa, koska palvelin ei tue yksilökohtaisten lisätietojen tallennusta.Objektia ei voitu luoda, koska se on jo olemassa.Objektia ei voitu poistaa, koska sitä ei ole olemassa.Operaatio epäonnistui, koska kiintiö on ylittynyt postipalvelimella.Palvelin ei tue laajennusta %s.Postilaatikon erikoiskäyttö atribuutti ei ole tuettu.Väliaikainen ongelmatilanne yritettäessä tätä operaatiota. Yritä myöhemmin uudestaan.Odottamaton vastaus palvelimelta autentikoinnin aikana.Tuntematon autentikointimetori: %sSinulla ei ole riittäviä oikeuksia tämän toiminnon suorittamiseen.Horde_Imap_Client-2.29.15/locale/fi/LC_MESSAGES/Horde_Imap_Client.po0000664000175000017500000002302313150761653022601 0ustar janjan# Finnish translations for Horde_Imap_Client package. # Copyright 2012-2017 Horde LLC (http://www.horde.org/) # This file is distributed under the same license as the Horde_Imap_Client package. # Leena Heino , 2011-2012. # msgid "" msgstr "" "Project-Id-Version: Horde_Imap_Client \n" "Report-Msgid-Bugs-To: dev@lists.horde.org\n" "POT-Creation-Date: 2012-11-06 16:40+0100\n" "PO-Revision-Date: 2012-11-07 17:24:08+0200\n" "Last-Translator: Leena Heino \n" "Language-Team: Finnish \n" "Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: lib/Horde/Imap/Client/Exception/NoSupportPop3.php:25 #, php-format msgid "%s not supported on POP3 servers." msgstr "%s ei ole tuettu POP3-palvelimille." #: lib/Horde/Imap/Client/Socket.php:4380 msgid "Authentication credentials have expired." msgstr "Autentikointitiedot ovat vanhentuneet." #: lib/Horde/Imap/Client/Socket.php:4364 msgid "Authentication failed." msgstr "Autentikointi epäonnistui." #: lib/Horde/Imap/Client/Auth/DigestMD5.php:149 msgid "Authentication failure." msgstr "Autentikointivirhe." #: lib/Horde/Imap/Client/Socket.php:4372 msgid "Authentication was successful, but authorization failed." msgstr "Autentikointi epäonnistui, mutta autorisointi epäonnistui." #: lib/Horde/Imap/Client/Interaction/Server/Tagged.php:34 msgid "Bad tagged response." msgstr "Virheellinen tagätty vastaus." #: lib/Horde/Imap/Client/Exception/SearchCharset.php:36 msgid "Cannot convert search query text to new charset" msgstr "Ei voida muuntaa hakulauseen tekstiä uuteen merkistöön" #: lib/Horde/Imap/Client/Base.php:1899 lib/Horde/Imap/Client/Base.php:1958 msgid "Cannot expunge read-only mailbox." msgstr "" "Ei voida tyhjentää poistetuja vain lukuun tarkoitetusta postilaatikosta." #: lib/Horde/Imap/Client/Socket.php:4165 msgid "Charset used in search query is not supported on the mail server." msgstr "Palvelin ei tue haussa käytettyä merkistöä." #: lib/Horde/Imap/Client/Socket.php:931 #, php-format msgid "Could not open mailbox \"%s\"." msgstr "Ei voitu aukaista postilaatikkoa \"%s\"." #: lib/Horde/Imap/Client/Socket.php:335 msgid "Could not open secure TLS connection to the IMAP server." msgstr "Ei voitu aukaista salattua TLS-yhteyttä IMAP-palvelimelle." #: lib/Horde/Imap/Client/Socket/Pop3.php:189 #: lib/Horde/Imap/Client/Socket/Pop3.php:201 msgid "Could not open secure connection to the POP3 server." msgstr "Ei voitu aukaista salattua yhteyttä POP3-palvelimelle" #: lib/Horde/Imap/Client/Socket.php:4265 msgid "Could not save message data because it is too large." msgstr "Liian suuren tietomäärän takia viestin tietoja ei voitu talentaa." #: lib/Horde/Imap/Client/Socket.php:4256 msgid "Could not save message on server." msgstr "Viestiä ei voi tallentaa palvelimelle." #: lib/Horde/Imap/Client/Socket/Pop3.php:280 msgid "Error connecting to POP3 server." msgstr "Virhetilanne yhdistettäessä POP3-palvelimelle." #: lib/Horde/Imap/Client/Socket.php:504 msgid "Error connecting to mail server." msgstr "Virhetilanne yhdistettäessä postipalvelimelle." #: lib/Horde/Imap/Client/Utf7imap.php:117 #: lib/Horde/Imap/Client/Utf7imap.php:142 #: lib/Horde/Imap/Client/Utf7imap.php:146 #: lib/Horde/Imap/Client/Utf7imap.php:205 #: lib/Horde/Imap/Client/Utf7imap.php:222 #: lib/Horde/Imap/Client/Utf7imap.php:226 #: lib/Horde/Imap/Client/Utf7imap.php:234 #: lib/Horde/Imap/Client/Utf7imap.php:240 msgid "Error converting UTF7-IMAP string." msgstr "Virhetilanne muunnettaessa UTF7-IMAP merkkijonoa." #: lib/Horde/Imap/Client/Socket.php:3683 lib/Horde/Imap/Client/Socket.php:3964 msgid "Error when communicating with the mail server." msgstr "Virhetilanne liikennöinnissä postipalvelimelle. " #: lib/Horde/Imap/Client/Socket.php:3838 msgid "IMAP Server closed the connection." msgstr "IMAP-palvelin sulki yhteyden." #: lib/Horde/Imap/Client/Socket.php:3823 lib/Horde/Imap/Client/Socket.php:3854 msgid "IMAP error reported by server." msgstr "IMAP-palvelimen antama virhe." #: lib/Horde/Imap/Client/Socket.php:3389 #, php-format msgid "Invalid METADATA entry: \"%s\"." msgstr "Epäkelpo METADATA tieto: \"%s\"." #: lib/Horde/Imap/Client/Socket.php:3476 #, php-format msgid "Invalid METADATA value type \"%s\"." msgstr "Epäkelpo METADATA arvotyyppi: \"%s\"." #: lib/Horde/Imap/Client/Socket.php:3890 msgid "Mail server closed the connection unexpectedly." msgstr "Postipalvelin sulki yhteyden odottamatta." #: lib/Horde/Imap/Client/Socket.php:395 msgid "Mail server denied authentication." msgstr "Postipalvelin esti autentikoinnin." #: lib/Horde/Imap/Client/Socket.php:1812 lib/Horde/Imap/Client/Socket.php:2483 #: lib/Horde/Imap/Client/Socket.php:2504 lib/Horde/Imap/Client/Socket.php:2933 #: lib/Horde/Imap/Client/Socket.php:2988 msgid "Mailbox does not support mod-sequences." msgstr "Postilaatikko ei tue mod-sequences -piirrettä." #: lib/Horde/Imap/Client/Socket.php:378 msgid "No supported IMAP authentication method could be found." msgstr "Tuettua IMAP-autentikointitapaa ei löytynyt." #: lib/Horde/Imap/Client/Socket.php:4388 msgid "Operation failed due to a lack of a secure connection." msgstr "Toiminto epäonnistui salatut yhteydet eivät ole käytettävissä." #: lib/Horde/Imap/Client/Socket/Pop3.php:1096 msgid "POP3 Server closed the connection unexpectedly." msgstr "POP3-palvelin katkaisi yhteyden yllättäen." #: lib/Horde/Imap/Client/Socket/Pop3.php:1156 msgid "POP3 error reported by server." msgstr "POP3-palvelimen antama virhe." #: lib/Horde/Imap/Client/Socket/Pop3.php:240 msgid "POP3 server denied authentication." msgstr "POP3-palvelin esti autentikoinnin." #: lib/Horde/Imap/Client/Socket.php:4356 msgid "Remote server is temporarily unavailable." msgstr "Etäpalvelin on väliakaisesti saavuttamattomissa." #: lib/Horde/Imap/Client/Socket.php:323 msgid "Server does not support TLS connections." msgstr "Palvelin ei tue TLS-yhteyksiä." #: lib/Horde/Imap/Client/Socket/Pop3.php:189 msgid "Server does not support secure connections." msgstr "Palvelin ei tue salattuja yhteyksiä." #: lib/Horde/Imap/Client/Socket.php:527 msgid "Server rejected connection." msgstr "Palvelin hylkäsi yhteyden." #: lib/Horde/Imap/Client/Socket.php:3748 msgid "Server write error." msgstr "Palvelimen kirjoitusvirhe." #: lib/Horde/Imap/Client/Socket.php:4309 msgid "The comparison algorithm was not recognized by the server." msgstr "Palvelin ei tunnista vertailualgoritmiä." #: lib/Horde/Imap/Client/Socket.php:536 msgid "The mail server does not support IMAP4rev1 (RFC 3501)." msgstr "Postipalvelin ei tue toimintoa IMAP4rev1 (RFC 3501)." #: lib/Horde/Imap/Client/Socket.php:4435 msgid "The mail server has denied the request." msgstr "Postipalvelin esti pyynnön." #: lib/Horde/Imap/Client/Socket.php:4419 msgid "The mail server is reporting corrupt data in your mailbox." msgstr "" "Postipalvelin raportoi, että postilaatikossa on korruptoituneita tietoja." #: lib/Horde/Imap/Client/Socket.php:4177 lib/Horde/Imap/Client/Socket.php:4222 msgid "The mail server was unable to parse the contents of the mail message." msgstr "Postipalvelin ei pystynyt käsittelemään viestin tietoja." #: lib/Horde/Imap/Client/Socket.php:4327 msgid "The metadata item could not be saved because it is too large." msgstr "Metadata tietoja ei voitu tallentaa, koska se oli liian suuri." #: lib/Horde/Imap/Client/Socket.php:4345 msgid "" "The metadata item could not be saved because the maximum number of " "annotations has been exceeded." msgstr "" "Metadata tietoa ei voi tallentaa, koska lisätietojen suurin sallittu määrä " "on ylittynyt." #: lib/Horde/Imap/Client/Socket.php:4336 msgid "" "The metadata item could not be saved because the server does not support " "private annotations." msgstr "" "Metadata tietoja ei voitu tallentaa, koska palvelin ei tue yksilökohtaisten " "lisätietojen tallennusta." #: lib/Horde/Imap/Client/Socket.php:4453 msgid "The object could not be created because it already exists." msgstr "Objektia ei voitu luoda, koska se on jo olemassa." #: lib/Horde/Imap/Client/Socket.php:4462 msgid "The object could not be deleted because it does not exist." msgstr "Objektia ei voitu poistaa, koska sitä ei ole olemassa." #: lib/Horde/Imap/Client/Socket.php:4444 msgid "" "The operation failed because the quota has been exceeded on the mail server." msgstr "Operaatio epäonnistui, koska kiintiö on ylittynyt postipalvelimella." #: lib/Horde/Imap/Client/Exception/NoSupportExtension.php:36 #, php-format msgid "The server does not support the %s extension." msgstr "Palvelin ei tue laajennusta %s." #: lib/Horde/Imap/Client/Socket.php:4471 msgid "The special-use attribute requested for the mailbox is not supported." msgstr "Postilaatikon erikoiskäyttö atribuutti ei ole tuettu." #: lib/Horde/Imap/Client/Socket.php:4405 msgid "" "There was a temporary issue when attempting this operation. Please try again " "later." msgstr "" "Väliaikainen ongelmatilanne yritettäessä tätä operaatiota. Yritä myöhemmin " "uudestaan." #: lib/Horde/Imap/Client/Socket.php:604 #: lib/Horde/Imap/Client/Socket/Pop3.php:334 msgid "Unexpected response from server when authenticating." msgstr "Odottamaton vastaus palvelimelta autentikoinnin aikana." #: lib/Horde/Imap/Client/Socket.php:648 #: lib/Horde/Imap/Client/Socket/Pop3.php:374 #, php-format msgid "Unknown authentication method: %s" msgstr "Tuntematon autentikointimetori: %s" #: lib/Horde/Imap/Client/Socket.php:4396 msgid "You do not have adequate permissions to carry out this operation." msgstr "Sinulla ei ole riittäviä oikeuksia tämän toiminnon suorittamiseen." Horde_Imap_Client-2.29.15/locale/fr/LC_MESSAGES/Horde_Imap_Client.mo0000664000175000017500000001564213150761653022617 0ustar janjan6I|!(8T/i!A84S4!  "!.D"s!/"%'H7p6/ ". )Q ({ +   : 6; 'r : E H =d a ] :b : L -% ES S 4 !"AD-N|5H5Y`-77V14'0'N6v&%$D;-4>;";^(3.7B"z"A>/ARqPQ>g^g1m4G+DHdB/5<e*5',3$ # .4 ")+/!0  &1-%6 (2%s not supported on POP3 servers.Authentication credentials have expired.Authentication failed.Authentication failure.Authentication was successful, but authorization failed.Bad tagged response.Cannot convert search query text to new charsetCannot expunge read-only mailbox.Charset used in search query is not supported on the mail server.Could not open mailbox "%s".Could not open secure TLS connection to the IMAP server.Could not open secure connection to the POP3 server.Could not save message data because it is too large.Could not save message on server.Error connecting to POP3 server.Error connecting to mail server.Error converting UTF7-IMAP string.Error when communicating with the mail server.IMAP Server closed the connection.IMAP error reported by server.Invalid METADATA entry: "%s".Invalid METADATA value type "%s".Mail server closed the connection unexpectedly.Mail server denied authentication.Mailbox does not support mod-sequences.No supported IMAP authentication method could be found.Operation failed due to a lack of a secure connection.POP3 Server closed the connection unexpectedly.POP3 error reported by server.POP3 server denied authentication.Remote server is temporarily unavailable.Server does not support TLS connections.Server does not support secure connections.Server rejected connection.Server write error.The comparison algorithm was not recognized by the server.The mail server does not support IMAP4rev1 (RFC 3501).The mail server has denied the request.The mail server is reporting corrupt data in your mailbox.The mail server was unable to parse the contents of the mail message.The mail server was unable to parse the contents of the mail message: %sThe metadata item could not be saved because it is too large.The metadata item could not be saved because the maximum number of annotations has been exceeded.The metadata item could not be saved because the server does not support private annotations.The object could not be created because it already exists.The object could not be deleted because it does not exist.The operation failed because the quota has been exceeded on the mail server.The server does not support the %s extension.The special-use attribute requested for the mailbox is not supported.There was a temporary issue when attempting this operation. Please try again later.Unexpected response from server when authenticating.Unknown authentication method: %sYou do not have adequate permissions to carry out this operation.Project-Id-Version: Horde_Imap_Client Report-Msgid-Bugs-To: dev@lists.horde.org POT-Creation-Date: 2013-01-14 09:19+0100 PO-Revision-Date: 2013-01-16 16:26+0100 Last-Translator: Paul De Vlieger Language-Team: French Language: fr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n > 1); X-Generator: Lokalize 1.4 %s n'est pas supporté sur les serveurs POP3.Votre session a expiré.La connexion a échouée.Échec de la connexion.L'authentification a réussi mais pas l'autorisation.Mauvaise réponse.Impossible de convertir la recherche dans le nouveau jeu de caractères.Impossible d'effacer une boite mail en lecture seule.Le jeu de caractères utilisé dans la recherche n'est pas reconnu sur le serveur de messagerie.Impossible d'ouvrir la boite mail « %s ».Échec de la connexion sécurisée TLS au serveur IMAP.Échec de la connexion sécurisée TLS au serveur POP3.Le message est trop grand pour être sauvegardé.Impossible de sauvegarder le message sur le serveur.Échec de la connexion au serveur POP3.Échec de la connexion au serveur de messagerie.Erreur lors de la conversion UTF7-IMAP.Erreur de communication avec le serveur de messagerie.Le serveur IMAP a fermé la connexion.Erreur IMAP sur le serveur.Entrée METADATA invalide: « %s »Valeur METADATA invalide: « %s »Le serveur de messagerie a fermé la connexion de façon inattendue.Le serveur mail a refusé l'authentification.Les boites mail ne supportent pas les mod-sequences.Aucune méthode d'authentification IMAP n'a pu être trouvée.L'opération a échouée : connexion sécurisée manquante.Le serveur POP3 a fermé la connexion de façon inattendue.Erreur POP3 sur le serveur.Le serveur a refusé l'authentification.Le serveur distant est temporairement indisponible.Le serveur ne supporte pas les connexions TLS.Le serveur ne supporte pas les connexions sécurisées.Le serveur a rejeté la connexion.Erreur d'écriture sur le serveur.L'algorithme de comparaison n'a pas été reconnu par le serveur.Le serveur de messagerie ne supporte pas IMAP4rev1 (RFC 3501).Le serveur de messagerie a refusé la requête.Le serveur de messagerie signale une corruption de données dans votre boite mail.Le serveur de messagerie n'a pas réussi à récupérer le contenu des messages.Le serveur de messagerie n'a pas réussi à récupérer le contenu du message: %sLes méta-données sont trop grandes pour être sauvegardées.La méta-donnée n'a pas pu être enregistrée car le maximum d'annotations a été dépassé.La méta-donnée n'a pas pu être enregistrée car le serveur ne supporte pas les annotations privées.L'objet ne peut être crée car il existe déjà.L'objet ne peut être supprimé car il n'existe pas.L'opération a échouée car le quota a été dépassé sur ce serveur.Le serveur ne supporte pas l'extension: %s.L'attribut spécial demandé pour la boite mail n'est pas supporté.Il y a eu une erreur temporaire en essayant d'effectuer cette action. Veuillez réessayer plus tard.Réponse inattendue du serveur distant lors de l'authentification.La méthode d'authentification %s est inconnue.Vous n'avez pas l'autorisation d'effectuer cette opération.Horde_Imap_Client-2.29.15/locale/fr/LC_MESSAGES/Horde_Imap_Client.po0000664000175000017500000002407613150761653022623 0ustar janjan# French translations for Horde_Imap_Client package. # Copyright (C) 2013 Horde LLC (http://www.horde.org/) # This file is distributed under the same license as the Horde_Imap_Client package. # # Paul De Vlieger , 2013 msgid "" msgstr "" "Project-Id-Version: Horde_Imap_Client \n" "Report-Msgid-Bugs-To: dev@lists.horde.org\n" "POT-Creation-Date: 2013-01-14 09:19+0100\n" "PO-Revision-Date: 2013-01-16 16:26+0100\n" "Last-Translator: Paul De Vlieger \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Generator: Lokalize 1.4\n" #: lib/Horde/Imap/Client/Exception/NoSupportPop3.php:33 #, php-format msgid "%s not supported on POP3 servers." msgstr "%s n'est pas supporté sur les serveurs POP3." #: lib/Horde/Imap/Client/Socket.php:4419 msgid "Authentication credentials have expired." msgstr "Votre session a expiré." #: lib/Horde/Imap/Client/Socket.php:4403 msgid "Authentication failed." msgstr "La connexion a échouée." #: lib/Horde/Imap/Client/Auth/DigestMD5.php:157 msgid "Authentication failure." msgstr "Échec de la connexion." #: lib/Horde/Imap/Client/Socket.php:4411 msgid "Authentication was successful, but authorization failed." msgstr "L'authentification a réussi mais pas l'autorisation." #: lib/Horde/Imap/Client/Interaction/Server/Tagged.php:42 msgid "Bad tagged response." msgstr "Mauvaise réponse." #: lib/Horde/Imap/Client/Exception/SearchCharset.php:44 msgid "Cannot convert search query text to new charset" msgstr "" "Impossible de convertir la recherche dans le nouveau jeu de caractères." #: lib/Horde/Imap/Client/Base.php:1900 lib/Horde/Imap/Client/Base.php:1959 msgid "Cannot expunge read-only mailbox." msgstr "Impossible d'effacer une boite mail en lecture seule." #: lib/Horde/Imap/Client/Socket.php:4198 msgid "Charset used in search query is not supported on the mail server." msgstr "" "Le jeu de caractères utilisé dans la recherche n'est pas reconnu sur le " "serveur de messagerie." #: lib/Horde/Imap/Client/Socket.php:950 #, php-format msgid "Could not open mailbox \"%s\"." msgstr "Impossible d'ouvrir la boite mail « %s »." #: lib/Horde/Imap/Client/Socket.php:357 msgid "Could not open secure TLS connection to the IMAP server." msgstr "Échec de la connexion sécurisée TLS au serveur IMAP." #: lib/Horde/Imap/Client/Socket/Pop3.php:200 #: lib/Horde/Imap/Client/Socket/Pop3.php:212 msgid "Could not open secure connection to the POP3 server." msgstr "Échec de la connexion sécurisée TLS au serveur POP3." #: lib/Horde/Imap/Client/Socket.php:4304 msgid "Could not save message data because it is too large." msgstr "Le message est trop grand pour être sauvegardé." #: lib/Horde/Imap/Client/Socket.php:4295 msgid "Could not save message on server." msgstr "Impossible de sauvegarder le message sur le serveur." #: lib/Horde/Imap/Client/Socket/Pop3.php:291 msgid "Error connecting to POP3 server." msgstr "Échec de la connexion au serveur POP3." #: lib/Horde/Imap/Client/Socket.php:526 msgid "Error connecting to mail server." msgstr "Échec de la connexion au serveur de messagerie." #: lib/Horde/Imap/Client/Utf7imap.php:127 #: lib/Horde/Imap/Client/Utf7imap.php:152 #: lib/Horde/Imap/Client/Utf7imap.php:156 #: lib/Horde/Imap/Client/Utf7imap.php:215 #: lib/Horde/Imap/Client/Utf7imap.php:232 #: lib/Horde/Imap/Client/Utf7imap.php:236 #: lib/Horde/Imap/Client/Utf7imap.php:244 #: lib/Horde/Imap/Client/Utf7imap.php:250 msgid "Error converting UTF7-IMAP string." msgstr "Erreur lors de la conversion UTF7-IMAP." #: lib/Horde/Imap/Client/Socket.php:3736 lib/Horde/Imap/Client/Socket.php:4012 msgid "Error when communicating with the mail server." msgstr "Erreur de communication avec le serveur de messagerie." #: lib/Horde/Imap/Client/Socket.php:3891 msgid "IMAP Server closed the connection." msgstr "Le serveur IMAP a fermé la connexion." #: lib/Horde/Imap/Client/Socket.php:3876 lib/Horde/Imap/Client/Socket.php:3907 msgid "IMAP error reported by server." msgstr "Erreur IMAP sur le serveur." #: lib/Horde/Imap/Client/Socket.php:3460 #, php-format msgid "Invalid METADATA entry: \"%s\"." msgstr "Entrée METADATA invalide: « %s »" #: lib/Horde/Imap/Client/Socket.php:3545 #, php-format msgid "Invalid METADATA value type \"%s\"." msgstr "Valeur METADATA invalide: « %s »" #: lib/Horde/Imap/Client/Socket.php:3943 msgid "Mail server closed the connection unexpectedly." msgstr "Le serveur de messagerie a fermé la connexion de façon inattendue." #: lib/Horde/Imap/Client/Socket.php:417 msgid "Mail server denied authentication." msgstr "Le serveur mail a refusé l'authentification." #: lib/Horde/Imap/Client/Socket.php:1867 lib/Horde/Imap/Client/Socket.php:2536 #: lib/Horde/Imap/Client/Socket.php:2557 lib/Horde/Imap/Client/Socket.php:3001 #: lib/Horde/Imap/Client/Socket.php:3057 msgid "Mailbox does not support mod-sequences." msgstr "Les boites mail ne supportent pas les mod-sequences." #: lib/Horde/Imap/Client/Socket.php:400 msgid "No supported IMAP authentication method could be found." msgstr "Aucune méthode d'authentification IMAP n'a pu être trouvée." #: lib/Horde/Imap/Client/Socket.php:4427 msgid "Operation failed due to a lack of a secure connection." msgstr "L'opération a échouée : connexion sécurisée manquante." #: lib/Horde/Imap/Client/Socket/Pop3.php:1107 msgid "POP3 Server closed the connection unexpectedly." msgstr "Le serveur POP3 a fermé la connexion de façon inattendue." #: lib/Horde/Imap/Client/Socket/Pop3.php:1175 msgid "POP3 error reported by server." msgstr "Erreur POP3 sur le serveur." #: lib/Horde/Imap/Client/Socket/Pop3.php:251 msgid "POP3 server denied authentication." msgstr "Le serveur a refusé l'authentification." #: lib/Horde/Imap/Client/Socket.php:4395 msgid "Remote server is temporarily unavailable." msgstr "Le serveur distant est temporairement indisponible." #: lib/Horde/Imap/Client/Socket.php:345 msgid "Server does not support TLS connections." msgstr "Le serveur ne supporte pas les connexions TLS." #: lib/Horde/Imap/Client/Socket/Pop3.php:200 msgid "Server does not support secure connections." msgstr "Le serveur ne supporte pas les connexions sécurisées." #: lib/Horde/Imap/Client/Socket.php:549 msgid "Server rejected connection." msgstr "Le serveur a rejeté la connexion." #: lib/Horde/Imap/Client/Socket.php:3801 msgid "Server write error." msgstr "Erreur d'écriture sur le serveur." #: lib/Horde/Imap/Client/Socket.php:4348 msgid "The comparison algorithm was not recognized by the server." msgstr "L'algorithme de comparaison n'a pas été reconnu par le serveur." #: lib/Horde/Imap/Client/Socket.php:558 msgid "The mail server does not support IMAP4rev1 (RFC 3501)." msgstr "Le serveur de messagerie ne supporte pas IMAP4rev1 (RFC 3501)." #: lib/Horde/Imap/Client/Socket.php:4474 msgid "The mail server has denied the request." msgstr "Le serveur de messagerie a refusé la requête." #: lib/Horde/Imap/Client/Socket.php:4458 msgid "The mail server is reporting corrupt data in your mailbox." msgstr "" "Le serveur de messagerie signale une corruption de données dans votre boite " "mail." #: lib/Horde/Imap/Client/Socket.php:4261 msgid "The mail server was unable to parse the contents of the mail message." msgstr "" "Le serveur de messagerie n'a pas réussi à récupérer le contenu des messages." #: lib/Horde/Imap/Client/Socket.php:4214 #, php-format msgid "" "The mail server was unable to parse the contents of the mail message: %s" msgstr "" "Le serveur de messagerie n'a pas réussi à récupérer le contenu du message: %s" #: lib/Horde/Imap/Client/Socket.php:4366 msgid "The metadata item could not be saved because it is too large." msgstr "Les méta-données sont trop grandes pour être sauvegardées." #: lib/Horde/Imap/Client/Socket.php:4384 msgid "" "The metadata item could not be saved because the maximum number of " "annotations has been exceeded." msgstr "" "La méta-donnée n'a pas pu être enregistrée car le maximum d'annotations a " "été dépassé." #: lib/Horde/Imap/Client/Socket.php:4375 msgid "" "The metadata item could not be saved because the server does not support " "private annotations." msgstr "" "La méta-donnée n'a pas pu être enregistrée car le serveur ne supporte pas " "les annotations privées." #: lib/Horde/Imap/Client/Socket.php:4492 msgid "The object could not be created because it already exists." msgstr "L'objet ne peut être crée car il existe déjà." #: lib/Horde/Imap/Client/Socket.php:4501 msgid "The object could not be deleted because it does not exist." msgstr "L'objet ne peut être supprimé car il n'existe pas." #: lib/Horde/Imap/Client/Socket.php:4483 msgid "" "The operation failed because the quota has been exceeded on the mail server." msgstr "L'opération a échouée car le quota a été dépassé sur ce serveur." #: lib/Horde/Imap/Client/Exception/NoSupportExtension.php:44 #, php-format msgid "The server does not support the %s extension." msgstr "Le serveur ne supporte pas l'extension: %s." #: lib/Horde/Imap/Client/Socket.php:4510 msgid "The special-use attribute requested for the mailbox is not supported." msgstr "L'attribut spécial demandé pour la boite mail n'est pas supporté." #: lib/Horde/Imap/Client/Socket.php:4444 msgid "" "There was a temporary issue when attempting this operation. Please try again " "later." msgstr "" "Il y a eu une erreur temporaire en essayant d'effectuer cette action. " "Veuillez réessayer plus tard." #: lib/Horde/Imap/Client/Socket.php:626 #: lib/Horde/Imap/Client/Socket/Pop3.php:345 msgid "Unexpected response from server when authenticating." msgstr "Réponse inattendue du serveur distant lors de l'authentification." #: lib/Horde/Imap/Client/Socket.php:670 #: lib/Horde/Imap/Client/Socket/Pop3.php:385 #, php-format msgid "Unknown authentication method: %s" msgstr "La méthode d'authentification %s est inconnue." #: lib/Horde/Imap/Client/Socket.php:4435 msgid "You do not have adequate permissions to carry out this operation." msgstr "Vous n'avez pas l'autorisation d'effectuer cette opération." Horde_Imap_Client-2.29.15/locale/hu/LC_MESSAGES/Horde_Imap_Client.mo0000664000175000017500000001512613150761653022621 0ustar janjan5Gl!(8</Q!A84;4p! ". ":]|!/"'776o")* (= +f   : 6 '4 :\ E H =& ad ] :$ :_ L - E S[ 4 ! AH%!=@]>2Q rJI0',X1)4'>"]$6/* B7Gz+* -7'e0*;4?,t825 ?C[]?=7}c-%GPm@'.'.,$/ 3(  "4 '*-!0)+1%2#5 &%s not supported on POP3 servers.Authentication credentials have expired.Authentication failed.Authentication failure.Authentication was successful, but authorization failed.Bad tagged response.Cannot convert search query text to new charsetCannot expunge read-only mailbox.Charset used in search query is not supported on the mail server.Could not open mailbox "%s".Could not open secure TLS connection to the IMAP server.Could not open secure connection to the POP3 server.Could not save message data because it is too large.Could not save message on server.Error connecting to mail server.Error converting UTF7-IMAP string.Error when communicating with the mail server.IMAP Server closed the connection.IMAP error reported by server.Invalid METADATA entry: "%s".Invalid METADATA value type "%s".Mail server closed the connection unexpectedly.Mail server denied authentication.Mailbox does not support mod-sequences.No supported IMAP authentication method could be found.Operation failed due to a lack of a secure connection.POP3 error reported by server.POP3 server denied authentication.Remote server is temporarily unavailable.Server closed the connection unexpectedly.Server does not support TLS connections.Server does not support secure connections.Server rejected connection.Server write error.The comparison algorithm was not recognized by the server.The mail server does not support IMAP4rev1 (RFC 3501).The mail server has denied the request.The mail server is reporting corrupt data in your mailbox.The mail server was unable to parse the contents of the mail message.The mail server was unable to parse the contents of the mail message: %sThe metadata item could not be saved because it is too large.The metadata item could not be saved because the maximum number of annotations has been exceeded.The metadata item could not be saved because the server does not support private annotations.The object could not be created because it already exists.The object could not be deleted because it does not exist.The operation failed because the quota has been exceeded on the mail server.The server does not support the %s extension.The special-use attribute requested for the mailbox is not supported.There was a temporary issue when attempting this operation. Please try again later.Unexpected response from server when authenticating.Unknown authentication method: %sYou do not have adequate permissions to carry out this operation.Project-Id-Version: Horde_Imap_Client Report-Msgid-Bugs-To: dev@lists.horde.org POT-Creation-Date: 2014-03-07 12:17+0100 PO-Revision-Date: 2014-05-05 17:32+0200 Last-Translator: Andras Galos Language-Team: i18n@lists.horde.org Language: hu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); A %s nem támogatott POP3 szerverekenBejelentkezési adatok elavultak.A bejelentkezés nem sikerült.A bejelentkezés nem sikerült.A bejelentkezés sikerült, de a hozzáférés meg lett tagadva.Hibás válasz.A keresés új karakterkészletbe konvertálása nem sikerültA csak olvasható mappa tiszítása nem sikerült.A keresésben használt karakterkódolás nem használható a levelezőszerveren.A "%s" mappa nem nyitható meg.Nem sikerült biztonságos TLS kapcsolat létrehozása az IMAP szerverhez.Nem sikerült biztonságos TLS kapcsolat létrehozása a POP3 szerverhez.A levél nem jelenlíthető meg, mert túl nagy.A levél mentése a szerverre nem sikerült.Nem sikerült a levelezőszerverhez kapcsolódni.Az UTF7-IMAP konvertálás nem sikerült.Hiba történt a szerverrel való kommunikációban.Az IMAP szerver lezárta a kapcsolatot.IMAP hibát jelzett a szerver.Érvénytelen METADATA elem: "%s".Érvénytelen METADATA típus: "%s".A levelezőszerver váratlanul lezárta a kapcsolatot.A levelezőszerver megtagadta a hozzáférést.A mappa nem támogatja ezt: mod-sequences.Nem sikerült támogatott IMAP bejelentkezősi módszert találni.A művelet végrehajtása biztonságos kapcsolat híján nem sikerült.A szerver POP3 hibát jelzettA POP3 szerver megtagadta a hozzáférést.A távoli szerver jelenleg nem elérhető.A szerver váratlanul lezárta a kapcsolatot.A szerver nem támogat TLS kapcsolatot.A szerver nem támogat biztonságos kapcsolatot.A szerver visszautasította a kapcsolatot.Írási hiba a szerveren.A szerver nem ismerte fel az összehasonlító algoritmust.Az IMAP4rev1 (RFC 3501) nem támogatott a szerveren.A levelezőszerver elutasította a kérést.A levelező szerver hibás adatot jelen a postafiókban.A levelező szerver nem tudta a levelet beolvasni.A levelező szerver nem tudta a levelet beolvasni: %sA metaadatok mentése nem sikerült, mert túl nagy méretűek.A metaadatok mentése nem sikerült, mert túlléptük a megjegyzések maximális számát.A metaadatok mentése nem sikerült, mert a szerver nem támogatja a privát megjegyzéseket.Az objektum létrehozása nem sikerült, mert az már létezik.Az elem nem létezik, ezért a törlése nem sikerült.A művelet végrehajtása nem sikerült, mert túlléptük a rendelkezésre álló kvóta méretet.A szerver nem támogatja a %s kiterjesztést.Az egyedi paraméter nem támogatott.Hiba történt a művelet végrehajtása során. Kérem próbálja meg később.Váratlan válasz a távoli szervertőt a bejelentkezés során.Ismeretlen bejelentkezési módszer: %sÖn nem jogosult a művelet végrehajtására.Horde_Imap_Client-2.29.15/locale/hu/LC_MESSAGES/Horde_Imap_Client.po0000664000175000017500000002337713150761653022633 0ustar janjan# Hungarian translations for Horde_Imap_Client package. # Copyright (C) 2014 Horde LLC (http://www.horde.org/) # This file is distributed under the same license as the Horde_Imap_Client package. # msgid "" msgstr "" "Project-Id-Version: Horde_Imap_Client \n" "Report-Msgid-Bugs-To: dev@lists.horde.org\n" "POT-Creation-Date: 2014-03-07 12:17+0100\n" "PO-Revision-Date: 2014-05-05 17:32+0200\n" "Last-Translator: Andras Galos \n" "Language-Team: i18n@lists.horde.org\n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: lib/Horde/Imap/Client/Exception/NoSupportPop3.php:33 msgid "%s not supported on POP3 servers." msgstr "A %s nem támogatott POP3 szervereken" #: lib/Horde/Imap/Client/Socket.php:4622 msgid "Authentication credentials have expired." msgstr "Bejelentkezési adatok elavultak." #: lib/Horde/Imap/Client/Socket.php:4606 msgid "Authentication failed." msgstr "A bejelentkezés nem sikerült." #: lib/Horde/Imap/Client/Auth/DigestMD5.php:157 msgid "Authentication failure." msgstr "A bejelentkezés nem sikerült." #: lib/Horde/Imap/Client/Socket.php:4614 msgid "Authentication was successful, but authorization failed." msgstr "A bejelentkezés sikerült, de a hozzáférés meg lett tagadva." #: lib/Horde/Imap/Client/Interaction/Server/Tagged.php:42 msgid "Bad tagged response." msgstr "Hibás válasz." #: lib/Horde/Imap/Client/Exception/SearchCharset.php:44 msgid "Cannot convert search query text to new charset" msgstr "A keresés új karakterkészletbe konvertálása nem sikerült" #: lib/Horde/Imap/Client/Base.php:2032 lib/Horde/Imap/Client/Base.php:2095 msgid "Cannot expunge read-only mailbox." msgstr "A csak olvasható mappa tiszítása nem sikerült." #: lib/Horde/Imap/Client/Socket.php:4400 msgid "Charset used in search query is not supported on the mail server." msgstr "" "A keresésben használt karakterkódolás nem használható a levelezőszerveren." #: lib/Horde/Imap/Client/Socket.php:1076 msgid "Could not open mailbox \"%s\"." msgstr "A \"%s\" mappa nem nyitható meg." #: lib/Horde/Imap/Client/Socket.php:393 msgid "Could not open secure TLS connection to the IMAP server." msgstr "Nem sikerült biztonságos TLS kapcsolat létrehozása az IMAP szerverhez." #: lib/Horde/Imap/Client/Socket/Pop3.php:194 #: lib/Horde/Imap/Client/Socket/Pop3.php:208 msgid "Could not open secure connection to the POP3 server." msgstr "Nem sikerült biztonságos TLS kapcsolat létrehozása a POP3 szerverhez." #: lib/Horde/Imap/Client/Socket.php:4506 msgid "Could not save message data because it is too large." msgstr "A levél nem jelenlíthető meg, mert túl nagy." #: lib/Horde/Imap/Client/Socket.php:4497 msgid "Could not save message on server." msgstr "A levél mentése a szerverre nem sikerült." #: lib/Horde/Imap/Client/Socket.php:573 #: lib/Horde/Imap/Client/Socket/Pop3.php:284 msgid "Error connecting to mail server." msgstr "Nem sikerült a levelezőszerverhez kapcsolódni." #: lib/Horde/Imap/Client/Utf7imap.php:127 #: lib/Horde/Imap/Client/Utf7imap.php:152 #: lib/Horde/Imap/Client/Utf7imap.php:156 #: lib/Horde/Imap/Client/Utf7imap.php:215 #: lib/Horde/Imap/Client/Utf7imap.php:232 #: lib/Horde/Imap/Client/Utf7imap.php:236 #: lib/Horde/Imap/Client/Utf7imap.php:244 #: lib/Horde/Imap/Client/Utf7imap.php:250 msgid "Error converting UTF7-IMAP string." msgstr "Az UTF7-IMAP konvertálás nem sikerült." #: lib/Horde/Imap/Client/Socket.php:4075 #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:70 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:179 #: lib/Horde/Imap/Client/Socket/Pop3.php:1177 msgid "Error when communicating with the mail server." msgstr "Hiba történt a szerverrel való kommunikációban." #: lib/Horde/Imap/Client/Socket.php:4187 msgid "IMAP Server closed the connection." msgstr "Az IMAP szerver lezárta a kapcsolatot." #: lib/Horde/Imap/Client/Socket.php:4173 msgid "IMAP error reported by server." msgstr "IMAP hibát jelzett a szerver." #: lib/Horde/Imap/Client/Socket.php:3682 msgid "Invalid METADATA entry: \"%s\"." msgstr "Érvénytelen METADATA elem: \"%s\"." #: lib/Horde/Imap/Client/Socket.php:3769 msgid "Invalid METADATA value type \"%s\"." msgstr "Érvénytelen METADATA típus: \"%s\"." #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:120 msgid "Mail server closed the connection unexpectedly." msgstr "A levelezőszerver váratlanul lezárta a kapcsolatot." #: lib/Horde/Imap/Client/Socket.php:541 msgid "Mail server denied authentication." msgstr "A levelezőszerver megtagadta a hozzáférést." #: lib/Horde/Imap/Client/Base.php:2365 lib/Horde/Imap/Client/Base.php:2685 #: lib/Horde/Imap/Client/Base.php:2950 lib/Horde/Imap/Client/Base.php:3035 msgid "Mailbox does not support mod-sequences." msgstr "A mappa nem támogatja ezt: mod-sequences." #: lib/Horde/Imap/Client/Socket.php:469 msgid "No supported IMAP authentication method could be found." msgstr "Nem sikerült támogatott IMAP bejelentkezősi módszert találni." #: lib/Horde/Imap/Client/Socket.php:4630 msgid "Operation failed due to a lack of a secure connection." msgstr "A művelet végrehajtása biztonságos kapcsolat híján nem sikerült." #: lib/Horde/Imap/Client/Socket/Pop3.php:1236 msgid "POP3 error reported by server." msgstr "A szerver POP3 hibát jelzett" #: lib/Horde/Imap/Client/Socket/Pop3.php:253 msgid "POP3 server denied authentication." msgstr "A POP3 szerver megtagadta a hozzáférést." #: lib/Horde/Imap/Client/Socket.php:4598 msgid "Remote server is temporarily unavailable." msgstr "A távoli szerver jelenleg nem elérhető." #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:62 msgid "Server closed the connection unexpectedly." msgstr "A szerver váratlanul lezárta a kapcsolatot." #: lib/Horde/Imap/Client/Socket.php:381 msgid "Server does not support TLS connections." msgstr "A szerver nem támogat TLS kapcsolatot." #: lib/Horde/Imap/Client/Socket/Pop3.php:194 msgid "Server does not support secure connections." msgstr "A szerver nem támogat biztonságos kapcsolatot." #: lib/Horde/Imap/Client/Socket.php:593 msgid "Server rejected connection." msgstr "A szerver visszautasította a kapcsolatot." #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:41 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:53 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:86 msgid "Server write error." msgstr "Írási hiba a szerveren." #: lib/Horde/Imap/Client/Socket.php:4551 msgid "The comparison algorithm was not recognized by the server." msgstr "A szerver nem ismerte fel az összehasonlító algoritmust." #: lib/Horde/Imap/Client/Socket.php:602 msgid "The mail server does not support IMAP4rev1 (RFC 3501)." msgstr "Az IMAP4rev1 (RFC 3501) nem támogatott a szerveren." #: lib/Horde/Imap/Client/Socket.php:4677 msgid "The mail server has denied the request." msgstr "A levelezőszerver elutasította a kérést." #: lib/Horde/Imap/Client/Socket.php:4661 msgid "The mail server is reporting corrupt data in your mailbox." msgstr "A levelező szerver hibás adatot jelen a postafiókban." #: lib/Horde/Imap/Client/Socket.php:4463 msgid "The mail server was unable to parse the contents of the mail message." msgstr "A levelező szerver nem tudta a levelet beolvasni." #: lib/Horde/Imap/Client/Socket.php:4416 msgid "" "The mail server was unable to parse the contents of the mail message: %s" msgstr "A levelező szerver nem tudta a levelet beolvasni: %s" #: lib/Horde/Imap/Client/Socket.php:4569 msgid "The metadata item could not be saved because it is too large." msgstr "A metaadatok mentése nem sikerült, mert túl nagy méretűek." #: lib/Horde/Imap/Client/Socket.php:4587 msgid "" "The metadata item could not be saved because the maximum number of " "annotations has been exceeded." msgstr "" "A metaadatok mentése nem sikerült, mert túlléptük a megjegyzések maximális " "számát." #: lib/Horde/Imap/Client/Socket.php:4578 msgid "" "The metadata item could not be saved because the server does not support " "private annotations." msgstr "" "A metaadatok mentése nem sikerült, mert a szerver nem támogatja a privát " "megjegyzéseket." #: lib/Horde/Imap/Client/Socket.php:4695 msgid "The object could not be created because it already exists." msgstr "Az objektum létrehozása nem sikerült, mert az már létezik." #: lib/Horde/Imap/Client/Socket.php:4704 msgid "The object could not be deleted because it does not exist." msgstr "Az elem nem létezik, ezért a törlése nem sikerült." #: lib/Horde/Imap/Client/Socket.php:4686 msgid "" "The operation failed because the quota has been exceeded on the mail server." msgstr "" "A művelet végrehajtása nem sikerült, mert túlléptük a rendelkezésre álló " "kvóta méretet." #: lib/Horde/Imap/Client/Exception/NoSupportExtension.php:44 msgid "The server does not support the %s extension." msgstr "A szerver nem támogatja a %s kiterjesztést." #: lib/Horde/Imap/Client/Socket.php:4713 msgid "The special-use attribute requested for the mailbox is not supported." msgstr "Az egyedi paraméter nem támogatott." #: lib/Horde/Imap/Client/Socket.php:4647 msgid "" "There was a temporary issue when attempting this operation. Please try again " "later." msgstr "Hiba történt a művelet végrehajtása során. Kérem próbálja meg később." #: lib/Horde/Imap/Client/Socket.php:691 #: lib/Horde/Imap/Client/Socket/Pop3.php:339 msgid "Unexpected response from server when authenticating." msgstr "Váratlan válasz a távoli szervertőt a bejelentkezés során." #: lib/Horde/Imap/Client/Socket.php:728 #: lib/Horde/Imap/Client/Socket/Pop3.php:385 msgid "Unknown authentication method: %s" msgstr "Ismeretlen bejelentkezési módszer: %s" #: lib/Horde/Imap/Client/Socket.php:4638 msgid "You do not have adequate permissions to carry out this operation." msgstr "Ön nem jogosult a művelet végrehajtására." Horde_Imap_Client-2.29.15/locale/ja/LC_MESSAGES/Horde_Imap_Client.mo0000664000175000017500000001636713150761653022607 0ustar janjan5Gl!(8</Q!A84;4p! ". ":]|!/"'776o")* (= +f   : 6 '4 :\ E H =& ad ] :$ :_ L - E S[ 4 ! AH8*&Qp?BB+`n0FLG?960E0v,1&'-HU3J<BZ3/99;;u?*!H>M3o QySKckuNEK]:>WyZE, rc.,$/ 3(  "4 '*-!0)+1%2#5 &%s not supported on POP3 servers.Authentication credentials have expired.Authentication failed.Authentication failure.Authentication was successful, but authorization failed.Bad tagged response.Cannot convert search query text to new charsetCannot expunge read-only mailbox.Charset used in search query is not supported on the mail server.Could not open mailbox "%s".Could not open secure TLS connection to the IMAP server.Could not open secure connection to the POP3 server.Could not save message data because it is too large.Could not save message on server.Error connecting to mail server.Error converting UTF7-IMAP string.Error when communicating with the mail server.IMAP Server closed the connection.IMAP error reported by server.Invalid METADATA entry: "%s".Invalid METADATA value type "%s".Mail server closed the connection unexpectedly.Mail server denied authentication.Mailbox does not support mod-sequences.No supported IMAP authentication method could be found.Operation failed due to a lack of a secure connection.POP3 error reported by server.POP3 server denied authentication.Remote server is temporarily unavailable.Server closed the connection unexpectedly.Server does not support TLS connections.Server does not support secure connections.Server rejected connection.Server write error.The comparison algorithm was not recognized by the server.The mail server does not support IMAP4rev1 (RFC 3501).The mail server has denied the request.The mail server is reporting corrupt data in your mailbox.The mail server was unable to parse the contents of the mail message.The mail server was unable to parse the contents of the mail message: %sThe metadata item could not be saved because it is too large.The metadata item could not be saved because the maximum number of annotations has been exceeded.The metadata item could not be saved because the server does not support private annotations.The object could not be created because it already exists.The object could not be deleted because it does not exist.The operation failed because the quota has been exceeded on the mail server.The server does not support the %s extension.The special-use attribute requested for the mailbox is not supported.There was a temporary issue when attempting this operation. Please try again later.Unexpected response from server when authenticating.Unknown authentication method: %sYou do not have adequate permissions to carry out this operation.Project-Id-Version: Horde_Imap_Client Report-Msgid-Bugs-To: dev@lists.horde.org POT-Creation-Date: 2014-01-28 00:26-0700 PO-Revision-Date: 2014-02-22 12:49+0900 Last-Translator: Hiromi Kimura Language-Team: i18n@lists.horde.org Language: ja MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=1; plural=0; X-Generator: Poedit 1.6.3 POP3サーバは %s をサポートしていません。認証用証明書は期限切れです。認証に失敗しました。認証できません。認証は成功しましたが、認可に失敗しました。不正なタグ応答です。検索文字列を新しい文字セットに変換できません読み出し専用メールボックスは削除できません。検索文字中の文字セットはメールサーバではサポートされていません。メールボックス "%s" が開けません。IMAPサーバへのTLS接続はオープンできませんでした。POP3サーバへの安全な接続はオープンできませんでした。メッセージが大きすぎるので保存できません。メッセージをサーバーに保存できません。メールサーバへの接続に失敗しました。UTF7-IMAP文字列への変換エラーです。メールサーバとの通信エラーです。IMAP サーバは接続を閉じました。サーバはIMAPエラーを報告しました。不正なメタデータ項目:"%s".不正なメタデータの種類 "%s".メールサーバとの接続が予期せずに切断されました。メールサーバは認証を拒否しました。メールボックスは mod-sequence をサポートしていません。サポートされた IMAP 認証が見つかりません。安全な接続ができないため操作に失敗しました。サーバは POP3 エラーを報告しました。POP3 サーバは認証を拒否しました。リモートサーバは一時的に使用不能です。サーバは接続を予期せずに切断しました。サーバは TLS 接続をサポートしていません。サーバは安全な接続をサポートしていません。サーバは接続を拒絶しました。サーバ書き込みエラー。比較アルゴリズムがサーバで認識されませんでした。メールサーバは IMAP4rev1(RFC3501) をサポートしていません。メールサーバは要求を拒否しました。メールサーバはあなたのメールボックスのデータが壊れていると報告しています。メールサーバはメッセージの内容を解析できませんでした。メールサーバはメッセージの内容を解析できませんでした:%sメタデータが大きすぎたため、保存できませんでした。注釈の最大数を超過しているため、メタデータは保存できませんでした。サーバが私的な注釈をサポートしていないので、メタデータは保存できませんでした。オブジェクトは既に存在するので作成されませんでした。オブジェクトは存在しないので削除できませんでした。メールサーバのクォータを超過しているので、操作は失敗しました。サーバは %s 拡張をサポートしていません。メールボックスの特別な属性の使用はサポートされていません。この操作には一時的な問題がありました。後で再度試して下さい。認証時にサーバから予期しない応答がありました。不明な認証方式です:%sあなたにはこの操作を実行するのに十分なアクセス権を持っていません。Horde_Imap_Client-2.29.15/locale/ja/LC_MESSAGES/Horde_Imap_Client.po0000664000175000017500000002502413150761653022600 0ustar janjan# Japanese translation for Horde. # Copyright (C) 2012-2013 Horde LLC (http://www.horde.org/) # This file is distributed under the same license as the Horde_Imap_Client package. # Hiromi Kimura # msgid "" msgstr "" "Project-Id-Version: Horde_Imap_Client\n" "Report-Msgid-Bugs-To: dev@lists.horde.org\n" "POT-Creation-Date: 2014-01-28 00:26-0700\n" "PO-Revision-Date: 2014-02-22 12:49+0900\n" "Last-Translator: Hiromi Kimura \n" "Language-Team: i18n@lists.horde.org\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Poedit 1.6.3\n" #: lib/Horde/Imap/Client/Exception/NoSupportPop3.php:34 #, php-format msgid "%s not supported on POP3 servers." msgstr "POP3サーバは %s をサポートしていません。" #: lib/Horde/Imap/Client/Socket.php:4635 msgid "Authentication credentials have expired." msgstr "認証用証明書は期限切れです。" #: lib/Horde/Imap/Client/Socket.php:4619 msgid "Authentication failed." msgstr "認証に失敗しました。" #: lib/Horde/Imap/Client/Auth/DigestMD5.php:158 msgid "Authentication failure." msgstr "認証できません。" #: lib/Horde/Imap/Client/Socket.php:4627 msgid "Authentication was successful, but authorization failed." msgstr "認証は成功しましたが、認可に失敗しました。" #: lib/Horde/Imap/Client/Interaction/Server/Tagged.php:44 msgid "Bad tagged response." msgstr "不正なタグ応答です。" #: lib/Horde/Imap/Client/Exception/SearchCharset.php:45 msgid "Cannot convert search query text to new charset" msgstr "検索文字列を新しい文字セットに変換できません" #: lib/Horde/Imap/Client/Base.php:2032 lib/Horde/Imap/Client/Base.php:2095 msgid "Cannot expunge read-only mailbox." msgstr "読み出し専用メールボックスは削除できません。" #: lib/Horde/Imap/Client/Socket.php:4413 msgid "Charset used in search query is not supported on the mail server." msgstr "検索文字中の文字セットはメールサーバではサポートされていません。" #: lib/Horde/Imap/Client/Socket.php:1077 #, php-format msgid "Could not open mailbox \"%s\"." msgstr "メールボックス \"%s\" が開けません。" #: lib/Horde/Imap/Client/Socket.php:393 msgid "Could not open secure TLS connection to the IMAP server." msgstr "IMAPサーバへのTLS接続はオープンできませんでした。" #: lib/Horde/Imap/Client/Socket/Pop3.php:194 #: lib/Horde/Imap/Client/Socket/Pop3.php:208 msgid "Could not open secure connection to the POP3 server." msgstr "POP3サーバへの安全な接続はオープンできませんでした。" #: lib/Horde/Imap/Client/Socket.php:4519 msgid "Could not save message data because it is too large." msgstr "メッセージが大きすぎるので保存できません。" #: lib/Horde/Imap/Client/Socket.php:4510 msgid "Could not save message on server." msgstr "メッセージをサーバーに保存できません。" #: lib/Horde/Imap/Client/Socket.php:574 #: lib/Horde/Imap/Client/Socket/Pop3.php:284 msgid "Error connecting to mail server." msgstr "メールサーバへの接続に失敗しました。" #: lib/Horde/Imap/Client/Utf7imap.php:128 #: lib/Horde/Imap/Client/Utf7imap.php:156 #: lib/Horde/Imap/Client/Utf7imap.php:163 #: lib/Horde/Imap/Client/Utf7imap.php:225 #: lib/Horde/Imap/Client/Utf7imap.php:245 #: lib/Horde/Imap/Client/Utf7imap.php:252 #: lib/Horde/Imap/Client/Utf7imap.php:263 #: lib/Horde/Imap/Client/Utf7imap.php:272 msgid "Error converting UTF7-IMAP string." msgstr "UTF7-IMAP文字列への変換エラーです。" #: lib/Horde/Imap/Client/Socket.php:4081 #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:71 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:180 #: lib/Horde/Imap/Client/Socket/Pop3.php:1191 msgid "Error when communicating with the mail server." msgstr "メールサーバとの通信エラーです。" #: lib/Horde/Imap/Client/Socket.php:4200 msgid "IMAP Server closed the connection." msgstr "IMAP サーバは接続を閉じました。" #: lib/Horde/Imap/Client/Socket.php:4186 msgid "IMAP error reported by server." msgstr "サーバはIMAPエラーを報告しました。" #: lib/Horde/Imap/Client/Socket.php:3682 #, php-format msgid "Invalid METADATA entry: \"%s\"." msgstr "不正なメタデータ項目:\"%s\"." #: lib/Horde/Imap/Client/Socket.php:3768 #, php-format msgid "Invalid METADATA value type \"%s\"." msgstr "不正なメタデータの種類 \"%s\"." #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:121 msgid "Mail server closed the connection unexpectedly." msgstr "メールサーバとの接続が予期せずに切断されました。" #: lib/Horde/Imap/Client/Socket.php:542 msgid "Mail server denied authentication." msgstr "メールサーバは認証を拒否しました。" #: lib/Horde/Imap/Client/Base.php:2365 lib/Horde/Imap/Client/Base.php:2685 #: lib/Horde/Imap/Client/Base.php:2950 lib/Horde/Imap/Client/Base.php:3035 msgid "Mailbox does not support mod-sequences." msgstr "メールボックスは mod-sequence をサポートしていません。" #: lib/Horde/Imap/Client/Socket.php:469 msgid "No supported IMAP authentication method could be found." msgstr "サポートされた IMAP 認証が見つかりません。" #: lib/Horde/Imap/Client/Socket.php:4643 msgid "Operation failed due to a lack of a secure connection." msgstr "安全な接続ができないため操作に失敗しました。" #: lib/Horde/Imap/Client/Socket/Pop3.php:1250 msgid "POP3 error reported by server." msgstr "サーバは POP3 エラーを報告しました。" #: lib/Horde/Imap/Client/Socket/Pop3.php:253 msgid "POP3 server denied authentication." msgstr "POP3 サーバは認証を拒否しました。" #: lib/Horde/Imap/Client/Socket.php:4611 msgid "Remote server is temporarily unavailable." msgstr "リモートサーバは一時的に使用不能です。" #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:63 msgid "Server closed the connection unexpectedly." msgstr "サーバは接続を予期せずに切断しました。" #: lib/Horde/Imap/Client/Socket.php:381 msgid "Server does not support TLS connections." msgstr "サーバは TLS 接続をサポートしていません。" #: lib/Horde/Imap/Client/Socket/Pop3.php:194 msgid "Server does not support secure connections." msgstr "サーバは安全な接続をサポートしていません。" #: lib/Horde/Imap/Client/Socket.php:594 msgid "Server rejected connection." msgstr "サーバは接続を拒絶しました。" #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:42 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:54 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:87 msgid "Server write error." msgstr "サーバ書き込みエラー。" #: lib/Horde/Imap/Client/Socket.php:4564 msgid "The comparison algorithm was not recognized by the server." msgstr "比較アルゴリズムがサーバで認識されませんでした。" #: lib/Horde/Imap/Client/Socket.php:603 msgid "The mail server does not support IMAP4rev1 (RFC 3501)." msgstr "メールサーバは IMAP4rev1(RFC3501) をサポートしていません。" #: lib/Horde/Imap/Client/Socket.php:4690 msgid "The mail server has denied the request." msgstr "メールサーバは要求を拒否しました。" #: lib/Horde/Imap/Client/Socket.php:4674 msgid "The mail server is reporting corrupt data in your mailbox." msgstr "" "メールサーバはあなたのメールボックスのデータが壊れていると報告しています。" #: lib/Horde/Imap/Client/Socket.php:4476 msgid "The mail server was unable to parse the contents of the mail message." msgstr "メールサーバはメッセージの内容を解析できませんでした。" #: lib/Horde/Imap/Client/Socket.php:4429 #, php-format msgid "" "The mail server was unable to parse the contents of the mail message: %s" msgstr "メールサーバはメッセージの内容を解析できませんでした:%s" #: lib/Horde/Imap/Client/Socket.php:4582 msgid "The metadata item could not be saved because it is too large." msgstr "メタデータが大きすぎたため、保存できませんでした。" #: lib/Horde/Imap/Client/Socket.php:4600 msgid "" "The metadata item could not be saved because the maximum number of " "annotations has been exceeded." msgstr "注釈の最大数を超過しているため、メタデータは保存できませんでした。" #: lib/Horde/Imap/Client/Socket.php:4591 msgid "" "The metadata item could not be saved because the server does not support " "private annotations." msgstr "" "サーバが私的な注釈をサポートしていないので、メタデータは保存できませんでし" "た。" #: lib/Horde/Imap/Client/Socket.php:4708 msgid "The object could not be created because it already exists." msgstr "オブジェクトは既に存在するので作成されませんでした。" #: lib/Horde/Imap/Client/Socket.php:4717 msgid "The object could not be deleted because it does not exist." msgstr "オブジェクトは存在しないので削除できませんでした。" #: lib/Horde/Imap/Client/Socket.php:4699 msgid "" "The operation failed because the quota has been exceeded on the mail server." msgstr "メールサーバのクォータを超過しているので、操作は失敗しました。" #: lib/Horde/Imap/Client/Exception/NoSupportExtension.php:46 #, php-format msgid "The server does not support the %s extension." msgstr "サーバは %s 拡張をサポートしていません。" #: lib/Horde/Imap/Client/Socket.php:4726 msgid "The special-use attribute requested for the mailbox is not supported." msgstr "メールボックスの特別な属性の使用はサポートされていません。" #: lib/Horde/Imap/Client/Socket.php:4660 msgid "" "There was a temporary issue when attempting this operation. Please try again " "later." msgstr "この操作には一時的な問題がありました。後で再度試して下さい。" #: lib/Horde/Imap/Client/Socket.php:692 #: lib/Horde/Imap/Client/Socket/Pop3.php:339 msgid "Unexpected response from server when authenticating." msgstr "認証時にサーバから予期しない応答がありました。" #: lib/Horde/Imap/Client/Socket.php:729 #: lib/Horde/Imap/Client/Socket/Pop3.php:385 #, php-format msgid "Unknown authentication method: %s" msgstr "不明な認証方式です:%s" #: lib/Horde/Imap/Client/Socket.php:4651 msgid "You do not have adequate permissions to carry out this operation." msgstr "あなたにはこの操作を実行するのに十分なアクセス権を持っていません。" Horde_Imap_Client-2.29.15/locale/nl/LC_MESSAGES/Horde_Imap_Client.mo0000664000175000017500000001512113150761653022611 0ustar janjan5Gl!(8</Q!A84;4p!  " .,"[~!/" '07X6/" )9 (c +   : 6# 'Z : E = aA ] : :< Lw - E S8 4 ! A %$# .C9T= D N9h88&?;>{CA+@'l $8)$=b/z6 (0+)\0"<4+*`5JC eP`;=SJ*MiU2!<.,%/ 3*) 0# 4 (-"+1&2$5 !'%s not supported on POP3 servers.Authentication credentials have expired.Authentication failed.Authentication failure.Authentication was successful, but authorization failed.Bad tagged response.Cannot convert search query text to new charsetCannot expunge read-only mailbox.Charset used in search query is not supported on the mail server.Could not open mailbox "%s".Could not open secure TLS connection to the IMAP server.Could not open secure connection to the POP3 server.Could not save message data because it is too large.Could not save message on server.Error connecting to POP3 server.Error connecting to mail server.Error converting UTF7-IMAP string.Error when communicating with the mail server.IMAP Server closed the connection.IMAP error reported by server.Invalid METADATA entry: "%s".Invalid METADATA value type "%s".Mail server closed the connection unexpectedly.Mail server denied authentication.Mailbox does not support mod-sequences.No supported IMAP authentication method could be found.Operation failed due to a lack of a secure connection.POP3 Server closed the connection unexpectedly.POP3 error reported by server.POP3 server denied authentication.Remote server is temporarily unavailable.Server does not support TLS connections.Server does not support secure connections.Server rejected connection.Server write error.The comparison algorithm was not recognized by the server.The mail server does not support IMAP4rev1 (RFC 3501).The mail server has denied the request.The mail server is reporting corrupt data in your mailbox.The mail server was unable to parse the contents of the mail message.The metadata item could not be saved because it is too large.The metadata item could not be saved because the maximum number of annotations has been exceeded.The metadata item could not be saved because the server does not support private annotations.The object could not be created because it already exists.The object could not be deleted because it does not exist.The operation failed because the quota has been exceeded on the mail server.The server does not support the %s extension.The special-use attribute requested for the mailbox is not supported.There was a temporary issue when attempting this operation. Please try again later.Unexpected response from server when authenticating.Unknown authentication method: %sYou do not have adequate permissions to carry out this operation.Project-Id-Version: Horde_Imap_Client Report-Msgid-Bugs-To: dev@lists.horde.org POT-Creation-Date: 2012-11-06 16:40+0100 PO-Revision-Date: 2012-11-29 22:21+0100 Last-Translator: Arjen de Korte Language-Team: American English Language: nl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Generator: Lokalize 1.4 %s niet ondersteund op POP3 servers.Verificatie gegevens zijn verlopen.Verificatie mislukt.Verificatiefout.Verificatie was succesvol, maar toestemming is geweigerd.Ongeldig gelabeld antwoord.Kan de zoekopdracht niet naar de nieuwe karakterset omzetten.Kan alleen-lezen map niet legen.Karakterset in zoekopdracht wordt niet ondersteund op de mailserver.Kan map "%s" niet openen.Kan geen beveiligde TLS verbinding met IMAP server maken.Kon geen beveiligde verbinding maken met de POP3 server.Kan bericht gegevens niet opslaan omdat het te groot is.Kon bericht niet opslaan op de server.Er is een fout opgetreden bij het verbinden met de POP3 server.Er is een fout opgetreden bij het verbinden met de mailserver.Er is een fout opgetreden bij het omzetten van de UTF7-IMAP string.Er is een fout opgetreden bij het communiceren met de mailserver.IMAP server heeft de verbinding beëindigd.IMAP fout gerapporteerd door de server.Ongeldige METADATA invoer: "%s".Ongeldige METADATA waarde type "%s".De mailserver heeft de verbinding onverwacht beëindigd.Mailserver heeft de aanmelding geweigerd.Map ondersteund geen mod-sequenties.Geen ondersteunde IMAP De bewerking vereist een beveiligde verbinding.POP3 server heeft de verbinding onverwacht beëindigd.POP3 fout gemeld door de server.POP3 server heeft verificatie geweigerd.Server op afstand is tijdelijk niet beschikbaar.Server ondersteunt geen TLS verbindingen.Server ondersteunt geen beveiligde verbindingen.Server heeft verbinding geweigerd.Server schrijffout.Het vergelijkingsalgoritme wordt niet herkend door de serverDe mailserver ondersteunt IMAP4rev1 (RFC 3501) niet.De mailserver heeft het verzoek geweigerd.De mailserver rapporteert beschadigde data in uw map.De mailserver was niet in staat om de inhoud van het bericht te verwerken.Het metadata item kon niet worden opgeslagen omdat het te groot is.Het metadata item kon niet worden opgeslagen omdat het maximale aantal annotaties wordt overschreden.Het metadata item kon niet worden opgeslagen omdat de server geen privé annotaties ondersteund.Het object kon niet worden aangemaakt omdat het al bestaat.Het object kon niet worden verwijderd omdat het niet bestaat.De bewerking is mislukt omdat het quotum op de mailserver is overschreden.De server ondersteunt de %s extensie niet.Het special-use attribuut dat is gevraagd voor de map wordt niet ondersteund.Er is een tijdelijk probleem opgetreden bij het uitvoeren van deze bewerking. Probeer het later nog eens.Onverwacht antwoord van server bij de verificatie.Onbekende verificatie methode: %sU heeft onvoldoende rechten om deze bewerking uit te voeren.Horde_Imap_Client-2.29.15/locale/nl/LC_MESSAGES/Horde_Imap_Client.po0000664000175000017500000002334613150761653022624 0ustar janjan# Dutch translations for Horde_Imap_Client package. # Copyright 2012-2017 Horde LLC (http://www.horde.org/) # This file is distributed under the same license as the Horde_Imap_Client package. # # Automatically generated, 2012. # Arjen de Korte , 2012. msgid "" msgstr "" "Project-Id-Version: Horde_Imap_Client\n" "Report-Msgid-Bugs-To: dev@lists.horde.org\n" "POT-Creation-Date: 2012-11-06 16:40+0100\n" "PO-Revision-Date: 2012-11-29 22:21+0100\n" "Last-Translator: Arjen de Korte \n" "Language-Team: American English \n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Lokalize 1.4\n" #: lib/Horde/Imap/Client/Exception/NoSupportPop3.php:25 #, php-format msgid "%s not supported on POP3 servers." msgstr "%s niet ondersteund op POP3 servers." #: lib/Horde/Imap/Client/Socket.php:4380 msgid "Authentication credentials have expired." msgstr "Verificatie gegevens zijn verlopen." #: lib/Horde/Imap/Client/Socket.php:4364 msgid "Authentication failed." msgstr "Verificatie mislukt." #: lib/Horde/Imap/Client/Auth/DigestMD5.php:149 msgid "Authentication failure." msgstr "Verificatiefout." #: lib/Horde/Imap/Client/Socket.php:4372 msgid "Authentication was successful, but authorization failed." msgstr "Verificatie was succesvol, maar toestemming is geweigerd." #: lib/Horde/Imap/Client/Interaction/Server/Tagged.php:34 msgid "Bad tagged response." msgstr "Ongeldig gelabeld antwoord." #: lib/Horde/Imap/Client/Exception/SearchCharset.php:36 msgid "Cannot convert search query text to new charset" msgstr "Kan de zoekopdracht niet naar de nieuwe karakterset omzetten." #: lib/Horde/Imap/Client/Base.php:1899 lib/Horde/Imap/Client/Base.php:1958 msgid "Cannot expunge read-only mailbox." msgstr "Kan alleen-lezen map niet legen." #: lib/Horde/Imap/Client/Socket.php:4165 msgid "Charset used in search query is not supported on the mail server." msgstr "Karakterset in zoekopdracht wordt niet ondersteund op de mailserver." #: lib/Horde/Imap/Client/Socket.php:931 #, php-format msgid "Could not open mailbox \"%s\"." msgstr "Kan map \"%s\" niet openen." #: lib/Horde/Imap/Client/Socket.php:335 msgid "Could not open secure TLS connection to the IMAP server." msgstr "Kan geen beveiligde TLS verbinding met IMAP server maken." #: lib/Horde/Imap/Client/Socket/Pop3.php:189 #: lib/Horde/Imap/Client/Socket/Pop3.php:201 msgid "Could not open secure connection to the POP3 server." msgstr "Kon geen beveiligde verbinding maken met de POP3 server." #: lib/Horde/Imap/Client/Socket.php:4265 msgid "Could not save message data because it is too large." msgstr "Kan bericht gegevens niet opslaan omdat het te groot is." #: lib/Horde/Imap/Client/Socket.php:4256 msgid "Could not save message on server." msgstr "Kon bericht niet opslaan op de server." #: lib/Horde/Imap/Client/Socket/Pop3.php:280 msgid "Error connecting to POP3 server." msgstr "Er is een fout opgetreden bij het verbinden met de POP3 server." #: lib/Horde/Imap/Client/Socket.php:504 msgid "Error connecting to mail server." msgstr "Er is een fout opgetreden bij het verbinden met de mailserver." #: lib/Horde/Imap/Client/Utf7imap.php:117 #: lib/Horde/Imap/Client/Utf7imap.php:142 #: lib/Horde/Imap/Client/Utf7imap.php:146 #: lib/Horde/Imap/Client/Utf7imap.php:205 #: lib/Horde/Imap/Client/Utf7imap.php:222 #: lib/Horde/Imap/Client/Utf7imap.php:226 #: lib/Horde/Imap/Client/Utf7imap.php:234 #: lib/Horde/Imap/Client/Utf7imap.php:240 msgid "Error converting UTF7-IMAP string." msgstr "Er is een fout opgetreden bij het omzetten van de UTF7-IMAP string." #: lib/Horde/Imap/Client/Socket.php:3683 lib/Horde/Imap/Client/Socket.php:3964 msgid "Error when communicating with the mail server." msgstr "Er is een fout opgetreden bij het communiceren met de mailserver." #: lib/Horde/Imap/Client/Socket.php:3838 msgid "IMAP Server closed the connection." msgstr "IMAP server heeft de verbinding beëindigd." #: lib/Horde/Imap/Client/Socket.php:3823 lib/Horde/Imap/Client/Socket.php:3854 msgid "IMAP error reported by server." msgstr "IMAP fout gerapporteerd door de server." #: lib/Horde/Imap/Client/Socket.php:3389 #, php-format msgid "Invalid METADATA entry: \"%s\"." msgstr "Ongeldige METADATA invoer: \"%s\"." #: lib/Horde/Imap/Client/Socket.php:3476 #, php-format msgid "Invalid METADATA value type \"%s\"." msgstr "Ongeldige METADATA waarde type \"%s\"." #: lib/Horde/Imap/Client/Socket.php:3890 msgid "Mail server closed the connection unexpectedly." msgstr "De mailserver heeft de verbinding onverwacht beëindigd." #: lib/Horde/Imap/Client/Socket.php:395 msgid "Mail server denied authentication." msgstr "Mailserver heeft de aanmelding geweigerd." #: lib/Horde/Imap/Client/Socket.php:1812 lib/Horde/Imap/Client/Socket.php:2483 #: lib/Horde/Imap/Client/Socket.php:2504 lib/Horde/Imap/Client/Socket.php:2933 #: lib/Horde/Imap/Client/Socket.php:2988 msgid "Mailbox does not support mod-sequences." msgstr "Map ondersteund geen mod-sequenties." #: lib/Horde/Imap/Client/Socket.php:378 msgid "No supported IMAP authentication method could be found." msgstr "Geen ondersteunde IMAP " #: lib/Horde/Imap/Client/Socket.php:4388 msgid "Operation failed due to a lack of a secure connection." msgstr "De bewerking vereist een beveiligde verbinding." #: lib/Horde/Imap/Client/Socket/Pop3.php:1096 msgid "POP3 Server closed the connection unexpectedly." msgstr "POP3 server heeft de verbinding onverwacht beëindigd." #: lib/Horde/Imap/Client/Socket/Pop3.php:1156 msgid "POP3 error reported by server." msgstr "POP3 fout gemeld door de server." #: lib/Horde/Imap/Client/Socket/Pop3.php:240 msgid "POP3 server denied authentication." msgstr "POP3 server heeft verificatie geweigerd." #: lib/Horde/Imap/Client/Socket.php:4356 msgid "Remote server is temporarily unavailable." msgstr "Server op afstand is tijdelijk niet beschikbaar." #: lib/Horde/Imap/Client/Socket.php:323 msgid "Server does not support TLS connections." msgstr "Server ondersteunt geen TLS verbindingen." #: lib/Horde/Imap/Client/Socket/Pop3.php:189 msgid "Server does not support secure connections." msgstr "Server ondersteunt geen beveiligde verbindingen." #: lib/Horde/Imap/Client/Socket.php:527 msgid "Server rejected connection." msgstr "Server heeft verbinding geweigerd." #: lib/Horde/Imap/Client/Socket.php:3748 msgid "Server write error." msgstr "Server schrijffout." #: lib/Horde/Imap/Client/Socket.php:4309 msgid "The comparison algorithm was not recognized by the server." msgstr "Het vergelijkingsalgoritme wordt niet herkend door de server" #: lib/Horde/Imap/Client/Socket.php:536 msgid "The mail server does not support IMAP4rev1 (RFC 3501)." msgstr "De mailserver ondersteunt IMAP4rev1 (RFC 3501) niet." #: lib/Horde/Imap/Client/Socket.php:4435 msgid "The mail server has denied the request." msgstr "De mailserver heeft het verzoek geweigerd." #: lib/Horde/Imap/Client/Socket.php:4419 msgid "The mail server is reporting corrupt data in your mailbox." msgstr "De mailserver rapporteert beschadigde data in uw map." #: lib/Horde/Imap/Client/Socket.php:4177 lib/Horde/Imap/Client/Socket.php:4222 msgid "The mail server was unable to parse the contents of the mail message." msgstr "" "De mailserver was niet in staat om de inhoud van het bericht te verwerken." #: lib/Horde/Imap/Client/Socket.php:4327 msgid "The metadata item could not be saved because it is too large." msgstr "Het metadata item kon niet worden opgeslagen omdat het te groot is." #: lib/Horde/Imap/Client/Socket.php:4345 msgid "" "The metadata item could not be saved because the maximum number of " "annotations has been exceeded." msgstr "" "Het metadata item kon niet worden opgeslagen omdat het maximale aantal " "annotaties wordt overschreden." #: lib/Horde/Imap/Client/Socket.php:4336 msgid "" "The metadata item could not be saved because the server does not support " "private annotations." msgstr "" "Het metadata item kon niet worden opgeslagen omdat de server geen privé " "annotaties ondersteund." #: lib/Horde/Imap/Client/Socket.php:4453 msgid "The object could not be created because it already exists." msgstr "Het object kon niet worden aangemaakt omdat het al bestaat." #: lib/Horde/Imap/Client/Socket.php:4462 msgid "The object could not be deleted because it does not exist." msgstr "Het object kon niet worden verwijderd omdat het niet bestaat." #: lib/Horde/Imap/Client/Socket.php:4444 msgid "" "The operation failed because the quota has been exceeded on the mail server." msgstr "" "De bewerking is mislukt omdat het quotum op de mailserver is overschreden." #: lib/Horde/Imap/Client/Exception/NoSupportExtension.php:36 #, php-format msgid "The server does not support the %s extension." msgstr "De server ondersteunt de %s extensie niet." #: lib/Horde/Imap/Client/Socket.php:4471 msgid "The special-use attribute requested for the mailbox is not supported." msgstr "" "Het special-use attribuut dat is gevraagd voor de map wordt niet ondersteund." #: lib/Horde/Imap/Client/Socket.php:4405 msgid "" "There was a temporary issue when attempting this operation. Please try again " "later." msgstr "" "Er is een tijdelijk probleem opgetreden bij het uitvoeren van deze " "bewerking. Probeer het later nog eens." #: lib/Horde/Imap/Client/Socket.php:604 #: lib/Horde/Imap/Client/Socket/Pop3.php:334 msgid "Unexpected response from server when authenticating." msgstr "Onverwacht antwoord van server bij de verificatie." #: lib/Horde/Imap/Client/Socket.php:648 #: lib/Horde/Imap/Client/Socket/Pop3.php:374 #, php-format msgid "Unknown authentication method: %s" msgstr "Onbekende verificatie methode: %s" #: lib/Horde/Imap/Client/Socket.php:4396 msgid "You do not have adequate permissions to carry out this operation." msgstr "U heeft onvoldoende rechten om deze bewerking uit te voeren." Horde_Imap_Client-2.29.15/locale/tr/LC_MESSAGES/Horde_Imap_Client.mo0000664000175000017500000001532113150761653022627 0ustar janjan7I!(8+d/y!A 8*4c4! ".3"b!/"'7_7u6" )& *P ({ + !   :" 6] ' : E H= = a ]& : : L -G Eu S 4!DAf'>-f$H<5*rL81<9n&,*3'%[+!&;-2!`@F+,K,x7*,15g>0 4->bA?T#Lx/$D&_ESL )m9+6(-4% $ /5",03#!&1  '2.*7 ) %s not supported on POP3 servers.Authentication credentials have expired.Authentication failed.Authentication failure.Authentication was successful, but authorization failed.Bad tagged response.Cannot convert search query text to new charsetCannot expunge read-only mailbox.Charset used in search query is not supported on the mail server.Could not open mailbox "%s".Could not open secure TLS connection to the IMAP server.Could not open secure connection to the POP3 server.Could not save message data because it is too large.Could not save message on server.Error connecting to mail server.Error converting UTF7-IMAP string.Error when communicating with the mail server.IMAP Server closed the connection.IMAP error reported by server.Invalid METADATA entry: "%s".Invalid METADATA value type "%s".Mail server closed the connection unexpectedly.Mail server denied authentication.Mailbox does not support mod-sequences.No password provided.No supported IMAP authentication method could be found.Operation failed due to a lack of a secure connection.POP3 error reported by server.POP3 server denied authentication.Remote server is temporarily unavailable.Server closed the connection unexpectedly.Server does not support TLS connections.Server does not support secure connections.Server failed verification check.Server rejected connection.Server write error.The comparison algorithm was not recognized by the server.The mail server does not support IMAP4rev1 (RFC 3501).The mail server has denied the request.The mail server is reporting corrupt data in your mailbox.The mail server was unable to parse the contents of the mail message.The mail server was unable to parse the contents of the mail message: %sThe metadata item could not be saved because it is too large.The metadata item could not be saved because the maximum number of annotations has been exceeded.The metadata item could not be saved because the server does not support private annotations.The object could not be created because it already exists.The object could not be deleted because it does not exist.The operation failed because the quota has been exceeded on the mail server.The server does not support the %s extension.The special-use attribute requested for the mailbox is not supported.There was a temporary issue when attempting this operation. Please try again later.Unexpected response from server when authenticating.Unknown authentication method: %sYou do not have adequate permissions to carry out this operation.Project-Id-Version: Horde_Imap_Client Report-Msgid-Bugs-To: dev@lists.horde.org POT-Creation-Date: 2017-06-09 15:57+0300 PO-Revision-Date: 2017-06-09 16:19+0300 Language-Team: İTÜ BİDB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Generator: Poedit 1.8.12 Last-Translator: Plural-Forms: nplurals=2; plural=(n != 1); Language: tr %s, POP3 sunucularında desteklenmiyor.Kimlik doğrulama bilgilerinin süresi doldu.Kimlik doğrulama başarısız oldu.Kimlik doğrulama hatası.Kimlik doğrulama başarılıydı ancak yetkilendirme başarısız oldu.Kötü etiketli yanıt.Arama sorgusu metni yeni karakter setine dönüştürülemezSalt okunur dizini silmek mümkün değil.Arama sorgusunda kullanılan karakter seti posta sunucusunda desteklenmiyor.Dizin "%s" açılamadı.IMAP sunucusuna güvenli TLS bağlantısı açılamadı.POP3 sunucusuna güvenli bağlantı açılamadı.İleti verileri çok büyük olduğu için kaydedilemedi.İleti sunucu üzerinde kaydedilemedi.Posta sunucusuna bağlanırken hata oluştu.UTF7-IMAP dizesini dönüştürme hatası.Posta sunucusu ile iletişim kurarken hata oluştu.IMAP Sunucusu bağlantıyı kapattı.Sunucu tarafından IMAP hatası bildirildi.Geçersiz METADATA girişi: "%s".Geçersiz METADATA değer türü "%s".Posta sunucusu bağlantıyı beklenmedik şekilde kapattı.Posta sunucusu kimlik doğrulamayı reddetti.Dizin mod dizilerini desteklemez.Parola sağlanmadı.Desteklenen hiçbir IMAP kimlik doğrulama yöntemi bulunamadı.Güvenli bir bağlantı eksikliği nedeniyle işlem başarısız oldu.Sunucu tarafından POP3 hatası bildirildi.POP3 sunucusu kimlik doğrulamayı reddetti.Uzak sunucu geçici olarak kullanılamıyor.Sunucu bağlantıyı beklenmedik bir şekilde kapattı.Sunucu TLS bağlantılarını desteklemez.Sunucu güvenli bağlantıları desteklemez.Sunucu doğrulama kontrolünde başarısız oldu.Sunucu bağlantıyı reddetti.Sunucu yazma hatası.Karşılaştırma algoritması sunucu tarafından tanınmadı.Posta sunucusu IMAP4rev1 (RFC 3501) desteklemez.Posta sunucusu isteği reddetti.Posta sunucusu dizininizde bozuk veriler bildiriyor.Posta sunucusu posta iletisinin içeriğini ayrıştıramadı.Posta sunucusu posta iletisinin içeriğini ayrıştıramadı: %sMetadata veri öğesi çok büyük olduğu için kaydedilemedi.En fazla ek açıklama sayısı aşıldığı için meta veri öğesi kaydedilemedi.Sunucu özel notları desteklemediği için meta veri öğesi kaydedilemedi.Nesne zaten var olduğu için oluşturulamadı.Nesne bulunmadığından silinemedi.Posta sunucusunda kota aşıldığı için işlem başarısız oldu.Sunucu %s uzantısını desteklemiyor.Posta kutusu için istenen özel kullanım özelliği desteklenmiyor.Bu işlemi denerken geçici bir sorun oluştu. Lütfen daha sonra tekrar deneyiniz.Kimlik doğrulama işlemi sırasında sunucu tarafından beklenmeyen yanıt.Bilinmeyen kimlik doğrulama yöntemi: %sBu işlemi gerçekleştirmek için yeterli izninizin yok.Horde_Imap_Client-2.29.15/locale/tr/LC_MESSAGES/Horde_Imap_Client.po0000664000175000017500000002466013150761653022640 0ustar janjan# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Horde LLC (http://www.horde.org/) # This file is distributed under the same license as the Horde_Imap_Client package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Horde_Imap_Client\n" "Report-Msgid-Bugs-To: dev@lists.horde.org\n" "POT-Creation-Date: 2017-06-09 15:57+0300\n" "PO-Revision-Date: 2017-06-09 16:19+0300\n" "Language-Team: İTÜ BİDB \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.12\n" "Last-Translator: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Language: tr\n" #: lib/Horde/Imap/Client/Exception/NoSupportPop3.php:34 #, php-format msgid "%s not supported on POP3 servers." msgstr "%s, POP3 sunucularında desteklenmiyor." #: lib/Horde/Imap/Client/Socket.php:5035 msgid "Authentication credentials have expired." msgstr "Kimlik doğrulama bilgilerinin süresi doldu." #: lib/Horde/Imap/Client/Socket.php:747 lib/Horde/Imap/Client/Socket.php:5019 #: lib/Horde/Imap/Client/Socket/Pop3.php:441 #: lib/Horde/Imap/Client/Socket/Pop3.php:460 #: lib/Horde/Imap/Client/Socket/Pop3.php:486 #: lib/Horde/Imap/Client/Socket/Pop3.php:498 msgid "Authentication failed." msgstr "Kimlik doğrulama başarısız oldu." #: lib/Horde/Imap/Client/Auth/DigestMD5.php:158 #: lib/Horde/Imap/Client/Auth/Scram.php:124 msgid "Authentication failure." msgstr "Kimlik doğrulama hatası." #: lib/Horde/Imap/Client/Socket.php:5027 msgid "Authentication was successful, but authorization failed." msgstr "Kimlik doğrulama başarılıydı ancak yetkilendirme başarısız oldu." #: lib/Horde/Imap/Client/Interaction/Server/Tagged.php:44 msgid "Bad tagged response." msgstr "Kötü etiketli yanıt." #: lib/Horde/Imap/Client/Exception/SearchCharset.php:45 msgid "Cannot convert search query text to new charset" msgstr "Arama sorgusu metni yeni karakter setine dönüştürülemez" #: lib/Horde/Imap/Client/Base.php:1922 lib/Horde/Imap/Client/Base.php:1985 msgid "Cannot expunge read-only mailbox." msgstr "Salt okunur dizini silmek mümkün değil." #: lib/Horde/Imap/Client/Socket.php:4811 msgid "Charset used in search query is not supported on the mail server." msgstr "" "Arama sorgusunda kullanılan karakter seti posta sunucusunda desteklenmiyor." #: lib/Horde/Imap/Client/Socket.php:1240 #, php-format msgid "Could not open mailbox \"%s\"." msgstr "Dizin \"%s\" açılamadı." #: lib/Horde/Imap/Client/Socket.php:358 lib/Horde/Imap/Client/Socket.php:400 msgid "Could not open secure TLS connection to the IMAP server." msgstr "IMAP sunucusuna güvenli TLS bağlantısı açılamadı." #: lib/Horde/Imap/Client/Socket/Pop3.php:219 #: lib/Horde/Imap/Client/Socket/Pop3.php:233 msgid "Could not open secure connection to the POP3 server." msgstr "POP3 sunucusuna güvenli bağlantı açılamadı." #: lib/Horde/Imap/Client/Socket.php:4919 msgid "Could not save message data because it is too large." msgstr "İleti verileri çok büyük olduğu için kaydedilemedi." #: lib/Horde/Imap/Client/Socket.php:4910 msgid "Could not save message on server." msgstr "İleti sunucu üzerinde kaydedilemedi." #: lib/Horde/Imap/Client/Socket.php:606 #: lib/Horde/Imap/Client/Socket/Pop3.php:324 msgid "Error connecting to mail server." msgstr "Posta sunucusuna bağlanırken hata oluştu." #: lib/Horde/Imap/Client/Utf7imap.php:128 #: lib/Horde/Imap/Client/Utf7imap.php:156 #: lib/Horde/Imap/Client/Utf7imap.php:163 #: lib/Horde/Imap/Client/Utf7imap.php:225 #: lib/Horde/Imap/Client/Utf7imap.php:245 #: lib/Horde/Imap/Client/Utf7imap.php:252 #: lib/Horde/Imap/Client/Utf7imap.php:263 #: lib/Horde/Imap/Client/Utf7imap.php:272 msgid "Error converting UTF7-IMAP string." msgstr "UTF7-IMAP dizesini dönüştürme hatası." #: lib/Horde/Imap/Client/Socket.php:4467 #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:83 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:214 #: lib/Horde/Imap/Client/Socket/Pop3.php:1382 msgid "Error when communicating with the mail server." msgstr "Posta sunucusu ile iletişim kurarken hata oluştu." #: lib/Horde/Imap/Client/Socket.php:4605 msgid "IMAP Server closed the connection." msgstr "IMAP Sunucusu bağlantıyı kapattı." #: lib/Horde/Imap/Client/Socket.php:4591 msgid "IMAP error reported by server." msgstr "Sunucu tarafından IMAP hatası bildirildi." #: lib/Horde/Imap/Client/Socket.php:4009 #, php-format msgid "Invalid METADATA entry: \"%s\"." msgstr "Geçersiz METADATA girişi: \"%s\"." #: lib/Horde/Imap/Client/Socket.php:4102 #, php-format msgid "Invalid METADATA value type \"%s\"." msgstr "Geçersiz METADATA değer türü \"%s\"." #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:148 msgid "Mail server closed the connection unexpectedly." msgstr "Posta sunucusu bağlantıyı beklenmedik şekilde kapattı." #: lib/Horde/Imap/Client/Socket.php:573 msgid "Mail server denied authentication." msgstr "Posta sunucusu kimlik doğrulamayı reddetti." #: lib/Horde/Imap/Client/Base.php:2255 lib/Horde/Imap/Client/Base.php:2534 #: lib/Horde/Imap/Client/Base.php:2806 lib/Horde/Imap/Client/Base.php:2891 msgid "Mailbox does not support mod-sequences." msgstr "Dizin mod dizilerini desteklemez." #: lib/Horde/Imap/Client/Socket.php:370 #: lib/Horde/Imap/Client/Socket/Pop3.php:201 msgid "No password provided." msgstr "Parola sağlanmadı." #: lib/Horde/Imap/Client/Socket.php:498 msgid "No supported IMAP authentication method could be found." msgstr "Desteklenen hiçbir IMAP kimlik doğrulama yöntemi bulunamadı." #: lib/Horde/Imap/Client/Socket.php:5043 msgid "Operation failed due to a lack of a secure connection." msgstr "Güvenli bir bağlantı eksikliği nedeniyle işlem başarısız oldu." #: lib/Horde/Imap/Client/Socket/Pop3.php:1448 msgid "POP3 error reported by server." msgstr "Sunucu tarafından POP3 hatası bildirildi." #: lib/Horde/Imap/Client/Socket/Pop3.php:295 msgid "POP3 server denied authentication." msgstr "POP3 sunucusu kimlik doğrulamayı reddetti." #: lib/Horde/Imap/Client/Socket.php:5011 msgid "Remote server is temporarily unavailable." msgstr "Uzak sunucu geçici olarak kullanılamıyor." #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:75 msgid "Server closed the connection unexpectedly." msgstr "Sunucu bağlantıyı beklenmedik bir şekilde kapattı." #: lib/Horde/Imap/Client/Socket.php:388 msgid "Server does not support TLS connections." msgstr "Sunucu TLS bağlantılarını desteklemez." #: lib/Horde/Imap/Client/Socket/Pop3.php:219 msgid "Server does not support secure connections." msgstr "Sunucu güvenli bağlantıları desteklemez." #: lib/Horde/Imap/Client/Socket.php:809 #: lib/Horde/Imap/Client/Socket/Pop3.php:508 msgid "Server failed verification check." msgstr "Sunucu doğrulama kontrolünde başarısız oldu." #: lib/Horde/Imap/Client/Socket.php:626 msgid "Server rejected connection." msgstr "Sunucu bağlantıyı reddetti." #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:47 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:64 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:110 msgid "Server write error." msgstr "Sunucu yazma hatası." #: lib/Horde/Imap/Client/Socket.php:4964 msgid "The comparison algorithm was not recognized by the server." msgstr "Karşılaştırma algoritması sunucu tarafından tanınmadı." #: lib/Horde/Imap/Client/Socket.php:635 msgid "The mail server does not support IMAP4rev1 (RFC 3501)." msgstr "Posta sunucusu IMAP4rev1 (RFC 3501) desteklemez." #: lib/Horde/Imap/Client/Socket.php:5092 msgid "The mail server has denied the request." msgstr "Posta sunucusu isteği reddetti." #: lib/Horde/Imap/Client/Socket.php:5074 msgid "The mail server is reporting corrupt data in your mailbox." msgstr "Posta sunucusu dizininizde bozuk veriler bildiriyor." #: lib/Horde/Imap/Client/Socket.php:4876 msgid "The mail server was unable to parse the contents of the mail message." msgstr "Posta sunucusu posta iletisinin içeriğini ayrıştıramadı." #: lib/Horde/Imap/Client/Socket.php:4827 #, php-format msgid "" "The mail server was unable to parse the contents of the mail message: %s" msgstr "Posta sunucusu posta iletisinin içeriğini ayrıştıramadı: %s" #: lib/Horde/Imap/Client/Socket.php:4982 msgid "The metadata item could not be saved because it is too large." msgstr "Metadata veri öğesi çok büyük olduğu için kaydedilemedi." #: lib/Horde/Imap/Client/Socket.php:5000 msgid "" "The metadata item could not be saved because the maximum number of " "annotations has been exceeded." msgstr "" "En fazla ek açıklama sayısı aşıldığı için meta veri öğesi kaydedilemedi." #: lib/Horde/Imap/Client/Socket.php:4991 msgid "" "The metadata item could not be saved because the server does not support " "private annotations." msgstr "Sunucu özel notları desteklemediği için meta veri öğesi kaydedilemedi." #: lib/Horde/Imap/Client/Socket.php:5110 msgid "The object could not be created because it already exists." msgstr "Nesne zaten var olduğu için oluşturulamadı." #: lib/Horde/Imap/Client/Socket.php:5119 msgid "The object could not be deleted because it does not exist." msgstr "Nesne bulunmadığından silinemedi." #: lib/Horde/Imap/Client/Socket.php:5101 msgid "" "The operation failed because the quota has been exceeded on the mail server." msgstr "Posta sunucusunda kota aşıldığı için işlem başarısız oldu." #: lib/Horde/Imap/Client/Exception/NoSupportExtension.php:46 #, php-format msgid "The server does not support the %s extension." msgstr "Sunucu %s uzantısını desteklemiyor." #: lib/Horde/Imap/Client/Socket.php:5128 msgid "The special-use attribute requested for the mailbox is not supported." msgstr "Posta kutusu için istenen özel kullanım özelliği desteklenmiyor." #: lib/Horde/Imap/Client/Socket.php:5060 msgid "" "There was a temporary issue when attempting this operation. Please try again " "later." msgstr "" "Bu işlemi denerken geçici bir sorun oluştu. Lütfen daha sonra tekrar " "deneyiniz." #: lib/Horde/Imap/Client/Socket.php:723 #: lib/Horde/Imap/Client/Socket/Pop3.php:379 msgid "Unexpected response from server when authenticating." msgstr "Kimlik doğrulama işlemi sırasında sunucu tarafından beklenmeyen yanıt." #: lib/Horde/Imap/Client/Socket.php:839 #: lib/Horde/Imap/Client/Socket/Pop3.php:518 #, php-format msgid "Unknown authentication method: %s" msgstr "Bilinmeyen kimlik doğrulama yöntemi: %s" #: lib/Horde/Imap/Client/Socket.php:5051 msgid "You do not have adequate permissions to carry out this operation." msgstr "Bu işlemi gerçekleştirmek için yeterli izninizin yok." Horde_Imap_Client-2.29.15/locale/Horde_Imap_Client.pot0000664000175000017500000001740413150761653020610 0ustar janjan# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Horde LLC (http://www.horde.org/) # This file is distributed under the same license as the Horde_Imap_Client package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Horde_Imap_Client\n" "Report-Msgid-Bugs-To: dev@lists.horde.org\n" "POT-Creation-Date: 2017-07-26 12:13+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: lib/Horde/Imap/Client/Exception/NoSupportPop3.php:34 #, php-format msgid "%s not supported on POP3 servers." msgstr "" #: lib/Horde/Imap/Client/Socket.php:5035 msgid "Authentication credentials have expired." msgstr "" #: lib/Horde/Imap/Client/Socket.php:747 lib/Horde/Imap/Client/Socket.php:5019 #: lib/Horde/Imap/Client/Socket/Pop3.php:441 #: lib/Horde/Imap/Client/Socket/Pop3.php:460 #: lib/Horde/Imap/Client/Socket/Pop3.php:486 #: lib/Horde/Imap/Client/Socket/Pop3.php:498 msgid "Authentication failed." msgstr "" #: lib/Horde/Imap/Client/Auth/DigestMD5.php:158 #: lib/Horde/Imap/Client/Auth/Scram.php:124 msgid "Authentication failure." msgstr "" #: lib/Horde/Imap/Client/Socket.php:5027 msgid "Authentication was successful, but authorization failed." msgstr "" #: lib/Horde/Imap/Client/Interaction/Server/Tagged.php:44 msgid "Bad tagged response." msgstr "" #: lib/Horde/Imap/Client/Exception/SearchCharset.php:45 msgid "Cannot convert search query text to new charset" msgstr "" #: lib/Horde/Imap/Client/Base.php:1924 lib/Horde/Imap/Client/Base.php:1987 msgid "Cannot expunge read-only mailbox." msgstr "" #: lib/Horde/Imap/Client/Socket.php:4811 msgid "Charset used in search query is not supported on the mail server." msgstr "" #: lib/Horde/Imap/Client/Socket.php:1240 #, php-format msgid "Could not open mailbox \"%s\"." msgstr "" #: lib/Horde/Imap/Client/Socket.php:358 lib/Horde/Imap/Client/Socket.php:400 msgid "Could not open secure TLS connection to the IMAP server." msgstr "" #: lib/Horde/Imap/Client/Socket/Pop3.php:219 #: lib/Horde/Imap/Client/Socket/Pop3.php:233 msgid "Could not open secure connection to the POP3 server." msgstr "" #: lib/Horde/Imap/Client/Socket.php:4919 msgid "Could not save message data because it is too large." msgstr "" #: lib/Horde/Imap/Client/Socket.php:4910 msgid "Could not save message on server." msgstr "" #: lib/Horde/Imap/Client/Socket.php:606 #: lib/Horde/Imap/Client/Socket/Pop3.php:324 msgid "Error connecting to mail server." msgstr "" #: lib/Horde/Imap/Client/Utf7imap.php:128 #: lib/Horde/Imap/Client/Utf7imap.php:156 #: lib/Horde/Imap/Client/Utf7imap.php:163 #: lib/Horde/Imap/Client/Utf7imap.php:225 #: lib/Horde/Imap/Client/Utf7imap.php:245 #: lib/Horde/Imap/Client/Utf7imap.php:252 #: lib/Horde/Imap/Client/Utf7imap.php:263 #: lib/Horde/Imap/Client/Utf7imap.php:272 msgid "Error converting UTF7-IMAP string." msgstr "" #: lib/Horde/Imap/Client/Socket.php:4467 #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:83 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:214 #: lib/Horde/Imap/Client/Socket/Pop3.php:1382 msgid "Error when communicating with the mail server." msgstr "" #: lib/Horde/Imap/Client/Socket.php:4605 msgid "IMAP Server closed the connection." msgstr "" #: lib/Horde/Imap/Client/Socket.php:4591 msgid "IMAP error reported by server." msgstr "" #: lib/Horde/Imap/Client/Socket.php:4009 #, php-format msgid "Invalid METADATA entry: \"%s\"." msgstr "" #: lib/Horde/Imap/Client/Socket.php:4102 #, php-format msgid "Invalid METADATA value type \"%s\"." msgstr "" #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:148 msgid "Mail server closed the connection unexpectedly." msgstr "" #: lib/Horde/Imap/Client/Socket.php:573 msgid "Mail server denied authentication." msgstr "" #: lib/Horde/Imap/Client/Base.php:2257 lib/Horde/Imap/Client/Base.php:2536 #: lib/Horde/Imap/Client/Base.php:2808 lib/Horde/Imap/Client/Base.php:2893 msgid "Mailbox does not support mod-sequences." msgstr "" #: lib/Horde/Imap/Client/Socket.php:370 #: lib/Horde/Imap/Client/Socket/Pop3.php:201 msgid "No password provided." msgstr "" #: lib/Horde/Imap/Client/Socket.php:498 msgid "No supported IMAP authentication method could be found." msgstr "" #: lib/Horde/Imap/Client/Socket.php:5043 msgid "Operation failed due to a lack of a secure connection." msgstr "" #: lib/Horde/Imap/Client/Socket/Pop3.php:1448 msgid "POP3 error reported by server." msgstr "" #: lib/Horde/Imap/Client/Socket/Pop3.php:295 msgid "POP3 server denied authentication." msgstr "" #: lib/Horde/Imap/Client/Socket.php:5011 msgid "Remote server is temporarily unavailable." msgstr "" #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:75 msgid "Server closed the connection unexpectedly." msgstr "" #: lib/Horde/Imap/Client/Socket.php:388 msgid "Server does not support TLS connections." msgstr "" #: lib/Horde/Imap/Client/Socket/Pop3.php:219 msgid "Server does not support secure connections." msgstr "" #: lib/Horde/Imap/Client/Socket.php:809 #: lib/Horde/Imap/Client/Socket/Pop3.php:508 msgid "Server failed verification check." msgstr "" #: lib/Horde/Imap/Client/Socket.php:626 msgid "Server rejected connection." msgstr "" #: lib/Horde/Imap/Client/Socket/Connection/Pop3.php:47 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:64 #: lib/Horde/Imap/Client/Socket/Connection/Socket.php:110 msgid "Server write error." msgstr "" #: lib/Horde/Imap/Client/Socket.php:4964 msgid "The comparison algorithm was not recognized by the server." msgstr "" #: lib/Horde/Imap/Client/Socket.php:635 msgid "The mail server does not support IMAP4rev1 (RFC 3501)." msgstr "" #: lib/Horde/Imap/Client/Socket.php:5092 msgid "The mail server has denied the request." msgstr "" #: lib/Horde/Imap/Client/Socket.php:5074 msgid "The mail server is reporting corrupt data in your mailbox." msgstr "" #: lib/Horde/Imap/Client/Socket.php:4876 msgid "The mail server was unable to parse the contents of the mail message." msgstr "" #: lib/Horde/Imap/Client/Socket.php:4827 #, php-format msgid "" "The mail server was unable to parse the contents of the mail message: %s" msgstr "" #: lib/Horde/Imap/Client/Socket.php:4982 msgid "The metadata item could not be saved because it is too large." msgstr "" #: lib/Horde/Imap/Client/Socket.php:5000 msgid "" "The metadata item could not be saved because the maximum number of " "annotations has been exceeded." msgstr "" #: lib/Horde/Imap/Client/Socket.php:4991 msgid "" "The metadata item could not be saved because the server does not support " "private annotations." msgstr "" #: lib/Horde/Imap/Client/Socket.php:5110 msgid "The object could not be created because it already exists." msgstr "" #: lib/Horde/Imap/Client/Socket.php:5119 msgid "The object could not be deleted because it does not exist." msgstr "" #: lib/Horde/Imap/Client/Socket.php:5101 msgid "" "The operation failed because the quota has been exceeded on the mail server." msgstr "" #: lib/Horde/Imap/Client/Exception/NoSupportExtension.php:46 #, php-format msgid "The server does not support the %s extension." msgstr "" #: lib/Horde/Imap/Client/Socket.php:5128 msgid "The special-use attribute requested for the mailbox is not supported." msgstr "" #: lib/Horde/Imap/Client/Socket.php:5060 msgid "" "There was a temporary issue when attempting this operation. Please try again " "later." msgstr "" #: lib/Horde/Imap/Client/Socket.php:723 #: lib/Horde/Imap/Client/Socket/Pop3.php:379 msgid "Unexpected response from server when authenticating." msgstr "" #: lib/Horde/Imap/Client/Socket.php:839 #: lib/Horde/Imap/Client/Socket/Pop3.php:518 #, php-format msgid "Unknown authentication method: %s" msgstr "" #: lib/Horde/Imap/Client/Socket.php:5051 msgid "You do not have adequate permissions to carry out this operation." msgstr "" Horde_Imap_Client-2.29.15/migration/Horde/Imap/Client/1_horde_imap_client_base_tables.php0000664000175000017500000000523313150761653027375 0ustar janjan * @category Horde * @copyright 2013-2017 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class HordeImapClientBaseTables extends Horde_Db_Migration_Base { public function up() { if (in_array('horde_imap_client_data', $this->tables())) { return; } $t = $this->createTable('horde_imap_client_data', array( 'autoincrementKey' => 'messageid' )); $t->column('hostspec', 'string', array( 'limit' => 255, 'null' => false )); $t->column('mailbox', 'string', array( 'limit' => 255, 'null' => false )); $t->column('modified', 'bigint'); $t->column('port', 'integer', array( 'null' => false )); $t->column('username', 'string', array( 'limit' => 255, 'null' => false )); $t->end(); $this->addIndex( 'horde_imap_client_data', array('hostspec', 'mailbox', 'port', 'username') ); $t = $this->createTable('horde_imap_client_message', array( 'autoincrementKey' => false )); $t->column('data', 'binary'); $t->column('msguid', 'string', array( 'null' => false )); $t->column('messageid', 'bigint', array( 'null' => false )); $t->end(); $this->addIndex( 'horde_imap_client_message', array('msguid', 'messageid') ); $t = $this->createTable('horde_imap_client_metadata', array( 'autoincrementKey' => false )); $t->column('data', 'binary'); $t->column('field', 'string', array( 'null' => false )); $t->column('messageid', 'bigint', array( 'null' => false )); $t->end(); $this->addIndex( 'horde_imap_client_metadata', array('messageid') ); } public function down() { $this->dropTable('horde_imap_client_data'); $this->dropTable('horde_imap_client_message'); $this->dropTable('horde_imap_client_metadata'); } } Horde_Imap_Client-2.29.15/migration/Horde/Imap/Client/2_horde_imap_client_change_column_name.php0000664000175000017500000000243513150761653030735 0ustar janjan * @category Horde * @copyright 2014-2017 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class HordeImapClientChangeColumnName extends Horde_Db_Migration_Base { public function up() { if (array_key_exists('uid', $this->columns('horde_imap_client_data'))) { $this->renameColumn('horde_imap_client_data', 'uid', 'messageid'); } if (array_key_exists('uid', $this->columns('horde_imap_client_message'))) { $this->renameColumn('horde_imap_client_message', 'uid', 'messageid'); } if (array_key_exists('uid', $this->columns('horde_imap_client_metadata'))) { $this->renameColumn('horde_imap_client_metadata', 'uid', 'messageid'); } } public function down() { } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Base/MailboxTest.php0000664000175000017500000001375313150761653023265 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Base_MailboxTest extends PHPUnit_Framework_TestCase { private $ob; public function setUp() { $this->ob = new Horde_Imap_Client_Base_Mailbox(); } public function testInitialStatus() { $this->assertInstanceOf( 'Horde_Imap_Client_Ids_Map', $this->ob->map ); } /** * @dataProvider basicIntegerStatusPropertiesProvider */ public function testBasicIntegerStatusProperties($property) { $this->assertNull( $this->ob->getStatus($property) ); $this->ob->setStatus($property, 1); $this->assertSame( 1, $this->ob->getStatus($property) ); $this->ob->setStatus($property, "1"); $this->assertSame( 1, $this->ob->getStatus($property) ); } public function basicIntegerStatusPropertiesProvider() { return array( array(Horde_Imap_Client::STATUS_HIGHESTMODSEQ), array(Horde_Imap_Client::STATUS_MESSAGES), array(Horde_Imap_Client::STATUS_UIDNEXT), array(Horde_Imap_Client::STATUS_UIDVALIDITY) ); } /** * @dataProvider defaultSyncPropertiesProvider */ public function testDefaultSyncProperties($property) { $this->assertInternalType('array', $this->ob->getStatus($property)); $this->assertEmpty($this->ob->getStatus($property)); } public function defaultSyncPropertiesProvider() { return array( array(Horde_Imap_Client::STATUS_SYNCFLAGUIDS), array(Horde_Imap_Client::STATUS_SYNCVANISHED) ); } public function testFirstUnseen() { $this->assertFalse( $this->ob->getStatus(Horde_Imap_Client::STATUS_FIRSTUNSEEN) ); $this->ob->setStatus(Horde_Imap_Client::STATUS_MESSAGES, 1); $this->assertNull( $this->ob->getStatus(Horde_Imap_Client::STATUS_FIRSTUNSEEN) ); $this->ob->setStatus(Horde_Imap_Client::STATUS_FIRSTUNSEEN, 1); $this->assertSame( 1, $this->ob->getStatus(Horde_Imap_Client::STATUS_FIRSTUNSEEN) ); $this->ob->setStatus(Horde_Imap_Client::STATUS_FIRSTUNSEEN, "1"); $this->assertSame( 1, $this->ob->getStatus(Horde_Imap_Client::STATUS_FIRSTUNSEEN) ); } public function testDefaultPermFlags() { $this->assertTrue( in_array('\\*', $this->ob->getStatus(Horde_Imap_Client::STATUS_PERMFLAGS)) ); } public function testUnseen() { $this->assertEquals( 0, $this->ob->getStatus(Horde_Imap_Client::STATUS_UNSEEN) ); $this->ob->setStatus(Horde_Imap_Client::STATUS_MESSAGES, 1); $this->assertNull( $this->ob->getStatus(Horde_Imap_Client::STATUS_FIRSTUNSEEN) ); $this->ob->setStatus(Horde_Imap_Client::STATUS_UNSEEN, 1); $this->assertSame( 1, $this->ob->getStatus(Horde_Imap_Client::STATUS_UNSEEN) ); $this->ob->setStatus(Horde_Imap_Client::STATUS_UNSEEN, "1"); $this->assertSame( 1, $this->ob->getStatus(Horde_Imap_Client::STATUS_UNSEEN) ); } public function testStatusRecent() { $this->ob->setStatus(Horde_Imap_Client::STATUS_RECENT, 1); $this->ob->setStatus(Horde_Imap_Client::STATUS_RECENT, 1); $this->ob->setStatus(Horde_Imap_Client::STATUS_RECENT, 1); $this->assertEquals( 3, $this->ob->getStatus(Horde_Imap_Client::STATUS_RECENT_TOTAL) ); $this->ob->setStatus(Horde_Imap_Client::STATUS_RECENT, "1"); $this->assertEquals( 4, $this->ob->getStatus(Horde_Imap_Client::STATUS_RECENT_TOTAL) ); } public function testSyncModseqIsOnlySetOnce() { $this->ob->setStatus(Horde_Imap_Client::STATUS_SYNCMODSEQ, "1"); $this->ob->setStatus(Horde_Imap_Client::STATUS_SYNCMODSEQ, 2); $this->assertSame( 1, $this->ob->getStatus(Horde_Imap_Client::STATUS_SYNCMODSEQ) ); } /** * @dataProvider statusEntriesAreAdditiveProvider */ public function testStatusEntriesAreAdditive($val) { $this->ob->setStatus($val, array(1)); $this->ob->setStatus($val, array(2)); $this->assertEquals( array(1, 2), $this->ob->getStatus($val) ); } public function statusEntriesAreAdditiveProvider() { return array( array(Horde_Imap_Client::STATUS_SYNCFLAGUIDS), array(Horde_Imap_Client::STATUS_SYNCVANISHED) ); } public function testReset() { $this->ob->map->update((array(1 => 2))); $this->ob->setStatus(Horde_Imap_Client::STATUS_SYNCMODSEQ, 1); $this->ob->setStatus(Horde_Imap_Client::STATUS_RECENT_TOTAL, 1); $this->ob->reset(); $this->assertEquals( 0, count($this->ob->map) ); $this->assertEquals( 1, $this->ob->getStatus(Horde_Imap_Client::STATUS_SYNCMODSEQ) ); $this->assertEquals( 0, $this->ob->getStatus(Horde_Imap_Client::STATUS_RECENT_TOTAL) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Cache/CacheTest.php0000664000175000017500000000174313150761653023022 0ustar janjan * @category Horde * @copyright 2013-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Cache_CacheTest extends Horde_Imap_Client_Cache_TestBase { protected function _getBackend() { $factory_cache = new Horde_Test_Factory_Cache(); return new Horde_Imap_Client_Cache_Backend_Cache(array( 'cacheob' => $factory_cache->create() )); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Cache/DbTest.php0000664000175000017500000000260213150761653022337 0ustar janjan * @category Horde * @copyright 2013-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Cache_DbTest extends Horde_Imap_Client_Cache_TestBase { protected function _getBackend() { $factory_db = new Horde_Test_Factory_Db(); try { $db = $factory_db->create(array( 'migrations' => array( 'migrationsPath' => __DIR__ . '/../../../../../migration/Horde/Imap/Client' ) )); } catch (Horde_Test_Exception $e) { $this->markTestSkipped('Sqlite not available.'); } return new Horde_Imap_Client_Cache_Backend_Db(array( 'db' => $db, 'hostspec' => self::HOSTSPEC, 'port' => self::PORT, 'username' => self::USERNAME )); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Cache/HashtableTest.php0000664000175000017500000000221513150761653023705 0ustar janjan * @category Horde * @copyright 2013-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Cache_HashtableTest extends Horde_Imap_Client_Cache_TestBase { protected function _getBackend() { $factory_hashtable = new Horde_Test_Factory_Hashtable(); try { return new Horde_Imap_Client_Cache_Backend_Hashtable(array( 'hashtable' => $factory_hashtable->create() )); } catch (Horde_Test_Exception $e) { $this->markTestSkipped('HashTable not available.'); } } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Cache/MongoTest.php0000664000175000017500000000332713150761653023076 0ustar janjan * @category Horde * @copyright 2013-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Cache_MongoTest extends Horde_Imap_Client_Cache_TestBase { private $_dbname = 'horde_imap_client_cache_mongodbtest'; private $_mongo; protected function _getBackend() { if (($config = self::getConfig('IMAPCLIENT_TEST_CONFIG', __DIR__ . '/..')) && isset($config['mongo'])) { $factory = new Horde_Test_Factory_Mongo(); $this->_mongo = $factory->create(array( 'config' => $config['mongo'], 'dbname' => $this->_dbname )); } if (empty($this->_mongo)) { $this->markTestSkipped('MongoDB not available.'); } return new Horde_Imap_Client_Cache_Backend_Mongo(array( 'hostspec' => self::HOSTSPEC, 'mongo_db' => $this->_mongo, 'port' => self::PORT, 'username' => self::USERNAME )); } public function tearDown() { if (!empty($this->_mongo)) { $this->_mongo->selectDB(null)->drop(); } parent::tearDown(); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Cache/TestBase.php0000664000175000017500000001620513150761653022670 0ustar janjan * @category Horde * @copyright 2013-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ abstract class Horde_Imap_Client_Cache_TestBase extends Horde_Test_Case { const HOSTSPEC = 'foo.example.com'; const PORT = 143; const USERNAME = 'baz'; private $_cache; public function setUp() { $baseob = $this->getMock('Horde_Imap_Client_Socket', array(), array(), '', false); $baseob->expects($this->any()) ->method('getParam') ->will($this->returnCallback(array($this, '_baseobHandler'))); $this->_cache = new Horde_Imap_Client_Cache(array( 'backend' => $this->_getBackend(), 'baseob' => $baseob )); /* Setup DB with dummy data. Yes... I realize this sort of relies * on set() and setMetaData() to be working, but otherwise we have to * track INTERNAL changes to the driver from this EXTERNAL * perspective. */ $this->_cache->set('foo1', array( '100' => array( 'subject' => 'Test1' ), '101' => array( 'subject' => 'Test2' ), '102' => array( 'from' => 'foo2@example.com', 'subject' => 'Test3' ), '103' => array( 'subject' => 'Test4' ) ), 1); $this->_cache->set('foo2', array( '300' => array( 'from' => 'foo3@example.com', ), '400' => array( 'subject' => 'Test 5' ) ), 1); $this->_cache->setMetaData('foo1', '1', array( 'bar' => 'foo' )); } abstract protected function _getBackend(); public function _baseobHandler($param) { switch ($param) { case 'hostspec': return self::HOSTSPEC; case 'port': return self::PORT; case 'username': return self::USERNAME; } } public function tearDown() { unset($this->_cache); } public function testGet() { $res = $this->_cache->get('foo1', array(100, 101, 102), array(), 1); $this->assertEquals( 3, count($res) ); $this->assertEquals( 1, count($res['100']) ); $this->assertEquals( 1, count($res['101']) ); $this->assertEquals( 2, count($res['102']) ); $this->assertEquals( 'Test3', $res['102']['subject'] ); $res = $this->_cache->get('foo2', array(300, 301), array(), 1); $this->assertEquals( 1, count($res) ); $this->assertEquals( 'foo3@example.com', $res['300']['from'] ); $this->assertFalse(array_key_exists('301', $res)); $res = $this->_cache->get('foo2', array(300), array('to'), 1); $this->assertFalse(array_key_exists('to', $res['300'])); $res = $this->_cache->get('foo3', array(400), array(), 1); $this->assertEquals( 0, count($res) ); } public function testGetCachedUids() { $res = $this->_cache->get('foo1', array(), array(), 1); $this->assertEquals( 4, count($res) ); $res = $this->_cache->get('foo2', array(), array(), 1); $this->assertEquals( 2, count($res) ); $res = $this->_cache->get('foo3', array(), array(), 1); $this->assertEquals( 0, count($res) ); } public function testSet() { /* Insert */ $data = array( '100' => array( 'size' => 5, 'to' => 'foo3@example2.com' ), '101' => array( 'to' => 'foo3@example2.com' ) ); $this->_cache->set('foo1', $data, 1); $res = $this->_cache->get('foo1', array(100, 101), array(), 1); $this->assertEquals( 3, count($res['100']) ); $this->assertEquals( 2, count($res['101']) ); /* Update */ $data = array( '102' => array( 'subject' => 'ABC' ) ); $this->_cache->set('foo1', $data, 1); $res = $this->_cache->get('foo1', array(102), array(), 1); $this->assertEquals( 'ABC', $res['102']['subject'] ); } public function testGetMetaData() { $res = $this->_cache->getMetaData('foo1', '1', array()); $this->assertEquals( 2, count($res) ); $res = $this->_cache->getMetaData('foo1', '1', array('uidvalid')); $this->assertEquals( 1, count($res) ); $this->assertEquals( 1, $res['uidvalid'] ); $res = $this->_cache->getMetaData('foo2', '1', array()); $this->assertEquals( 1, count($res) ); $this->assertFalse(array_key_exists('bar', $res)); } public function testSetMetaData() { /* Insert */ $this->_cache->setMetaData('foo1', '1', array('baz' => 'ABC')); $res = $this->_cache->getMetaData('foo1', '1', array('baz')); $this->assertEquals( 'ABC', $res['baz'] ); /* Update */ $this->_cache->setMetaData('foo1', '1', array('baz' => 'DEF')); $res = $this->_cache->getMetaData('foo1', '1', array('baz')); $this->assertEquals( 'DEF', $res['baz'] ); } public function testDeleteMessages() { $this->_cache->deleteMsgs('foo1', array(100, 101)); $this->assertEquals( 2, count($this->_cache->get('foo1', array(), array(), 1)) ); /* Total count shouldn't change here. */ $this->_cache->deleteMsgs('foo1', array(100, 101)); $this->assertEquals( 2, count($this->_cache->get('foo1', array(), array(), 1)) ); } public function testDeleteMailbox() { $this->_cache->deleteMailbox('foo1'); $this->assertEquals( 0, count($this->_cache->get('foo1', array(), array(), 1)) ); } public function testSerialization() { $this->assertInstanceOf( get_class($this->_cache), unserialize(serialize($this->_cache)) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Capability/ImapTest.php0000664000175000017500000000641013150761653024630 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Capability_ImapTest extends PHPUnit_Framework_TestCase { public function testImpliedExtensions() { $c = new Horde_Imap_Client_Data_Capability_Imap(); $c->add('QRESYNC'); $this->assertTrue($c->query('QRESYNC')); /* QRESYNC implies CONDSTORE and ENABLE. */ $this->assertTrue($c->query('CONDSTORE')); $this->assertTrue($c->query('ENABLE')); } public function testCmdlengthProperty() { $c = new Horde_Imap_Client_Data_Capability_Imap(); $this->assertEquals( 2000, $c->cmdlength ); $c->add('CONDSTORE'); $this->assertEquals( 8000, $c->cmdlength ); } public function isEnabled() { $c = new Horde_Imap_Client_Data_Capability_Imap(); $c->add('FOO'); $this->assertEquals( array(), $c->isEnabled() ); $this->assertFalse($c->isEnabled('FOO')); $c->enable('FOO'); $this->assertEquals( array('FOO'), $c->isEnabled() ); $this->assertTrue($c->isEnabled('FOO')); } public function testEnable() { $c = new Horde_Imap_Client_Data_Capability_Imap(); $c->enable('FOO'); $this->assertTrue($c->isEnabled('Foo')); $c->enable('BAR=BAZ'); $this->assertTrue($c->isEnabled('bar=baz')); $c->enable('FOO', false); $this->assertFalse($c->isEnabled('foo')); } public function testObserver() { $c = new Horde_Imap_Client_Data_Capability_Imap(); $mock = $this->getMock('SplObserver'); $mock->expects($this->once()) ->method('update') ->with($this->equalTo($c)); $c->attach($mock); $c->enable('FOO'); /* Duplicate enable should not trigger update() again. */ $c->enable('FOO'); } public function testSerialize() { $c = new Horde_Imap_Client_Data_Capability_Imap(); $c->add('FOO', 'A'); $c->add('FOO', 'B'); $c->add('BAR'); $c->enable('BAR'); $mock = $this->getMock('SplObserver'); $mock->expects($this->never()) ->method('update') ->with($this->equalTo($c)); $c->attach($mock); $c_copy = unserialize(serialize($c)); $this->assertTrue($c_copy->query('FOO', 'A')); $this->assertTrue($c_copy->query('FOO', 'B')); $this->assertTrue($c_copy->query('BAR')); $this->assertFalse($c_copy->isEnabled('BAR')); $c_copy->add('BAZ'); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Fetch/FetchPop3Test.php0000664000175000017500000000160213150761653024503 0ustar janjan * @category Horde * @copyright 2015-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Fetch_FetchPop3Test extends Horde_Imap_Client_Data_Fetch_TestBase { protected function _setUp() { $this->ob_class = 'Horde_Imap_Client_Data_Fetch_Pop3'; } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Fetch/FetchTest.php0000664000175000017500000000156413150761653023750 0ustar janjan * @category Horde * @copyright 2015-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Fetch_FetchTest extends Horde_Imap_Client_Data_Fetch_TestBase { protected function _setUp() { $this->ob_class = 'Horde_Imap_Client_Data_Fetch'; } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Fetch/TestBase.php0000664000175000017500000004523413150761653023573 0ustar janjan * @category Horde * @copyright 2015-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ abstract class Horde_Imap_Client_Data_Fetch_TestBase extends PHPUnit_Framework_TestCase { private $ob; /* Set in child class via _setUp(). */ protected $ob_class; abstract protected function _setUp(); public function setUp() { $this->_setUp(); $this->ob = new Horde_Imap_Client_Data_Fetch($this->ob_class); } /** * @dataProvider fullMsgProvider */ public function testFullMsg($stream_ob, $set_stream) { $string = strval($stream_ob); $stream_ob->rewind(); $this->ob->setFullMsg($set_stream ? $stream_ob->stream : $string); $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $this->assertEquals( $string, $val->getFullMsg(false) ); $this->assertEquals( $string, stream_get_contents($val->getFullMsg(true)) ); } } public function fullMsgProvider() { $stream = new Horde_Stream_String(array('string' => 'Foo')); return array( array( clone $stream, false ), array( clone $stream, true ) ); } public function testStructure() { $this->assertInstanceOf( 'Horde_Mime_Part', $this->ob->getStructure() ); $test = new Horde_Mime_Part(); $test->setType('image/foo'); $this->ob->setStructure($test); $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $ret = $val->getStructure(); $this->assertInstanceOf( 'Horde_Mime_Part', $ret ); $this->assertEquals( 'image/foo', $ret->getType('image/foo') ); } } /** * @dataProvider headersProvider */ public function testHeaders($input, $string) { $label = 'foo'; if (!is_null($input)) { $this->ob->setHeaders($label, $input); } $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $this->assertEquals( $string, $val->getHeaders($label) ); $stream = $val->getHeaders( $label, constant($this->ob_class . '::HEADER_STREAM') ); rewind($stream); $this->assertEquals( $string, stream_get_contents($stream) ); $hdr_ob = $val->getHeaders( $label, constant($this->ob_class . '::HEADER_PARSE') ); $this->assertInstanceOf( 'Horde_Mime_Headers', $hdr_ob ); $this->assertEquals( trim($string), trim($hdr_ob->toString(array('nowrap' => true))) ); } } public function headersProvider() { $hdrs = new Horde_Mime_Headers(); $hdrs->addHeader('From', 'test@example.com'); return array( array( null, '' ), array( "From: test@example.com\n\n", "From: test@example.com\n\n" ), array( $hdrs, "From: test@example.com\n\n" ) ); } /** * @dataProvider headerTextProvider */ public function testHeaderText($input, $string) { $id = 1; if (!is_null($input)) { $this->ob->setHeaderText($id, $input); } $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $this->assertEquals( $string, $val->getHeaderText($id) ); $stream = $val->getHeaderText( $id, constant($this->ob_class . '::HEADER_STREAM') ); rewind($stream); $this->assertEquals( $string, stream_get_contents($stream) ); $hdr_ob = $val->getHeaderText( $id, constant($this->ob_class . '::HEADER_PARSE') ); $this->assertInstanceOf( 'Horde_Mime_Headers', $hdr_ob ); $this->assertEquals( trim($string), trim($hdr_ob->toString(array('nowrap' => true))) ); } } public function headerTextProvider() { return array( array( null, '' ), array( "From: test@example.com\n\n", "From: test@example.com\n\n" ) ); } /** * @dataProvider mimeHeaderProvider */ public function testMimeHeader($input, $string) { $id = 1; if (!is_null($input)) { $this->ob->setMimeHeader($id, $input); } $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $this->assertEquals( $string, $val->getMimeHeader($id) ); $stream = $val->getMimeHeader( $id, constant($this->ob_class . '::HEADER_STREAM') ); rewind($stream); $this->assertEquals( $string, stream_get_contents($stream) ); $hdr_ob = $val->getMimeHeader( $id, constant($this->ob_class . '::HEADER_PARSE') ); $this->assertInstanceOf( 'Horde_Mime_Headers', $hdr_ob ); $this->assertEquals( trim($string), trim($hdr_ob->toString(array('nowrap' => true))) ); } } public function mimeHeaderProvider() { return array( array( null, '' ), array( "From: test@example.com\n\n", "From: test@example.com\n\n" ) ); } /** * @dataProvider bodyPartProvider */ public function testBodyPart($stream_ob, $set_stream, $decode) { $id = 1; $string = strval($stream_ob); $stream_ob->rewind(); if (strlen($string)) { $this->ob->setBodyPart( $id, $set_stream ? $stream_ob->stream : $string, $decode ); } $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $this->assertEquals( $string, $val->getBodyPart($id, false) ); $this->assertEquals( $string, stream_get_contents($val->getBodyPart($id, true)) ); $this->assertEquals( $decode, $this->ob->getBodyPartDecode($id) ); } } public function bodyPartProvider() { $stream = new Horde_Stream_String(array('string' => 'Foo')); $empty_stream = new Horde_Stream(); return array( array( clone $stream, false, null ), array( clone $stream, false, '8bit' ), array( clone $stream, false, 'binary' ), array( clone $empty_stream, false, null ), array( clone $stream, true, null ), array( clone $stream, true, '8bit' ), array( clone $stream, true, 'binary' ), array( clone $empty_stream, true, null ) ); } /** * @dataProvider bodyPartSizeProvider */ public function testBodyPartSize($size) { $id = 1; if (!is_null($size)) { $this->ob->setBodyPartSize($id, $size); } $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $this->assertEquals( $size, $val->getBodyPartSize($id) ); } } public function bodyPartSizeProvider() { return array( array(200), array(null) ); } /** * @dataProvider bodyTextProvider */ public function testBodyText($stream_ob, $set_stream) { $id = 1; $string = strval($stream_ob); $stream_ob->rewind(); if (strlen($string)) { $this->ob->setBodyText( $id, $set_stream ? $stream_ob->stream : $string ); } $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $this->assertEquals( $string, $val->getBodyText($id, false) ); $this->assertEquals( $string, stream_get_contents($val->getBodyText($id, true)) ); } } public function bodyTextProvider() { $stream = new Horde_Stream_String(array('string' => 'Foo')); return array( array( clone $stream, false ), array( clone $stream, true ) ); } /** * @dataProvider envelopeProvider */ public function testEnvelope($data, $to) { if (!is_null($data)) { $this->ob->setEnvelope($data); } $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $envelope = $val->getEnvelope(); $this->assertInstanceOf( 'Horde_Imap_Client_Data_Envelope', $envelope ); $addr_ob = $envelope->to; $this->assertInstanceof( 'Horde_Mail_Rfc822_List', $addr_ob ); $this->assertEquals( $to, strval($addr_ob) ); } } public function envelopeProvider() { $addr = new Horde_Imap_Client_Data_Envelope(); $addr->to = 'foo@example.com'; return array( array( array('to' => 'foo@example.com'), 'foo@example.com' ), array( $addr, 'foo@example.com' ), array( null, '' ) ); } /** * @dataProvider flagsProvider */ public function testFlags($flags, $expected) { $this->ob->setFlags($flags); $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $f = $this->ob->getFlags(); $this->assertEquals( $expected, $f ); } } public function flagsProvider() { return array( array( array('foo'), array('foo') ), array( array(), array(), ), array( array('FoO', 'BAR', ' baZ '), array('foo', 'bar', 'baz') ) ); } /** * @dataProvider imapDateProvider */ public function testImapDate($date, $expected) { if (!is_null($date)) { $this->ob->setImapDate($date); } $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $d = $this->ob->getImapDate(); $this->assertInstanceOf( 'Horde_Imap_Client_DateTime', $d ); $this->assertEquals( is_null($expected) ? time() : $expected, intval(strval($d)) ); } } public function imapDateProvider() { return array( array( '12 Sep 2007 15:49:12 UT', 1189612152 ), array( new Horde_Imap_Client_DateTime('12 Sep 2007 15:49:12 UT'), 1189612152 ), array( null, null ) ); } /** * @dataProvider sizeProvider */ public function testSize($size, $expected) { if (!is_null($size)) { $this->ob->setSize($size); } $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $this->assertEquals( $expected, $this->ob->getSize() ); } } public function sizeProvider() { return array( array( 200, 200 ), array( null, 0 ) ); } /** * @dataProvider uidProvider */ public function testUid($uid, $expected) { if (!is_null($uid)) { $this->ob->setUid($uid); } $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $this->assertEquals( $expected, $this->ob->getUid() ); } } public function uidProvider() { return array( array( 200, 200 ), array( null, null ) ); } /** * @dataProvider seqProvider */ public function testSeq($seq, $expected) { if (!is_null($seq)) { $this->ob->setSeq($seq); } $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $this->assertEquals( $expected, $this->ob->getSeq() ); } } public function seqProvider() { return array( array( 200, 200 ), array( null, null ) ); } /** * @dataProvider modSeqProvider */ public function testModSeq($modseq, $expected) { if (!is_null($modseq)) { $this->ob->setModSeq($modseq); } $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $this->assertEquals( $expected, $this->ob->getModSeq() ); } } public function modSeqProvider() { return array( array( 200, 200 ), array( null, null ) ); } /** * @dataProvider downgradedProvider */ public function testDowngraded($downgraded, $expected) { if (!is_null($downgraded)) { $this->ob->setDowngraded($downgraded); } $serialize_ob = unserialize(serialize($this->ob)); foreach (array($this->ob, $serialize_ob) as $val) { $this->assertEquals( $expected, $this->ob->isDowngraded() ); } } public function downgradedProvider() { return array( array( true, true ), array( false, false ), array( null, false ) ); } public function testMerge() { $this->ob->setUid(1); $this->assertEquals( 1, $this->ob->getUid() ); $this->assertNull($this->ob->getSeq()); $ob2 = new Horde_Imap_Client_Data_Fetch($this->ob_class); $ob2->setUid(2); $ob2->setSeq(2); $this->ob->merge($ob2); $this->assertEquals( 2, $this->ob->getUid() ); $this->assertEquals( 2, $this->ob->getSeq() ); } public function testObjectStateFunctions() { $this->assertEmpty($this->ob->getRawData()); $this->assertFalse($this->ob->exists(Horde_Imap_Client::FETCH_UID)); $this->assertFalse($this->ob->exists(Horde_Imap_Client::FETCH_SEQ)); $this->assertTrue($this->ob->isDefault()); $this->ob->setUid(1); $this->assertNotEmpty($this->ob->getRawData()); $this->assertTrue($this->ob->exists(Horde_Imap_Client::FETCH_UID)); $this->assertFalse($this->ob->exists(Horde_Imap_Client::FETCH_SEQ)); $this->assertFalse($this->ob->isDefault()); } public function testClone() { $stream = new Horde_Stream_String(array('string' => 'Foo')); $stream->rewind(); $this->ob->setFullMsg($stream->stream); $ob2 = clone $this->ob; $this->ob->setFullMsg('Bar'); $this->assertEquals( 'Bar', $this->ob->getFullMsg() ); $this->assertEquals( 'Foo', $ob2->getFullMsg() ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/Astring/NonasciiTest.php0000664000175000017500000000173213150761653026265 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_Astring_NonasciiTest extends Horde_Imap_Client_Data_Format_AstringTest { protected $cname = 'Horde_Imap_Client_Data_Format_Astring_Nonascii'; public function nonasciiInputProvider() { return array( array(true) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/Mailbox/ListMailboxTest.php0000664000175000017500000000601213150761653026731 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_Mailbox_ListMailboxTest extends Horde_Imap_Client_Data_Format_Mailbox_TestBase { protected $cname = 'Horde_Imap_Client_Data_Format_ListMailbox'; public function stringRepresentationProvider() { return array( array('Foo', 'Foo'), array('Foo(', 'Foo('), array('Foo]', 'Foo]'), array('Foo%Bar', 'Foo%Bar'), array('Foo*Bar', 'Foo*Bar'), array('Envoyé', 'Envoyé') ); } public function escapeProvider() { return array( array('Foo', 'Foo'), array('Foo(', '"Foo("'), array('Foo]', 'Foo]'), /* Don't escape '%'. */ array('Foo%Bar', 'Foo%Bar'), /* Don't escape '*'. */ array('Foo*Bar', 'Foo*Bar'), array('Envoyé', 'Envoy&AOk-') ); } public function verifyProvider() { return array( array('Foo', false), array('Foo(', false), array('Foo]', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', false) ); } public function binaryProvider() { return array( array('Foo', false), array('Foo(', false), array('Foo]', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', false) ); } public function literalProvider() { return array( array('Foo', false), array('Foo(', false), array('Foo]', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', false) ); } public function quotedProvider() { return array( array('Foo', false), array('Foo(', true), array('Foo]', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', false) ); } public function escapeStreamProvider() { return array( array('Foo', '"Foo"'), array('Foo(', '"Foo("'), array('Foo]', '"Foo]"'), array('Foo%Bar', '"Foo%Bar"'), array('Foo*Bar', '"Foo*Bar"'), array('Envoyé', '"Envoy&AOk-"') ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/Mailbox/ListMailboxUtf8Test.php0000664000175000017500000000601613150761653027504 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_Mailbox_ListMailboxUtf8Test extends Horde_Imap_Client_Data_Format_Mailbox_TestBase { protected $cname = 'Horde_Imap_Client_Data_Format_ListMailbox_Utf8'; public function stringRepresentationProvider() { return array( array('Foo', 'Foo'), array('Foo(', 'Foo('), array('Foo]', 'Foo]'), array('Foo%Bar', 'Foo%Bar'), array('Foo*Bar', 'Foo*Bar'), array('Envoyé', 'Envoyé') ); } public function escapeProvider() { return array( array('Foo', 'Foo'), array('Foo(', '"Foo("'), array('Foo]', 'Foo]'), /* Don't escape '%'. */ array('Foo%Bar', 'Foo%Bar'), /* Don't escape '*'. */ array('Foo*Bar', 'Foo*Bar'), array('Envoyé', '"Envoyé"') ); } public function verifyProvider() { return array( array('Foo', false), array('Foo(', false), array('Foo]', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', false) ); } public function binaryProvider() { return array( array('Foo', false), array('Foo(', false), array('Foo]', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', false) ); } public function literalProvider() { return array( array('Foo', false), array('Foo(', false), array('Foo]', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', false) ); } public function quotedProvider() { return array( array('Foo', false), array('Foo(', true), array('Foo]', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', true) ); } public function escapeStreamProvider() { return array( array('Foo', '"Foo"'), array('Foo(', '"Foo("'), array('Foo]', '"Foo]"'), array('Foo%Bar', '"Foo%Bar"'), array('Foo*Bar', '"Foo*Bar"'), array('Envoyé', '"Envoyé"') ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/Mailbox/MailboxTest.php0000664000175000017500000000615513150761653026105 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_Mailbox_MailboxTest extends Horde_Imap_Client_Data_Format_Mailbox_TestBase { protected $cname = 'Horde_Imap_Client_Data_Format_Mailbox'; public function stringRepresentationProvider() { return array( array('Foo', 'Foo'), array('Foo(', 'Foo('), array('Foo%Bar', 'Foo%Bar'), array('Foo*Bar', 'Foo*Bar'), array('Envoyé', 'Envoyé') ); } public function escapeProvider() { return array( array('Foo', 'Foo'), array('Foo(', '"Foo("'), array('Foo%Bar', '"Foo%Bar"'), array('Foo*Bar', '"Foo*Bar"'), array('Envoyé', 'Envoy&AOk-') ); } public function verifyProvider() { return array( array('Foo', false), array('Foo(', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', false) ); } public function binaryProvider() { return array( array('Foo', false), array('Foo(', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', false) ); } public function literalProvider() { return array( array('Foo', false), array('Foo(', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', false) ); } public function quotedProvider() { return array( array('Foo', false), array('Foo(', true), array('Foo%Bar', true), array('Foo*Bar', true), array('Envoyé', false) ); } public function escapeStreamProvider() { return array( array('Foo', '"Foo"'), array('Foo(', '"Foo("'), array('Foo%Bar', '"Foo%Bar"'), array('Foo*Bar', '"Foo*Bar"'), array('Envoyé', '"Envoy&AOk-"') ); } public function testBadInput() { /* @todo: Change in Horde_Imap_Client 3.0 to detect Exception, instead * of blank mailbox name. */ $ob = new Horde_Imap_Client_Data_Format_Mailbox("foo\0"); /* binary() call creates the blank string representation. */ $this->assertFalse($ob->binary()); $this->assertEquals( '', strval($ob) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/Mailbox/MailboxUtf8Test.php0000664000175000017500000000556413150761653026657 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_Mailbox_MailboxUtf8Test extends Horde_Imap_Client_Data_Format_Mailbox_TestBase { protected $cname = 'Horde_Imap_Client_Data_Format_Mailbox_Utf8'; public function stringRepresentationProvider() { return array( array('Foo', 'Foo'), array('Foo(', 'Foo('), array('Foo%Bar', 'Foo%Bar'), array('Foo*Bar', 'Foo*Bar'), array('Envoyé', 'Envoyé') ); } public function escapeProvider() { return array( array('Foo', 'Foo'), array('Foo(', '"Foo("'), array('Foo%Bar', '"Foo%Bar"'), array('Foo*Bar', '"Foo*Bar"'), array('Envoyé', '"Envoyé"') ); } public function verifyProvider() { return array( array('Foo', false), array('Foo(', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', false) ); } public function binaryProvider() { return array( array('Foo', false), array('Foo(', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', false) ); } public function literalProvider() { return array( array('Foo', false), array('Foo(', false), array('Foo%Bar', false), array('Foo*Bar', false), array('Envoyé', false) ); } public function quotedProvider() { return array( array('Foo', false), array('Foo(', true), array('Foo%Bar', true), array('Foo*Bar', true), array('Envoyé', true) ); } public function escapeStreamProvider() { return array( array('Foo', '"Foo"'), array('Foo(', '"Foo("'), array('Foo%Bar', '"Foo%Bar"'), array('Foo*Bar', '"Foo*Bar"'), array('Envoyé', '"Envoyé"') ); } /** * @expectedException Horde_Imap_Client_Data_Format_Exception */ public function testBadInput() { new $this->cname("foo\1"); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/Mailbox/TestBase.php0000664000175000017500000000613013150761653025355 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ abstract class Horde_Imap_Client_Data_Format_Mailbox_TestBase extends PHPUnit_Framework_TestCase { protected $cname; /** * @dataProvider stringRepresentationProvider */ public function testStringRepresentation($mbox, $str) { $m = new $this->cname($mbox); $this->assertEquals( $str, strval($m) ); } abstract public function stringRepresentationProvider(); /** * @dataProvider escapeProvider */ public function testEscape($mbox, $str) { $m = new $this->cname($mbox); $this->assertEquals( $str, $m->escape() ); } abstract public function escapeProvider(); /** * @dataProvider verifyProvider */ public function testVerify($mbox, $exception) { $m = new $this->cname($mbox); try { $m->verify(); if ($exception) { $this->fail(); } } catch (Exception $e) { if (!$exception) { $this->fail(); } } } abstract public function verifyProvider(); /** * @dataProvider binaryProvider */ public function testBinary($mbox, $expected) { $m = new $this->cname($mbox); if ($expected) { $this->assertTrue($m->binary()); } else { $this->assertFalse($m->binary()); } } abstract public function binaryProvider(); /** * @dataProvider literalProvider */ public function testLiteral($mbox, $expected) { $m = new $this->cname($mbox); if ($expected) { $this->assertTrue($m->literal()); } else { $this->assertFalse($m->literal()); } } abstract public function literalProvider(); /** * @dataProvider quotedProvider */ public function testQuoted($mbox, $expected) { $m = new $this->cname($mbox); if ($expected) { $this->assertTrue($m->quoted()); } else { $this->assertFalse($m->quoted()); } } abstract public function quotedProvider(); /** * @dataProvider escapeStreamProvider */ public function testEscapeStream($mbox, $expected) { $m = new $this->cname($mbox); $this->assertEquals( $expected, stream_get_contents($m->escapeStream(), -1, 0) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/Nstring/NonasciiTest.php0000664000175000017500000000173213150761653026302 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_Nstring_NonasciiTest extends Horde_Imap_Client_Data_Format_NstringTest { protected $cname = 'Horde_Imap_Client_Data_Format_Nstring_Nonascii'; public function nonasciiInputProvider() { return array( array(true) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/String/NonasciiTest.php0000664000175000017500000000172613150761653026127 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_String_NonasciiTest extends Horde_Imap_Client_Data_Format_StringTest { protected $cname = 'Horde_Imap_Client_Data_Format_String_Nonascii'; public function nonasciiInputProvider() { return array( array(true) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/String/TestBase.php0000664000175000017500000000740113150761653025232 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ abstract class Horde_Imap_Client_Data_Format_String_TestBase extends Horde_Imap_Client_Data_Format_TestBase { protected $cname; /** * @dataProvider stringRepresentationProvider */ public function testStringRepresentation($ob, $expected) { $this->assertEquals( $expected, strval($ob) ); } abstract public function stringRepresentationProvider(); /** * @dataProvider escapeProvider */ public function testEscape($ob, $expected) { try { $this->assertEquals( $expected, $ob->escape() ); } catch (Horde_Imap_Client_Data_Format_Exception $e) { if ($expected !== false) { $this->fail(); } } } abstract public function escapeProvider(); /** * @dataProvider verifyProvider */ public function testVerify($ob, $result) { try { $ob->verify(); if (!$result) { $this->fail(); } } catch (Horde_Imap_Client_Data_Format_Exception $e) { if ($result) { $this->fail(); } } } abstract public function verifyProvider(); /** * @dataProvider binaryProvider */ public function testBinary($ob, $expected) { if ($expected) { $this->assertTrue($ob->binary()); } else { $this->assertFalse($ob->binary()); } } abstract public function binaryProvider(); /** * @dataProvider literalProvider */ public function testLiteral($ob, $expected) { if ($expected) { $this->assertTrue($ob->literal()); } else { $this->assertFalse($ob->literal()); } } abstract public function literalProvider(); /** * @dataProvider quotedProvider */ public function testQuoted($ob, $expected) { if ($expected) { $this->assertTrue($ob->quoted()); } else { $this->assertFalse($ob->quoted()); } } abstract public function quotedProvider(); /** * @dataProvider escapeStreamProvider */ public function testEscapeStream($ob, $expected) { try { $this->assertEquals( $expected, stream_get_contents($ob->escapeStream(), -1, 0) ); } catch (Horde_Imap_Client_Data_Format_Exception $e) { if ($expected !== false) { $this->fail(); } } } abstract public function escapeStreamProvider(); /** * @dataProvider nonasciiInputProvider */ public function testNonasciiInput($result) { try { new $this->cname('Envoyé'); if (!$result) { $this->fail(); } } catch (Horde_Imap_Client_Data_Format_Exception $e) { if ($result) { $this->fail(); } } } abstract public function nonasciiInputProvider(); } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/AstringTest.php0000664000175000017500000000470113150761653024521 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_AstringTest extends Horde_Imap_Client_Data_Format_String_TestBase { protected $cname = 'Horde_Imap_Client_Data_Format_Astring'; protected function getTestObs() { return array( new $this->cname('Foo'), new $this->cname('Foo('), /* This is an invalid atom, but valid (non-quoted) astring. */ new $this->cname('Foo]'), new $this->cname('') ); } public function stringRepresentationProvider() { return $this->createProviderArray(array( 'Foo', 'Foo(', 'Foo]', '' )); } public function escapeProvider() { return $this->createProviderArray(array( 'Foo', '"Foo("', 'Foo]', '""' )); } public function verifyProvider() { return $this->createProviderArray(array( true, true, true, true )); } public function binaryProvider() { return $this->createProviderArray(array( false, false, false, false )); } public function literalProvider() { return $this->binaryProvider(); } public function quotedProvider() { return $this->createProviderArray(array( false, true, false, true )); } public function escapeStreamProvider() { return $this->createProviderArray(array( '"Foo"', '"Foo("', '"Foo]"', '""' )); } public function nonasciiInputProvider() { return array( array(false) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/AtomTest.php0000664000175000017500000000600213150761653024006 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_AtomTest extends Horde_Imap_Client_Data_Format_TestBase { protected function getTestObs() { return array( new Horde_Imap_Client_Data_Format_Atom('Foo'), /* Illegal atom character. */ new Horde_Imap_Client_Data_Format_Atom('Foo('), /* This is an invalid atom, but valid (non-quoted) astring. */ new Horde_Imap_Client_Data_Format_Atom('Foo]'), new Horde_Imap_Client_Data_Format_Atom('') ); } /** * @dataProvider stringRepresentationProvider */ public function testStringRepresentation($ob, $expected) { $this->assertEquals( $expected, strval($ob) ); } public function stringRepresentationProvider() { return $this->createProviderArray(array( 'Foo', 'Foo(', 'Foo]', '', )); } /** * @dataProvider escapeProvider */ public function testEscape($ob, $expected) { $this->assertEquals( $expected, $ob->escape() ); } public function escapeProvider() { return $this->createProviderArray(array( 'Foo', 'Foo(', 'Foo]', '""', )); } /** * @dataProvider verifyProvider */ public function testVerify($ob, $expected) { try { $ob->verify(); if ($expected) { $this->fail(); } } catch (Horde_Imap_Client_Data_Format_Exception $e) { if (!$expected) { $this->fail(); } } } public function verifyProvider() { return $this->createProviderArray(array( false, true, true, false )); } /** * @dataProvider stripNonAtomCharactersProvider */ public function testStripNonAtomCharacters($str, $expected) { $atom = new Horde_Imap_Client_Data_Format_Atom($str); $this->assertEquals( $expected, $atom->stripNonAtomCharacters() ); } public function stripNonAtomCharactersProvider() { return array( array('ABC123abc', 'ABC123abc'), array('A[{À*"A', 'A[A') ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/DateTest.php0000664000175000017500000000311713150761653023767 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_DateTest extends Horde_Imap_Client_Data_Format_TestBase { protected function getTestObs() { return array( new Horde_Imap_Client_Data_Format_Date('January 1, 2010'), new Horde_Imap_Client_Data_Format_Date('@1262304000') ); } /** * @dataProvider obsProvider */ public function testConstructor($ob) { $this->assertEquals( new Horde_Imap_Client_DateTime('January 1, 2010'), $ob->getData() ); } /** * @dataProvider obsProvider */ public function testStringRepresentation($ob) { $this->assertEquals( '1-Jan-2010', strval($ob) ); } /** * @dataProvider obsProvider */ public function testEscape($ob) { $this->assertEquals( '1-Jan-2010', $ob->escape() ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/DateTimeTest.php0000664000175000017500000000317713150761653024614 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_DateTimeTest extends Horde_Imap_Client_Data_Format_TestBase { protected function getTestObs() { return array( new Horde_Imap_Client_Data_Format_DateTime('January 1, 2010'), new Horde_Imap_Client_Data_Format_DateTime('@1262304000') ); } /** * @dataProvider obsProvider */ public function testConstructor($ob) { $this->assertEquals( new Horde_Imap_Client_DateTime('January 1, 2010'), $ob->getData() ); } /** * @dataProvider obsProvider */ public function testStringRepresentation($ob) { $this->assertEquals( '1-Jan-2010 00:00:00 +0000', strval($ob) ); } /** * @dataProvider obsProvider */ public function testEscape($ob) { $this->assertEquals( '"1-Jan-2010 00:00:00 +0000"', $ob->escape() ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/ListTest.php0000664000175000017500000000624713150761653024034 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_ListTest extends PHPUnit_Framework_TestCase { public function testBasicListFunctions() { $ob = new Horde_Imap_Client_Data_Format_List(); $this->assertEquals( 0, count($ob) ); $ob->add(new Horde_Imap_Client_Data_Format_Atom('Foo')); $ob->add(new Horde_Imap_Client_Data_Format_Atom('Bar')); $ob->add(new Horde_Imap_Client_Data_Format_String('Baz')); $this->assertEquals( 3, count($ob) ); $this->assertEquals( 'Foo Bar "Baz"', strval($ob) ); $this->assertEquals( 'Foo Bar "Baz"', $ob->escape() ); foreach ($ob as $key => $val) { switch ($key) { case 0: case 1: $this->assertEquals( 'Horde_Imap_Client_Data_Format_Atom', get_class($val) ); break; case 2: $this->assertEquals( 'Horde_Imap_Client_Data_Format_String', get_class($val) ); break; } } } public function testAdvancedListFunctions() { $ob = new Horde_Imap_Client_Data_Format_List('Foo'); $this->assertEquals( 1, count($ob) ); $ob_array = iterator_to_array($ob); $this->assertEquals( 'Horde_Imap_Client_Data_Format_Atom', get_class(reset($ob_array)) ); $ob->add(array( 'Foo', new Horde_Imap_Client_Data_Format_List(array('Bar')) )); $this->assertEquals( 3, count($ob) ); $this->assertEquals( 'Foo Foo (Bar)', $ob->escape() ); $ob = new Horde_Imap_Client_Data_Format_List(array( 'Foo', new Horde_Imap_Client_Data_Format_List(array( 'Foo1' )), 'Bar', new Horde_Imap_Client_Data_Format_List(array( new Horde_Imap_Client_Data_Format_String('Bar1'), new Horde_Imap_Client_Data_Format_List(array( 'Baz' )) )) )); $this->assertEquals( 4, count($ob) ); $this->assertEquals( 'Foo (Foo1) Bar ("Bar1" (Baz))', $ob->escape() ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/NilTest.php0000664000175000017500000000253713150761653023641 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_NilTest extends Horde_Imap_Client_Data_Format_TestBase { protected function getTestObs() { return array( new Horde_Imap_Client_Data_Format_Nil(), /* Argument is ignored. */ new Horde_Imap_Client_Data_Format_Nil('Foo') ); } /** * @dataProvider obsProvider */ public function testStringRepresentation($ob) { $this->assertEquals( '', strval($ob) ); } /** * @dataProvider obsProvider */ public function testEscape($ob) { $this->assertEquals( 'NIL', $ob->escape() ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/NstringTest.php0000664000175000017500000000451713150761653024543 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_NstringTest extends Horde_Imap_Client_Data_Format_String_TestBase { protected $cname = 'Horde_Imap_Client_Data_Format_Nstring'; protected function getTestObs() { return array( new $this->cname('Foo'), new $this->cname('Foo('), /* This is an invalid atom, but valid nstring. */ new $this->cname('Foo]'), new $this->cname() ); } public function stringRepresentationProvider() { return $this->createProviderArray(array( 'Foo', 'Foo(', 'Foo]', '' )); } public function escapeProvider() { return $this->createProviderArray(array( '"Foo"', '"Foo("', '"Foo]"', 'NIL' )); } public function verifyProvider() { return $this->createProviderArray(array( true, true, true, true )); } public function binaryProvider() { return $this->createProviderArray(array( false, false, false, false )); } public function literalProvider() { return $this->binaryProvider(); } public function quotedProvider() { return $this->createProviderArray(array( true, true, true, false )); } public function escapeStreamProvider() { return $this->escapeProvider(); } public function nonasciiInputProvider() { return array( array(false) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/NumberTest.php0000664000175000017500000000426113150761653024343 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_NumberTest extends Horde_Imap_Client_Data_Format_TestBase { protected function getTestObs() { return array( new Horde_Imap_Client_Data_Format_Number(1), new Horde_Imap_Client_Data_Format_Number('1'), /* Invalid number. */ new Horde_Imap_Client_Data_Format_Number('Foo') ); } /** * @dataProvider stringRepresentationProvider */ public function testStringRepresentation($ob, $expected) { $this->assertEquals( $expected, strval($ob) ); } public function stringRepresentationProvider() { return $this->createProviderArray(array( '1', '1', '0' )); } /** * @dataProvider stringRepresentationProvider */ public function testEscape($ob, $expected) { $this->assertEquals( $expected, $ob->escape() ); } /** * @dataProvider verifyProvider */ public function testVerify($ob, $expected) { try { $ob->verify(); if ($expected) { $this->fail(); } } catch (Horde_Imap_Client_Data_Format_Exception $e) { if (!$expected) { $this->fail(); } } } public function verifyProvider() { return $this->createProviderArray(array( false, false, true )); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/StringTest.php0000664000175000017500000000530313150761653024357 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_Format_StringTest extends Horde_Imap_Client_Data_Format_String_TestBase { protected $cname = 'Horde_Imap_Client_Data_Format_String'; protected function getTestObs() { return array( new $this->cname('Foo'), new $this->cname('Foo('), /* This is an invalid atom, but valid string. */ new $this->cname('Foo]'), /* This string requires a literal. */ new $this->cname("Foo\n]"), /* This string requires a binary literal. */ new $this->cname("12\x00\n3") ); } public function stringRepresentationProvider() { return $this->createProviderArray(array( 'Foo', 'Foo(', 'Foo]', "Foo\n]", "12\x00\n3" )); } public function escapeProvider() { return $this->createProviderArray(array( '"Foo"', '"Foo("', '"Foo]"', false, false )); } public function verifyProvider() { return $this->createProviderArray(array( true, true, true, true, true )); } public function binaryProvider() { return $this->createProviderArray(array( false, false, false, false, true )); } public function literalProvider() { return $this->createProviderArray(array( false, false, false, true, true )); } public function quotedProvider() { return $this->createProviderArray(array( true, true, true, false, false )); } public function escapeStreamProvider() { return $this->escapeProvider(); } public function nonasciiInputProvider() { return array( array(false) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/Format/TestBase.php0000664000175000017500000000246213150761653023766 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ abstract class Horde_Imap_Client_Data_Format_TestBase extends PHPUnit_Framework_TestCase { abstract protected function getTestObs(); protected function createProviderArray($data) { $data = array_values($data); $out = array(); foreach (array_values($this->getTestObs()) as $key => $val) { $out[] = array_merge( array($val), isset($data[$key]) ? (is_array($data[$key]) ? $data[$key] : array($data[$key])) : array() ); } return $out; } public function obsProvider() { return $this->createProviderArray(array()); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/AclTest.php0000664000175000017500000000316113150761653022360 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_AclTest extends PHPUnit_Framework_TestCase { public function testIterator() { $ob = new Horde_Imap_Client_Data_Acl('lrs'); $this->assertNotEmpty(count(iterator_to_array($ob))); } public function testSerialization() { $this->assertInstanceOf( 'Horde_Imap_Client_Data_Acl', unserialize(serialize(new Horde_Imap_Client_Data_Acl('lrs'))) ); } /** * @dataProvider bug10079Provider */ public function testBug10079($rights, $expected) { $ob = new Horde_Imap_Client_Data_Acl($rights); $this->assertEquals( $expected, strval($ob) ); } public function bug10079Provider() { return array( // RFC 2086 rights string array('lrswipcda', 'lrswipakxte'), // RFC 4314 rights string array('lrswipakte', 'lrswipakte') ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/CapabilityTest.php0000664000175000017500000001141213150761653023740 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_CapabilityTest extends PHPUnit_Framework_TestCase { public function testQuery() { $c = new Horde_Imap_Client_Data_Capability(); $c->add('FOO'); $this->assertTrue($c->query('FOO')); $this->assertTrue($c->query('foo')); $this->assertFalse($c->query('BAR')); $this->assertFalse($c->query('FOO', 'BAR')); $c->add('bar'); $this->assertTrue($c->query('bar')); $this->assertTrue($c->query('BAR')); } public function testQueryParameters() { $c = new Horde_Imap_Client_Data_Capability(); $c->add('FOO', array('A', 'B')); $this->assertTrue($c->query('FOO')); $this->assertTrue($c->query('foo')); $this->assertTrue($c->query('FOO', 'A')); $this->assertTrue($c->query('FOO', 'B')); $this->assertTrue($c->query('FOO', 'a')); $this->assertTrue($c->query('FOO', 'b')); $this->assertTrue($c->query('foo', 'a')); $this->assertTrue($c->query('foo', 'b')); $this->assertFalse($c->query('FOO', 'C')); } public function testIncrementalParameterAddition() { $c = new Horde_Imap_Client_Data_Capability(); $c->add('FOO', 'A'); $c->add('FOO', 'B'); $this->assertTrue($c->query('FOO')); $this->assertTrue($c->query('FOO', 'A')); $this->assertTrue($c->query('FOO', 'B')); $this->assertTrue($c->query('FOO', 'a')); $this->assertTrue($c->query('FOO', 'b')); $this->assertTrue($c->query('foo', 'a')); $this->assertTrue($c->query('foo', 'b')); $this->assertFalse($c->query('FOO', 'C')); /* This should not affect the current parameter list. */ $c->add('FOO'); $this->assertTrue($c->query('FOO', 'A')); $this->assertTrue($c->query('FOO', 'B')); $c->add('FOO', array('C', 'D')); $this->assertTrue($c->query('FOO', 'A')); $this->assertTrue($c->query('FOO', 'B')); $this->assertTrue($c->query('FOO', 'C')); $this->assertTrue($c->query('FOO', 'D')); } public function testRemoval() { $c = new Horde_Imap_Client_Data_Capability(); $c->add('FOO'); $this->assertTrue($c->query('FOO')); $c->remove('FOO'); $this->assertFalse($c->query('FOO')); $c->add('BAR', array('A', 'B', 'C')); $c->remove('BAR', array('A', 'C')); $this->assertTrue($c->query('BAR')); $this->assertFalse($c->query('BAR', 'A')); $this->assertTrue($c->query('BAR', 'B')); $this->assertFalse($c->query('BAR', 'C')); $c->remove('BAR', 'b'); $this->assertFalse($c->query('BAR')); $this->assertFalse($c->query('BAR', 'A')); $this->assertFalse($c->query('BAR', 'B')); $this->assertFalse($c->query('BAR', 'C')); } public function testGetParams() { $c = new Horde_Imap_Client_Data_Capability(); $c->add('FOO', 'A'); $c->add('FOO', 'B'); $c->add('BAR'); $this->assertNotEmpty($c->getParams('FOO')); $this->assertEquals( array('A', 'B'), $c->getParams('FOO') ); $this->assertEmpty($c->getParams('BAR')); $this->assertEmpty($c->getParams('BAZ')); } public function isEnabled() { $c = new Horde_Imap_Client_Data_Capability(); $c->add('FOO'); $this->assertFalse($c->isEnabled('FOO')); } public function testObserver() { $c = new Horde_Imap_Client_Data_Capability(); $mock = $this->getMock('SplObserver'); $mock->expects($this->once()) ->method('update') ->with($this->equalTo($c)); $c->attach($mock); $c->add('FOO'); } public function testSerialize() { $c = new Horde_Imap_Client_Data_Capability(); $c->add('FOO', 'A'); $c->add('FOO', 'B'); $c->add('BAR'); $c_copy = unserialize(serialize($c)); $this->assertTrue($c_copy->query('FOO', 'A')); $this->assertTrue($c_copy->query('FOO', 'B')); $this->assertTrue($c_copy->query('BAR')); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/SearchCharsetTest.php0000664000175000017500000000462513150761653024406 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_SearchCharsetTest extends PHPUnit_Framework_TestCase { public function testQuery() { $s = new Horde_Imap_Client_Data_SearchCharset(); $s->setValid('ISO-8859-1', false); $this->assertNull($s->query('UTF-8', true)); $this->assertTrue($s->query('US-ASCII', true)); $this->assertFalse($s->query('iso-8859-1', true)); } /** * @expectedException RuntimeException */ public function testQueryWithoutBaseOb() { $s = new Horde_Imap_Client_Data_SearchCharset(); $s->query('UTF-8'); } public function testRemoval() { $s = new Horde_Imap_Client_Data_SearchCharset(); $s->setValid('UTF-8'); $this->assertTrue($s->query('UTF-8', true)); $s->setValid('utf-8', false); $this->assertFalse($s->query('UTF-8', true)); } public function testCharsetsProperty() { $s = new Horde_Imap_Client_Data_SearchCharset(); $s->setValid('UTF-8'); $s->setValid('UTF-8'); $this->assertEquals( array('US-ASCII', 'UTF-8'), $s->charsets ); } public function testObserver() { $s = new Horde_Imap_Client_Data_SearchCharset(); $mock = $this->getMock('SplObserver'); $mock->expects($this->once()) ->method('update') ->with($this->equalTo($s)); $s->attach($mock); $s->setValid('utf-8'); /* This should be ignored. */ $s->setValid('UTF-8'); } public function testSerialize() { $s = new Horde_Imap_Client_Data_SearchCharset(); $s->setValid('utf-8'); $s_copy = unserialize(serialize($s)); $s_copy->query('UTF-8', true); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/SearchCharsetUtf8Test.php0000664000175000017500000000431513150761653025151 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_SearchCharsetUtf8Test extends PHPUnit_Framework_TestCase { public function testQuery() { $s = new Horde_Imap_Client_Data_SearchCharset_Utf8(); $s->setValid('ISO-8859-1', false); $this->assertTrue($s->query('UTF-8', true)); $this->assertTrue($s->query('US-ASCII', true)); $this->assertFalse($s->query('iso-8859-1', true)); } public function testRemoval() { $s = new Horde_Imap_Client_Data_SearchCharset_Utf8(); $s->setValid('UTF-8'); $this->assertTrue($s->query('UTF-8', true)); $s->setValid('utf-8', false); $this->assertTrue($s->query('UTF-8', true)); } public function testCharsetsProperty() { $s = new Horde_Imap_Client_Data_SearchCharset_Utf8(); $s->setValid('UTF-8'); $s->setValid('UTF-8'); $this->assertEquals( array('US-ASCII', 'UTF-8'), $s->charsets ); } public function testObserver() { $s = new Horde_Imap_Client_Data_SearchCharset_Utf8(); $mock = $this->getMock('SplObserver'); $mock->expects($this->never()) ->method('update') ->with($this->equalTo($s)); $s->attach($mock); $s->setValid('utf-8'); /* This should be ignored. */ $s->setValid('UTF-8'); } public function testSerialize() { $s = new Horde_Imap_Client_Data_SearchCharset_Utf8(); $s_copy = unserialize(serialize($s)); $s_copy->query('UTF-8', true); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/SubjectParseTest.php0000664000175000017500000000377513150761653024266 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_SubjectParseTest extends PHPUnit_Framework_TestCase { /** * @dataProvider subjectParseProvider */ public function testSubjectParse($subject, $expected) { $this->assertEquals( $expected, strval(new Horde_Imap_Client_Data_BaseSubject($subject)) ); } public function subjectParseProvider() { // Format: Test string, Expected parse result return array( array('Test', 'Test'), array('Re: Test', 'Test'), array('re: Test', 'Test'), array('Fwd: Test', 'Test'), array('fwd: Test', 'Test'), array(' Fw: Test', 'Test'), array('fw: Test', 'Test'), array('fwd [foo] : Test', 'Test'), array('Fwd: Re: Test', 'Test'), array('Fwd: Re: Test (fwd)', 'Test'), array(' re : Test (fwd)', 'Test'), array(' re : [foo]Test(Fwd)', 'Test'), array("re \t: \tTest", 'Test'), array('Re:', ''), array(' RE : ', ''), array('Fwd:', ''), array(' FWD : ', ''), // This used to throw an undefined index error. array('fwd', 'fwd'), // Tabs array("Re: re:re: fwd:[fwd: \t Test] (fwd) (fwd)(fwd) ", 'Test') ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Data/ThreadTest.php0000664000175000017500000001037613150761653023076 0ustar janjan * @category Horde * @copyright 2015-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Data_ThreadTest extends PHPUnit_Framework_TestCase { /** * @dataProvider countProvider */ public function testCount($thread, $expected) { $this->assertEquals( $expected, count($thread) ); } public function countProvider() { return array( array( new Horde_Imap_Client_Data_Thread(array(), 'uid'), 0 ), array( new Horde_Imap_Client_Data_Thread( array(array(1 => 0), array(2 => 0), array(3 => 0)), 'uid' ), 3 ), array( new Horde_Imap_Client_Data_Thread( json_decode( '[{"8":0,"10":1,"12":1,"15":2,"7":2,"9":2,"11":3,"13":4,"14":5,"20":6,"23":7,"25":8,"27":9,"16":4},{"18":0,"21":1,"24":2,"26":3,"28":2,"29":3,"17":4,"19":5,"22":2},{"33":0,"35":1,"30":2,"34":2,"32":3,"31":4,"36":1},{"41":0,"38":1,"37":2,"39":0,"40":1,"42":2},{"5":0,"4":1,"6":1,"1":0,"2":1,"3":2},{"45":0,"44":0,"47":0,"46":0},{"48":0,"49":1,"50":2,"51":3,"52":4,"171":4,"170":3,"169":2,"168":1,"167":0,"53":0,"172":0,"54":0,"173":0},{"55":0,"56":1,"175":1,"174":0,"57":0,"176":0,"58":0,"177":0},{"151":0,"152":1,"153":2,"154":3,"156":4,"157":5,"155":2},{"59":0,"178":0},{"60":0,"179":0},{"61":0,"180":0},{"62":0,"181":0},{"158":0,"159":0,"160":1,"163":2,"164":1,"166":2},{"161":0,"162":1,"165":2},{"63":0,"64":1,"66":2,"67":2,"69":3,"70":4,"68":2,"71":3,"72":3,"65":0},{"73":0,"74":1,"75":0,"76":1,"77":1,"78":2,"79":1,"80":2,"81":3,"82":0,"83":1,"84":2,"85":0,"86":0},{"87":0,"88":1,"89":1,"90":1,"92":2,"101":3,"95":2,"97":3,"99":4,"100":5,"111":5,"102":4,"91":1,"93":1,"98":2,"94":1,"96":2,"110":2,"115":3,"127":4,"128":5,"129":6,"134":4,"116":3,"117":3,"119":4,"120":5,"121":6,"122":7,"123":8,"124":9,"125":10,"133":10,"138":11,"130":8,"132":9,"135":9,"131":5,"136":6,"137":7,"139":7,"118":3,"103":1,"104":2,"105":1,"106":2,"107":3,"109":4,"113":5,"126":5,"112":4,"114":5,"140":4,"108":1},{"141":0,"142":0,"143":1,"144":2,"146":3,"147":3,"145":0,"150":1,"148":0,"149":0},{"182":0,"183":1,"184":2,"185":3,"186":4,"190":5,"187":1,"188":2,"189":3,"191":4},{"192":0,"193":1,"194":2,"195":3,"196":4,"197":5,"198":6,"199":6,"202":7,"204":7,"207":8,"208":9,"209":9,"201":6,"203":7,"205":7,"210":6,"211":7,"212":7,"200":1,"206":2},{"213":0,"225":1,"237":2,"214":0,"215":1,"217":2,"228":2,"216":1,"218":2,"219":3,"221":4,"226":5,"220":3,"222":4,"223":0,"224":0,"227":1,"229":2,"230":2,"231":3,"233":4,"236":5,"232":3,"234":4,"235":5},{"238":0,"239":1,"240":2,"241":3,"242":4,"243":5,"244":5,"245":6,"246":6,"247":7,"248":8,"249":9,"251":9,"255":10,"250":8,"252":9,"253":10,"254":11,"258":12,"259":13,"260":14,"261":15,"262":16,"263":17,"266":18,"264":16,"265":17,"268":18,"267":17,"269":12,"256":11,"257":12},{"270":0,"271":1,"272":2,"273":3,"277":4,"281":5,"285":6,"286":7,"288":7,"289":4,"290":5,"291":6,"292":5,"274":3,"275":4,"276":5,"278":6,"279":7,"280":7,"283":8,"282":5,"287":4,"293":5,"306":6,"284":3},{"294":0,"295":1,"298":2,"299":3,"296":1,"297":2,"300":3},{"301":0,"302":0,"316":1,"318":2,"326":3,"303":0,"304":1,"305":2,"307":3,"308":3,"323":4,"310":5,"321":6,"322":5,"324":5,"313":6,"312":4,"314":3,"309":1,"319":2,"315":3,"320":4,"317":1,"325":1},{"311":0,"327":1,"328":2,"329":3,"330":4,"331":4,"335":5,"341":6,"343":5,"344":6},{"332":0,"333":1,"338":1,"334":0,"336":1,"337":1,"339":0,"340":0,"342":0}]', true ), 'uid' ), 343 ) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Fetch/Results/FetchPop3Test.php0000664000175000017500000000177413150761653025305 0ustar janjan * @category Horde * @copyright 2015-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Fetch_Results_FetchPop3Test extends Horde_Imap_Client_Fetch_Results_TestBase { protected function _setUp() { $this->ob_class = 'Horde_Imap_Client_Data_Fetch_Pop3'; $this->ob_ids = array('a', 'b', 'c'); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Fetch/Results/FetchTest.php0000664000175000017500000000175013150761653024535 0ustar janjan * @category Horde * @copyright 2015-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Fetch_Results_FetchTest extends Horde_Imap_Client_Fetch_Results_TestBase { protected function _setUp() { $this->ob_class = 'Horde_Imap_Client_Data_Fetch'; $this->ob_ids = array(1, 2, 3); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Fetch/Results/TestBase.php0000664000175000017500000000720413150761653024356 0ustar janjan * @category Horde * @copyright 2015-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ abstract class Horde_Imap_Client_Fetch_Results_TestBase extends PHPUnit_Framework_TestCase { protected $ob; /* Set in child class via _setUp(). */ protected $ob_class; protected $ob_ids; abstract protected function _setUp(); public function setUp() { $this->_setUp(); $this->ob = new Horde_Imap_Client_Fetch_Results($this->ob_class); foreach ($this->ob_ids as $val) { $this->ob[$val] = new $this->ob_class(); } } /** * @dataProvider keyTypeProvider */ public function testKeyType($ob_key_type, $key_type) { $reflection = new ReflectionClass($this->ob); $ob = $reflection->newInstanceArgs(array_filter(array( $this->ob_class, $ob_key_type ))); $this->assertEquals( $key_type, $ob->key_type ); } public function keyTypeProvider() { return array( array( Horde_Imap_Client_Fetch_Results::SEQUENCE, Horde_Imap_Client_Fetch_Results::SEQUENCE ), array( Horde_Imap_Client_Fetch_Results::UID, Horde_Imap_Client_Fetch_Results::UID ), array( null, Horde_Imap_Client_Fetch_Results::UID ) ); } public function testGet() { $ids = array_merge( $this->ob_ids, /* Create non-existent object. */ array('1000', 'Z') ); foreach ($ids as $id) { $this->assertInstanceOf( $this->ob_class, $this->ob->get($id) ); } } public function testIds() { $this->assertEquals( $this->ob_ids, $this->ob->ids() ); } public function testFirst() { $this->assertNull($this->ob->first()); $ob = new Horde_Imap_Client_Fetch_Results($this->ob_class); $fetch = $ob->get('1'); $this->assertEquals( $fetch, $ob->first() ); } public function testClear() { $this->ob->clear(); $this->assertEquals( array(), $this->ob->ids() ); } public function testCount() { $this->assertEquals( count($this->ob_ids), count($this->ob) ); } public function testIterator() { $i = 0; foreach ($this->ob as $val) { $this->assertInstanceof( $this->ob_class, $val ); ++$i; } $this->assertEquals( count($this->ob_ids), $i ); } public function testSerialize() { $this->ob->get('1')->setModSeq(500); $ob2 = unserialize(serialize($this->ob)); $this->assertEquals( 500, $ob2->get('1')->getModSeq() ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/fixtures/clientsort.txt0000664000175000017500000001223413150761653024240 0ustar janjanKiAxIEZFVENIIChVSUQgMSBGTEFHUyAoXFNlZW4pIFJGQzgyMi5TSVpFIDM4NzUxIElOVEVSTkFMREFURSAiMDEtQXVnLTIwMTQgMDc6MzA6MDAgLTA3MDAiIEVOVkVMT1BFICgiVGh1LCAwMiBNYXkgMjAwMiAxNjozMDoyMCArMDAwMCIgInBlYXItY3ZzIERpZ2VzdCAyIE1heSAyMDAyIDE2OjMwOjIwIC0wMDAwIElzc3VlIDI1NyIgKChOSUwgTklMICJwZWFyLWN2cy1kaWdlc3QtaGVscCIgImxpc3RzLnBocC5uZXQiKSkgKChOSUwgTklMICJwZWFyLWN2cy1kaWdlc3QtaGVscCIgImxpc3RzLnBocC5uZXQiKSkgKChOSUwgTklMICJwZWFyLWN2cy1kaWdlc3QtaGVscCIgImxpc3RzLnBocC5uZXQiKSkgKChOSUwgTklMICJwZWFyLWN2cyIgImxpc3RzLnBocC5uZXQiKSkgTklMIE5JTCBOSUwgIjwxMDIwMzU3MDIwLjk5NTUwLmV6bWxtQGxpc3RzLnBocC5uZXQ+IikpCiogMiBGRVRDSCAoVUlEIDIgRkxBR1MgKFxTZWVuKSBSRkM4MjIuU0laRSA0OTY3IElOVEVSTkFMREFURSAiMDEtQXVnLTIwMTQgMDg6MzA6MDAgLTA3MDAiIEVOVkVMT1BFICgiU3VuLCAxMiBNYXkgMjAwMiAwMDoxNjozMiAtMDUwMCIgIkludGVyZXNhbnRlLi4uLi4uLiIgKCgiSmVzdXMiIE5JTCAicXVlbGF0aW8iICJuYXZlZ2FsaWEuY29tIikpICgoIkplc3VzIiBOSUwgInF1ZWxhdGlvIiAibmF2ZWdhbGlhLmNvbSIpKSAoKCJKZXN1cyIgTklMICJxdWVsYXRpbyIgIm5hdmVnYWxpYS5jb20iKSkgKChOSUwgTklMICJxdWVsYXRpbyIgIm5hdmVnYWxpYS5jb20iKSkgTklMIE5JTCBOSUwgIjxNQkJCSUNNQUpPTUFLSUJPRkVLR0tFREFDQkFBLnF1ZWxhdGlvQG5hdmVnYWxpYS5jb20+IikpCiogMyBGRVRDSCAoVUlEIDMgRkxBR1MgKFxTZWVuKSBSRkM4MjIuU0laRSAxMzQxMjMgSU5URVJOQUxEQVRFICIwMS1BdWctMjAxNCAwOTozMDowMCAtMDcwMCIgRU5WRUxPUEUgKCIyNCBNYXkgMjAwMiAxMzoyOTowMCArMDIwMCIgIkphdGtvOnNpdG91bXVrc2V0IiAoKCJUZXJ2byBUaW1vIiBOSUwgIlRpbW8uVGVydm8iICJ2YW50YWEuZmkiKSkgKCgiVGVydm8gVGltbyIgTklMICJUaW1vLlRlcnZvIiAidmFudGFhLmZpIikpICgoIlRlcnZvIFRpbW8iIE5JTCAiVGltby5UZXJ2byIgInZhbnRhYS5maSIpKSAoKCJUaW1vIFRlcnZvIiBOSUwgInRpbW8udGVydm8iICJlZHUudmFudGFhLmZpIikpIE5JTCBOSUwgTklMICI8SkE4QUFBQUFBL2RlMHdBQllRQUdQR1hBN05oVUB2YW50YWEuZmk+IikpCiogNCBGRVRDSCAoVUlEIDQgRkxBR1MgKFxTZWVuKSBSRkM4MjIuU0laRSAxNzYyIElOVEVSTkFMREFURSAiMDEtQXVnLTIwMTQgMTA6MzA6MDAgLTA3MDAiIEVOVkVMT1BFICgiTW9uLCAzIEp1biAyMDAyIDEzOjMyOjMxIC0wNDAwICIgIk5vcnRvbiBBbnRpVmlydXMgZGV0ZWN0ZWQgYSB2aXJ1cyBpbiBhIG1lc3NhZ2UgeW91IHNlbnQuIFRoZSBpbmYgZWN0ZWQgYXR0YWNobWVudCB3YXMgZGVsZXRlZC4iICgoIk5BViBmb3IgTWljcm9zb2Z0IEV4Y2hhbmdlLUVYQ0hBTkdFMSIgTklMICJOQVZNU0UtRVhDSEFOR0UxIiAiV2FzaGluZ3RvblRpbWVzLmNvbSIpKSAoKCJOQVYgZm9yIE1pY3Jvc29mdCBFeGNoYW5nZS1FWENIQU5HRTEiIE5JTCAiTkFWTVNFLUVYQ0hBTkdFMSIgIldhc2hpbmd0b25UaW1lcy5jb20iKSkgKCgiTkFWIGZvciBNaWNyb3NvZnQgRXhjaGFuZ2UtRVhDSEFOR0UxIiBOSUwgIk5BVk1TRS1FWENIQU5HRTEiICJXYXNoaW5ndG9uVGltZXMuY29tIikpICgoIidzbHVzYXJ6MiciIE5JTCAic2x1c2FyejIiICJiaWd3b3JtLmNvbG9yYWRvLmVkdSIpKSBOSUwgTklMIE5JTCAiPDhBOUY5OUE4OTBFNkQ0MTE4MzkxMDBCMEQwMjBFRkVGMDE1Q0MzMThAZXhjaGFuZ2UxLndhc2hpbmd0b250aW1lcy5jb20+IikpCiogNSBGRVRDSCAoVUlEIDUgRkxBR1MgKFxTZWVuKSBSRkM4MjIuU0laRSAzMjU5IElOVEVSTkFMREFURSAiMDEtQXVnLTIwMTQgMDI6MzA6MDAgLTA3MDAiIEVOVkVMT1BFICgiU3VuLCAyNiBNYXkgMjAwMiAxNToxNTowMiAtMDMwMCIgIkhlbGxvLHNsdXNhcnosamFwYW5lc2UgbGFzcycgc2V4eSBwaWN0dXJlcyIgKCgicHVibGljaWRhZGUiIE5JTCAicHVibGljaWRhZGUiICJyYW1wZXJhLmNvbS5iciIpKSAoKCJwdWJsaWNpZGFkZSIgTklMICJwdWJsaWNpZGFkZSIgInJhbXBlcmEuY29tLmJyIikpICgoInB1YmxpY2lkYWRlIiBOSUwgInB1YmxpY2lkYWRlIiAicmFtcGVyYS5jb20uYnIiKSkgKChOSUwgTklMICJzbHVzYXJ6IiAidWNzdS5jb2xvcmFkby5lZHUiKSkgTklMIE5JTCBOSUwgIjwyMDAyMDUyNjE4MTUuZzRRSUYxVzAzMDMxQGxpbnV4MWUuY3J1emVpcm8uY29tLmJyPiIpKQoqIDYgRkVUQ0ggKFVJRCA2IEZMQUdTIChcU2VlbikgUkZDODIyLlNJWkUgMTg0NTI3MSBJTlRFUk5BTERBVEUgIjAxLUF1Zy0yMDE0IDAzOjMwOjAwIC0wNzAwIiBFTlZFTE9QRSAoIk1vbiwgNiBGZWIgMTk5MyAwMjo1Mzo0NyAtMDgwMCAoUFNUKSIgIk11bHRpLW1lZGlhIG1haWwgZGVtb25zdHJhdGlvbiAiICgoIk1hcmsgQ3Jpc3BpbiIgTklMICJtcmMiICJDQUMuV2FzaGluZ3Rvbi5FRFUiKSkgKCgiTWFyayBDcmlzcGluIiBOSUwgIm1yYyIgIkNBQy5XYXNoaW5ndG9uLkVEVSIpKSAoKCJNYXJrIENyaXNwaW4iIE5JTCAibXJjIiAiQ0FDLldhc2hpbmd0b24uRURVIikpICgoTklMIE5JTCAiTVJDIiAiQ0FDLldhc2hpbmd0b24uRURVIikpIE5JTCBOSUwgTklMICI8Q01NLjAuODguNjg3MTY4MDkyLm1yY0Bha2Jhci5jYWMud2FzaGluZ3Rvbi5lZHU+ICIpKQoqIDcgRkVUQ0ggKFVJRCA3IEZMQUdTIChcU2VlbikgUkZDODIyLlNJWkUgNDc1NTY5IElOVEVSTkFMREFURSAiMDEtQXVnLTIwMTQgMDQ6MzA6MDAgLTA3MDAiIEVOVkVMT1BFICgiU3VuLCA5IEp1biAyMDAyIDE5OjQzOjM1IC0wNDAwIiAiUGhvdG8gaW4gTi5ZLiBUaW1lcyBUcmF2ZWwgc2VjdGlvbiB0b2RheSIgKCgiV2FsdCBIYWdlbmJ1Y2giIE5JTCAiaGFnZW5kYXoiICJwdGQubmV0IikpICgoIldhbHQgSGFnZW5idWNoIiBOSUwgImhhZ2VuZGF6IiAicHRkLm5ldCIpKSAoKCJXYWx0IEhhZ2VuYnVjaCIgTklMICJoYWdlbmRheiIgInB0ZC5uZXQiKSkgKCgiQ2hhcmxlcyBIYWdlbmJ1Y2giIE5JTCAiY2h1Y2siICJob3JkZS5vcmciKSkgKChOSUwgTklMICJqZW5uaWZlcl9jYXJ0ZWUiICJ5YWhvby5jb20iKSkgTklMIE5JTCAiPHYwNDIyMDgwMGI5Mjk5ODZjMWQ3M0BbMjQuMjI5LjE4My4xODJdPiIpKQoqIDggRkVUQ0ggKFVJRCA4IEZMQUdTIChcU2VlbikgUkZDODIyLlNJWkUgMTA0NzEgSU5URVJOQUxEQVRFICIwMS1BdWctMjAxNCAwNTozMDowMCAtMDcwMCIgRU5WRUxPUEUgKCJUdWUsIDIwIEp1biAyMDAwIDIxOjIxOjMwIC0wNDAwIiAicGRmIiAoKCJDaHVjayBIYWdlbmJ1Y2giIE5JTCAiY2h1Y2siICJob3JkZS5vcmciKSkgKChOSUwgTklMICJjaHVjayIgIm5pcmdhbC5ob3JkZS5vcmciKSkgKCgiQ2h1Y2sgSGFnZW5idWNoIiBOSUwgImNodWNrIiAiaG9yZGUub3JnIikpICgoTklMIE5JTCAiY2hhZ2VuYnUiICJ3c28ud2lsbGlhbXMuZWR1IikpIE5JTCBOSUwgTklMICI8MjAwMDA2MjAyMTIxMzAuQTE0ODg0QHlvdXIubW9tPiIpKQoqIDkgRkVUQ0ggKFVJRCA5IEZMQUdTIChcU2VlbikgUkZDODIyLlNJWkUgMjIyNjIgSU5URVJOQUxEQVRFICIwMS1BdWctMjAxNCAwNjozMDowMCAtMDcwMCIgRU5WRUxPUEUgKCJXZWQsIDA4IFNlcCAxOTk5IDE0OjIzOjQ3ICswMjAwIiAiZXhjZWwiICgoIlBoaWxpcCBTdGVlbWFuIiBOSUwgInBoaWxpcC5zdGVlbWFuIiAia2gua2hiby5iZSIpKSAoKCJQaGlsaXAgU3RlZW1hbiIgTklMICJwaGlsaXAuc3RlZW1hbiIgImtoLmtoYm8uYmUiKSkgKCgiUGhpbGlwIFN0ZWVtYW4iIE5JTCAicGhpbGlwLnN0ZWVtYW4iICJraC5raGJvLmJlIikpICgoTklMIE5JTCAic3RlZW1hbiIgImtoLmtoYm8uYmUiKSkgTklMIE5JTCBOSUwgIjwzN0Q2NTU1Mi43OEQ3Njg4MUBraC5raGJvLmJlPiIpKQo=Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/fixtures/clientsort2.txt0000664000175000017500000000221513150761653024320 0ustar janjanKiAxIEZFVENIIChVSUQgMSBGTEFHUyAoXFNlZW4pIFJGQzgyMi5TSVpFIDM4NzUxIElOVEVSTkFMREFURSAiMDEtQXVnLTIwMTQgMDc6MzA6MDAgLTA3MDAiIEVOVkVMT1BFICgiVGh1LCAwMiBNYXkgMjAwMiAxNjozMDoyMCArMDAwMCIgInBlYXItY3ZzIERpZ2VzdCAyIE1heSAyMDAyIDE2OjMwOjIwIC0wMDAwIElzc3VlIDI1NyIgKChOSUwgTklMICJwZWFyLWN2cy1kaWdlc3QtaGVscCIgImxpc3RzLnBocC5uZXQiKSkgKChOSUwgTklMICJwZWFyLWN2cy1kaWdlc3QtaGVscCIgImxpc3RzLnBocC5uZXQiKSkgKChOSUwgTklMICJwZWFyLWN2cy1kaWdlc3QtaGVscCIgImxpc3RzLnBocC5uZXQiKSkgKChOSUwgTklMICJwZWFyLWN2cyIgImxpc3RzLnBocC5uZXQiKSkgTklMIE5JTCBOSUwgIjwxMDIwMzU3MDIwLjk5NTUwLmV6bWxtQGxpc3RzLnBocC5uZXQ+IikpCiogMiBGRVRDSCAoVUlEIDIgRkxBR1MgKFxTZWVuKSBSRkM4MjIuU0laRSAzODc1MSBJTlRFUk5BTERBVEUgIjAxLUF1Zy0yMDE0IDA3OjMwOjAwIC0wNzAwIiBFTlZFTE9QRSAoIlRodSwgMDIgTWF5IDIwMDIgMTc6MzA6MjAgKzAwMDAiICJwZWFyLWN2cyBEaWdlc3QgMiBNYXkgMjAwMiAxNjozMDoyMCAtMDAwMCBJc3N1ZSAyNTciICgoTklMIE5JTCAicGVhci1jdnMtZGlnZXN0LWhlbHAiICJsaXN0cy5waHAubmV0IikpICgoTklMIE5JTCAicGVhci1jdnMtZGlnZXN0LWhlbHAiICJsaXN0cy5waHAubmV0IikpICgoTklMIE5JTCAicGVhci1jdnMtZGlnZXN0LWhlbHAiICJsaXN0cy5waHAubmV0IikpICgoTklMIE5JTCAicGVhci1jdnMiICJsaXN0cy5waHAubmV0IikpIE5JTCBOSUwgTklMICI8MTAyMDM1NzAyMC45OTU1MC5lem1sbUBsaXN0cy5waHAubmV0PiIpKQo= Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/fixtures/remote1.txt0000664000175000017500000000072713150761653023432 0ustar janjanReturn-Path: Delivered-To: foo@example.com Received: from test1.example.com (test1.example.com [192.168.10.10]) by test2.example.com (Postfix) with ESMTP id E6F7890AF for ; Sat, 26 Jul 2008 20:09:03 -0600 (MDT) Message-ID: Date: Sat, 26 Jul 2008 21:10:00 -0500 (CDT) From: Test To: foo@example.com Subject: Test e-mail 1 Mime-Version: 1.0 Content-Type: text/plain Test. Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/fixtures/remote2.txt0000664000175000017500000000115213150761653023424 0ustar janjanReturn-Path: Delivered-To: foo@example.com Received: from test1.example.com (test1.example.com [192.168.10.10]) by test2.example.com (Postfix) with ESMTP id E8796FBA for ; Sat, 26 Jul 2008 21:19:13 -0600 (MDT) Message-ID: <98761234@test1.example.com> Date: Sat, 26 Jul 2008 21:19:00 -0500 (CDT) From: Test To: foo@example.com Subject: Re: Test e-mail 1 Mime-Version: 1.0 Content-Type: text/plain In-Reply-To: References: Test reply. Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/fixtures/remote3.txt0000664000175000017500000000074113150761653023430 0ustar janjanReturn-Path: Delivered-To: foo2@example.com Received: from test2.example.com (test2.example.com [192.168.10.10]) by test3.example.com (Postfix) with ESMTP id JJKKAA for ; Sat, 26 Jul 2008 21:29:23 -0600 (MDT) Message-ID: Date: Sat, 26 Jul 2008 22:29:20 -0500 (CDT) From: Test 2 To: foo2@example.com Subject: Re: Test e-mail 3 Mime-Version: 1.0 Content-Type: text/plain 3rd test message. Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/fixtures/remote4.txt0000664000175000017500000000705113150761653023432 0ustar janjanReturn-Path: Delivered-To: test@example.com Received: from localhost (localhost [127.0.0.1]) by foo.example.com (Postfix) with ESMTP id BBCC02F667 for ; Thu, 2 Oct 2008 13:15:25 -0600 (MDT) Received: from foo2.example.com (foo2.example.com [192.168.100.100]) by foo.example.com (Horde Framework) with HTTP; Thu, 02 Oct 2008 13:15:25 -0600 Message-ID: <2008yhnujm@foo.example.com> Date: Thu, 02 Oct 2008 13:15:25 -0600 From: "A. Test User" To: test@example.com Subject: Fwd: Test MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=_5oyqt8yksw5p" Content-Transfer-Encoding: 7bit User-Agent: Test e-mail program This message is in MIME format. --=_5oyqt8yksw5p Content-Type: multipart/alternative; boundary="=_5otck98hqrbh" Content-Transfer-Encoding: 7bit This message is in MIME format. --=_5otck98hqrbh Content-Type: text/plain; charset=ISO-8859-1 Content-Description: Plaintext Version of Message Content-Disposition: inline Content-Transfer-Encoding: 7bit multipart/alternative test. --=_5otck98hqrbh Content-Type: text/html; charset=ISO-8859-1 Content-Description: HTML Version of Message Content-Disposition: inline Content-Transfer-Encoding: 7bit

multipart/alternative test.

--=_5otck98hqrbh-- --=_5oyqt8yksw5p Content-Type: message/rfc822; name="Forwarded Message: Test" MIME-Version: 1.0 Return-Path: Delivered-To: test@example.com Received: from localhost (localhost [127.0.0.1]) by foo.example.com (Postfix) with ESMTP id E57162F667 for ; Thu, 2 Oct 2008 13:12:11 -0600 (MDT) Received: from foo2.example.com (foo2.example.com [192.168.100.100]) by foo.example.com (Horde Framework) with HTTP; Thu, 02 Oct 2008 13:12:11 -0600 Message-ID: <20081002131211.2404701yx4vklbez@test.example.com> Date: Thu, 02 Oct 2008 13:12:11 -0600 From: Test User To: Test User Subject: Test MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=_22nxtd2snnyj" Content-Transfer-Encoding: 7bit User-Agent: Test Agent This message is in MIME format. --=_22nxtd2snnyj Content-Type: text/plain; charset=ISO-8859-1; DelSp="Yes"; format="flowed" Content-Disposition: inline Content-Transfer-Encoding: 7bit Test w/attachment --=_22nxtd2snnyj Content-Type: image/png; name="info_icon.png" Content-Disposition: attachment; filename="info_icon.png" Content-Transfer-Encoding: base64 iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAwFBMVEUAAAAMExoUGyMVGyMcIysj OE0yRlwvS2cwS2czT2w0T2w1UnA5VnREWGw9WnhAW3hKWm1CXnxGYoBKZoRLZoNOaohVbYdTb41U b4xXc5Fbd5VldolfeJJgeJFfe5ljf51nf5pog6Fsh6Vuh6F3hpZ9ipiBlq2AmLOHm66WqL2Yqr2Z rMCcrL2issOltMamtciwvc7///////////////////////////////////////////////////// //////+mdyt7AAAAQHRSTlP///////////////////////////////////////////////////// //////////////////////////////8AwnuxRAAAAIxJREFUeNptj1cOwkAMRIdesoQQSkjooYc6 J+D+t8L2CpAi5u89z2ptvErxApafwK64nA89fET9ccw3q2U2rXmBpzCZpckIKjDTOZkm42ETKgrr K8d9E3dhksKD0MRN56SyM3HVPqncNbHfyntSOGjAvj2thUkXtOEXqy7msc5ble/q0SR0Hen/P66U N4YNJcNOYmoYAAAAAElFTkSuQmCC --=_22nxtd2snnyj-- --=_5oyqt8yksw5p Content-Type: text/plain; charset=UTF-8; name="test_txt.txt" Content-Disposition: attachment; filename="test_txt.txt" Content-Transfer-Encoding: 7bit Test text attachment. --=_5oyqt8yksw5p-- Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/fixtures/remote5.txt0000664000175000017500000000072713150761653023436 0ustar janjanReturn-Path: Delivered-To: foo@example.com Received: from test1.example.com (test1.example.com [192.168.10.10]) by test2.example.com (Postfix) with ESMTP id E6F7890AF for ; Sat, 26 Jul 2008 20:09:04 -0600 (MDT) Message-ID: Date: Sat, 26 Jul 2008 21:10:01 -0500 (CDT) From: Test To: foo@example.com Subject: Test e-mail 1 Mime-Version: 1.0 Content-Type: text/plain Test. Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Ids/Pop3Test.php0000664000175000017500000000423113150761653022347 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Ids_Pop3Test extends PHPUnit_Framework_TestCase { /** * @dataProvider pop3SequenceStringGenerateProvider */ public function testPop3SequenceStringGenerate($in, $expected) { $this->assertEquals( $expected, strval(new Horde_Imap_Client_Ids_Pop3($in)) ); } public function pop3SequenceStringGenerateProvider() { return array( array(array('ABCDEFGHIJ', 'ABCDE'), 'ABCDEFGHIJ ABCDE'), array('ABCDEFGHIJ', 'ABCDEFGHIJ') ); } /** * @dataProvider pop3SequenceStringParseProvider */ public function testPop3SequenceStringParse($in, $expected) { $ids = new Horde_Imap_Client_Ids_Pop3($in); $this->assertEquals( $expected, $ids->ids ); } public function pop3SequenceStringParseProvider() { return array( array('ABCDEFGHIJ ABCDE', array('ABCDEFGHIJ', 'ABCDE')), array('ABCDEFGHIJ ABC ABCDE', array('ABCDEFGHIJ', 'ABC', 'ABCDE')), array('ABCDEFGHIJ', array('ABCDEFGHIJ')), // This is not a range in POP3 IDs array('10:12', array('10:12')) ); } public function testPop3Sort() { $ids = new Horde_Imap_Client_Ids_Pop3(array( 'ABC', 'A', 'AC', 'AB' )); $this->assertEquals( 'ABC A AC AB', $ids->tostring_sort ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Interaction/CommandTest.php0000664000175000017500000000423613150761653024651 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Interaction_CommandTest extends PHPUnit_Framework_TestCase { /** * @dataProvider continuationCheckProvider */ public function testContinuationCheck($command, $result) { $this->assertEquals( $result, $command->continuation ); } public function continuationCheckProvider() { $out = array(); $cmd = new Horde_Imap_Client_Interaction_Command('FOO', '1'); $cmd->add(array( 'FOO', 'BAR' )); $out[] = array($cmd, false); $cmd = clone $cmd; $cmd->add( new Horde_Imap_Client_Interaction_Command_Continuation(function() {}) ); $out[] = array($cmd, true); $cmd = new Horde_Imap_Client_Interaction_Command('FOO', '1'); $cmd->add(array( 'FOO', array( 'BAR' ), new Horde_Imap_Client_Data_Format_List(array( 'BAR' )) )); $out[] = array($cmd, false); $cmd = new Horde_Imap_Client_Interaction_Command('FOO', '1'); $cmd->add(array( 'FOO', array( 'BAR', array( 'BAZ', array( new Horde_Imap_Client_Data_Format_String_Nonascii('Envoyé') ) ) ) )); $out[] = array($cmd, true); return $out; } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Live/Base.php0000664000175000017500000000213113150761653021715 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Live_Base extends PHPUnit_Framework_TestCase { public static $live; public static function tearDownAfterClass() { self::$live = null; } public function onNotSuccessfulTest(Exception $e) { if ($e instanceof Horde_Imap_Client_Exception) { $e->setMessage($e->getMessage() . ' [' . self::$live->url . ']'); } parent::onNotSuccessfulTest($e); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Live/Imap.php0000664000175000017500000006650613150761653021751 0ustar janjan * @category Horde * @copyright 2013-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Live_Imap extends Horde_Imap_Client_Live_Base { const DEFAULT_MBOX = '_____TestMailboxTest'; const DEFAULT_MBOX_UTF8 = '_____TestMailboxTest1è'; const DEFAULT_SPAM_MBOX = '____TestMailboxSpam'; public static $config; private static $created; private static $test_mbox; private static $test_mbox_utf8; private static $test_spam_mailbox; public static function setUpBeforeClass() { $c = array_shift(self::$config); self::$created = false; self::$test_mbox = isset($c['test_mbox']) ? $c['test_mbox'] : self::DEFAULT_MBOX; self::$test_mbox_utf8 = isset($c['test_mbox_utf8']) ? $c['test_mbox_utf8'] : self::DEFAULT_MBOX_UTF8; self::$test_spam_mailbox = isset($c['test_spam_mailbox']) ? $c['test_spam_mailbox'] : self::DEFAULT_SPAM_MBOX; try { $c['client_config']['cache'] = array( 'cacheob' => new Horde_Cache( new Horde_Cache_Storage_Mock(), array('compress' => true) ) ); } catch (Exception $e) {} self::$live = new Horde_Imap_Client_Socket( $c['client_config'] ); } public static function tearDownAfterClass() { if (self::$created) { foreach (array(self::$test_mbox, self::$test_mbox_utf8) as $val) { try { self::$live->deleteMailbox($val); } catch (Horde_Imap_Client_Exception $e) {} } } parent::tearDownAfterClass(); } /* Tests */ public function testPreLoginCommands() { try { $c = self::$live->capability; } catch (Horde_Imap_Client_Exception $e) { switch ($e->getCode()) { case $e::SERVER_CONNECT: $this->markTestSkipped('Could not connect to server'); break; } throw $e; } $this->assertInstanceOf( 'Horde_Imap_Client_Data_Capability', $c ); if (!$c->query('imap4rev1')) { $this->fail('No support of IMAP4rev1'); } } /** * @depends testPreLoginCommands */ public function testLogin() { /* Throws exception on error, which will prevent all further testing * on this server. */ self::$live->login(); } /** * @depends testLogin */ public function testPostLoginCapability() { /* Re-use testPreLoginCommands(). */ $this->testPreLoginCommands(); } /** * @depends testLogin */ public function testId() { try { $id = self::$live->getID(); } catch (Horde_Imap_Client_Exception_NoSupportExtension $e) { $this->markTestSkipped('No support for ID extension'); } $this->assertInternalType('array', $id); } /** * @depends testLogin */ public function testGetLanguage() { try { $lang = self::$live->getLanguage(true); } catch (Horde_Imap_Client_Exception_NoSupportExtension $e) { $this->markTestSkipped('No support for LANGUAGE extension'); } $this->assertInternalType('array', $lang); } /** * @depends testLogin */ public function testGetComparator() { self::$live->getComparator(); } /** * @depends testLogin */ public function testNamespaces() { $ns = self::$live->getNamespaces(array(), array('ob_return' => true)); $this->assertInstanceOf( 'Horde_Imap_Client_Namespace_List', $ns ); // Tack on namespace information to mailbox names. $ns = iterator_to_array($ns); $ns_prefix = strval(reset($ns)); self::$test_mbox = $ns_prefix . self::$test_mbox; self::$test_mbox_utf8 = $ns_prefix . self::$test_mbox_utf8; self::$test_spam_mailbox = $ns_prefix . self::$test_spam_mailbox; self::$created = true; } /** * @depends testNamespaces */ public function testCreateSpecialMailbox() { // Delete if it exists try { self::$live->deleteMailbox(self::$test_spam_mailbox); } catch (Horde_Imap_Client_Exception $e) {} // @todo check rfc support self::$live->createMailbox( self::$test_spam_mailbox, array('special_use' => '\Junk') ); } /** * @depends testNamespaces */ public function testCreateMailbox() { // Delete test mailbox, if it exists. try { self::$live->deleteMailbox(self::$test_mbox); } catch (Horde_Imap_Client_Exception $e) {} self::$live->createMailbox(self::$test_mbox); } /** * @depends testCreateMailbox */ public function testOpenMailbox() { self::$live->openMailbox( self::$test_mbox, Horde_Imap_Client::OPEN_READONLY ); self::$live->openMailbox( self::$test_mbox, Horde_Imap_Client::OPEN_READWRITE ); self::$live->openMailbox( self::$test_mbox, Horde_Imap_Client::OPEN_AUTO ); } /** * @depends testCreateMailbox */ public function testSubscribeMailbox() { self::$live->subscribeMailbox(self::$test_mbox, true); self::$live->subscribeMailbox(self::$test_mbox, false); } /** * @depends testOpenMailbox * @depends testSubscribeMailbox */ public function testRenameMailbox() { // Delete test mailbox, if it exists. try { self::$live->deleteMailbox(self::$test_mbox_utf8); } catch (Horde_Imap_Client_Exception $e) {} self::$live->renameMailbox( self::$test_mbox, self::$test_mbox_utf8 ); } /** * @depends testRenameMailbox */ public function testDeleteMailbox() { self::$live->deleteMailbox(self::$test_mbox_utf8); // Delete non-existent mailbox. try { self::$live->deleteMailbox(self::$test_mbox_utf8); } catch (Horde_Imap_Client_Exception $e) {} } /** * @depends testLogin */ public function testListMailbox() { // Listing all mailboxes in base level (flat format). $l = self::$live->listMailboxes( '%', Horde_Imap_Client::MBOX_ALL, array('flat' => true) ); $this->assertInternalType('array', $l); // Listing all mailboxes (flat format). $l = self::$live->listMailboxes( '*', Horde_Imap_Client::MBOX_ALL, array('flat' => true) ); $this->assertInternalType('array', $l); // Listing subscribed mailboxes (flat format). $l = self::$live->listMailboxes( '*', Horde_Imap_Client::MBOX_SUBSCRIBED, array('flat' => true) ); $this->assertInternalType('array', $l); // Listing unsubscribed mailboxes in base level (with attribute // information). $l = self::$live->listMailboxes( '%', Horde_Imap_Client::MBOX_UNSUBSCRIBED, array('attributes' => true) ); $this->assertInternalType('array', $l); } /** * @depends testDeleteMailbox */ public function testCreateMailboxesForSelectedTests() { /* This method is mostly a placeholder to ensure that we create * the mailboxes for the tests that involve manipulation of the * contents of the mailbox. */ self::$live->createMailbox(self::$test_mbox); self::$live->createMailbox(self::$test_mbox_utf8); } /** * @depends testCreateMailboxesForSelectedTests */ public function testStatus() { // All status information for test mailbox. $s = self::$live->status( self::$test_mbox, Horde_Imap_Client::STATUS_ALL ); $this->assertInternalType('array', $s); // Only UIDNEXT status information for test mailbox. $s = self::$live->status( self::$test_mbox, Horde_Imap_Client::STATUS_UIDNEXT ); $this->assertInternalType('array', $s); // Only FIRSTUNSEEN, FLAGS, PERMFLAGS, HIGHESTMODSEQ, and UIDNOTSTICKY // status information for test mailbox. $s = self::$live->status( self::$test_mbox, Horde_Imap_Client::STATUS_FIRSTUNSEEN | Horde_Imap_Client::STATUS_FLAGS | Horde_Imap_Client::STATUS_PERMFLAGS | Horde_Imap_Client::STATUS_HIGHESTMODSEQ | Horde_Imap_Client::STATUS_UIDNOTSTICKY ); $this->assertInternalType('array', $s); // Github Issue #134 (UTF8 mailbox) $s = self::$live->status( self::$test_mbox_utf8, Horde_Imap_Client::STATUS_MESSAGES ); $this->assertEquals( 0, $s['messages'] ); } /** * @depends testStatus */ public function testAppendMessagesToMailbox() { // Appending test e-mail 1 (with Flagged), 2 via a stream (with Seen), // 3 via a stream (with internaldate), and 4 via a string: $handle = fopen(__DIR__ . '/../fixtures/remote2.txt', 'r'); $handle2 = fopen(__DIR__ . '/../fixtures/remote3.txt', 'r'); $uid = self::$live->append(self::$test_mbox, array( array( 'data' => file_get_contents(__DIR__ . '/../fixtures/remote1.txt'), 'flags' => array(Horde_Imap_Client::FLAG_FLAGGED) ), array( 'data' => $handle, 'flags' => array(Horde_Imap_Client::FLAG_SEEN) ), array( 'data' => $handle2, 'internaldate' => new DateTime('17 August 2003') ), array( 'data' => file_get_contents(__DIR__ . '/../fixtures/remote4.txt') ) )); if (!($uid instanceof Horde_Imap_Client_Ids)) { $this->fail('Append successful but UIDs not properly returned.'); } fclose($handle); fclose($handle2); } /** * @depends testAppendMessagesToMailbox */ public function testCopyingEmailToUtf8Mailbox() { $copy_uid = self::$live->copy( self::$test_mbox, self::$test_mbox_utf8, array( 'force_map' => true, 'ids' => new Horde_Imap_Client_Ids(1, true) ) ); $this->assertEquals( 1, count($copy_uid) ); } /** * @depends testCopyingEmailToUtf8Mailbox */ public function testAppendMessagesToUtf8Mailbox() { /* Use a different message than any currently living in test_mbox * since some servers (Gmail) will de-duplicate and ignore the later * move to that mailbox. */ $uid = self::$live->append(self::$test_mbox_utf8, array( array( 'data' => file_get_contents(__DIR__ . '/../fixtures/remote5.txt') ) )); if (!($uid instanceof Horde_Imap_Client_Ids)) { $this->fail('Append successful but UIDs not properly returned.'); } } /** * @depends testAppendMessagesToUtf8Mailbox */ public function testDeletingMessageFromMailboxViaFlagAndExpunge() { // Get status of test mailbox (should have 4 messages). $status = self::$live->status( self::$test_mbox, Horde_Imap_Client::STATUS_MESSAGES ); $this->assertEquals( 4, $status['messages'] ); // Flagging test e-mail 2 with the Deleted flag. self::$live->store(self::$test_mbox, array( 'add' => array(Horde_Imap_Client::FLAG_DELETED), 'ids' => new Horde_Imap_Client_Ids(2, true) )); // Expunging mailbox by specifying non-deleted UID. self::$live->expunge( self::$test_mbox, array('ids' => new Horde_Imap_Client_Ids(1, true)) ); // Expunging mailbox (should remove test e-mail 2) self::$live->expunge(self::$test_mbox); // Get status of test mailbox (should have 3 messages). $status = self::$live->status( self::$test_mbox, Horde_Imap_Client::STATUS_MESSAGES ); $this->assertEquals( 3, $status['messages'] ); } /** * @depends testDeletingMessageFromMailboxViaFlagAndExpunge */ public function testMoveMessage() { // Move test e-mail 2 from utf-8 test mailbox to the test mailbox. self::$live->copy( self::$test_mbox_utf8, self::$test_mbox, array( 'ids' => new Horde_Imap_Client_Ids(2, true), 'move' => true ) ); } /** * @depends testMoveMessage */ public function testOptimizedSearches() { // Searching test mailbox (should be optimized by using internal // status instead). $res = self::$live->search( self::$test_mbox, new Horde_Imap_Client_Search_Query(), array( 'results' => array(Horde_Imap_Client::SEARCH_RESULTS_COUNT) ) ); $this->assertEquals( 4, $res['count'] ); // All messages are unseen $query2 = new Horde_Imap_Client_Search_Query(); $query2->flag(Horde_Imap_Client::FLAG_SEEN, false); $res = self::$live->search( self::$test_mbox, $query2, array( 'results' => array(Horde_Imap_Client::SEARCH_RESULTS_COUNT) ) ); $this->assertEquals( 4, $res['count'] ); } /** * @depends testOptimizedSearches */ public function testSimpleSearch() { // Create a simple 'ALL' search query $all_query = new Horde_Imap_Client_Search_Query(); // Search test mailbox for all messages (returning UIDs). $res = self::$live->search(self::$test_mbox, $all_query); $this->assertEquals( 4, $res['count'] ); } /** * @depends testOptimizedSearches */ public function testSequenceNumberSearchReturn() { // Searching test mailbox for all messages (returning message sequence // numbers). $res = self::$live->search( self::$test_mbox, new Horde_Imap_Client_Search_Query(), array( 'results' => array( Horde_Imap_Client::SEARCH_RESULTS_COUNT, Horde_Imap_Client::SEARCH_RESULTS_MATCH, Horde_Imap_Client::SEARCH_RESULTS_MAX, Horde_Imap_Client::SEARCH_RESULTS_MIN ), 'sequence' => true ) ); $this->assertEquals( 4, $res['count'] ); } /** * @depends testOptimizedSearches */ public function testMailboxSort() { // Sort test mailbox by from and reverse date for all messages. $res = self::$live->search( self::$test_mbox, new Horde_Imap_Client_Search_Query(), array( 'sequence' => true, 'sort' => array( Horde_Imap_Client::SORT_FROM, Horde_Imap_Client::SORT_REVERSE, Horde_Imap_Client::SORT_DATE ) ) ); try { $this->assertEquals( array(3, 4, 1, 2), $res['match']->ids ); } catch (Exception $e) { $this->markTestSkipped('Broken IMAP server'); } } /** * @depends testOptimizedSearches */ public function testMailboxThreadByReferences() { if (!self::$live->capability->query('THREAD', 'REFERENCES')) { $this->markTestSkipped('Server does not support THREAD=REFERENCES'); } $res = self::$live->thread( self::$test_mbox, array( 'criteria' => Horde_Imap_Client::THREAD_REFERENCES, 'sequence' => true ) ); $this->assertInstanceOf( 'Horde_Imap_Client_Data_Thread', $res ); $this->assertEquals( 4, count($res) ); // Thread order: (1,4)(2)(3) $thread = $res->getThread(2); $this->assertArrayHasKey(2, $thread); $this->assertNull($thread[2]->base); $thread = $res->getThread(4); $this->assertArrayHasKey(1, $thread); $this->assertArrayHasKey(4, $thread); $this->assertEquals(1, $thread[1]->base); $this->assertEquals(1, $thread[4]->base); // Sort 1st 2 messages in test mailbox by thread - references // algorithm (UIDs). $ten_query = new Horde_Imap_Client_Search_Query(); $ten_query->ids(new Horde_Imap_Client_Ids('1:2', true)); $res = self::$live->thread( self::$test_mbox, array( 'criteria' => Horde_Imap_Client::THREAD_REFERENCES, 'search' => $ten_query ) ); $this->assertInstanceOf( 'Horde_Imap_Client_Data_Thread', $res ); // Thread order: (1)(2) $thread = $res->getThread(1); $this->assertArrayHasKey(1, $thread); $this->assertNull($thread[1]->base); } /** * @depends testOptimizedSearches */ public function testMailboxThreadByOrderedSubject() { // Sort test mailbox by thread - orderedsubject algorithm (sequence // numbers). $res = self::$live->thread( self::$test_mbox, array( 'criteria' => Horde_Imap_Client::THREAD_ORDEREDSUBJECT, 'sequence' => true ) ); $this->assertInstanceOf( 'Horde_Imap_Client_Data_Thread', $res ); $this->assertEquals( 4, count($res) ); // Thread order: (1,4)(2)(3) $thread = $res->getThread(2); $this->assertArrayHasKey(2, $thread); $this->assertNull($thread[2]->base); $thread = $res->getThread(4); $this->assertArrayHasKey(1, $thread); $this->assertArrayHasKey(4, $thread); try { $this->assertEquals(1, $thread[1]->base); } catch (Exception $e) { $this->markTestSkipped('Broken IMAP server'); } $this->assertEquals(1, $thread[4]->base); } /** * @depends testOptimizedSearches */ public function testSimpleFetch() { $simple_fetch = new Horde_Imap_Client_Fetch_Query(); $simple_fetch->structure(); $simple_fetch->envelope(); $simple_fetch->imapDate(); $simple_fetch->size(); $simple_fetch->flags(); // Simple fetch example. $res = self::$live->fetch( self::$test_mbox, $simple_fetch, array( 'ids' => new Horde_Imap_Client_Ids(1, true) ) ); $this->assertInstanceOf( 'Horde_Imap_Client_Fetch_Results', $res ); $this->assertEquals(1, count($res)); $this->assertInstanceOf( 'Horde_Imap_Client_Data_Envelope', $res[1]->getEnvelope() ); $this->assertEquals( 'Test e-mail 1', $res[1]->getEnvelope()->subject ); } /** * @depends testOptimizedSearches */ public function testComplexFetch() { // Fetching message information from complex MIME message. $complex_fetch = new Horde_Imap_Client_Fetch_Query(); $complex_fetch->fullText(array( 'length' => 100, 'peek' => true )); // Header of entire message $complex_fetch->headerText(array( 'length' => 100, 'peek' => true )); // Header of message/rfc822 part $complex_fetch->headerText(array( 'id' => 2, 'length' => 100, 'peek' => true )); // Body text of entire message $complex_fetch->bodyText(array( 'length' => 100, 'peek' => true )); // Body text of message/rfc822 part $complex_fetch->bodyText(array( 'id' => 2, 'length' => 100, 'peek' => true )); // MIME Header of multipart/alternative part $complex_fetch->mimeHeader('1', array( 'length' => 100, 'peek' => true )); // MIME Header of text/plain part embedded in message/rfc822 part $complex_fetch->mimeHeader('2.1', array( 'length' => 100, 'peek' => true )); // Body text of multipart/alternative part $complex_fetch->bodyPart('1', array( 'length' => 100, 'peek' => true )); // Body text of image/png part embedded in message/rfc822 part // Try to do server-side decoding, if available $complex_fetch->mimeHeader('2.2', array( 'decode' => true, 'length' => 100, 'peek' => true )); // If supported, return decoded body part size $complex_fetch->bodyPartSize('2.2'); // Select message-id header from base message header $complex_fetch->headers('headersearch1', array('message-id'), array( 'length' => 100, 'peek' => true )); // Select everything but message-id header from message/rfc822 header $complex_fetch->headers('headersearch2', array('message-id'), array( 'id' => '2', 'length' => 100, 'notsearch' => true, 'peek' => true )); $complex_fetch->structure(); $complex_fetch->flags(); $complex_fetch->imapDate(); $complex_fetch->size(); $complex_fetch->uid(); if (self::$live->capability->query('CONDSTORE')) { $complex_fetch->modseq(); } try { $res = self::$live->fetch( self::$test_mbox, $complex_fetch, array( 'ids' => new Horde_Imap_Client_Ids(3, true) ) ); } catch (Horde_Imap_Client_Exception $e) { if ($e->getCode() === $e::MBOXNOMODSEQ) { $this->markTestSkipped('Mailbox does not support MODSEQ.'); } throw $e; } $this->assertInstanceOf( 'Horde_Imap_Client_Fetch_Results', $res ); $this->assertEquals(1, count($res)); $this->assertEquals( 'Message-ID: <2008yhnujm@foo.example.com>', trim($res[3]->getHeaders('headersearch1')) ); /* Return stream instead. */ $this->assertInternalType( 'resource', $res[3]->getHeaders('headersearch1', Horde_Imap_Client_Data_Fetch::HEADER_STREAM) ); /* Parse headers instead. */ $this->assertInstanceOf( 'Horde_Mime_Headers', $res[3]->getHeaders('headersearch1', Horde_Imap_Client_Data_Fetch::HEADER_PARSE) ); } /** * @depends testCreateMailboxesForSelectedTests */ public function testMetadata() { try { self::$live->setMetadata( self::$test_mbox, array('/shared/comment' => 'test') ); } catch (Horde_Imap_Client_Exception_NoSupportExtension $e) { $this->markTestSkipped('Server does not support METADATA.'); } $res = self::$live->getMetadata(self::$test_mbox, '/shared/comment'); $this->assertArrayHasKey(self::$test_mbox, $res); $this->assertArrayHasKey('/shared/comment', $res[self::$test_mbox]); $this->assertEquals( 'test', $res[self::$test_mbox]['/shared/comment'] ); } /** * @depends testSimpleSearch * @depends testSequenceNumberSearchReturn * @depends testOptimizedSearches * @depends testMailboxSort * @depends testMailboxThreadByReferences * @depends testMailboxThreadByOrderedSubject * @depends testSimpleFetch * @depends testComplexFetch */ public function testFlagMessageDeletedWithoutExpunging() { // Flagging test e-mail 3 with the Deleted flag. self::$live->store( self::$test_mbox, array( 'add' => array(Horde_Imap_Client::FLAG_DELETED), 'ids' => new Horde_Imap_Client_Ids(3, true) ) ); // Get status of test mailbox (should have 4 messages). // Gmail will auto-expunge, so skip the close() test. $status = self::$live->status( self::$test_mbox, Horde_Imap_Client::STATUS_MESSAGES ); if ($status['messages'] === 3) { return; } // Closing test mailbox without expunging. self::$live->close(); // Get status of test mailbox (should have 4 messages). $status = self::$live->status( self::$test_mbox, Horde_Imap_Client::STATUS_MESSAGES ); $this->assertEquals( 4, $status['messages'] ); } /** * @depends testFlagMessageDeletedWithoutExpunging */ public function testExpungeMessagesWhileClosing() { // Re-open test mailbox READ-WRITE. self::$live->openMailbox( self::$test_mbox, Horde_Imap_Client::OPEN_READWRITE ); // Closing test mailbox while expunging. self::$live->close(array('expunge' => true)); // Get status of test mailbox (should have 3 messages). $status = self::$live->status( self::$test_mbox, Horde_Imap_Client::STATUS_MESSAGES ); $this->assertEquals(3, $status['messages']); } /** * @depends testLogin * @expectedException Horde_Imap_Client_Exception */ public function testAppendToNonExistentMailbox() { // Do a test append to a non-existent mailbox - this MUST fail (RFC // 3501 [6.3.11]). self::$live->append( self::$test_mbox . 'ABC', array( array( 'data' => file_get_contents(__DIR__ . '/../fixtures/remote1.txt'), 'flags' => array(Horde_Imap_Client::FLAG_FLAGGED) ) ) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Live/ImapTest.php0000664000175000017500000000345013150761653022576 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Live_ImapTest extends Horde_Test_Case { /** * Add the tests to the current test runner. */ public static function suite() { $suite = new PHPUnit_Framework_TestSuite; $c = self::getConfig('IMAPCLIENT_TEST_CONFIG', __DIR__ . '/../'); if (!is_null($c) && !empty($c['imapclient'])) { $key = 0; foreach ($c['imapclient'] as $val) { if (!empty($val['enabled']) && !empty($val['client_config']['username']) && !empty($val['client_config']['password'])) { /* Create a temp class for each instance to ensure that * no @depends mixing between servers occurs. */ $temp_class = 'Horde_Imap_Client_Live_Imap_' . ++$key; eval( "class $temp_class extends Horde_Imap_Client_Live_Imap {}" ); Horde_Imap_Client_Live_Imap::$config[] = $val; $suite->addTestSuite($temp_class); } } } return $suite; } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Live/Pop3.php0000664000175000017500000000604713150761653021676 0ustar janjan * @category Horde * @copyright 2013-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Live_Pop3 extends Horde_Imap_Client_Live_Base { public static $config; public static function setUpBeforeClass() { $c = array_shift(self::$config); try { $c['client_config']['cache'] = array( 'cacheob' => new Horde_Cache( new Horde_Cache_Storage_Mock(), array('compress' => true) ) ); } catch (Exception $e) {} self::$live = new Horde_Imap_Client_Socket_Pop3( $c['client_config'] ); } /* Tests */ public function testPreLoginCommands() { $c = self::$live->capability; $this->assertInstanceOf( 'Horde_Imap_Client_Data_Capability', $c ); } /** * @depends testPreLoginCommands */ public function testLogin() { /* Throws exception on error, which will prevent all further testing * on this server. */ self::$live->login(); } /** * @depends testLogin */ public function testPostLoginCapability() { /* Re-use testPreLoginCommands(). */ $this->testPreLoginCommands(); } /** * @depends testLogin */ public function testOpenMailbox() { self::$live->openMailbox('INBOX', Horde_Imap_Client::OPEN_READONLY); self::$live->openMailbox('INBOX', Horde_Imap_Client::OPEN_READWRITE); self::$live->openMailbox('INBOX', Horde_Imap_Client::OPEN_AUTO); } /** * @depends testLogin */ public function testListMailbox() { // Listing all mailboxes (flat format). $l = self::$live->listMailboxes( '*', Horde_Imap_Client::MBOX_ALL, array('flat' => true) ); $this->assertEquals(1, count($l)); } /** * @depends testLogin */ public function testStatus() { $s = self::$live->status('INBOX', Horde_Imap_Client::STATUS_ALL); $this->assertInternalType('array', $s); $this->assertArrayHasKey('messages', $s); $this->assertArrayHasKey('recent', $s); $this->assertEquals($s['messages'], $s['recent']); $this->assertArrayHasKey('uidnext', $s); $this->assertArrayHasKey('uidvalidity', $s); $this->assertArrayHasKey('unseen', $s); $this->assertEquals(0, $s['unseen']); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Live/Pop3Test.php0000664000175000017500000000345513150761653022536 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Live_Pop3Test extends Horde_Test_Case { /** * Add the tests to the current test runner. */ public static function suite() { $suite = new PHPUnit_Framework_TestSuite; $c = self::getConfig('IMAPCLIENT_TEST_CONFIG_POP3', __DIR__ . '/../'); if (!is_null($c) && !empty($c['pop3client'])) { $key = 0; foreach ($c['pop3client'] as $val) { if (!empty($val['enabled']) && !empty($val['client_config']['username']) && !empty($val['client_config']['password'])) { /* Create a temp class for each instance to ensure that * no @depends mixing between servers occurs. */ $temp_class = 'Horde_Imap_Client_Live_Pop3_' . ++$key; eval( "class $temp_class extends Horde_Imap_Client_Live_Pop3 {}" ); Horde_Imap_Client_Live_Pop3::$config[] = $val; $suite->addTestSuite($temp_class); } } } return $suite; } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Namespace/DataTest.php0000664000175000017500000001045513150761653023561 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Namespace_DataTest extends PHPUnit_Framework_TestCase { private $ob; public function setUp() { $this->ob = new Horde_Imap_Client_Data_Namespace(); } /** * @dataProvider defaultProvider */ public function testDefaultValues($name, $value) { $this->assertEquals( $value, $this->ob->$name ); } /** * @dataProvider settingProvider */ public function testSettingValues($name, $value, $expected = null) { if (is_null($expected)) { $expected = $value; } $this->assertFalse(isset($this->ob->$name)); $this->ob->$name = $value; $this->assertEquals( $expected, $this->ob->$name ); if (!is_null($value)) { $this->assertTrue(isset($this->ob->$name)); } } /** */ public function testStringVal() { $this->assertEquals( '', strval($this->ob) ); $this->ob->name = 123; $this->assertEquals( '123', strval($this->ob) ); } /** */ public function testBaseReturn() { $this->ob->delimiter = '.'; $this->ob->name = 'foo.'; $this->assertEquals( 'foo', $this->ob->base ); } /** */ public function testSerialize() { $this->ob->delimiter = '.'; $this->ob->name = 'foo.'; $ob2 = unserialize(serialize($this->ob)); $this->assertEquals( $this->ob->delimiter, $ob2->delimiter ); $this->assertEquals( $this->ob->name, $ob2->name ); $this->assertEquals( $this->ob->translation, $ob2->translation ); } /** * @dataProvider stripProvider */ public function testStripNamespace($name, $delimiter, $mbox, $expected) { $this->ob->name = $name; $this->ob->delimiter = $delimiter; $this->assertEquals( $expected, $this->ob->stripNamespace($mbox) ); } /** */ public function defaultProvider() { return array( array('base', ''), array('delimiter', ''), array('hidden', false), array('name', ''), array('translation', ''), array('type', Horde_Imap_Client_Data_Namespace::NS_PERSONAL), // Bogus value array('foo', null) ); } /** */ public function settingProvider() { return array( array('delimiter', '.'), array('delimiter', '/'), array('delimiter', 1, '1'), array('hidden', false), array('hidden', 0, false), array('hidden', true), array('hidden', 1, true), array('name', 'foo'), array('name', 123, '123'), array('translation', 'foo'), array('translation', 123, '123'), array('type', Horde_Imap_Client_Data_Namespace::NS_PERSONAL), array('type', Horde_Imap_Client_Data_Namespace::NS_OTHER), array('type', Horde_Imap_Client_Data_Namespace::NS_SHARED), // Bogus value array('foo', null) ); } /** */ public function stripProvider() { return array( array('foo.', '.', 'foo.bar', 'bar'), array('foo.', '.', 'foo2.bar', 'foo2.bar'), array('foo.bar.', '.', 'foo.bar.baz', 'baz'), array('', '.', 'foo.bar', 'foo.bar') ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Namespace/ListTest.php0000664000175000017500000000620513150761653023621 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Namespace_ListTest extends PHPUnit_Framework_TestCase { private $ob; public function setUp() { $this->ob = new Horde_Imap_Client_Namespace_List(); $ob2 = new Horde_Imap_Client_Data_Namespace(); $ob2->delimiter = '.'; $ob2->type = $ob2::NS_SHARED; $this->ob[''] = $ob2; $ob3 = new Horde_Imap_Client_Data_Namespace(); $ob3->delimiter = '.'; $ob3->hidden = true; $ob3->name = 'foo'; $this->ob['foo'] = $ob3; } /** * @dataProvider arrayProvider */ public function testArrayAccess($name, $exists = true) { if ($exists) { $this->assertTrue(isset($this->ob[$name])); $this->assertInstanceof( 'Horde_Imap_Client_Data_Namespace', $this->ob[$name] ); } else { $this->assertFalse(isset($this->ob[$name])); $this->assertNull($this->ob[$name]); } } /** */ public function testCountable() { $this->assertEquals( 2, count($this->ob) ); } /** */ public function testIterator() { foreach ($this->ob as $val) { $this->assertInstanceof( 'Horde_Imap_Client_Data_Namespace', $val ); } } /** */ public function testSerialize() { $ob2 = unserialize(serialize($this->ob)); $this->assertEquals( 2, count($this->ob) ); } /** * @dataProvider getNamespaceProvider */ public function testGetNamespace($mbox, $personal, $expected) { if (is_null($expected)) { $this->assertNull($this->ob->getNamespace($mbox, $personal)); } else { $this->assertEquals( $expected, strval($this->ob->getNamespace($mbox, $personal)) ); } } /** */ public function arrayProvider() { return array( array(''), array('foo'), array('bar', false) ); } /** */ public function getNamespaceProvider() { return array( array('baz', false, ''), array('baz', true, null), array('foo.bar', false, 'foo'), array('foo.bar', true, 'foo'), array('baz.bar', false, ''), array('baz.bar', true, null) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Socket/ClientSortTest.php0000664000175000017500000002502713150761653024333 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Socket_ClientSortTest extends PHPUnit_Framework_TestCase { public $socket_ob; public $sort_ob; public function setUp() { require_once __DIR__ . '/../Stub/ClientSort.php'; require_once __DIR__ . '/../Stub/Socket.php'; $this->socket_ob = new Horde_Imap_Client_Stub_Socket(array( 'password' => 'foo', 'username' => 'bar' )); $this->sort_ob = new Horde_Imap_Client_Stub_ClientSort( $this->socket_ob ); } /** * @dataProvider clientSortProvider */ public function testClientSortProvider($sort, $expected, $locale, $fetch_data) { $ids = new Horde_Imap_Client_Ids(); $pipeline = $this->socket_ob->pipeline(); foreach ($fetch_data as $val) { $token = new Horde_Imap_Client_Tokenize($val); $token->rewind(); $token->next(); $ids->add($token->next()); $this->socket_ob->doServerResponse($pipeline, $val); } $this->socket_ob->fetch_results = $pipeline->fetch; $sorted = $this->sort_ob->clientSort( $ids, array( 'sort' => $sort ) ); $this->assertEquals( count($expected), count($sorted) ); if (!$locale || class_exists('Collator')) { $this->assertEquals( $expected, array_values($sorted) ); } } public function clientSortProvider() { // Test file is base64 encoded to obfuscate the data. $fetch_data = array_filter(explode("\n", base64_decode( file_get_contents(__DIR__ . '/../fixtures/clientsort.txt') ))); $fetch_data2 = array_filter(explode("\n", base64_decode( file_get_contents(__DIR__ . '/../fixtures/clientsort2.txt') ))); return array( array( array(Horde_Imap_Client::SORT_SEQUENCE), range(1, 9), false, $fetch_data ), array( array( Horde_Imap_Client::SORT_REVERSE, Horde_Imap_Client::SORT_SEQUENCE ), range(9, 1), false, $fetch_data ), array( array(Horde_Imap_Client::SORT_ARRIVAL), array( 5, // 02:30 6, // 03:30 7, // 04:30 8, // 05:30 9, // 06:30 1, // 07:30 2, // 08:30 3, // 09:30 4 // 10:30 ), false, $fetch_data ), array( array( Horde_Imap_Client::SORT_REVERSE, Horde_Imap_Client::SORT_ARRIVAL ), array( 4, // See SORT_ARRIVAL example above for non-reverse // results 3, 2, 1, 9, 8, 7, 6, 5 ), false, $fetch_data ), array( array(Horde_Imap_Client::SORT_DATE), array( 6, // Mon, 6 Feb 1993 02:53:47 -0800 (PST) 9, // Wed, 08 Sep 1999 14:23:47 +0200 8, // Tue, 20 Jun 2000 21:21:30 -0400 1, // Thu, 02 May 2002 16:30:20 +0000 2, // Sun, 12 May 2002 00:16:32 -0500 3, // 24 May 2002 13:29:00 +0200 5, // Sun, 26 May 2002 15:15:02 -0300 4, // Mon, 3 Jun 2002 13:32:31 -0400 7 // Sun, 9 Jun 2002 19:43:35 -0400 ), false, $fetch_data ), array( array(Horde_Imap_Client::SORT_FROM), array( 8, // chuck 7, // hagendaz 6, // mrc 4, // NAVMSE-EXCHANGE1 1, // pear-cvs-digest-help 9, // philip.steeman 5, // publicidade 2, // quelatio 3, // Timo.Tervo ), true, $fetch_data ), array( array(Horde_Imap_Client::SORT_TO), array( 8, // chagenbu 7, // chuck 6, // MRC 1, // pear-cvs 2, // quelatio 5, // slusarz 4, // slusarz2 9, // steeman 3, // timo.tervo ), true, $fetch_data ), array( array(Horde_Imap_Client::SORT_DISPLAYFROM), array( 8, // Chuck 2, // Jesus 6, // Mark 4, // NAV 1, // pear 9, // Philip 5, // publicidade 3, // Tervo 7 // Walt ), true, $fetch_data ), array( array(Horde_Imap_Client::SORT_DISPLAYTO), array( 4, // ' 8, // chagenbu 7, // Charles Hagenbuch 6, // MRC 1, // pear 2, // quelatio 5, // slusarz 9, // steeman 3, // Timo ), true, $fetch_data ), /* Bug #10503 */ array( array(Horde_Imap_Client::SORT_SUBJECT), array( 9, // excel 5, // Hello 2, // Interesante 3, // Jatko 6, // Multi 4, // Norton 8, // pdf 1, // pear, 7 // Photo ), true, $fetch_data ), array( array(Horde_Imap_Client::SORT_SIZE), array( 4, // 1762 5, // 3259 2, // 4967 8, // 10471 9, // 22262 1, // 38751 3, // 134123 7, // 475569 6 // 1845271 ), false, $fetch_data ), /* Test "ties" in data. */ array( array( Horde_Imap_Client::SORT_SIZE, Horde_Imap_Client::SORT_DATE ), array( 1, 2 ), false, $fetch_data2 ) ); } public function testClientSideThreadOrderedSubject() { $data = array( array( 'Sat, 26 Jul 2008 21:10:00 -0500 (CDT)', 'Test e-mail 1' ), array( 'Sat, 26 Jul 2008 21:10:00 -0500 (CDT)', 'Test e-mail 2' ), array( 'Sat, 26 Jul 2008 22:29:20 -0500 (CDT)', 'Re: Test e-mail 2' ), array( 'Sat, 26 Jul 2008 21:10:00 -0500 (CDT)', 'Test e-mail 1' ), ); $results = new Horde_Imap_Client_Fetch_Results(); foreach ($data as $key => $val) { $data = new Horde_Imap_Client_Data_Fetch(); $data->setEnvelope( new Horde_Imap_Client_Data_Envelope(array( 'date' => $val[0], 'subject' => $val[1] )) ); $results[++$key] = $data; } $thread = $this->sort_ob->threadOrderedSubject($results, true); foreach (array(1, 4) as $val) { $t = $thread->getThread($val); $this->assertEquals( array(1, 4), array_keys($t) ); $this->assertEquals( 1, $t[1]->base ); $this->assertEquals( 1, $t[1]->last ); $this->assertEquals( 0, $t[1]->level ); $this->assertEquals( 1, $t[4]->base ); $this->assertEquals( 1, $t[4]->last ); $this->assertEquals( 1, $t[4]->level ); } foreach (array(2, 3) as $val) { $t = $thread->getThread($val); $this->assertEquals( array(2, 3), array_keys($t) ); $this->assertEquals( 2, $t[2]->base ); $this->assertEquals( 1, $t[2]->last ); $this->assertEquals( 0, $t[2]->level ); $this->assertEquals( 2, $t[3]->base ); $this->assertEquals( 1, $t[3]->last ); $this->assertEquals( 1, $t[3]->level ); } } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Stub/ClientSort.php0000664000175000017500000000210113150761653023144 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Stub_ClientSort extends Horde_Imap_Client_Socket_ClientSort { public function __construct(Horde_Imap_Client_Socket $socket) { parent::__construct($socket); if (class_exists('Collator')) { $this->_collator = new Collator('root'); } } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Stub/DigestMD5.php0000664000175000017500000000236113150761653022613 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Stub_Auth_DigestMD5 extends Horde_Imap_Client_Auth_DigestMD5 { /** * Cnonce to use. * * @var string */ protected $_cnonce; /** */ public function __construct($id, $pass, $challenge, $hostname, $service, $cnonce) { $this->_cnonce = $cnonce; parent::__construct($id, $pass, $challenge, $hostname, $service); } /** */ protected function _getCnonce() { return $this->_cnonce; } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Stub/Scram.php0000664000175000017500000000162313150761653022133 0ustar janjan * @category Horde * @copyright 2015-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Stub_Auth_Scram extends Horde_Imap_Client_Auth_Scram { /** */ public function setNonce($nonce) { $this->_nonce = $nonce; } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Stub/Socket.php0000664000175000017500000000525413150761653022322 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Stub_Socket extends Horde_Imap_Client_Socket { public $fetch_results; public function getThreadSort($data) { return new Horde_Imap_Client_Data_Thread($this->doServerResponse($this->_pipeline(), $data)->data['threadparse'], 'uid'); } public function parseNamespace($data) { return $this->doServerResponse($this->_pipeline(), $data)->data['namespace']; } public function parseACL($data) { return $this->doServerResponse($this->_pipeline(), $data)->data['getacl']; } public function parseMyACLRights($data) { return $this->doServerResponse($this->_pipeline(), $data)->data['myrights']; } public function parseListRights($data) { return $this->doServerResponse($this->_pipeline(), $data)->data['listaclrights']; } /** * @param array $data Options: * - results: (Horde_Imap_Client_Fetch_Results) */ public function parseFetch($data, array $opts = array()) { $pipeline = $this->_pipeline(); if (isset($opts['results'])) { $pipeline->fetch = $opts['results']; } $pipeline->data['modseqs_nouid'] = array(); return $this->doServerResponse($pipeline, $data); } public function doServerResponse($pipeline, $data) { $server = Horde_Imap_Client_Interaction_Server::create( new Horde_Imap_Client_Tokenize($data) ); $this->_serverResponse($pipeline, $server); return $pipeline; } public function doResponseCode($data) { $server = Horde_Imap_Client_Interaction_Server::create( new Horde_Imap_Client_Tokenize($data) ); $this->_responseCode($this->_pipeline(), $server); } public function pipeline($cmd = null) { return $this->_pipeline($cmd); } public function fetch($mailbox, $query, array $options = array()) { return $this->fetch_results; } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Stub/Utf7imap.php0000664000175000017500000000163113150761653022561 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Stub_Utf7imap extends Horde_Imap_Client_Utf7imap { public static function setMbstring($val) { self::$_mbstring = (bool)$val; } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Url/BaseTest.php0000664000175000017500000000231013150761653022417 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Url_BaseTest extends PHPUnit_Framework_TestCase { /** * @dataProvider badUrlProvider */ public function testBadUrl($classname) { $url = new $classname('NOT A VALID URL'); $this->assertNull($url->hostspec); } public function badUrlProvider() { return array( array('Horde_Imap_Client_Url'), array('Horde_Imap_Client_Url_Imap'), array('Horde_Imap_Client_Url_Imap_Relative'), array('Horde_Imap_Client_Url_Pop3') ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Url/ImapDeprecatedTest.php0000664000175000017500000001161113150761653024420 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Url_ImapDeprecatedTest extends Horde_Imap_Client_Url_TestBase { protected $classname = 'Horde_Imap_Client_Url'; protected $protocol = 'imap'; public function testUrlProvider() { return array( array( 'imap://test.example.com/', null, array( 'hostspec' => 'test.example.com', 'port' => 143, 'relative' => false, 'mailbox' => '', 'protocol' => 'imap' ) ), array( 'imap://test.example.com:143/', 'imap://test.example.com/', array( 'hostspec' => 'test.example.com', 'port' => 143, 'relative' => false, 'mailbox' => '', 'protocol' => 'imap' ) ), array( 'imap://testuser@test.example.com/', null, array( 'hostspec' => 'test.example.com', 'port' => 143, 'relative' => false, 'username' => 'testuser', 'mailbox' => '', 'protocol' => 'imap' ) ), array( 'imap://testuser@test.example.com:14300/', null, array( 'hostspec' => 'test.example.com', 'port' => 14300, 'relative' => false, 'username' => 'testuser', 'mailbox' => '', 'protocol' => 'imap' ) ), array( 'imap://testuser;AUTH=*@test.example.com:143/', 'imap://testuser@test.example.com/', array( 'hostspec' => 'test.example.com', 'port' => 143, 'username' => 'testuser', 'relative' => false, 'mailbox' => '', 'protocol' => 'imap' ) ), array( 'imap://testuser;AUTH=PLAIN@test.example.com:14300/', null, array( 'hostspec' => 'test.example.com', 'port' => 14300, 'username' => 'testuser', 'relative' => false, 'auth' => 'PLAIN', 'mailbox' => '', 'protocol' => 'imap' ) ), array( 'imap://test.example.com:14300/INBOX.Quarant%26AOQ-ne;UIDVALIDITY=1240054819/;UID=39193/;SECTION=HEADER/;PARTIAL=0.1024', null, array( 'hostspec' => 'test.example.com', 'partial' => '0.1024', 'port' => 14300, 'relative' => false, 'section' => 'HEADER', 'uid' => 39193, 'uidvalidity' => 1240054819, 'mailbox' => 'INBOX.Quarant&AOQ-ne', 'protocol' => 'imap' ) ), array( 'imap://test.example.com:14300/INBOX;UIDVALIDITY=123/;UID=456?FLAGGED%20SINCE%201-Feb-1994%20NOT%20FROM%20%22Smith%22', 'imap://test.example.com:14300/INBOX;UIDVALIDITY=123?FLAGGED%20SINCE%201-Feb-1994%20NOT%20FROM%20%22Smith%22', array( 'hostspec' => 'test.example.com', 'port' => 14300, 'relative' => false, 'uidvalidity' => 123, 'mailbox' => 'INBOX', // Ignore extra data after UIDVALIDITY 'uid' => '', // Search example from RFC 3501 [6.4.4] 'search' => 'FLAGGED SINCE 1-Feb-1994 NOT FROM "Smith"', 'protocol' => 'imap' ) ) ); } public function serializeProvider() { return array( array('imap://test.example.com/') ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Url/ImapRelativeTest.php0000664000175000017500000001063513150761653024140 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Url_ImapRelativeTest extends Horde_Imap_Client_Url_TestBase { protected $classname = 'Horde_Imap_Client_Url_Imap_Relative'; protected $protocol = 'imap'; public function testUrlProvider() { return array( array( 'imap://test.example.com/', '', array( 'host' => 'test.example.com', 'port' => 143, 'mailbox' => null ) ), array( 'imap://test.example.com:143/', '', array( 'host' => 'test.example.com', 'port' => 143, 'mailbox' => null ) ), array( 'imap://testuser@test.example.com/', '', array( 'host' => 'test.example.com', 'port' => 143, 'username' => 'testuser', 'mailbox' => null ) ), array( 'imap://testuser@test.example.com:14300/', '', array( 'host' => 'test.example.com', 'port' => 14300, 'username' => 'testuser', 'mailbox' => null, ) ), array( 'imap://testuser;AUTH=*@test.example.com:143/', '', array( 'auth' => null, 'host' => 'test.example.com', 'port' => 143, 'username' => 'testuser', 'mailbox' => null ) ), array( 'imap://testuser;AUTH=PLAIN@test.example.com:14300/', '', array( 'host' => 'test.example.com', 'port' => 14300, 'username' => 'testuser', 'auth' => 'PLAIN', 'mailbox' => null ) ), array( 'imap://test.example.com:14300/Quarant%26AOQ-ne;UIDVALIDITY=1240054819/;UID=39193/;SECTION=HEADER/;PARTIAL=0.1024', '/Quarant%26AOQ-ne;UIDVALIDITY=1240054819/;UID=39193/;SECTION=HEADER/;PARTIAL=0.1024', array( 'host' => 'test.example.com', 'partial' => '0.1024', 'port' => 14300, 'section' => 'HEADER', 'uid' => 39193, 'uidvalidity' => 1240054819, 'mailbox' => new Horde_Imap_Client_Mailbox('Quarant&AOQ-ne', true) ) ), array( 'imap://test.example.com:14300/INBOX;UIDVALIDITY=123/;UID=456?FLAGGED%20SINCE%201-Feb-1994%20NOT%20FROM%20%22Smith%22', '/INBOX;UIDVALIDITY=123?FLAGGED%20SINCE%201-Feb-1994%20NOT%20FROM%20%22Smith%22', array( 'host' => 'test.example.com', 'port' => 14300, 'uidvalidity' => 123, 'mailbox' => new Horde_Imap_Client_Mailbox('INBOX', true), // Ignore extra data after UIDVALIDITY 'uid' => '', // Search example from RFC 3501 [6.4.4] 'search' => 'FLAGGED SINCE 1-Feb-1994 NOT FROM "Smith"' ) ), array( ';UID=1240054819/;SECTION=HEADER', null, array() ) ); } public function serializeProvider() { return array( array(';UID=1240054819') ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Url/ImapTest.php0000664000175000017500000001042613150761653022442 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Url_ImapTest extends Horde_Imap_Client_Url_TestBase { protected $classname = 'Horde_Imap_Client_Url_Imap'; protected $protocol = 'imap'; public function testUrlProvider() { return array( array( 'imap://test.example.com/', null, array( 'host' => 'test.example.com', 'port' => 143, 'mailbox' => null ) ), array( 'imap://test.example.com:143/', 'imap://test.example.com/', array( 'host' => 'test.example.com', 'port' => 143, 'mailbox' => null ) ), array( 'imap://testuser@test.example.com/', null, array( 'host' => 'test.example.com', 'port' => 143, 'username' => 'testuser', 'mailbox' => null ) ), array( 'imap://testuser@test.example.com:14300/', null, array( 'host' => 'test.example.com', 'port' => 14300, 'username' => 'testuser', 'mailbox' => null, ) ), array( 'imap://testuser;AUTH=*@test.example.com:143/', 'imap://testuser@test.example.com/', array( 'auth' => null, 'host' => 'test.example.com', 'port' => 143, 'username' => 'testuser', 'mailbox' => null ) ), array( 'imap://testuser;AUTH=PLAIN@test.example.com:14300/', null, array( 'host' => 'test.example.com', 'port' => 14300, 'username' => 'testuser', 'auth' => 'PLAIN', 'mailbox' => null ) ), array( 'imap://test.example.com:14300/Quarant%26AOQ-ne;UIDVALIDITY=1240054819/;UID=39193/;SECTION=HEADER/;PARTIAL=0.1024', null, array( 'host' => 'test.example.com', 'partial' => '0.1024', 'port' => 14300, 'section' => 'HEADER', 'uid' => 39193, 'uidvalidity' => 1240054819, 'mailbox' => new Horde_Imap_Client_Mailbox('Quarant&AOQ-ne', true) ) ), array( 'imap://test.example.com:14300/INBOX;UIDVALIDITY=123/;UID=456?FLAGGED%20SINCE%201-Feb-1994%20NOT%20FROM%20%22Smith%22', 'imap://test.example.com:14300/INBOX;UIDVALIDITY=123?FLAGGED%20SINCE%201-Feb-1994%20NOT%20FROM%20%22Smith%22', array( 'host' => 'test.example.com', 'port' => 14300, 'uidvalidity' => 123, 'mailbox' => new Horde_Imap_Client_Mailbox('INBOX', true), // Ignore extra data after UIDVALIDITY 'uid' => '', // Search example from RFC 3501 [6.4.4] 'search' => 'FLAGGED SINCE 1-Feb-1994 NOT FROM "Smith"' ) ) ); } public function serializeProvider() { return array( array('imap://test.example.com/') ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Url/Pop3DeprecatedTest.php0000664000175000017500000000751113150761653024357 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Url_Pop3DeprecatedTest extends Horde_Imap_Client_Url_TestBase { protected $classname = 'Horde_Imap_Client_Url'; protected $protocol = 'pop'; public function testUrlProvider() { return array( array( 'pop://test.example.com/', null, array( 'hostspec' => 'test.example.com', 'port' => 110, 'relative' => false, 'protocol' => 'pop' ) ), array( 'pop://test.example.com:110/', 'pop://test.example.com/', array( 'hostspec' => 'test.example.com', 'port' => 110, 'relative' => false, 'protocol' => 'pop' ) ), array( 'pop://testuser@test.example.com/', null, array( 'hostspec' => 'test.example.com', 'port' => 110, 'relative' => false, 'username' => 'testuser', 'protocol' => 'pop' ) ), // This is the default port for IMAP, not POP3 array( 'pop://testuser@test.example.com:143/', null, array( 'hostspec' => 'test.example.com', 'port' => 143, 'relative' => false, 'username' => 'testuser', 'protocol' => 'pop' ) ), array( 'pop://testuser;AUTH=*@test.example.com:110/', 'pop://testuser@test.example.com/', array( 'hostspec' => 'test.example.com', 'port' => 110, 'username' => 'testuser', 'relative' => false, 'protocol' => 'pop' ) ), array( 'pop://testuser;AUTH=PLAIN@test.example.com/', null, array( 'hostspec' => 'test.example.com', 'port' => 110, 'username' => 'testuser', 'relative' => false, 'auth' => 'PLAIN', 'protocol' => 'pop' ) ), // Ignore everything after the port. array( 'pop://test.example.com:110/INBOX.Quarant%26AOQ-ne;UIDVALIDITY=1240054819/;UID=39193/;SECTION=HEADER', 'pop://test.example.com/', array( 'hostspec' => 'test.example.com', 'port' => 110, 'relative' => false, 'section' => '', 'uid' => '', 'uidvalidity' => '', 'mailbox' => '' ) ) ); } public function serializeProvider() { return array( array('pop://test.example.com/') ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Url/Pop3Test.php0000664000175000017500000000651313150761653022377 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Url_Pop3Test extends Horde_Imap_Client_Url_TestBase { protected $classname = 'Horde_Imap_Client_Url_Pop3'; protected $host = 'host'; protected $protocol = 'pop'; public function testUrlProvider() { return array( array( 'pop://test.example.com/', null, array( 'host' => 'test.example.com', 'port' => 110 ) ), array( 'pop://test.example.com:110/', 'pop://test.example.com/', array( 'host' => 'test.example.com', 'port' => 110 ) ), array( 'pop://testuser@test.example.com/', null, array( 'host' => 'test.example.com', 'port' => 110, 'username' => 'testuser' ) ), // This is the default port for IMAP, not POP3 array( 'pop://testuser@test.example.com:143/', null, array( 'host' => 'test.example.com', 'port' => 143, 'username' => 'testuser' ) ), array( 'pop://testuser;AUTH=*@test.example.com:110/', 'pop://testuser@test.example.com/', array( 'auth' => null, 'host' => 'test.example.com', 'port' => 110, 'username' => 'testuser' ) ), array( 'pop://testuser;AUTH=PLAIN@test.example.com/', null, array( 'host' => 'test.example.com', 'port' => 110, 'username' => 'testuser', 'auth' => 'PLAIN' ) ), // Ignore everything after the port. array( 'pop://test.example.com:110/INBOX.Quarant%26AOQ-ne;UIDVALIDITY=1240054819/;UID=39193/;SECTION=HEADER', 'pop://test.example.com/', array( 'host' => 'test.example.com', 'port' => 110, 'section' => '', 'uid' => '', 'uidvalidity' => '', 'mailbox' => '' ) ) ); } public function serializeProvider() { return array( array('pop://test.example.com/') ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Url/TestBase.php0000664000175000017500000000304713150761653022427 0ustar janjan * @category Horde * @copyright 2014-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ abstract class Horde_Imap_Client_Url_TestBase extends PHPUnit_Framework_TestCase { protected $classname; /** * @dataProvider testUrlProvider */ public function testUrlParsing($in, $url, $expected) { $ob = new $this->classname($in); foreach ($expected as $key => $val) { $this->assertEquals( $val, $ob->$key ); } $this->assertEquals( is_null($url) ? $in : $url, strval($ob) ); } abstract public function testUrlProvider(); /** * @dataProvider serializeProvider() */ public function testSerialize($url) { $orig = new $this->classname($url); $copy = unserialize(serialize($orig)); $this->assertEquals( $orig, $copy ); } abstract public function serializeProvider(); } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/AllTests.php0000664000175000017500000000013213150761653021676 0ustar janjanrun(); Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/AuthTest.php0000664000175000017500000000644513150761653021721 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_AuthTest extends PHPUnit_Framework_TestCase { public static function setUpBeforeClass() { require_once __DIR__ . '/Stub/DigestMD5.php'; require_once __DIR__ . '/Stub/Scram.php'; } /** * @dataProvider digestMd5Provider */ public function testDigestMd5($c) { $ob = new Horde_Imap_Client_Stub_Auth_DigestMD5( $c['user'], $c['pass'], $c['challenge'], $c['hostname'], $c['service'], $c['cnonce'] ); $this->assertEquals( $c['expected'], $ob->response ); } public function digestMd5Provider() { return array( array( // IMAP example from RFC 2831 [4] array( 'user' => 'chris', 'pass' => 'secret', 'challenge' => base64_decode('cmVhbG09ImVsd29vZC5pbm5vc29mdC5jb20iLG5vbmNlPSJPQTZNRzl0RVFHbTJoaCIscW9wPSJhdXRoIixhbGdvcml0aG09bWQ1LXNlc3MsY2hhcnNldD11dGYtOA=='), 'hostname' => 'elwood.innosoft.com', 'service' => 'imap', 'cnonce' => 'OA6MHXh6VqTrRk', 'expected' => 'd388dad90d4bbd760a152321f2143af7' ) ) ); } /** * @dataProvider scramProvider */ public function testScram($c) { $ob = new Horde_Imap_Client_Stub_Auth_Scram( $c['user'], $c['pass'], $c['hash'] ); $ob->setNonce($c['nonce']); $this->assertEquals( $c['c1'], $ob->getClientFirstMessage() ); $this->assertTrue($ob->parseServerFirstMessage($c['s1'])); $this->assertEquals( $c['c2'], $ob->getClientFinalMessage() ); $this->assertTrue($ob->parseServerFinalMessage($c['s2'])); } public function scramProvider() { return array( array( // Example from RFC 5802 [5] array( 'user' => 'user', 'pass' => 'pencil', 'hash' => 'SHA1', 'nonce' => 'fyko+d2lbbFgONRv9qkxdawL', 'c1' => 'n,,n=user,r=fyko+d2lbbFgONRv9qkxdawL', 's1' => 'r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096', 'c2' => 'c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts=', 's2' => 'v=rmF9pqV8S7suAoZWja4dJRkFsKQ=' ) ) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/bootstrap.php0000664000175000017500000000014313150761654022163 0ustar janjan false, // Configuration for the remote IMAP server test. 'client_config' => array( 'username' => '', 'password' => '', 'hostspec' => '', 'port' => '', 'secure' => true, // true, false, 'ssl', or 'tls' 'debug' => null, // e.g. 'php://output', // Test for XOAUTH2 //'xoauth2_token' => '' ), ), ); $conf['pop3client'] = array( // Add array entry for every POP3 client to test. array( 'enabled' => false, // Configuration for the remote POP3 server test. 'client_config' => array( 'username' => '', 'password' => '', 'hostspec' => '', 'port' => '', 'secure' => true, // true, false, 'ssl', or 'tls' 'debug' => null // e.g. 'php://output' ), ), ); // Configuration for the Mongo cache driver test. // Format: mongodb://[username:password@]host $conf['mongo'] = null; Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/DateTimeTest.php0000664000175000017500000000433113150761654022505 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_DateTimeTest extends PHPUnit_Framework_TestCase { public function provider() { return array( // Bug #5715 array('12 Sep 2007 15:49:12 UT', 1189612152), // Bug #9847 array('Fri, 06 Oct 2006 12:15:13 +0100 (GMT+01:00)', 1160133313), // Bug #13114; This should resolve to 4/13 8:04:48pm UTC of the // current year. array('Apr 13 20:4:48', gmmktime(20, 4, 48, 4, 13)), // Bad date input array('This is a bad date', 0), // Bug #14381 array('Thu, 1 Aug 2013 20:22:47 0000', 1375388567) ); } /** * @dataProvider provider */ public function testDateTimeParsing($date, $expected) { $ob = new Horde_Imap_Client_DateTime($date); $this->assertEquals( $expected, intval(strval($ob)) ); } public function testClone() { $ob = new Horde_Imap_Client_DateTime('12 Sep 2007 15:49:12 UTC'); $ob2 = clone $ob; $ob2->modify('+1 minute'); $this->assertEquals( 1189612152, intval(strval($ob)) ); $this->assertEquals( 1189612152 + 60, intval(strval($ob2)) ); } public function testSerialize() { $ob = new Horde_Imap_Client_DateTime('12 Sep 2007 15:49:12 UTC'); $ob2 = unserialize(serialize($ob)); $this->assertEquals( 1189612152, intval(strval($ob2)) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/IdsTest.php0000664000175000017500000001747113150761654021541 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_IdsTest extends PHPUnit_Framework_TestCase { public function testBasicAddingOfIds() { $ids = new Horde_Imap_Client_Ids(array(1, 3, 5)); $this->assertEquals( 3, count($ids) ); $this->assertEquals( '1,3,5', strval($ids) ); $this->assertFalse($ids->isEmpty()); } /** * @dataProvider ignoreInvalidAddsProvider */ public function testIgnoreInvalidAdds($in) { $ids = new Horde_Imap_Client_Ids($in); $this->assertEquals( 0, count($ids) ); $ids = new Horde_Imap_Client_Ids(); $ids->add($in); $this->assertEquals( 0, count($ids) ); } public function ignoreInvalidAddsProvider() { return array( array(null), array(new stdClass) ); } public function testEmptyIdsArray() { $ids = new Horde_Imap_Client_Ids(array()); $this->assertEquals( 0, count($ids) ); $this->assertEquals( '', strval($ids) ); $this->assertTrue($ids->isEmpty()); } /** * @dataProvider sequenceParsingProvider */ public function testSequenceParsing($in, $expected) { $ids = new Horde_Imap_Client_Ids($in); $this->assertEquals( count($expected), count($ids) ); $this->assertEquals( $expected, iterator_to_array($ids) ); } public function sequenceParsingProvider() { return array( array('12:10', array(10, 11, 12)), array('12,11,10', array(12, 11, 10)), array('10:12,10,11,12,10:12', array(10, 11, 12)), array('10', array(10)) ); } /** * @dataProvider rangeGenerationProvider */ public function testRangeGeneration($in, $expected) { $ids = new Horde_Imap_Client_Ids($in); $this->assertEquals( $expected, $ids->range_string ); } public function rangeGenerationProvider() { return array( array('100,300,200', '100:300'), array(Horde_Imap_Client_Ids::ALL, ''), array('50', '50') ); } public function testSorting() { $ids = new Horde_Imap_Client_Ids('14,12,10'); $this->assertEquals( '14,12,10', $ids->tostring ); $this->assertEquals( '10,12,14', $ids->tostring_sort ); } /** * @dataProvider specialIdValueStringRepresentationsProvider */ public function testSpecialIdValueStringRepresentations($in, $expected) { $ids = new Horde_Imap_Client_Ids($in); $this->assertEquals( $expected, $ids->tostring ); } public function specialIdValueStringRepresentationsProvider() { return array( array(Horde_Imap_Client_Ids::ALL, '1:*'), array(Horde_Imap_Client_Ids::SEARCH_RES, '$'), array(Horde_Imap_Client_Ids::LARGEST, '*') ); } public function testDuplicatesAllowed() { $ids = new Horde_Imap_Client_Ids('1:10,1:10'); $this->assertEquals( 10, count($ids) ); $ids = new Horde_Imap_Client_Ids(); $ids->duplicates = true; $ids->add('1:10,1:10'); $this->assertEquals( 20, count($ids) ); } public function testSplit() { // ~5000 non-sequential IDs $ids = new Horde_Imap_Client_Ids(range(1, 10000, 2)); $split = $ids->split(2000); $this->assertGreaterThan(1, count($split)); foreach (array_slice($split, 0, -1) as $val) { $this->assertGreaterThan( 2000, strlen($val) ); $this->assertNotEquals( ',', substr($val, -1) ); } $last = array_pop($split); $this->assertLessThan( 2001, strlen($last) ); $this->assertNotEquals( ',', substr($last, -1) ); } public function testSplitOnAll() { $ids = new Horde_Imap_Client_Ids(Horde_Imap_Client_Ids::ALL); $this->assertEquals( array( '1:*' ), $ids->split(2000) ); } public function testRemove() { $ids = new Horde_Imap_Client_Ids('1:100'); $this->assertEquals( 100, count($ids) ); // Remove from array $ids->remove(range(1, 10)); $this->assertEquals( 90, count($ids) ); // Removing same IDs shouldn't change anything. $ids->remove(range(1, 10)); $this->assertEquals( 90, count($ids) ); // Remove via sequence string $ids->remove('11:20'); $this->assertEquals( 80, count($ids) ); // Remove via object $ids->remove(new Horde_Imap_Client_Ids('21:30')); $this->assertEquals( 70, count($ids) ); } /** * @dataProvider minAndMaxProvider */ public function testMinAndMax($in, $min, $max) { $ids = new Horde_Imap_Client_Ids($in); $this->assertEquals( $min, $ids->min ); $this->assertEquals( $max, $ids->max ); } public function minAndMaxProvider() { return array( array(array(1), 1, 1), array(array(1, 2), 1, 2), array(array(1, 5, 3), 1, 5) ); } public function testReverse() { $ids = new Horde_Imap_Client_Ids(array(1, 3, 5)); $ids->reverse(); $this->assertEquals( array(5, 3, 1), $ids->ids ); } /** * @dataProvider sequenceStringGenerationProvider */ public function testSequenceStringGeneration($in, $expected) { $ids = new Horde_Imap_Client_Ids($in); $this->assertEquals( $expected, strval($ids) ); } public function sequenceStringGenerationProvider() { return array( array(array(1, 2, 3), '1:3'), array(array(3, 2, 1), '3,2,1'), array(array(1, 2, 3, 5), '1:3,5') ); } public function testClone() { $ids = new Horde_Imap_Client_Ids(array(1, 3)); $ids2 = clone $ids; $ids2->add(5); $this->assertEquals( array(1, 3), iterator_to_array($ids) ); $this->assertEquals( array(1, 3, 5), iterator_to_array($ids2) ); } public function testSerialize() { $ids = new Horde_Imap_Client_Ids(array(1, 3, 5)); $ids2 = unserialize(serialize($ids)); $this->assertEquals( array(1, 3, 5), iterator_to_array($ids2) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/MailboxTest.php0000664000175000017500000000653713150761654022416 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_MailboxTest extends PHPUnit_Framework_TestCase { public function testMailboxClone() { $ob = new Horde_Imap_Client_Mailbox('Envoyé'); $ob2 = clone $ob; $this->assertEquals( 'Envoyé', $ob2->utf8 ); } public function testMailboxSerialize() { $mailbox = unserialize( serialize(new Horde_Imap_Client_Mailbox('Envoyé')) ); $this->assertEquals( 'Envoyé', $mailbox->utf8 ); $this->assertEquals( 'Envoy&AOk-', $mailbox->utf7imap ); } public function testMailboxGet() { $a = Horde_Imap_Client_Mailbox::get('B'); $this->assertEquals( 'B', $a->utf7imap ); $mailbox = new Horde_Imap_Client_Mailbox('A'); $b = Horde_Imap_Client_Mailbox::get($mailbox); $this->assertEquals( $mailbox, $b ); } public function testBug10093() { $orig = 'Foo&Bar-2011'; $mailbox = new Horde_Imap_Client_Mailbox($orig); $this->assertEquals( 'Foo&Bar-2011', $mailbox->utf8 ); $this->assertEquals( 'Foo&-Bar-2011', $mailbox->utf7imap ); } /** * @dataProvider listEscapeProvider */ public function testListEscape($orig, $expected) { $mailbox = new Horde_Imap_Client_Mailbox($orig); $this->assertEquals( $expected, $mailbox->list_escape ); } public function listEscapeProvider() { return array( array('***Foo***', '%Foo%'), array('IN.***Foo**.Bar.Test**', 'IN.%Foo%.Bar.Test%') ); } public function testInboxCaseInsensitive() { $mailbox = new Horde_Imap_Client_Mailbox('inbox'); $this->assertEquals( 'INBOX', $mailbox ); } public function testBug13825() { $mbox = 'INBOX.! Astrid"'; $mbox_escape = '"INBOX.! Astrid\""'; $ob = new Horde_Imap_Client_Mailbox($mbox); $this->assertEquals( $ob, Horde_Imap_Client_Mailbox::get($mbox) ); $this->assertEquals( $ob, Horde_Imap_Client_Mailbox::get($ob) ); $format = new Horde_Imap_Client_Data_Format_Mailbox($ob); $this->assertEquals( $mbox_escape, $format->escape() ); $format2 = new Horde_Imap_Client_Data_Format_Mailbox_Utf8($ob); $this->assertEquals( $mbox_escape, $format2->escape() ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/MapTest.php0000664000175000017500000001461413150761654021533 0ustar janjan Sequence Number mapping object. * * @author Michael Slusarz * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_MapTest extends PHPUnit_Framework_TestCase { private $lookup; private $map; public function setUp() { $this->lookup = array( 2 => 5, 4 => 10, 6 => 15, 8 => 20, 10 => 25, 12 => 30 ); $this->map = new Horde_Imap_Client_Ids_Map($this->lookup); } public function testUpdate() { $map = new Horde_Imap_Client_Ids_Map(); $map->update(array( 1 => 1 )); $this->assertEquals( array( 1 => 1 ), $map->map ); $map->update(array( 2 => 2 )); $this->assertEquals( array( 1 => 1, 2 => 2 ), $map->map ); $map->update(array( 1 => 3 )); $this->assertEquals( array( 2 => 2, 1 => 3 ), $map->map ); $map->update(array( 2 => 4, 1 => 5 )); $this->assertEquals( array( 2 => 4, 1 => 5 ), $map->map ); } public function testCount() { $this->assertEquals( 6, count($this->map) ); } /** * @depends testCount */ public function testClone() { $map2 = clone $this->map; $map2->update(array( 1 => 1 )); $this->assertEquals( 6, count($this->map) ); $this->assertEquals( 7, count($map2) ); } /** * @dataProvider lookupProvider * @depends testClone */ public function testLookup($range, $expected = null) { $map = clone $this->map; $this->assertEquals( $expected ?: $map->map, $map->lookup($range) ); } public function lookupProvider() { return array( array( new Horde_Imap_Client_Ids('5:15'), array( 2 => 5, 4 => 10, 6 => 15 ) ), array( new Horde_Imap_Client_Ids('2:6', true), array( 2 => 5, 4 => 10, 6 => 15 ) ), array( new Horde_Imap_Client_Ids(Horde_Imap_Client_Ids::ALL) ) ); } /** * @dataProvider removeProvider * @depends testClone */ public function testRemove($range, $expected) { $map = clone $this->map; $map->remove($range); $this->assertEquals( $expected, $map->map ); } public function removeProvider() { return array( array( new Horde_Imap_Client_Ids('10'), array( 2 => 5, 5 => 15, 7 => 20, 9 => 25, 11 => 30 ) ), array( new Horde_Imap_Client_Ids('4', true), array( 2 => 5, 5 => 15, 7 => 20, 9 => 25, 11 => 30 ) ), array( new Horde_Imap_Client_Ids('10:15,25'), array( 2 => 5, 6 => 20, 9 => 30 ) ), // Efficient sequence number remove. array( new Horde_Imap_Client_Ids(array('10', '6', '4'), true), array( 2 => 5, 6 => 20, 9 => 30 ) ), // Inefficient sequence number remove. array( new Horde_Imap_Client_Ids(array('4', '5', '8'), true), array( 2 => 5, 6 => 20, 9 => 30 ) ), // Shortcut removing all. array( new Horde_Imap_Client_Ids('5:30'), array() ), array( new Horde_Imap_Client_Ids(array('5', '10', '15', '20', '25', '30')), array() ), array( new Horde_Imap_Client_Ids(array('2', '4', '6', '8', '10', '12'), true), array() ), array( new Horde_Imap_Client_Ids(array('12', '10', '8', '6', '4', '2'), true), array() ), ); } public function testRemoveWithDuplicateSequenceNumbers() { $map = new Horde_Imap_Client_Ids_Map(array( 1 => 1, 2 => 2, 3 => 3 )); // Inefficient sequence number remove with duplicate sequence numbers. $ids = new Horde_Imap_Client_Ids(array(), true); $ids->duplicates = true; $ids->add(array('2', '2')); $map->remove($ids); $this->assertEquals( array( 1 => 1 ), $map->map ); } public function testIterator() { $this->assertEquals( $this->map->map, iterator_to_array($this->map) ); } public function testSerialize() { $map = unserialize(serialize($this->map)); $this->assertEquals( $this->map->map, $map->map ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/phpunit.xml0000664000175000017500000000005613150761654021651 0ustar janjan Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/SearchTest.php0000664000175000017500000004614613150761654022230 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_SearchTest extends PHPUnit_Framework_TestCase { /** * @dataProvider flagQueryProvider */ public function testFlagQuery($flags, $fuzzy, $expected) { $ob = new Horde_Imap_Client_Search_Query(); foreach ($flags as $val) { $ob->flag($val[0], $val[1], array('fuzzy' => $fuzzy)); } $this->assertTrue($ob->flagSearch()); $this->assertEquals( $expected, $fuzzy ? $this->_fuzzy($ob) : strval($ob) ); } public function flagQueryProvider() { return array( array( array( /* System flag - set. */ array('\\answered', true), /* System flag - not set. */ array('\\draft', false), /* System flag - set. */ array('foo', true), /* System flag - not set. */ array('bar', false) ), false, 'ANSWERED UNDRAFT KEYWORD FOO UNKEYWORD BAR' ), array( array( array('foo', true) ), true, 'FUZZY KEYWORD FOO' ) ); } /** * @dataProvider newMsgsQueryProvider */ public function testNewMsgsQuery($newmsgs, $fuzzy, $expected) { $ob = new Horde_Imap_Client_Search_Query(); $ob->newMsgs($newmsgs, array('fuzzy' => $fuzzy)); $this->assertEquals( $expected, $fuzzy ? $this->_fuzzy($ob) : strval($ob) ); } public function newMsgsQueryProvider() { return array( array(true, false, 'NEW'), array(false, false, 'OLD'), array(true, true, 'FUZZY NEW'), array(false, true, 'FUZZY OLD') ); } /** * @dataProvider headerTextQueryProvider */ public function testHeaderTextQuery($not, $fuzzy, $expected) { $ob = new Horde_Imap_Client_Search_Query(); $ob->headerText('Foo', 'Bar', $not, array('fuzzy' => $fuzzy)); $this->assertEquals( $expected, $fuzzy ? $this->_fuzzy($ob) : strval($ob) ); } public function headerTextQueryProvider() { return array( array(false, false, 'HEADER FOO Bar'), array(true, false, 'NOT HEADER FOO Bar'), array(false, true, 'FUZZY HEADER FOO Bar'), array(true, true, 'FUZZY NOT HEADER FOO Bar') ); } public function testHeaderTextUtf8Query() { $ob = new Horde_Imap_Client_Search_Query(); $ob->headerText('Foo', 'EëE'); try { $ob->build(); $this->fail(); } catch (Horde_Imap_Client_Data_Format_Exception $e) { // Expected } $ob->charset('UTF-8', false); $this->assertNotEmpty($ob->build()); } /** * @dataProvider textQueryProvider */ public function testTextQuery($body, $not, $fuzzy, $expected) { $ob = new Horde_Imap_Client_Search_Query(); $ob->text('foo', $body, $not, array('fuzzy' => $fuzzy)); $this->assertEquals( $expected, $fuzzy ? $this->_fuzzy($ob) : strval($ob) ); } public function textQueryProvider() { return array( array(true, false, false, 'BODY foo'), array(false, false, false, 'TEXT foo'), array(true, true, false, 'NOT BODY foo'), array(false, true, false, 'NOT TEXT foo'), array(true, false, true, 'FUZZY BODY foo'), array(false, false, true, 'FUZZY TEXT foo'), array(true, true, true, 'FUZZY NOT BODY foo'), array(false, true, true, 'FUZZY NOT TEXT foo') ); } /** * @dataProvider sizeQueryProvider */ public function testSizeQuery($larger, $not, $fuzzy, $expected) { $ob = new Horde_Imap_Client_Search_Query(); $ob->size(100, $larger, $not, array('fuzzy' => $fuzzy)); $this->assertEquals( $expected, $fuzzy ? $this->_fuzzy($ob) : strval($ob) ); } public function sizeQueryProvider() { return array( array(true, false, false, 'LARGER 100'), array(false, false, false, 'SMALLER 100'), array(true, true, false, 'NOT LARGER 100'), array(false, true, false, 'NOT SMALLER 100'), array(true, false, true, 'FUZZY LARGER 100'), array(false, false, true, 'FUZZY SMALLER 100'), array(true, true, true, 'FUZZY NOT LARGER 100'), array(false, true, true, 'FUZZY NOT SMALLER 100') ); } /** * @dataProvider idsQueryProvider */ public function testIdsQuery($ids, $not, $fuzzy, $expected) { $ob = new Horde_Imap_Client_Search_Query(); $ob->ids(new Horde_Imap_Client_Ids($ids), $not, array( 'fuzzy' => $fuzzy )); $this->assertEquals( $expected, $fuzzy ? $this->_fuzzy($ob) : strval($ob) ); } public function idsQueryProvider() { return array( array('1,2,3', false, false, 'UID 1:3'), array('1:3', true, false, 'NOT UID 1:3'), array('1,2,3', false, true, 'FUZZY UID 1:3'), array('1:3', true, true, 'FUZZY NOT UID 1:3') ); } /** * @dataProvider dateSearchQueryProvider */ public function testDateSearchQuery( $range, $header, $not, $fuzzy, $expected ) { $ob = new Horde_Imap_Client_Search_Query(); $ob->dateSearch( new DateTime('January 1, 2010'), $range, $header, $not, array('fuzzy' => $fuzzy) ); $this->assertEquals( $expected, $fuzzy ? $this->_fuzzy($ob) : strval($ob) ); } public function dateSearchQueryProvider() { return array( array( Horde_Imap_Client_Search_Query::DATE_BEFORE, true, false, false, 'SENTBEFORE 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_BEFORE, false, false, false, 'BEFORE 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_BEFORE, true, true, false, 'NOT SENTBEFORE 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_BEFORE, false, true, false, 'NOT BEFORE 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_BEFORE, true, true, true, 'FUZZY NOT SENTBEFORE 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_BEFORE, false, true, true, 'FUZZY NOT BEFORE 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_ON, true, false, false, 'SENTON 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_ON, false, false, false, 'ON 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_ON, true, true, false, 'NOT SENTON 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_ON, false, true, false, 'NOT ON 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_ON, true, true, true, 'FUZZY NOT SENTON 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_ON, false, true, true, 'FUZZY NOT ON 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_SINCE, true, false, false, 'SENTSINCE 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_SINCE, false, false, false, 'SINCE 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_SINCE, true, true, false, 'NOT SENTSINCE 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_SINCE, false, true, false, 'NOT SINCE 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_SINCE, true, true, true, 'FUZZY NOT SENTSINCE 1-Jan-2010', ), array( Horde_Imap_Client_Search_Query::DATE_SINCE, false, true, true, 'FUZZY NOT SINCE 1-Jan-2010', ) ); } /** * @dataProvider intervalSearchQueryProvider */ public function testIntervalSearchQuery($range, $not, $fuzzy, $expected) { $ob = new Horde_Imap_Client_Search_Query(); $ob->intervalSearch(30, $range, $not, array('fuzzy' => $fuzzy)); $this->assertEquals( $expected, $fuzzy ? $this->_fuzzy($ob, array('WITHIN')) : strval($ob) ); } public function intervalSearchQueryProvider() { return array( array( Horde_Imap_Client_Search_Query::INTERVAL_OLDER, false, false, 'OLDER 30' ), array( Horde_Imap_Client_Search_Query::INTERVAL_OLDER, true, false, 'NOT OLDER 30' ), array( Horde_Imap_Client_Search_Query::INTERVAL_OLDER, false, true, 'FUZZY OLDER 30' ), array( Horde_Imap_Client_Search_Query::INTERVAL_OLDER, true, true, 'FUZZY NOT OLDER 30' ), array( Horde_Imap_Client_Search_Query::INTERVAL_YOUNGER, false, false, 'YOUNGER 30' ), array( Horde_Imap_Client_Search_Query::INTERVAL_YOUNGER, true, false, 'NOT YOUNGER 30' ), array( Horde_Imap_Client_Search_Query::INTERVAL_YOUNGER, false, true, 'FUZZY YOUNGER 30' ), array( Horde_Imap_Client_Search_Query::INTERVAL_YOUNGER, true, true, 'FUZZY NOT YOUNGER 30' ) ); } public function testOrQueries() { $ob2 = new Horde_Imap_Client_Search_Query(); $ob2->flag('\\deleted', false); $ob2->headerText('from', 'ABC'); $ob3 = new Horde_Imap_Client_Search_Query(); $ob3->flag('\\deleted', true); $ob3->headerText('from', 'DEF'); $ob = new Horde_Imap_Client_Search_Query(); $ob->orSearch(array($ob2, $ob3)); $this->assertEquals( 'OR (DELETED FROM DEF) (UNDELETED FROM ABC)', strval($ob) ); $ob4 = new Horde_Imap_Client_Search_Query(); $ob4->flag('\\flagged', true); $ob4->headerText('from', 'GHI'); $ob5 = new Horde_Imap_Client_Search_Query(); $ob5->orSearch(array($ob2, $ob3, $ob4)); $this->assertEquals( 'OR (FLAGGED FROM GHI) (OR (DELETED FROM DEF) (UNDELETED FROM ABC))', strval($ob5) ); } public function testOrQueriesWithABaseQuery() { $or_ob = new Horde_Imap_Client_Search_Query(); $ob = new Horde_Imap_Client_Search_Query(); $ob->flag('\\deleted', false); $ob->headerText('from', 'ABC'); $or_ob->orSearch($ob); $ob = new Horde_Imap_Client_Search_Query(); $ob->flag('\\deleted', true); $ob->headerText('from', 'DEF'); $or_ob->orSearch($ob); $base_ob = new Horde_Imap_Client_Search_Query(); $base_ob->flag('\\seen', false); $base_ob->andSearch($or_ob); $this->assertEquals( 'UNSEEN OR (DELETED FROM DEF) (UNDELETED FROM ABC)', strval($base_ob) ); } /** * @dataProvider modseqSearchQueryProvider */ public function testModseq($name, $type, $not, $fuzzy, $expected) { $ob = new Horde_Imap_Client_Search_Query(); $ob->modseq(123, $name, $type, $not, array('fuzzy' => $fuzzy)); $this->assertEquals( $expected, $fuzzy ? $this->_fuzzy($ob, array('CONDSTORE')) : strval($ob) ); } public function modseqSearchQueryProvider() { return array( array(null, null, false, false, 'MODSEQ 123'), array(null, null, true, false, 'NOT MODSEQ 123'), array(null, null, false, true, 'FUZZY MODSEQ 123'), array(null, null, true, true, 'FUZZY NOT MODSEQ 123'), array('foo', null, false, false, 'MODSEQ "foo" all 123'), array('foo', null, true, false, 'NOT MODSEQ "foo" all 123'), array('foo', null, false, true, 'FUZZY MODSEQ "foo" all 123'), array('foo', null, true, true, 'FUZZY NOT MODSEQ "foo" all 123'), array('foo', 'all', false, false, 'MODSEQ "foo" all 123'), array('foo', 'all', true, false, 'NOT MODSEQ "foo" all 123'), array('foo', 'all', false, true, 'FUZZY MODSEQ "foo" all 123'), array('foo', 'all', true, true, 'FUZZY NOT MODSEQ "foo" all 123'), array('foo', 'shared', false, false, 'MODSEQ "foo" shared 123'), array('foo', 'shared', true, false, 'NOT MODSEQ "foo" shared 123'), array('foo', 'shared', false, true, 'FUZZY MODSEQ "foo" shared 123'), array('foo', 'shared', true, true, 'FUZZY NOT MODSEQ "foo" shared 123'), array('foo', 'priv', false, false, 'MODSEQ "foo" priv 123'), array('foo', 'priv', true, false, 'NOT MODSEQ "foo" priv 123'), array('foo', 'priv', false, true, 'FUZZY MODSEQ "foo" priv 123'), array('foo', 'priv', true, true, 'FUZZY NOT MODSEQ "foo" priv 123') ); } /** * @dataProvider previousSearchQueryProvider */ public function testPreviousSearchQuery($not, $fuzzy, $expected) { $ob = new Horde_Imap_Client_Search_Query(); $ob->previousSearch($not, array('fuzzy' => $fuzzy)); $this->assertEquals( $expected, $fuzzy ? $this->_fuzzy($ob, array('ESEARCH', 'SEARCHRES')) : strval($ob) ); } public function previousSearchQueryProvider() { return array( array(false, false, 'NOT $'), array(true, false, '$'), array(false, true, 'FUZZY NOT $'), array(true, true, 'FUZZY $') ); } public function testClone() { $ob = new Horde_Imap_Client_Search_Query(); $ob->text('foo'); $ob2 = clone $ob; $ob2->text('bar'); $this->assertEquals( 'BODY foo', strval($ob) ); $this->assertEquals( 'BODY foo BODY bar', strval($ob2) ); } public function testSerialize() { $ob = new Horde_Imap_Client_Search_Query(); $ob->ids(new Horde_Imap_Client_Ids('1:3'), true); $ob->text('foo'); $ob->charset('US-ASCII', false); $this->assertEquals( 'NOT UID 1:3 BODY foo', strval(unserialize(serialize($ob))) ); } public function testBug13971() { $ob = new Horde_Imap_Client_Search_Query(); $ob->ids(new Horde_Imap_Client_Ids(array())); $ob->text('foo'); $this->assertEquals( '', strval($ob) ); $ob2 = new Horde_Imap_Client_Search_Query(); $ob2->text('foo2'); $ob2->andSearch($ob); $this->assertEquals( '', strval($ob2) ); $ob3 = new Horde_Imap_Client_Search_Query(); $ob3->text('foo3'); $ob3->orSearch($ob); $this->assertEquals( 'BODY foo3', strval($ob3) ); $ob2->orSearch($ob3); $this->assertEquals( 'BODY foo3', strval($ob2) ); /* A NOT qualifier on an empty ID list should ignore the list. */ $ob->ids(new Horde_Imap_Client_Ids(array()), true); $this->assertEquals( 'BODY foo', strval($ob) ); } /** * @dataProvider inconsistentCharsetsInAndOrSearchesProvider * @expectedException InvalidArgumentException */ public function testInconsistentCharsetsInAndOrSearches($query) { $query->build(null); } public function inconsistentCharsetsInAndOrSearchesProvider() { $ob = new Horde_Imap_Client_Search_Query(); $ob->text('foo'); $ob->charset('UTF-8', false); $ob2 = new Horde_Imap_Client_Search_Query(); $ob2->text('foo2'); $ob2->charset('ISO-8859-1', false); $ob2->andSearch($ob); $ob3 = new Horde_Imap_Client_Search_Query(); $ob3->text('foo2'); $ob3->charset('ISO-8859-1', false); $ob3->orSearch($ob); return array(array($ob2), array($ob3)); } private function _fuzzy($ob, array $exts = array()) { $capability = new Horde_Imap_Client_Data_Capability_Imap(); $capability->add('SEARCH', 'FUZZY'); foreach ($exts as $val) { $capability->add($val); } $res = $ob->build($capability); return $res['query']->escape(); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/SocketTest.php0000664000175000017500000002560013150761654022243 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_SocketTest extends PHPUnit_Framework_TestCase { public $test_ob; public function setUp() { require_once __DIR__ . '/Stub/Socket.php'; $this->test_ob = new Horde_Imap_Client_Stub_Socket(array( 'password' => 'foo', 'username' => 'bar' )); } public function tearDown() { unset($this->test_ob); } public function testSimpleThreadParse() { $data = '* THREAD (1)'; $thread = $this->test_ob->getThreadSort($data); $this->assertTrue($thread instanceof Horde_Imap_Client_Data_Thread); $list = $thread->messageList(); $this->assertTrue($list instanceof Horde_Imap_Client_Ids); $this->assertEquals( array(1), $list->ids ); $this->assertEquals( 1, count($thread) ); $this->assertEquals( array(1), unserialize(serialize($list))->ids ); $thread_list = $thread->getThread(1); $this->assertEquals( 1, count($thread_list) ); $this->assertTrue(is_object($thread_list[1])); $this->assertTrue(is_null($thread_list[1]->base)); $this->assertTrue($thread_list[1]->last); $this->assertEquals( 0, $thread_list[1]->level ); $thread_list = $thread->getThread(2); $this->assertTrue(empty($thread_list)); } public function testComplexThreadParse() { $data = '* THREAD ((1)(2)(3)(4 (5)(6))(7 8)(9)(10 (11 12)(13 (14 (15)))))(16 17)'; $thread = $this->test_ob->getThreadSort($data); $list = $thread->messageList(); $this->assertTrue($list instanceof Horde_Imap_Client_Ids); $this->assertEquals( range(1, 17), $list->ids ); $this->assertEquals( range(1, 17), unserialize(serialize($list))->ids ); $thread_list = $thread->getThread(16); $this->assertTrue(!empty($thread_list)); $thread_list = $thread->getThread(18); $this->assertTrue(empty($thread_list)); $thread_list = $thread->getThread(10); $this->assertEquals( 15, count($thread_list) ); foreach (array(1, 2, 3, 4, 5, 7, 9, 11) as $k) { $this->assertFalse($thread_list[$k]->last); } foreach (array(6, 8, 10, 12, 13, 14, 15) as $k) { $this->assertTrue($thread_list[$k]->last); } foreach (range(1, 15) as $k) { $this->assertEquals( 1, $thread_list[$k]->base ); } foreach (array(1, 2, 3, 4, 7, 9, 10) as $k) { $this->assertEquals( 0, $thread_list[$k]->level ); } foreach (array(5, 6, 8, 11, 13) as $k) { $this->assertEquals( 1, $thread_list[$k]->level ); } foreach (array(12, 14) as $k) { $this->assertEquals( 2, $thread_list[$k]->level ); } foreach (array(15) as $k) { $this->assertEquals( 3, $thread_list[$k]->level ); } } public function testBug11450() { $data = '* NAMESPACE (("INBOX." ".")) (("user." ".")) (("" "."))'; $this->assertEquals( 3, count($this->test_ob->parseNamespace($data)) ); } public function testNamespaceParsing() { $data = '* NAMESPACE (("" "/")) NIL NIL'; $this->assertEquals( 1, count($this->test_ob->parseNamespace($data)) ); } public function testLargeEnvelopeData() { $test = '* 1 FETCH (ENVELOPE ("Fri, 28 Sep 2012 17:09:32 -0700" {10000}' . str_repeat('F', 10000) . ' ((NIL NIL "foo" "example.com")) ((NIL NIL "foo" "example.com")) ((NIL NIL "foo" "example.com")) (' . str_repeat('(NIL NIL "bar" "example.com")', 50000) . ') NIL NIL NIL "<123@example.com>"))'; $this->test_ob->setParam('envelope_addrs', 1000); $this->test_ob->setParam('envelope_string', 2000); $env = $this->test_ob->parseFetch($test)->fetch->first()->getEnvelope(); $this->assertEquals( 1000, count($env->to) ); $this->assertEquals( 2000, strlen($env->subject) ); } public function testUntaggedResponseAlert() { // Bug #11453 $test = '* NO [ALERT] Foo Bar'; $this->test_ob->doResponseCode($test); $alerts = $this->test_ob->alerts(); $this->assertEquals( 1, count($alerts) ); $this->assertEquals( 'Foo Bar', reset($alerts) ); } public function testBug11899() { $test = '* 1 FETCH (ENVELOPE (NIL "Standard Subject" (("Test User" NIL "tester" "domain.tld")) (("Test User" NIL "tester" "domain.tld")) (("Test User" NIL "tester" "domain.tld")) (' . str_repeat('("=?windows-1252?Q?=95Test_User?=" NIL "tester" "domain.tld")', 135) . ') NIL NIL NIL ""))'; $env = $this->test_ob->parseFetch($test)->fetch->first()->getEnvelope(); $this->assertEquals( 135, count($env->to) ); } public function testBug11907() { $test = '* 1 FETCH (BODYSTRUCTURE (((("text" "plain" ("charset" "iso-8859-1") NIL NIL "quoted-printable" 2456 153 NIL NIL NIL)("text" "html" ("charset" "iso-8859-1") NIL NIL "quoted-printable" 21256 392 NIL NIL NIL) "alternative" ("boundary" "----=_NextPart_002_0022_01CDDD09.86926E40") NIL NIL)("image" "jpeg" ("name" "image001.jpg") "" NIL "base64" 7658 NIL NIL NIL) "related" ("boundary" "----=_NextPart_001_0021_01CDDD09.86926E40") NIL NIL)("application" "vnd.openxmlformats-officedocument.spreadsheetml.sheet" ("name" "C&C S.A.S.xlsx") NIL NIL "base64" 26184 NIL ("attachment" ("filename" "C&C S.A.S.xlsx")) NIL) "mixed" ("boundary" "----=_NextPart_000_0020_01CDDD09.86926E40") NIL "es-co"))'; $parse = $this->test_ob->parseFetch($test)->fetch->first()->getStructure(); $this->assertEquals( 'multipart/mixed', $parse->getType() ); } public function testBug11946() { $test = array( '* 1 FETCH (FLAGS (\Seen \Flagged))', '* 1 FETCH (UID 9)' ); $res = new Horde_Imap_Client_Fetch_Results(); $this->test_ob->parseFetch($test[0], array('results' => $res)); $this->test_ob->parseFetch($test[1], array('results' => $res)); $this->assertEquals( array('\seen', '\flagged'), $res->first()->getFlags() ); $this->assertEquals( 9, $res->first()->getUid() ); $test[1] = '* 1 FETCH (UID 9 FLAGS (\Seen \Flagged))'; $res = new Horde_Imap_Client_Fetch_Results(); $this->test_ob->parseFetch($test[0], array('results' => $res)); $this->test_ob->parseFetch($test[1], array('results' => $res)); $this->assertEquals( array('\seen', '\flagged'), $res->first()->getFlags() ); } /* See RFC 5162 (Errata #1807) - QRESYNC/CONDSTORE has design flaw where * it is allowable to send FETCH responses with MODSEQ/FLAGS but without * UID. This makes the responses practically useless. This has been * fixed in RFC 7162. */ public function testModseqFlagsWithoutUid() { $test = '* 1 FETCH (UID 2 MODSEQ (5) FLAGS (\Seen \Flagged))'; $this->assertEquals( 0, count($this->test_ob->parseFetch($test)->data['modseqs_nouid']) ); $test = '* 1 FETCH (MODSEQ (5) FLAGS (\Seen \Flagged))'; $this->assertEquals( 1, count($this->test_ob->parseFetch($test)->data['modseqs_nouid']) ); } public function testBug11994() { $test = '* ACL INBOX foo lrswipcda cyrus lripcda'; $parsed = $this->test_ob->parseAcl($test); $this->assertEquals( 2, count($parsed) ); $this->assertTrue($parsed['foo']['s']); $this->assertFalse($parsed['cyrus']['s']); $test = '* MYRIGHTS INBOX lrwipkxtecda'; $parsed = $this->test_ob->parseMyACLRights($test); $this->assertTrue($parsed['l']); $this->assertFalse($parsed['s']); $test = '* LISTRIGHTS INBOX foo lkxca r s w i p t e d 0 1 3 4 5 6'; $parsed = $this->test_ob->parseListRights($test); $this->assertNotNull($parsed['l']); $this->assertNull($parsed['2']); } public function testBug12190() { $test = '* 1 FETCH (BODYSTRUCTURE ((("TEXT" "PLAIN" ("CHARSET" "us-ascii") NIL NIL "QUOTED-PRINTABLE" 1112 52 NIL NIL NIL)("TEXT" "HTML" ("CHARSET" "us-ascii") NIL NIL "QUOTED-PRINTABLE" 8149 194 NIL NIL NIL) "ALTERNATIVE" ("BOUNDARY" "_000_8F9CBFD3A05011448603998C351D400CD1D065P3PWEX2MB009ex2se_") NIL NIL)("MESSAGE" "RFC822" NIL NIL NIL "7BIT" 1290 NIL ("ATTACHMENT" ("CREATION-DATE" "Fri, 09 Nov 2012 18:16:04 GMT" "MODIFICATION-DATE" "Fri, 09 Nov 2012 18:16:04 GMT")) NIL) "MIXED" ("BOUNDARY" "_004_8F9CBFD3A05011448603998C351D400CD1D065P3PWEX2MB009ex2se_") NIL NIL))'; $parse = $this->test_ob->parseFetch($test)->fetch->first()->getStructure(); $this->assertEquals( 'multipart/mixed', $parse->getType() ); $this->assertEquals( 'multipart/alternative', $parse->getPart('1')->getType() ); $this->assertEquals( 'message/rfc822', $parse->getPart('2')->getType() ); } public function testParseEnvelopeBlankSubject() { $test = '* 1 FETCH (ENVELOPE (NIL "" (("Test User" NIL "tester" "domain.tld")) (("Test User" NIL "tester" "domain.tld")) (("Test User" NIL "tester" "domain.tld")) ((NIL NIL "foo" "example.com")) NIL NIL NIL ""))'; $env = $this->test_ob->parseFetch($test)->fetch->first()->getEnvelope(); $this->assertNotNull($env->to); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/SortTest.php0000664000175000017500000001132413150761654021740 0ustar janjan * @category Horde * @copyright 2012-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_SortTest extends PHPUnit_Framework_TestCase { /** * @dataProvider numericComponentSortingProvider */ public function testNumericComponentSorting($mboxes, $expected) { $list_ob = new Horde_Imap_Client_Mailbox_List($mboxes); $list_ob->sort(array( 'delimiter' => '.' )); $this->assertEquals( $expected, array_values(iterator_to_array($list_ob)) ); } public function numericComponentSortingProvider() { return array( array( array( '100', '1', '10000', '10', '1000' ), array( '1', '10', '100', '1000', '10000' ) ), array( array( 'Foo.002', 'Foo.00002', 'Foo.0002' ), array( 'Foo.002', 'Foo.0002', 'Foo.00002' ) ) ); } /** * @dataProvider inboxSortProvider */ public function testInboxSort($mboxes, $expected) { $list_ob = new Horde_Imap_Client_Mailbox_List($mboxes); $sorted = $list_ob->sort(array( 'inbox' => true, )); $this->assertEquals( $expected, array_values($sorted) ); $list_ob = new Horde_Imap_Client_Mailbox_List($mboxes); $sorted = $list_ob->sort(array( 'inbox' => false, )); $this->assertEquals( $mboxes, $sorted ); } public function inboxSortProvider() { return array( array( array( 'A', 'Z', 'INBOX', 'C' ), array( 'INBOX', 'A', 'C', 'Z' ) ) ); } /** * @dataProvider indexAssociationProvider */ public function testIndexAssociation($mboxes, $expected) { $list_ob = new Horde_Imap_Client_Mailbox_List($mboxes); $sorted = $list_ob->sort(); $this->assertEquals( $expected, array_values($sorted) ); $this->assertEquals( $expected, array_keys($sorted) ); } public function indexAssociationProvider() { return array( array( array( 'Z' => 'Z', 'A' => 'A' ), array( 'A', 'Z' ) ) ); } /** * @dataProvider noUpdateOfListObjectProvider */ public function testNoUpdateOfListObject($mboxes, $expected) { $list_ob = new Horde_Imap_Client_Mailbox_List($mboxes); $sorted = $list_ob->sort(array( 'noupdate' => true )); $this->assertEquals( $expected, array_values($sorted) ); $this->assertEquals( $mboxes, array_values(iterator_to_array($list_ob)) ); $list_ob = new Horde_Imap_Client_Mailbox_List($mboxes); $sorted = $list_ob->sort(); $this->assertEquals( $expected, array_values($sorted) ); $this->assertEquals( $expected, array_values(iterator_to_array($list_ob)) ); } public function noUpdateOfListObjectProvider() { return array( array( array( 'Z', 'A' ), array( 'A', 'Z' ) ) ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/TokenizeTest.php0000664000175000017500000003256313150761654022611 0ustar janjan * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_TokenizeTest extends PHPUnit_Framework_TestCase { public function testTokenizeSimple() { $test1 = 'FOO BAR'; $token1 = new Horde_Imap_Client_Tokenize($test1); $tmp = iterator_to_array($token1); $this->assertEquals( 'FOO', $tmp[0] ); $this->assertEquals( 'BAR', $tmp[1] ); } public function testTokenizeQuotes() { $test1 = 'FOO "BAR"'; $token1 = new Horde_Imap_Client_Tokenize($test1); $tmp = iterator_to_array($token1); $this->assertEquals( 'FOO', $tmp[0] ); $this->assertEquals( 'BAR', $tmp[1] ); $test2 = '"\"BAR\""'; $token2 = new Horde_Imap_Client_Tokenize($test2); $tmp = iterator_to_array($token2); $this->assertEquals( '"BAR"', $tmp[0] ); } public function testTokenizeLiteral() { $test1 = 'FOO {3}BAR BAZ'; $token1 = new Horde_Imap_Client_Tokenize($test1); $tmp = iterator_to_array($token1); $this->assertEquals( 'FOO', $tmp[0] ); $this->assertEquals( 'BAR', $tmp[1] ); $this->assertEquals( 'BAZ', $tmp[2] ); } public function testTokenizeNil() { $test1 = 'FOO NIL'; $token1 = new Horde_Imap_Client_Tokenize($test1); $token1->rewind(); $this->assertEquals( 'FOO', $token1->next() ); $this->assertNull($token1->next()); $this->assertFalse($token1->next()); } public function testTokenizeList() { $test1 = 'FOO ("BAR") BAZ'; $token1 = new Horde_Imap_Client_Tokenize($test1); $token1->rewind(); $this->assertEquals( 'FOO', $token1->next() ); $this->assertTrue($token1->next()); $this->assertEquals( 'BAR', $token1->next() ); $this->assertFalse($token1->next()); $this->assertEquals( 'BAZ', $token1->next() ); $this->assertFalse($token1->next()); $test2 = '(BAR NIL NIL)'; $token2 = new Horde_Imap_Client_Tokenize($test2); $token2->rewind(); $this->assertTrue($token2->next()); $this->assertEquals( 'BAR', $token2->next() ); $this->assertNull($token2->next()); $this->assertNull($token2->next()); $this->assertFalse($token2->next()); $test3 = '(\Foo)'; $token3 = new Horde_Imap_Client_Tokenize($test3); $token3->rewind(); $this->assertTrue($token3->next()); $this->assertEquals( '\\Foo', $token3->next() ); $this->assertFalse($token3->next()); } public function testTokenizeBadWhitespace() { $test1 = ' FOO BAR '; $token1 = new Horde_Imap_Client_Tokenize($test1); $tmp = iterator_to_array($token1); $this->assertEquals( 'FOO', $tmp[0] ); $this->assertEquals( 'BAR', $tmp[1] ); } public function testTokenizeComplexFetchExample() { $test = <<rewind(); $this->assertEquals( '*', $token->next() ); $this->assertEquals( '8', $token->next() ); $this->assertEquals( 'FETCH', $token->next() ); $this->assertTrue($token->next()); $this->assertEquals( 'UID', $token->next() ); $this->assertEquals( '39210', $token->next() ); $this->assertEquals( 'BODYSTRUCTURE', $token->next() ); $this->assertTrue($token->next()); $this->assertTrue($token->next()); $this->assertEquals( 'text', $token->next() ); $this->assertEquals( 'plain', $token->next() ); $this->assertTrue($token->next()); $this->assertEquals( 'charset', $token->next() ); $this->assertEquals( 'ISO-8859-1', $token->next() ); $this->assertFalse($token->next()); $this->assertNull($token->next()); $this->assertNull($token->next()); $this->assertEquals( 'quoted-printable', $token->next() ); $this->assertEquals( 1559, $token->next() ); $this->assertEquals( 40, $token->next() ); $this->assertNull($token->next()); $this->assertNull($token->next()); $this->assertNull($token->next()); $this->assertNull($token->next()); $this->assertFalse($token->next()); $this->assertTrue($token->next()); $this->assertEquals( 'text', $token->next() ); $this->assertEquals( 'html', $token->next() ); $this->assertTrue($token->next()); $this->assertEquals( 'charset', $token->next() ); $this->assertEquals( 'ISO-8859-1', $token->next() ); $this->assertFalse($token->next()); $this->assertNull($token->next()); $this->assertNull($token->next()); $this->assertEquals( 'quoted-printable', $token->next() ); $this->assertEquals( 25318, $token->next() ); $this->assertEquals( 427, $token->next() ); $this->assertNull($token->next()); $this->assertNull($token->next()); $this->assertNull($token->next()); $this->assertNull($token->next()); $this->assertFalse($token->next()); $this->assertEquals( 'alternative', $token->next() ); $this->assertTrue($token->next()); $this->assertEquals( 'boundary', $token->next() ); $this->assertEquals( '_Part_1_xMiAxODoyNjozNyAtMDQwMA==', $token->next() ); $this->assertFalse($token->next()); $this->assertNull($token->next()); $this->assertNull($token->next()); $this->assertNull($token->next()); $this->assertFalse($token->next()); $this->assertFalse($token->next()); $this->assertFalse($token->next()); } public function testBug11450() { $test = '* NAMESPACE (("INBOX." ".")) (("user." ".")) (("" "."))'; $token = new Horde_Imap_Client_Tokenize($test); $token->rewind(); $this->assertEquals( '*', $token->next() ); $this->assertEquals( 'NAMESPACE', $token->next() ); $this->assertTrue($token->next()); $this->assertTrue($token->next()); $this->assertEquals( 'INBOX.', $token->next() ); $this->assertEquals( '.', $token->next() ); $this->assertFalse($token->next()); $this->assertFalse($token->next()); $this->assertTrue($token->next()); $this->assertTrue($token->next()); $this->assertEquals( 'user.', $token->next() ); $this->assertEquals( '.', $token->next() ); $this->assertFalse($token->next()); $this->assertFalse($token->next()); $this->assertTrue($token->next()); $this->assertTrue($token->next()); $this->assertEquals( '', $token->next() ); $this->assertEquals( '.', $token->next() ); $this->assertFalse($token->next()); $this->assertFalse($token->next()); } public function testFlushIterator() { $test = 'FOO (BAR (BAZ BAZ2) BAR2) FOO2'; $token = new Horde_Imap_Client_Tokenize($test); $token->rewind(); $token->next(); // FOO $token->next(); // Opening paren $this->assertEquals( array('BAR', 'BAR2'), $token->flushIterator() ); $this->assertEquals( 'FOO2', $token->next() ); $token->rewind(); $token->next(); // FOO $token->next(); // Opening paren $this->assertEquals( array(), $token->flushIterator(false) ); $this->assertEquals( 'FOO2', $token->next() ); $token->rewind(); $token->next(); // FOO $token->next(); // Opening paren $this->assertEquals( array(), $token->flushIterator(false, false) ); $this->assertTrue($token->eos); } public function testLiteralLength() { $test = 'FOO'; $token = new Horde_Imap_Client_Tokenize($test); $this->assertNull($token->getLiteralLength()); $test = 'FOO {100}'; $token = new Horde_Imap_Client_Tokenize($test); $len = $token->getLiteralLength(); $this->assertNotNull($len); $this->assertFalse($len['binary']); $this->assertEquals( 100, $len['length'] ); $test = 'FOO ~{100}'; $token = new Horde_Imap_Client_Tokenize($test); $len = $token->getLiteralLength(); $this->assertNotNull($len); $this->assertTrue($len['binary']); $this->assertEquals( 100, $len['length'] ); // Test non-binary-marker tilde. $test = '* LIST () "" ~foo'; $token = new Horde_Imap_Client_Tokenize($test); $token->rewind(); $this->assertEquals( '*', $token->next() ); $this->assertEquals( 'LIST', $token->next() ); $this->assertTrue($token->next()); $this->assertFalse($token->next()); $this->assertEquals( '', $token->next() ); $this->assertEquals( '~foo', $token->next() ); } public function testLiteralStream() { $token = new Horde_Imap_Client_Tokenize(); $token->add('FOO {10}'); $token->addLiteralStream('1234567890'); $token->add(' BAR'); $token->rewind(); $this->assertEquals( 'FOO', $token->next() ); /* Internal stream is converted to string. */ $this->assertEquals( '1234567890', $token->next() ); $this->assertEquals( 'BAR', $token->next() ); $this->assertTrue($token->eos); /* Check to see stream is returned if nextStream() is called and * a literal is encountered. */ $token->rewind(); $this->assertEquals( 'FOO', $token->nextStream() ); $stream = $token->nextStream(); $this->assertInstanceOf('Horde_Stream_Temp', $stream); $this->assertEquals( '1234567890', strval($stream) ); $this->assertEquals( 'BAR', $token->nextStream() ); $token = new Horde_Imap_Client_Tokenize(); $token->add('{200}' . str_repeat('Z', 200)); $token->rewind(); $this->assertEquals( str_repeat('Z', 200), $token->next() ); $token->rewind(); $stream = $token->nextStream(); $this->assertInstanceOf('Horde_Stream_Temp', $stream); $this->assertEquals(str_repeat('Z', 200), strval($stream)); } /** * @expectedException LogicException */ public function testClone() { $test = 'FOO BAR'; $token = new Horde_Imap_Client_Tokenize($test); clone $token; } /** * @expectedException LogicException */ public function testSerialize() { $test = 'FOO BAR'; $token = new Horde_Imap_Client_Tokenize($test); serialize($token); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Utf7ConvertTest.php0000664000175000017500000000446113150761654023203 0ustar janjan UTF-8 conversions. * * @author Michael Slusarz * @category Horde * @copyright 2011-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Utf7ConvertTest extends PHPUnit_Framework_TestCase { public static function setUpBeforeClass() { require_once __DIR__ . '/Stub/Utf7imap.php'; } /** * @dataProvider conversionProvider * @requires extension mbstring */ public function testConversionWithMbstring($orig, $expected = null) { Horde_Imap_Client_Stub_Utf7imap::setMbstring(true); $this->_testConversion($orig, $expected); } /** * @dataProvider conversionProvider */ public function testConversionWithoutMbstring($orig, $expected = null) { Horde_Imap_Client_Stub_Utf7imap::setMbstring(false); $this->_testConversion($orig, $expected); } protected function _testConversion($orig, $expected) { $utf7_imap = Horde_Imap_Client_Stub_Utf7imap::Utf8ToUtf7Imap( $orig, !is_null($expected) ); $this->assertEquals( $expected ?: $orig, $utf7_imap ); if ($expected) { $utf8 = Horde_Imap_Client_Stub_Utf7imap::Utf7ImapToUtf8($utf7_imap); $this->assertEquals( $orig, $utf8 ); } } public function conversionProvider() { return array( array('Envoyé', 'Envoy&AOk-'), array('Töst-', 'T&APY-st-'), array('&', '&-'), array('&-'), array('Envoy&AOk-'), array('T&APY-st-'), // Bug #10133 array('Entw&APw-rfe'), // Bug #10093 array('Foo&Bar-2011', 'Foo&-Bar-2011') ); } } Horde_Imap_Client-2.29.15/test/Horde/Imap/Client/Xoauth2Test.php0000664000175000017500000000233113150761654022341 0ustar janjan * @category Horde * @copyright 2013-2016 Horde LLC * @ignore * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client * @subpackage UnitTests */ class Horde_Imap_Client_Xoauth2Test extends PHPUnit_Framework_TestCase { public function testTokenGeneration() { // Example from https://developers.google.com/gmail/xoauth2_protocol $xoauth2 = new Horde_Imap_Client_Password_Xoauth2( 'someuser@example.com', 'vF9dft4qmTc2Nvb3RlckBhdHRhdmlzdGEuY29tCg==' ); $this->assertEquals( 'dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlYXJlciB2RjlkZnQ0cW1UYzJOdmIzUmxja0JoZEhSaGRtbHpkR0V1WTI5dENnPT0BAQ==', $xoauth2->getPassword() ); } }