/** * Update a specific contact record * * @param mixed Record identifier * @param array Hash array with save data * @return boolean True on success, False on error */ function update($id, $save_cols) { $record = $this->get_record($id, true); $result = $this->get_result(); $record = $result->first(); $newdata = array(); $replacedata = array(); $deletedata = array(); foreach ($save_cols as $col => $val) { $fld = $this->_map_field($col); if ($fld) { // The field does exist compare it to the ldap record. if ($record[$col] != $val) { // Changed, but find out how. if (!isset($record[$col])) { // Field was not set prior, need to add it. $newdata[$fld] = $val; } elseif ($val == '') { // Field supplied is empty, verify that it is not required. if (!in_array($fld, $this->prop['required_fields'])) { // It is not, safe to clear. $deletedata[$fld] = $record[$col]; } // end if } else { // The data was modified, save it out. $replacedata[$fld] = $val; } // end else } // end if } // end if } // end foreach $dn = base64_decode($id); // Update the entry as required. if (!empty($deletedata)) { // Delete the fields. $this->_debug("C: Delete [dn: {$dn}]: " . print_r($deletedata, true)); if (!ldap_mod_del($this->conn, $dn, $deletedata)) { $this->_debug("S: " . ldap_error($this->conn)); return false; } $this->_debug("S: OK"); } // end if if (!empty($replacedata)) { // Handle RDN change if ($replacedata[$this->prop['LDAP_rdn']]) { $newdn = $this->prop['LDAP_rdn'] . '=' . rcube_ldap::quote_string($replacedata[$this->prop['LDAP_rdn']], true) . ',' . $this->prop['base_dn']; if ($dn != $newdn) { $newrdn = $this->prop['LDAP_rdn'] . '=' . rcube_ldap::quote_string($replacedata[$this->prop['LDAP_rdn']], true); unset($replacedata[$this->prop['LDAP_rdn']]); } } // Replace the fields. if (!empty($replacedata)) { $this->_debug("C: Replace [dn: {$dn}]: " . print_r($replacedata, true)); if (!ldap_mod_replace($this->conn, $dn, $replacedata)) { $this->_debug("S: " . ldap_error($this->conn)); return false; } $this->_debug("S: OK"); } // end if } // end if if (!empty($newdata)) { // Add the fields. $this->_debug("C: Add [dn: {$dn}]: " . print_r($newdata, true)); if (!ldap_mod_add($this->conn, $dn, $newdata)) { $this->_debug("S: " . ldap_error($this->conn)); return false; } $this->_debug("S: OK"); } // end if // Handle RDN change if (!empty($newrdn)) { $this->_debug("C: Rename [dn: {$dn}] [dn: {$newrdn}]"); if (@ldap_rename($this->conn, $dn, $newrdn, NULL, TRUE)) { $this->_debug("S: " . ldap_error($this->conn)); return base64_encode($newdn); } $this->_debug("S: OK"); } return true; }
/** * Search contacts * * @param array List of fields to search in * @param string Search value * @param boolean True if results are requested, False if count only * @return array Indexed list of contact records and 'count' value */ function search($fields, $value, $strict = false, $select = true) { // special treatment for ID-based search if ($fields == 'ID' || $fields == $this->primary_key) { $ids = explode(',', $value); $result = new rcube_result_set(); foreach ($ids as $id) { if ($rec = $this->get_record($id, true)) { $result->add($rec); $result->count++; } } return $result; } $filter = '(|'; $wc = !$strict && $this->prop['fuzzy_search'] ? '*' : ''; if (is_array($this->prop['search_fields'])) { foreach ($this->prop['search_fields'] as $k => $field) { $filter .= "({$field}={$wc}" . rcube_ldap::quote_string($value) . "{$wc})"; } } else { foreach ((array) $fields as $field) { if ($f = $this->_map_field($field)) { $filter .= "({$f}={$wc}" . rcube_ldap::quote_string($value) . "{$wc})"; } } } $filter .= ')'; // avoid double-wildcard if $value is empty $filter = preg_replace('/\\*+/', '*', $filter); // add general filter to query if (!empty($this->prop['filter'])) { $filter = '(&(' . preg_replace('/^\\(|\\)$/', '', $this->prop['filter']) . ')' . $filter . ')'; } // set filter string and execute search $this->set_search_set($filter); $this->_exec_search(); if ($select) { $this->list_records(); } else { $this->result = $this->count(); } return $this->result; }