|
|
|
@ -1006,8 +1006,8 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
/**
|
|
|
|
|
* Get a specific contact record
|
|
|
|
|
*
|
|
|
|
|
* @param mixed Record identifier
|
|
|
|
|
* @param boolean Return as associative array
|
|
|
|
|
* @param mixed $dn Record identifier
|
|
|
|
|
* @param boolean $assoc Return as associative array
|
|
|
|
|
*
|
|
|
|
|
* @return mixed Hash array or rcube_result_set with all record fields
|
|
|
|
|
*/
|
|
|
|
@ -1065,8 +1065,9 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
* Check the given data before saving.
|
|
|
|
|
* If input not valid, the message to display can be fetched using get_error()
|
|
|
|
|
*
|
|
|
|
|
* @param array Assoziative array with data to save
|
|
|
|
|
* @param boolean Try to fix/complete record automatically
|
|
|
|
|
* @param array &$save_data Associative array with data to save
|
|
|
|
|
* @param boolean $autofix Try to fix/complete record automatically
|
|
|
|
|
*
|
|
|
|
|
* @return boolean True if input is valid, False if not.
|
|
|
|
|
*/
|
|
|
|
|
public function validate(&$save_data, $autofix = false)
|
|
|
|
@ -1083,23 +1084,24 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Verify that the required fields are set.
|
|
|
|
|
$missing = null;
|
|
|
|
|
$missing = array();
|
|
|
|
|
$ldap_data = $this->_map_data($save_data);
|
|
|
|
|
|
|
|
|
|
foreach ($this->prop['required_fields'] as $fld) {
|
|
|
|
|
if (!isset($ldap_data[$fld]) || $ldap_data[$fld] === '') {
|
|
|
|
|
$missing[$fld] = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($missing) {
|
|
|
|
|
if (!empty($missing)) {
|
|
|
|
|
// try to complete record automatically
|
|
|
|
|
if ($autofix) {
|
|
|
|
|
$sn_field = $this->fieldmap['surname'];
|
|
|
|
|
$fn_field = $this->fieldmap['firstname'];
|
|
|
|
|
$mail_field = $this->fieldmap['email'];
|
|
|
|
|
$sn_field = $this->fieldmap['surname'];
|
|
|
|
|
$fn_field = $this->fieldmap['firstname'];
|
|
|
|
|
$mail_field = $this->fieldmap['email'];
|
|
|
|
|
|
|
|
|
|
// try to extract surname and firstname from displayname
|
|
|
|
|
$name_parts = preg_split('/[\s,.]+/', $save_data['name']);
|
|
|
|
|
$name_parts = preg_split('/[\s,.]+/', $save_data['name']);
|
|
|
|
|
|
|
|
|
|
if ($sn_field && $missing[$sn_field]) {
|
|
|
|
|
$save_data['surname'] = array_pop($name_parts);
|
|
|
|
@ -1135,10 +1137,10 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
/**
|
|
|
|
|
* Create a new contact record
|
|
|
|
|
*
|
|
|
|
|
* @param array Associative array with save data
|
|
|
|
|
* Keys: Field name with optional section in the form FIELD:SECTION
|
|
|
|
|
* Values: Field value. Can be either a string or an array of strings for multiple values
|
|
|
|
|
* @param boolean True to check for duplicates first
|
|
|
|
|
* @param array $save_cols Associative array with save data
|
|
|
|
|
* Keys: Field name with optional section in the form FIELD:SECTION
|
|
|
|
|
* Values: Field value. Can be either a string or an array of strings for multiple values
|
|
|
|
|
* @param boolean $check True to check for duplicates first
|
|
|
|
|
*
|
|
|
|
|
* @return mixed The created record ID on success, False on error
|
|
|
|
|
*/
|
|
|
|
@ -1198,8 +1200,9 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
$dn = self::dn_encode($dn);
|
|
|
|
|
|
|
|
|
|
// add new contact to the selected group
|
|
|
|
|
if ($this->group_id)
|
|
|
|
|
if ($this->group_id) {
|
|
|
|
|
$this->add_to_group($this->group_id, $dn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $dn;
|
|
|
|
|
}
|
|
|
|
@ -1214,17 +1217,15 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
*/
|
|
|
|
|
function update($id, $save_cols)
|
|
|
|
|
{
|
|
|
|
|
$record = $this->get_record($id, true);
|
|
|
|
|
|
|
|
|
|
$record = $this->get_record($id, true);
|
|
|
|
|
$newdata = array();
|
|
|
|
|
$replacedata = array();
|
|
|
|
|
$deletedata = array();
|
|
|
|
|
$subdata = array();
|
|
|
|
|
$subdeldata = array();
|
|
|
|
|
$subnewdata = array();
|
|
|
|
|
|
|
|
|
|
$ldap_data = $this->_map_data($save_cols);
|
|
|
|
|
$old_data = $record['_raw_attrib'];
|
|
|
|
|
$ldap_data = $this->_map_data($save_cols);
|
|
|
|
|
$old_data = $record['_raw_attrib'];
|
|
|
|
|
|
|
|
|
|
// special handling of photo col
|
|
|
|
|
if ($photo_fld = $this->fieldmap['photo']) {
|
|
|
|
@ -1286,9 +1287,9 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
// The data was modified, save it out.
|
|
|
|
|
$replacedata[$fld] = $val;
|
|
|
|
|
}
|
|
|
|
|
} // end if
|
|
|
|
|
} // end if
|
|
|
|
|
} // end foreach
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// console($old_data, $ldap_data, '----', $newdata, $replacedata, $deletedata, '----', $subdata, $subnewdata, $subdeldata);
|
|
|
|
|
|
|
|
|
@ -1301,7 +1302,7 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
$this->set_error(self::ERROR_SAVING, 'errorsaving');
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} // end if
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!empty($replacedata)) {
|
|
|
|
|
// Handle RDN change
|
|
|
|
@ -1322,7 +1323,7 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // end if
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RDN change, we need to remove all sub-entries
|
|
|
|
|
if (!empty($newrdn)) {
|
|
|
|
@ -1346,7 +1347,7 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
$this->set_error(self::ERROR_SAVING, 'errorsaving');
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} // end if
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle RDN change
|
|
|
|
|
if (!empty($newrdn)) {
|
|
|
|
@ -1398,7 +1399,7 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
if (!is_array($ids)) {
|
|
|
|
|
// Not an array, break apart the encoded DNs.
|
|
|
|
|
$ids = explode(',', $ids);
|
|
|
|
|
} // end if
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach ($ids as $id) {
|
|
|
|
|
$dn = self::dn_decode($id);
|
|
|
|
@ -1423,13 +1424,14 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
|
|
|
|
|
// remove contact from all groups where he was a member
|
|
|
|
|
if ($this->groups) {
|
|
|
|
|
$dn = self::dn_encode($dn);
|
|
|
|
|
$dn = self::dn_encode($dn);
|
|
|
|
|
$group_ids = $this->get_record_groups($dn);
|
|
|
|
|
|
|
|
|
|
foreach (array_keys($group_ids) as $group_id) {
|
|
|
|
|
$this->remove_from_group($group_id, $dn);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // end foreach
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return count($ids);
|
|
|
|
|
}
|
|
|
|
@ -1478,7 +1480,7 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
$attrvals['{'.$k.'}'] = is_array($v) ? $v[0] : $v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach ((array)$this->prop['autovalues'] as $lf => $templ) {
|
|
|
|
|
foreach ((array) $this->prop['autovalues'] as $lf => $templ) {
|
|
|
|
|
if (empty($attrs[$lf])) {
|
|
|
|
|
if (strpos($templ, '(') !== false) {
|
|
|
|
|
// replace {attr} placeholders with (escaped!) attribute values to be safely eval'd
|
|
|
|
@ -1514,16 +1516,17 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
*/
|
|
|
|
|
private function _ldap2result($rec)
|
|
|
|
|
{
|
|
|
|
|
$out = array('_type' => 'person');
|
|
|
|
|
$out = array('_type' => 'person');
|
|
|
|
|
$fieldmap = $this->fieldmap;
|
|
|
|
|
|
|
|
|
|
if ($rec['dn'])
|
|
|
|
|
if ($rec['dn']) {
|
|
|
|
|
$out[$this->primary_key] = self::dn_encode($rec['dn']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// determine record type
|
|
|
|
|
if ($this->is_group_entry($rec)) {
|
|
|
|
|
$out['_type'] = 'group';
|
|
|
|
|
$out['readonly'] = true;
|
|
|
|
|
$out['_type'] = 'group';
|
|
|
|
|
$out['readonly'] = true;
|
|
|
|
|
$fieldmap['name'] = $this->group_data['name_attr'] ?: $this->prop['groups']['name_attr'];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1537,8 +1540,7 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach ($fieldmap as $rf => $lf)
|
|
|
|
|
{
|
|
|
|
|
foreach ($fieldmap as $rf => $lf) {
|
|
|
|
|
// we might be dealing with normalized and non-normalized data
|
|
|
|
|
$entry = $rec[$lf];
|
|
|
|
|
if (!is_array($entry) || !isset($entry['count'])) {
|
|
|
|
@ -1616,7 +1618,7 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
foreach ($this->fieldmap as $rf => $fld) {
|
|
|
|
|
$val = $save_cols[$rf];
|
|
|
|
|
|
|
|
|
|
// check for value in base field (eg.g email instead of email:foo)
|
|
|
|
|
// check for value in base field (eg. email instead of email:foo)
|
|
|
|
|
list($col, $subtype) = explode(':', $rf);
|
|
|
|
|
if (!$val && !empty($save_cols[$col])) {
|
|
|
|
|
$val = $save_cols[$col];
|
|
|
|
@ -1626,8 +1628,10 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
$val = $this->get_col_values($col, $save_cols, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_array($val))
|
|
|
|
|
if (is_array($val)) {
|
|
|
|
|
$val = array_filter($val); // remove empty entries
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($fld && $val) {
|
|
|
|
|
// The field does exist, add it to the entry.
|
|
|
|
|
$ldap_data[$fld] = $val;
|
|
|
|
@ -1910,7 +1914,8 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
/**
|
|
|
|
|
* Get group properties such as name and email address(es)
|
|
|
|
|
*
|
|
|
|
|
* @param string Group identifier
|
|
|
|
|
* @param string $group_id Group identifier
|
|
|
|
|
*
|
|
|
|
|
* @return array Group properties as hash array
|
|
|
|
|
*/
|
|
|
|
|
function get_group($group_id)
|
|
|
|
@ -1924,7 +1929,8 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
/**
|
|
|
|
|
* Create a contact group with the given name
|
|
|
|
|
*
|
|
|
|
|
* @param string The group name
|
|
|
|
|
* @param string $group_name The group name
|
|
|
|
|
*
|
|
|
|
|
* @return mixed False on error, array with record props in success
|
|
|
|
|
*/
|
|
|
|
|
function create_group($group_name)
|
|
|
|
@ -1954,7 +1960,8 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
/**
|
|
|
|
|
* Delete the given group and all linked group members
|
|
|
|
|
*
|
|
|
|
|
* @param string Group identifier
|
|
|
|
|
* @param string $group_id Group identifier
|
|
|
|
|
*
|
|
|
|
|
* @return boolean True on success, false if no data was changed
|
|
|
|
|
*/
|
|
|
|
|
function delete_group($group_id)
|
|
|
|
@ -1978,9 +1985,10 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
/**
|
|
|
|
|
* Rename a specific contact group
|
|
|
|
|
*
|
|
|
|
|
* @param string Group identifier
|
|
|
|
|
* @param string New name to set for this group
|
|
|
|
|
* @param string New group identifier (if changed, otherwise don't set)
|
|
|
|
|
* @param string $group_id Group identifier
|
|
|
|
|
* @param string $new_name New name to set for this group
|
|
|
|
|
* @param string &$new_gid New group identifier (if changed, otherwise don't set)
|
|
|
|
|
*
|
|
|
|
|
* @return boolean New name on success, false if no data was changed
|
|
|
|
|
*/
|
|
|
|
|
function rename_group($group_id, $new_name, &$new_gid)
|
|
|
|
@ -2005,8 +2013,8 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
/**
|
|
|
|
|
* Add the given contact records the a certain group
|
|
|
|
|
*
|
|
|
|
|
* @param string Group identifier
|
|
|
|
|
* @param array|string List of contact identifiers to be added
|
|
|
|
|
* @param string $group_id Group identifier
|
|
|
|
|
* @param array|string $contact_ids List of contact identifiers to be added
|
|
|
|
|
*
|
|
|
|
|
* @return int Number of contacts added
|
|
|
|
|
*/
|
|
|
|
@ -2040,8 +2048,8 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
/**
|
|
|
|
|
* Remove the given contact records from a certain group
|
|
|
|
|
*
|
|
|
|
|
* @param string Group identifier
|
|
|
|
|
* @param array|string List of contact identifiers to be removed
|
|
|
|
|
* @param string $group_id Group identifier
|
|
|
|
|
* @param array|string $contact_ids List of contact identifiers to be removed
|
|
|
|
|
*
|
|
|
|
|
* @return int Number of deleted group members
|
|
|
|
|
*/
|
|
|
|
@ -2075,7 +2083,7 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
/**
|
|
|
|
|
* Get group assignments of a specific contact record
|
|
|
|
|
*
|
|
|
|
|
* @param mixed Record identifier
|
|
|
|
|
* @param mixed $contact_id Record identifier
|
|
|
|
|
*
|
|
|
|
|
* @return array List of assigned groups as ID=>Name pairs
|
|
|
|
|
* @since 0.5-beta
|
|
|
|
@ -2092,9 +2100,11 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
$member_attr = $this->get_group_member_attr();
|
|
|
|
|
$add_filter = '';
|
|
|
|
|
|
|
|
|
|
if ($member_attr != 'member' && $member_attr != 'uniqueMember')
|
|
|
|
|
if ($member_attr != 'member' && $member_attr != 'uniqueMember') {
|
|
|
|
|
$add_filter = "($member_attr=$contact_dn)";
|
|
|
|
|
$filter = strtr("(|(member=$contact_dn)(uniqueMember=$contact_dn)$add_filter)", array('\\' => '\\\\'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$filter = strtr("(|(member=$contact_dn)(uniqueMember=$contact_dn)$add_filter)", array("\\" => "\\\\"));
|
|
|
|
|
|
|
|
|
|
$ldap_data = $this->ldap->search($base_dn, $filter, 'sub', array('dn', $name_attr));
|
|
|
|
|
if ($ldap_data === false) {
|
|
|
|
@ -2103,10 +2113,12 @@ class rcube_ldap extends rcube_addressbook
|
|
|
|
|
|
|
|
|
|
$groups = array();
|
|
|
|
|
foreach ($ldap_data as $entry) {
|
|
|
|
|
if (!$entry['dn'])
|
|
|
|
|
if (!$entry['dn']) {
|
|
|
|
|
$entry['dn'] = $ldap_data->get_dn();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$group_name = $entry[$name_attr][0];
|
|
|
|
|
$group_id = self::dn_encode($entry['dn']);
|
|
|
|
|
$group_id = self::dn_encode($entry['dn']);
|
|
|
|
|
$groups[$group_id] = $group_name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|