/* Perform a search. */ if ($search_mode == 'duplicate') { try { $duplicates = $driver->searchDuplicates(); $view = new Turba_View_Duplicates($duplicates, $driver, $vars->type, $vars->dupe); $page_output->addScriptFile('tables.js', 'horde'); } catch (Exception $e) { $notification->push($e); } } else { try { if ($search_mode == 'basic' && ($results = $driver->search($criteria, null, 'OR')) || $search_mode == 'advanced' && ($results = $driver->search($criteria))) { /* Read the columns to display from the preferences. */ $sources = Turba::getColumns(); $columns = isset($sources[$source]) ? $sources[$source] : array(); $results->sort(Turba::getPreferredSortOrder()); $view = new Turba_View_List($results, null, $columns); $view->setType('search'); } else { $notification->push(_("Failed to search the address book"), 'horde.error'); } } catch (Turba_Exception $e) { $notification->push($e, 'horde.error'); } } } } /* Build search mode tabs. */ $sUrl = Horde::url('search.php'); $tabs = new Horde_Core_Ui_Tabs('search_mode', $vars); $tabs->addTab(_("Basic Search"), $sUrl, 'basic');
public function run() { extract($this->_params, EXTR_REFS); $this->updateSortOrderFromVars(); $title = _("Address Book Listing"); if (!$browse_source_count && $vars->get('key') != '**search') { $notification->push(_("There are no browseable address books."), 'horde.warning'); } else { try { $driver = $factory->create($source); } catch (Turba_Exception $e) { $notification->push($e, 'horde.error'); unset($driver); } } if (isset($driver)) { $actionID = $vars->get('actionID'); switch ($actionID) { case 'delete': $keys = $vars->get('objectkeys'); if (!is_array($keys)) { break; } $key = false; if ($vars->exists('key')) { $key = $vars->get('key'); } if ($key && $key != '**search') { // We are removing a contact from a list. $errorCount = 0; $list = $driver->getObject($key); foreach ($keys as $sourceKey) { list($objectSource, $objectKey) = explode(':', $sourceKey, 2); if (!$list->removeMember($objectKey, $objectSource)) { $errorCount++; } } if (!$errorCount) { $notification->push(sprintf(_("Successfully removed %d contact(s) from list."), count($keys)), 'horde.success'); } elseif (count($keys) == $errorCount) { $notification->push(sprintf(_("Error removing %d contact(s) from list."), count($keys)), 'horde.error'); } else { $notification->push(sprintf(_("Error removing %d of %d requested contact(s) from list."), $errorCount, count($keys)), 'horde.error'); } $list->store(); } else { // We are deleting an object. $errorCount = 0; foreach ($keys as $sourceKey) { list($objectSource, $objectKey) = explode(':', $sourceKey, 2); try { $driver->delete($objectKey); } catch (Turba_Exception $e) { ++$errorCount; } } if (!$errorCount) { $notification->push(sprintf(ngettext("Successfully deleted %d contact.", "Successfully deleted %d contacts.", count($keys)), count($keys)), 'horde.success'); } elseif (count($keys) == $errorCount) { $notification->push(sprintf(ngettext("Error deleting %d contact.", "Error deleting %d contacts.", count($keys)), count($keys)), 'horde.error'); } else { $notification->push(sprintf(ngettext("Error deleting %d of %d requested contact.", "Error deleting %d of %d requested contacts.", count($keys)), $errorCount, count($keys)), 'horde.error'); } } break; case 'move': case 'copy': $keys = $vars->get('objectkeys'); if (!(is_array($keys) && $keys)) { break; } // If we have data, try loading the target address book driver. $targetSource = $vars->get('targetAddressbook'); try { $targetDriver = $factory->create($targetSource); } catch (Turba_Exception $e) { $notification->push($e, 'horde.error'); break; } if (Turba::hasMaxContacts($targetDriver)) { break; } foreach ($keys as $sourceKey) { // Split up the key into source and object ids. list($objectSource, $objectKey) = explode(':', $sourceKey, 2); // Ignore this entry if the target is the same as the // source. if ($objectSource == $targetDriver->getName()) { continue; } // Try and load the driver for the source. try { $sourceDriver = $factory->create($objectSource); } catch (Turba_Exception $e) { $notification->push($e, 'horde.error'); continue; } try { $object = $sourceDriver->getObject($objectKey); } catch (Horde_Exception_NotFound $e) { $notification->push(_("Failed to find object to be added"), 'horde.error'); continue; } if ($object->isGroup()) { if ($actionID == 'move') { $notification->push(sprintf(_("\"%s\" was not moved because it is a list."), $object->getValue('name')), 'horde.warning'); } else { $notification->push(sprintf(_("\"%s\" was not copied because it is a list."), $object->getValue('name')), 'horde.warning'); } continue; } // Try adding to the target. $objAttributes = array(); // Get the values through the Turba_Object class. foreach (array_keys($targetDriver->getCriteria()) as $info_key) { if (!is_array($targetDriver->map[$info_key]) || isset($targetDriver->map[$info_key]['attribute'])) { $objectValue = $object->getValue($info_key); // Get 'data' value if object type is image, the // direct value in other case. $objAttributes[$info_key] = isset($attributes[$info_key]) && $attributes[$info_key]['type'] == 'image' ? $objectValue['load']['data'] : $objectValue; } } unset($objAttributes['__owner']); if ($actionID == 'copy') { unset($objAttributes['__uid']); } // Try adding tags. $objAttributes['__tags'] = $object->getValue('__tags'); try { $targetDriver->add($objAttributes); } catch (Turba_Exception $e) { $notification->push(sprintf(_("Failed to add %s to %s: %s"), $object->getValue('name'), $targetDriver->title, $e), 'horde.error'); break; } $notification->push(sprintf(_("Successfully added %s to %s"), $object->getValue('name'), $targetDriver->title), 'horde.success'); // If we're moving objects, and we succeeded, // delete them from the original source now. if ($actionID == 'move') { try { $sourceDriver->delete($objectKey, false); } catch (Turba_Exception $e) { $notification->push(sprintf(_("There was an error deleting \"%s\" from the source address book."), $object->getValue('name')), 'horde.error'); } /* Log the adding of this item in the history again, * because otherwise the delete log would be after the * add log. */ try { $history->log('turba:' . $targetDriver->getName() . ':' . $objAttributes['__uid'], array('action' => 'add'), true); } catch (Exception $e) { Horde::log($e, 'ERR'); } } } break; case 'add': // Add a contact to a list. $keys = $vars->get('objectkeys'); if (!($targetKey = $vars->get('targetList'))) { break; } $args = array(); if (strlen($vars->get('targetNew'))) { $targetSource = $vars->get('targetAddressbook'); $args['attr'] = array('name' => $targetKey); } else { list($targetSource, $args['gid']) = explode(':', $targetKey, 2); if (!isset($cfgSources[$targetSource])) { break; } } $members = array(); foreach ($keys as $key) { $members[] = explode(':', $key, 2); } try { $res = Turba_Object_Group::createGroup($targetSource, $members, $args); } catch (Turba_Exception $e) { $notification->push($e, 'horde.error'); break; } if (isset($args['name'])) { $notification->push(sprintf(_("Successfully created the contact list \"%s\"."), $args['name']), 'horde.success'); } if (!empty($res->error)) { if ($res->success) { $notification->push(sprintf(_("Error adding %d of %d requested contact(s) to list."), count($res->error), count($res->error) + $res->success), 'horde.error'); } else { $notification->push(sprintf(_("Error adding %d contact(s) to list."), count($res->error)), 'horde.error'); } } elseif ($res->success) { $notification->push(sprintf(_("Successfully added %d contact(s) to list."), $res->success), 'horde.success'); } break; } // We might get here from the search page but are not allowed to // browse the current address book. if ($actionID && empty($cfgSources[$source]['browse'])) { Horde::url($prefs->getValue('initial_page'), true)->redirect(); } } $templates = array(); if (isset($driver)) { Turba::addBrowseJs(); // Read the columns to display from the preferences. $sources = Turba::getColumns(); $columns = isset($sources[$source]) ? $sources[$source] : array(); $sortorder = Turba::getPreferredSortOrder(); if ($vars->get('key')) { // We are displaying a list. try { $list = $driver->getObject($vars->get('key')); } catch (Horde_Exception $e) { $notification->push(_("There was an error displaying the list"), 'horde.error'); $list = null; } if ($list && $list->isGroup()) { $title = sprintf(_("Contacts in list: %s"), $list->getValue('name')); $templates[] = '/browse/header.inc'; // Show List Members. try { $results = $list->listMembers($sortorder); if (count($results) != $list->count()) { $count = $list->count() - count($results); $notification->push(sprintf(ngettext("There is %d contact in this list that is not viewable to you", "There are %d contacts in this list that are not viewable to you", $count), $count), 'horde.message'); } $view = new Turba_View_List($results, null, $columns); $view->setType('list'); } catch (Turba_Exception $e) { $notification->push(_("Failed to browse list"), 'horde.error'); } } } else { // We are displaying an address book. $title = $cfgSources[$source]['title']; $templates[] = '/browse/header.inc'; if (empty($cfgSources[$source]['browse'])) { $notification->push(_("Your default address book is not browseable."), 'horde.warning'); } else { $type_filter = array(); switch ($vars->get('show')) { case 'contacts': $type_filter = array('__type' => 'Object'); break; case 'lists': $type_filter = array('__type' => 'Group'); break; } try { $results = $driver->search($type_filter, $sortorder, 'AND', array_merge(array('__uid'), $columns ? $columns : array('name'))); $view = new Turba_View_List($results, null, $columns); $view->setType('directory'); } catch (Turba_Exception $e) { $notification->push($e, 'horde.error'); } } } } else { $templates[] = '/browse/header.inc'; } $page_output->addScriptFile('quickfinder.js', 'horde'); $page_output->addScriptFile('scriptaculous/effects.js', 'horde'); $page_output->addScriptFile('redbox.js', 'horde'); $page_output->header(array('title' => $title)); $notification->notify(array('listeners' => 'status')); foreach ($templates as $template) { require TURBA_TEMPLATES . $template; } if (isset($view) && is_object($view)) { $view->display(); } $page_output->footer(); }
/** * Returns a contact search result. * * @param mixed $names The search filter values. * @param array $opts Optional parameters: * - customStrict: (array) An array of fields that must match exactly. * DEFAULT: None * - fields: (array) The fields to search on. * DEFAULT: Search all configured search fields. * - forceSource: (boolean) Whether to use the specified sources, even * if they have been disabled in the preferences? * DEFAULT: false * - matchBegin: (boolean) Match word boundaries only? * DEFAULT: false * - returnFields: Only return these fields. * DEFAULT: Return all fields. * - rfc822Return: Return a Horde_Mail_Rfc822_List object. * DEFAULT: Returns an array of search results. * - sources: (array) The sources to search in. * DEFAULT: Search the user's default address book * - count_only: (boolean) If true, only return the count of matching * results. * DEFAULT: false (Return the full data set). * * @return mixed Either a hash containing the search results or a * Rfc822 List object (if 'rfc822Return' is true). * @throws Turba_Exception */ public function search($names = null, array $opts = array()) { global $attributes, $cfgSources, $injector; $opts = array_merge(array('fields' => array(), 'forceSource' => false, 'matchBegin' => false, 'returnFields' => array(), 'rfc822Return' => false, 'sources' => array(), 'customStrict' => array(), 'count_only' => false), $opts); $results = !empty($opts['count_only']) ? 0 : (empty($opts['rfc822Return']) ? array() : new Horde_Mail_Rfc822_List()); if (!isset($cfgSources) || !is_array($cfgSources) || !count($cfgSources) || is_null($names)) { return $results; } if (!is_array($names)) { $names = array($names); } if (!$opts['forceSource']) { // Make sure the selected source is activated in Turba. $addressbooks = array_keys(Turba::getAddressBooks()); foreach (array_keys($opts['sources']) as $id) { if (!in_array($opts['sources'][$id], $addressbooks)) { unset($opts['sources'][$id]); } } } // ...and ensure the default source is used as a default. if (!count($opts['sources'])) { $opts['sources'] = array(Turba::getDefaultAddressbook()); } $driver = $injector->getInstance('Turba_Factory_Driver'); foreach ($opts['sources'] as $source) { // Skip invalid sources -or- // skip sources that aren't browseable if the search is empty. if (!isset($cfgSources[$source]) || empty($cfgSources[$source]['browse']) && (!count($names) || count($names) == 1 && empty($names[0]))) { continue; } if (empty($opts['fields'][$source])) { $opts['fields'][$source] = $GLOBALS['cfgSources'][$source]['search']; } $sdriver = $driver->create($source); foreach ($names as $name) { $trimname = trim($name); $out = $criteria = array(); unset($tname); if (strlen($trimname)) { if (isset($opts['fields'][$source])) { foreach ($opts['fields'][$source] as $field) { $criteria[$field] = $trimname; } } } try { $search = $sdriver->search($criteria, Turba::getPreferredSortOrder(), 'OR', $opts['returnFields'], $opts['customStrict'], $opts['matchBegin'], $opts['count_only']); } catch (Exception $e) { continue; } if ($opts['count_only']) { $results += $search; continue; } elseif (!$search instanceof Turba_List) { continue; } $rfc822 = new Horde_Mail_Rfc822(); while ($ob = $search->next()) { $emails = $seen = array(); if ($ob->isGroup()) { /* Is a distribution list. */ $members = $ob->listMembers(); if (!$members instanceof Turba_List || !count($members)) { continue; } $listatt = $ob->getAttributes(); $listName = $ob->getValue('name'); while ($ob = $members->next()) { foreach (array_keys($ob->getAttributes()) as $key) { $value = $ob->getValue($key); if (empty($value)) { continue; } $seen_key = trim(Horde_String::lower($ob->getValue('name'))) . trim(Horde_String::lower(is_array($value) ? $value['load']['file'] : $value)); if (isset($attributes[$key]) && $attributes[$key]['type'] == 'email' && empty($seen[$seen_key])) { $emails[] = $value; $seen[$seen_key] = true; } } } if (empty($opts['rfc822Return'])) { $out[] = array('email' => implode(', ', $emails), 'id' => $listatt['__key'], 'name' => $listName, 'source' => $source); } else { $results->add(new Horde_Mail_Rfc822_Group($listName, $emails)); } } else { /* Not a group. */ $att = array('__key' => $ob->getValue('__key')); foreach (array_keys($ob->driver->getCriteria()) as $key) { $att[$key] = $ob->getValue($key); } $email = new Horde_Mail_Rfc822_List(); $display_name = $ob->hasValue('name') || !isset($ob->driver->alternativeName) ? Turba::formatName($ob) : $ob->getValue($ob->driver->alternativeName); unset($tdisplay_name); foreach (array_keys($att) as $key) { if ($ob->getValue($key) && isset($attributes[$key]) && $attributes[$key]['type'] == 'email') { $e_val = $ob->getValue($key); if (strlen($trimname)) { /* Ticket #12480: Don't return email if it * doesn't contain the search string, since * an entry can contain multiple e-mail * fields. Return all e-mails if it * occurs in the name. */ if (!isset($tname)) { $tname = Horde_String_Transliterate::toAscii($name); } if (!isset($tdisplay_name)) { $tdisplay_name = Horde_String_Transliterate::toAscii($display_name); } $add = Horde_String::ipos(Horde_String_Transliterate::toAscii($e_val), $tname) !== false || Horde_String::ipos($tdisplay_name, $tname) !== false; } else { $add = true; } if ($add) { // Multiple addresses support $email->add($rfc822->parseAddressList($e_val, array('limit' => isset($attributes[$key]['params']) && is_array($attributes[$key]['params']) && !empty($attributes[$key]['params']['allow_multi']) ? 0 : 1))); } } } if (count($email)) { foreach ($email as $val) { $seen_key = trim(Horde_String::lower($display_name)) . '/' . Horde_String::lower($val->bare_address); if (empty($seen[$seen_key])) { $seen[$seen_key] = true; if (empty($opts['rfc822Return'])) { $emails[] = $val->bare_address; } else { $val->personal = $display_name; $results->add($val); } } } } elseif (empty($opts['rfc822Return'])) { $emails[] = null; } if (empty($opts['rfc822Return'])) { foreach ($emails as $val) { $out[] = array_merge($att, array('__type' => 'Object', 'email' => $val, 'id' => $att['__key'], 'name' => $display_name, 'source' => $source)); } } } } if (!empty($out)) { $results[$name] = $out; } } } return $results; }
/** * Retrieves a natural language description of the sort order * * @return string */ public function getSortOrderDescription() { $description = array(); $sortorder = Turba::getPreferredSortOrder(); foreach ($sortorder as $elt) { $field = $elt['field']; if (!strlen($field) || $field == 'lastname') { $field = 'name'; } $description[] = $GLOBALS['attributes'][$field]['label']; } return join(', ', $description); }