| | |
| | | |
| | | // private properties |
| | | protected $ldap; |
| | | protected $formats = array(); |
| | | protected $prop = array(); |
| | | protected $fieldmap = array(); |
| | | protected $filter = ''; |
| | |
| | | protected $result; |
| | | protected $ldap_result; |
| | | protected $mail_domain = ''; |
| | | protected $debug = false; |
| | | protected $debug = false; |
| | | |
| | | /** |
| | | * Group objectclass (lowercase) to member attribute mapping |
| | |
| | | if (is_array($p['fieldmap'])) { |
| | | $p['fieldmap'] = array_filter($p['fieldmap']); |
| | | foreach ($p['fieldmap'] as $rf => $lf) |
| | | $this->fieldmap[$rf] = $this->_attr_name(strtolower($lf)); |
| | | $this->fieldmap[$rf] = $this->_attr_name($lf); |
| | | } |
| | | else if (!empty($p)) { |
| | | // read deprecated *_field properties to remain backwards compatible |
| | | foreach ($p as $prop => $value) |
| | | if (!empty($value) && preg_match('/^(.+)_field$/', $prop, $matches)) |
| | | $this->fieldmap[$matches[1]] = $this->_attr_name(strtolower($value)); |
| | | $this->fieldmap[$matches[1]] = $this->_attr_name($value); |
| | | } |
| | | |
| | | // use fieldmap to advertise supported coltypes to the application |
| | | foreach ($this->fieldmap as $colv => $lfv) { |
| | | list($col, $type) = explode(':', $colv); |
| | | list($lf, $limit, $delim) = explode(':', $lfv); |
| | | $params = explode(':', $lfv); |
| | | |
| | | if ($limit == '*') $limit = null; |
| | | else $limit = max(1, intval($limit)); |
| | | $lf = array_shift($params); |
| | | $limit = 1; |
| | | |
| | | foreach ($params as $idx => $param) { |
| | | // field format specification |
| | | if (preg_match('/^(date)\[(.+)\]$/i', $param, $m)) { |
| | | $this->formats[$lf] = array('type' => strtolower($m[1]), 'format' => $m[2]); |
| | | } |
| | | // first argument is a limit |
| | | else if ($idx === 0) { |
| | | if ($param == '*') $limit = null; |
| | | else $limit = max(1, intval($param)); |
| | | } |
| | | // second is a composite field separator |
| | | else if ($idx === 1 && $param) { |
| | | $this->coltypes[$col]['serialized'][$type] = $param; |
| | | } |
| | | } |
| | | |
| | | if (!is_array($this->coltypes[$col])) { |
| | | $subtypes = $type ? array($type) : null; |
| | |
| | | $this->coltypes[$col]['limit'] += $limit; |
| | | } |
| | | |
| | | if ($delim) |
| | | $this->coltypes[$col]['serialized'][$type] = $delim; |
| | | |
| | | $this->fieldmap[$colv] = $lf; |
| | | $this->fieldmap[$colv] = $lf; |
| | | } |
| | | |
| | | // support for composite address |
| | |
| | | } |
| | | |
| | | foreach ($this->prop['required_fields'] as $key => $val) { |
| | | $this->prop['required_fields'][$key] = $this->_attr_name(strtolower($val)); |
| | | $this->prop['required_fields'][$key] = $this->_attr_name($val); |
| | | } |
| | | |
| | | // Build sub_fields filter |
| | |
| | | $bind_dn = $this->prop['bind_dn']; |
| | | |
| | | $this->base_dn = $this->prop['base_dn']; |
| | | $this->groups_base_dn = ($this->prop['groups']['base_dn']) ? |
| | | $this->prop['groups']['base_dn'] : $this->base_dn; |
| | | $this->groups_base_dn = $this->prop['groups']['base_dn'] ?: $this->base_dn; |
| | | |
| | | // User specific access, generate the proper values to use. |
| | | if ($this->prop['user_specific']) { |
| | |
| | | $attrib = array_merge($attrib, array_values($this->group_types)); |
| | | $attrib[] = 'memberURL'; |
| | | |
| | | $filter = $this->prop['groups']['member_filter'] ? $this->prop['groups']['member_filter'] : '(objectclass=*)'; |
| | | $filter = $this->prop['groups']['member_filter'] ?: '(objectclass=*)'; |
| | | |
| | | for ($i=0; $i < $entry[$attr]['count']; $i++) { |
| | | if (empty($entry[$attr][$i])) |
| | |
| | | } |
| | | else { |
| | | // map address book fields into ldap attributes |
| | | $me = $this; |
| | | $attributes = array(); |
| | | array_walk((array) $fields, function($field) use ($me, &$attributes) { |
| | | if ($me->coltypes[$field] && ($attrs = (array)$me->coltypes[$field]['attributes'])) { |
| | | $attributes = array_merge($attributes, $attrs); |
| | | foreach ((array) $fields as $field) { |
| | | if ($this->coltypes[$field] && ($attrs = $this->coltypes[$field]['attributes'])) { |
| | | $attributes = array_merge($attributes, (array) $attrs); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | |
| | | // compose a full-text-like search filter |
| | |
| | | /** |
| | | * Create a new contact record |
| | | * |
| | | * @param array Hash array with save data |
| | | * @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 |
| | | * |
| | | * @return encoded record ID on success, False on error |
| | | * @return mixed The created record ID on success, False on error |
| | | */ |
| | | function insert($save_cols) |
| | | function insert($save_cols, $check = false) |
| | | { |
| | | // Map out the column names to their LDAP ones to build the new entry. |
| | | $newentry = $this->_map_data($save_cols); |
| | |
| | | } |
| | | } |
| | | |
| | | return $newdn ? $newdn : true; |
| | | return $newdn ?: true; |
| | | } |
| | | |
| | | /** |
| | |
| | | function delete_all($with_groups = false) |
| | | { |
| | | // searching for contact entries |
| | | $dn_list = $this->ldap->list_entries($this->base_dn, $this->prop['filter'] ? $this->prop['filter'] : '(objectclass=*)'); |
| | | $dn_list = $this->ldap->list_entries($this->base_dn, $this->prop['filter'] ?: '(objectclass=*)'); |
| | | |
| | | if (!empty($dn_list)) { |
| | | foreach ($dn_list as $idx => $entry) { |
| | |
| | | if ($this->is_group_entry($rec)) { |
| | | $out['_type'] = 'group'; |
| | | $out['readonly'] = true; |
| | | $fieldmap['name'] = $this->group_data['name_attr'] ? $this->group_data['name_attr'] : $this->prop['groups']['name_attr']; |
| | | $fieldmap['name'] = $this->group_data['name_attr'] ?: $this->prop['groups']['name_attr']; |
| | | } |
| | | |
| | | // assign object type from object class mapping |
| | |
| | | if ($col == 'email' && $this->mail_domain && !strpos($value, '@')) |
| | | $out[$rf][] = sprintf('%s@%s', $value, $this->mail_domain); |
| | | else if (in_array($col, array('street','zipcode','locality','country','region'))) |
| | | $out['address'.($subtype?':':'').$subtype][$i][$col] = $value; |
| | | $out['address' . ($subtype ? ':' : '') . $subtype][$i][$col] = $value; |
| | | else if ($col == 'address' && strpos($value, '$') !== false) // address data is represented as string separated with $ |
| | | list($out[$rf][$i]['street'], $out[$rf][$i]['locality'], $out[$rf][$i]['zipcode'], $out[$rf][$i]['country']) = explode('$', $value); |
| | | else if ($rec[$lf]['count'] > 1) |
| | |
| | | } |
| | | } |
| | | |
| | | foreach ($this->formats as $fld => $format) { |
| | | if (empty($ldap_data[$fld])) { |
| | | continue; |
| | | } |
| | | |
| | | switch ($format['type']) { |
| | | case 'date': |
| | | if ($dt = rcube_utils::anytodatetime($ldap_data[$fld])) { |
| | | $ldap_data[$fld] = $dt->format($format['format']); |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | |
| | | return $ldap_data; |
| | | } |
| | | |
| | |
| | | |
| | | list($name, $limit) = explode(':', $namev, 2); |
| | | $suffix = $limit ? ':'.$limit : ''; |
| | | $name = strtolower($name); |
| | | |
| | | return (isset($aliases[$name]) ? $aliases[$name] : $name) . $suffix; |
| | | } |
| | |
| | | $filter = $this->prop['groups']['filter']; |
| | | $scope = $this->prop['groups']['scope']; |
| | | $name_attr = $this->prop['groups']['name_attr']; |
| | | $email_attr = $this->prop['groups']['email_attr'] ? $this->prop['groups']['email_attr'] : 'mail'; |
| | | $email_attr = $this->prop['groups']['email_attr'] ?: 'mail'; |
| | | $sort_attrs = $this->prop['groups']['sort'] ? (array)$this->prop['groups']['sort'] : array($name_attr); |
| | | $sort_attr = $sort_attrs[0]; |
| | | |
| | |
| | | $new_dn = 'cn=' . rcube_ldap_generic::quote_string($group_name, true) . ',' . $this->groups_base_dn; |
| | | $new_gid = self::dn_encode($new_dn); |
| | | $member_attr = $this->get_group_member_attr(); |
| | | $name_attr = $this->prop['groups']['name_attr'] ? $this->prop['groups']['name_attr'] : 'cn'; |
| | | $name_attr = $this->prop['groups']['name_attr'] ?: 'cn'; |
| | | $new_entry = array( |
| | | 'objectClass' => $this->prop['groups']['object_classes'], |
| | | $name_attr => $group_name, |
| | | $member_attr => '', |
| | | $name_attr => $group_name, |
| | | $member_attr => '', |
| | | ); |
| | | |
| | | if (!$this->ldap->add_entry($new_dn, $new_entry)) { |
| | |
| | | |
| | | $base_dn = $this->groups_base_dn; |
| | | $contact_dn = self::dn_decode($contact_id); |
| | | $name_attr = $this->prop['groups']['name_attr'] ? $this->prop['groups']['name_attr'] : 'cn'; |
| | | $name_attr = $this->prop['groups']['name_attr'] ?: 'cn'; |
| | | $member_attr = $this->get_group_member_attr(); |
| | | $add_filter = ''; |
| | | |