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