diff --git a/config/hooks.php.dist b/config/hooks.php.dist index 2e366d132..2ffcf7d9e 100644 --- a/config/hooks.php.dist +++ b/config/hooks.php.dist @@ -11,747 +11,746 @@ * * $Id$ */ -if (!class_exists('IMP_Hooks')) { - class IMP_Hooks + +class IMP_Hooks +{ + /** + * AUTHENTICATION HOOK: pre-authentication actions. + * + * See horde/config/hooks.php.dist for more information. + * + * IMP uses the following credentials: + * - password: (string) The password for mail server authentication. + * - server: (string) [optional] Use this server key (see + * config/backends.php). + * - transparent: (boolean) If $credentials['authMethod'] is + * 'transparent', and you want IMP to use the + * userId/credentials generated in the preauthenticate + * hook, this must be true. If false, IMP will instead + * try to authenticate using hordeauth. + * + * The following credentials will exist in $credentials, but changing + * these values has no effect on authentication: + * - imp_server_key: (string; 'authenticate' only) The backend server + * key selected on the login page. + */ + // public function preauthenticate($userId, $credentials) + // { + // switch ($credentials['authMethod']) { + // case 'admin': + // return true; + // + // case 'authenticate': + // // Example: Load-balance - pick IMAP server based on first + // // letter in username. Server entries 'server_[a-z]' must + // // be defined in config/backends.local.php. + // + // // $credentials['server'] = 'server_' . substr($userId, 0, 1); + // // return [ + // // 'credentials' => $credentials, + // // 'userId' => $userId + // // ]; + // + // return true; + // + // case 'transparent': + // // Example: Always login as 'demo' user, with password 'demo'. + // + // // return [ + // // 'credentials' => array( + // // 'password' => 'demo', + // // 'transparent' => true + // // ), + // // 'userId' => 'demo' + // // ]; + // + // return true; + // } + // } + + + /** + * AUTHENTICATION HOOK: post-authentication actions. + * + * See horde/config/hooks.php.dist for more information. + * See preauthenticate() above for the list of credentials available. + */ + // public function postauthenticate($userId, $credentials) + // { + // return true; + // } + + /** + * AUTHENTICATION HOOK: imap pre-authentication. This hook allows + * modification of credentials immediately before authentication to the + * IMAP server. This gives the chance to modify the username and + * have it affect ONLY the IMAP authentication process. I.e., the modified + * username is NOT visible to Horde or any application. This is useful e.g. + * when the IMAP server requires prepending the user's IP address to the + * username for audit purposes. + * + * @param array $credentials An array containing authentication credentials + * - userId: (string) The authentication username. + * + * @return array The possibly modified authentication credentials. + */ + // public function imap_preauthenticate($credentials) + // { + // $credentials['userId'] = $_SERVER['REMOTE_ADDR'] . '@' . $credentials['userId']; + // return $credentials; + // } + + + /** + * PREFERENCE INIT: Set preference values on login. + * + * See horde/config/hooks.php.dist for more information. + * + * MAKE SURE YOU ACTIVATE THE INIT HOOK IN config/prefs.local.php! + */ + // public function prefs_init($pref, $value, $username, $scope_ob) + // { + // switch ($pref) { + // case 'add_source': + // // Dynamically set the add_source preference. + // + // // Example: Useful hook when using a Turba source with shares + // // enabled (i.e. the example localsql configuration). + // return is_null($username) + // ? $value + // : $GLOBALS['registry']->call('contacts/getDefaultShare'); + // + // + // case 'search_fields': + // case 'search_sources': + // // Dynamically set the search_fields/search_sources preferences. + // + // // Example: Use the list of sources defined in the contacts + // // application (e.g. Turba). + // if (!is_null($username) && + // $GLOBALS['registry']->hasMethod('contacts/sources')) { + // $sources = $GLOBALS['registry']->call('contacts/sources'); + // + // if ($pref == 'search_fields') { + // $out = []; + // foreach (array_keys($sources) as $source) { + // $out[$source] = []; + // foreach ($GLOBALS['registry']->call('contacts/fields', [$source]) as $key => $val){ + // if ($val['search']) { + // $out[$source][] = $key; + // } + // } + // } + // } else { + // $out = array_keys($sources); + // } + // + // return json_encode($out); + // } + // + // return $value; + // } + // } + + + /** + * Perform actions on compose attachments. + * + * @param IMP_Compose_Attachment $atc The attachment object. + * + * @throws IMP_Compose_Exception + */ + public function compose_attachment(IMP_Compose_Attachment $atc) { - /** - * AUTHENTICATION HOOK: pre-authentication actions. - * - * See horde/config/hooks.php.dist for more information. - * - * IMP uses the following credentials: - * - password: (string) The password for mail server authentication. - * - server: (string) [optional] Use this server key (see - * config/backends.php). - * - transparent: (boolean) If $credentials['authMethod'] is - * 'transparent', and you want IMP to use the - * userId/credentials generated in the preauthenticate - * hook, this must be true. If false, IMP will instead - * try to authenticate using hordeauth. - * - * The following credentials will exist in $credentials, but changing - * these values has no effect on authentication: - * - imp_server_key: (string; 'authenticate' only) The backend server - * key selected on the login page. - */ - // public function preauthenticate($userId, $credentials) - // { - // switch ($credentials['authMethod']) { - // case 'admin': - // return true; - // - // case 'authenticate': - // // Example: Load-balance - pick IMAP server based on first - // // letter in username. Server entries 'server_[a-z]' must - // // be defined in config/backends.local.php. - // - // // $credentials['server'] = 'server_' . substr($userId, 0, 1); - // // return array( - // // 'credentials' => $credentials, - // // 'userId' => $userId - // // ); - // - // return true; - // - // case 'transparent': - // // Example: Always login as 'demo' user, with password 'demo'. - // - // // return array( - // // 'credentials' => array( - // // 'password' => 'demo', - // // 'transparent' => true - // // ), - // // 'userId' => 'demo' - // // ); - // - // return true; - // } - // } - - - /** - * AUTHENTICATION HOOK: post-authentication actions. - * - * See horde/config/hooks.php.dist for more information. - * See preauthenticate() above for the list of credentials available. - */ - // public function postauthenticate($userId, $credentials) - // { - // return true; - // } - - /** - * AUTHENTICATION HOOK: imap pre-authentication. This hook allows - * modification of credentials immediately before authentication to the - * IMAP server. This gives the chance to modify the username and - * have it affect ONLY the IMAP authentication process. I.e., the modified - * username is NOT visible to Horde or any application. This is useful e.g. - * when the IMAP server requires prepending the user's IP address to the - * username for audit purposes. - * - * @param array $credentials An array containing authentication credentials - * - userId: (string) The authentication username. - * - * @return array The possibly modified authentication credentials. - */ - // public function imap_preauthenticate($credentials) - // { - // $credentials['userId'] = $_SERVER['REMOTE_ADDR'] . '@' . $credentials['userId']; - // return $credentials; - // } - - - /** - * PREFERENCE INIT: Set preference values on login. - * - * See horde/config/hooks.php.dist for more information. - * - * MAKE SURE YOU ACTIVATE THE INIT HOOK IN config/prefs.local.php! - */ - // public function prefs_init($pref, $value, $username, $scope_ob) - // { - // switch ($pref) { - // case 'add_source': - // // Dynamically set the add_source preference. - // - // // Example: Useful hook when using a Turba source with shares - // // enabled (i.e. the example localsql configuration). - // return is_null($username) - // ? $value - // : $GLOBALS['registry']->call('contacts/getDefaultShare'); - // - // - // case 'search_fields': - // case 'search_sources': - // // Dynamically set the search_fields/search_sources preferences. - // - // // Example: Use the list of sources defined in the contacts - // // application (e.g. Turba). - // if (!is_null($username) && - // $GLOBALS['registry']->hasMethod('contacts/sources')) { - // $sources = $GLOBALS['registry']->call('contacts/sources'); - // - // if ($pref == 'search_fields') { - // $out = array(); - // foreach (array_keys($sources) as $source) { - // $out[$source] = array(); - // foreach ($GLOBALS['registry']->call('contacts/fields', array($source)) as $key => $val){ - // if ($val['search']) { - // $out[$source][] = $key; - // } - // } - // } - // } else { - // $out = array_keys($sources); - // } - // - // return json_encode($out); - // } - // - // return $value; - // } - // } - - - /** - * Perform actions on compose attachments. - * - * @param IMP_Compose_Attachment $atc The attachment object. - * - * @throws IMP_Compose_Exception - */ - public function compose_attachment(IMP_Compose_Attachment $atc) - { - // // Example: Do a virus scan on the attachment, and reject attachment - // // if a virus is found. - // // This example uses the open source ClamAV binary (tested with - // // v0.96). See: http://www.clamav.net/ - // $clamscan = '/path/to/clamscan'; - // exec($clamscan . ' --quiet ' . escapeshellarg($atc->tmpfile), $output, $return_var); - // - // switch ($return_var) { - // case 1: - // // Virus found. - // throw IMP_Compose_Exception::createAndLog('INFO', 'Virus found in uploaded attachment. Attachment will not be added to the compose message.'); - // - // case 2: - // // Error occurred. - // Horde::log('Unknown error when scanning message for virus.', 'INFO'); - // break; - // } - } - - - /** - * Check compose e-mail recipient before sending. - * - * @param Horde_Mail_Rfc822_Address $addr The address object. - * - * @return mixed If an error, an array with the following possible keys: - * - msg: (string) The error text. - * - level: (string; OPTIONAL) Either 'bad' (DEFAULT) or 'warn'. - */ - // public function compose_addr(Horde_Mail_Rfc822_Address $addr) - // { - // // Example #1: Only allow sending to local addresses (the - // // "example.com" domain. - // if ($addr->host != 'example.com') { - // return array( - // 'msg' => 'Can only send to addresses at example.com.', - // 'level' => 'bad' - // ); - // } - // - // - // // Example #2: Require valid domain (i.e. disallow bare usernames). - // if (!strlen($addr->host)) { - // return array( - // 'msg' => sprintf('"%s" is missing the domain name.', $addr->mailbox), - // 'level' => 'bad' - // ); - // } - // } - - - /** - * Checks the raw text of the outoging compose message for words that - * might indicate an attachment is present, and issues a warning if no - * attachments are indeed present. - * - * If this hook is not defined, this check is not performed. - * - * This hook is run at most once per message. - * - * @return array A list of words to search for in the body text. - */ - // public function attach_body_check($body) - // { - // /* List of words to search for. */ - // return array( - // 'attachment', 'attached' - // ); - // } - - - /** - * Perform an action before a message has been sent. - * - * If an exception is thrown, sending is cancelled and the exception text - * will be shown to the user in an error message. - * - * @param Horde_Mime_Part $message The message content object. - * @param Horde_Mime_Headers $headers The message headers object. - * @param IMP_Compose $compose The compose object. - * - * @throws IMP_Compose_Exception - */ - // public function pre_sent( - // Horde_Mime_Part $message, - // Horde_Mime_Headers $headers, - // IMP_Compose $compose - // ) - // { - // // Example #1: Add custom headers to outgoing message. - // $custom_hdrs = array(); - // - // /* Add information on organization to which the sender belongs. - // * Not standardized for use in e-mail, but generally recognized. - // * See RFC 2076 [3.7]; RFC 1036 [2.2.8] */ - // $custom_hdrs['Organization'] = 'Example Corp.'; - // - // // Add the IP of the remote browser - // $custom_hdrs['X-Originating-IP'] = $_SERVER['REMOTE_ADDR']; - // - // // Add the Browser information of the remote browser - // $custom_hdrs['X-Remote-Browser'] = $_SERVER['HTTP_USER_AGENT']; - // - // foreach ($custom_hdrs as $key => $val) { - // $headers->addHeader($key, $val); - // } - // } - - - /** - * Perform an action after a message has been sent successfully. - * - * @param Horde_Mime_Part $message The message content object. - * @param Horde_Mime_Headers $headers The message headers object. - */ - // public function post_sent($message, $headers) - // { - // // Do action here -- no return value from this hook. - // } - - - /** - * Dynamically create the contents of the message trailer text. - * - * @param boolean $html If true, the trailer text to be - * used in the HTML part. If null is - * returned, the plaintext trailer - * text will be used. - * @param IMP_Prefs_Identity $identity The identity object of the sender. - * @param Horde_Mail_Rfc822_List $to The list of addresses the message - * is being sent to. (Note: this list - * is calculated before the pre_sent - * hook is executed, so any - * recipients added in that hook will - * not be seen here.) - * - * @return string The trailer text to be used. - */ - // public function trailer( - // $html, - // IMP_Prefs_Identity $identity, - // Horde_Mail_Rfc822_List $to - // ) - // { - // // Example #1: Static trailer text. - // if ($html) { - // return "
This message was sent using IMP.
"; - // } else { - // return "--------------------------------\n" . - // "This message was sent using IMP."; - // } - // - // - // // Example #2: Set the trailer from the system taglines file, - // // located at "/usr/share/tagline" (generated by the "TaRT" utility; - // // See: http://sourceforge.net/projects/linuxtart/). - // return file_get_contents('/usr/share/tagline'); - // - // - // // Example #3: Set the trailer using the LDAP directory (entry - // // 'ispmanDomainSignature'). - // $vdomain = Horde_String::lower(preg_replace('|^.*?\.|i', '', getenv('HTTP_HOST'))); - // $ldapServer = 'localhost'; - // $ldapPort = '389'; - // $searchBase = 'ispmanDomain=' . $vdomain . ",o=ispman"; - // - // $ds = @ldap_connect($ldapServer, $ldapPort); - // $searchResult = @ldap_search($ds, $searchBase, 'uid=' . $vdomain); - // $information = @ldap_get_entries($ds, $searchResult); - // $trailer = $information[0]['ispmandomainsignature'][0]; - // @ldap_close($ds); - // - // return $trailer; - // } - - - /** - * Add additional message flags in the message listing screen for a - * mailbox. - * - * @param array $data The overview information for a message as returned - * from the IMP_Mailbox_List::getMailboxArray() call - * (see lib/Mailbox/List.php for documentation on the - * structure of the array). - * - * @return array An array of additional flags to add. These flags must be - * defined in the 'msgflags' preference. On error, return - * an empty array. - */ - // public function msglist_flags($data) - // { - // // Example #1: Add a icon if the message was sent from a user within - // // the same domain. - // $flags = array(); - // - // if (($from_ob = $data['envelope']->from[0]) && - // ($from_ob->host == 'example.com')) { - // /* The '$indomain' flag in this example must have already been - // * created in the 'msgflags' preference. */ - // $flags = array('$indomain'); - // } - // - // return $flags; - // } - - - /** - * If message content filtering is enabled (see 'filtering' preference), - * this defines the message filtering configuration. - * - * @return array An array with the following keys: - * - replacement: (string) The string filtered words will be replaced - * with. - * - words: (array) The list of words to filter. - */ - public function msg_filter() - { - return [ - 'replacement' => '****', - 'words' => [ - 'poop', - ], - ]; - } - - - /** - * Alter access permissions for a mailbox. - * - * The better way to accomplish this is to directly manipulate the ACLs - * on the IMAP server (admins can do this via the ACL management page in - * IMP's preferences). However, if ACL is not available on the remote - * server, or mailbox permissions need to be dynamically altered, this - * hook can be used instead. - * - * NOTE: This hook is only called once during a user's session - the - * results of this hook are cached within the session. - * - * @param IMP_Mailbox $mailbox The mailbox. - * @param Horde_Imap_Client_Data_Acl $acl The mailbox ACL. - */ - // public function mbox_acl(IMP_Mailbox $mailbox, - // Horde_Imap_Client_Data_Acl $acl) - // { - // // Example #1: Make the 'Foo' mailbox a "fixed" folder (can't be - // // renamed or deleted). - // if ($mailbox == 'Foo') { - // unset($acl[Horde_Imap_Client::ACL_DELETEMBOX]); - // } - // - // - // // Example #2: Make the 'Bar' mailbox read-only. - // if ($mailbox == 'Bar') { - // unset( - // $acl[Horde_Imap_Client::ACL_DELETEMBOX], - // $acl[Horde_Imap_Client::ACL_DELETEMSGS], - // $acl[Horde_Imap_Client::ACL_EXPUNGE], - // $acl[Horde_Imap_Client::ACL_INSERT], - // $acl[Horde_Imap_Client::ACL_SEEN], - // $acl[Horde_Imap_Client::ACL_WRITE] - // ); - // } - // - // - // // Example #3: Make the 'Example' mailbox not appear in folder - // // lists. - // if ($mailbox == 'Example') { - // unset($acl[Horde_Imap_Client::ACL_LOOKUP]); - // } - // } - - - /** - * Allow a custom mailbox icon to be specified for "standard" mailboxes - * ("Standard" means all mailboxes except the INBOX, sent-mail, and - * trash mailboxes.) - * - * @return array A list of mailboxes, with the name as keys and the - * values an array with 'icon' and 'alt' entries. - * If a mailbox name doesn't appear in the list, the - * default mailbox icon is displayed. - */ - // public function mbox_icons() - // { - // // Example #1: Default Kolab redirection scheme - // $types = $GLOBALS['injector']->getInstance('Horde_Kolab_Storage') - // ->getList()->getQuery()->listTypes(); - // - // $icons = array(); - // foreach ($types as $f => $type) { - // $t = preg_replace('/\.default$/', '', $type); - // switch ($t) { - // case 'event': - // $icons[$f] = array( - // 'alt' => _("Calendar"), - // 'icon' => Horde_Themes::img('kronolith.png', 'kronolith') - // ); - // break; - // - // case 'task': - // $icons[$f] = array( - // 'alt' => _("Tasks"), - // 'icon' => Horde_Themes::img('nag.png', 'nag') - // ); - // break; - // - // case 'note': - // $icons[$f] = array( - // 'alt' => _("Notes"), - // 'icon' => Horde_Themes::img('mnemo.png', 'mnemo') - // ); - // break; - // - // case 'contact': - // $icons[$f] = array( - // 'alt' => _("Contacts"), - // 'icon' => Horde_Themes::img('turba.png', 'turba') - // ); - // break; - // - // case 'h-prefs': - // $icons[$f] = array( - // 'alt' => _("Preferences"), - // 'icon' => Horde_Themes::img('prefs.png', 'horde') - // ); - // break; - // } - // } - // - // return $icons; - // } - - - /** - * Dynamically alter a mailbox display label. - * - * @param string $mbox The mailbox name. - * @param string $label The current label. - * - * @return string The display label for $mbox. - */ - // public function mbox_label($mbox, $label) - // { - // // Example #1: Show 'foo' as 'bar' - // return ($mbox == 'foo') - // ? 'bar' - // : $label; - // } - - - /** - * Override sort preferences for a mailbox. - * - * @param IMP_Prefs_Sort_Sortpref $ob A sortpref object. - */ - // public function mbox_sort($ob) - // { - // // The sortpref object has two properties that can be set - 'sortby' - // // and 'sortdir'. These properties will already contain the default - // // values if there is no specific sort preferences defined for a - // // mailbox (the mailbox can be found in the 'mbox' property). - // - // // Example #1: Assume that the 'sortdir' preference defaults to an - // // ascending sort. However, the sort direction is desired to be - // // descending for date searches (i.e. newest messages first). - // if ($ob->sortdir_default && - // in_array($ob->sortby, array(Horde_Imap_Client::SORT_SEQUENCE, IMP::IMAP_SORT_DATE))) { - // $ob->sortdir = 1; - // } - // } - - - /** - * Determine whether to prompt a user to send a Message Disposition - * Notification (MDN; a/k/a read-receipt) if their preferences require - * a prompt. Useful if MDNs should automatically be sent for a certain - * subset of messages, e.g. e-mail addresses within the domain. - * - * @param Horde_Mime_Headers $headers A headers object. - * - * @return boolean Should the user be prompted to send a MDN? - */ - // public function mdn_check($headers) - // { - // // Example #1: Don't require MDN prompt if the message is sent by - // // someone within the same domain (NOTE: this does no checking on - // // spoofed e-mail addresses; further verification should probably - // // be done before automatically sending out a MDN). - // if ($h = $headers['from']) { - // $from = $h->getAddressList(true)->first(); - // return (strcasecmp($from->host, 'example.com') !== 0); - // } - // - // return false; - // } - - - /** - * Default browser-based preference values for the dynamic view. - * Any value not returned here will use the default value (listed below). - * - * @return array The list of pref keys / default values. - */ - public function dynamic_prefs() - { - return [ - /* Preview pane. Valid values: - * - 'horiz': Horizontal mode - * - 'vert': Vertical mode - * - [empty value]: No preview */ - // 'preview' => 'horiz', - - /* Quicksearch field (search box on mailbox page). Valid values: - * - 'all': Search entire message (body & headers) - * - 'body': Search message body - * - 'from': Search from header - * - 'recip': Search recipients (To/CC/BCC) headers - * - 'subject': Search subject */ - // 'qsearch_field' => 'all', - - /* Splitbar (horizontal) height. Value is number of messages to - * show. 0 means auto-determine default size. */ - // 'splitbar_horiz' => 0, - - /* Splitbar (vertical) width. Value is width (in pixels) of the - * mailbox listing. 0 means auto-determine default size. */ - // 'splitbar_vert' => 0, - - /* Toggle headers in preview. 1 to show headers, 0 to hide. */ - // 'toggle_hdrs' => 0, - ]; - } - - - /** - * Dynamically disable composing messages. - * - * @return boolean Is composing disabled? - */ - // public function disable_compose() - // { - // // Example #1: Entirely disable composition. - // return false; - // } - - - /** - * Perform an action after messages have been reported as spam/innocent. - * - * @param string $action Either 'spam' or 'innocent'. - * @param IMP_Indices $indices The list of indices that have been - * reported as spam/innocent. - */ - // public function post_spam($action, $indices) - // { - // // Example #1: Copy messages to a (not)spam mailbox. This is the - // // full mailbox name. - // $targetMbox = 'foo'; - // - // $indices->copy($targetMbox, 'copy', array('create' => true)); - // } - - - /** - * Determine quota for a user. - * - * @param array $params Parameters for the function, set in backends.php. - * - * @return array Tuple with two members: - * - first: disk space used (in bytes) - * - second: maximum disk space (in bytes) - */ - // public function quota($params = null) - // { - // // Example #1: Sample function for returning the quota. - // // Uses the PECL ssh2 extension. - // // Requires the 'command' parameter to be defined in backends.php, - // // which defines the quota reporting function to run on the SSH - // // host. - // $imap_ob = $GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create(); - // $host = $imap_ob->getParam('hostspec'); - // $user = $params['host']; - // $pass = $imap_ob->getParam('password'); - // $command = $params['command']; - // - // $session = ssh2_connect($host); - // if (!$session) { - // throw new IMP_Exception(_("Connection to server failed.")); + // // Example: Do a virus scan on the attachment, and reject attachment + // // if a virus is found. + // // This example uses the open source ClamAV binary (tested with + // // v0.96). See: http://www.clamav.net/ + // $clamscan = '/path/to/clamscan'; + // exec($clamscan . ' --quiet ' . escapeshellarg($atc->tmpfile), $output, $return_var); + // + // switch ($return_var) { + // case 1: + // // Virus found. + // throw IMP_Compose_Exception::createAndLog('INFO', 'Virus found in uploaded attachment. Attachment will not be added to the compose message.'); + // + // case 2: + // // Error occurred. + // Horde::log('Unknown error when scanning message for virus.', 'INFO'); + // break; // } - // - // if (!ssh2_auth_password($session, $user, $pass)) { - // throw new IMP_Exception(_("Authentication failed.")); - // } - // - // $stream = ssh2_exec($session, $command, false); - // stream_set_blocking($stream, true); - // - // $quota = preg_split('/\s+/', trim(stream_get_contents($stream)), 2); - // return array($quota[1] * 1024, $quota[2] * 1024); - // } - - - /** - * Retrieves public S/MIME keys of message recipients. - * - * The hook will be called first when searching for the keys, and further - * lookup techniques will only be used if the hook throws an exception or - * returns an empty result. - * - * @param string $address The email address of the recipient. - * - * @return string The base64-encoded public S/MIME key that matches the - * email address. - */ - // public function smime_key($address) - // { - // // Example #1: Retrieve S/MIME key from an LDAP backend. - // $ldapServer = 'localhost'; - // $ldapPort = 389; - // $searchBase = 'ou=users,dc=example,dc=com'; - // $binddn = 'uid=admin,dc=example,dc=com'; - // $bindpw = 'secret'; - // $attribute = 'simepublickey'; - // - // if (!@ldap_connect($ldapServer, $ldapPort)) { - // return; - // } - // if (!@ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)) { - // return; - // } - // if (!@ldap_bind($ds, $binddn, $bindpw)) { - // return; - // } - // - // $searchResult = @ldap_search($ds, $searchBase, 'mail=' . $address); - // $information = @ldap_get_entries($ds, $searchResult); - // ldap_close($ds); - // - // if ($information === false || $information['count'] == 0) { - // return; - // } - // - // return $information[0][$attribute][0]; - // } - - - /** - * Retrieves public PGP keys of message recipients. - * - * The hook will be called first when searching for the keys, and further - * lookup techniques will only be used if the hook throws an exception or - * returns an empty result. - * - * @param string $address The email address of the recipient. - * @param string $keyid The PGP key id of the recipient. - * - * @return string The base64-encoded public PGP key that matches either - * the email address or the fingerprint. - */ - // public function pgp_key($address, $keyid) - // { - // // Example #1: Retrieve PGP key from an LDAP backend. - // $ldapServer = 'localhost'; - // $ldapPort = 389; - // $searchBase = 'ou=users,dc=example,dc=com'; - // $binddn = 'uid=admin,dc=example,dc=com'; - // $bindpw = 'secret'; - // $attribute = 'pgppublickey'; - // - // if (!@ldap_connect($ldapServer, $ldapPort)) { - // return; - // } - // if (!@ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)) { - // return; - // } - // if (!@ldap_bind($ds, $binddn, $bindpw)) { - // return; - // } - // - // $searchResult = @ldap_search($ds, $searchBase, 'mail=' . $address); - // $information = @ldap_get_entries($ds, $searchResult); - // ldap_close($ds); - // - // if ($information === false || $information['count'] == 0) { - // return; - // } - // - // return $information[0][$attribute][0]; - // } + } + + + /** + * Check compose e-mail recipient before sending. + * + * @param Horde_Mail_Rfc822_Address $addr The address object. + * + * @return mixed If an error, an array with the following possible keys: + * - msg: (string) The error text. + * - level: (string; OPTIONAL) Either 'bad' (DEFAULT) or 'warn'. + */ + // public function compose_addr(Horde_Mail_Rfc822_Address $addr) + // { + // // Example #1: Only allow sending to local addresses (the + // // "example.com" domain. + // if ($addr->host != 'example.com') { + // return [ + // 'msg' => 'Can only send to addresses at example.com.', + // 'level' => 'bad' + // ]; + // } + // + // + // // Example #2: Require valid domain (i.e. disallow bare usernames). + // if (!strlen($addr->host)) { + // return [ + // 'msg' => sprintf('"%s" is missing the domain name.', $addr->mailbox), + // 'level' => 'bad' + // ]; + // } + // } + + + /** + * Checks the raw text of the outoging compose message for words that + * might indicate an attachment is present, and issues a warning if no + * attachments are indeed present. + * + * If this hook is not defined, this check is not performed. + * + * This hook is run at most once per message. + * + * @return array A list of words to search for in the body text. + */ + // public function attach_body_check($body) + // { + // /* List of words to search for. */ + // return [ + // 'attachment', 'attached' + // ]; + // } + + + /** + * Perform an action before a message has been sent. + * + * If an exception is thrown, sending is cancelled and the exception text + * will be shown to the user in an error message. + * + * @param Horde_Mime_Part $message The message content object. + * @param Horde_Mime_Headers $headers The message headers object. + * @param IMP_Compose $compose The compose object. + * + * @throws IMP_Compose_Exception + */ + // public function pre_sent( + // Horde_Mime_Part $message, + // Horde_Mime_Headers $headers, + // IMP_Compose $compose + // ) + // { + // // Example #1: Add custom headers to outgoing message. + // $custom_hdrs = []; + // + // /* Add information on organization to which the sender belongs. + // * Not standardized for use in e-mail, but generally recognized. + // * See RFC 2076 [3.7]; RFC 1036 [2.2.8] */ + // $custom_hdrs['Organization'] = 'Example Corp.'; + // + // // Add the IP of the remote browser + // $custom_hdrs['X-Originating-IP'] = $_SERVER['REMOTE_ADDR']; + // + // // Add the Browser information of the remote browser + // $custom_hdrs['X-Remote-Browser'] = $_SERVER['HTTP_USER_AGENT']; + // + // foreach ($custom_hdrs as $key => $val) { + // $headers->addHeader($key, $val); + // } + // } + + + /** + * Perform an action after a message has been sent successfully. + * + * @param Horde_Mime_Part $message The message content object. + * @param Horde_Mime_Headers $headers The message headers object. + */ + // public function post_sent($message, $headers) + // { + // // Do action here -- no return value from this hook. + // } + + + /** + * Dynamically create the contents of the message trailer text. + * + * @param boolean $html If true, the trailer text to be + * used in the HTML part. If null is + * returned, the plaintext trailer + * text will be used. + * @param IMP_Prefs_Identity $identity The identity object of the sender. + * @param Horde_Mail_Rfc822_List $to The list of addresses the message + * is being sent to. (Note: this list + * is calculated before the pre_sent + * hook is executed, so any + * recipients added in that hook will + * not be seen here.) + * + * @return string The trailer text to be used. + */ + // public function trailer( + // $html, + // IMP_Prefs_Identity $identity, + // Horde_Mail_Rfc822_List $to + // ) + // { + // // Example #1: Static trailer text. + // if ($html) { + // return "
This message was sent using IMP.
"; + // } else { + // return "--------------------------------\n" . + // "This message was sent using IMP."; + // } + // + // + // // Example #2: Set the trailer from the system taglines file, + // // located at "/usr/share/tagline" (generated by the "TaRT" utility; + // // See: http://sourceforge.net/projects/linuxtart/). + // return file_get_contents('/usr/share/tagline'); + // + // + // // Example #3: Set the trailer using the LDAP directory (entry + // // 'ispmanDomainSignature'). + // $vdomain = Horde_String::lower(preg_replace('|^.*?\.|i', '', getenv('HTTP_HOST'))); + // $ldapServer = 'localhost'; + // $ldapPort = '389'; + // $searchBase = 'ispmanDomain=' . $vdomain . ",o=ispman"; + // + // $ds = @ldap_connect($ldapServer, $ldapPort); + // $searchResult = @ldap_search($ds, $searchBase, 'uid=' . $vdomain); + // $information = @ldap_get_entries($ds, $searchResult); + // $trailer = $information[0]['ispmandomainsignature'][0]; + // @ldap_close($ds); + // + // return $trailer; + // } + + + /** + * Add additional message flags in the message listing screen for a + * mailbox. + * + * @param array $data The overview information for a message as returned + * from the IMP_Mailbox_List::getMailboxArray() call + * (see lib/Mailbox/List.php for documentation on the + * structure of the array). + * + * @return array An array of additional flags to add. These flags must be + * defined in the 'msgflags' preference. On error, return + * an empty array. + */ + // public function msglist_flags($data) + // { + // // Example #1: Add a icon if the message was sent from a user within + // // the same domain. + // $flags = []; + // + // if (($from_ob = $data['envelope']->from[0]) && + // ($from_ob->host == 'example.com')) { + // /* The '$indomain' flag in this example must have already been + // * created in the 'msgflags' preference. */ + // $flags = ['$indomain']; + // } + // + // return $flags; + // } + + + /** + * If message content filtering is enabled (see 'filtering' preference), + * this defines the message filtering configuration. + * + * @return array An array with the following keys: + * - replacement: (string) The string filtered words will be replaced + * with. + * - words: (array) The list of words to filter. + */ + public function msg_filter() + { + return [ + 'replacement' => '****', + 'words' => array( + 'poop' + ) + ]; + } + /** + * Alter access permissions for a mailbox. + * + * The better way to accomplish this is to directly manipulate the ACLs + * on the IMAP server (admins can do this via the ACL management page in + * IMP's preferences). However, if ACL is not available on the remote + * server, or mailbox permissions need to be dynamically altered, this + * hook can be used instead. + * + * NOTE: This hook is only called once during a user's session - the + * results of this hook are cached within the session. + * + * @param IMP_Mailbox $mailbox The mailbox. + * @param Horde_Imap_Client_Data_Acl $acl The mailbox ACL. + */ + // public function mbox_acl(IMP_Mailbox $mailbox, + // Horde_Imap_Client_Data_Acl $acl) + // { + // // Example #1: Make the 'Foo' mailbox a "fixed" folder (can't be + // // renamed or deleted). + // if ($mailbox == 'Foo') { + // unset($acl[Horde_Imap_Client::ACL_DELETEMBOX]); + // } + // + // + // // Example #2: Make the 'Bar' mailbox read-only. + // if ($mailbox == 'Bar') { + // unset( + // $acl[Horde_Imap_Client::ACL_DELETEMBOX], + // $acl[Horde_Imap_Client::ACL_DELETEMSGS], + // $acl[Horde_Imap_Client::ACL_EXPUNGE], + // $acl[Horde_Imap_Client::ACL_INSERT], + // $acl[Horde_Imap_Client::ACL_SEEN], + // $acl[Horde_Imap_Client::ACL_WRITE] + // ); + // } + // + // + // // Example #3: Make the 'Example' mailbox not appear in folder + // // lists. + // if ($mailbox == 'Example') { + // unset($acl[Horde_Imap_Client::ACL_LOOKUP]); + // } + // } + + + /** + * Allow a custom mailbox icon to be specified for "standard" mailboxes + * ("Standard" means all mailboxes except the INBOX, sent-mail, and + * trash mailboxes.) + * + * @return array A list of mailboxes, with the name as keys and the + * values an array with 'icon' and 'alt' entries. + * If a mailbox name doesn't appear in the list, the + * default mailbox icon is displayed. + */ + // public function mbox_icons() + // { + // // Example #1: Default Kolab redirection scheme + // $types = $GLOBALS['injector']->getInstance('Horde_Kolab_Storage') + // ->getList()->getQuery()->listTypes(); + // + // $icons = []; + // foreach ($types as $f => $type) { + // $t = preg_replace('/\.default$/', '', $type); + // switch ($t) { + // case 'event': + // $icons[$f] = [ + // 'alt' => _("Calendar"), + // 'icon' => Horde_Themes::img('kronolith.png', 'kronolith') + // ]; + // break; + // + // case 'task': + // $icons[$f] = [ + // 'alt' => _("Tasks"), + // 'icon' => Horde_Themes::img('nag.png', 'nag') + // ]; + // break; + // + // case 'note': + // $icons[$f] = [ + // 'alt' => _("Notes"), + // 'icon' => Horde_Themes::img('mnemo.png', 'mnemo') + // ]; + // break; + // + // case 'contact': + // $icons[$f] = [ + // 'alt' => _("Contacts"), + // 'icon' => Horde_Themes::img('turba.png', 'turba') + // ]; + // break; + // + // case 'h-prefs': + // $icons[$f] = [ + // 'alt' => _("Preferences"), + // 'icon' => Horde_Themes::img('prefs.png', 'horde') + // ]; + // break; + // } + // } + // + // return $icons; + // } + + + /** + * Dynamically alter a mailbox display label. + * + * @param string $mbox The mailbox name. + * @param string $label The current label. + * + * @return string The display label for $mbox. + */ + // public function mbox_label($mbox, $label) + // { + // // Example #1: Show 'foo' as 'bar' + // return ($mbox == 'foo') + // ? 'bar' + // : $label; + // } + + + /** + * Override sort preferences for a mailbox. + * + * @param IMP_Prefs_Sort_Sortpref $ob A sortpref object. + */ + // public function mbox_sort($ob) + // { + // // The sortpref object has two properties that can be set - 'sortby' + // // and 'sortdir'. These properties will already contain the default + // // values if there is no specific sort preferences defined for a + // // mailbox (the mailbox can be found in the 'mbox' property). + // + // // Example #1: Assume that the 'sortdir' preference defaults to an + // // ascending sort. However, the sort direction is desired to be + // // descending for date searches (i.e. newest messages first). + // if ($ob->sortdir_default && + // in_array($ob->sortby, array(Horde_Imap_Client::SORT_SEQUENCE, IMP::IMAP_SORT_DATE))) { + // $ob->sortdir = 1; + // } + // } + + + /** + * Determine whether to prompt a user to send a Message Disposition + * Notification (MDN; a/k/a read-receipt) if their preferences require + * a prompt. Useful if MDNs should automatically be sent for a certain + * subset of messages, e.g. e-mail addresses within the domain. + * + * @param Horde_Mime_Headers $headers A headers object. + * + * @return boolean Should the user be prompted to send a MDN? + */ + // public function mdn_check($headers) + // { + // // Example #1: Don't require MDN prompt if the message is sent by + // // someone within the same domain (NOTE: this does no checking on + // // spoofed e-mail addresses; further verification should probably + // // be done before automatically sending out a MDN). + // if ($h = $headers['from']) { + // $from = $h->getAddressList(true)->first(); + // return (strcasecmp($from->host, 'example.com') !== 0); + // } + // + // return false; + // } + + + /** + * Default browser-based preference values for the dynamic view. + * Any value not returned here will use the default value (listed below). + * + * @return array The list of pref keys / default values. + */ + public function dynamic_prefs() + { + return array( + /* Preview pane. Valid values: + * - 'horiz': Horizontal mode + * - 'vert': Vertical mode + * - [empty value]: No preview */ + // 'preview' => 'horiz', + + /* Quicksearch field (search box on mailbox page). Valid values: + * - 'all': Search entire message (body & headers) + * - 'body': Search message body + * - 'from': Search from header + * - 'recip': Search recipients (To/CC/BCC) headers + * - 'subject': Search subject */ + // 'qsearch_field' => 'all', + + /* Splitbar (horizontal) height. Value is number of messages to + * show. 0 means auto-determine default size. */ + // 'splitbar_horiz' => 0, + + /* Splitbar (vertical) width. Value is width (in pixels) of the + * mailbox listing. 0 means auto-determine default size. */ + // 'splitbar_vert' => 0, + + /* Toggle headers in preview. 1 to show headers, 0 to hide. */ + // 'toggle_hdrs' => 0, + ); } + + + /** + * Dynamically disable composing messages. + * + * @return boolean Is composing disabled? + */ + // public function disable_compose() + // { + // // Example #1: Entirely disable composition. + // return false; + // } + + + /** + * Perform an action after messages have been reported as spam/innocent. + * + * @param string $action Either 'spam' or 'innocent'. + * @param IMP_Indices $indices The list of indices that have been + * reported as spam/innocent. + */ + // public function post_spam($action, $indices) + // { + // // Example #1: Copy messages to a (not)spam mailbox. This is the + // // full mailbox name. + // $targetMbox = 'foo'; + // + // $indices->copy($targetMbox, 'copy', array('create' => true)); + // } + + + /** + * Determine quota for a user. + * + * @param array $params Parameters for the function, set in backends.php. + * + * @return array Tuple with two members: + * - first: disk space used (in bytes) + * - second: maximum disk space (in bytes) + */ + // public function quota($params = null) + // { + // // Example #1: Sample function for returning the quota. + // // Uses the PECL ssh2 extension. + // // Requires the 'command' parameter to be defined in backends.php, + // // which defines the quota reporting function to run on the SSH + // // host. + // $imap_ob = $GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create(); + // $host = $imap_ob->getParam('hostspec'); + // $user = $params['host']; + // $pass = $imap_ob->getParam('password'); + // $command = $params['command']; + // + // $session = ssh2_connect($host); + // if (!$session) { + // throw new IMP_Exception(_("Connection to server failed.")); + // } + // + // if (!ssh2_auth_password($session, $user, $pass)) { + // throw new IMP_Exception(_("Authentication failed.")); + // } + // + // $stream = ssh2_exec($session, $command, false); + // stream_set_blocking($stream, true); + // + // $quota = preg_split('/\s+/', trim(stream_get_contents($stream)), 2); + // return array($quota[1] * 1024, $quota[2] * 1024); + // } + + + /** + * Retrieves public S/MIME keys of message recipients. + * + * The hook will be called first when searching for the keys, and further + * lookup techniques will only be used if the hook throws an exception or + * returns an empty result. + * + * @param string $address The email address of the recipient. + * + * @return string The base64-encoded public S/MIME key that matches the + * email address. + */ + // public function smime_key($address) + // { + // // Example #1: Retrieve S/MIME key from an LDAP backend. + // $ldapServer = 'localhost'; + // $ldapPort = 389; + // $searchBase = 'ou=users,dc=example,dc=com'; + // $binddn = 'uid=admin,dc=example,dc=com'; + // $bindpw = 'secret'; + // $attribute = 'simepublickey'; + // + // if (!@ldap_connect($ldapServer, $ldapPort)) { + // return; + // } + // if (!@ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)) { + // return; + // } + // if (!@ldap_bind($ds, $binddn, $bindpw)) { + // return; + // } + // + // $searchResult = @ldap_search($ds, $searchBase, 'mail=' . $address); + // $information = @ldap_get_entries($ds, $searchResult); + // ldap_close($ds); + // + // if ($information === false || $information['count'] == 0) { + // return; + // } + // + // return $information[0][$attribute][0]; + // } + + + /** + * Retrieves public PGP keys of message recipients. + * + * The hook will be called first when searching for the keys, and further + * lookup techniques will only be used if the hook throws an exception or + * returns an empty result. + * + * @param string $address The email address of the recipient. + * @param string $keyid The PGP key id of the recipient. + * + * @return string The base64-encoded public PGP key that matches either + * the email address or the fingerprint. + */ + // public function pgp_key($address, $keyid) + // { + // // Example #1: Retrieve PGP key from an LDAP backend. + // $ldapServer = 'localhost'; + // $ldapPort = 389; + // $searchBase = 'ou=users,dc=example,dc=com'; + // $binddn = 'uid=admin,dc=example,dc=com'; + // $bindpw = 'secret'; + // $attribute = 'pgppublickey'; + // + // if (!@ldap_connect($ldapServer, $ldapPort)) { + // return; + // } + // if (!@ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)) { + // return; + // } + // if (!@ldap_bind($ds, $binddn, $bindpw)) { + // return; + // } + // + // $searchResult = @ldap_search($ds, $searchBase, 'mail=' . $address); + // $information = @ldap_get_entries($ds, $searchResult); + // ldap_close($ds); + // + // if ($information === false || $information['count'] == 0) { + // return; + // } + // + // return $information[0][$attribute][0]; + // } + + }