PageRenderTime 33ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/concrete/core/models/user.php

https://bitbucket.org/selfeky/xclusivescardwebsite
PHP | 559 lines | 441 code | 67 blank | 51 comment | 97 complexity | 639b406b6cac9ea51f1b463115e5591a MD5 | raw file
  1. <?php defined('C5_EXECUTE') or die("Access Denied.");
  2. /**
  3. * @package Users
  4. * @author Andrew Embler <andrew@concrete5.org>
  5. * @copyright Copyright (c) 2003-2008 Concrete5. (http://www.concrete5.org)
  6. * @license http://www.concrete5.org/license/ MIT License
  7. *
  8. */
  9. /**
  10. * The user object deals primarily with logging users in and session-related activities.
  11. *
  12. * @package Users
  13. * @category Concrete
  14. * @copyright Copyright (c) 2003-2008 Concrete5. (http://www.concrete5.org)
  15. * @license http://www.concrete5.org/license/ MIT License
  16. *
  17. */
  18. class Concrete5_Model_User extends Object {
  19. public $uID = '';
  20. public $uName = '';
  21. public $uGroups = array();
  22. public $superUser = false;
  23. public $uTimezone = NULL;
  24. protected $uDefaultLanguage = null;
  25. // an associative array of all access entity objects that are associated with this user.
  26. protected $accessEntities = array();
  27. /**
  28. * @param int $uID
  29. * @param boolean $login
  30. * @return User
  31. */
  32. public static function getByUserID($uID, $login = false, $cacheItemsOnLogin = true) {
  33. $db = Loader::db();
  34. $v = array($uID);
  35. $q = "SELECT uID, uName, uIsActive, uLastOnline, uTimezone, uDefaultLanguage FROM Users WHERE uID = ?";
  36. $r = $db->query($q, $v);
  37. if ($r) {
  38. $row = $r->fetchRow();
  39. $nu = new User();
  40. $nu->uID = $row['uID'];
  41. $nu->uName = $row['uName'];
  42. $nu->uIsActive = $row['uIsActive'];
  43. $nu->uDefaultLanguage = $row['uDefaultLanguage'];
  44. $nu->uLastLogin = $row['uLastLogin'];
  45. $nu->uTimezone = $row['uTimezone'];
  46. $nu->uGroups = $nu->_getUserGroups(true);
  47. $nu->superUser = ($nu->getUserID() == USER_SUPER_ID);
  48. if ($login) {
  49. User::regenerateSession();
  50. $_SESSION['uID'] = $row['uID'];
  51. $_SESSION['uName'] = $row['uName'];
  52. $_SESSION['uBlockTypesSet'] = false;
  53. $_SESSION['uGroups'] = $nu->uGroups;
  54. $_SESSION['uLastOnline'] = $row['uLastOnline'];
  55. $_SESSION['uTimezone'] = $row['uTimezone'];
  56. $_SESSION['uDefaultLanguage'] = $row['uDefaultLanguage'];
  57. if ($cacheItemsOnLogin) {
  58. Loader::helper('concrete/interface')->cacheInterfaceItems();
  59. }
  60. $nu->recordLogin();
  61. }
  62. }
  63. return $nu;
  64. }
  65. protected static function regenerateSession() {
  66. unset($_SESSION['dashboardMenus']);
  67. unset($_SESSION['ccmQuickNavRecentPages']);
  68. unset($_SESSION['accessEntities']);
  69. @session_regenerate_id(true);
  70. }
  71. /**
  72. * @param int $uID
  73. * @return User
  74. */
  75. public function loginByUserID($uID) {
  76. return User::getByUserID($uID, true);
  77. }
  78. public static function isLoggedIn() {
  79. return $_SESSION['uID'] > 0 && $_SESSION['uName'] != '';
  80. }
  81. public function checkLogin() {
  82. $aeu = Config::get('ACCESS_ENTITY_UPDATED');
  83. if ($aeu && $aeu > $_SESSION['accessEntitiesUpdated']) {
  84. User::refreshUserGroups();
  85. }
  86. if ($_SESSION['uID'] > 0) {
  87. $db = Loader::db();
  88. $row = $db->GetRow("select uID, uIsActive from Users where uID = ? and uName = ?", array($_SESSION['uID'], $_SESSION['uName']));
  89. $checkUID = $row['uID'];
  90. if ($checkUID == $_SESSION['uID']) {
  91. if (!$row['uIsActive']) {
  92. return false;
  93. }
  94. $_SESSION['uOnlineCheck'] = time();
  95. if (($_SESSION['uOnlineCheck'] - $_SESSION['uLastOnline']) > (ONLINE_NOW_TIMEOUT / 2)) {
  96. $db = Loader::db();
  97. $db->query("update Users set uLastOnline = {$_SESSION['uOnlineCheck']} where uID = {$this->uID}");
  98. $_SESSION['uLastOnline'] = $_SESSION['uOnlineCheck'];
  99. }
  100. return true;
  101. } else {
  102. return false;
  103. }
  104. }
  105. }
  106. public function __construct() {
  107. $args = func_get_args();
  108. if (isset($args[1])) {
  109. // first, we check to see if the username and password match the admin username and password
  110. // $username = uName normally, but if not it's email address
  111. $username = $args[0];
  112. $password = $args[1];
  113. if (!$args[2]) {
  114. $_SESSION['uGroups'] = false;
  115. }
  116. $password = User::encryptPassword($password, PASSWORD_SALT);
  117. $v = array($username, $password);
  118. if (defined('USER_REGISTRATION_WITH_EMAIL_ADDRESS') && USER_REGISTRATION_WITH_EMAIL_ADDRESS == true) {
  119. $q = "select uID, uName, uIsActive, uIsValidated, uTimezone, uDefaultLanguage from Users where uEmail = ? and uPassword = ?";
  120. } else {
  121. $q = "select uID, uName, uIsActive, uIsValidated, uTimezone, uDefaultLanguage from Users where uName = ? and uPassword = ?";
  122. }
  123. $db = Loader::db();
  124. $r = $db->query($q, $v);
  125. if ($r) {
  126. $row = $r->fetchRow();
  127. if ($row['uID'] && $row['uIsValidated'] === '0' && defined('USER_VALIDATE_EMAIL_REQUIRED') && USER_VALIDATE_EMAIL_REQUIRED == TRUE) {
  128. $this->loadError(USER_NON_VALIDATED);
  129. } else if ($row['uID'] && $row['uIsActive']) {
  130. $this->uID = $row['uID'];
  131. $this->uName = $row['uName'];
  132. $this->uIsActive = $row['uIsActive'];
  133. $this->uTimezone = $row['uTimezone'];
  134. $this->uDefaultLanguage = $row['uDefaultLanguage'];
  135. $this->uGroups = $this->_getUserGroups($args[2]);
  136. if ($row['uID'] == USER_SUPER_ID) {
  137. $this->superUser = true;
  138. } else {
  139. $this->superUser = false;
  140. }
  141. $this->recordLogin();
  142. if (!$args[2]) {
  143. User::regenerateSession();
  144. $_SESSION['uID'] = $row['uID'];
  145. $_SESSION['uName'] = $row['uName'];
  146. $_SESSION['superUser'] = $this->superUser;
  147. $_SESSION['uBlockTypesSet'] = false;
  148. $_SESSION['uGroups'] = $this->uGroups;
  149. $_SESSION['uTimezone'] = $this->uTimezone;
  150. $_SESSION['uDefaultLanguage'] = $this->uDefaultLanguage;
  151. Loader::helper('concrete/interface')->cacheInterfaceItems();
  152. }
  153. } else if ($row['uID'] && !$row['uIsActive']) {
  154. $this->loadError(USER_INACTIVE);
  155. } else {
  156. $this->loadError(USER_INVALID);
  157. }
  158. $r->free();
  159. } else {
  160. $this->loadError(USER_INVALID);
  161. }
  162. } else {
  163. $req = Request::get();
  164. if ($req->hasCustomRequestUser()) {
  165. $this->uID = null;
  166. $this->uName = null;
  167. $this->superUser = false;
  168. $this->uDefaultLanguage = null;
  169. $this->uTimezone = null;
  170. $ux = $req->getCustomRequestUser();
  171. if ($ux) {
  172. $this->uID = $ux->getUserID();
  173. $this->uName = $ux->getUserName();
  174. $this->superUser = $ux->getUserID() == USER_SUPER_ID;
  175. if ($ux->getUserDefaultLanguage()) {
  176. $this->uDefaultLanguage = $ux->getUserDefaultLanguage();
  177. }
  178. $this->uTimezone = $ux->getUserTimezone();
  179. }
  180. } else if (isset($_SESSION['uID'])) {
  181. $this->uID = $_SESSION['uID'];
  182. $this->uName = $_SESSION['uName'];
  183. $this->uTimezone = $_SESSION['uTimezone'];
  184. if (isset($_SESSION['uDefaultLanguage'])) {
  185. $this->uDefaultLanguage = $_SESSION['uDefaultLanguage'];
  186. }
  187. $this->superUser = ($_SESSION['uID'] == USER_SUPER_ID) ? true : false;
  188. } else {
  189. $this->uID = null;
  190. $this->uName = null;
  191. $this->superUser = false;
  192. $this->uDefaultLanguage = null;
  193. $this->uTimezone = null;
  194. }
  195. $this->uGroups = $this->_getUserGroups();
  196. if (!isset($args[2]) && !$req->hasCustomRequestUser()) {
  197. $_SESSION['uGroups'] = $this->uGroups;
  198. }
  199. }
  200. return $this;
  201. }
  202. function recordLogin() {
  203. $db = Loader::db();
  204. $uLastLogin = $db->getOne("select uLastLogin from Users where uID = ?", array($this->uID));
  205. $db->query("update Users set uLastIP = ?, uLastLogin = ?, uPreviousLogin = ?, uNumLogins = uNumLogins + 1 where uID = ?", array(ip2long(Loader::helper('validation/ip')->getRequestIP()), time(), $uLastLogin, $this->uID));
  206. }
  207. function recordView($c) {
  208. $db = Loader::db();
  209. $uID = ($this->uID > 0) ? $this->uID : 0;
  210. $cID = $c->getCollectionID();
  211. $v = array($cID, $uID);
  212. $db->query("insert into PageStatistics (cID, uID, date) values (?, ?, NOW())", $v);
  213. }
  214. public function encryptPassword($uPassword, $salt = PASSWORD_SALT) {
  215. return md5($uPassword . ':' . $salt);
  216. }
  217. function isActive() {
  218. return $this->uIsActive;
  219. }
  220. function isSuperUser() {
  221. return $this->superUser;
  222. }
  223. function getLastOnline() {
  224. return $this->uLastOnline;
  225. }
  226. function getUserName() {
  227. return $this->uName;
  228. }
  229. function isRegistered() {
  230. return $this->getUserID() > 0;
  231. }
  232. function getUserID() {
  233. return $this->uID;
  234. }
  235. function getUserTimezone() {
  236. return $this->uTimezone;
  237. }
  238. function logout() {
  239. // First, we check to see if we have any collection in edit mode
  240. $this->unloadCollectionEdit();
  241. @session_unset();
  242. @session_destroy();
  243. Events::fire('on_user_logout');
  244. if ($_COOKIE['ccmUserHash']) {
  245. setcookie("ccmUserHash", "", 315532800, DIR_REL . '/');
  246. }
  247. }
  248. function checkUserForeverCookie() {
  249. if ($_COOKIE['ccmUserHash']) {
  250. $hashVal = explode(':', $_COOKIE['ccmUserHash']);
  251. $_uID = $hashVal[0];
  252. $uHash = $hashVal[1];
  253. if ($uHash == md5(PASSWORD_SALT . $_uID)) {
  254. User::loginByUserID($_uID);
  255. }
  256. }
  257. }
  258. function setUserForeverCookie() {
  259. $hashVal = md5(PASSWORD_SALT . $this->getUserID());
  260. setcookie("ccmUserHash", $this->getUserID() . ':' . $hashVal, time() + 1209600, DIR_REL . '/');
  261. }
  262. function getUserGroups() {
  263. $ugtmp = array();
  264. // we have to do this because we don't have a localized version of the guest and registered group names
  265. // when we called _getUserGroups() below. So we have to push out the defining of the guest and registered
  266. // names til runtime
  267. foreach($this->uGroups as $key => $value) {
  268. $ugtmp[$key] = $value;
  269. if ($key == GUEST_GROUP_ID) {
  270. $ugtmp[$key] = GUEST_GROUP_NAME;
  271. }
  272. if ($key == REGISTERED_GROUP_ID) {
  273. $ugtmp[$key] = REGISTERED_GROUP_NAME;
  274. }
  275. }
  276. return $ugtmp;
  277. }
  278. /**
  279. * Sets a default language for a user record
  280. */
  281. public function setUserDefaultLanguage($lang) {
  282. $db = Loader::db();
  283. $this->uDefaultLanguage = $lang;
  284. $_SESSION['uDefaultLanguage'] = $lang;
  285. $db->Execute('update Users set uDefaultLanguage = ? where uID = ?', array($lang, $this->getUserID()));
  286. }
  287. /**
  288. * Gets the default language for the logged-in user
  289. */
  290. public function getUserDefaultLanguage() {
  291. return $this->uDefaultLanguage;
  292. }
  293. function refreshUserGroups() {
  294. unset($_SESSION['uGroups']);
  295. unset($_SESSION['accessEntities']);
  296. $ug = $this->_getUserGroups();
  297. $_SESSION['uGroups'] = $ug;
  298. $this->uGroups = $ug;
  299. }
  300. public function getUserAccessEntityObjects() {
  301. $req = Request::get();
  302. if ($req->hasCustomRequestUser()) {
  303. // we bypass session-saving performance
  304. // and we don't save them in session.
  305. return PermissionAccessEntity::getForUser($this);
  306. }
  307. if (isset($_SESSION['accessEntities'])) {
  308. $entities = $_SESSION['accessEntities'];
  309. } else {
  310. $entities = PermissionAccessEntity::getForUser($this);
  311. $_SESSION['accessEntities'] = $entities;
  312. $_SESSION['accessEntitiesUpdated'] = time();
  313. }
  314. return $entities;
  315. }
  316. function _getUserGroups($disableLogin = false) {
  317. $req = Request::get();
  318. if ((!empty($_SESSION['uGroups'])) && (!$disableLogin) && (!$req->hasCustomRequestUser())) {
  319. $ug = $_SESSION['uGroups'];
  320. } else {
  321. $db = Loader::db();
  322. if ($this->uID) {
  323. $ug[REGISTERED_GROUP_ID] = REGISTERED_GROUP_ID;
  324. //$_SESSION['uGroups'][REGISTERED_GROUP_ID] = REGISTERED_GROUP_NAME;
  325. $uID = $this->uID;
  326. $q = "select Groups.gID, Groups.gName, Groups.gUserExpirationIsEnabled, Groups.gUserExpirationSetDateTime, Groups.gUserExpirationInterval, Groups.gUserExpirationAction, Groups.gUserExpirationMethod, UserGroups.ugEntered from UserGroups inner join Groups on (UserGroups.gID = Groups.gID) where UserGroups.uID = '$uID'";
  327. $r = $db->query($q);
  328. if ($r) {
  329. while ($row = $r->fetchRow()) {
  330. $expire = false;
  331. if ($row['gUserExpirationIsEnabled']) {
  332. switch($row['gUserExpirationMethod']) {
  333. case 'SET_TIME':
  334. if (time() > strtotime($row['gUserExpirationSetDateTime'])) {
  335. $expire = true;
  336. }
  337. break;
  338. case 'INTERVAL':
  339. if (time() > strtotime($row['ugEntered']) + ($row['gUserExpirationInterval'] * 60)) {
  340. $expire = true;
  341. }
  342. break;
  343. }
  344. }
  345. if ($expire) {
  346. if ($row['gUserExpirationAction'] == 'REMOVE' || $row['gUserExpirationAction'] == 'REMOVE_DEACTIVATE') {
  347. $db->Execute('delete from UserGroups where uID = ? and gID = ?', array($uID, $row['gID']));
  348. }
  349. if ($row['gUserExpirationAction'] == 'DEACTIVATE' || $row['gUserExpirationAction'] == 'REMOVE_DEACTIVATE') {
  350. $db->Execute('update Users set uIsActive = 0 where uID = ?', array($uID));
  351. }
  352. } else {
  353. $ug[$row['gID']] = $row['gName'];
  354. }
  355. }
  356. $r->free();
  357. }
  358. }
  359. // now we populate also with guest information, since presumably logged-in users
  360. // see the same stuff as guest
  361. $ug[GUEST_GROUP_ID] = GUEST_GROUP_ID;
  362. }
  363. return $ug;
  364. }
  365. function enterGroup($g, $joinType = "") {
  366. // takes a group object, and, if the user is not already in the group, it puts them into it
  367. $dt = Loader::helper('date');
  368. if (is_object($g)) {
  369. $gID = $g->getGroupID();
  370. $db = Loader::db();
  371. $db->Replace('UserGroups', array(
  372. 'uID' => $this->getUserID(),
  373. 'gID' => $g->getGroupID(),
  374. 'type' => $joinType,
  375. 'ugEntered' => $dt->getSystemDateTime()
  376. ),
  377. array('uID', 'gID'), true);
  378. Events::fire('on_user_enter_group', $this, $g);
  379. }
  380. }
  381. public function updateGroupMemberType($g, $joinType) {
  382. if ($g instanceof Group) {
  383. $db = Loader::db();
  384. $dt = Loader::helper('date');
  385. $db->Execute('update UserGroups set type = ?, ugEntered = ? where uID = ? and gID = ?', array($joinType, $dt->getSystemDateTime(), $this->uID, $g->getGroupID()));
  386. }
  387. }
  388. function exitGroup($g) {
  389. // takes a group object, and, if the user is in the group, they exit the group
  390. if (is_object($g)) {
  391. $gID = $g->getGroupID();
  392. $db = Loader::db();
  393. $ret = Events::fire('on_user_exit_group', $this, $g);
  394. $q = "delete from UserGroups where uID = '{$this->uID}' and gID = '{$gID}'";
  395. $r = $db->query($q);
  396. }
  397. }
  398. function getGroupMemberType($g) {
  399. $db = Loader::db();
  400. $r = $db->GetOne("select type from UserGroups where uID = ? and gID = ?", array($this->getUserID(), $g->getGroupID()));
  401. return $r;
  402. }
  403. function inGroup($g, $joinType = null) {
  404. $db = Loader::db();
  405. if (isset($joinType) && is_object($g)) {
  406. $v = array($this->uID, $g->getGroupID(), $joinType);
  407. $cnt = $db->GetOne("select gID from UserGroups where uID = ? and gID = ? and type = ?", $v);
  408. } else if (is_object($g)) {
  409. $v = array($this->uID, $g->getGroupID());
  410. $cnt = $db->GetOne("select gID from UserGroups where uID = ? and gID = ?", $v);
  411. }
  412. return $cnt > 0;
  413. }
  414. function loadMasterCollectionEdit($mcID, $ocID) {
  415. // basically, this function loads the master collection ID you're working on into session
  416. // so you can work on it without the system failing because you're editing a template
  417. $_SESSION['mcEditID'] = $mcID;
  418. $_SESSION['ocID'] = $ocID;
  419. }
  420. function loadCollectionEdit(&$c) {
  421. $c->refreshCache();
  422. // can only load one page into edit mode at a time.
  423. if ($c->isCheckedOut()) {
  424. return false;
  425. }
  426. $db = Loader::db();
  427. $cID = $c->getCollectionID();
  428. // first, we check to see if we have a collection in edit mode. If we do, we relinquish it
  429. $this->unloadCollectionEdit(false);
  430. $q = "select cIsCheckedOut, cCheckedOutDatetime from Pages where cID = '{$cID}'";
  431. $r = $db->query($q);
  432. if ($r) {
  433. $row = $r->fetchRow();
  434. if (!$row['cIsCheckedOut']) {
  435. $_SESSION['editCID'] = $cID;
  436. $uID = $this->getUserID();
  437. $dh = Loader::helper('date');
  438. $datetime = $dh->getSystemDateTime();
  439. $q2 = "update Pages set cIsCheckedOut = 1, cCheckedOutUID = '{$uID}', cCheckedOutDatetime = '{$datetime}', cCheckedOutDatetimeLastEdit = '{$datetime}' where cID = '{$cID}'";
  440. $r2 = $db->query($q2);
  441. $c->cIsCheckedOut = 1;
  442. $c->cCheckedOutUID = $uID;
  443. $c->cCheckedOutDatetime = $datetime;
  444. $c->cCheckedOutDatetimeLastEdit = $datetime;
  445. }
  446. }
  447. }
  448. function unloadCollectionEdit($removeCache = true) {
  449. // first we remove the cached versions of all of these pages
  450. $db = Loader::db();
  451. if ($this->getUserID() > 0) {
  452. $col = $db->GetCol("select cID from Pages where cCheckedOutUID = " . $this->getUserID());
  453. foreach($col as $cID) {
  454. $p = Page::getByID($cID);
  455. if ($removeCache) {
  456. $p->refreshCache();
  457. }
  458. }
  459. $q = "update Pages set cIsCheckedOut = 0, cCheckedOutUID = null, cCheckedOutDatetime = null, cCheckedOutDatetimeLastEdit = null where cCheckedOutUID = " . $this->getUserID();
  460. $r = $db->query($q);
  461. }
  462. }
  463. public function config($cfKey) {
  464. if ($this->isRegistered()) {
  465. $db = Loader::db();
  466. $val = $db->GetOne("select cfValue from Config where uID = ? and cfKey = ?", array($this->getUserID(), $cfKey));
  467. return $val;
  468. }
  469. }
  470. public function saveConfig($cfKey, $cfValue) {
  471. $db = Loader::db();
  472. $db->Replace('Config', array('cfKey' => $cfKey, 'cfValue' => $cfValue, 'uID' => $this->getUserID()), array('cfKey', 'uID'), true);
  473. }
  474. function refreshCollectionEdit(&$c) {
  475. if ($this->isLoggedIn() && $c->getCollectionCheckedOutUserID() == $this->getUserID()) {
  476. $db = Loader::db();
  477. $cID = $c->getCollectionID();
  478. $dh = Loader::helper('date');
  479. $datetime = $dh->getSystemDateTime();
  480. $q = "update Pages set cCheckedOutDatetimeLastEdit = '{$datetime}' where cID = '{$cID}'";
  481. $r = $db->query($q);
  482. $c->cCheckedOutDatetimeLastEdit = $datetime;
  483. }
  484. }
  485. function forceCollectionCheckInAll() {
  486. // This function forces checkin to take place
  487. $db = Loader::db();
  488. $q = "update Pages set cIsCheckedOut = 0, cCheckedOutUID = null, cCheckedOutDatetime = null, cCheckedOutDatetimeLastEdit = null";
  489. $r = $db->query($q);
  490. return $r;
  491. }
  492. }