<?php
// $Horde: turba/lib/api.php,v 1.14.2.13 2003/02/10 01:36:55 jan Exp $

// Find the base file path of Turba
if (!defined('TURBA_BASE')) define('TURBA_BASE', dirname(__FILE__) . '/..');

// Include the Turba base libraries and setup.
require_once TURBA_BASE . '/lib/base.php';

function turbaImportvCard($source, $vcard_data)
{
    require_once HORDE_BASE . '/lib/Data.php';
    require_once TURBA_BASE . '/lib/Source.php';
    require_once TURBA_BASE . '/lib/Object.php';
    require_once 'PEAR.php';
    global $cfgSources;

    if (empty($source) || !isset($cfgSources[$source])) {
        return PEAR::raiseError(_("Invalid address book."), HORDE_ERROR, null, null, $source);
    }

    if ($cfgSources[$source]['readonly']
        && (!isset($cfgSources[$source]['admin'])
        || !in_array(Auth::getAuth(), $cfgSources[$source]['admin']))) {
        return PEAR::raiseError(_("Address book is read-only."), HORDE_ERROR, null, null, $source);
    }

    $vcard = new Data_rfc2425();
    if (!$data = $vcard->import($vcard_data)) {
        return PEAR::raiseError(_("There was an error importing the vCard data."));
    }

    $driver = &Turba_Source::singleton($source, $cfgSources[$source]);

    $objects = array();
    foreach ($data as $object) {
        if ($object['type'] == 'VCARD') {
            $hash = Turba_Object::fromvCard($object, $vcard);
            $res = $driver->search($hash, 'lastname', TURBA_SEARCH_AND);
            if (PEAR::isError($res) || $res->count() > 0) {
                $objects[] = PEAR::raiseError(_("This person is already in your address book."), HORDE_MESSAGE, null, null, $source);
            } else {
                $hash['__owner'] = Auth::getAuth();
                $objectID = $driver->addObject($hash);
                if (!PEAR::isError($objectID)) {
                    $objects[$objectID] = isset($hash['name']) ? $hash['name'] : _("Unnamed Contact");
                } else {
                    if (count($objects)) {
                        foreach ($objects as $id => $name) {
                            $driver->removeObject($id);
                        }
                    }
                    return PEAR::raiseError(_("There was an error importing the vCard data."));
                }
            }
        }
    }

    return $objects;
}

function turbaExpandAddresses($names = array(), $addressbooks = array(), $fields = array())
{
    include TURBA_BASE . '/config/attributes.php';
    require_once TURBA_BASE . '/lib/Source.php';
    global $cfgSources;

    if (!isset($cfgSources) || !is_array($cfgSources) || !count($cfgSources)) {
        return array();
    }

    if (count($addressbooks) == 0) {
        $addressbooks = array(key($cfgSources));
    }

    $results = array();
    $seen = array();
    foreach ($addressbooks as $source) {
        if (isset($cfgSources[$source])) {
            $driver = &Turba_Source::singleton($source, $cfgSources[$source]);
            if (PEAR::isError($driver)) {
                return new PEAR_Error(_("Failed to connect to the specified directory."), HORDE_ERROR, null, null, $source);
            }

            foreach ($names as $name) {
                $criteria = array();
                if (isset($fields[$source])) {
                    foreach ($fields[$source] as $field) {
                        $criteria[$field] = trim($name);
                    }
                }
                if (count($criteria) == 0) {
                    $criteria['name'] = trim($name);
                }
                $res = $driver->search($criteria, 'lastname', TURBA_SEARCH_OR);

                if (!isset($results[$name])) {
                    $results[$name] = array();
                }
                if (get_class($res) == 'turba_list') {
                    while ($ob = $res->next()) {
                        if (!$ob->isGroup()) {
                            /* Not a Group */
                            $att = $ob->getAttributes();
                            foreach ($att as $key => $value) {
                                if (!empty($value) && isset($attributes[$key]) &&
                                    $attributes[$key]['type'] == 'email' &&
                                    empty($seen[$name][trim(strtolower($att['name'])) . trim(strtolower($value))])) {

                                    $results[$name][] = array('name' => $att['name'], 'email' => $value, '__type' => 'Contact');
                                    $seen[$name][trim(strtolower($att['name'])) . trim(strtolower($value))] = true;
                                }
                            }
                        } else {
                            /* Is a Distribution List */
                            $listatt = $ob->getAttributes();
                            $seeninlist = array();
                            $members = $ob->listMembers();
                            if (get_class($members) == 'turba_list') {
                                if ($members->count() == 1) {
                                    $ob = $members->next();
                                    $att = $ob->getAttributes();
                                    $email = '';
                                    foreach ($att as $key => $value) {
                                        if (!empty($value) && isset($attributes[$key]) &&
                                            $attributes[$key]['type'] == 'email') {
                                            $email = $value;
                                        }
                                    }
                                    $results[$name][] = array('name' => $listatt['name'] . ' - ' . $att['name'], 'email' => $email);
                                } else {
                                    $email = '';
                                    while ($ob = $members->next()) {
                                        $att = $ob->getAttributes();
                                        foreach ($att as $key => $value) {
                                            if (!empty($value) && isset($attributes[$key]) &&
                                                $attributes[$key]['type'] == 'email' &&
                                                empty($seeninlist[trim(strtolower($att['name'])) . trim(strtolower($value))])) {

                                                $email .= ($email == '') ? '' : ', ';
                                                $email .= '"' . $att['name'] . '" <' . $value . '>';
                                                $seeninlist[trim(strtolower($att['name'])) . trim(strtolower($value))] = true;
                                            }
                                        }
                                    }
                                    $results[$name][] = array('name' => $listatt['name'], 'email' => $email);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return $results;
}

function turbaAddAddress($name = '', $address = '', $addressbook = '')
{
    require_once 'PEAR.php';
    require_once TURBA_BASE . '/lib/Source.php';
    global $cfgSources;

    if (empty($addressbook) || !isset($cfgSources[$addressbook])) {
        return PEAR::raiseError(_("Invalid address book."), HORDE_ERROR, null, null, $addressbook);
    }

    if (empty($name)) {
        return PEAR::raiseError(_("Invalid name."), HORDE_ERROR, null, null, $addressbook);
    }

    if (empty($address)) {
        return PEAR::raiseError(_("Invalid e-mail address."), HORDE_ERROR, null, null, $addressbook);
    }

    if ($cfgSources[$addressbook]['readonly']
        && (!isset($cfgSources[$addressbook]['admin'])
        || !in_array(Auth::getAuth(), $cfgSources[$addressbook]['admin']))) {
        return PEAR::raiseError(_("Address book is read-only."), HORDE_ERROR, null, null, $addressbook);
    }

    $driver = &Turba_Source::singleton($addressbook, $cfgSources[$addressbook]);
    $res = $driver->search(array('name' => $name, 'email' => $address), 'lastname', TURBA_SEARCH_AND);
    if (PEAR::isError($res) || $res->count() > 0) {
        return PEAR::raiseError(_("This person is already in your address book."), HORDE_MESSAGE, null, null, $addressbook);
    }

    return $driver->addObject(array('name' => $name, 'email' => $address, '__owner' => Auth::getAuth()));
}

function turbaGetSources($writeable = false)
{
    require_once 'PEAR.php';
    global $cfgSources;

    if (!isset($cfgSources) || !is_array($cfgSources) || !count($cfgSources)) {
        return array();
    }

    $sources = array();
    foreach ($cfgSources as $key => $entry) {
        if (!$writeable || (!$entry['readonly'] ||
                           (isset($entry['admin']) && in_array(Auth::getAuth(), $entry['admin'])))) {
            $sources[$key] = $entry['title'];
        }
    }

    return $sources;
}

function turbaGetFields($addressbook = '')
{
    include TURBA_BASE . '/config/attributes.php';
    require_once 'PEAR.php';
    global $cfgSources;

    if (empty($addressbook) || !isset($cfgSources[$addressbook])) {
        return PEAR::raiseError(_("Invalid address book."), HORDE_ERROR, null, null, $addressbook);
    }

    $fields = array();
    foreach ($cfgSources[$addressbook]['map'] as $field_name => $null) {
        if (substr($field_name, 0, 2) != '__') {
            $fields[$field_name] = array('name' => $field_name,
                                         'type' => $attributes[$field_name]['type'],
                                         'desc' => $attributes[$field_name]['desc'],
                                         'search' => in_array($field_name, $cfgSources[$addressbook]['search']));
        }
    }

    return $fields;
}

function turbaAddField($address = '', $name = '', $field = '', $value = '', $addressbook = '')
{
    require_once 'PEAR.php';
    require_once TURBA_BASE . '/lib/Source.php';
    global $cfgSources;

    if (empty($addressbook) || !isset($cfgSources[$addressbook])) {
        return PEAR::raiseError(_("Invalid address book."), HORDE_ERROR, null, null, $addressbook);
    }

    if (empty($address)) {
        return PEAR::raiseError(_("Invalid e-mail address."), HORDE_ERROR, null, null, $addressbook);
    }

    if (empty($name)) {
        return PEAR::raiseError(_("Invalid name."), HORDE_ERROR, null, null, $addressbook);
    }

    if (empty($value)) {
        return PEAR::raiseError(_("Invalid entry."), HORDE_ERROR, null, null, $addressbook);
    }

    if ($cfgSources[$addressbook]['readonly']
        && (!isset($cfgSources[$addressbook]['admin'])
        || !in_array(Auth::getAuth(), $cfgSources[$addressbook]['admin']))) {
        return PEAR::raiseError(_("Address book is read-only."), HORDE_ERROR, null, null, $addressbook);
    }

    $driver = &Turba_Source::singleton($addressbook, $cfgSources[$addressbook]);
    $res = $driver->search(array('email' => trim($address), 'name' => trim($name)), null, TURBA_SEARCH_AND);
    if (PEAR::isError($res)) {
        return PEAR::raiseError(_("Error while searching directory."), HORDE_MESSAGE, null, null, $addressbook);
    } elseif ($res->count() > 0) {
        $res2 = $driver->search(array('email' => $address, 'name' => $name, $field => $value), 'lastname', TURBA_SEARCH_AND);
        if (PEAR::isError($res2)) {
            return PEAR::raiseError(_("Error while searching directory."), HORDE_MESSAGE, null, null, $addressbook);
        } elseif ($res2->count() > 0) {
            return PEAR::raiseError(sprintf(_("This person already has a %s entry in the address book."), $field), HORDE_MESSAGE, null, null, $addressbook);
        } else {
            $ob = $res->next();
            $ob->setValue($field, $value);
            $ob->store();
        }
    } else {
        return $driver->addObject(array('email' => $address, 'name' => $name, $field => $value, '__owner' => Auth::getAuth()));
    }

    return;
}

function turbaGetField($address = '', $field = '', $addressbooks = array())
{
    include TURBA_BASE . '/config/attributes.php';
    require_once TURBA_BASE . '/lib/Source.php';
    require_once 'PEAR.php';
    global $cfgSources;

    if (empty($address)) {
        return PEAR::raiseError(_("Invalid email."), HORDE_ERROR);
    }

    if (!isset($cfgSources) || !is_array($cfgSources) || !count($cfgSources)) {
        return array();
    }

    if (count($addressbooks) == 0) {
        $addressbooks = array(key($cfgSources));
    }

    $count = 0;
    foreach ($addressbooks as $source) {
        if (isset($cfgSources[$source])) {
            $driver = &Turba_Source::singleton($source, $cfgSources[$source]);
            if (PEAR::isError($driver)) {
                return PEAR::raiseError(_("Failed to connect to the specified directory."), HORDE_ERROR, null, null, $source);
            } else {
                $res = $driver->search(array('email' => $address));
                if (get_class($res) == 'turba_list') {
                    $count += $res->count();
                    if ($res->count() == 1) {
                        $ob = $res->next();
                        if ($ob->hasValue($field)) {
                            $result = $ob->getValue($field);
                        }
                    }
                } else {
                    return PEAR::raiseError(_("Failed to search the specified directory."), HORDE_ERROR, null, null, $source);
                }
            }
        }
    }

    if ($count > 1) {
        return PEAR::raiseError(_("More than 1 entry returned."), HORDE_WARNING, null, null, $source);
    } elseif (!isset($result)) {
        return PEAR::raiseError(sprintf(_("No %s entry found for %s."), $field, $address), HORDE_WARNING, null, null, $source);
    }

    return $result;
}

function turbaListField($field = '', $addressbooks = array())
{
    include TURBA_BASE . '/config/attributes.php';
    require_once TURBA_BASE . '/lib/Source.php';
    require_once 'PEAR.php';
    global $cfgSources;

    $results = array();

    if (!isset($cfgSources) || !is_array($cfgSources) || !count($cfgSources)) {
        return array();
    }

    if (count($addressbooks) == 0) {
        $addressbooks = array(key($cfgSources));
    }

    foreach ($addressbooks as $source) {
        if (isset($cfgSources[$source])) {
            $driver = &Turba_Source::singleton($source, $cfgSources[$source]);
            if (PEAR::isError($driver)) {
                return PEAR::raiseError(_("Failed to connect to the specified directory."), HORDE_ERROR, null, null, $source);
            } else {
                $res = $driver->search(array());
                if (get_class($res) == 'turba_list') {
                    while ($ob = $res->next()) {
                        if ($ob->hasValue($field)) {
                            $results[$ob->getValue('email')]['name'] = $ob->getValue('name');
                            $results[$ob->getValue('email')][$field] = $ob->getValue($field);
                        }
                    }
                } else {
                    return PEAR::raiseError(_("Failed to search the specified directory."), HORDE_ERROR, null, null, $source);
                }
            }
        }
    }

    return $results;
}

function turbaDeleteField($address = '', $field = '', $addressbooks = array())
{
    include TURBA_BASE . '/config/attributes.php';
    require_once TURBA_BASE . '/lib/Source.php';
    require_once 'PEAR.php';
    global $cfgSources;

    if (empty($address)) {
        return PEAR::raiseError(_("Invalid email."), HORDE_ERROR);
    }

    if (!isset($cfgSources) || !is_array($cfgSources) || !count($cfgSources)) {
        return array();
    }

    if (count($addressbooks) == 0) {
        $addressbooks = array(key($cfgSources));
    }

    foreach ($addressbooks as $source) {
        if (isset($cfgSources[$source])) {
            $driver = &Turba_Source::singleton($source, $cfgSources[$source]);
            if (PEAR::isError($driver)) {
                return PEAR::raiseError(_("Failed to connect to the specified directory."), HORDE_ERROR, null, null, $source);
            } else {
                $res = $driver->search(array('email' => $address));
                if (get_class($res) == 'turba_list') {
                    if ($res->count() > 1) {
                        return PEAR::raiseError(_("More than 1 entry returned."), HORDE_ERROR, null, null, $source);
                    } else {
                        $ob = $res->next();
                        if (is_object($ob) && $ob->hasValue($field)) {
                            $ob->setValue($field, '');
                            $ob->store();
                        } else {
                            return PEAR::raiseError(sprintf(_("No %s entry found for %s."), $field, $address), HORDE_ERROR, null, null, $source);
                        }
                    }
                }
            }
        }
    }

    return;
}
