source: github/program/include/rcube_user.php @ 56505a1

HEADcourier-fixdev-browser-capabilitiespdorelease-0.6release-0.7release-0.8
Last change on this file since 56505a1 was 56505a1, checked in by alecpl <alec@…>, 3 years ago
  • Options virtuser_* replaced with virtuser_* plugins
  • Plugin API: Implemented 'email2user' and 'user2email' hooks
  • Property mode set to 100644
File size: 12.6 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-2009, 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$
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  public $ID = null;
33  public $data = null;
34  public $language = null;
35 
36  private $db = null;
37 
38 
39  /**
40   * Object constructor
41   *
42   * @param object DB Database connection
43   */
44  function __construct($id = null, $sql_arr = null)
45  {
46    $this->db = rcmail::get_instance()->get_dbh();
47   
48    if ($id && !$sql_arr)
49    {
50      $sql_result = $this->db->query("SELECT * FROM ".get_table_name('users')." WHERE user_id=?", $id);
51      $sql_arr = $this->db->fetch_assoc($sql_result);
52    }
53   
54    if (!empty($sql_arr))
55    {
56      $this->ID = $sql_arr['user_id'];
57      $this->data = $sql_arr;
58      $this->language = $sql_arr['language'];
59    }
60  }
61
62
63  /**
64   * Build a user name string (as e-mail address)
65   *
66   * @return string Full user name
67   */
68  function get_username()
69  {
70    return $this->data['username'] ? $this->data['username'] . (!strpos($this->data['username'], '@') ? '@'.$this->data['mail_host'] : '') : false;
71  }
72 
73 
74  /**
75   * Get the preferences saved for this user
76   *
77   * @return array Hash array with prefs
78   */
79  function get_prefs()
80  {
81    if (!empty($this->language))
82      $prefs = array('language' => $this->language);
83   
84    if ($this->ID && $this->data['preferences'])
85      $prefs += (array)unserialize($this->data['preferences']);
86   
87    return $prefs;
88  }
89 
90 
91  /**
92   * Write the given user prefs to the user's record
93   *
94   * @param array User prefs to save
95   * @return boolean True on success, False on failure
96   */
97  function save_prefs($a_user_prefs)
98  {
99    if (!$this->ID)
100      return false;
101     
102    $config = rcmail::get_instance()->config;
103    $old_prefs = (array)$this->get_prefs();
104
105    // merge (partial) prefs array with existing settings
106    $save_prefs = $a_user_prefs + $old_prefs;
107    unset($save_prefs['language']);
108   
109    // don't save prefs with default values if they haven't been changed yet
110    foreach ($a_user_prefs as $key => $value) {
111      if (!isset($old_prefs[$key]) && ($value == $config->get($key)))
112        unset($save_prefs[$key]);
113    }
114   
115    $this->db->query(
116      "UPDATE ".get_table_name('users')."
117       SET    preferences=?,
118              language=?
119       WHERE  user_id=?",
120      serialize($save_prefs),
121      $_SESSION['language'],
122      $this->ID);
123
124    $this->language = $_SESSION['language'];
125    if ($this->db->affected_rows()) {
126      $config->set_user_prefs($a_user_prefs);
127      return true;
128    }
129
130    return false;
131  }
132 
133 
134  /**
135   * Get default identity of this user
136   *
137   * @param int  Identity ID. If empty, the default identity is returned
138   * @return array Hash array with all cols of the identity record
139   */
140  function get_identity($id = null)
141  {
142    $result = $this->list_identities($id ? sprintf('AND identity_id=%d', $id) : '');
143    return $result[0];
144  }
145 
146 
147  /**
148   * Return a list of all identities linked with this user
149   *
150   * @return array List of identities
151   */
152  function list_identities($sql_add = '')
153  {
154    // get contacts from DB
155    $sql_result = $this->db->query(
156      "SELECT * FROM ".get_table_name('identities')."
157       WHERE del<>1 AND user_id=?
158       $sql_add
159       ORDER BY ".$this->db->quoteIdentifier('standard')." DESC, name ASC, identity_id ASC",
160      $this->ID);
161   
162    $result = array();
163    while ($sql_arr = $this->db->fetch_assoc($sql_result)) {
164      $result[] = $sql_arr;
165    }
166   
167    return $result;
168  }
169 
170 
171  /**
172   * Update a specific identity record
173   *
174   * @param int    Identity ID
175   * @param array  Hash array with col->value pairs to save
176   * @return boolean True if saved successfully, false if nothing changed
177   */
178  function update_identity($iid, $data)
179  {
180    if (!$this->ID)
181      return false;
182   
183    $query_cols = $query_params = array();
184   
185    foreach ((array)$data as $col => $value)
186    {
187      $query_cols[] = $this->db->quoteIdentifier($col) . '=?';
188      $query_params[] = $value;
189    }
190    $query_params[] = $iid;
191    $query_params[] = $this->ID;
192
193    $sql = "UPDATE ".get_table_name('identities')."
194       SET ".join(', ', $query_cols)."
195       WHERE  identity_id=?
196       AND    user_id=?
197       AND    del<>1";
198
199    call_user_func_array(array($this->db, 'query'),
200                        array_merge(array($sql), $query_params));
201   
202    return $this->db->affected_rows();
203  }
204 
205 
206  /**
207   * Create a new identity record linked with this user
208   *
209   * @param array  Hash array with col->value pairs to save
210   * @return int  The inserted identity ID or false on error
211   */
212  function insert_identity($data)
213  {
214    if (!$this->ID)
215      return false;
216
217    unset($data['user_id']);
218
219    $insert_cols = $insert_values = array();
220    foreach ((array)$data as $col => $value)
221    {
222      $insert_cols[] = $this->db->quoteIdentifier($col);
223      $insert_values[] = $value;
224    }
225    $insert_cols[] = 'user_id';
226    $insert_values[] = $this->ID;
227
228    $sql = "INSERT INTO ".get_table_name('identities')."
229        (".join(', ', $insert_cols).")
230       VALUES (".join(', ', array_pad(array(), sizeof($insert_values), '?')).")";
231
232    call_user_func_array(array($this->db, 'query'),
233                        array_merge(array($sql), $insert_values));
234
235    return $this->db->insert_id('identities');
236  }
237 
238 
239  /**
240   * Mark the given identity as deleted
241   *
242   * @param int  Identity ID
243   * @return boolean True if deleted successfully, false if nothing changed
244   */
245  function delete_identity($iid)
246  {
247    if (!$this->ID)
248      return false;
249
250    $sql_result = $this->db->query("SELECT count(*) AS ident_count FROM " .
251      get_table_name('identities') .
252      " WHERE user_id = ? AND del <> 1",
253      $this->ID);
254
255    $sql_arr = $this->db->fetch_assoc($sql_result);
256    if ($sql_arr['ident_count'] <= 1)
257      return false;
258   
259    $this->db->query(
260      "UPDATE ".get_table_name('identities')."
261       SET    del=1
262       WHERE  user_id=?
263       AND    identity_id=?",
264      $this->ID,
265      $iid);
266
267    return $this->db->affected_rows();
268  }
269 
270 
271  /**
272   * Make this identity the default one for this user
273   *
274   * @param int The identity ID
275   */
276  function set_default($iid)
277  {
278    if ($this->ID && $iid)
279    {
280      $this->db->query(
281        "UPDATE ".get_table_name('identities')."
282         SET ".$this->db->quoteIdentifier('standard')."='0'
283         WHERE  user_id=?
284         AND    identity_id<>?
285         AND    del<>1",
286        $this->ID,
287        $iid);
288    }
289  }
290 
291 
292  /**
293   * Update user's last_login timestamp
294   */
295  function touch()
296  {
297    if ($this->ID)
298    {
299      $this->db->query(
300        "UPDATE ".get_table_name('users')."
301         SET    last_login=".$this->db->now()."
302         WHERE  user_id=?",
303        $this->ID);
304    }
305  }
306 
307 
308  /**
309   * Clear the saved object state
310   */
311  function reset()
312  {
313    $this->ID = null;
314    $this->data = null;
315  }
316 
317 
318  /**
319   * Find a user record matching the given name and host
320   *
321   * @param string IMAP user name
322   * @param string IMAP host name
323   * @return object rcube_user New user instance
324   */
325  static function query($user, $host)
326  {
327    $dbh = rcmail::get_instance()->get_dbh();
328   
329    // query for matching user name
330    $query = "SELECT * FROM ".get_table_name('users')." WHERE mail_host=? AND %s=?";
331    $sql_result = $dbh->query(sprintf($query, 'username'), $host, $user);
332   
333    // query for matching alias
334    if (!($sql_arr = $dbh->fetch_assoc($sql_result))) {
335      $sql_result = $dbh->query(sprintf($query, 'alias'), $host, $user);
336      $sql_arr = $dbh->fetch_assoc($sql_result);
337    }
338   
339    // user already registered -> overwrite username
340    if ($sql_arr)
341      return new rcube_user($sql_arr['user_id'], $sql_arr);
342    else
343      return false;
344  }
345 
346 
347  /**
348   * Create a new user record and return a rcube_user instance
349   *
350   * @param string IMAP user name
351   * @param string IMAP host
352   * @return object rcube_user New user instance
353   */
354  static function create($user, $host)
355  {
356    $user_name  = '';
357    $user_email = '';
358    $rcmail = rcmail::get_instance();
359
360    // try to resolve user in virtuser table and file
361    if ($email_list = self::user2email($user, false, true)) {
362      $user_email = is_array($email_list[0]) ? $email_list[0][0] : $email_list[0];
363    }
364
365    $data = $rcmail->plugins->exec_hook('create_user',
366        array('user'=>$user, 'user_name'=>$user_name, 'user_email'=>$user_email));
367
368    // plugin aborted this operation
369    if ($data['abort'])
370      return false;
371
372    $user_name = $data['user_name'];
373    $user_email = $data['user_email'];
374
375    $dbh = $rcmail->get_dbh();
376
377    $dbh->query(
378      "INSERT INTO ".get_table_name('users')."
379        (created, last_login, username, mail_host, alias, language)
380       VALUES (".$dbh->now().", ".$dbh->now().", ?, ?, ?, ?)",
381      strip_newlines($user),
382      strip_newlines($host),
383      strip_newlines($data['alias'] ? $data['alias'] : $user_email),
384      $_SESSION['language']);
385
386    if ($user_id = $dbh->insert_id('users'))
387    {
388      // create rcube_user instance to make plugin hooks work
389      $user_instance = new rcube_user($user_id);
390      $rcmail->user = $user_instance;
391
392      $mail_domain = $rcmail->config->mail_domain($host);
393
394      if ($user_email=='')
395        $user_email = strpos($user, '@') ? $user : sprintf('%s@%s', $user, $mail_domain);
396
397      if ($user_name == '') {
398        $user_name = $user != $user_email ? $user : '';
399      }
400
401      if (empty($email_list))
402        $email_list[] = strip_newlines($user_email);
403      // identities_level check
404      else if (count($email_list) > 1 && $rcmail->config->get('identities_level', 0) > 1)
405        $email_list = array($email_list[0]);
406
407      // create new identities records
408      $standard = 1;
409      foreach ($email_list as $row) {
410        if (is_array($row)) {
411          $email = $row[0];
412          $name = $row[1] ? $row[1] : $user_name;
413        }
414        else {
415          $email = $row;
416          $name = $user_name;
417        }
418
419        $plugin = $rcmail->plugins->exec_hook('create_identity', array(
420          'login' => true,
421          'record' => array(
422            'user_id' => $user_id,
423            'name' => strip_newlines($name),
424            'email' => $email,
425            'standard' => $standard,
426          ),
427        ));
428         
429        if (!$plugin['abort'] && $plugin['record']['email']) {
430          $rcmail->user->insert_identity($plugin['record']);
431        }
432        $standard = 0;
433      }
434    }
435    else
436    {
437      raise_error(array(
438        'code' => 500,
439        'type' => 'php',
440        'line' => __LINE__,
441        'file' => __FILE__,
442        'message' => "Failed to create new user"), true, false);
443    }
444   
445    return $user_id ? $user_instance : false;
446  }
447 
448 
449  /**
450   * Resolve username using a virtuser plugins
451   *
452   * @param string E-mail address to resolve
453   * @return string Resolved IMAP username
454   */
455  static function email2user($email)
456  {
457    $rcmail = rcmail::get_instance();
458    $plugin = $rcmail->plugins->exec_hook('email2user',
459      array('email' => $email, 'user' => NULL));
460
461    return $plugin['user'];
462  }
463
464
465  /**
466   * Resolve e-mail address from virtuser plugins
467   *
468   * @param string User name
469   * @param boolean If true returns first found entry
470   * @param boolean If true returns email as array (email and name for identity)
471   * @return mixed Resolved e-mail address string or array of strings
472   */
473  static function user2email($user, $first=true, $extended=false)
474  {
475    $rcmail = rcmail::get_instance();
476    $plugin = $rcmail->plugins->exec_hook('user2email',
477      array('email' => NULL, 'user' => $user,
478        'first' => $first, 'extended' => $extended));
479
480    return empty($plugin['email']) ? NULL : $plugin['email'];
481  }
482 
483}
Note: See TracBrowser for help on using the repository browser.