From 39cafac3f5e9cff676b379c1ecb1c847eec558e2 Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Fri, 07 Oct 2011 07:07:23 -0400
Subject: [PATCH] Autocomplete LDAP records when adding contacts from mail (#1488073)

---
 program/include/rcube_ldap.php |   84 ++++++++++++++++++++++++++++++-----------
 1 files changed, 61 insertions(+), 23 deletions(-)

diff --git a/program/include/rcube_ldap.php b/program/include/rcube_ldap.php
index a3f6dc5..3af343f 100644
--- a/program/include/rcube_ldap.php
+++ b/program/include/rcube_ldap.php
@@ -448,13 +448,6 @@
             return $this->result;
         }
 
-        // add general filter to query
-        if (!empty($this->prop['filter']) && empty($this->filter))
-        {
-            $filter = $this->prop['filter'];
-            $this->set_search_set($filter);
-        }
-
         // query URL is given by the selected group
         if ($this->group_id && $this->group_url)
         {
@@ -463,9 +456,13 @@
             {
                 $this->base_dn = $m[1];
                 $this->prop['scope'] = $m[2];
-                $this->filter = $m[3];
+                $this->filter = $this->filter ? '(&(' . $m[3] . ')(' . $this->filter . '))' : $m[3];
             }
         }
+
+        // add general filter to query
+        if (!empty($this->prop['filter']) && empty($this->filter))
+            $this->set_search_set($this->prop['filter']);
 
         // exec LDAP search if no result resource is stored
         if ($this->conn && !$this->ldap_result)
@@ -689,19 +686,49 @@
      * 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
      * @return boolean True if input is valid, False if not.
      */
-    public function validate($save_data)
+    public function validate(&$save_data, $autofix = false)
     {
         // check for name input
         if (empty($save_data['name'])) {
-            $this->set_error('warning', 'nonamewarning');
+            $this->set_error(self::ERROR_VALIDATE, 'nonamewarning');
+            return false;
+        }
+
+        // Verify that the required fields are set.
+        $missing = null;
+        $ldap_data = $this->_map_data($save_data);
+        foreach ($this->prop['required_fields'] as $fld) {
+            if (!isset($ldap_data[$fld])) {
+                $missing[$fld] = 1;
+            }
+        }
+
+        if ($missing) {
+            // try to complete record automatically
+            if ($autofix) {
+                $reverse_map = array_flip($this->fieldmap);
+                $name_parts = preg_split('/[\s,.]+/', $save_data['name']);
+                if ($missing['sn']) {
+                    $sn_field = $reverse_map['sn'];
+                    $save_data[$sn_field] = array_pop ($name_parts);
+                }
+                if ($missing[($fn_field = $this->fieldmap['firstname'])]) {
+                    $save_data['firstname'] = array_shift($name_parts);
+                }
+
+                return $this->validate($save_data, false);
+            }
+
+            // TODO: generate message saying which fields are missing
+            $this->set_error(self::ERROR_VALIDATE, 'formincomplete');
             return false;
         }
 
         // validate e-mail addresses
-        return parent::validate($save_data);
+        return parent::validate($save_data, $autofix);
     }
 
 
@@ -715,17 +742,8 @@
     function insert($save_cols)
     {
         // Map out the column names to their LDAP ones to build the new entry.
-        $newentry = array();
+        $newentry = $this->_map_data($save_cols);
         $newentry['objectClass'] = $this->prop['LDAP_Object_Classes'];
-        foreach ($this->fieldmap as $col => $fld) {
-            $val = $save_cols[$col];
-            if (is_array($val))
-                $val = array_filter($val);  // remove empty entries
-            if ($fld && $val) {
-                // The field does exist, add it to the entry.
-                $newentry[$fld] = $val;
-            } // end if
-        } // end foreach
 
         // Verify that the required fields are set.
         $missing = null;
@@ -738,7 +756,7 @@
         // abort process if requiered fields are missing
         // TODO: generate message saying which fields are missing
         if ($missing) {
-            $this->set_error(self::ERROR_INCOMPLETE, 'formincomplete');
+            $this->set_error(self::ERROR_VALIDATE, 'formincomplete');
             return false;
         }
 
@@ -1052,6 +1070,26 @@
 
 
     /**
+     * Convert a record data set into LDAP field attributes
+     */
+    private function _map_data($save_cols)
+    {
+        $ldap_data = array();
+        foreach ($this->fieldmap as $col => $fld) {
+            $val = $save_cols[$col];
+            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;
+            }
+        }
+        
+        return $ldap_data;
+    }
+
+
+    /**
      * Returns unified attribute name (resolving aliases)
      */
     private static function _attr_name($name)

--
Gitblit v1.9.1