<?php
/**
 * Horde Hooks configuration file.
 *
 * THE HOOKS PROVIDED IN THIS FILE ARE EXAMPLES ONLY.  DO NOT ENABLE THEM
 * BLINDLY IF YOU DO NOT KNOW WHAT YOU ARE DOING.  YOU HAVE TO CUSTOMIZE THEM
 * TO MATCH YOUR SPECIFIC NEEDS AND SYSTEM ENVIRONMENT.
 *
 * This file is where you define any hooks, for preferences or general Horde
 * use, that your installation uses. The functions in this file can vastly
 * change how your installation behaves, so make sure to test out any changes
 * here before doing them in a production environment.
 *
 * Errors
 * ======
 * All critical/fatal errors should be reported by throwing a Horde_Exception
 * object.
 *
 *
 * Preferences Hooks
 * =================
 * Two types of preferences hooks are available.
 *
 * Setting value at login
 * ----------------------
 * If the 'hook' parameter is non-empty for a preference (config/prefs.php),
 * the prefs_init hook will be run on login to allow alteration of the value.
 * This hook receives the preference name, preference value, username, and
 * the master scope object (Horde_Prefs_Scope) as parameters and uses the
 * return value from the hook as the new preference value.
 *
 * Username will be null if the user is not authenticated.
 *
 * This hook is ONLY executed on login and preferences are cached during a
 * users' session.
 *
 * NOTE: Because the prefs_init hook is called BEFORE the application is
 *       initialized, application data will not be available in this hook.
 *       If you want to alter preferences values based on application data,
 *       you should use the appauthenticated hook instead.
 *
 * On change
 * ---------
 * A hook named prefs_change will be called after a preference is altered.
 * It is passed the preference name that has changed and does not expect a
 * return value.
 *
 *
 * Authentication Hooks
 * ====================
 * There are two special hooks called during the initial authentication
 * of any Horde application responsible for authentication.
 * These hooks are only called ONCE per session.
 *
 * preauthenticate
 * ---------------
 * This hook is used to dynamically alter the login credentials before
 * authentication occurs.
 *
 * It is only called in Horde applications responsible for authentication.
 *
 * It is only called ONCE per session.
 *
 * If there is no active session, $userId and $credentials will be the values
 * provided by the base Horde authentication driver. ($userId will often
 * be empty in this situation.)
 * For all other apps, $userId and $credentials will be the values of the
 * currently logged on Horde user.
 *
 * Parameters in:
 *   $userId (string): User ID to be used for authentication.
 *   $credentials (array): The array of credentials to be used for
 *                         authentication. The key 'authMethod' will contain
 *                         the authentication event that triggered the hook.
 *                         Possible values: 'authenticate', 'transparent', or
 *                         'admin'.
 *
 * The return value from this hook is as follows:
 *   [throw Horde_Auth_Exception] - Fatal error.
 *   false (boolean) - Authentication will fail.
 *   true (boolean) - Authentication will continue with no alteration of the
 *                    user ID/credentials.
 *   (array) - Replace the credentials with the given key/values. Keys are
 *             'userId' and 'credentials'. Only the keys defined will be
 *             altered.
 *
 * postauthenticate
 * ----------------
 * This hook is used to dynamically alter the login credentials after
 * authentication occurs.
 *
 * It is only called in Horde applications responsible for authentication.
 *
 * It is only called ONCE per session.
 *
 * Parameters in:
 *   $userId (string): The Horde ID.
 *   $credentials (array): The array of credentials used for authentication.
 *
 * The return value from this hook is as follows:
 *   [throw Horde_Auth_Exception] - Fatal error.
 *   false (boolean) - Authentication will fail.
 *   true (boolean) - Authentication succeeds with no alteration of the
 *                    credentials.
 *   (array) - Replace the credentials with the given value.
 *
 * authusername
 * ------------
 * This hook is used to dynamically convert between an authentication username
 * and a Horde username.
 *
 * It is only available in the base Horde application.
 *
 * Parameters in:
 *   $userId (string): The username.
 *   $toHorde (boolean): If true, convert from authentication ID to Horde ID.
 *                       Otherwise, do the reverse conversion.
 *
 * The return value from this hook is as follows:
 *   [throw Horde_Auth_Exception] - Fatal error.
 *   (string) - The converted username.
 *
 *
 * Login Hooks
 * ===========
 *
 * appauthenticated
 * ----------------
 * This hook is called after the initial application initialization is
 * complete (the application will have passed authentication at this point).
 *
 * This hook is called for EVERY Horde application.
 *
 * This hook is only called ONCE per session.
 *
 * This hook takes no parameters and expects no return value. An Exception
 * thrown from this hook will cause a fatal error.
 *
 *
 * Application Initialization Hook
 * ===============================
 *
 * pushapp
 * -------
 * This hook is called the first time an application is pushed onto the stack.
 * It is passed no parameters and expects no return value.
 * Any Exception thrown in this hook will cause a fatal error.
 *
 *
 * AJAX Hooks
 * ==========
 * These are hooks that are available in any application that has an AJAX
 * interface configured.
 *
 * ajaxaction
 * ----------
 * This hook is used to add user-defined AJAX action handlers to an
 * application.
 *
 * Parameters in:
 *   $action (string): The AJAX action.
 *   $vars (Horde_Variables): The URL parameters.
 *
 * The return value from this hook is as follows:
 *   [throw Horde_Exception] - Fatal error.
 *   [mixed] - The data to send to the browser (will be JSON encoded).
 *
 *
 * CSS Hooks
 * =========
 *
 * cssfiles
 * --------
 * This hook allows additional CSS stylesheets to be added to the page
 * output.
 *
 * Parameters in:
 *   $theme (string): The current theme.
 *
 * The return value from this hook is as follows:
 *   [throw Horde_Exception] - Fatal error.
 *   [array] - An array of CSS files to add. Keys are the filesystem location,
 *             values are the URI location.
 *
 *
 * TODO: groupldap, share_add, share_modify, share_remove
 *
 * $Id: 3305816919e6679dd5ba6c7915a10dd6a17368b2 $
 */

class Horde_Hooks
{
//    // PREFERENCES INIT: See above for documentation.
//    public function prefs_init($pref, $value, $username, $scope_ob)
//    {
//        switch ($pref) {
//        case 'from_addr':
//            // Example from_addr init. THIS FUNCTION ASSUMES THAT YOU ARE
//            // USING A LDAP SERVER and that your /etc/ldap.conf is correctly
//            // set to a valid host.
//            //
//            // You are responsible for bringing in to the local scope any
//            // information you need. You can "global" anything else you
//            // need.
//            //
//            // Returns an address: either just the user@ side or a full
//            // address.
//
//            // Example #1
//            if (is_null($username)) {
//                return $value;
//            }
//
//            $base_context = 'o=myorg';
//            $scope = 'sub';
//
//            // You will probably need to replace cd= with uid=; this
//            // syntax is for Netware 5.1 nldap.
//            $cmd = '/usr/bin/ldapsearch -b ' . $base_context . ' -s ' . $scope . ' cn=' .
//                escapeshellcmd($username) .
//                ' | /usr/bin/grep mail | /usr/bin/awk \'{print $2}\'';
//            $mails = `$cmd`;
//            $mail_array = explode("\n", $mails);
//
//            // Send back the first email found, not the whole list.
//            $mail = $mail_array['0'];
//
//            // If no email address is found, then the login name will
//            // be used.
//            return empty($mail)
//                ? ''
//                : $mail;
//
//
//            // Example #2
//            if (is_null($username)) {
//                return $value;
//            }
//
//            $ldapServer = '172.31.0.236';
//            $ldapPort = '389';
//            $searchBase = 'o=myorg';
//
//            $ds = @ldap_connect($ldapServer, $ldapPort);
//
//            // You will probably need to replace cn= with uid=; this syntax
//            // is for Netware 5.1 nldap.
//            $searchResult = @ldap_search($ds, $searchBase, 'cn=' . $username);
//            $information = @ldap_get_entries($ds, $searchResult);
//            if (($information === false) || ($information['count'] == 0)) {
//               $user = '';
//            } else {
//                $user = ($information[0]['mail'][0] != '')
//                    ? $information[0]['mail'][0]
//                    : $information[0]['cn'][0];
//            }
//
//            ldap_close($ds);
//
//            return empty($user)
//                ? $username
//                : $user;
//
//
//        case 'fullname':
//            // Examples on how to set the fullname.
//
//            // Example #1: Set the fullname from the GECOS information in
//            // the passwd file.
//            if (is_null($username)) {
//                return $value;
//            }
//
//            $user = $GLOBALS['registry']->getAuth('bare');
//
//            $array = posix_getpwnam($user);
//            $gecos_array = explode(',', $array['gecos']);
//            return empty($gecos_array)
//                ? $user
//                : $gecos_array[0];
//
//
//            // Example #2: Set the fullname from LDAP information. In this
//            // example we look if a Spanish name exists and return this or
//            // the standard 'cn' entry if not.
//            if (is_null($username)) {
//                return $value;
//            }
//
//            $ldapServer = 'ldap.example.com';
//            $ldapPort = '389';
//            $searchBase = 'ou=people,o=example.com';
//
//            $ds = @ldap_connect($ldapServer, $ldapPort);
//
//            $searchResult = @ldap_search($ds, $searchBase, 'uid=' . $username);
//            $information = @ldap_get_entries($ds, $searchResult);
//            if (($information === false) || ($information['count'] == 0)) {
//                $name = '';
//            } else {
//                $name = ($information[0]['cn;lang-es'][0] != '')
//                    ? $information[0]['cn;lang-es'][0]
//                    : $information[0]['cn'][0];
//            }
//
//            ldap_close($ds);
//
//            return empty($name)
//                ? $username
//                : $name;
//        }
//    }


//    // PREFERENCES CHANGE: See above for documentation.
//    public function prefs_change($pref)
//    {
//        switch ($pref) {
//        case 'theme':
//            $GLOBALS['notification']->push('You changed your theme to ' . $GLOBALS['prefs']->getValue('theme') . '.');
//            break;
//        }
//    }


//    // PREAUTHENTICATE HOOK: See above for description of format.
//    public function preauthenticate($userId, $credentials)
//    {
//        // Example #1: Make Horde respect the Unix convention of not
//        // allowing login when a file named /etc/nologin exist.
//        return !file_exists('/etc/nologin');
//
//
//        // Example #2: Block access to Horde if the remote host exists in
//        // the DNSBL. It requires the PEAR Net_DNSBL package.
//        $dnsbl = new Net_DNSBL();
//        $dnsbl->setBlacklists(array('sbl-xbl.spamhaus.org', 'bl.spamcop.net'));
//        return !$dnsbl->isListed($_SERVER['REMOTE_ADDR']);
//
//
//        // Example #3: Block access for user 'foo'.
//        return ($userId != 'foo');
//
//
//        // Example #4: Create credentials needed by the LDAP Horde_Auth
//        // driver for adding/deleting/updating users.
//        $entry = array(
//            'dn' => 'uid=' . $userId . ',ou=People,dc=example.com',
//            'cn' => isset($credentials['user_fullname']) ? $credentials['user_fullname'] : $userId,
//            'sn' => $userId,
//            'objectclass' => array(
//                'top',
//                'person',
//                'qmailuser',
//                'CourierMailAccount',
//            ),
//            'mailhost' => 'mail.example.com',
//            'mailMessageStore' => '/home/mail/' . $userId,
//            'homeDirectory' => '/home/mail/' . $userId,
//            'mailbox' => '/Maildir',
//            'homeDirectory' => '/Maildir',
//            'uid' => $userId,
//            'accountStatus' => 'active',
//            'mailQuota' => '104857600S',
//            'mail' => $userId,
//            'uidNumber' => 501,
//            'gidNumber' => 501,
//            'deliveryMode' => 'nolocal'
//        );
//
//        // Need to check for new users (password) and edited users
//        // (user_pass_2)
//        if (isset($credentials['password'])) {
//            $entry['userPassword'] = '{MD5}' . base64_encode(pack('H*', md5($credentials['password'])));
//        } elseif (isset($credentials['user_pass_2'])) {
//            $entry['userPassword'] = '{MD5}' . base64_encode(pack('H*', md5($credentials['user_pass_2'])));
//        }
//        $entry['deliveryMode'] = 'nolocal';
//
//        return array(
//            'userId' => $userId,
//            'credentials' => $entry
//        );
//     }


//    // POSTAUTHENTICATE HOOK: See above for description of format.
//    public function postauthenticate($userId, $credentials)
//    {
//        // Example #1: Validating the user's right to login to Horde by
//        // by consulting group membership in an LDAP directory.  That
//        // way, if your Horde installation is configured to authenticate
//        // against IMP which in turn authenticate via IMAP, it is still
//        // possible to limit access to Horde by group membership.  The
//        // following example had been made with an MS Active Directory in
//        // mind.  Note that if the LDAP directory is unavailable or some
//        // other error occur, authentication will fail.
//        $ldapServer = 'ad.example.com';
//        $ldapPort = '389';
//
//        // Note that credential is sent plain-text in this case, so don't
//        // use privileged account here or setup SSL (by using port 636
//        // above).
//        $binddn = 'cn=WithoutPrivilege,dc=ulaval-dev,dc=ca';
//        $bindpw = 'Remember this is sent in the clear unless SSL is used';
//        $searchBase = 'ou=People,dc=example,dc=com';
//
//        // Attribute to match $userId against in search
//        $userAttr = 'sAMAccountName';
//
//        // Group membership attribute, need to be all lowercase
//        $groupAttr = 'memberof';
//
//        // Attribute to check for right to use Horde
//        $groupdn = 'cn=HordeUser,ou=People,dc=example,dc=com';
//        $ret = false;
//
//        $ds = @ldap_connect($ldapServer, $ldapPort);
//
//        if (@ldap_bind($ds, $binddn, $bindpw)) {
//            $searchResult = @ldap_search($ds, $searchBase, $userAttr . '=' . $userId, array($groupAttr), 0, 1, 5);
//            if ($information = @ldap_get_entries($ds, $searchResult)) {
//                // Make pattern case-insensitive
//                $pattern = '/' . $groupdn . '/i';
//                foreach ($information[0][$groupAttr] as $group) {
//                    if (preg_match($pattern, $group)) {
//                        $ret = true;
//                        break;
//                    }
//                }
//            }
//        }
//
//        ldap_close($ds);
//
//        return $ret;
//     }


//    // USERNAME HOOK: See above for description of format.
//    public function authusername($userId, $toHorde)
//    {
//        // Example #1: Append the virtual domain to the username.
//        // ex. $HTTP_HOST = 'mail.mydomain.com', $userId = 'myname' returns:
//        // 'myname@mydomain.com'
//        $vdomain = preg_replace('|^mail\.|i', '', getenv('HTTP_HOST'));
//        $vdomain = Horde_String::lower($vdomain);
//
//        if ($toHorde) {
//            return $userId . '@' . $vdomain;
//        } else {
//            return (substr($userId, -strlen($vdomain)) == $vdomain)
//              ? substr($userId, 0, -strlen($vdomain) - 1)
//              : $userId;
//        }
//
//
//        // Example #2: Convert username to all lowercase. This might be
//        // necessary if an authentication backend is case insensitive to
//        // take into account that Horde's preference system is case
//        // sensitive.
//        // ex. $userId = 'MyName' returns: 'myname'
//        return $toHorde
//            ? Horde_String::lower($userId)
//            : $userId;
//
//
//        // Example #3: Map the LDAP "uid" back to the LDAP "mail"
//        // attribute in case both are allowed user IDs for login.
//        if (!$toHorde) {
//            return $userId;
//        }
//        $ldapServer = 'localhost';
//        $ldapPort = '389';
//        $searchBase = 'dc=example,dc=com';
//        $binddn = 'cn=manager,' . $searchBase;
//        $bindpw = 'PASSWORD';
//
//        $ds = @ldap_connect($ldapServer, $ldapPort);
//        $searchResult = @ldap_search($ds, $searchBase, 'uid=' . $userId);
//        $information = @ldap_get_entries($ds, $searchResult);
//        if (($information !== false) && ($information['count'] > 0)) {
//            $userId = $information[0]['mail'][0];
//        }
//        return $userId;
//    }


//    // APPLICATION AUTHENTICATED HOOK: See above for format.
//    public function appauthenticated()
//    {
//        // Code to run when an application is first authenticated
//    }


//    // PRE-PUSH HOOK: See above for format.
//    public function pushapp()
//    {
//        // Code to run immediately before the app is switched to horde
//    }


//    // POST-PUSH HOOK: See above for format.
//    public function pushapp_post()
//    {
//        // Code to run immediately after the app is successfully switched to
//        // horde
//    }


//    // ADD CSS HOOK: See above for description of format.
//    public function cssfiles($theme)
//    {
//        return array(
//            '/file/path/to/css' => 'uri/to/css'
//        );
//    }


    /**
     * Modify the browser object.
     *
     * @param Horde_Core_Browser $browser  The browser object.
     */
//    public function browser_modify($browser)
//    {
//        // Example #1: Mark all browsers as mobile. Useful if this
//        // particular Horde installation is dedicated solely to serving
//        // mobile devices.
//        $browser->setMobile(true);
//    }


    /**
     * Allow altering or validating data submitted by a user during a signup
     * request before any attempts are made to add them to the system.
     *
     * @param array $info  TODO
     *
     * @return array  TODO
     */
//    public function signup_preprocess($info)
//    {
//         $info['user_name'] = Horde_String::lower($info['user_name']);
//         return $info;
//    }


    /**
     * Callback when a signup is queued for administrative approval.
     *
     * @param string $userId  The username.
     * @param array $data     TODO
     */
//    public function signup_queued($userId, $data)
//    {
//        // Example #1: Send a notification message to the web server
//        // administrator's e-mail address.
//        $ $aders = array(
//            'To'      => $_SERVER['SERVER_ADMIN'],
//            'From'    => $_SERVER['SERVER_ADMIN'],
//            'Subject' => 'New ' . $GLOBALS['registry']->get('name', 'horde') . ' Signup'
//        );
//
//        try {
//            $extraFields = Horde::callHook('signup_getextra');
//        } catch (Horde_Exception $e) {
//        } catch (Horde_Exception_HookNotSet $e) {}
//
//        $msg  = _("A new signup has been received and is awaiting your approval.") .
//            "\n\n" .
//            $this->_signup_queued_walkdata($extraFields, $data) .
//            "\n" .
//            sprintf(_("You can approve this signup at %s"), Horde::url('admin/user.php', true, array('append_session' => -1)));
//
//        $GLOBALS['injector']->getInstance('Horde_Mail')->send($_SERVER['SERVER_ADMIN'], $headers, $msg);
//    }
//
//    // Helper function for signup_queued Example #1
//    private function _signup_queued_walkdata($fields, $data)
//    {
//        $msg = '';
//        foreach ($data as $field => $value) {
//            if (in_array($field, array('password', 'url'))) {
//                continue;
//            }
//
//            if (is_array($value)) {
//                $msg .= $this->_signup_queued_walkdata($fields, $value);
//            } else {
//                $field = isset($fields[$field]['label'])
//                    ? $fields[$field]['label']
//                    : $field;
//                $msg .= "$field: $value\n";
//            }
//        }
//        return $msg;
//    }


    /**
     * Provide any extra fields which need to be filled in when a
     * non-registered user wishes to sign up.
     *
     * @return array  An array of the following form:
     * <pre>
     * $somearray['somefieldname'] = array(...
     * desc     - Any help text attached to the field
     * label    - The text that the user will see attached to this field
     * params   - Any allowed parameter to Horde_Form field types
     * readonly - (boolean) Whether this editable
     * required - (boolean) Whether this field is mandatory
     * type     - Any allowed Horde_Form field type
     * </pre>
     */
//    public function signup_getextra()
//    {
//        // Example #1: A hypothetical case where we would want to store
//        // extra information about a user into a turba sql address book. All
//        // this example does is include the attributes.php file from turba.
//        // NOTE: You NEED Turba to be correctly installed before you can use
//        // this example.
//        return Horde::loadConfiguration('attributes.php', 'attributes', 'turba');
//     }


    /**
     * TODO
     *
     * @param string $userId    The username.
     * @param array $extra      A hash with the extra information requested via
     *                          the signup_getextra hook.
     * @param string $password  The password.
     */
//    public function signup_addextra($userId, $extra, $password)
//    {
//        // Example #1: Continuation of Example #1 from signup_getextra().
//        // Here we connect to the database using the sql parameters
//        // configured in $conf and store the extra fields in turba_objects,
//        // using the $userId as the key for the object and values from the
//        // $extra array. You could create your own sql syntax or code to
//        // store this in whichever backend you require.
//        // NOTE: You NEED Turba to be correctly installed before you can use
//        // this example. It also assumes you are using an SQL backend.
//        $db = $GLOBALS['injector']->getInstance('Horde_Db_Adapter');
//
//        $fields = $values = $markers = array();
//        foreach ($extra as $field => $value) {
//            $fields[] = 'object_' . Horde_String::lower($field);
//            $markers[] = '?';
//            $values[] = Horde_String::convertCharset($value, 'UTF-8', $db->getCharset());
//        }
//        $fields[] = 'object_id';
//        $markers[] = '?';
//        $values[] = $userId;
//
//        $query  = 'INSERT INTO turba_objects ( owner_id, ' . implode(', ', $fields) . ')';
//        $query .= ' VALUES ( \'admin\', ' . implode(', ', $markers) . ')';
//        $db->insert($query, $values);
//    }


    /**
     * Alter the share list.
     *
     * @param string $userId     TODO
     * @param TODO $perm         TODO
     * @param string $owner      TODO
     * @param array $share_list  TODO
     *
     * @return array  The altered share list.
     */
//    public function share_list($userId, $perm, $owner, $share_list)
//    {
//        return $share_list;
//    }


    /**
     * Hook called if a user tries to make an action that is under permission
     * control that they don't have sufficient permissions for.  It can be
     * used to show the user a custom message including HTML code (via the
     * notification system), or to interrupt the code flow and send the user
     * to a different page.
     *
     * @param string $app         Horde application.
     * @param string $permission  Permission that failed.
     */
//    public function perms_denied($app, $permission)
//    {
//        // Example #1: Provide link to upgrade script in notification
//        // message.
//        $GLOBALS['notification']->push(sprintf('Permission denied. Click <a href="http://www.example.com/upgrade.php?app=%s">HERE</a> to upgrade %s.', $app, $GLOBALS['registry']->get('name')), 'horde.error', array('content.raw'));
//    }


    /**
     * IMSP share init. TODO
     *
     * @param TODO $share_obj TODO
     * @param string $app TODO
     */
//    public function share_init($share_obj, $app)
//    {
//        global $cfgSources, $prefs, $session;
//
//        // TODO: Move to turba?
//        if (($app == 'turba') &&
//            (!empty($cfgSources['imsp']['use_shares']))) {
//            // Only do this once per session or when this session variable
//            // is purposely unset.
//            if ($session->get('horde', 'imsp_synched')) {
//                return;
//            }
//
//            $results = Net_IMSP_Utils::synchShares($share_obj, $cfgSources['imsp']);
//            if (!$results instanceof PEAR_Error) {
//                $session->set('horde', 'imsp_synched') = true;
//
//                // Now deal with adding or removing address books from prefs.
//                // FIXME: Updating prefs seems to hang the server. Narrowed
//                // down to the fact that $prefs->setValue() also attempts to
//                // call a hook. (Commenting out the callHook call fixes). Can
//                // anyone verify this on their install?
//                $dirty = false;
//                $abooks = $prefs->getValue('addressbooks');
//                $abooks = empty($abooks)
//                    ? array()
//                    : explode("\n", $prefs->getValue('addressbooks'));
//
//                if (count($results['removed'] > 0)) {
//                    foreach ($results['removed'] as $sharename) {
//                       $key = array_search($sharename, $abooks);
//                       if ($key === true) {
//                           unset($abooks[$key]);
//                           $dirty = true;
//                       }
//                    }
//                }
//
//                if (count($results['added']) > 0) {
//                    foreach ($results['added'] as $sharename) {
//                        if (array_search($sharename, $abooks) === false) {
//                            $abooks[] = $sharename;
//                            $dirty = true;
//                        }
//                    }
//                }
//
//                if ($dirty) {
//                    $result = $prefs->setValue('addressbooks', implode("\n", $abooks));
//                }
//
//                // We have to save the connection info for the imsp server
//                // since the share_modify hook will not occur from within
//                // turba's context.
//                $session->set('horde', 'imsp_config', $cfgSources['imsp']['params']);
//            }
//        }
//    }


    /**
     * IMSP share modify. TODO
     *
     * @param TODO $share TODO
     */
//    public function share_modify($share)
//    {
//        global $injector, $session, $share;
//
//        $params = unserialize($share->get('params'));
//        if (is_array($params) &&
//            !empty($params['source']) &&
//            ($params['source'] == 'imsp') &&
//            ($config = $session->get('horde', 'imsp_config'))) {
//            // Ensure we don't try to change ownership.
//            $params = @unserialize($share->get('params'));
//            $bookName = $params['name'];
//            if (strpos($bookName, $share->get('owner')) !== 0) {
//                throw new Horde_Exception('Changing ownership of IMSP address books is not supported.');
//            }
//
//            // Update the ACLS
//            $perms = $share->getPermission();
//            $users = $injector->getInstance('Horde_Perms')->getUserPermissions();
//            foreach ($users as $user => $perm) {
//                $acl = Net_IMSP_Utils::permsToACL($perm);
//                $result = Net_IMSP_Utils::setACL($config, $bookName, $user, $acl);
//            }
//        }
//    }

    /**
     * ActiveSync hook for determing a Horde username from an email address.
     *
     * @param string $email  The email address
     *
     * @return string  The username to use to authenticate to Horde with.
     */
    // public function activesync_get_autodiscover_username($email)
    // {
    //     return substr($email, 0, strpos($email, '@'));
    // }

    /**
     * ActiveSync hook for overriding the XML output. Takes an array of
     * autodiscover parameters and returns the raw XML string to send to the
     * client. USING THIS HOOK MEANS YOU ARE RESPONSIBLE FOR SENDING CORRECT
     * XML TO THE CLIENT. ACTIVESYNC WILL SEND THIS STRING AS-IS. ONLY USE THIS
     * IF YOU KNOW WHAT YOU ARE DOING!
     *
     * @param array $params  The array of available Autodiscover parameters.
     *
     * @return string  The XML string.
     */
    // public function activesync_autodiscover_xml(array $params)
    // {
    // }

    /**
     * ActiveSync hook for modifying the various Autodiscover values before
     * the XML string is build by the ActiveSync server code. Use, e.g., if you
     * need to alter the value of the host before sending it to the client.
     *
     * @param array $params  The array of Autodiscover parameters.
     *
     * @return array  The possibly modified array of Autodiscover parameters.
     */
    // public function activesync_autodiscover_parameters(array $params)
    // {
    //     return $params;
    // }

}
