506 lines
22 KiB
PHP
506 lines
22 KiB
PHP
<?php
|
|
/**
|
|
* The Turba_View_Browse class provides the logic for browsing lists
|
|
* of contacts.
|
|
*
|
|
* Copyright 2000-2017 Horde LLC (http://www.horde.org/)
|
|
*
|
|
* See the enclosed file LICENSE for license information (ASL). If you did
|
|
* did not receive this file, see http://www.horde.org/licenses/apache.
|
|
*
|
|
* @author Chuck Hagenbuch <chuck@horde.org>
|
|
* @package Turba
|
|
*/
|
|
class Turba_View_Browse
|
|
{
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $_params;
|
|
|
|
/**
|
|
* Constructor;
|
|
*
|
|
* @param array $params Stuff to import into the view's scope.
|
|
*/
|
|
public function __construct(array $params)
|
|
{
|
|
$this->_params = $params;
|
|
}
|
|
|
|
public function updateSortOrderFromVars()
|
|
{
|
|
extract($this->_params, EXTR_REFS);
|
|
Turba::setPreferredSortOrder($vars, $source);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
$max_contacts = Turba::getExtendedPermission($targetDriver, 'max_contacts');
|
|
if ($max_contacts !== true &&
|
|
$max_contacts <= count($targetDriver)) {
|
|
Horde::permissionDeniedError(
|
|
'turba',
|
|
'max_contacts',
|
|
sprintf(_("You are not allowed to create more than %d contacts in \"%s\"."), $max_contacts, $cfgSources[$targetSource]['title'])
|
|
);
|
|
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');
|
|
$targetKey = $vars->get('targetList');
|
|
if (empty($targetKey)) {
|
|
break;
|
|
}
|
|
|
|
if (!$vars->exists('targetNew') || $vars->get('targetNew') == '') {
|
|
list($targetSource, $targetKey) = explode(':', $targetKey, 2);
|
|
if (!isset($cfgSources[$targetSource])) {
|
|
break;
|
|
}
|
|
|
|
try {
|
|
$targetDriver = $factory->create($targetSource);
|
|
} catch (Turba_Exception $e) {
|
|
$notification->push($e, 'horde.error');
|
|
break;
|
|
}
|
|
|
|
try {
|
|
$target = $targetDriver->getObject($targetKey);
|
|
} catch (Horde_Exception $e) {
|
|
$notification->push($e);
|
|
break;
|
|
}
|
|
} else {
|
|
$targetSource = $vars->get('targetAddressbook');
|
|
try {
|
|
$targetDriver = $factory->create($targetSource);
|
|
} catch (Turba_Exception $e) {
|
|
$notification->push($e, 'horde.error');
|
|
break;
|
|
}
|
|
}
|
|
if (!empty($target) && $target->isGroup()) {
|
|
// Adding contact to an existing list.
|
|
if (is_array($keys)) {
|
|
$errorCount = 0;
|
|
foreach ($keys as $sourceKey) {
|
|
list($objectSource, $objectKey) = explode(':', $sourceKey, 2);
|
|
try {
|
|
$target->addMember($objectKey, $objectSource);
|
|
} catch (Turba_Exception $e) {
|
|
$notification->push($e, 'horde.error');
|
|
$errorCount++;
|
|
}
|
|
}
|
|
if (!$errorCount) {
|
|
$notification->push(
|
|
sprintf(_("Successfully added %d contact(s) to list."),
|
|
count($keys)),
|
|
'horde.success');
|
|
} elseif ($errorCount == count($keys)) {
|
|
$notification->push(
|
|
sprintf(_("Error adding %d contact(s) to list."),
|
|
count($keys)),
|
|
'horde.error');
|
|
} else {
|
|
$notification->push(
|
|
sprintf(_("Error adding %d of %d requested contact(s) to list."),
|
|
$errorCount,
|
|
count($keys)),
|
|
'horde.error');
|
|
}
|
|
$target->store();
|
|
}
|
|
} else {
|
|
// Check permissions.
|
|
$max_contacts = Turba::getExtendedPermission($driver, 'max_contacts');
|
|
if ($max_contacts !== true &&
|
|
$max_contacts <= count($driver)) {
|
|
Horde::permissionDeniedError(
|
|
'turba',
|
|
'max_contacts',
|
|
sprintf(_("You are not allowed to create more than %d contacts in \"%s\"."),
|
|
$max_contacts,
|
|
$cfgSources[$source]['title'])
|
|
);
|
|
break;
|
|
}
|
|
|
|
// Adding contact to a new list.
|
|
$newList = array(
|
|
'__owner' => $targetDriver->getContactOwner(),
|
|
'__type' => 'Group',
|
|
'name' => $targetKey
|
|
);
|
|
|
|
try {
|
|
$targetKey = $targetDriver->add($newList);
|
|
} catch (Turba_Exception $e) {
|
|
$notification->push(_("There was an error creating a new list."), 'horde.error');
|
|
$targetKey = null;
|
|
}
|
|
|
|
if ($targetKey) {
|
|
try {
|
|
$target = $targetDriver->getObject($targetKey);
|
|
if ($target->isGroup()) {
|
|
$notification->push(
|
|
sprintf(_("Successfully created the contact list \"%s\"."),
|
|
$newList['name']),
|
|
'horde.success');
|
|
if (is_array($keys)) {
|
|
$errorCount = 0;
|
|
foreach ($keys as $sourceKey) {
|
|
list($objectSource, $objectKey) = explode(':', $sourceKey, 2);
|
|
try {
|
|
$target->addMember($objectKey, $objectSource);
|
|
} catch (Turba_Exception $e) {
|
|
$notification->push($e, 'horde.error');
|
|
++$errorCount;
|
|
}
|
|
}
|
|
if (!$errorCount) {
|
|
$notification->push(
|
|
sprintf(_("Successfully added %d contact(s) to list."),
|
|
count($keys)),
|
|
'horde.success');
|
|
} elseif ($errorCount == count($keys)) {
|
|
$notification->push(
|
|
sprintf(_("Error adding %d contact(s) to list."),
|
|
count($keys)),
|
|
'horde.error');
|
|
} else {
|
|
$notification->push(
|
|
sprintf(_("Error adding %d of %d requested contact(s) to list."),
|
|
$errorCount,
|
|
count($keys)),
|
|
'horde.error');
|
|
}
|
|
$target->store();
|
|
}
|
|
}
|
|
} catch (Turba_Exception $e) {}
|
|
}
|
|
}
|
|
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();
|
|
}
|
|
|
|
}
|