mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-25 09:23:28 +01:00
move addresbook_bo to Api\Contacts, ldap to Api\Ldap, ldapserverinfo to Api\Ldap\ServerInfo, bo_tracking to Api\Storage\Tracking, historylog to Api\Storage\History, Api\Customfields to Api\Storage\Customfields
This commit is contained in:
parent
fcca19cfcf
commit
7ada2354d3
File diff suppressed because it is too large
Load Diff
@ -5,11 +5,13 @@
|
|||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @package addressbook
|
* @package addressbook
|
||||||
* @copyright (c) 2007-15 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @copyright (c) 2007-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use EGroupware\Api;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SiteMgr contact form for the addressbook
|
* SiteMgr contact form for the addressbook
|
||||||
*
|
*
|
||||||
@ -75,7 +77,7 @@ class addressbook_contactform
|
|||||||
elseif ($content['submitit'])
|
elseif ($content['submitit'])
|
||||||
{
|
{
|
||||||
$submitted = true;
|
$submitted = true;
|
||||||
$contact = new addressbook_bo();
|
$contact = new Api\Contacts();
|
||||||
if ($content['owner']) // save the contact in the addressbook
|
if ($content['owner']) // save the contact in the addressbook
|
||||||
{
|
{
|
||||||
$content['private'] = 0; // in case default_private is set
|
$content['private'] = 0; // in case default_private is set
|
||||||
@ -90,9 +92,9 @@ class addressbook_contactform
|
|||||||
// the anonymous user to have run rights for addressbook AND
|
// the anonymous user to have run rights for addressbook AND
|
||||||
// edit rights for the addressbook used to store the new entry,
|
// edit rights for the addressbook used to store the new entry,
|
||||||
// which is clearly not wanted securitywise
|
// which is clearly not wanted securitywise
|
||||||
egw_vfs::$is_root = true;
|
Api\Vfs::$is_root = true;
|
||||||
egw_link::link('addressbook',$id,egw_link::VFS_APPNAME,$value,$name);
|
egw_link::link('addressbook',$id,egw_link::VFS_APPNAME,$value,$name);
|
||||||
egw_vfs::$is_root = false;
|
Api\Vfs::$is_root = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,8 +110,7 @@ class addressbook_contactform
|
|||||||
{
|
{
|
||||||
if ($content['email_contactform'])
|
if ($content['email_contactform'])
|
||||||
{
|
{
|
||||||
require_once(EGW_INCLUDE_ROOT.'/addressbook/inc/class.addressbook_tracking.inc.php');
|
$tracking = new Api\Contacts\Tracking($contact);
|
||||||
$tracking = new addressbook_tracking($contact);
|
|
||||||
}
|
}
|
||||||
if ($tracking->do_notifications($contact->data2db($content),null))
|
if ($tracking->do_notifications($contact->data2db($content),null))
|
||||||
{
|
{
|
||||||
@ -141,7 +142,7 @@ class addressbook_contactform
|
|||||||
static $contact;
|
static $contact;
|
||||||
if (is_null($contact))
|
if (is_null($contact))
|
||||||
{
|
{
|
||||||
$contact = new addressbook_bo();
|
$contact = new Api\Contacts();
|
||||||
}
|
}
|
||||||
$content['show']['custom'.$custom] = true;
|
$content['show']['custom'.$custom] = true;
|
||||||
$content['customfield'][$custom] = $name;
|
$content['customfield'][$custom] = $name;
|
||||||
@ -174,7 +175,7 @@ class addressbook_contactform
|
|||||||
if ($name[0] == '#') // custom field
|
if ($name[0] == '#') // custom field
|
||||||
{
|
{
|
||||||
static $contact;
|
static $contact;
|
||||||
if (is_null($contact)) $contact = new addressbook_bo();
|
if (is_null($contact)) $contact = new Api\Contacts();
|
||||||
$content['show']['custom'.$custom] = true;
|
$content['show']['custom'.$custom] = true;
|
||||||
$content['customfield'][$custom] = $name;
|
$content['customfield'][$custom] = $name;
|
||||||
$content['customlabel'][$custom] = $contact->customfields[substr($name,1)]['label'];
|
$content['customlabel'][$custom] = $contact->customfields[substr($name,1)]['label'];
|
||||||
|
@ -7,10 +7,12 @@
|
|||||||
* @package addressbook
|
* @package addressbook
|
||||||
* @subpackage groupdav
|
* @subpackage groupdav
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @copyright (c) 2007-15 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @copyright (c) 2007-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use EGroupware\Api;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EGroupware: GroupDAV access: addressbook handler
|
* EGroupware: GroupDAV access: addressbook handler
|
||||||
*
|
*
|
||||||
@ -953,7 +955,7 @@ class addressbook_groupdav extends groupdav_handler
|
|||||||
if (is_null($non_deleted_tids))
|
if (is_null($non_deleted_tids))
|
||||||
{
|
{
|
||||||
$non_deleted_tids = $this->bo->content_types;
|
$non_deleted_tids = $this->bo->content_types;
|
||||||
unset($non_deleted_tids[addressbook_so::DELETED_TYPE]);
|
unset($non_deleted_tids[Api\Contacts::DELETED_TYPE]);
|
||||||
$non_deleted_tids = array_keys($non_deleted_tids);
|
$non_deleted_tids = array_keys($non_deleted_tids);
|
||||||
}
|
}
|
||||||
$contact = $this->bo->read(array(self::$path_attr => $id, 'tid' => $non_deleted_tids));
|
$contact = $this->bo->read(array(self::$path_attr => $id, 'tid' => $non_deleted_tids));
|
||||||
@ -1000,7 +1002,7 @@ class addressbook_groupdav extends groupdav_handler
|
|||||||
$contact = null;
|
$contact = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($contact && $contact['tid'] == addressbook_so::DELETED_TYPE)
|
if ($contact && $contact['tid'] == Api\Contacts::DELETED_TYPE)
|
||||||
{
|
{
|
||||||
$contact = null; // handle deleted events, as not existing (404 Not Found)
|
$contact = null; // handle deleted events, as not existing (404 Not Found)
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* eGroupWare
|
* EGroupware Addressbook
|
||||||
*
|
*
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @package importexport
|
* @package importexport
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Cornelius Weiss <nelius@cwtech.de>
|
* @author Cornelius Weiss <nelius@cwtech.de>
|
||||||
* @copyright Cornelius Weiss <nelius@cwtech.de>
|
* @copyright Cornelius Weiss <nelius@cwtech.de>
|
||||||
* @version $Id: $
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use EGroupware\Api;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class import_csv for addressbook
|
* class import_csv for addressbook
|
||||||
@ -30,6 +31,8 @@ class addressbook_import_contacts_csv extends importexport_basic_import_csv {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* For figuring out if a contact has changed
|
* For figuring out if a contact has changed
|
||||||
|
*
|
||||||
|
* @var Api\Contacts\Tracking
|
||||||
*/
|
*/
|
||||||
protected $tracking;
|
protected $tracking;
|
||||||
|
|
||||||
@ -48,10 +51,10 @@ class addressbook_import_contacts_csv extends importexport_basic_import_csv {
|
|||||||
public function init(importexport_definition &$_definition ) {
|
public function init(importexport_definition &$_definition ) {
|
||||||
|
|
||||||
// fetch the addressbook bo
|
// fetch the addressbook bo
|
||||||
$this->bocontacts = new addressbook_bo();
|
$this->bocontacts = new Api\Contacts();
|
||||||
|
|
||||||
// Get the tracker for changes
|
// Get the tracker for changes
|
||||||
$this->tracking = new addressbook_tracking($this->bocontacts);
|
$this->tracking = new Api\Contacts\Tracking($this->bocontacts);
|
||||||
|
|
||||||
$this->lookups = array(
|
$this->lookups = array(
|
||||||
'tid' => array('n'=>'contact')
|
'tid' => array('n'=>'contact')
|
||||||
@ -138,10 +141,10 @@ class addressbook_import_contacts_csv extends importexport_basic_import_csv {
|
|||||||
// Also handle categories in their own field
|
// Also handle categories in their own field
|
||||||
$record_array = $record->get_record_array();
|
$record_array = $record->get_record_array();
|
||||||
$more_categories = array();
|
$more_categories = array();
|
||||||
foreach($this->definition->plugin_options['field_mapping'] as $number => $field_name) {
|
foreach($this->definition->plugin_options['field_mapping'] as $field_name) {
|
||||||
if(!array_key_exists($field_name, $record_array) ||
|
if(!array_key_exists($field_name, $record_array) ||
|
||||||
substr($field_name,0,3) != 'cat' || !$record->$field_name || $field_name == 'cat_id') continue;
|
substr($field_name,0,3) != 'cat' || !$record->$field_name || $field_name == 'cat_id') continue;
|
||||||
list($cat, $cat_id) = explode('-', $field_name);
|
list(, $cat_id) = explode('-', $field_name);
|
||||||
if(is_numeric($record->$field_name) && $record->$field_name != 1) {
|
if(is_numeric($record->$field_name) && $record->$field_name != 1) {
|
||||||
// Column has a single category ID
|
// Column has a single category ID
|
||||||
$more_categories[] = $record->$field_name;
|
$more_categories[] = $record->$field_name;
|
||||||
@ -175,7 +178,7 @@ class addressbook_import_contacts_csv extends importexport_basic_import_csv {
|
|||||||
if($record_array[$condition['string']]) {
|
if($record_array[$condition['string']]) {
|
||||||
$searchcondition = array( $condition['string'] => $record_array[$condition['string']]);
|
$searchcondition = array( $condition['string'] => $record_array[$condition['string']]);
|
||||||
// if we use account_id for the condition, we need to set the owner for filtering, as this
|
// if we use account_id for the condition, we need to set the owner for filtering, as this
|
||||||
// enables addressbook_so to decide what backend is to be used
|
// enables Api\Contacts\Storage to decide what backend is to be used
|
||||||
if ($condition['string']=='account_id') $searchcondition['owner']=0;
|
if ($condition['string']=='account_id') $searchcondition['owner']=0;
|
||||||
$contacts = $this->bocontacts->search(
|
$contacts = $this->bocontacts->search(
|
||||||
//array( $condition['string'] => $record[$condition['string']],),
|
//array( $condition['string'] => $record[$condition['string']],),
|
||||||
@ -204,7 +207,7 @@ class addressbook_import_contacts_csv extends importexport_basic_import_csv {
|
|||||||
break;
|
break;
|
||||||
case 'equal':
|
case 'equal':
|
||||||
// Match on field
|
// Match on field
|
||||||
$result = $this->equal($record, $condition, $matches);
|
$result = $this->equal($record, $condition);
|
||||||
if($result)
|
if($result)
|
||||||
{
|
{
|
||||||
// Apply true action to any matching records found
|
// Apply true action to any matching records found
|
||||||
@ -270,7 +273,8 @@ class addressbook_import_contacts_csv extends importexport_basic_import_csv {
|
|||||||
$old = $this->bocontacts->read($_data['id']);
|
$old = $this->bocontacts->read($_data['id']);
|
||||||
// if we get countrycodes as countryname, try to translate them -> the rest should be handled by bo classes.
|
// if we get countrycodes as countryname, try to translate them -> the rest should be handled by bo classes.
|
||||||
foreach(array('adr_one_', 'adr_two_') as $c_prefix) {
|
foreach(array('adr_one_', 'adr_two_') as $c_prefix) {
|
||||||
if (strlen(trim($_data[$c_prefix.'countryname']))==2) $_data[$c_prefix.'countryname'] = $GLOBALS['egw']->country->get_full_name(trim($_data[$c_prefix.'countryname']),$translated=true);
|
if (strlen(trim($_data[$c_prefix.'countryname']))==2)
|
||||||
|
$_data[$c_prefix.'countryname'] = $GLOBALS['egw']->country->get_full_name(trim($_data[$c_prefix.'countryname']), true);
|
||||||
}
|
}
|
||||||
// Don't change a user account into a contact
|
// Don't change a user account into a contact
|
||||||
if($old['owner'] == 0) {
|
if($old['owner'] == 0) {
|
||||||
@ -412,4 +416,3 @@ class addressbook_import_contacts_csv extends importexport_basic_import_csv {
|
|||||||
return $this->results;
|
return $this->results;
|
||||||
}
|
}
|
||||||
} // end of iface_export_plugin
|
} // end of iface_export_plugin
|
||||||
?>
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1138,9 +1138,9 @@ window.egw_LAB.wait(function() {
|
|||||||
if ($contact['owner'] || // regular contact or
|
if ($contact['owner'] || // regular contact or
|
||||||
empty($contact['account_id']) || // accounts without account_id
|
empty($contact['account_id']) || // accounts without account_id
|
||||||
// already deleted account (should no longer happen, but needed to allow for cleanup)
|
// already deleted account (should no longer happen, but needed to allow for cleanup)
|
||||||
$contact['tid'] == addressbook_so::DELETED_TYPE)
|
$contact['tid'] == self::DELETED_TYPE)
|
||||||
{
|
{
|
||||||
$Ok = $this->delete($id, $contact['tid'] != addressbook_so::DELETED_TYPE && $contact['account_id']);
|
$Ok = $this->delete($id, $contact['tid'] != self::DELETED_TYPE && $contact['account_id']);
|
||||||
}
|
}
|
||||||
// delete single account --> redirect to admin
|
// delete single account --> redirect to admin
|
||||||
elseif (count($checked) == 1 && $contact['account_id'])
|
elseif (count($checked) == 1 && $contact['account_id'])
|
||||||
@ -1684,7 +1684,7 @@ window.egw_LAB.wait(function() {
|
|||||||
{
|
{
|
||||||
$row['class'] .= 'rowAccount rowNoDelete ';
|
$row['class'] .= 'rowAccount rowNoDelete ';
|
||||||
}
|
}
|
||||||
elseif (!$this->check_perms(EGW_ACL_DELETE,$row) || (!$GLOBALS['egw_info']['user']['apps']['admin'] && $this->config['history'] != 'userpurge' && $query['col_filter']['tid'] == addressbook_so::DELETED_TYPE))
|
elseif (!$this->check_perms(EGW_ACL_DELETE,$row) || (!$GLOBALS['egw_info']['user']['apps']['admin'] && $this->config['history'] != 'userpurge' && $query['col_filter']['tid'] == self::DELETED_TYPE))
|
||||||
{
|
{
|
||||||
$row['class'] .= 'rowNoDelete ';
|
$row['class'] .= 'rowNoDelete ';
|
||||||
}
|
}
|
||||||
@ -2274,7 +2274,7 @@ window.egw_LAB.wait(function() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Links for deleted entries
|
// Links for deleted entries
|
||||||
if($content['tid'] == addressbook_so::DELETED_TYPE)
|
if($content['tid'] == self::DELETED_TYPE)
|
||||||
{
|
{
|
||||||
$content['link_to']['show_deleted'] = true;
|
$content['link_to']['show_deleted'] = true;
|
||||||
if(!$GLOBALS['egw_info']['user']['apps']['admin'] && $this->config['history'] != 'userpurge')
|
if(!$GLOBALS['egw_info']['user']['apps']['admin'] && $this->config['history'] != 'userpurge')
|
||||||
@ -2604,7 +2604,7 @@ window.egw_LAB.wait(function() {
|
|||||||
'to_id' => $content['id'],
|
'to_id' => $content['id'],
|
||||||
);
|
);
|
||||||
// Links for deleted entries
|
// Links for deleted entries
|
||||||
if($content['tid'] == addressbook_so::DELETED_TYPE)
|
if($content['tid'] == self::DELETED_TYPE)
|
||||||
{
|
{
|
||||||
$content['link_to']['show_deleted'] = true;
|
$content['link_to']['show_deleted'] = true;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* eGgroupWare admin - UI for adding custom fields
|
* EGgroupware admin - UI for adding custom fields
|
||||||
*
|
*
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
@ -10,6 +10,8 @@
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use EGroupware\Api;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Customfields class - manages customfield definitions in egw_config table
|
* Customfields class - manages customfield definitions in egw_config table
|
||||||
*
|
*
|
||||||
@ -103,10 +105,10 @@ class customfields
|
|||||||
{
|
{
|
||||||
if (($this->appname = $appname))
|
if (($this->appname = $appname))
|
||||||
{
|
{
|
||||||
$this->fields = egw_customfields::get($this->appname,true);
|
$this->fields = Api\Storage\Customfields::get($this->appname,true);
|
||||||
$this->content_types = config::get_content_types($this->appname);
|
$this->content_types = Api\Config::get_content_types($this->appname);
|
||||||
}
|
}
|
||||||
$this->so = new so_sql('phpgwapi','egw_customfields',null,'',true);
|
$this->so = new Api\Storage\Base('phpgwapi','egw_customfields',null,'',true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -121,7 +123,7 @@ class customfields
|
|||||||
$this->use_private = !isset($_GET['use_private']) || (boolean)$_GET['use_private'] || $content['use_private'];
|
$this->use_private = !isset($_GET['use_private']) || (boolean)$_GET['use_private'] || $content['use_private'];
|
||||||
|
|
||||||
// Read fields, constructor doesn't always know appname
|
// Read fields, constructor doesn't always know appname
|
||||||
$this->fields = egw_customfields::get($this->appname,true);
|
$this->fields = Api\Storage\Customfields::get($this->appname,true);
|
||||||
|
|
||||||
$this->tmpl = new etemplate_new();
|
$this->tmpl = new etemplate_new();
|
||||||
$this->tmpl->read('admin.customfields');
|
$this->tmpl->read('admin.customfields');
|
||||||
@ -135,7 +137,7 @@ class customfields
|
|||||||
{
|
{
|
||||||
if(count($this->content_types) == 0)
|
if(count($this->content_types) == 0)
|
||||||
{
|
{
|
||||||
$this->content_types = config::get_content_types($this->appname);
|
$this->content_types = Api\Config::get_content_types($this->appname);
|
||||||
}
|
}
|
||||||
if (count($this->content_types)==0)
|
if (count($this->content_types)==0)
|
||||||
{
|
{
|
||||||
@ -152,7 +154,7 @@ class customfields
|
|||||||
}
|
}
|
||||||
elseif($content['content_types']['create'])
|
elseif($content['content_types']['create'])
|
||||||
{
|
{
|
||||||
if($new_type = $this->create_content_type($content))
|
if(($new_type = $this->create_content_type($content)))
|
||||||
{
|
{
|
||||||
$content['content_types']['types'] = $this->content_type = $new_type;
|
$content['content_types']['types'] = $this->content_type = $new_type;
|
||||||
}
|
}
|
||||||
@ -214,7 +216,6 @@ class customfields
|
|||||||
|
|
||||||
$content['type_template'] = $this->appname . '.admin.types';
|
$content['type_template'] = $this->appname . '.admin.types';
|
||||||
$content['content_types']['appname'] = $this->appname;
|
$content['content_types']['appname'] = $this->appname;
|
||||||
$content_types = array_keys($this->content_types);
|
|
||||||
|
|
||||||
$content['content_type_options'] = $this->content_types[$this->content_type]['options'];
|
$content['content_type_options'] = $this->content_types[$this->content_type]['options'];
|
||||||
$content['content_type_options']['type'] = $this->types2[$this->content_type];
|
$content['content_type_options']['type'] = $this->types2[$this->content_type];
|
||||||
@ -251,6 +252,7 @@ class customfields
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Allow extending app a change to change content before display
|
// Allow extending app a change to change content before display
|
||||||
|
$readonlys = null;
|
||||||
static::app_index($content, $sel_options, $readonlys, $preserve);
|
static::app_index($content, $sel_options, $readonlys, $preserve);
|
||||||
|
|
||||||
// Make sure app css gets loaded, extending app might cause et2 to miss it
|
// Make sure app css gets loaded, extending app might cause et2 to miss it
|
||||||
@ -292,7 +294,7 @@ class customfields
|
|||||||
$this->use_private = !isset($_GET['use_private']) || (boolean)$_GET['use_private'] || $content['use_private'];
|
$this->use_private = !isset($_GET['use_private']) || (boolean)$_GET['use_private'] || $content['use_private'];
|
||||||
|
|
||||||
// Read fields, constructor doesn't always know appname
|
// Read fields, constructor doesn't always know appname
|
||||||
$this->fields = egw_customfields::get($this->appname,true);
|
$this->fields = Api\Storage\Customfields::get($this->appname,true);
|
||||||
|
|
||||||
// Update based on info returned from template
|
// Update based on info returned from template
|
||||||
if (is_array($content))
|
if (is_array($content))
|
||||||
@ -328,8 +330,8 @@ class customfields
|
|||||||
{
|
{
|
||||||
foreach(explode("\n",trim($content['cf_values'])) as $line)
|
foreach(explode("\n",trim($content['cf_values'])) as $line)
|
||||||
{
|
{
|
||||||
list($var,$value) = explode('=',trim($line),2);
|
list($var_raw,$value) = explode('=',trim($line),2);
|
||||||
$var = trim($var);
|
$var = trim($var_raw);
|
||||||
$values[$var] = trim($value)==='' ? $var : $value;
|
$values[$var] = trim($value)==='' ? $var : $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -343,10 +345,10 @@ class customfields
|
|||||||
$update_content[substr($key,3)] = $value;
|
$update_content[substr($key,3)] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
egw_customfields::update($update_content);
|
Api\Storage\Customfields::update($update_content);
|
||||||
if(!$cf_id)
|
if(!$cf_id)
|
||||||
{
|
{
|
||||||
$this->fields = egw_customfields::get($this->appname,true);
|
$this->fields = Api\Storage\Customfields::get($this->appname,true);
|
||||||
$cf_id = (int)$this->fields[$content['cf_name']]['id'];
|
$cf_id = (int)$this->fields[$content['cf_name']]['id'];
|
||||||
}
|
}
|
||||||
egw_framework::refresh_opener('Saved', 'admin', $cf_id, 'edit');
|
egw_framework::refresh_opener('Saved', 'admin', $cf_id, 'edit');
|
||||||
@ -415,7 +417,7 @@ class customfields
|
|||||||
{
|
{
|
||||||
if(count($this->content_types) == 0)
|
if(count($this->content_types) == 0)
|
||||||
{
|
{
|
||||||
$this->content_types = config::get_content_types($this->appname);
|
$this->content_types = Api\Config::get_content_types($this->appname);
|
||||||
}
|
}
|
||||||
if (count($this->content_types)==0)
|
if (count($this->content_types)==0)
|
||||||
{
|
{
|
||||||
@ -455,6 +457,7 @@ class customfields
|
|||||||
*/
|
*/
|
||||||
protected function app_index(&$content, &$sel_options, &$readonlys)
|
protected function app_index(&$content, &$sel_options, &$readonlys)
|
||||||
{
|
{
|
||||||
|
unset($content, $sel_options, $readonlys); // not used, as this is a stub
|
||||||
// This is just a stub.
|
// This is just a stub.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,78 +497,6 @@ class customfields
|
|||||||
return $actions;
|
return $actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_fields(&$content)
|
|
||||||
{
|
|
||||||
foreach($content['fields'] as $field)
|
|
||||||
{
|
|
||||||
$name = trim($field['name']);
|
|
||||||
$old_name = $field['old_name'];
|
|
||||||
|
|
||||||
if (!empty($delete) && $delete == $old_name)
|
|
||||||
{
|
|
||||||
unset($this->fields[$old_name]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (isset($field['old_name']))
|
|
||||||
{
|
|
||||||
if (empty($name)) // empty name not allowed
|
|
||||||
{
|
|
||||||
$content['error_msg'] = lang('Name must not be empty !!!');
|
|
||||||
$name = $old_name;
|
|
||||||
}
|
|
||||||
if (!empty($name) && $old_name != $name) // renamed
|
|
||||||
{
|
|
||||||
unset($this->fields[$old_name]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elseif (empty($name)) // new item and empty ==> ignore it
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$values = array();
|
|
||||||
if (!empty($field['values']))
|
|
||||||
{
|
|
||||||
foreach(explode("\n",$field['values']) as $line)
|
|
||||||
{
|
|
||||||
list($var,$value) = explode('=',trim($line),2);
|
|
||||||
$var = trim($var);
|
|
||||||
$values[$var] = empty($value) ? $var : $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->fields[$name] = array(
|
|
||||||
'type' => $field['type'],
|
|
||||||
'type2' => $field['type2'],
|
|
||||||
'label' => empty($field['label']) ? $name : $field['label'],
|
|
||||||
'help' => $field['help'],
|
|
||||||
'values'=> $values,
|
|
||||||
'len' => $field['len'],
|
|
||||||
'rows' => (int)$field['rows'],
|
|
||||||
'order' => (int)$field['order'],
|
|
||||||
'private' => $field['private'],
|
|
||||||
'needed' => $field['needed'],
|
|
||||||
);
|
|
||||||
if(!$this->fields[$name]['type2'] && $this->manage_content_types)
|
|
||||||
{
|
|
||||||
$this->fields[$name]['type2'] = (string)0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!function_exists('sort_by_order'))
|
|
||||||
{
|
|
||||||
function sort_by_order($arr1,$arr2)
|
|
||||||
{
|
|
||||||
return $arr1['order'] - $arr2['order'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uasort($this->fields,sort_by_order);
|
|
||||||
|
|
||||||
$n = 0;
|
|
||||||
foreach($this->fields as $name => $data)
|
|
||||||
{
|
|
||||||
$this->fields[$name]['order'] = ($n += 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function update(&$content)
|
function update(&$content)
|
||||||
{
|
{
|
||||||
$this->content_types[$this->content_type]['options'] = $content['content_type_options'];
|
$this->content_types[$this->content_type]['options'] = $content['content_type_options'];
|
||||||
@ -627,7 +558,7 @@ class customfields
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach($this->content_types as $letter => $type)
|
foreach($this->content_types as $type)
|
||||||
{
|
{
|
||||||
if($type['name'] == $new_name)
|
if($type['name'] == $new_name)
|
||||||
{
|
{
|
||||||
@ -640,8 +571,8 @@ class customfields
|
|||||||
{
|
{
|
||||||
if (!$this->content_types[chr($i)] &&
|
if (!$this->content_types[chr($i)] &&
|
||||||
// skip letter of deleted type for addressbook content-types, as it gives SQL error
|
// skip letter of deleted type for addressbook content-types, as it gives SQL error
|
||||||
// content-type are lowercase, addressbook_so::DELETED_TYPE === 'D', but DB is case-insensitive
|
// content-type are lowercase, Api\Contacts::DELETED_TYPE === 'D', but DB is case-insensitive
|
||||||
($this->appname !== 'addressbook' || chr($i) !== strtolower(addressbook_so::DELETED_TYPE)))
|
($this->appname !== 'addressbook' || chr($i) !== strtolower(Api\Contacts::DELETED_TYPE)))
|
||||||
{
|
{
|
||||||
$new_type = chr($i);
|
$new_type = chr($i);
|
||||||
break;
|
break;
|
||||||
@ -664,32 +595,32 @@ class customfields
|
|||||||
$config->value('types',$this->content_types);
|
$config->value('types',$this->content_types);
|
||||||
$config->save_repository();
|
$config->save_repository();
|
||||||
|
|
||||||
egw_customfields::save($this->appname, $this->fields);
|
Api\Storage\Customfields::save($this->appname, $this->fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get customfields of using application
|
* get customfields of using application
|
||||||
*
|
*
|
||||||
* @deprecated use egw_customfields::get() direct, no need to instanciate this UI class
|
* @deprecated use Api\Storage\Customfields::get() direct, no need to instanciate this UI class
|
||||||
* @author Cornelius Weiss
|
* @author Cornelius Weiss
|
||||||
* @param boolean $all_private_too =false should all the private fields be returned too
|
* @param boolean $all_private_too =false should all the private fields be returned too
|
||||||
* @return array with customfields
|
* @return array with customfields
|
||||||
*/
|
*/
|
||||||
function get_customfields($all_private_too=false)
|
function get_customfields($all_private_too=false)
|
||||||
{
|
{
|
||||||
return egw_customfields::get($this->appname,$all_private_too);
|
return Api\Storage\Customfields::get($this->appname,$all_private_too);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get_content_types of using application
|
* get_content_types of using application
|
||||||
*
|
*
|
||||||
* @deprecated use config::get_content_types() direct, no need to instanciate this UI class
|
* @deprecated use Api\Config::get_content_types() direct, no need to instanciate this UI class
|
||||||
* @author Cornelius Weiss
|
* @author Cornelius Weiss
|
||||||
* @return array with content-types
|
* @return array with content-types
|
||||||
*/
|
*/
|
||||||
function get_content_types()
|
function get_content_types()
|
||||||
{
|
{
|
||||||
return config::get_content_types($this->appname);
|
return Api\Config::get_content_types($this->appname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -228,13 +228,13 @@ class Config
|
|||||||
* @param string $app
|
* @param string $app
|
||||||
* @param boolean $all_private_too =false should all the private fields be returned too, default no
|
* @param boolean $all_private_too =false should all the private fields be returned too, default no
|
||||||
* @param string $only_type2 =null if given only return fields of type2 == $only_type2
|
* @param string $only_type2 =null if given only return fields of type2 == $only_type2
|
||||||
* @deprecated use Api\Customfields::get()
|
* @deprecated use Api\Storage\Customfields::get()
|
||||||
* @return array with customfields
|
* @return array with customfields
|
||||||
*/
|
*/
|
||||||
static function get_customfields($app, $all_private_too=false, $only_type2=null)
|
static function get_customfields($app, $all_private_too=false, $only_type2=null)
|
||||||
{
|
{
|
||||||
//error_log(__METHOD__."('$app', $all_private_too, $only_type2) deprecated, use Customfields::get() in ". function_backtrace());
|
//error_log(__METHOD__."('$app', $all_private_too, $only_type2) deprecated, use Storage\Customfields::get() in ". function_backtrace());
|
||||||
return Customfields::get($app, $all_private_too, $only_type2);
|
return Storage\Customfields::get($app, $all_private_too, $only_type2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
2402
api/src/Contacts.php
Executable file
2402
api/src/Contacts.php
Executable file
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Addressbook - ADS Backend
|
* EGroupware API: Contacts ADS Backend
|
||||||
*
|
*
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Ralf Becker <rb@stylite.de>
|
* @author Ralf Becker <rb@stylite.de>
|
||||||
* @package addressbook
|
* @package api
|
||||||
|
* @subpackage contacts
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace EGroupware\Api\Contacts;
|
||||||
|
|
||||||
|
use EGroupware\Api;
|
||||||
|
|
||||||
|
// explicitly reference classes still in phpgwapi
|
||||||
|
use accounts_ads;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Active directory backend for accounts (not yet AD contacts)
|
* Active directory backend for accounts (not yet AD contacts)
|
||||||
*
|
*
|
||||||
@ -22,7 +30,7 @@
|
|||||||
* All values used to construct filters need to run through ldap::quote(),
|
* All values used to construct filters need to run through ldap::quote(),
|
||||||
* to be save against LDAP query injection!!!
|
* to be save against LDAP query injection!!!
|
||||||
*/
|
*/
|
||||||
class addressbook_ads extends addressbook_ldap
|
class Ads extends Ldap
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* LDAP searches only a limited set of attributes for performance reasons,
|
* LDAP searches only a limited set of attributes for performance reasons,
|
||||||
@ -79,6 +87,8 @@ class addressbook_ads extends addressbook_ldap
|
|||||||
*/
|
*/
|
||||||
function __construct(array $ldap_config=null, $ds=null)
|
function __construct(array $ldap_config=null, $ds=null)
|
||||||
{
|
{
|
||||||
|
if (false) parent::__construct (); // quiten IDE warning, we are explicitly NOT calling parrent constructor!
|
||||||
|
|
||||||
$this->accountName = $GLOBALS['egw_info']['user']['account_lid'];
|
$this->accountName = $GLOBALS['egw_info']['user']['account_lid'];
|
||||||
|
|
||||||
if ($ldap_config)
|
if ($ldap_config)
|
||||||
@ -103,8 +113,8 @@ class addressbook_ads extends addressbook_ldap
|
|||||||
{
|
{
|
||||||
$this->connect();
|
$this->connect();
|
||||||
}
|
}
|
||||||
$this->ldapServerInfo = ldapserverinfo::get($this->ds, $this->ldap_config['ads_host']);
|
$this->ldapServerInfo = Api\Ldap\ServerInfo::get($this->ds, $this->ldap_config['ads_host']);
|
||||||
$this->is_samba4 = $this->ldapServerInfo->serverType == SAMBA4_LDAPSERVER;
|
$this->is_samba4 = $this->ldapServerInfo->serverType == Api\Ldap\ServerInfo::SAMBA4;
|
||||||
|
|
||||||
// AD seems to use user, instead of inetOrgPerson
|
// AD seems to use user, instead of inetOrgPerson
|
||||||
unset($this->schema2egw['posixaccount']);
|
unset($this->schema2egw['posixaccount']);
|
||||||
@ -118,13 +128,13 @@ class addressbook_ads extends addressbook_ldap
|
|||||||
unset($this->schema2egw['user']['n_fileas']);
|
unset($this->schema2egw['user']['n_fileas']);
|
||||||
unset($this->schema2egw['inetorgperson']);
|
unset($this->schema2egw['inetorgperson']);
|
||||||
|
|
||||||
foreach($this->schema2egw as $schema => $attributes)
|
foreach($this->schema2egw as $attributes)
|
||||||
{
|
{
|
||||||
$this->all_attributes = array_merge($this->all_attributes,array_values($attributes));
|
$this->all_attributes = array_merge($this->all_attributes,array_values($attributes));
|
||||||
}
|
}
|
||||||
$this->all_attributes = array_values(array_unique($this->all_attributes));
|
$this->all_attributes = array_values(array_unique($this->all_attributes));
|
||||||
|
|
||||||
$this->charset = translation::charset();
|
$this->charset = Api\Translation::charset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -134,6 +144,8 @@ class addressbook_ads extends addressbook_ldap
|
|||||||
*/
|
*/
|
||||||
function connect($admin=false)
|
function connect($admin=false)
|
||||||
{
|
{
|
||||||
|
unset($admin); // not used, but required by function signature
|
||||||
|
|
||||||
$this->ds = $this->accounts_ads->ldap_connection();
|
$this->ds = $this->accounts_ads->ldap_connection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,21 +171,21 @@ class addressbook_ads extends addressbook_ldap
|
|||||||
/**
|
/**
|
||||||
* reads contact data
|
* reads contact data
|
||||||
*
|
*
|
||||||
* @param string/array $contact_id contact_id or array with values for id or account_id
|
* @param string/array $_contact_id contact_id or array with values for id or account_id
|
||||||
* @return array/boolean data if row could be retrived else False
|
* @return array/boolean data if row could be retrived else False
|
||||||
*/
|
*/
|
||||||
function read($contact_id)
|
function read($_contact_id)
|
||||||
{
|
{
|
||||||
if (is_array($contact_id) && isset($contact_id['account_id']) ||
|
if (is_array($_contact_id) && isset($_contact_id['account_id']) ||
|
||||||
!is_array($contact_id) && substr($contact_id,0,8) == 'account:')
|
!is_array($_contact_id) && substr($_contact_id,0,8) == 'account:')
|
||||||
{
|
{
|
||||||
$account_id = (int)(is_array($contact_id) ? $contact_id['account_id'] : substr($contact_id,8));
|
$account_id = (int)(is_array($_contact_id) ? $_contact_id['account_id'] : substr($_contact_id,8));
|
||||||
$contact_id = $GLOBALS['egw']->accounts->id2name($account_id, 'person_id');
|
$_contact_id = $GLOBALS['egw']->accounts->id2name($account_id, 'person_id');
|
||||||
}
|
}
|
||||||
$contact_id = !is_array($contact_id) ? $contact_id :
|
$contact_id = !is_array($_contact_id) ? $_contact_id :
|
||||||
(isset ($contact_id['id']) ? $contact_id['id'] : $contact_id['uid']);
|
(isset ($_contact_id['id']) ? $_contact_id['id'] : $_contact_id['uid']);
|
||||||
|
|
||||||
$rows = $this->_searchLDAP($this->allContactsDN, $filter=$this->id_filter($contact_id), $this->all_attributes, ADDRESSBOOK_ALL);
|
$rows = $this->_searchLDAP($this->allContactsDN, $filter=$this->id_filter($contact_id), $this->all_attributes, Ldap::ALL);
|
||||||
//error_log(__METHOD__."('$contact_id') _searchLDAP($this->allContactsDN, '$filter',...)=".array2string($rows));
|
//error_log(__METHOD__."('$contact_id') _searchLDAP($this->allContactsDN, '$filter',...)=".array2string($rows));
|
||||||
return $rows ? $rows[0] : false;
|
return $rows ? $rows[0] : false;
|
||||||
}
|
}
|
||||||
@ -214,5 +226,4 @@ class addressbook_ads extends addressbook_ldap
|
|||||||
|
|
||||||
parent::sanitize_update($ldapContact);
|
parent::sanitize_update($ldapContact);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,20 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Addressbook - LDAP Backend
|
* EGroupware API: Contacts LDAP Backend
|
||||||
*
|
*
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Cornelius Weiss <egw-AT-von-und-zu-weiss.de>
|
* @author Cornelius Weiss <egw-AT-von-und-zu-weiss.de>
|
||||||
* @author Lars Kneschke <l.kneschke-AT-metaways.de>
|
* @author Lars Kneschke <l.kneschke-AT-metaways.de>
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @package addressbook
|
* @package api
|
||||||
|
* @subpackage contacts
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
define('ADDRESSBOOK_ALL',0);
|
namespace EGroupware\Api\Contacts;
|
||||||
define('ADDRESSBOOK_ACCOUNTS',1);
|
|
||||||
define('ADDRESSBOOK_PERSONAL',2);
|
use EGroupware\Api;
|
||||||
define('ADDRESSBOOK_GROUP',3);
|
|
||||||
|
// explicitly reference classes still in phpgwapi
|
||||||
|
use common; // randomstring
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LDAP Backend for contacts, compatible with vars and parameters of eTemplate's so_sql.
|
* LDAP Backend for contacts, compatible with vars and parameters of eTemplate's so_sql.
|
||||||
@ -23,8 +26,14 @@ define('ADDRESSBOOK_GROUP',3);
|
|||||||
* All values used to construct filters need to run through ldap::quote(),
|
* All values used to construct filters need to run through ldap::quote(),
|
||||||
* to be save against LDAP query injection!!!
|
* to be save against LDAP query injection!!!
|
||||||
*/
|
*/
|
||||||
class addressbook_ldap
|
class Ldap
|
||||||
{
|
{
|
||||||
|
|
||||||
|
const ALL = 0;
|
||||||
|
const ACCOUNTS = 1;
|
||||||
|
const PERSONAL = 2;
|
||||||
|
const GROUP = 3;
|
||||||
|
|
||||||
var $data;
|
var $data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -298,7 +307,7 @@ class addressbook_ldap
|
|||||||
}
|
}
|
||||||
$this->all_attributes = array_values(array_unique($this->all_attributes));
|
$this->all_attributes = array_values(array_unique($this->all_attributes));
|
||||||
|
|
||||||
$this->charset = translation::charset();
|
$this->charset = Api\Translation::charset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -414,7 +423,7 @@ class addressbook_ldap
|
|||||||
$filter = $this->id_filter($contact_id);
|
$filter = $this->id_filter($contact_id);
|
||||||
}
|
}
|
||||||
$rows = $this->_searchLDAP($this->allContactsDN,
|
$rows = $this->_searchLDAP($this->allContactsDN,
|
||||||
$filter, $this->all_attributes, ADDRESSBOOK_ALL, array('_posixaccount2egw'));
|
$filter, $this->all_attributes, self::ALL, array('_posixaccount2egw'));
|
||||||
|
|
||||||
return $rows ? $rows[0] : false;
|
return $rows ? $rows[0] : false;
|
||||||
}
|
}
|
||||||
@ -508,7 +517,7 @@ class addressbook_ldap
|
|||||||
|
|
||||||
if(empty($contactUID))
|
if(empty($contactUID))
|
||||||
{
|
{
|
||||||
$ldapContact[$this->dn_attribute] = $this->data[$this->contacts_id] = $contactUID = md5($GLOBALS['egw']->common->randomstring(15));
|
$ldapContact[$this->dn_attribute] = $this->data[$this->contacts_id] = $contactUID = md5(common::randomstring(15));
|
||||||
}
|
}
|
||||||
//error_log(__METHOD__."() contactUID='$contactUID', isUpdate=".array2string($isUpdate).", oldContactInfo=".array2string($oldContactInfo));
|
//error_log(__METHOD__."() contactUID='$contactUID', isUpdate=".array2string($isUpdate).", oldContactInfo=".array2string($oldContactInfo));
|
||||||
// add for all supported objectclasses the objectclass and it's attributes
|
// add for all supported objectclasses the objectclass and it's attributes
|
||||||
@ -537,7 +546,7 @@ class addressbook_ldap
|
|||||||
{
|
{
|
||||||
// dont convert the (binary) jpegPhoto!
|
// dont convert the (binary) jpegPhoto!
|
||||||
$ldapContact[$ldapFieldName] = $ldapFieldName == 'jpegphoto' ? $data[$egwFieldName] :
|
$ldapContact[$ldapFieldName] = $ldapFieldName == 'jpegphoto' ? $data[$egwFieldName] :
|
||||||
translation::convert(trim($data[$egwFieldName]),$this->charset,'utf-8');
|
Api\Translation::convert(trim($data[$egwFieldName]),$this->charset,'utf-8');
|
||||||
}
|
}
|
||||||
elseif($isUpdate && isset($data[$egwFieldName]))
|
elseif($isUpdate && isset($data[$egwFieldName]))
|
||||||
{
|
{
|
||||||
@ -593,7 +602,7 @@ class addressbook_ldap
|
|||||||
{
|
{
|
||||||
$result = ldap_read($this->ds, $dn, 'objectclass=*');
|
$result = ldap_read($this->ds, $dn, 'objectclass=*');
|
||||||
$entries = ldap_get_entries($this->ds, $result);
|
$entries = ldap_get_entries($this->ds, $result);
|
||||||
$oldContact = ldap::result2array($entries[0]);
|
$oldContact = Api\Ldap::result2array($entries[0]);
|
||||||
unset($oldContact['dn']);
|
unset($oldContact['dn']);
|
||||||
|
|
||||||
$newContact = $oldContact;
|
$newContact = $oldContact;
|
||||||
@ -681,7 +690,7 @@ class addressbook_ldap
|
|||||||
|
|
||||||
foreach($keys as $entry)
|
foreach($keys as $entry)
|
||||||
{
|
{
|
||||||
$entry = ldap::quote(is_array($entry) ? $entry['id'] : $entry);
|
$entry = Api\Ldap::quote(is_array($entry) ? $entry['id'] : $entry);
|
||||||
if(($result = ldap_search($this->ds, $this->allContactsDN,
|
if(($result = ldap_search($this->ds, $this->allContactsDN,
|
||||||
"(|(entryUUID=$entry)(uid=$entry))", $attributes)))
|
"(|(entryUUID=$entry)(uid=$entry))", $attributes)))
|
||||||
{
|
{
|
||||||
@ -759,33 +768,33 @@ class addressbook_ldap
|
|||||||
{
|
{
|
||||||
if (!($accountName = $GLOBALS['egw']->accounts->id2name($filter['owner']))) return false;
|
if (!($accountName = $GLOBALS['egw']->accounts->id2name($filter['owner']))) return false;
|
||||||
|
|
||||||
$searchDN = 'cn='. ldap::quote(strtolower($accountName)) .',';
|
$searchDN = 'cn='. Api\Ldap::quote(strtolower($accountName)) .',';
|
||||||
|
|
||||||
if ($filter['owner'] < 0)
|
if ($filter['owner'] < 0)
|
||||||
{
|
{
|
||||||
$searchDN .= $this->sharedContactsDN;
|
$searchDN .= $this->sharedContactsDN;
|
||||||
$addressbookType = ADDRESSBOOK_GROUP;
|
$addressbookType = self::GROUP;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$searchDN .= $this->personalContactsDN;
|
$searchDN .= $this->personalContactsDN;
|
||||||
$addressbookType = ADDRESSBOOK_PERSONAL;
|
$addressbookType = self::PERSONAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elseif (!isset($filter['owner']))
|
elseif (!isset($filter['owner']))
|
||||||
{
|
{
|
||||||
$searchDN = $this->allContactsDN;
|
$searchDN = $this->allContactsDN;
|
||||||
$addressbookType = ADDRESSBOOK_ALL;
|
$addressbookType = self::ALL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$searchDN = $this->accountContactsDN;
|
$searchDN = $this->accountContactsDN;
|
||||||
$addressbookType = ADDRESSBOOK_ACCOUNTS;
|
$addressbookType = self::ACCOUNTS;
|
||||||
}
|
}
|
||||||
// create the search filter
|
// create the search filter
|
||||||
switch($addressbookType)
|
switch($addressbookType)
|
||||||
{
|
{
|
||||||
case ADDRESSBOOK_ACCOUNTS:
|
case self::ACCOUNTS:
|
||||||
$objectFilter = $this->accountsFilter;
|
$objectFilter = $this->accountsFilter;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -813,8 +822,8 @@ class addressbook_ldap
|
|||||||
{
|
{
|
||||||
if(($ldapSearchKey = $mapping[$egwSearchKey]))
|
if(($ldapSearchKey = $mapping[$egwSearchKey]))
|
||||||
{
|
{
|
||||||
$searchString = translation::convert($searchValue,$this->charset,'utf-8');
|
$searchString = Api\Translation::convert($searchValue,$this->charset,'utf-8');
|
||||||
$searchFilter .= '('.$ldapSearchKey.'='.$wildcard.ldap::quote($searchString).$wildcard.')';
|
$searchFilter .= '('.$ldapSearchKey.'='.$wildcard.Api\Ldap::quote($searchString).$wildcard.')';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -915,7 +924,7 @@ class addressbook_ldap
|
|||||||
}
|
}
|
||||||
elseif ($value)
|
elseif ($value)
|
||||||
{
|
{
|
||||||
$filters .= '(uidNumber='.ldap::quote($value).')';
|
$filters .= '(uidNumber='.Api\Ldap::quote($value).')';
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -935,9 +944,9 @@ class addressbook_ldap
|
|||||||
if (count($cats) > 1) $filters .= '(|';
|
if (count($cats) > 1) $filters .= '(|';
|
||||||
foreach($cats as $cat)
|
foreach($cats as $cat)
|
||||||
{
|
{
|
||||||
$catName = translation::convert(
|
$catName = Api\Translation::convert(
|
||||||
$GLOBALS['egw']->categories->id2name($cat),$this->charset,'utf-8');
|
$GLOBALS['egw']->categories->id2name($cat),$this->charset,'utf-8');
|
||||||
$filters .= '(category='.ldap::quote($catName).')';
|
$filters .= '(category='.Api\Ldap::quote($catName).')';
|
||||||
}
|
}
|
||||||
if (count($cats) > 1) $filters .= ')';
|
if (count($cats) > 1) $filters .= ')';
|
||||||
}
|
}
|
||||||
@ -965,13 +974,13 @@ class addressbook_ldap
|
|||||||
{
|
{
|
||||||
// todo: value = "!''"
|
// todo: value = "!''"
|
||||||
$filters .= '('.$mapping[$key].'='.($value === "!''" ? '*' :
|
$filters .= '('.$mapping[$key].'='.($value === "!''" ? '*' :
|
||||||
ldap::quote(translation::convert($value,$this->charset,'utf-8'))).')';
|
Api\Ldap::quote(Api\Translation::convert($value,$this->charset,'utf-8'))).')';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// filter for letter-search
|
// filter for letter-search
|
||||||
elseif (preg_match("/^([^ ]+) ".preg_quote($GLOBALS['egw']->db->capabilities[egw_db::CAPABILITY_CASE_INSENSITIV_LIKE])." '(.*)%'$/",$value,$matches))
|
elseif (preg_match("/^([^ ]+) ".preg_quote($GLOBALS['egw']->db->capabilities[Api\Db::CAPABILITY_CASE_INSENSITIV_LIKE])." '(.*)%'$/",$value,$matches))
|
||||||
{
|
{
|
||||||
list(,$name,$value) = $matches;
|
list(,$name,$value) = $matches;
|
||||||
if (strpos($name,'.') !== false) list(,$name) = explode('.',$name);
|
if (strpos($name,'.') !== false) list(,$name) = explode('.',$name);
|
||||||
@ -979,8 +988,8 @@ class addressbook_ldap
|
|||||||
{
|
{
|
||||||
if (isset($mapping[$name]))
|
if (isset($mapping[$name]))
|
||||||
{
|
{
|
||||||
$filters .= '('.$mapping[$name].'='.ldap::quote(
|
$filters .= '('.$mapping[$name].'='.Api\Ldap::quote(
|
||||||
translation::convert($value,$this->charset,'utf-8')).'*)';
|
Api\Translation::convert($value,$this->charset,'utf-8')).'*)';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1017,7 +1026,7 @@ class addressbook_ldap
|
|||||||
|
|
||||||
//error_log(__METHOD__."('$_ldapContext', '$_filter', ".array2string($_attributes).", $_addressbooktype)");
|
//error_log(__METHOD__."('$_ldapContext', '$_filter', ".array2string($_attributes).", $_addressbooktype)");
|
||||||
|
|
||||||
if($_addressbooktype == ADDRESSBOOK_ALL || $_ldapContext == $this->allContactsDN)
|
if($_addressbooktype == self::ALL || $_ldapContext == $this->allContactsDN)
|
||||||
{
|
{
|
||||||
$result = ldap_search($this->ds, $_ldapContext, $_filter, $_attributes, 0, $this->ldapLimit);
|
$result = ldap_search($this->ds, $_ldapContext, $_filter, $_attributes, 0, $this->ldapLimit);
|
||||||
}
|
}
|
||||||
@ -1048,7 +1057,7 @@ class addressbook_ldap
|
|||||||
{
|
{
|
||||||
if(!empty($entry[$ldapFieldName][0]) && !is_int($egwFieldName) && !isset($contact[$egwFieldName]))
|
if(!empty($entry[$ldapFieldName][0]) && !is_int($egwFieldName) && !isset($contact[$egwFieldName]))
|
||||||
{
|
{
|
||||||
$contact[$egwFieldName] = translation::convert($entry[$ldapFieldName][0],'utf-8');
|
$contact[$egwFieldName] = Api\Translation::convert($entry[$ldapFieldName][0],'utf-8');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$objectclass2egw = '_'.$objectclass.'2egw';
|
$objectclass2egw = '_'.$objectclass.'2egw';
|
||||||
@ -1206,7 +1215,7 @@ class addressbook_ldap
|
|||||||
$ldapContact['category'] = array();
|
$ldapContact['category'] = array();
|
||||||
foreach(is_array($data['cat_id']) ? $data['cat_id'] : explode(',',$data['cat_id']) as $cat)
|
foreach(is_array($data['cat_id']) ? $data['cat_id'] : explode(',',$data['cat_id']) as $cat)
|
||||||
{
|
{
|
||||||
$ldapContact['category'][] = translation::convert(
|
$ldapContact['category'][] = Api\Translation::convert(
|
||||||
ExecMethod('phpgwapi.categories.id2name',$cat),$this->charset,'utf-8');
|
ExecMethod('phpgwapi.categories.id2name',$cat),$this->charset,'utf-8');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1217,7 +1226,7 @@ class addressbook_ldap
|
|||||||
{
|
{
|
||||||
if($value != '$, $$$')
|
if($value != '$, $$$')
|
||||||
{
|
{
|
||||||
$ldapContact[$attr] = translation::convert($value,$this->charset,'utf-8');
|
$ldapContact[$attr] = Api\Translation::convert($value,$this->charset,'utf-8');
|
||||||
}
|
}
|
||||||
elseif($isUpdate)
|
elseif($isUpdate)
|
||||||
{
|
{
|
||||||
@ -1421,6 +1430,6 @@ class addressbook_ldap
|
|||||||
*/
|
*/
|
||||||
function change_owner($account_id,$new_owner)
|
function change_owner($account_id,$new_owner)
|
||||||
{
|
{
|
||||||
error_log("so_ldap::change_owner($account_id,$new_owner) not yet implemented");
|
error_log(__METHOD__."($account_id,$new_owner) not yet implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,19 +1,27 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* EGroupware : Addressbook - SQL backend
|
* EGroupware API: Contacts - SQL storage
|
||||||
*
|
*
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @package addressbook
|
* @package api
|
||||||
* @copyright (c) 2006-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @subpackage contacts
|
||||||
|
* @copyright (c) 2006-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace EGroupware\Api\Contacts;
|
||||||
|
|
||||||
|
use EGroupware\Api;
|
||||||
|
|
||||||
|
// explicitly reference classes still in phpgwapi
|
||||||
|
use common; // common::generate_uid
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQL storage object of the adressbook
|
* Contacts - SQL storage
|
||||||
*/
|
*/
|
||||||
class addressbook_sql extends so_sql_cf
|
class Sql extends Api\Storage
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* name of custom fields table
|
* name of custom fields table
|
||||||
@ -60,15 +68,15 @@ class addressbook_sql extends so_sql_cf
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param egw_db $db=null
|
* @param Api\Db $db =null
|
||||||
*/
|
*/
|
||||||
function __construct(egw_db $db=null)
|
function __construct(Api\Db $db=null)
|
||||||
{
|
{
|
||||||
parent::__construct('phpgwapi', 'egw_addressbook', self::EXTRA_TABLE, 'contact_',
|
parent::__construct('phpgwapi', 'egw_addressbook', self::EXTRA_TABLE,
|
||||||
$extra_key='_name',$extra_value='_value',$extra_id='_id',$db);
|
'contact_', '_name', '_value', '_id', $db);
|
||||||
|
|
||||||
// Get custom fields from addressbook instead of phpgwapi
|
// Get custom fields from addressbook instead of phpgwapi
|
||||||
$this->customfields = config::get_customfields('addressbook');
|
$this->customfields = Api\Storage\Customfields::get('addressbook');
|
||||||
|
|
||||||
if ($GLOBALS['egw_info']['server']['account_repository'])
|
if ($GLOBALS['egw_info']['server']['account_repository'])
|
||||||
{
|
{
|
||||||
@ -146,7 +154,7 @@ class addressbook_sql extends so_sql_cf
|
|||||||
}
|
}
|
||||||
if ($param['searchletter'])
|
if ($param['searchletter'])
|
||||||
{
|
{
|
||||||
$filter[] = 'org_name '.$this->db->capabilities[egw_db::CAPABILITY_CASE_INSENSITIV_LIKE].' '.$this->db->quote($param['searchletter'].'%');
|
$filter[] = 'org_name '.$this->db->capabilities[Api\Db::CAPABILITY_CASE_INSENSITIV_LIKE].' '.$this->db->quote($param['searchletter'].'%');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -169,8 +177,8 @@ class addressbook_sql extends so_sql_cf
|
|||||||
// org total for more then one $by
|
// org total for more then one $by
|
||||||
$by_expr = $by == 'org_unit_count' ? "COUNT(DISTINCT CASE WHEN org_unit IS NULL THEN '' ELSE org_unit END)" :
|
$by_expr = $by == 'org_unit_count' ? "COUNT(DISTINCT CASE WHEN org_unit IS NULL THEN '' ELSE org_unit END)" :
|
||||||
"COUNT(DISTINCT CASE WHEN adr_one_locality IS NULL THEN '' ELSE adr_one_locality END)";
|
"COUNT(DISTINCT CASE WHEN adr_one_locality IS NULL THEN '' ELSE adr_one_locality END)";
|
||||||
$append = "GROUP BY org_name HAVING $by_expr > 1 ORDER BY org_name $sort";
|
parent::search($param['search'],array('org_name'),
|
||||||
parent::search($param['search'],array('org_name'),$append,array(
|
"GROUP BY org_name HAVING $by_expr > 1 ORDER BY org_name $sort", array(
|
||||||
"NULL AS $by",
|
"NULL AS $by",
|
||||||
'1 AS is_main',
|
'1 AS is_main',
|
||||||
'COUNT(DISTINCT egw_addressbook.contact_id) AS org_count',
|
'COUNT(DISTINCT egw_addressbook.contact_id) AS org_count',
|
||||||
@ -178,8 +186,8 @@ class addressbook_sql extends so_sql_cf
|
|||||||
"COUNT(DISTINCT CASE WHEN adr_one_locality IS NULL THEN '' ELSE adr_one_locality END) AS adr_one_locality_count",
|
"COUNT(DISTINCT CASE WHEN adr_one_locality IS NULL THEN '' ELSE adr_one_locality END) AS adr_one_locality_count",
|
||||||
),$wildcard,false,$op/*'OR'*/,'UNION',$filter);
|
),$wildcard,false,$op/*'OR'*/,'UNION',$filter);
|
||||||
// org by location
|
// org by location
|
||||||
$append = "GROUP BY org_name,$by ORDER BY org_name $sort,$by $sort";
|
parent::search($param['search'],array('org_name'),
|
||||||
parent::search($param['search'],array('org_name'),$append,array(
|
"GROUP BY org_name,$by ORDER BY org_name $sort,$by $sort", array(
|
||||||
"CASE WHEN $by IS NULL THEN '' ELSE $by END AS $by",
|
"CASE WHEN $by IS NULL THEN '' ELSE $by END AS $by",
|
||||||
'0 AS is_main',
|
'0 AS is_main',
|
||||||
'COUNT(DISTINCT egw_addressbook.contact_id) AS org_count',
|
'COUNT(DISTINCT egw_addressbook.contact_id) AS org_count',
|
||||||
@ -195,7 +203,7 @@ class addressbook_sql extends so_sql_cf
|
|||||||
|
|
||||||
// query the values for *_count == 1, to display them instead
|
// query the values for *_count == 1, to display them instead
|
||||||
$filter['org_name'] = $orgs = array();
|
$filter['org_name'] = $orgs = array();
|
||||||
foreach($rows as $n => $row)
|
foreach($rows as $row)
|
||||||
{
|
{
|
||||||
if ($row['org_unit_count'] == 1 || $row['adr_one_locality_count'] == 1)
|
if ($row['org_unit_count'] == 1 || $row['adr_one_locality_count'] == 1)
|
||||||
{
|
{
|
||||||
@ -208,7 +216,8 @@ class addressbook_sql extends so_sql_cf
|
|||||||
|
|
||||||
if (count($filter['org_name']))
|
if (count($filter['org_name']))
|
||||||
{
|
{
|
||||||
foreach((array) parent::search($criteria,array('org_name','org_unit','adr_one_locality'),'GROUP BY org_name,org_unit,adr_one_locality',
|
foreach((array) parent::search(null, array('org_name','org_unit','adr_one_locality'),
|
||||||
|
'GROUP BY org_name,org_unit,adr_one_locality',
|
||||||
'',$wildcard,false,$op/*'AND'*/,false,$filter) as $row)
|
'',$wildcard,false,$op/*'AND'*/,false,$filter) as $row)
|
||||||
{
|
{
|
||||||
$org_key = $row['org_name'].($by ? '|||'.$row[$by] : '');
|
$org_key = $row['org_name'].($by ? '|||'.$row[$by] : '');
|
||||||
@ -243,11 +252,11 @@ class addressbook_sql extends so_sql_cf
|
|||||||
*
|
*
|
||||||
* For a union-query you call search for each query with $start=='UNION' and one more with only $order_by and $start set to run the union-query.
|
* For a union-query you call search for each query with $start=='UNION' and one more with only $order_by and $start set to run the union-query.
|
||||||
*
|
*
|
||||||
* @param array/string $criteria array of key and data cols, OR a SQL query (content for WHERE), fully quoted (!)
|
* @param array|string $criteria array of key and data cols, OR a SQL query (content for WHERE), fully quoted (!)
|
||||||
* @param boolean/string/array $only_keys=true True returns only keys, False returns all cols. or
|
* @param boolean|string|array $only_keys =true True returns only keys, False returns all cols. or
|
||||||
* comma seperated list or array of columns to return
|
* comma seperated list or array of columns to return
|
||||||
* @param string $order_by ='' fieldnames + {ASC|DESC} separated by colons ',', can also contain a GROUP BY (if it contains ORDER BY)
|
* @param string $order_by ='' fieldnames + {ASC|DESC} separated by colons ',', can also contain a GROUP BY (if it contains ORDER BY)
|
||||||
* @param string/array $extra_cols='' string or array of strings to be added to the SELECT, eg. "count(*) as num"
|
* @param string|array $extra_cols ='' string or array of strings to be added to the SELECT, eg. "count(*) as num"
|
||||||
* @param string $wildcard ='' appended befor and after each criteria
|
* @param string $wildcard ='' appended befor and after each criteria
|
||||||
* @param boolean $empty =false False=empty criteria are ignored in query, True=empty have to be empty in row
|
* @param boolean $empty =false False=empty criteria are ignored in query, True=empty have to be empty in row
|
||||||
* @param string $op ='AND' defaults to 'AND', can be set to 'OR' too, then criteria's are OR'ed together
|
* @param string $op ='AND' defaults to 'AND', can be set to 'OR' too, then criteria's are OR'ed together
|
||||||
@ -360,7 +369,9 @@ class addressbook_sql extends so_sql_cf
|
|||||||
// fall through
|
// fall through
|
||||||
}
|
}
|
||||||
// postgres requires that expressions in order by appear in the columns of a distinct select
|
// postgres requires that expressions in order by appear in the columns of a distinct select
|
||||||
if ($this->db->Type != 'mysql' && preg_match_all("/(#?[a-zA-Z_.]+) *(<> *''|IS NULL|IS NOT NULL)? *(ASC|DESC)?(,|$)/ui",$order_by,$all_matches,PREG_SET_ORDER))
|
$all_matches = null;
|
||||||
|
if ($this->db->Type != 'mysql' && preg_match_all("/(#?[a-zA-Z_.]+) *(<> *''|IS NULL|IS NOT NULL)? *(ASC|DESC)?(,|$)/ui",
|
||||||
|
$order_by, $all_matches, PREG_SET_ORDER))
|
||||||
{
|
{
|
||||||
if (!is_array($extra_cols)) $extra_cols = $extra_cols ? explode(',',$extra_cols) : array();
|
if (!is_array($extra_cols)) $extra_cols = $extra_cols ? explode(',',$extra_cols) : array();
|
||||||
foreach($all_matches as $matches)
|
foreach($all_matches as $matches)
|
||||||
@ -394,10 +405,12 @@ class addressbook_sql extends so_sql_cf
|
|||||||
// Understand search by date with wildcard (????.10.??) according to user date preference
|
// Understand search by date with wildcard (????.10.??) according to user date preference
|
||||||
if(is_string($criteria) && strpos($criteria, '?') !== false)
|
if(is_string($criteria) && strpos($criteria, '?') !== false)
|
||||||
{
|
{
|
||||||
$date_format = $GLOBALS['egw_info']['user']['preferences']['common']['dateformat'];
|
|
||||||
// First, check for a 'date', with wildcards, in the user's format
|
// First, check for a 'date', with wildcards, in the user's format
|
||||||
$date_regex = str_replace(array('Y','m','d','.','-'), array('(?P<Y>(?:\?|\Q){4})','(?P<m>(?:\?|\Q){2})','(?P<d>(?:\?|\Q){2})','\.','\-'),$date_format);
|
$date_regex = str_replace('Q','d',
|
||||||
$date_regex = str_replace('Q','d',$date_regex);
|
str_replace(array('Y','m','d','.','-'),
|
||||||
|
array('(?P<Y>(?:\?|\Q){4})','(?P<m>(?:\?|\Q){2})','(?P<d>(?:\?|\Q){2})','\.','\-'),
|
||||||
|
$GLOBALS['egw_info']['user']['preferences']['common']['dateformat']));
|
||||||
|
|
||||||
if(preg_match_all('$'.$date_regex.'$', $criteria, $matches))
|
if(preg_match_all('$'.$date_regex.'$', $criteria, $matches))
|
||||||
{
|
{
|
||||||
foreach($matches[0] as $m_id => $match)
|
foreach($matches[0] as $m_id => $match)
|
||||||
@ -467,7 +480,7 @@ class addressbook_sql extends so_sql_cf
|
|||||||
{
|
{
|
||||||
if (!$new_owner) // otherwise we would create an account (contact_owner==0)
|
if (!$new_owner) // otherwise we would create an account (contact_owner==0)
|
||||||
{
|
{
|
||||||
throw egw_exception_wrong_parameter(__METHOD__."($account_id, $new_owner) new owner must not be 0!");
|
throw Api\Exception\WrongParameter(__METHOD__."($account_id, $new_owner) new owner must not be 0!");
|
||||||
}
|
}
|
||||||
// contacts
|
// contacts
|
||||||
$this->db->update($this->table_name,array(
|
$this->db->update($this->table_name,array(
|
||||||
@ -690,7 +703,7 @@ class addressbook_sql extends so_sql_cf
|
|||||||
/**
|
/**
|
||||||
* Deletes a distribution list (incl. it's members)
|
* Deletes a distribution list (incl. it's members)
|
||||||
*
|
*
|
||||||
* @param int/array $list list_id(s)
|
* @param int|array $list list_id(s)
|
||||||
* @return number of members deleted or false if list does not exist
|
* @return number of members deleted or false if list does not exist
|
||||||
*/
|
*/
|
||||||
function delete_list($list)
|
function delete_list($list)
|
||||||
@ -745,7 +758,7 @@ class addressbook_sql extends so_sql_cf
|
|||||||
}
|
}
|
||||||
// catch Illegal mix of collations (ascii_general_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '=' (1267)
|
// catch Illegal mix of collations (ascii_general_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '=' (1267)
|
||||||
// caused by non-ascii chars compared with ascii field uid
|
// caused by non-ascii chars compared with ascii field uid
|
||||||
catch(egw_exception_db $e) {
|
catch(Api\Db\Exception $e) {
|
||||||
_egw_log_exception($e);
|
_egw_log_exception($e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -767,6 +780,8 @@ class addressbook_sql extends so_sql_cf
|
|||||||
*/
|
*/
|
||||||
function save($keys = NULL, $extra_where = NULL)
|
function save($keys = NULL, $extra_where = NULL)
|
||||||
{
|
{
|
||||||
|
unset($extra_where); // not used, but required by function signature
|
||||||
|
|
||||||
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'])) {
|
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'])) {
|
||||||
$minimum_uid_length = $GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'];
|
$minimum_uid_length = $GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'];
|
||||||
} else {
|
} else {
|
1138
api/src/Contacts/Storage.php
Executable file
1138
api/src/Contacts/Storage.php
Executable file
File diff suppressed because it is too large
Load Diff
@ -1,19 +1,27 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Addressbook - history and notifications
|
* EGroupware API - Contacts history and notifications
|
||||||
*
|
*
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @package addressbook
|
* @package api
|
||||||
* @copyright (c) 2007 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @subpackage contacts
|
||||||
|
* @copyright (c) 2007-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace EGroupware\Api\Contacts;
|
||||||
|
|
||||||
|
use EGroupware\Api;
|
||||||
|
|
||||||
|
// explicitly reference classes still in phpgwapi
|
||||||
|
use common;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Addressbook - tracking object
|
* Contacts history and notifications
|
||||||
*/
|
*/
|
||||||
class addressbook_tracking extends bo_tracking
|
class Tracking extends Api\Storage\Tracking
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Application we are tracking (required!)
|
* Application we are tracking (required!)
|
||||||
@ -64,10 +72,10 @@ class addressbook_tracking extends bo_tracking
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param addressbook_bo $bocontacts
|
* @param Api\Contacts $bocontacts
|
||||||
* @return tracker_tracking
|
* @return tracker_tracking
|
||||||
*/
|
*/
|
||||||
function __construct(addressbook_bo $bocontacts)
|
function __construct(Api\Contacts $bocontacts)
|
||||||
{
|
{
|
||||||
$this->contacts = $bocontacts;
|
$this->contacts = $bocontacts;
|
||||||
|
|
||||||
@ -93,7 +101,7 @@ class addressbook_tracking extends bo_tracking
|
|||||||
/**
|
/**
|
||||||
* Get a notification-config value
|
* Get a notification-config value
|
||||||
*
|
*
|
||||||
* @param string $what
|
* @param string $name
|
||||||
* - 'copy' array of email addresses notifications should be copied too, can depend on $data
|
* - 'copy' array of email addresses notifications should be copied too, can depend on $data
|
||||||
* - 'lang' string lang code for copy mail
|
* - 'lang' string lang code for copy mail
|
||||||
* - 'sender' string send email address
|
* - 'sender' string send email address
|
||||||
@ -103,7 +111,9 @@ class addressbook_tracking extends bo_tracking
|
|||||||
*/
|
*/
|
||||||
function get_config($name,$data,$old=null)
|
function get_config($name,$data,$old=null)
|
||||||
{
|
{
|
||||||
//echo "<p>addressbook_tracking::get_config($name,".print_r($data,true).",...)</p>\n";
|
unset($old); // not used, but required by function signature
|
||||||
|
|
||||||
|
//echo "<p>".__METHOD__."($name,".print_r($data,true).",...)</p>\n";
|
||||||
switch($name)
|
switch($name)
|
||||||
{
|
{
|
||||||
case 'copy':
|
case 'copy':
|
||||||
@ -180,6 +190,8 @@ class addressbook_tracking extends bo_tracking
|
|||||||
*/
|
*/
|
||||||
protected function get_message($data,$old,$receiver=null)
|
protected function get_message($data,$old,$receiver=null)
|
||||||
{
|
{
|
||||||
|
unset($receiver); // not used, but required by function signature
|
||||||
|
|
||||||
if (!$data['modified'] || !$old)
|
if (!$data['modified'] || !$old)
|
||||||
{
|
{
|
||||||
return lang('New contact submitted by %1 at %2',
|
return lang('New contact submitted by %1 at %2',
|
||||||
@ -202,6 +214,8 @@ class addressbook_tracking extends bo_tracking
|
|||||||
*/
|
*/
|
||||||
protected function get_subject($data,$old,$deleted=null,$receiver=null)
|
protected function get_subject($data,$old,$deleted=null,$receiver=null)
|
||||||
{
|
{
|
||||||
|
unset($old, $deleted, $receiver); // not used, but required by function signature
|
||||||
|
|
||||||
if ($data['is_contactform'])
|
if ($data['is_contactform'])
|
||||||
{
|
{
|
||||||
$prefix = ($data['subject_contactform'] ? $data['subject_contactform'] : lang('Contactform')).': ';
|
$prefix = ($data['subject_contactform'] ? $data['subject_contactform'] : lang('Contactform')).': ';
|
||||||
@ -218,6 +232,8 @@ class addressbook_tracking extends bo_tracking
|
|||||||
*/
|
*/
|
||||||
function get_details($data,$receiver=null)
|
function get_details($data,$receiver=null)
|
||||||
{
|
{
|
||||||
|
unset($receiver); // not used, but required by function signature
|
||||||
|
|
||||||
foreach($this->contacts->contact_fields as $name => $label)
|
foreach($this->contacts->contact_fields as $name => $label)
|
||||||
{
|
{
|
||||||
if (!$data[$name] && $name != 'owner') continue;
|
if (!$data[$name] && $name != 'owner') continue;
|
@ -1,20 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Addressbook - Univention Backend
|
* EGroupware API: Contacts Univention Backend
|
||||||
*
|
*
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Ralf Becker <rb@stylite.de>
|
* @author Ralf Becker <rb@stylite.de>
|
||||||
* @package addressbook
|
* @package api
|
||||||
|
* @subpackage contacts
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace EGroupware\Api\Contacts;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Univention backend for addressbook
|
* Univention backend for addressbook
|
||||||
*
|
*
|
||||||
* Different mail attribute is only difference to LDAP backend
|
* Different mail attribute is only difference to LDAP backend
|
||||||
*/
|
*/
|
||||||
class addressbook_univention extends addressbook_ldap
|
class Univention extends Ldap
|
||||||
{
|
{
|
||||||
function __construct($ldap_config = null, $ds = null)
|
function __construct($ldap_config = null, $ds = null)
|
||||||
{
|
{
|
263
api/src/Ldap.php
Normal file
263
api/src/Ldap.php
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* EGroupware API - LDAP connection handling
|
||||||
|
*
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Lars Kneschke <l.kneschke@metaways.de>
|
||||||
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
|
*
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package api
|
||||||
|
* @subpackage ldap
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace EGroupware\Api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LDAP connection handling
|
||||||
|
*
|
||||||
|
* Please note for SSL or TLS connections hostname has to be:
|
||||||
|
* - SSL: "ldaps://host[:port]/"
|
||||||
|
* - TLS: "tls://host[:port]/"
|
||||||
|
* Both require certificats installed on the webserver, otherwise the connection will fail!
|
||||||
|
*
|
||||||
|
* If multiple (space-separated) ldap hosts or urls are given, try them in order and
|
||||||
|
* move first successful one to first place in session, to try not working ones
|
||||||
|
* only once per session.
|
||||||
|
*/
|
||||||
|
class Ldap
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Holds the LDAP link identifier
|
||||||
|
*
|
||||||
|
* @var resource $ds
|
||||||
|
*/
|
||||||
|
var $ds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds the detected information about the connected ldap server
|
||||||
|
*
|
||||||
|
* @var Ldap\ServerInfo $ldapserverinfo
|
||||||
|
*/
|
||||||
|
var $ldapserverinfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throw Exceptions in ldapConnect instead of echoing error and returning false
|
||||||
|
*
|
||||||
|
* @var boolean $exception_on_error
|
||||||
|
*/
|
||||||
|
var $exception_on_error=false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param boolean $exception_on_error =false true: throw Exceptions in ldapConnect instead of echoing error and returning false
|
||||||
|
*/
|
||||||
|
function __construct($exception_on_error=false)
|
||||||
|
{
|
||||||
|
$this->exception_on_error = $exception_on_error;
|
||||||
|
$this->restoreSessionData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information about connected ldap server
|
||||||
|
*
|
||||||
|
* @return Ldap\ServerInfo|null
|
||||||
|
*/
|
||||||
|
function getLDAPServerInfo()
|
||||||
|
{
|
||||||
|
return $this->ldapserverinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* escapes a string for use in searchfilters meant for ldap_search.
|
||||||
|
*
|
||||||
|
* Escaped Characters are: '*', '(', ')', ' ', '\', NUL
|
||||||
|
* It's actually a PHP-Bug, that we have to escape space.
|
||||||
|
* For all other Characters, refer to RFC2254.
|
||||||
|
*
|
||||||
|
* @param string|array $string either a string to be escaped, or an array of values to be escaped
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
static function quote($string)
|
||||||
|
{
|
||||||
|
return str_replace(array('\\','*','(',')','\0',' '),array('\\\\','\*','\(','\)','\\0','\20'),$string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a single ldap result into a associative array
|
||||||
|
*
|
||||||
|
* @param array $ldap array with numerical and associative indexes and count's
|
||||||
|
* @return boolean|array with only associative index and no count's or false on error (parm is no array)
|
||||||
|
*/
|
||||||
|
static function result2array($ldap)
|
||||||
|
{
|
||||||
|
if (!is_array($ldap)) return false;
|
||||||
|
|
||||||
|
$arr = array();
|
||||||
|
foreach($ldap as $var => $val)
|
||||||
|
{
|
||||||
|
if (is_int($var) || $var == 'count') continue;
|
||||||
|
|
||||||
|
if (is_array($val) && $val['count'] == 1)
|
||||||
|
{
|
||||||
|
$arr[$var] = $val[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (is_array($val)) unset($val['count']);
|
||||||
|
|
||||||
|
$arr[$var] = $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to ldap server and return a handle
|
||||||
|
*
|
||||||
|
* If multiple (space-separated) ldap hosts or urls are given, try them in order and
|
||||||
|
* move first successful one to first place in session, to try not working ones
|
||||||
|
* only once per session.
|
||||||
|
*
|
||||||
|
* @param $host ='' ldap host, default $GLOBALS['egw_info']['server']['ldap_host']
|
||||||
|
* @param $dn ='' ldap dn, default $GLOBALS['egw_info']['server']['ldap_root_dn']
|
||||||
|
* @param $passwd ='' ldap pw, default $GLOBALS['egw_info']['server']['ldap_root_pw']
|
||||||
|
* @return resource|boolean resource from ldap_connect() or false on error
|
||||||
|
* @throws Exception\AssertingFailed 'LDAP support unavailable!' (no ldap extension)
|
||||||
|
*/
|
||||||
|
function ldapConnect($host='', $dn='', $passwd='')
|
||||||
|
{
|
||||||
|
if(!function_exists('ldap_connect'))
|
||||||
|
{
|
||||||
|
if ($this->exception_on_error) throw new Exception\AssertionFailed('LDAP support unavailable!');
|
||||||
|
|
||||||
|
printf('<b>Error: LDAP support unavailable</b><br>',$host);
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
if (empty($host))
|
||||||
|
{
|
||||||
|
$host = $GLOBALS['egw_info']['server']['ldap_host'];
|
||||||
|
}
|
||||||
|
if (empty($dn))
|
||||||
|
{
|
||||||
|
$dn = $GLOBALS['egw_info']['server']['ldap_root_dn'];
|
||||||
|
$passwd = $GLOBALS['egw_info']['server']['ldap_root_pw'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// if multiple hosts given, try them all, but only once per session!
|
||||||
|
if (isset($_SESSION) && isset($_SESSION['ldapConnect']) && isset($_SESSION['ldapConnect'][$host]))
|
||||||
|
{
|
||||||
|
$host = $_SESSION['ldapConnect'][$host];
|
||||||
|
}
|
||||||
|
foreach($hosts=preg_split('/[ ,;]+/', $host) as $h)
|
||||||
|
{
|
||||||
|
if ($this->_connect($h, $dn, $passwd))
|
||||||
|
{
|
||||||
|
if ($h !== $host)
|
||||||
|
{
|
||||||
|
if (isset($_SESSION)) // store working host as first choice in session
|
||||||
|
{
|
||||||
|
$_SESSION['ldapConnect'][$host] = implode(' ',array_unique(array_merge(array($h),$hosts)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->ds;
|
||||||
|
}
|
||||||
|
error_log(__METHOD__."('$h', '$dn', \$passwd) Can't connect/bind to ldap server!".
|
||||||
|
($this->ds ? ' '.ldap_error($this->ds).' ('.ldap_errno($this->ds).')' : '').
|
||||||
|
' '.function_backtrace());
|
||||||
|
}
|
||||||
|
// give visible error, only if we cant connect to any ldap server
|
||||||
|
if ($this->exception_on_error) throw new Exception\NoPermission("Can't connect/bind to LDAP server '$host' and dn='$dn'!");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* connect to the ldap server and return a handle
|
||||||
|
*
|
||||||
|
* @param string $host ldap host
|
||||||
|
* @param string $dn ldap dn
|
||||||
|
* @param string $passwd ldap pw
|
||||||
|
* @return resource|boolean resource from ldap_connect() or false on error
|
||||||
|
*/
|
||||||
|
private function _connect($host, $dn, $passwd)
|
||||||
|
{
|
||||||
|
if (($use_tls = substr($host,0,6) == 'tls://'))
|
||||||
|
{
|
||||||
|
$port = parse_url($host,PHP_URL_PORT);
|
||||||
|
$host = parse_url($host,PHP_URL_HOST);
|
||||||
|
}
|
||||||
|
// connect to ldap server (never fails, as connection happens in bind!)
|
||||||
|
if(!($this->ds = !empty($port) ? ldap_connect($host, $port) : ldap_connect($host)))
|
||||||
|
{
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
// set network timeout to not block for minutes
|
||||||
|
ldap_set_option($this->ds, LDAP_OPT_NETWORK_TIMEOUT, 5);
|
||||||
|
|
||||||
|
if(ldap_set_option($this->ds, LDAP_OPT_PROTOCOL_VERSION, 3))
|
||||||
|
{
|
||||||
|
$supportedLDAPVersion = 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$supportedLDAPVersion = 2;
|
||||||
|
}
|
||||||
|
if ($use_tls) ldap_start_tls($this->ds);
|
||||||
|
|
||||||
|
if (!isset($this->ldapserverinfo) ||
|
||||||
|
!is_a($this->ldapserverinfo,'EGroupware\Ldap\ServerInfo') ||
|
||||||
|
$this->ldapserverinfo->host != $host)
|
||||||
|
{
|
||||||
|
//error_log("no ldap server info found");
|
||||||
|
@ldap_bind($this->ds, $GLOBALS['egw_info']['server']['ldap_root_dn'], $GLOBALS['egw_info']['server']['ldap_root_pw']);
|
||||||
|
|
||||||
|
$this->ldapserverinfo = Ldap\ServerInfo::get($this->ds, $host, $supportedLDAPVersion);
|
||||||
|
$this->saveSessionData();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!@ldap_bind($this->ds, $dn, $passwd))
|
||||||
|
{
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->ds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* disconnect from the ldap server
|
||||||
|
*/
|
||||||
|
function ldapDisconnect()
|
||||||
|
{
|
||||||
|
if(is_resource($this->ds))
|
||||||
|
{
|
||||||
|
ldap_unbind($this->ds);
|
||||||
|
unset($this->ds);
|
||||||
|
unset($this->ldapserverinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* restore the session data
|
||||||
|
*/
|
||||||
|
function restoreSessionData()
|
||||||
|
{
|
||||||
|
if (isset($GLOBALS['egw']->session)) // no availible in setup
|
||||||
|
{
|
||||||
|
$this->ldapserverinfo = Cache::getSession(__CLASS__, 'ldapServerInfo');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* save the session data
|
||||||
|
*/
|
||||||
|
function saveSessionData()
|
||||||
|
{
|
||||||
|
if (isset($GLOBALS['egw']->session)) // no availible in setup
|
||||||
|
{
|
||||||
|
Cache::getSession(__CLASS__, 'ldapServerInfo', $this->ldapserverinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
243
api/src/Ldap/ServerInfo.php
Normal file
243
api/src/Ldap/ServerInfo.php
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* EGroupware API - LDAP server information
|
||||||
|
*
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Lars Kneschke <l.kneschke@metaways.de>
|
||||||
|
*
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package api
|
||||||
|
* @subpackage ldap
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace EGroupware\Api\Ldap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to store and retrieve information (eg. supported object classes) of a connected ldap server
|
||||||
|
*/
|
||||||
|
class ServerInfo
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Unknown LDAP server
|
||||||
|
*/
|
||||||
|
const UNKNOWN = 0;
|
||||||
|
/**
|
||||||
|
* OpenLDAP server
|
||||||
|
*/
|
||||||
|
const OPENLDAP = 1;
|
||||||
|
/**
|
||||||
|
* Samba4 LDAP server
|
||||||
|
*/
|
||||||
|
const SAMBA4 = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array $namingContext holds the supported namingcontexts
|
||||||
|
*/
|
||||||
|
var $namingContext = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string $version holds the LDAP server version
|
||||||
|
*/
|
||||||
|
var $version = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var integer $serverType holds the type of LDAP server(OpenLDAP, ADS, NDS, ...)
|
||||||
|
*/
|
||||||
|
var $serverType = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string $_subSchemaEntry the subschema entry DN
|
||||||
|
*/
|
||||||
|
var $subSchemaEntry = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array $supportedObjectClasses the supported objectclasses
|
||||||
|
*/
|
||||||
|
var $supportedObjectClasses = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array $supportedOIDs the supported OIDs
|
||||||
|
*/
|
||||||
|
var $supportedOIDs = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of host
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $host;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param string $host
|
||||||
|
*/
|
||||||
|
function __construct($host)
|
||||||
|
{
|
||||||
|
$this->host = $host;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets the version
|
||||||
|
*
|
||||||
|
* @return integer the supported ldap version
|
||||||
|
*/
|
||||||
|
function getVersion()
|
||||||
|
{
|
||||||
|
return $this->version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the namingcontexts
|
||||||
|
*
|
||||||
|
* @param array $_namingContext the supported namingcontexts
|
||||||
|
*/
|
||||||
|
function setNamingContexts($_namingContext)
|
||||||
|
{
|
||||||
|
$this->namingContext = $_namingContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the type of the ldap server(OpenLDAP, ADS, NDS, ...)
|
||||||
|
*
|
||||||
|
* @param integer $_serverType the type of ldap server
|
||||||
|
*/
|
||||||
|
function setServerType($_serverType)
|
||||||
|
{
|
||||||
|
$this->serverType = $_serverType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the DN for the subschema entry
|
||||||
|
*
|
||||||
|
* @param string $_subSchemaEntry the subschema entry DN
|
||||||
|
*/
|
||||||
|
function setSubSchemaEntry($_subSchemaEntry)
|
||||||
|
{
|
||||||
|
$this->subSchemaEntry = $_subSchemaEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the supported objectclasses
|
||||||
|
*
|
||||||
|
* @param array $_supportedObjectClasses the supported objectclasses
|
||||||
|
*/
|
||||||
|
function setSupportedObjectClasses($_supportedObjectClasses)
|
||||||
|
{
|
||||||
|
$this->supportedOIDs = $_supportedObjectClasses;
|
||||||
|
$this->supportedObjectClasses = array_flip($_supportedObjectClasses);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the version
|
||||||
|
*
|
||||||
|
* @param integer $_version the supported ldap version
|
||||||
|
*/
|
||||||
|
function setVersion($_version)
|
||||||
|
{
|
||||||
|
$this->version = $_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks for supported objectclasses
|
||||||
|
*
|
||||||
|
* @return bool returns true if the ldap server supports this objectclass
|
||||||
|
*/
|
||||||
|
function supportsObjectClass($_objectClass)
|
||||||
|
{
|
||||||
|
if($this->supportedObjectClasses[strtolower($_objectClass)])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query given ldap connection for available information
|
||||||
|
*
|
||||||
|
* @param resource $ds
|
||||||
|
* @param string $host
|
||||||
|
* @param int $version 2 or 3
|
||||||
|
* @return ldapserverinfo
|
||||||
|
*/
|
||||||
|
public static function get($ds, $host, $version=3)
|
||||||
|
{
|
||||||
|
$filter='(objectclass=*)';
|
||||||
|
$justthese = array('structuralObjectClass','namingContexts','supportedLDAPVersion','subschemaSubentry','vendorname');
|
||||||
|
if(($sr = @ldap_read($ds, '', $filter, $justthese)))
|
||||||
|
{
|
||||||
|
if(($info = ldap_get_entries($ds, $sr)))
|
||||||
|
{
|
||||||
|
$ldapServerInfo = new ServerInfo($host);
|
||||||
|
$ldapServerInfo->setVersion($version);
|
||||||
|
|
||||||
|
// check for naming contexts
|
||||||
|
if($info[0]['namingcontexts'])
|
||||||
|
{
|
||||||
|
for($i=0; $i<$info[0]['namingcontexts']['count']; $i++)
|
||||||
|
{
|
||||||
|
$namingcontexts[] = $info[0]['namingcontexts'][$i];
|
||||||
|
}
|
||||||
|
$ldapServerInfo->setNamingContexts($namingcontexts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for ldap server type
|
||||||
|
if($info[0]['structuralobjectclass'])
|
||||||
|
{
|
||||||
|
switch($info[0]['structuralobjectclass'][0])
|
||||||
|
{
|
||||||
|
case 'OpenLDAProotDSE':
|
||||||
|
$ldapServerType = OPENLDAP_LDAPSERVER;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$ldapServerType = UNKNOWN_LDAPSERVER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$ldapServerInfo->setServerType($ldapServerType);
|
||||||
|
}
|
||||||
|
if ($info[0]['vendorname'] && stripos($info[0]['vendorname'][0], 'samba') !== false)
|
||||||
|
{
|
||||||
|
$ldapServerInfo->setServerType(SAMBA4_LDAPSERVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for subschema entry dn
|
||||||
|
if($info[0]['subschemasubentry'])
|
||||||
|
{
|
||||||
|
$subschemasubentry = $info[0]['subschemasubentry'][0];
|
||||||
|
$ldapServerInfo->setSubSchemaEntry($subschemasubentry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create list of supported objetclasses
|
||||||
|
if(!empty($subschemasubentry))
|
||||||
|
{
|
||||||
|
$filter='(objectclass=*)';
|
||||||
|
$justthese = array('objectClasses');
|
||||||
|
|
||||||
|
if(($sr = ldap_read($ds, $subschemasubentry, $filter, $justthese)))
|
||||||
|
{
|
||||||
|
if(($info = ldap_get_entries($ds, $sr)))
|
||||||
|
{
|
||||||
|
if($info[0]['objectclasses']) {
|
||||||
|
for($i=0; $i<$info[0]['objectclasses']['count']; $i++)
|
||||||
|
{
|
||||||
|
$matches = null;
|
||||||
|
if(preg_match('/^\( (.*) NAME \'(\w*)\' /', $info[0]['objectclasses'][$i], $matches))
|
||||||
|
{
|
||||||
|
#_debug_array($matches);
|
||||||
|
if(count($matches) == 3)
|
||||||
|
{
|
||||||
|
$supportedObjectClasses[$matches[1]] = strtolower($matches[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$ldapServerInfo->setSupportedObjectClasses($supportedObjectClasses);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $ldapServerInfo;
|
||||||
|
}
|
||||||
|
}
|
@ -167,7 +167,7 @@ class Storage extends Storage\Base
|
|||||||
$this->extra_join_order = " LEFT JOIN $extra_table extra_order ON $table.$this->autoinc_id=extra_order.$this->extra_id";
|
$this->extra_join_order = " LEFT JOIN $extra_table extra_order ON $table.$this->autoinc_id=extra_order.$this->extra_id";
|
||||||
$this->extra_join_filter = " JOIN $extra_table extra_filter ON $table.$this->autoinc_id=extra_filter.$this->extra_id";
|
$this->extra_join_filter = " JOIN $extra_table extra_filter ON $table.$this->autoinc_id=extra_filter.$this->extra_id";
|
||||||
|
|
||||||
$this->customfields = Customfields::get($app, false, null, $db);
|
$this->customfields = Storage\Customfields::get($app, false, null, $db);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,7 +10,9 @@
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace EGroupware\Api;
|
namespace EGroupware\Api\Storage;
|
||||||
|
|
||||||
|
use EGroupware\Api;
|
||||||
|
|
||||||
// explicitly reference classes still in phpgwapi
|
// explicitly reference classes still in phpgwapi
|
||||||
use common;
|
use common;
|
||||||
@ -28,7 +30,7 @@ class Customfields implements \IteratorAggregate
|
|||||||
/**
|
/**
|
||||||
* Reference to the global db class
|
* Reference to the global db class
|
||||||
*
|
*
|
||||||
* @var Db
|
* @var Api\Db
|
||||||
*/
|
*/
|
||||||
static protected $db;
|
static protected $db;
|
||||||
|
|
||||||
@ -94,13 +96,13 @@ class Customfields implements \IteratorAggregate
|
|||||||
*/
|
*/
|
||||||
function getIterator()
|
function getIterator()
|
||||||
{
|
{
|
||||||
return new Db\CallbackIterator($this->iterator, function($_row)
|
return new Api\Db\CallbackIterator($this->iterator, function($_row)
|
||||||
{
|
{
|
||||||
$row = Db::strip_array_keys($_row, 'cf_');
|
$row = Api\Db::strip_array_keys($_row, 'cf_');
|
||||||
$row['private'] = $row['private'] ? explode(',', $row['private']) : array();
|
$row['private'] = $row['private'] ? explode(',', $row['private']) : array();
|
||||||
$row['type2'] = $row['type2'] ? explode(',', $row['type2']) : array();
|
$row['type2'] = $row['type2'] ? explode(',', $row['type2']) : array();
|
||||||
$row['values'] = json_decode($row['values'], true);
|
$row['values'] = json_decode($row['values'], true);
|
||||||
$row['needed'] = Db::from_bool($row['needed']);
|
$row['needed'] = Api\Db::from_bool($row['needed']);
|
||||||
|
|
||||||
return $row;
|
return $row;
|
||||||
}, array(), function($row)
|
}, array(), function($row)
|
||||||
@ -137,18 +139,18 @@ class Customfields implements \IteratorAggregate
|
|||||||
public static function get($app, $all_private_too=false, $only_type2=null, egw_db $db=null)
|
public static function get($app, $all_private_too=false, $only_type2=null, egw_db $db=null)
|
||||||
{
|
{
|
||||||
$cache_key = $app.':'.($all_private_too?'all':$GLOBALS['egw_info']['user']['account_id']).':'.$only_type2;
|
$cache_key = $app.':'.($all_private_too?'all':$GLOBALS['egw_info']['user']['account_id']).':'.$only_type2;
|
||||||
$cfs = Cache::getInstance(__CLASS__, $cache_key);
|
$cfs = Api\Cache::getInstance(__CLASS__, $cache_key);
|
||||||
|
|
||||||
if (!isset($cfs))
|
if (!isset($cfs))
|
||||||
{
|
{
|
||||||
$cfs = iterator_to_array(new Customfields($app, $all_private_too, $only_type2, 0, null, $db));
|
$cfs = iterator_to_array(new Customfields($app, $all_private_too, $only_type2, 0, null, $db));
|
||||||
|
|
||||||
Cache::setInstance(__CLASS__, $cache_key, $cfs);
|
Api\Cache::setInstance(__CLASS__, $cache_key, $cfs);
|
||||||
$cached = Cache::getInstance(__CLASS__, $app);
|
$cached = Api\Cache::getInstance(__CLASS__, $app);
|
||||||
if (!in_array($cache_key, (array)$cached))
|
if (!in_array($cache_key, (array)$cached))
|
||||||
{
|
{
|
||||||
$cached[] = $cache_key;
|
$cached[] = $cache_key;
|
||||||
Cache::setInstance(__CLASS__, $app, $cached);
|
Api\Cache::setInstance(__CLASS__, $app, $cached);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//error_log(__METHOD__."('$app', $all_private_too, '$only_type2') returning fields: ".implode(', ', array_keys($cfs)));
|
//error_log(__METHOD__."('$app', $all_private_too, '$only_type2') returning fields: ".implode(', ', array_keys($cfs)));
|
||||||
@ -224,7 +226,7 @@ class Customfields implements \IteratorAggregate
|
|||||||
case 'date-time':
|
case 'date-time':
|
||||||
if ($value)
|
if ($value)
|
||||||
{
|
{
|
||||||
$value = DateTime::to($value, $field['type'] == 'date' ? true : '');
|
$value = Api\DateTime::to($value, $field['type'] == 'date' ? true : '');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -461,13 +463,13 @@ class Customfields implements \IteratorAggregate
|
|||||||
*/
|
*/
|
||||||
protected static function invalidate_cache($app)
|
protected static function invalidate_cache($app)
|
||||||
{
|
{
|
||||||
if (($cached = Cache::getInstance(__CLASS__, $app)))
|
if (($cached = Api\Cache::getInstance(__CLASS__, $app)))
|
||||||
{
|
{
|
||||||
foreach($cached as $key)
|
foreach($cached as $key)
|
||||||
{
|
{
|
||||||
Cache::unsetInstance(__CLASS__, $key);
|
Api\Cache::unsetInstance(__CLASS__, $key);
|
||||||
}
|
}
|
||||||
Cache::unsetInstance(__CLASS__, $app);
|
Api\Cache::unsetInstance(__CLASS__, $app);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,7 +534,7 @@ class Customfields implements \IteratorAggregate
|
|||||||
/**
|
/**
|
||||||
* Initialise our db
|
* Initialise our db
|
||||||
*
|
*
|
||||||
* We use a reference here (no clone), as we no longer use Db::row() or Db::next_record()!
|
* We use a reference here (no clone), as we no longer use Api\Db::row() or Api\Db::next_record()!
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static function init_static()
|
public static function init_static()
|
288
api/src/Storage/History.php
Normal file
288
api/src/Storage/History.php
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* EGroupware API - Storage history logging
|
||||||
|
*
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Joseph Engo <jengo@phpgroupware.org>
|
||||||
|
* @copyright 2001 by Joseph Engo <jengo@phpgroupware.org>
|
||||||
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> new DB-methods and search
|
||||||
|
*
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package api
|
||||||
|
* @subpackage storage
|
||||||
|
* @access public
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace EGroupware\Api\Storage;
|
||||||
|
|
||||||
|
use EGroupware\Api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record history logging service
|
||||||
|
*
|
||||||
|
* This class need to be instanciated for EACH app, which wishes to use it!
|
||||||
|
*/
|
||||||
|
class History
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Reference to the global db object
|
||||||
|
*
|
||||||
|
* @var Api\Db
|
||||||
|
*/
|
||||||
|
var $db;
|
||||||
|
const TABLE = 'egw_history_log';
|
||||||
|
/**
|
||||||
|
* App.name this class is instanciated for / working on
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $appname;
|
||||||
|
var $user;
|
||||||
|
var $types = array(
|
||||||
|
'C' => 'Created',
|
||||||
|
'D' => 'Deleted',
|
||||||
|
'E' => 'Edited'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param string $appname app name this instance operates on
|
||||||
|
* @return historylog
|
||||||
|
*/
|
||||||
|
function __construct($appname='',$user=null)
|
||||||
|
{
|
||||||
|
$this->appname = $appname ? $appname : $GLOBALS['egw_info']['flags']['currentapp'];
|
||||||
|
$this->user = !is_null($user) ? $user : $GLOBALS['egw_info']['user']['account_id'];
|
||||||
|
|
||||||
|
if (is_object($GLOBALS['egw_setup']->db))
|
||||||
|
{
|
||||||
|
$this->db = $GLOBALS['egw_setup']->db;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->db = $GLOBALS['egw']->db;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the history-log of one or multiple records of $this->appname
|
||||||
|
*
|
||||||
|
* @param int|array $record_id one or more id's of $this->appname, or null to delete ALL records of $this->appname
|
||||||
|
* @return int number of deleted records/rows (0 is not necessaryly an error, it can just mean there's no record!)
|
||||||
|
*/
|
||||||
|
function delete($record_id)
|
||||||
|
{
|
||||||
|
$where = array('history_appname' => $this->appname);
|
||||||
|
|
||||||
|
if (is_array($record_id) || is_numeric($record_id))
|
||||||
|
{
|
||||||
|
$where['history_record_id'] = $record_id;
|
||||||
|
}
|
||||||
|
$this->db->delete(self::TABLE,$where,__LINE__,__FILE__);
|
||||||
|
|
||||||
|
return $this->db->affected_rows();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a history record, if $new_value != $old_value
|
||||||
|
*
|
||||||
|
* @param string $status 2 letter code: eg. $this->types: C=Created, D=Deleted, E=Edited
|
||||||
|
* @param int $record_id it of the record in $this->appname (set by the constructor)
|
||||||
|
* @param string $new_value new value
|
||||||
|
* @param string $old_value old value
|
||||||
|
*/
|
||||||
|
function add($status,$record_id,$new_value,$old_value)
|
||||||
|
{
|
||||||
|
if ($new_value != $old_value)
|
||||||
|
{
|
||||||
|
$this->db->insert(self::TABLE,array(
|
||||||
|
'history_record_id' => $record_id,
|
||||||
|
'history_appname' => $this->appname,
|
||||||
|
'history_owner' => $this->user,
|
||||||
|
'history_status' => $status,
|
||||||
|
'history_new_value' => $new_value,
|
||||||
|
'history_old_value' => $old_value,
|
||||||
|
'history_timestamp' => time(),
|
||||||
|
'sessionid' => $GLOBALS['egw']->session->sessionid_access_log,
|
||||||
|
),false,__LINE__,__FILE__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static function to add a history record
|
||||||
|
*/
|
||||||
|
public static function static_add($appname, $id, $user, $field_code, $new_value, $old_value = '')
|
||||||
|
{
|
||||||
|
if ($new_value != $old_value)
|
||||||
|
{
|
||||||
|
$GLOBALS['egw']->db->insert(self::TABLE,array(
|
||||||
|
'history_record_id' => $id,
|
||||||
|
'history_appname' => $appname,
|
||||||
|
'history_owner' => (int)$user,
|
||||||
|
'history_status' => $field_code,
|
||||||
|
'history_new_value' => $new_value,
|
||||||
|
'history_old_value' => $old_value,
|
||||||
|
'history_timestamp' => time(),
|
||||||
|
'sessionid' => $GLOBALS['egw']->session->sessionid_access_log,
|
||||||
|
),false,__LINE__,__FILE__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search history-log
|
||||||
|
*
|
||||||
|
* @param array|int $filter array with filters, or int record_id
|
||||||
|
* @param string $order ='history_id' sorting after history_id is identical to history_timestamp
|
||||||
|
* @param string $sort ='DESC'
|
||||||
|
* @param int $limit =null only return this many entries
|
||||||
|
* @return array of arrays with keys id, record_id, appname, owner (account_id), status, new_value, old_value,
|
||||||
|
* timestamp (Y-m-d H:i:s in servertime), user_ts (timestamp in user-time)
|
||||||
|
*/
|
||||||
|
function search($filter,$order='history_id',$sort='DESC',$limit=null)
|
||||||
|
{
|
||||||
|
if (!is_array($filter)) $filter = is_numeric($filter) ? array('history_record_id' => $filter) : array();
|
||||||
|
|
||||||
|
if (!$order || !preg_match('/^[a-z0-9_]+$/i',$order) || !preg_match('/^(asc|desc)?$/i',$sort))
|
||||||
|
{
|
||||||
|
$orderby = 'ORDER BY history_id DESC';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$orderby = "ORDER BY $order $sort";
|
||||||
|
}
|
||||||
|
foreach($filter as $col => $value)
|
||||||
|
{
|
||||||
|
if (!is_numeric($col) && substr($col,0,8) != 'history_')
|
||||||
|
{
|
||||||
|
$filter['history_'.$col] = $value;
|
||||||
|
unset($filter[$col]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isset($filter['history_appname'])) $filter['history_appname'] = $this->appname;
|
||||||
|
|
||||||
|
// do not try to read all history entries of an app
|
||||||
|
if (!$filter['history_record_id']) return array();
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
foreach($this->db->select(self::TABLE, '*', $filter, __LINE__, __FILE__,
|
||||||
|
isset($limit) ? 0 : false, $orderby, 'phpgwapi', $limit) as $row)
|
||||||
|
{
|
||||||
|
$row['user_ts'] = $this->db->from_timestamp($row['history_timestamp']) + 3600 * $GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'];
|
||||||
|
$rows[] = Api\Db::strip_array_keys($row,'history_');
|
||||||
|
}
|
||||||
|
return $rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a slice of history records
|
||||||
|
*
|
||||||
|
* Similar to search(), except this one can take a start and a number of records
|
||||||
|
*
|
||||||
|
* @see Base::get_rows()
|
||||||
|
*/
|
||||||
|
public static function get_rows(&$query, &$rows)
|
||||||
|
{
|
||||||
|
$filter = array();
|
||||||
|
$rows = array();
|
||||||
|
$filter['history_appname'] = $query['appname'];
|
||||||
|
$filter['history_record_id'] = $query['record_id'];
|
||||||
|
if(is_array($query['colfilter'])) {
|
||||||
|
foreach($query['colfilter'] as $column => $value) {
|
||||||
|
$filter[$column] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($GLOBALS['egw']->db->Type == 'mysql' && $GLOBALS['egw']->db->ServerInfo['version'] >= 4.0)
|
||||||
|
{
|
||||||
|
$mysql_calc_rows = 'SQL_CALC_FOUND_ROWS ';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$total = $GLOBALS['egw']->db->select(self::TABLE,'COUNT(*)',$filter,__LINE__,__FILE__,false,'','phpgwapi',0)->fetchColumn();
|
||||||
|
}
|
||||||
|
// filter out private (or no longer defined) custom fields
|
||||||
|
if ($filter['history_appname'])
|
||||||
|
{
|
||||||
|
$to_or[] = "history_status NOT LIKE '#%'";
|
||||||
|
// explicitly allow "##" used to store iCal/vCard X-attributes
|
||||||
|
if (in_array($filter['history_appname'], array('calendar','infolog','addressbook')))
|
||||||
|
{
|
||||||
|
$to_or[] = "history_status LIKE '##%'";
|
||||||
|
}
|
||||||
|
if (($cfs = Customfields::get($filter['history_appname'])))
|
||||||
|
{
|
||||||
|
$to_or[] = 'history_status IN ('.implode(',', array_map(function($str)
|
||||||
|
{
|
||||||
|
return $GLOBALS['egw']->db->quote('#'.$str);
|
||||||
|
}, array_keys($cfs))).')';
|
||||||
|
}
|
||||||
|
$filter[] = '('.implode(' OR ', $to_or).')';
|
||||||
|
}
|
||||||
|
$_query = array(array(
|
||||||
|
'table' => self::TABLE,
|
||||||
|
'cols' => array('history_id', 'history_record_id','history_appname','history_owner','history_status','history_new_value', 'history_timestamp','history_old_value'),
|
||||||
|
'where' => $filter,
|
||||||
|
));
|
||||||
|
|
||||||
|
// Add in files, if possible
|
||||||
|
if($GLOBALS['egw_info']['user']['apps']['filemanager'] &&
|
||||||
|
$file = Api\Vfs\Sqlfs\StreamWrapper::url_stat("/apps/{$query['appname']}/{$query['record_id']}",STREAM_URL_STAT_LINK))
|
||||||
|
{
|
||||||
|
$_query[] = array(
|
||||||
|
'table' => Api\Vfs\Sqlfs\StreamWrapper::TABLE,
|
||||||
|
'cols' =>array('fs_id', 'fs_dir', "'filemanager'",'COALESCE(fs_modifier,fs_creator)',"'~file~'",'fs_name','fs_modified', 'fs_mime'),
|
||||||
|
'where' => array('fs_dir' => $file['ino'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$new_file_id = array();
|
||||||
|
foreach($GLOBALS['egw']->db->union(
|
||||||
|
$_query,
|
||||||
|
__LINE__, __FILE__,
|
||||||
|
' ORDER BY ' . ($query['order'] ? $query['order'] : 'history_timestamp') . ' ' . ($query['sort'] ? $query['sort'] : 'DESC'),
|
||||||
|
$query['start'],
|
||||||
|
$query['num_rows']
|
||||||
|
) as $row)
|
||||||
|
{
|
||||||
|
$row['user_ts'] = $GLOBALS['egw']->db->from_timestamp($row['history_timestamp']) + 3600 * $GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'];
|
||||||
|
|
||||||
|
// Explode multi-part values
|
||||||
|
foreach(array('history_new_value','history_old_value') as $field)
|
||||||
|
{
|
||||||
|
if(strpos($row[$field],Tracking::ONE2N_SEPERATOR) !== false)
|
||||||
|
{
|
||||||
|
$row[$field] = explode(Tracking::ONE2N_SEPERATOR,$row[$field]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get information needed for proper display
|
||||||
|
if($row['history_appname'] == 'filemanager')
|
||||||
|
{
|
||||||
|
$new_version = $new_file_id[$row['history_new_value']];
|
||||||
|
$new_file_id[$row['history_new_value']] = count($rows);
|
||||||
|
$path = Api\Vfs\Sqlfs\StreamWrapper::id2path($row['history_id']);
|
||||||
|
|
||||||
|
// Apparently we don't have to do anything with it, just ask...
|
||||||
|
// without this, previous versions are not handled properly
|
||||||
|
Api\Vfs::getExtraInfo($path);
|
||||||
|
|
||||||
|
$row['history_new_value'] = array(
|
||||||
|
'path' => $path,
|
||||||
|
'name' => Api\Vfs::basename($path),
|
||||||
|
'mime' => $row['history_old_value']
|
||||||
|
);
|
||||||
|
$row['history_old_value'] = '';
|
||||||
|
if($new_version !== null)
|
||||||
|
{
|
||||||
|
$rows[$new_version]['old_value'] = $row['history_new_value'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$rows[] = Api\Db::strip_array_keys($row,'history_');
|
||||||
|
}
|
||||||
|
if ($mysql_calc_rows)
|
||||||
|
{
|
||||||
|
$total = $GLOBALS['egw']->db->query('SELECT FOUND_ROWS()')->fetchColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $total;
|
||||||
|
}
|
||||||
|
}
|
1220
api/src/Storage/Tracking.php
Normal file
1220
api/src/Storage/Tracking.php
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -5,11 +5,13 @@
|
|||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @package setup
|
* @package setup
|
||||||
* @copyright (c) 2007-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @copyright (c) 2007-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use EGroupware\Api;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* setup command: test or create the ldap connection and hierarchy
|
* setup command: test or create the ldap connection and hierarchy
|
||||||
*
|
*
|
||||||
@ -121,7 +123,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
{
|
{
|
||||||
if (!empty($this->domain) && !preg_match('/^([a-z0-9_-]+\.)*[a-z0-9]+/i',$this->domain))
|
if (!empty($this->domain) && !preg_match('/^([a-z0-9_-]+\.)*[a-z0-9]+/i',$this->domain))
|
||||||
{
|
{
|
||||||
throw new egw_exception_wrong_userinput(lang("'%1' is no valid domain name!",$this->domain));
|
throw new Api\Exception\WrongUserinput(lang("'%1' is no valid domain name!",$this->domain));
|
||||||
}
|
}
|
||||||
if ($this->remote_id && $check_only && !in_array($this->sub_command, array('set_mailbox', 'sid2uidnumber', 'copy2ad')))
|
if ($this->remote_id && $check_only && !in_array($this->sub_command, array('set_mailbox', 'sid2uidnumber', 'copy2ad')))
|
||||||
{
|
{
|
||||||
@ -186,7 +188,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
// check if base does exist
|
// check if base does exist
|
||||||
if (!@ldap_read($this->test_ldap->ds,$this->ldap_base,'objectClass=*'))
|
if (!@ldap_read($this->test_ldap->ds,$this->ldap_base,'objectClass=*'))
|
||||||
{
|
{
|
||||||
throw new egw_exception_wrong_userinput(lang('Base dn "%1" NOT found!',$this->ldap_base));
|
throw new Api\Exception\WrongUserinput(lang('Base dn "%1" NOT found!',$this->ldap_base));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!($sr = ldap_search($this->test_ldap->ds,$this->ldap_base,
|
if (!($sr = ldap_search($this->test_ldap->ds,$this->ldap_base,
|
||||||
@ -194,7 +196,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
array('uidNumber','gidNumber','uid','cn', 'objectClass',self::sambaSID))) ||
|
array('uidNumber','gidNumber','uid','cn', 'objectClass',self::sambaSID))) ||
|
||||||
!($entries = ldap_get_entries($this->test_ldap->ds, $sr)))
|
!($entries = ldap_get_entries($this->test_ldap->ds, $sr)))
|
||||||
{
|
{
|
||||||
throw new egw_exception(lang('Error searching "dn=%1" for "%2"!',$this->ldap_base, $search));
|
throw new Api\Exception(lang('Error searching "dn=%1" for "%2"!',$this->ldap_base, $search));
|
||||||
}
|
}
|
||||||
$change = $accounts = array();
|
$change = $accounts = array();
|
||||||
$cmd_change_account_id = 'admin/admin-cli.php --change-account-id <admin>@<domain>,<adminpw>';
|
$cmd_change_account_id = 'admin/admin-cli.php --change-account-id <admin>@<domain>,<adminpw>';
|
||||||
@ -203,7 +205,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
{
|
{
|
||||||
if ($key === 'count') continue;
|
if ($key === 'count') continue;
|
||||||
|
|
||||||
$entry = ldap::result2array($entry);
|
$entry = Api\Ldap::result2array($entry);
|
||||||
$accounts[$entry['dn']] = $entry;
|
$accounts[$entry['dn']] = $entry;
|
||||||
//print_r($entry);
|
//print_r($entry);
|
||||||
|
|
||||||
@ -247,7 +249,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
}
|
}
|
||||||
if (!$check_only && $modify && !ldap_modify($this->test_ldap->ds, $dn, $modify))
|
if (!$check_only && $modify && !ldap_modify($this->test_ldap->ds, $dn, $modify))
|
||||||
{
|
{
|
||||||
throw new egw_exception("Failed to modify ldap: !ldap_modify({$this->test_ldap->ds}, '$dn', ".array2string($modify).") ".ldap_error($this->test_ldap->ds).
|
throw new Api\Exception("Failed to modify ldap: !ldap_modify({$this->test_ldap->ds}, '$dn', ".array2string($modify).") ".ldap_error($this->test_ldap->ds).
|
||||||
"\n- ".implode("\n- ", $msg)); // EGroupware change already run successful
|
"\n- ".implode("\n- ", $msg)); // EGroupware change already run successful
|
||||||
}
|
}
|
||||||
if ($modify) ++$changed;
|
if ($modify) ++$changed;
|
||||||
@ -313,7 +315,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
// check if ads base does exist
|
// check if ads base does exist
|
||||||
if (!@ldap_read($ads->ds, $this->ads_context, 'objectClass=*'))
|
if (!@ldap_read($ads->ds, $this->ads_context, 'objectClass=*'))
|
||||||
{
|
{
|
||||||
throw new egw_exception_wrong_userinput(lang('Ads dn "%1" NOT found!',$this->ads_context));
|
throw new Api\Exception\WrongUserInput(lang('Ads dn "%1" NOT found!',$this->ads_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect to source ldap
|
// connect to source ldap
|
||||||
@ -322,7 +324,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
// check if ldap base does exist
|
// check if ldap base does exist
|
||||||
if (!@ldap_read($this->test_ldap->ds,$this->ldap_base,'objectClass=*'))
|
if (!@ldap_read($this->test_ldap->ds,$this->ldap_base,'objectClass=*'))
|
||||||
{
|
{
|
||||||
throw new egw_exception_wrong_userinput(lang('Base dn "%1" NOT found!',$this->ldap_base));
|
throw new Api\Exception\WrongUserInput(lang('Base dn "%1" NOT found!',$this->ldap_base));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!($sr = ldap_search($this->test_ldap->ds,$this->ldap_base,
|
if (!($sr = ldap_search($this->test_ldap->ds,$this->ldap_base,
|
||||||
@ -330,7 +332,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
'(&(objectClass=posixAccount)('.self::sambaSID.'=*)(!(uid=*$)))', $attrs)) ||
|
'(&(objectClass=posixAccount)('.self::sambaSID.'=*)(!(uid=*$)))', $attrs)) ||
|
||||||
!($entries = ldap_get_entries($this->test_ldap->ds, $sr)))
|
!($entries = ldap_get_entries($this->test_ldap->ds, $sr)))
|
||||||
{
|
{
|
||||||
throw new egw_exception(lang('Error searching "dn=%1" for "%2"!',$this->ldap_base, $search));
|
throw new Api\Exception(lang('Error searching "dn=%1" for "%2"!',$this->ldap_base, $search));
|
||||||
}
|
}
|
||||||
$changed = 0;
|
$changed = 0;
|
||||||
$utc_diff = null;
|
$utc_diff = null;
|
||||||
@ -338,12 +340,12 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
{
|
{
|
||||||
if ($key === 'count') continue;
|
if ($key === 'count') continue;
|
||||||
|
|
||||||
$entry_arr = ldap::result2array($entry);
|
$entry_arr = Api\Ldap::result2array($entry);
|
||||||
$uid = $entry_arr['uid'];
|
$uid = $entry_arr['uid'];
|
||||||
$entry = array_diff_key($entry_arr, $ignore_attr);
|
$entry = array_diff_key($entry_arr, $ignore_attr);
|
||||||
|
|
||||||
if (!($sr = ldap_search($ads->ds, $this->ads_context,
|
if (!($sr = ldap_search($ads->ds, $this->ads_context,
|
||||||
$search='(&(objectClass=user)(sAMAccountName='.ldap::quote($uid).'))', array('dn'))) ||
|
$search='(&(objectClass=user)(sAMAccountName='.Api\Ldap::quote($uid).'))', array('dn'))) ||
|
||||||
!($dest = ldap_get_entries($ads->ds, $sr)))
|
!($dest = ldap_get_entries($ads->ds, $sr)))
|
||||||
{
|
{
|
||||||
$msg[] = lang('User "%1" not found!', $uid);
|
$msg[] = lang('User "%1" not found!', $uid);
|
||||||
@ -591,7 +593,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
// should we run any or some addAccount hooks
|
// should we run any or some addAccount hooks
|
||||||
if ($this->add_account_hook)
|
if ($this->add_account_hook)
|
||||||
{
|
{
|
||||||
// setting up egw_info array with new ldap information, so hook can use ldap::ldapConnect()
|
// setting up egw_info array with new ldap information, so hook can use Api\Ldap::ldapConnect()
|
||||||
if (!$egw_info_set++)
|
if (!$egw_info_set++)
|
||||||
{
|
{
|
||||||
foreach(array('ldap_host','ldap_root_dn','ldap_root_pw','ldap_context','ldap_group_context','ldap_search_filter','ldap_encryptin_type','mail_suffix','mail_login_type') as $name)
|
foreach(array('ldap_host','ldap_root_dn','ldap_root_pw','ldap_context','ldap_group_context','ldap_search_filter','ldap_encryptin_type','mail_suffix','mail_login_type') as $name)
|
||||||
@ -798,7 +800,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
* @param string $dn =null default $this->ldap_root_dn
|
* @param string $dn =null default $this->ldap_root_dn
|
||||||
* @param string $pw =null default $this->ldap_root_pw
|
* @param string $pw =null default $this->ldap_root_pw
|
||||||
* @param string $host =null default $this->ldap_host, hostname, ip or ldap-url
|
* @param string $host =null default $this->ldap_host, hostname, ip or ldap-url
|
||||||
* @throws egw_exception_wrong_userinput Can not connect to ldap ...
|
* @throws Api\Exception\WrongUserInput Can not connect to ldap ...
|
||||||
*/
|
*/
|
||||||
private function connect($dn=null,$pw=null,$host=null)
|
private function connect($dn=null,$pw=null,$host=null)
|
||||||
{
|
{
|
||||||
@ -806,9 +808,9 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
if (is_null($pw)) $pw = $this->ldap_root_pw;
|
if (is_null($pw)) $pw = $this->ldap_root_pw;
|
||||||
if (is_null($host)) $host = $this->ldap_host;
|
if (is_null($host)) $host = $this->ldap_host;
|
||||||
|
|
||||||
if (!$pw) // ldap::ldapConnect use the current eGW's pw otherwise
|
if (!$pw) // Api\Ldap::ldapConnect use the current eGW's pw otherwise
|
||||||
{
|
{
|
||||||
throw new egw_exception_wrong_userinput(lang('You need to specify a password!'));
|
throw new Api\Exception\WrongUserInput(lang('You need to specify a password!'));
|
||||||
}
|
}
|
||||||
$this->test_ldap = new ldap();
|
$this->test_ldap = new ldap();
|
||||||
|
|
||||||
@ -821,7 +823,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
|
|
||||||
if (!$ds)
|
if (!$ds)
|
||||||
{
|
{
|
||||||
throw new egw_exception_wrong_userinput(lang('Can not connect to LDAP server on host %1 using DN %2!',
|
throw new Api\Exception\WrongUserInput(lang('Can not connect to LDAP server on host %1 using DN %2!',
|
||||||
$host,$dn).($this->test_ldap->ds ? ' ('.ldap_error($this->test_ldap->ds).')' : ''));
|
$host,$dn).($this->test_ldap->ds ? ' ('.ldap_error($this->test_ldap->ds).')' : ''));
|
||||||
}
|
}
|
||||||
return lang('Successful connected to LDAP server on %1 using DN %2.',$this->ldap_host,$dn);
|
return lang('Successful connected to LDAP server on %1 using DN %2.',$this->ldap_host,$dn);
|
||||||
@ -831,7 +833,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
* Count active (not expired) users
|
* Count active (not expired) users
|
||||||
*
|
*
|
||||||
* @return int number of active users
|
* @return int number of active users
|
||||||
* @throws egw_exception_wrong_userinput
|
* @throws Api\Exception\WrongUserInput
|
||||||
*/
|
*/
|
||||||
private function users()
|
private function users()
|
||||||
{
|
{
|
||||||
@ -840,7 +842,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
$sr = ldap_list($this->test_ldap->ds,$this->ldap_context,'ObjectClass=posixAccount',array('dn','shadowExpire'));
|
$sr = ldap_list($this->test_ldap->ds,$this->ldap_context,'ObjectClass=posixAccount',array('dn','shadowExpire'));
|
||||||
if (!($entries = ldap_get_entries($this->test_ldap->ds, $sr)))
|
if (!($entries = ldap_get_entries($this->test_ldap->ds, $sr)))
|
||||||
{
|
{
|
||||||
throw new egw_exception('Error listing "dn=%1"!',$this->ldap_context);
|
throw new Api\Exception('Error listing "dn=%1"!',$this->ldap_context);
|
||||||
}
|
}
|
||||||
$num = 0;
|
$num = 0;
|
||||||
foreach($entries as $n => $entry)
|
foreach($entries as $n => $entry)
|
||||||
@ -856,7 +858,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
* Check and if does not yet exist create the new database and user
|
* Check and if does not yet exist create the new database and user
|
||||||
*
|
*
|
||||||
* @return string with success message
|
* @return string with success message
|
||||||
* @throws egw_exception_wrong_userinput
|
* @throws Api\Exception\WrongUserInput
|
||||||
*/
|
*/
|
||||||
private function create()
|
private function create()
|
||||||
{
|
{
|
||||||
@ -883,7 +885,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
* Delete whole LDAP tree of an instance dn=$this->ldap_base using $this->ldap_admin/_pw
|
* Delete whole LDAP tree of an instance dn=$this->ldap_base using $this->ldap_admin/_pw
|
||||||
*
|
*
|
||||||
* @return string with success message
|
* @return string with success message
|
||||||
* @throws egw_exception if dn not found, not listable or delete fails
|
* @throws Api\Exception if dn not found, not listable or delete fails
|
||||||
*/
|
*/
|
||||||
private function delete_base()
|
private function delete_base()
|
||||||
{
|
{
|
||||||
@ -897,12 +899,12 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
// some precausion to not delete whole ldap tree!
|
// some precausion to not delete whole ldap tree!
|
||||||
if (count(explode(',',$this->ldap_base)) < 2)
|
if (count(explode(',',$this->ldap_base)) < 2)
|
||||||
{
|
{
|
||||||
throw new egw_exception_assertion_failed(lang('Refusing to delete dn "%1"!',$this->ldap_base));
|
throw new Api\Exception\AssertionFailed(lang('Refusing to delete dn "%1"!',$this->ldap_base));
|
||||||
}
|
}
|
||||||
// check if base does exist
|
// check if base does exist
|
||||||
if (!@ldap_read($this->test_ldap->ds,$this->ldap_base,'objectClass=*'))
|
if (!@ldap_read($this->test_ldap->ds,$this->ldap_base,'objectClass=*'))
|
||||||
{
|
{
|
||||||
throw new egw_exception_wrong_userinput(lang('Base dn "%1" NOT found!',$this->ldap_base));
|
throw new Api\Exception\WrongUserInput(lang('Base dn "%1" NOT found!',$this->ldap_base));
|
||||||
}
|
}
|
||||||
return lang('LDAP dn="%1" with %2 entries deleted.',
|
return lang('LDAP dn="%1" with %2 entries deleted.',
|
||||||
$this->ldap_base,$this->rdelete($this->ldap_base));
|
$this->ldap_base,$this->rdelete($this->ldap_base));
|
||||||
@ -913,14 +915,14 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
*
|
*
|
||||||
* @param string $dn
|
* @param string $dn
|
||||||
* @return int integer number of deleted entries
|
* @return int integer number of deleted entries
|
||||||
* @throws egw_exception if dn not listable or delete fails
|
* @throws Api\Exception if dn not listable or delete fails
|
||||||
*/
|
*/
|
||||||
private function rdelete($dn)
|
private function rdelete($dn)
|
||||||
{
|
{
|
||||||
if (!($sr = ldap_list($this->test_ldap->ds,$dn,'ObjectClass=*',array(''))) ||
|
if (!($sr = ldap_list($this->test_ldap->ds,$dn,'ObjectClass=*',array(''))) ||
|
||||||
!($entries = ldap_get_entries($this->test_ldap->ds, $sr)))
|
!($entries = ldap_get_entries($this->test_ldap->ds, $sr)))
|
||||||
{
|
{
|
||||||
throw new egw_exception(lang('Error listing "dn=%1"!',$dn));
|
throw new Api\Exception(lang('Error listing "dn=%1"!',$dn));
|
||||||
}
|
}
|
||||||
$deleted = 0;
|
$deleted = 0;
|
||||||
foreach($entries as $n => $entry)
|
foreach($entries as $n => $entry)
|
||||||
@ -930,7 +932,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
}
|
}
|
||||||
if (!ldap_delete($this->test_ldap->ds,$dn))
|
if (!ldap_delete($this->test_ldap->ds,$dn))
|
||||||
{
|
{
|
||||||
throw new egw_exception(lang('Error deleting "dn=%1"!',$dn));
|
throw new Api\Exception(lang('Error deleting "dn=%1"!',$dn));
|
||||||
}
|
}
|
||||||
return ++$deleted;
|
return ++$deleted;
|
||||||
}
|
}
|
||||||
@ -944,7 +946,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
* @param string $this->mbox_attr ='mailmessagestore' lowercase!!!
|
* @param string $this->mbox_attr ='mailmessagestore' lowercase!!!
|
||||||
* @param string $this->mail_login_type ='email' 'email', 'vmailmgr', 'standard' or 'uidNumber'
|
* @param string $this->mail_login_type ='email' 'email', 'vmailmgr', 'standard' or 'uidNumber'
|
||||||
* @return string with success message N entries modified
|
* @return string with success message N entries modified
|
||||||
* @throws egw_exception if dn not found, not listable or delete fails
|
* @throws Api\Exception if dn not found, not listable or delete fails
|
||||||
*/
|
*/
|
||||||
private function set_mailbox($check_only=false)
|
private function set_mailbox($check_only=false)
|
||||||
{
|
{
|
||||||
@ -958,7 +960,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
// check if base does exist
|
// check if base does exist
|
||||||
if (!@ldap_read($this->test_ldap->ds,$this->ldap_base,'objectClass=*'))
|
if (!@ldap_read($this->test_ldap->ds,$this->ldap_base,'objectClass=*'))
|
||||||
{
|
{
|
||||||
throw new egw_exception_wrong_userinput(lang('Base dn "%1" NOT found!',$this->ldap_base));
|
throw new Api\Exception\WrongUserInput(lang('Base dn "%1" NOT found!',$this->ldap_base));
|
||||||
}
|
}
|
||||||
$object_class = $this->object_class ? $this->object_class : 'qmailUser';
|
$object_class = $this->object_class ? $this->object_class : 'qmailUser';
|
||||||
$mbox_attr = $this->mbox_attr ? $this->mbox_attr : 'mailmessagestore';
|
$mbox_attr = $this->mbox_attr ? $this->mbox_attr : 'mailmessagestore';
|
||||||
@ -968,7 +970,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
'objectClass='.$object_class,array('mail','uidNumber','uid',$mbox_attr))) ||
|
'objectClass='.$object_class,array('mail','uidNumber','uid',$mbox_attr))) ||
|
||||||
!($entries = ldap_get_entries($this->test_ldap->ds, $sr)))
|
!($entries = ldap_get_entries($this->test_ldap->ds, $sr)))
|
||||||
{
|
{
|
||||||
throw new egw_exception(lang('Error listing "dn=%1"!',$this->ldap_base));
|
throw new Api\Exception(lang('Error listing "dn=%1"!',$this->ldap_base));
|
||||||
}
|
}
|
||||||
$modified = 0;
|
$modified = 0;
|
||||||
foreach($entries as $n => $entry)
|
foreach($entries as $n => $entry)
|
||||||
@ -987,7 +989,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
$mbox_attr => $mbox,
|
$mbox_attr => $mbox,
|
||||||
)))
|
)))
|
||||||
{
|
{
|
||||||
throw new egw_exception(lang("Error modifying dn=%1: %2='%3'!",$entry['dn'],$mbox_attr,$mbox));
|
throw new Api\Exception(lang("Error modifying dn=%1: %2='%3'!",$entry['dn'],$mbox_attr,$mbox));
|
||||||
}
|
}
|
||||||
++$modified;
|
++$modified;
|
||||||
if ($check_only) echo "$modified: $entry[dn]: $mbox_attr={$entry[$mbox_attr][0]} --> $mbox\n";
|
if ($check_only) echo "$modified: $entry[dn]: $mbox_attr={$entry[$mbox_attr][0]} --> $mbox\n";
|
||||||
@ -1015,7 +1017,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
* @param string $dn dn to create, eg. "cn=admin,dc=local"
|
* @param string $dn dn to create, eg. "cn=admin,dc=local"
|
||||||
* @param array $extra =array() extra attributes to set
|
* @param array $extra =array() extra attributes to set
|
||||||
* @return boolean true if the node was create, false if it was already there
|
* @return boolean true if the node was create, false if it was already there
|
||||||
* @throws egw_exception_wrong_userinput
|
* @throws Api\Exception\WrongUserinput
|
||||||
*/
|
*/
|
||||||
private function _create_node($dn,$extra=array())
|
private function _create_node($dn,$extra=array())
|
||||||
{
|
{
|
||||||
@ -1035,7 +1037,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
|
|
||||||
if (!isset(self::$requiredObjectclasses[$name]))
|
if (!isset(self::$requiredObjectclasses[$name]))
|
||||||
{
|
{
|
||||||
throw new egw_exception_wrong_userinput(lang('Can not create DN %1!',$dn).' '.
|
throw new Api\Exception\WrongUserinput(lang('Can not create DN %1!',$dn).' '.
|
||||||
lang('Supported node types:').implode(', ',array_keys(self::$requiredObjectclasses)));
|
lang('Supported node types:').implode(', ',array_keys(self::$requiredObjectclasses)));
|
||||||
}
|
}
|
||||||
if ($name == 'dc') $extra['o'] = $value; // required by organisation
|
if ($name == 'dc') $extra['o'] = $value; // required by organisation
|
||||||
@ -1046,7 +1048,7 @@ class setup_cmd_ldap extends setup_cmd
|
|||||||
'objectClass' => self::$requiredObjectclasses[$name],
|
'objectClass' => self::$requiredObjectclasses[$name],
|
||||||
)+$extra))
|
)+$extra))
|
||||||
{
|
{
|
||||||
throw new egw_exception_wrong_userinput(lang('Can not create DN %1!',$dn).
|
throw new Api\Exception\WrongUserinput(lang('Can not create DN %1!',$dn).
|
||||||
' ('.ldap_error($this->test_ldap->ds).', attributes='.print_r($attr,true).')');
|
' ('.ldap_error($this->test_ldap->ds).', attributes='.print_r($attr,true).')');
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user