source: subversion/trunk/roundcubemail/program/include/rcube_user.inc @ 938

Last change on this file since 938 was 938, checked in by thomasb, 5 years ago

New class rcube_user + send message disposition notification

File size: 10.7 KB
Line 
1<?php
2
3/*
4 +-----------------------------------------------------------------------+
5 | program/include/rcube_user.inc                                        |
6 |                                                                       |
7 | This file is part of the RoundCube Webmail client                     |
8 | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
9 | Licensed under the GNU GPL                                            |
10 |                                                                       |
11 | PURPOSE:                                                              |
12 |   This class represents a system user linked and provides access      |
13 |   to the related database records.                                    |
14 |                                                                       |
15 +-----------------------------------------------------------------------+
16 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
17 +-----------------------------------------------------------------------+
18
19 $Id: rcube_user.inc 933 2007-11-29 14:17:32Z thomasb $
20
21*/
22
23
24/**
25 * Class representing a system user
26 *
27 * @package    core
28 * @author     Thomas Bruederli <roundcube@gmail.com>
29 */
30class rcube_user
31{
32  var $ID = null;
33  var $data = null;
34 
35 
36  /**
37   * Object constructor
38   *
39   * @param object DB Database connection
40   */
41  function __construct($id = null, $sql_arr = null)
42  {
43    global $DB;
44   
45    if ($id && !$sql_arr)
46    {
47      $sql_result = $DB->query("SELECT * FROM ".get_table_name('users')." WHERE  user_id=?", $id);
48      $sql_arr = $DB->fetch_assoc($sql_result);
49    }
50   
51    if (!empty($sql_arr))
52    {
53      $this->ID = $sql_arr['user_id'];
54      $this->data = $sql_arr;
55    }
56  }
57
58  /**
59   * PHP 4 object constructor
60   *
61   * @see  rcube_user::__construct
62   */
63  function rcube_user($id = null, $sql_arr = null)
64  {
65    $this->__construct($id, $sql_arr);
66  }
67 
68 
69  /**
70   * Build a user name string (as e-mail address)
71   *
72   * @return string Full user name
73   */
74  function get_username()
75  {
76    return $this->data['username'] ? $this->data['username'] . (!strpos($this->data['username'], '@') ? '@'.$this->data['mail_host'] : '') : false;
77  }
78 
79 
80  /**
81   * Get the preferences saved for this user
82   *
83   * @return array Hash array with prefs
84   */
85  function get_prefs()
86  {
87    if ($this->ID && $this->data['preferences'])
88      return unserialize($this->data['preferences']);
89    else
90      return array();
91  }
92 
93 
94  /**
95   * Write the given user prefs to the user's record
96   *
97   * @param mixed User prefs to save
98   * @return boolean True on success, False on failure
99   */
100  function save_prefs($a_user_prefs)
101  {
102    global $DB, $CONFIG, $sess_user_lang;
103   
104    if (!$this->ID)
105      return false;
106
107    // merge (partial) prefs array with existing settings
108    $a_user_prefs += (array)$this->get_prefs();
109
110    $DB->query(
111      "UPDATE ".get_table_name('users')."
112       SET    preferences=?,
113              language=?
114       WHERE  user_id=?",
115      serialize($a_user_prefs),
116      $sess_user_lang,
117      $this->ID);
118
119    if ($DB->affected_rows())
120    {
121      $CONFIG = array_merge($CONFIG, $a_user_prefs);
122      return true;
123    }
124
125    return false;
126  }
127 
128 
129  /**
130   * Get default identity of this user
131   *
132   * @param int  Identity ID. If empty, the default identity is returned
133   * @return array Hash array with all cols of the
134   */
135  function get_identity($id = null)
136  {
137    global $DB;
138   
139    $sql_result = $this->list_identities($id ? sprintf('AND identity_id=%d', $id) : '');
140    return $DB->fetch_assoc($sql_result);
141  }
142 
143 
144  /**
145   * Return a list of all identities linked with this user
146   *
147   * @return array List of identities
148   */
149  function list_identities($sql_add = '')
150  {
151    global $DB;
152   
153    // get contacts from DB
154    $sql_result = $DB->query(
155      "SELECT * FROM ".get_table_name('identities')."
156       WHERE  del<>1
157       AND    user_id=?
158       $sql_add
159       ORDER BY ".$DB->quoteIdentifier('standard')." DESC, name ASC",
160      $this->ID);
161   
162    return $sql_result;
163  }
164 
165 
166  /**
167   * Update a specific identity record
168   *
169   * @param int    Identity ID
170   * @param array  Hash array with col->value pairs to save
171   * @return boolean True if saved successfully, false if nothing changed
172   */
173  function update_identity($iid, $data)
174  {
175    global $DB;
176   
177    if (!$this->ID)
178      return false;
179   
180    $write_sql = array();
181   
182    foreach ((array)$data as $col => $value)
183    {
184      $write_sql[] = sprintf("%s=%s",
185        $DB->quoteIdentifier($col),
186        $DB->quote($value));
187    }
188   
189    $DB->query(
190      "UPDATE ".get_table_name('identities')."
191       SET ".join(', ', $write_sql)."
192       WHERE  identity_id=?
193       AND    user_id=?
194       AND    del<>1",
195      $iid,
196      $this->ID);
197   
198    return $DB->affected_rows();
199  }
200 
201 
202  /**
203   * Create a new identity record linked with this user
204   *
205   * @param array  Hash array with col->value pairs to save
206   * @return int  The inserted identity ID or false on error
207   */
208  function insert_identity($data)
209  {
210    global $DB;
211   
212    if (!$this->ID)
213      return false;
214
215    $insert_cols = $insert_values = array();
216    foreach ((array)$data as $col => $value)
217    {
218      $insert_cols[] = $DB->quoteIdentifier($col);
219      $insert_values[] = $DB->quote($value);
220    }
221
222    $DB->query(
223      "INSERT INTO ".get_table_name('identities')."
224        (user_id, ".join(', ', $insert_cols).")
225       VALUES (?, ".join(', ', $insert_values).")",
226      $this->ID);
227
228    return $DB->insert_id(get_sequence_name('identities'));
229  }
230 
231 
232  /**
233   * Mark the given identity as deleted
234   *
235   * @param int  Identity ID
236   * @return boolean True if deleted successfully, false if nothing changed
237   */
238  function delete_identity($iid)
239  {
240    global $DB;
241   
242    if (!$this->ID)
243      return false;
244   
245    $DB->query(
246      "UPDATE ".get_table_name('identities')."
247       SET    del=1
248       WHERE  user_id=?
249       AND    identity_id=?",
250      $this->ID,
251      $iid);
252
253    return $DB->affected_rows();
254  }
255 
256 
257  /**
258   * Make this identity the default one for this user
259   *
260   * @param int The identity ID
261   */
262  function set_default($iid)
263  {
264    global $DB;
265   
266    if ($this->ID && $iid)
267    {
268      $DB->query(
269        "UPDATE ".get_table_name('identities')."
270         SET ".$DB->quoteIdentifier('standard')."='0'
271         WHERE  user_id=?
272         AND    identity_id<>?
273         AND    del<>1",
274        $this->ID,
275        $iid);
276    }
277  }
278 
279 
280  /**
281   * Update user's last_login timestamp
282   */
283  function touch()
284  {
285    global $DB;
286   
287    if ($this->ID)
288    {
289      $DB->query(
290        "UPDATE ".get_table_name('users')."
291         SET    last_login=".$DB->now()."
292         WHERE  user_id=?",
293        $this->ID);
294    }
295  }
296 
297 
298  /**
299   * Clear the saved object state
300   */
301  function reset()
302  {
303    $this->ID = null;
304    $this->data = null;
305  }
306 
307 
308  /**
309   * Find a user record matching the given name and host
310   *
311   * @param string IMAP user name
312   * @param string IMAP host name
313   * @return object rcube_user New user instance
314   * @static
315   */
316  function query($user, $host)
317  {
318    global $DB;
319   
320    // query if user already registered
321    $sql_result = $DB->query(
322      "SELECT * FROM ".get_table_name('users')."
323       WHERE  mail_host=? AND (username=? OR alias=?)",
324      $host,
325      $user,
326      $user);
327     
328    // user already registered -> overwrite username
329    if ($sql_arr = $DB->fetch_assoc($sql_result))
330      return new rcube_user($sql_arr['user_id'], $sql_arr);
331    else
332      return false;
333  }
334 
335 
336  /**
337   * Create a new user record and return a rcube_user instance
338   *
339   * @param string IMAP user name
340   * @param string IMAP host
341   * @return object rcube_user New user instance
342   * @static
343   */
344  function create($user, $host)
345  {
346    global $DB, $CONFIG;
347   
348    $user_email = '';
349
350    // try to resolve user in virtusertable
351    if (!empty($CONFIG['virtuser_file']) && !strpos($user, '@'))
352      $user_email = self::user2email($user);
353
354    $DB->query(
355      "INSERT INTO ".get_table_name('users')."
356        (created, last_login, username, mail_host, alias, language)
357       VALUES (".$DB->now().", ".$DB->now().", ?, ?, ?, ?)",
358      strip_newlines($user),
359      strip_newlines($host),
360      strip_newlines($user_email),
361      $_SESSION['user_lang']);
362
363    if ($user_id = $DB->insert_id(get_sequence_name('users')))
364    {
365      $mail_domain = rcmail_mail_domain($host);
366
367      if ($user_email=='')
368        $user_email = strpos($user, '@') ? $user : sprintf('%s@%s', $user, $mail_domain);
369
370      $user_name = $user != $user_email ? $user : '';
371
372      // try to resolve the e-mail address from the virtuser table
373      if (!empty($CONFIG['virtuser_query']) &&
374          ($sql_result = $DB->query(preg_replace('/%u/', $DB->escapeSimple($user), $CONFIG['virtuser_query']))) &&
375          ($DB->num_rows()>0))
376      {
377        while ($sql_arr = $DB->fetch_array($sql_result))
378        {
379          $DB->query(
380            "INSERT INTO ".get_table_name('identities')."
381              (user_id, del, standard, name, email)
382             VALUES (?, 0, 1, ?, ?)",
383            $user_id,
384            strip_newlines($user_name),
385            preg_replace('/^@/', $user . '@', $sql_arr[0]));
386        }
387      }
388      else
389      {
390        // also create new identity records
391        $DB->query(
392          "INSERT INTO ".get_table_name('identities')."
393            (user_id, del, standard, name, email)
394           VALUES (?, 0, 1, ?, ?)",
395          $user_id,
396          strip_newlines($user_name),
397          strip_newlines($user_email));
398      }
399    }
400    else
401    {
402      raise_error(array(
403        'code' => 500,
404        'type' => 'php',
405        'line' => __LINE__,
406        'file' => __FILE__,
407        'message' => "Failed to create new user"), true, false);
408    }
409   
410    return $user_id ? new rcube_user($user_id) : false;
411  }
412 
413 
414  /**
415   * Resolve username using a virtuser table
416   *
417   * @param string E-mail address to resolve
418   * @return string Resolved IMAP username
419   * @static
420   */
421  function email2user($email)
422  {
423    $user = $email;
424    $r = rcmail_findinvirtual("^$email");
425
426    for ($i=0; $i<count($r); $i++)
427    {
428      $data = $r[$i];
429      $arr = preg_split('/\s+/', $data);
430      if (count($arr) > 0)
431      {
432        $user = trim($arr[count($arr)-1]);
433        break;
434      }
435    }
436
437    return $user;
438  }
439
440
441  /**
442   * Resolve e-mail address from virtuser table
443   *
444   * @param string User name
445   * @return string Resolved e-mail address
446   * @static
447   */
448  function user2email($user)
449  {
450    $email = "";
451    $r = rcmail_findinvirtual("$user$");
452
453    for ($i=0; $i<count($r); $i++)
454    {
455      $data = $r[$i];
456      $arr = preg_split('/\s+/', $data);
457      if (count($arr) > 0)
458      {
459        $email = trim($arr[0]);
460        break;
461      }
462    }
463
464    return $email;
465  }
466
467}
468
469
470?>
Note: See TracBrowser for help on using the repository browser.