<?php
/**
 * Turba Base Class.
 *
 * $Horde: turba/lib/Turba.php,v 1.59.4.10 2005/09/27 20:39:41 jan Exp $
 *
 * @author  Chuck Hagenbuch <chuck@horde.org>
 * @author  Jon Parise <jon@horde.org>
 * @package Turba
 */
class Turba {

    function formatEmailAddresses($data, $name)
    {
        global $registry;
        static $batchCompose;

        if (!isset($batchCompose)) {
            $batchCompose = $registry->hasMethod('mail/batchCompose');
        }

        require_once 'Horde/MIME.php';

        $array = is_array($data);
        if (!$array) {
            $data = array($data);
        }

        $addresses = array();
        foreach ($data as $i => $email_vals) {
            $email_vals = explode(',', $email_vals);
            foreach ($email_vals as $j => $email_val) {
                $email_val = trim($email_val);

                // Format the address according to RFC822.
                $mailbox_host = explode('@', $email_val);
                if (!isset($mailbox_host[1])) {
                    $mailbox_host[1] = '';
                }

                $address = MIME::rfc822WriteAddress($mailbox_host[0], $mailbox_host[1], $name);

                // Get rid of the trailing @ (when no host is included in
                // the email address).
                $addresses[$i . ':' . $j] = array('to' => addslashes(str_replace('@>', '>', $address)));
                if (!$batchCompose) {
                    $addresses[$i . ':' . $j] = $GLOBALS['registry']->call('mail/compose', $addresses[$i . ':' . $j]);
                }
            }
        }

        if ($batchCompose) {
            $addresses = $GLOBALS['registry']->call('mail/batchCompose', array($addresses));
        }

        foreach ($data as $i => $email_vals) {
            $email_vals = explode(',', $email_vals);
            $email_values = false;
            foreach ($email_vals as $j => $email_val) {
                $mail_link = $addresses[$i . ':' . $j];
                if (is_a($mail_link, 'PEAR_Error')) {
                    $mail_link = 'mailto:' . urlencode($address);
                }

                $email_value = Horde::link($mail_link, $email_val) . htmlspecialchars($email_val) . '</a>';
                if ($email_values) {
                    $email_values .= ', ' . $email_value;
                } else {
                    $email_values = $email_value;
                }
            }
        }

        if ($array) {
            return $email_values[0];
        } else {
            return $email_values;
        }
    }

    function string2Columns($string)
    {
        $ret = array();
        $lines = explode("\n", $string);
        foreach ($lines as $line) {
            $line = trim($line);
            if (!empty($line)) {
                $columns = explode("\t", $line);
                if (count($columns) > 1) {
                    $source = array_splice($columns, 0, 1);
                    $ret[$source[0]] = $columns;
                }
            }
        }

        return $ret;
    }

    /**
     * Returns a best guess at the lastname in a string.
     *
     * @param $name     String contain the full name.
     *
     * @return          String containing the last name.
     */
    function guessLastname($name)
    {
        $name = trim(preg_replace('|\s|', ' ', $name));
        if (!empty($name)) {
            /* Assume that last names are always before any commas. */
            if (is_int(strpos($name, ','))) {
                $name = String::substr($name, 0, strpos($name, ','));
            }

            /* Take out anything in parentheses. */
            $name = trim(preg_replace('|\(.*\)|', '', $name));

            $namelist = explode(' ', $name);
            $name = $namelist[($nameindex = (count($namelist) - 1))];

            while (!empty($name) && String::length($name) < 5 &&
                   strspn($name[(String::length($name) - 1)], '.:-') &&
                   !empty($namelist[($nameindex - 1)])) {
                $nameindex--;
                $name = $namelist[$nameindex];
            }
        }
        return $name;
    }

    /**
     * Formats the name according to the user's preference.
     *
     * @param Turba_Object $ob  The object to get a name from.
     *
     * @return string  The formatted name, either "Firstname Lastname"
     *                 or "Lastname, Firstname" depending on the user's
     *                 preference.
     */
    function formatName($ob)
    {
        global $prefs;
        static $name_format;

        if (!isset($name_format)) {
            $name_format = $prefs->getValue('name_format');
        }

        /* See if we have the name fields split out explicitly. */
        if ($ob->hasValue('firstname') && $ob->hasValue('lastname')) {
            if ($name_format == 'last_first') {
                return $ob->getValue('lastname') . ', ' . $ob->getValue('firstname');
            } else {
                return $ob->getValue('firstname') . ' ' . $ob->getValue('lastname');
            }
        } else {
            /* One field, we'll have to guess. */
            $name = $ob->getValue('name');
            $lastname = Turba::guessLastname($name);
            if ($name_format == 'last_first' &&
                !is_int(strpos($name, ',')) &&
                String::length($name) > String::length($lastname)) {
                $name = preg_replace('/\s+' . preg_quote($lastname, '/') . '/', '', $name);
                $name = $lastname . ', ' . $name;
            }
            if ($name_format == 'first_last' &&
                is_int(strpos($name, ',')) &&
                String::length($name) > String::length($lastname)) {
                $name = preg_replace('/' . preg_quote($lastname, '/') . ',\s*/', '', $name);
                $name = $name . ' ' . $lastname;
            }
            return $name;
        }
    }

    /**
     * Checks if a user has the specified permissions on the passed-in
     * object.
     *
     * @param array $in        The data to check on.
     * @param string $filter   What are we checking for.
     * @param int $permission  What permission to check for.
     *
     * @return boolean         Boolean indicating if the current user has the
     *                         requested permission on the requested item.
     */
    function hasPermission($in, $filter, $permission = PERMS_READ)
    {
        switch ($filter) {
        case 'object':
            if (!is_a($in, 'Turba_AbstractObject')) {
                return false;
            }

            $userID = Auth::getAuth();
            if (Auth::isAdmin() || in_array($userID, $in->driver->admin)) {
                return true;
            }

            /* If permissions have been set on this source, we treat
             * them as authoritative. Otherwise, we fall through to
             * checking the admin array of the source. */
            $sourceTag = 'turba:sources:' . $in->driver->name;
            if ($GLOBALS['perms']->exists($sourceTag)) {
                return $GLOBALS['perms']->hasPermission($sourceTag, $userID, $permission, $in->getValue('__owner'));
            }

            switch ($permission) {
            case PERMS_SHOW:
            case PERMS_READ:
                if ($in->driver->public ||
                    ($in->hasValue('__owner') &&
                     $in->getValue('__owner') == $userID)) {
                    return true;
                }
                break;

            case PERMS_EDIT:
            case PERMS_DELETE:
                /* Find out if this is a case that the object is
                 * editable. */
                if (!$in->driver->readonly &&
                    $in->hasValue('__owner') &&
                    $in->getValue('__owner') == $userID) {
                    return true;
                }
                return false;
                break;
            }
            break;

        default:
            return true;
        }

        return false;
    }

    /**
     * Filters data based on permissions.
     *
     * @param array $in            The data we want filtered.
     * @param string $filter       What type of data we are filtering.
     * @param integer $permission  The PERMS_* constant we will filter on.
     *
     * @return array  The filtered data.
     */
    function permissionsFilter($in, $filter, $permission = PERMS_READ)
    {
        $out = array();

        switch ($filter) {
        case 'source':
            if (Auth::isAdmin()) {
                return $in;
            }

            $userID = Auth::getAuth();
            foreach ($in as $sourceID => $name) {
                $sourceTag = 'turba:sources:' . $sourceID;
                if (!$GLOBALS['perms']->exists($sourceTag) || $GLOBALS['perms']->hasPermission($sourceTag, $userID, $permission)) {
                    $out[$sourceID] = $name;
                }
            }
            break;

        default:
            $out = $in;
        }

        return $out;
    }

    /**
     * Build Turba's list of menu items.
     */
    function getMenu($returnType = 'object')
    {
        require_once 'Horde/Menu.php';

        $menu = &new Menu();
        if ($GLOBALS['source_count']) {
            $menu->add(Horde::applicationUrl('browse.php'), _("_Browse"), 'menu/browse.png', null, null, null, $GLOBALS['prefs']->getValue('initial_page') == 'browse.php' && basename($_SERVER['PHP_SELF']) == 'index.php' ? 'current' : null);
        }
        if (count($GLOBALS['addSources'])) {
            $menu->add(Horde::applicationUrl('add.php'), _("_Add"), 'menu/new.png');
        }
        $menu->add(Horde::applicationUrl('search.php'), _("_Search"), 'search.png', $GLOBALS['registry']->getImageDir('horde'), null, null, $GLOBALS['prefs']->getValue('initial_page') == 'search.php' && basename($_SERVER['PHP_SELF']) == 'index.php' ? 'current' : null);

        /* Import/Export */
        if ($GLOBALS['conf']['menu']['import_export']) {
            $menu->add(Horde::applicationUrl('data.php'), _("_Import/Export"), 'data.png', $GLOBALS['registry']->getImageDir('horde'));
        }

        if ($returnType == 'object') {
            return $menu;
        } else {
            return $menu->render();
        }
    }

}
