]> git.donarmstrong.com Git - roundcube.git/blobdiff - program/include/rcube_contacts.php
Imported Upstream version 0.7
[roundcube.git] / program / include / rcube_contacts.php
index af07b32bedd9d91bf07c2ed3f1b3dc20afa22320..a2883156ae8448a60b2885e19686049ffadecb3b 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_contacts.php 5011 2011-08-03 09:32:45Z alec $
+ $Id: rcube_contacts.php 5415 2011-11-11 15:04:45Z alec $
 
 */
 
@@ -41,7 +41,6 @@ class rcube_contacts extends rcube_addressbook
     private $user_id = 0;
     private $filter = null;
     private $result = null;
-    private $name;
     private $cache;
     private $table_cols = array('name', 'email', 'firstname', 'surname');
     private $fulltext_cols = array('name', 'firstname', 'surname', 'middlename', 'nickname',
@@ -50,6 +49,7 @@ class rcube_contacts extends rcube_addressbook
 
     // public properties
     public $primary_key = 'contact_id';
+    public $name;
     public $readonly = false;
     public $groups = true;
     public $undelete = true;
@@ -163,6 +163,29 @@ class rcube_contacts extends rcube_addressbook
     }
 
 
+    /**
+     * Get group properties such as name and email address(es)
+     *
+     * @param string Group identifier
+     * @return array Group properties as hash array
+     */
+    function get_group($group_id)
+    {
+        $sql_result = $this->db->query(
+            "SELECT * FROM ".get_table_name($this->db_groups).
+            " WHERE del<>1".
+            " AND contactgroup_id=?".
+            " AND user_id=?",
+            $group_id, $this->user_id);
+
+        if ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) {
+            $sql_arr['ID'] = $sql_arr['contactgroup_id'];
+            return $sql_arr;
+        }
+
+        return null;
+    }
+
     /**
      * List the current set of contact records
      *
@@ -245,14 +268,17 @@ class rcube_contacts extends rcube_addressbook
      *
      * @param mixed   $fields   The field name of array of field names to search in
      * @param mixed   $value    Search value (or array of values when $fields is array)
-     * @param boolean $strict   True for strict (=), False for partial (LIKE) matching
+     * @param int     $mode     Matching mode:
+     *                          0 - partial (*abc*),
+     *                          1 - strict (=),
+     *                          2 - prefix (abc*)
      * @param boolean $select   True if results are requested, False if count only
      * @param boolean $nocount  True to skip the count query (select only)
      * @param array   $required List of fields that cannot be empty
      *
      * @return object rcube_result_set Contact records and 'count' value
      */
-    function search($fields, $value, $strict=false, $select=true, $nocount=false, $required=array())
+    function search($fields, $value, $mode=0, $select=true, $nocount=false, $required=array())
     {
         if (!is_array($fields))
             $fields = array($fields);
@@ -260,6 +286,7 @@ class rcube_contacts extends rcube_addressbook
             $required = array($required);
 
         $where = $and_where = array();
+        $mode = intval($mode);
 
         foreach ($fields as $idx => $col) {
             // direct ID search
@@ -272,26 +299,56 @@ class rcube_contacts extends rcube_addressbook
             // fulltext search in all fields
             else if ($col == '*') {
                 $words = array();
-                foreach (explode(" ", self::normalize_string($value)) as $word)
-                    $words[] = $this->db->ilike('words', '%'.$word.'%');
+                foreach (explode(" ", self::normalize_string($value)) as $word) {
+                    switch ($mode) {
+                    case 1: // strict
+                        $words[] = '(' . $this->db->ilike('words', $word.' %')
+                            . ' OR ' . $this->db->ilike('words', '% '.$word.' %')
+                            . ' OR ' . $this->db->ilike('words', '% '.$word) . ')';
+                        break;
+                    case 2: // prefix
+                        $words[] = '(' . $this->db->ilike('words', $word.'%')
+                            . ' OR ' . $this->db->ilike('words', '% '.$word.'%') . ')';
+                        break;
+                    default: // partial
+                        $words[] = $this->db->ilike('words', '%'.$word.'%');
+                    }
+                }
                 $where[] = '(' . join(' AND ', $words) . ')';
             }
             else {
                 $val = is_array($value) ? $value[$idx] : $value;
                 // table column
                 if (in_array($col, $this->table_cols)) {
-                    if ($strict) {
+                    switch ($mode) {
+                    case 1: // strict
                         $where[] = $this->db->quoteIdentifier($col).' = '.$this->db->quote($val);
-                    }
-                    else {
+                        break;
+                    case 2: // prefix
+                        $where[] = $this->db->ilike($col, $val.'%');
+                        break;
+                    default: // partial
                         $where[] = $this->db->ilike($col, '%'.$val.'%');
                     }
                 }
                 // vCard field
                 else {
                     if (in_array($col, $this->fulltext_cols)) {
-                        foreach (explode(" ", self::normalize_string($val)) as $word)
-                            $words[] = $this->db->ilike('words', '%'.$word.'%');
+                        foreach (explode(" ", self::normalize_string($val)) as $word) {
+                            switch ($mode) {
+                            case 1: // strict
+                                $words[] = '(' . $this->db->ilike('words', $word.' %')
+                                    . ' OR ' . $this->db->ilike('words', '% '.$word.' %')
+                                    . ' OR ' . $this->db->ilike('words', '% '.$word) . ')';
+                                break;
+                            case 2: // prefix
+                                $words[] = '(' . $this->db->ilike('words', $word.'%')
+                                    . ' OR ' . $this->db->ilike('words', ' '.$word.'%') . ')';
+                                break;
+                            default: // partial
+                                $words[] = $this->db->ilike('words', '%'.$word.'%');
+                            }
+                        }
                         $where[] = '(' . join(' AND ', $words) . ')';
                     }
                     if (is_array($value))
@@ -339,13 +396,24 @@ class rcube_contacts extends rcube_addressbook
                         $search  = $post_search[$colname];
                         foreach ((array)$row[$col] as $value) {
                             // composite field, e.g. address
-                            if (is_array($value)) {
-                                $value = implode($value);
-                            }
-                            $value = mb_strtolower($value);
-                            if (($strict && $value == $search) || (!$strict && strpos($value, $search) !== false)) {
-                                $found[$colname] = true;
-                                break;
+                            foreach ((array)$value as $val) {
+                                $val = mb_strtolower($val);
+                                switch ($mode) {
+                                case 1:
+                                    $got = ($val == $search);
+                                    break;
+                                case 2:
+                                    $got = ($search == substr($val, 0, strlen($search)));
+                                    break;
+                                default:
+                                    $got = (strpos($val, $search) !== false);
+                                    break;
+                                }
+
+                                if ($got) {
+                                    $found[$colname] = true;
+                                    break 2;
+                                }
                             }
                         }
                     }
@@ -500,16 +568,17 @@ class rcube_contacts extends rcube_addressbook
      * 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)
     {
         // validate e-mail addresses
-        $valid = parent::validate($save_data);
+        $valid = parent::validate($save_data, $autofix);
 
         // require at least one e-mail address (syntax check is already done)
         if ($valid && !array_filter($this->get_col_values('email', $save_data, true))) {
-            $this->set_error('warning', 'noemailwarning');
+            $this->set_error(self::ERROR_VALIDATE, 'noemailwarning');
             $valid = false;
         }
 
@@ -773,8 +842,9 @@ class rcube_contacts extends rcube_addressbook
         $sql_result = $this->db->query(
             "UPDATE ".get_table_name($this->db_groups).
             " SET del=1, changed=".$this->db->now().
-            " WHERE contactgroup_id=?",
-            $gid
+            " WHERE contactgroup_id=?".
+            " AND user_id=?",
+            $gid, $this->user_id
         );
 
         $this->cache = null;
@@ -798,8 +868,9 @@ class rcube_contacts extends rcube_addressbook
         $sql_result = $this->db->query(
             "UPDATE ".get_table_name($this->db_groups).
             " SET name=?, changed=".$this->db->now().
-            " WHERE contactgroup_id=?",
-            $name, $gid
+            " WHERE contactgroup_id=?".
+            " AND user_id=?",
+            $name, $gid, $this->user_id
         );
 
         return $this->db->affected_rows() ? $name : false;