PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/libraries/joomla/database/table/user.php

http://github.com/joomla/joomla-platform
PHP | 482 lines | 288 code | 56 blank | 138 comment | 56 complexity | f9678819dc93a3fc49629d63c9db841a MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Database
  5. *
  6. * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. jimport('joomla.database.table');
  11. /**
  12. * Users table
  13. *
  14. * @package Joomla.Platform
  15. * @subpackage Table
  16. * @since 11.1
  17. */
  18. class JTableUser extends JTable
  19. {
  20. /**
  21. * Associative array of user names => group ids
  22. *
  23. * @var array
  24. * @since 11.1
  25. */
  26. public $groups;
  27. /**
  28. * Constructor
  29. *
  30. * @param JDatabase &$db A database connector object.
  31. *
  32. * @since 11.1
  33. */
  34. public function __construct(&$db)
  35. {
  36. parent::__construct('#__users', 'id', $db);
  37. // Initialise.
  38. $this->id = 0;
  39. $this->sendEmail = 0;
  40. }
  41. /**
  42. * Method to load a user, user groups, and any other necessary data
  43. * from the database so that it can be bound to the user object.
  44. *
  45. * @param integer $userId An optional user id.
  46. * @param boolean $reset False if row not found or on error
  47. * (internal error state set in that case).
  48. *
  49. * @return boolean True on success, false on failure.
  50. *
  51. * @since 11.1
  52. */
  53. public function load($userId = null, $reset = true)
  54. {
  55. // Get the id to load.
  56. if ($userId !== null)
  57. {
  58. $this->id = $userId;
  59. }
  60. else
  61. {
  62. $userId = $this->id;
  63. }
  64. // Check for a valid id to load.
  65. if ($userId === null)
  66. {
  67. return false;
  68. }
  69. // Reset the table.
  70. $this->reset();
  71. // Load the user data.
  72. $query = $this->_db->getQuery(true);
  73. $query->select('*');
  74. $query->from($this->_db->quoteName('#__users'));
  75. $query->where($this->_db->quoteName('id') . ' = ' . (int) $userId);
  76. $this->_db->setQuery($query);
  77. $data = (array) $this->_db->loadAssoc();
  78. // Check for an error message.
  79. if ($this->_db->getErrorNum())
  80. {
  81. $this->setError($this->_db->getErrorMsg());
  82. return false;
  83. }
  84. if (!count($data))
  85. {
  86. return false;
  87. }
  88. // Bind the data to the table.
  89. $return = $this->bind($data);
  90. if ($return !== false)
  91. {
  92. // Load the user groups.
  93. $query->clear();
  94. $query->select($this->_db->quoteName('g') . '.' . $this->_db->quoteName('id'));
  95. $query->select($this->_db->quoteName('g') . '.' . $this->_db->quoteName('title'));
  96. $query->from($this->_db->quoteName('#__usergroups') . ' AS g');
  97. $query->join('INNER', $this->_db->quoteName('#__user_usergroup_map') . ' AS m ON m.group_id = g.id');
  98. $query->where($this->_db->quoteName('m.user_id') . ' = ' . (int) $userId);
  99. $this->_db->setQuery($query);
  100. // Add the groups to the user data.
  101. $this->groups = $this->_db->loadAssocList('id', 'id');
  102. // Check for an error message.
  103. if ($this->_db->getErrorNum())
  104. {
  105. $this->setError($this->_db->getErrorMsg());
  106. return false;
  107. }
  108. }
  109. return $return;
  110. }
  111. /**
  112. * Method to bind the user, user groups, and any other necessary data.
  113. *
  114. * @param array $array The data to bind.
  115. * @param mixed $ignore An array or space separated list of fields to ignore.
  116. *
  117. * @return boolean True on success, false on failure.
  118. *
  119. * @since 11.1
  120. */
  121. public function bind($array, $ignore = '')
  122. {
  123. if (key_exists('params', $array) && is_array($array['params']))
  124. {
  125. $registry = new JRegistry;
  126. $registry->loadArray($array['params']);
  127. $array['params'] = (string) $registry;
  128. }
  129. // Attempt to bind the data.
  130. $return = parent::bind($array, $ignore);
  131. // Load the real group data based on the bound ids.
  132. if ($return && !empty($this->groups))
  133. {
  134. // Set the group ids.
  135. JArrayHelper::toInteger($this->groups);
  136. // Get the titles for the user groups.
  137. $query = $this->_db->getQuery(true);
  138. $query->select($this->_db->quoteName('id'));
  139. $query->select($this->_db->quoteName('title'));
  140. $query->from($this->_db->quoteName('#__usergroups'));
  141. $query->where($this->_db->quoteName('id') . ' = ' . implode(' OR ' . $this->_db->quoteName('id') . ' = ', $this->groups));
  142. $this->_db->setQuery($query);
  143. // Set the titles for the user groups.
  144. $this->groups = $this->_db->loadAssocList('id', 'id');
  145. // Check for a database error.
  146. if ($this->_db->getErrorNum())
  147. {
  148. $this->setError($this->_db->getErrorMsg());
  149. return false;
  150. }
  151. }
  152. return $return;
  153. }
  154. /**
  155. * Validation and filtering
  156. *
  157. * @return boolean True if satisfactory
  158. *
  159. * @since 11.1
  160. */
  161. public function check()
  162. {
  163. // Validate user information
  164. if (trim($this->name) == '')
  165. {
  166. $this->setError(JText::_('JLIB_DATABASE_ERROR_PLEASE_ENTER_YOUR_NAME'));
  167. return false;
  168. }
  169. if (trim($this->username) == '')
  170. {
  171. $this->setError(JText::_('JLIB_DATABASE_ERROR_PLEASE_ENTER_A_USER_NAME'));
  172. return false;
  173. }
  174. if (preg_match("#[<>\"'%;()&]#i", $this->username) || strlen(utf8_decode($this->username)) < 2)
  175. {
  176. $this->setError(JText::sprintf('JLIB_DATABASE_ERROR_VALID_AZ09', 2));
  177. return false;
  178. }
  179. if ((trim($this->email) == "") || !JMailHelper::isEmailAddress($this->email))
  180. {
  181. $this->setError(JText::_('JLIB_DATABASE_ERROR_VALID_MAIL'));
  182. return false;
  183. }
  184. // Set the registration timestamp
  185. if ($this->registerDate == null || $this->registerDate == $this->_db->getNullDate())
  186. {
  187. $this->registerDate = JFactory::getDate()->toSql();
  188. }
  189. // check for existing username
  190. $query = $this->_db->getQuery(true);
  191. $query->select($this->_db->quoteName('id'));
  192. $query->from($this->_db->quoteName('#__users'));
  193. $query->where($this->_db->quoteName('username') . ' = ' . $this->_db->quote($this->username));
  194. $query->where($this->_db->quoteName('id') . ' != ' . (int) $this->id);
  195. $this->_db->setQuery($query);
  196. $this->_db->setQuery($query);
  197. $xid = intval($this->_db->loadResult());
  198. if ($xid && $xid != intval($this->id))
  199. {
  200. $this->setError(JText::_('JLIB_DATABASE_ERROR_USERNAME_INUSE'));
  201. return false;
  202. }
  203. // check for existing email
  204. $query->clear();
  205. $query->select($this->_db->quoteName('id'));
  206. $query->from($this->_db->quoteName('#__users'));
  207. $query->where($this->_db->quoteName('email') . ' = ' . $this->_db->quote($this->email));
  208. $query->where($this->_db->quoteName('id') . ' != ' . (int) $this->id);
  209. $this->_db->setQuery($query);
  210. $xid = intval($this->_db->loadResult());
  211. if ($xid && $xid != intval($this->id))
  212. {
  213. $this->setError(JText::_('JLIB_DATABASE_ERROR_EMAIL_INUSE'));
  214. return false;
  215. }
  216. // check for root_user != username
  217. $config = JFactory::getConfig();
  218. $rootUser = $config->get('root_user');
  219. if (!is_numeric($rootUser))
  220. {
  221. $query->clear();
  222. $query->select($this->_db->quoteName('id'));
  223. $query->from($this->_db->quoteName('#__users'));
  224. $query->where($this->_db->quoteName('username') . ' = ' . $this->_db->quote($rootUser));
  225. $this->_db->setQuery($query);
  226. $xid = intval($this->_db->loadResult());
  227. if ($rootUser == $this->username && (!$xid || $xid && $xid != intval($this->id))
  228. || $xid && $xid == intval($this->id) && $rootUser != $this->username)
  229. {
  230. $this->setError(JText::_('JLIB_DATABASE_ERROR_USERNAME_CANNOT_CHANGE'));
  231. return false;
  232. }
  233. }
  234. return true;
  235. }
  236. /**
  237. * Method to store a row in the database from the JTable instance properties.
  238. * If a primary key value is set the row with that primary key value will be
  239. * updated with the instance property values. If no primary key value is set
  240. * a new row will be inserted into the database with the properties from the
  241. * JTable instance.
  242. *
  243. * @param boolean $updateNulls True to update fields even if they are null.
  244. *
  245. * @return boolean True on success.
  246. *
  247. * @link http://docs.joomla.org/JTable/store
  248. * @since 11.1
  249. */
  250. public function store($updateNulls = false)
  251. {
  252. // Get the table key and key value.
  253. $k = $this->_tbl_key;
  254. $key = $this->$k;
  255. // TODO: This is a dumb way to handle the groups.
  256. // Store groups locally so as to not update directly.
  257. $groups = $this->groups;
  258. unset($this->groups);
  259. // Insert or update the object based on presence of a key value.
  260. if ($key)
  261. {
  262. // Already have a table key, update the row.
  263. $return = $this->_db->updateObject($this->_tbl, $this, $this->_tbl_key, $updateNulls);
  264. }
  265. else
  266. {
  267. // Don't have a table key, insert the row.
  268. $return = $this->_db->insertObject($this->_tbl, $this, $this->_tbl_key);
  269. }
  270. // Handle error if it exists.
  271. if (!$return)
  272. {
  273. $this->setError(JText::sprintf('JLIB_DATABASE_ERROR_STORE_FAILED', strtolower(get_class($this)), $this->_db->getErrorMsg()));
  274. return false;
  275. }
  276. // Reset groups to the local object.
  277. $this->groups = $groups;
  278. unset($groups);
  279. // Store the group data if the user data was saved.
  280. if ($return && is_array($this->groups) && count($this->groups))
  281. {
  282. // Delete the old user group maps.
  283. $query = $this->_db->getQuery(true);
  284. $query->delete();
  285. $query->from($this->_db->quoteName('#__user_usergroup_map'));
  286. $query->where($this->_db->quoteName('user_id') . ' = ' . (int) $this->id);
  287. $this->_db->setQuery($query);
  288. $this->_db->query();
  289. // Check for a database error.
  290. if ($this->_db->getErrorNum())
  291. {
  292. $this->setError($this->_db->getErrorMsg());
  293. return false;
  294. }
  295. // Set the new user group maps.
  296. $query->clear();
  297. $query->insert($this->_db->quoteName('#__user_usergroup_map'));
  298. $query->columns(array($this->_db->quoteName('user_id'), $this->_db->quoteName('group_id')));
  299. $query->values($this->id . ', ' . implode('), (' . $this->id . ', ', $this->groups));
  300. $this->_db->setQuery($query);
  301. $this->_db->query();
  302. // Check for a database error.
  303. if ($this->_db->getErrorNum())
  304. {
  305. $this->setError($this->_db->getErrorMsg());
  306. return false;
  307. }
  308. }
  309. return true;
  310. }
  311. /**
  312. * Method to delete a user, user groups, and any other necessary data from the database.
  313. *
  314. * @param integer $userId An optional user id.
  315. *
  316. * @return boolean True on success, false on failure.
  317. *
  318. * @since 11.1
  319. */
  320. public function delete($userId = null)
  321. {
  322. // Set the primary key to delete.
  323. $k = $this->_tbl_key;
  324. if ($userId)
  325. {
  326. $this->$k = intval($userId);
  327. }
  328. // Delete the user.
  329. $query = $this->_db->getQuery(true);
  330. $query->delete();
  331. $query->from($this->_db->quoteName($this->_tbl));
  332. $query->where($this->_db->quoteName($this->_tbl_key) . ' = ' . (int) $this->$k);
  333. $this->_db->setQuery($query);
  334. $this->_db->query();
  335. // Check for a database error.
  336. if ($this->_db->getErrorNum())
  337. {
  338. $this->setError($this->_db->getErrorMsg());
  339. return false;
  340. }
  341. // Delete the user group maps.
  342. $query->clear();
  343. $query->delete();
  344. $query->from($this->_db->quoteName('#__user_usergroup_map'));
  345. $query->where($this->_db->quoteName('user_id') . ' = ' . (int) $this->$k);
  346. $this->_db->setQuery($query);
  347. $this->_db->query();
  348. // Check for a database error.
  349. if ($this->_db->getErrorNum())
  350. {
  351. $this->setError($this->_db->getErrorMsg());
  352. return false;
  353. }
  354. /*
  355. * Clean Up Related Data.
  356. */
  357. $query->clear();
  358. $query->delete();
  359. $query->from($this->_db->quoteName('#__messages_cfg'));
  360. $query->where($this->_db->quoteName('user_id') . ' = ' . (int) $this->$k);
  361. $this->_db->setQuery($query);
  362. $this->_db->query();
  363. // Check for a database error.
  364. if ($this->_db->getErrorNum())
  365. {
  366. $this->setError($this->_db->getErrorMsg());
  367. return false;
  368. }
  369. $query->clear();
  370. $query->delete();
  371. $query->from($this->_db->quoteName('#__messages'));
  372. $query->where($this->_db->quoteName('user_id_to') . ' = ' . (int) $this->$k);
  373. $this->_db->setQuery($query);
  374. $this->_db->query();
  375. // Check for a database error.
  376. if ($this->_db->getErrorNum())
  377. {
  378. $this->setError($this->_db->getErrorMsg());
  379. return false;
  380. }
  381. return true;
  382. }
  383. /**
  384. * Updates last visit time of user
  385. *
  386. * @param integer $timeStamp The timestamp, defaults to 'now'.
  387. * @param integer $userId The user id (optional).
  388. *
  389. * @return boolean False if an error occurs
  390. *
  391. * @since 11.1
  392. */
  393. public function setLastVisit($timeStamp = null, $userId = null)
  394. {
  395. // Check for User ID
  396. if (is_null($userId))
  397. {
  398. if (isset($this))
  399. {
  400. $userId = $this->id;
  401. }
  402. else
  403. {
  404. // do not translate
  405. jexit(JText::_('JLIB_DATABASE_ERROR_SETLASTVISIT'));
  406. }
  407. }
  408. // If no timestamp value is passed to function, than current time is used.
  409. $date = JFactory::getDate($timeStamp);
  410. // Update the database row for the user.
  411. $db = $this->_db;
  412. $query = $db->getQuery(true);
  413. $query->update($db->quoteName($this->_tbl));
  414. $query->set($db->quoteName('lastvisitDate') . '=' . $db->quote($date->toSql()));
  415. $query->where($db->quoteName('id') . '=' . (int) $userId);
  416. $db->setQuery($query);
  417. $db->query();
  418. // Check for a database error.
  419. if ($db->getErrorNum())
  420. {
  421. $this->setError($db->getErrorMsg());
  422. return false;
  423. }
  424. return true;
  425. }
  426. }