From 203323ba8559c1c548a747049e2508e7d4bcaff4 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Wed, 13 Feb 2013 12:27:51 +0100 Subject: Refactored the LDAP address book into a generic LDAP wrapper class and an address book implementation (as already started in the devel-ldap-refactoring branch) --- program/lib/Roundcube/rcube_ldap_result.php | 128 ++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 program/lib/Roundcube/rcube_ldap_result.php (limited to 'program/lib/Roundcube/rcube_ldap_result.php') diff --git a/program/lib/Roundcube/rcube_ldap_result.php b/program/lib/Roundcube/rcube_ldap_result.php new file mode 100644 index 000000000..92c289753 --- /dev/null +++ b/program/lib/Roundcube/rcube_ldap_result.php @@ -0,0 +1,128 @@ + | + +-----------------------------------------------------------------------+ +*/ + + +/** + * Model class representing an LDAP search result + * + * @package Framework + * @subpackage LDAP + */ +class rcube_ldap_result implements Iterator +{ + public $conn; + public $ldap; + public $base_dn; + public $filter; + + private $count = null; + private $current = null; + private $iteratorkey = 0; + + /** + * Default constructor + * + * @param resource $conn LDAP link identifier + * @param resource $ldap LDAP result entry identifier + * @param string $base_dn Base DN used to get this result + * @param string $filter Filter query used to get this result + * @param integer $count Record count value (pre-calculated) + */ + function __construct($conn, $ldap, $base_dn, $filter, $count = null) + { + $this->conn = $conn; + $this->ldap = $ldap; + $this->base_dn = $base_dn; + $this->filter = $filter; + $this->count = $count; + } + + /** + * Wrapper for ldap_sort() + */ + public function sort($attr) + { + return ldap_sort($this->conn, $this->ldap, $attr); + } + + /** + * Get entries count + */ + public function count() + { + if (!isset($this->count)) + $this->count = ldap_count_entries($this->conn, $this->ldap); + + return $this->count; + } + + /** + * Wrapper for ldap_get_entries() + * + * @param boolean $normalize Optionally normalize the entries to a list of hash arrays + * @return array List of LDAP entries + */ + public function entries($normalize = false) + { + $entries = ldap_get_entries($this->conn, $this->ldap); + return $normalize ? rcube_ldap_generic::normalize_result($entries) : $entries; + } + + /** + * Wrapper for ldap_get_dn() using the current entry pointer + */ + public function get_dn() + { + return $this->current ? ldap_get_dn($this->conn, $this->current) : null; + } + + + /*** Implements the PHP 5 Iterator interface to make foreach work ***/ + + function current() + { + return ldap_get_attributes($this->conn, $this->current); + } + + function key() + { + return $this->iteratorkey; + } + + function rewind() + { + $this->iteratorkey = 0; + $this->current = ldap_first_entry($this->conn, $this->ldap); + } + + function next() + { + $this->iteratorkey++; + $this->current = ldap_next_entry($this->conn, $this->current); + } + + function valid() + { + return (bool)$this->current; + } + +} -- cgit v1.2.3 From 807c3d0d9745e850d08ceb2a1d6c018f8b791706 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Thu, 14 Feb 2013 11:58:28 +0100 Subject: Optimmize memory usage by only fetching the necessary attributes used for contacts listing --- program/lib/Roundcube/rcube_ldap.php | 15 ++++++++++----- program/lib/Roundcube/rcube_ldap_generic.php | 3 +++ program/lib/Roundcube/rcube_ldap_result.php | 4 +++- 3 files changed, 16 insertions(+), 6 deletions(-) (limited to 'program/lib/Roundcube/rcube_ldap_result.php') diff --git a/program/lib/Roundcube/rcube_ldap.php b/program/lib/Roundcube/rcube_ldap.php index 5896690c3..c3c0533f8 100644 --- a/program/lib/Roundcube/rcube_ldap.php +++ b/program/lib/Roundcube/rcube_ldap.php @@ -193,8 +193,14 @@ class rcube_ldap extends rcube_addressbook $rcube = rcube::get_instance(); $this->cache = $rcube->get_cache('LDAP.' . asciiwords($this->prop['name']), 'db', 600); - // initialize ldap wrapper object + // determine which attributes to fetch $this->prop['attributes'] = array_merge(array_values($this->fieldmap), $fetch_attributes); + $this->prop['list_attributes'] = $fetch_attributes; + foreach ($rcube->config->get('contactlist_fields') as $col) { + $this->prop['list_attributes'] = array_merge($this->prop['list_attributes'], $this->_map_field($col)); + } + + // initialize ldap wrapper object $this->ldap = new rcube_ldap_generic($this->prop, true); $this->ldap->set_cache($this->cache); @@ -567,7 +573,7 @@ class rcube_ldap extends rcube_addressbook return $group_members; // read these attributes for all members - $attrib = $count ? array('dn','objectClass') : $this->prop['attributes']; + $attrib = $count ? array('dn','objectClass') : $this->prop['list_attributes']; $attrib[] = 'member'; $attrib[] = 'uniqueMember'; $attrib[] = 'memberURL'; @@ -605,15 +611,14 @@ class rcube_ldap extends rcube_addressbook { $group_members = array(); - for ($i=0; $i < $entry['memberurl']['count']; $i++) - { + for ($i=0; $i < $entry['memberurl']['count']; $i++) { // extract components from url if (!preg_match('!ldap:///([^\?]+)\?\?(\w+)\?(.*)$!', $entry['memberurl'][$i], $m)) continue; // add search filter if any $filter = $this->filter ? '(&(' . $m[3] . ')(' . $this->filter . '))' : $m[3]; - $attrs = $count ? array('dn','objectClass') : $this->prop['attributes']; + $attrs = $count ? array('dn','objectClass') : $this->prop['list_attributes']; if ($result = $this->ldap->search($m[1], $filter, $m[2], $attrs, $this->group_data)) { $entries = $result->entries(); for ($j = 0; $j < $entries['count']; $j++) { diff --git a/program/lib/Roundcube/rcube_ldap_generic.php b/program/lib/Roundcube/rcube_ldap_generic.php index 0b04129fb..c5ea4ea4c 100644 --- a/program/lib/Roundcube/rcube_ldap_generic.php +++ b/program/lib/Roundcube/rcube_ldap_generic.php @@ -412,6 +412,9 @@ class rcube_ldap_generic $this->_debug("S: ".($errmsg ? $errmsg : ldap_error($this->conn))); } } + else if ($this->debug) { + $this->_debug("S: ".ldap_count_entries($this->conn, $ldap_result)." record(s) found"); + } $this->result = new rcube_ldap_result($this->conn, $ldap_result, $base_dn, $filter, $vlv_count); diff --git a/program/lib/Roundcube/rcube_ldap_result.php b/program/lib/Roundcube/rcube_ldap_result.php index 92c289753..efc3331bc 100644 --- a/program/lib/Roundcube/rcube_ldap_result.php +++ b/program/lib/Roundcube/rcube_ldap_result.php @@ -100,7 +100,9 @@ class rcube_ldap_result implements Iterator function current() { - return ldap_get_attributes($this->conn, $this->current); + $attrib = ldap_get_attributes($this->conn, $this->current); + $attrib['dn'] = ldap_get_dn($this->conn, $this->current); + return $attrib; } function key() -- cgit v1.2.3