]> git.donarmstrong.com Git - roundcube.git/blob - program/include/rcube_contacts.php
Imported Upstream version 0.2~stable
[roundcube.git] / program / include / rcube_contacts.php
1 <?php
2
3 /*
4  +-----------------------------------------------------------------------+
5  | program/include/rcube_contacts.php                                    |
6  |                                                                       |
7  | This file is part of the RoundCube Webmail client                     |
8  | Copyright (C) 2006-2008, RoundCube Dev. - Switzerland                 |
9  | Licensed under the GNU GPL                                            |
10  |                                                                       |
11  | PURPOSE:                                                              |
12  |   Interface to the local address book database                        |
13  |                                                                       |
14  +-----------------------------------------------------------------------+
15  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
16  +-----------------------------------------------------------------------+
17
18  $Id: rcube_contacts.inc 328 2006-08-30 17:41:21Z thomasb $
19
20 */
21
22
23 /**
24  * Model class for the local address book database
25  *
26  * @package Addressbook
27  */
28 class rcube_contacts
29 {
30   var $db = null;
31   var $db_name = '';
32   var $user_id = 0;
33   var $filter = null;
34   var $result = null;
35   var $search_fields;
36   var $search_string;
37   var $table_cols = array('name', 'email', 'firstname', 'surname', 'vcard');
38   
39   /** public properties */
40   var $primary_key = 'contact_id';
41   var $readonly = false;
42   var $list_page = 1;
43   var $page_size = 10;
44   var $ready = false;
45
46   
47   /**
48    * Object constructor
49    *
50    * @param object  Instance of the rcube_db class
51    * @param integer User-ID
52    */
53   function __construct($dbconn, $user)
54   {
55     $this->db = $dbconn;
56     $this->db_name = get_table_name('contacts');
57     $this->user_id = $user;
58     $this->ready = $this->db && !$this->db->is_error();
59   }
60
61
62   /**
63    * Set internal list page
64    *
65    * @param  number  Page number to list
66    * @access public
67    */
68   function set_page($page)
69   {
70     $this->list_page = (int)$page;
71   }
72
73
74   /**
75    * Set internal page size
76    *
77    * @param  number  Number of messages to display on one page
78    * @access public
79    */
80   function set_pagesize($size)
81   {
82     $this->page_size = (int)$size;
83   }
84
85
86   /**
87    * Save a search string for future listings
88    *
89    * @param  string SQL params to use in listing method
90    */
91   function set_search_set($filter)
92   {
93     $this->filter = $filter;
94   }
95   
96   
97   /**
98    * Getter for saved search properties
99    *
100    * @return mixed Search properties used by this class
101    */
102   function get_search_set()
103   {
104     return $this->filter;
105   }
106
107
108   /**
109    * Reset all saved results and search parameters
110    */
111   function reset()
112   {
113     $this->result = null;
114     $this->filter = null;
115     $this->search_fields = null;
116     $this->search_string = null;
117   }
118   
119   
120   /**
121    * Close connection to source
122    * Called on script shutdown
123    */
124   function close(){}
125   
126   
127   /**
128    * List the current set of contact records
129    *
130    * @param  array  List of cols to show
131    * @param  int    Only return this number of records, use negative values for tail
132    * @return array  Indexed list of contact records, each a hash array
133    */
134   function list_records($cols=null, $subset=0)
135   {
136     // count contacts for this user
137     $this->result = $this->count();
138     $sql_result = NULL;
139
140     // get contacts from DB
141     if ($this->result->count)
142     {
143       $start_row = $subset < 0 ? $this->result->first + $this->page_size + $subset : $this->result->first;
144       $length = $subset != 0 ? abs($subset) : $this->page_size;
145       
146       $sql_result = $this->db->limitquery(
147         "SELECT * FROM ".$this->db_name."
148          WHERE  del<>1
149          AND    user_id=?" .
150         ($this->filter ? " AND (".$this->filter.")" : "") .
151         " ORDER BY name",
152         $start_row,
153         $length,
154         $this->user_id);
155     }
156     
157     while ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result)))
158     {
159       $sql_arr['ID'] = $sql_arr[$this->primary_key];
160       // make sure we have a name to display
161       if (empty($sql_arr['name']))
162         $sql_arr['name'] = $sql_arr['email'];
163       $this->result->add($sql_arr);
164     }
165     
166     return $this->result;
167   }
168
169
170   /**
171    * Search contacts
172    *
173    * @param array   List of fields to search in
174    * @param string  Search value
175    * @param boolean True if results are requested, False if count only
176    * @return Indexed list of contact records and 'count' value
177    */
178   function search($fields, $value, $strict=false, $select=true)
179   {
180     if (!is_array($fields))
181       $fields = array($fields);
182       
183     $add_where = array();
184     foreach ($fields as $col)
185     {
186       if ($col == 'ID' || $col == $this->primary_key)
187       {
188         $ids = !is_array($value) ? split(',', $value) : $value;
189         $add_where[] = $this->primary_key.' IN ('.join(',', $ids).')';
190       }
191       else if ($strict)
192         $add_where[] = $this->db->quoteIdentifier($col).'='.$this->db->quote($value);
193       else
194         $add_where[] = $this->db->ilike($col, '%'.$value.'%');
195     }
196     
197     if (!empty($add_where))
198     {
199       $this->set_search_set(join(' OR ', $add_where));
200       if ($select)
201         $this->list_records();
202       else
203         $this->result = $this->count();
204     }
205    
206     return $this->result; 
207   }
208
209
210   /**
211    * Count number of available contacts in database
212    *
213    * @return Result array with values for 'count' and 'first'
214    */
215   function count()
216   {
217     // count contacts for this user
218     $sql_result = $this->db->query(
219       "SELECT COUNT(contact_id) AS rows
220        FROM ".$this->db_name."
221        WHERE  del<>1
222        AND    user_id=?".
223        ($this->filter ? " AND (".$this->filter.")" : ""),
224       $this->user_id);
225
226     $sql_arr = $this->db->fetch_assoc($sql_result);
227     return new rcube_result_set($sql_arr['rows'], ($this->list_page-1) * $this->page_size);;
228   }
229
230
231   /**
232    * Return the last result set
233    *
234    * @return Result array or NULL if nothing selected yet
235    */
236   function get_result($as_res=true)
237   {
238     return $this->result;
239   }
240   
241   
242   /**
243    * Get a specific contact record
244    *
245    * @param mixed record identifier(s)
246    * @return Result object with all record fields or False if not found
247    */
248   function get_record($id, $assoc=false)
249   {
250     // return cached result
251     if ($this->result && ($first = $this->result->first()) && $first[$this->primary_key] == $id)
252       return $assoc ? $first : $this->result;
253       
254     $this->db->query(
255       "SELECT * FROM ".$this->db_name."
256        WHERE  contact_id=?
257        AND    user_id=?
258        AND    del<>1",
259       $id,
260       $this->user_id);
261
262     if ($sql_arr = $this->db->fetch_assoc())
263     {
264       $sql_arr['ID'] = $sql_arr[$this->primary_key];
265       $this->result = new rcube_result_set(1);
266       $this->result->add($sql_arr);
267     }
268
269     return $assoc && $sql_arr ? $sql_arr : $this->result;
270   }
271   
272   
273   /**
274    * Create a new contact record
275    *
276    * @param array Assoziative array with save data
277    * @return The created record ID on success, False on error
278    */
279   function insert($save_data, $check=false)
280   {
281     if (is_object($save_data) && is_a($save_data, rcube_result_set))
282       return $this->insert_recset($save_data, $check);
283
284     $insert_id = $existing = false;
285
286     if ($check)
287       $existing = $this->search('email', $save_data['email'], true, false);
288
289     $a_insert_cols = $a_insert_values = array();
290     foreach ($this->table_cols as $col)
291       if (isset($save_data[$col]))
292       {
293         $a_insert_cols[] = $this->db->quoteIdentifier($col);
294         $a_insert_values[] = $this->db->quote($save_data[$col]);
295       }
296     
297     if (!$existing->count && !empty($a_insert_cols))
298     {
299       $this->db->query(
300         "INSERT INTO ".$this->db_name."
301          (user_id, changed, del, ".join(', ', $a_insert_cols).")
302          VALUES (?, ".$this->db->now().", 0, ".join(', ', $a_insert_values).")",
303         $this->user_id);
304         
305       $insert_id = $this->db->insert_id(get_sequence_name('contacts'));
306     }
307     
308     return $insert_id;
309   }
310
311
312   /**
313    * Insert new contacts for each row in set
314    */
315   function insert_recset($result, $check=false)
316   {
317     $ids = array();
318     while ($row = $result->next())
319     {
320       if ($insert = $this->insert($row, $check))
321         $ids[] = $insert;
322     }
323     return $ids;
324   }
325   
326   
327   /**
328    * Update a specific contact record
329    *
330    * @param mixed Record identifier
331    * @param array Assoziative array with save data
332    * @return True on success, False on error
333    */
334   function update($id, $save_cols)
335   {
336     $updated = false;
337     $write_sql = array();
338     foreach ($this->table_cols as $col)
339       if (isset($save_cols[$col]))
340         $write_sql[] = sprintf("%s=%s", $this->db->quoteIdentifier($col), $this->db->quote($save_cols[$col]));
341
342     if (!empty($write_sql))
343     {
344       $this->db->query(
345         "UPDATE ".$this->db_name."
346          SET    changed=".$this->db->now().", ".join(', ', $write_sql)."
347          WHERE  contact_id=?
348          AND    user_id=?
349          AND    del<>1",
350         $id,
351         $this->user_id);
352
353       $updated = $this->db->affected_rows();
354     }
355     
356     return $updated;
357   }
358   
359   
360   /**
361    * Mark one or more contact records as deleted
362    *
363    * @param array  Record identifiers
364    */
365   function delete($ids)
366   {
367     if (is_array($ids))
368       $ids = join(',', $ids);
369
370     $this->db->query(
371       "UPDATE ".$this->db_name."
372        SET    del=1
373        WHERE  user_id=?
374        AND    contact_id IN (".$ids.")",
375       $this->user_id);
376
377     return $this->db->affected_rows();
378   }
379   
380   
381   /**
382    * Remove all records from the database
383    */
384   function delete_all()
385   {
386     $this->db->query("DELETE FROM {$this->db_name} WHERE user_id=?", $this->user_id);
387     return $this->db->affected_rows();
388   }
389
390 }