PageRenderTime 41ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 0ms

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

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