PageRenderTime 50ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/application/models/users/User.class.php

https://github.com/fb83/Project-Pier
PHP | 1280 lines | 602 code | 128 blank | 550 comment | 111 complexity | 47b408125fb3ea51dca341855b4085de MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0, AGPL-3.0, LGPL-2.1, GPL-3.0
  1. <?php
  2. function filenamecmp($a, $b) { return strcmp($a->getFileName(), $b->getFileName()); }
  3. /**
  4. * User class
  5. *
  6. * @http://www.projectpier.org/
  7. */
  8. class User extends BaseUser {
  9. /**
  10. * LDAP secure connection values
  11. */
  12. const LDAP_SECURE_CONNECTION_NO = 'no';
  13. const LDAP_SECURE_CONNECTION_TLS = 'tls';
  14. /**
  15. * Cached project permission values. Two level array. First level are projects (project ID) and
  16. * second are permissions associated with permission name
  17. *
  18. * @var array
  19. */
  20. private $project_permissions_cache = array();
  21. /**
  22. * Associative array. Key is project ID and value is true if user has access to that project
  23. *
  24. * @var array
  25. */
  26. private $is_project_user_cache = array();
  27. /**
  28. * True if user is member of owner company. This value is read on first request and cached
  29. *
  30. * @var boolean
  31. */
  32. private $is_member_of_owner_company = null;
  33. /**
  34. * Cached is_administrator value. First time value is requested it will be checked and cached.
  35. * After that every request will return cached value
  36. *
  37. * @var boolean
  38. */
  39. private $is_administrator = null;
  40. /**
  41. * Cached is_account_owner value. Value is retrieved on first requests
  42. *
  43. * @var boolean
  44. */
  45. private $is_account_owner = null;
  46. /**
  47. * Cached value of all projects
  48. *
  49. * @var array
  50. */
  51. private $projects;
  52. /**
  53. * Cached value of active projects
  54. *
  55. * @var array
  56. */
  57. private $active_projects;
  58. /**
  59. * Cached value of active main projects
  60. *
  61. * @var array
  62. */
  63. private $active_main_projects;
  64. /**
  65. * Cached value of finished projects
  66. *
  67. * @var array
  68. */
  69. private $finished_projects;
  70. /**
  71. * Array of all active milestons
  72. *
  73. * @var array
  74. */
  75. private $all_active_milestons;
  76. /**
  77. * Cached late milestones
  78. *
  79. * @var array
  80. */
  81. private $late_milestones;
  82. /**
  83. * Cached today milestones
  84. *
  85. * @var array
  86. */
  87. private $today_milestones;
  88. /**
  89. * Cached array of new objects
  90. *
  91. * @var array
  92. */
  93. private $whats_new;
  94. /**
  95. * canSeeCompany() method will cache its result here (company_id => visible as bool)
  96. *
  97. * @var array
  98. */
  99. private $visible_companies = array();
  100. /**
  101. * Cached array of new files
  102. *
  103. * @var array
  104. */
  105. private $files;
  106. /**
  107. * Cached array of new files
  108. *
  109. * @var array
  110. */
  111. private $importantfiles;
  112. /**
  113. * Contact reference. This value is read on first request and cached
  114. *
  115. * @var boolean
  116. */
  117. private $contact = null;
  118. /**
  119. * Construct user object
  120. *
  121. * @param void
  122. * @return User
  123. */
  124. function __construct() {
  125. parent::__construct();
  126. $this->addProtectedAttribute('password', 'salt', 'session_lifetime', 'token', 'twister', 'last_login', 'last_visit', 'last_activity');
  127. $this->active_projects = array();
  128. } // __construct
  129. /**
  130. * Check if this user is member of specific company
  131. *
  132. * @access public
  133. * @param Company $company
  134. * @return boolean
  135. */
  136. function isMemberOf(Company $company) {
  137. trace(__FILE__,'isMemberOf()');
  138. return $this->getContact()->getCompanyId() == $company->getId();
  139. } // isMemberOf
  140. /**
  141. * Usualy we check if user is member of owner company so this is the shortcut method
  142. *
  143. * @param void
  144. * @return boolean
  145. */
  146. function isMemberOfOwnerCompany() {
  147. trace(__FILE__,'isMemberOfOwnerCompany()');
  148. if (is_null($this->is_member_of_owner_company)) {
  149. $this->is_member_of_owner_company = $this->isMemberOf(owner_company());
  150. }
  151. return $this->is_member_of_owner_company;
  152. } // isMemberOfOwnerCompany
  153. /**
  154. * Check if this user is part of specific project
  155. *
  156. * @param Project $project
  157. * @return boolean
  158. */
  159. function isProjectUser(Project $project) {
  160. if (is_null($project)) {
  161. return false;
  162. }
  163. if ($project->getCreatedById() == $this->getId()) {
  164. return true;
  165. }
  166. if (!isset($this->is_project_user_cache[$project->getId()])) {
  167. $project_user = ProjectUsers::findById(array(
  168. 'project_id' => $project->getId(),
  169. 'user_id' => $this->getId())
  170. ); // findById
  171. $this->is_project_user_cache[$project->getId()] = $project_user instanceof ProjectUser;
  172. } // if
  173. return $this->is_project_user_cache[$project->getId()];
  174. } // isProjectUser
  175. /**
  176. * Set the project specific note for this user
  177. *
  178. * @param Project $project
  179. * @param string $data
  180. * @return boolean
  181. */
  182. function setProjectNote(Project $project, $data) {
  183. if (is_null($project)) {
  184. return false;
  185. }
  186. if (!$this->isProjectUser($project)) {
  187. return false;
  188. }
  189. $project_user = ProjectUsers::findById(array(
  190. 'project_id' => $project->getId(),
  191. 'user_id' => $this->getId())
  192. ); // findById
  193. if ($project_user instanceof ProjectUser) {
  194. $project_user->setNote($data);
  195. return $project_user->save();
  196. } // if
  197. return false;
  198. } // setProjectNote
  199. /**
  200. * Set the project specific note for this user
  201. *
  202. * @param Project $project
  203. * @param string $data
  204. * @return boolean
  205. */
  206. function getProjectNote(Project $project) {
  207. if (is_null($project)) {
  208. return false;
  209. }
  210. if (!$this->isProjectUser($project)) {
  211. return false;
  212. }
  213. $project_user = ProjectUsers::findById(array(
  214. 'project_id' => $project->getId(),
  215. 'user_id' => $this->getId())
  216. ); // findById
  217. if ($project_user instanceof ProjectUser) {
  218. return $project_user->getNote();
  219. } // if
  220. return false;
  221. } // getProjectNote
  222. /**
  223. * Set the project specific note for this user
  224. *
  225. * @param Project $project
  226. * @param string $data
  227. * @return boolean
  228. */
  229. function setProjectNoteView(Project $project, $data) {
  230. if (is_null($project)) {
  231. return false;
  232. }
  233. if (!$this->isProjectUser($project)) {
  234. return false;
  235. }
  236. $project_user = ProjectUsers::findById(array(
  237. 'project_id' => $project->getId(),
  238. 'user_id' => $this->getId())
  239. ); // findById
  240. if ($project_user instanceof ProjectUser) {
  241. $project_user->setNoteView($data);
  242. return $project_user->save();
  243. } // if
  244. return false;
  245. } // setProjectNote
  246. /**
  247. * Check if this of specific company website. If must be member of that company and is_admin flag set to true
  248. *
  249. * @param void
  250. * @return boolean
  251. */
  252. function isAdministrator() {
  253. trace(__FILE__,'isAdministrator():begin');
  254. if (is_null($this->is_administrator)) {
  255. trace(__FILE__,'isAdministrator():init is_administrator');
  256. //$this->is_administrator = $this->isAccountOwner() || ($this->isMemberOfOwnerCompany() && $this->getIsAdmin());
  257. $this->is_administrator = ($this->isMemberOfOwnerCompany() && $this->getIsAdmin());
  258. } // if
  259. trace(__FILE__,'isAdministrator():end');
  260. return $this->is_administrator;
  261. } // isAdministrator
  262. /**
  263. * Account owner is user account that was created when company website is created
  264. *
  265. * @param void
  266. * @return boolean
  267. */
  268. function isAccountOwner() {
  269. //if (is_null($this->is_account_owner)) {
  270. // $this->is_account_owner = $this->isMemberOfOwnerCompany() && (owner_company()->getCreatedById() == $this->getId());
  271. //} // if
  272. //return $this->is_account_owner;
  273. return false;
  274. } // isAccountOwner
  275. /**
  276. * Return project permission for specific user if he is on project. In case of any error $default is returned
  277. *
  278. * @access public
  279. * @param Project $project
  280. * @param string $permission Permission name
  281. * @param boolean $default Default value
  282. * @return boolean
  283. */
  284. function getProjectPermission(Project $project, $permission, $default = false) {
  285. trace(__FILE__,"getProjectPermission($permission, $default)");
  286. if (is_null($project)) return false;
  287. static $valid_permissions;
  288. if (!isset($valid_permissions)) {
  289. trace(__FILE__,"getProjectPermission($permission, $default):getPermissionsText()");
  290. $valid_permissions = array_keys(permission_manager()->getPermissionsText());
  291. } // if
  292. if (!in_array($permission, $valid_permissions)) {
  293. return $default;
  294. } // if
  295. trace(__FILE__,"getProjectPermission($permission, $default):findById project={$project->getId()}");
  296. $project_user = ProjectUsers::findById(array(
  297. 'project_id' => $project->getId(),
  298. 'user_id' => $this->getId()
  299. )); // findById
  300. if (!($project_user instanceof ProjectUser)) {
  301. return $default;
  302. } // if
  303. trace(__FILE__,"getProjectPermission($permission, $default):getPermissions()");
  304. $value = in_array($permission,$project_user->getPermissions()) ? true : false;
  305. return $value;
  306. } // getProjectPermission
  307. /**
  308. * Return if user can manage projects
  309. *
  310. * @access public
  311. * @return boolean
  312. */
  313. function canManageProjects() {
  314. trace(__FILE__,'canManageProjects()');
  315. $permission = PermissionManager::CAN_MANAGE_PROJECTS;
  316. $project_user = new ProjectUser();
  317. $project_user->setUserId($this->getId());
  318. $project_user->setProjectId(0);
  319. $value = in_array($permission,$project_user->getPermissions()) ? true : false;
  320. return $value;
  321. } // canManageProjects
  322. /***
  323. * Set a permission for this user
  324. *
  325. * @param string $permissionString Name of the permission. There are set of constants
  326. * in ProjectUser that hold permission names (PermissionManager::CAN_MANAGE_MESSAGES ...)
  327. * @param int $value 1 if the user should be granted the permission, any other value is a denial
  328. * @return boolean
  329. */
  330. function setPermission($permission_name, $value) {
  331. $permission_id = Permissions::getPermissionId($permission_name);
  332. if (!isset($permission_id) || !$permission_id) {
  333. return false;
  334. }
  335. // delete permission
  336. ProjectUserPermissions::delete( array(
  337. '`user_id` = ? AND `project_id` = ? AND `permission_id` = ?',
  338. $this->getId(),
  339. 0,
  340. $permission_id
  341. ));
  342. // add if $value == 1
  343. if ($value == 1) {
  344. $pup = new ProjectUserPermission();
  345. $pup->setProjectId(0);
  346. $pup->setUserId($this->getId());
  347. $pup->setPermissionId($permission_id);
  348. $pup->save();
  349. } // if
  350. } // setPermission
  351. /***
  352. * Set a permission for this user
  353. *
  354. * @param Project $project
  355. * @param string $permissionString Name of the permission. There are set of constants
  356. * in ProjectUser that hold permission names (PermissionManager::CAN_MANAGE_MESSAGES ...)
  357. * @param boolean $granted true=granted, false=denied
  358. * @return boolean
  359. */
  360. function setProjectPermission(Project $project, $permission_name, $granted) {
  361. trace(__FILE__, "setProjectPermission(project, $permission_name, $granted):begin");
  362. $permission_id = Permissions::getPermissionId($permission_name);
  363. if (!isset($permission_id) || !$permission_id) {
  364. return false;
  365. }
  366. if ($granted) {
  367. trace(__FILE__, "setProjectPermission(project, $permission_name, $granted):granted");
  368. $pup = new ProjectUserPermission();
  369. $pup->setProjectId($project->getId());
  370. $pup->setUserId($this->getId());
  371. $pup->setPermissionId($permission_id);
  372. $pup->save();
  373. } else {
  374. $pup = ProjectUserPermissions::findOne(array('conditions' => '`project_id` = '.$project->getId().' and `user_id` = '.$this->getId().' and `permission_id` = '.$permission_id));
  375. if (isset($pup) && ($pup instanceOf ProjectUserPermission)) {
  376. $pup->delete();
  377. } // if
  378. } // if
  379. } // setProjectPermission
  380. /***
  381. * Set a permission for this user
  382. *
  383. * @param Project $project
  384. * @param string $permission_group Name of the permission group
  385. * @param boolean $granted true=granted, false=denied
  386. * @return boolean
  387. */
  388. function setProjectPermissionsByGroup(Project $project, $permission_group, $granted) {
  389. trace(__FILE__, "setProjectPermissionsByGroup(project, $permission_name, $granted):begin");
  390. $permissions = PermissionManager::getPermissionsByGroup($permission_group);
  391. foreach($permissions as $permission_name) {
  392. $this->setProjectPermission($project, $permission_name, $granted);
  393. }
  394. } // setProjectPermission
  395. /**
  396. * This function will check if this user has all project permissions
  397. *
  398. * @param Project $project
  399. * @param boolean $use_cache
  400. * @return boolean
  401. */
  402. function hasAllProjectPermissions(Project $project, $use_cache = true) {
  403. $permissions = array_keys(PermissionManager::getPermissionsText());
  404. if (is_array($permissions)) {
  405. foreach ($permissions as $permission) {
  406. if (!$this->getProjectPermission($project, $permission)) {
  407. return false;
  408. }
  409. } // foreach
  410. } // if
  411. return true;
  412. } // hasAllProjectPermissions
  413. // ---------------------------------------------------
  414. // Retrieve
  415. // ---------------------------------------------------
  416. /**
  417. * Return owner company
  418. *
  419. * @access public
  420. * @param void
  421. * @return Company
  422. */
  423. function getCompany() {
  424. return $this->getContact()->getCompany();
  425. } // getCompany
  426. /**
  427. * Return owner company
  428. *
  429. * @access public
  430. * @param void
  431. * @return Company
  432. */
  433. function getCompanyId() {
  434. return $this->getContact()->getCompanyId();
  435. } // getCompany
  436. /**
  437. * Return display name for company of this user.
  438. *
  439. * @access public
  440. * @param void
  441. * @return string
  442. */
  443. function getCompanyDisplayName() {
  444. $company = self::getCompany();
  445. return is_null($company) ? '' : $company->getName();
  446. } // getDisplayName
  447. /**
  448. * Return associated contact
  449. *
  450. * @param void
  451. * @return Contact
  452. */
  453. function getContact() {
  454. if (!isset($this->contact)) {
  455. $contact = Contacts::findOne(array('conditions' => array('`user_id` = ? ', $this->getId())));
  456. if ($contact instanceof Contact) {
  457. $this->contact = $contact;
  458. } else {
  459. $this->contact = new Contact;
  460. $this->contact->setDisplayName(lang('missing contact'));
  461. $this->contact->setCompanyId(owner_company()->getId());
  462. }
  463. }
  464. return $this->contact;
  465. } // getContact
  466. /**
  467. * Return time zone
  468. *
  469. * @access public
  470. * @param void
  471. * @return Company
  472. */
  473. function getTimezone() {
  474. return $this->getContact()->getTimezone();
  475. } // getTimezone
  476. /**
  477. * Return all projects that this user is member of
  478. *
  479. * @access public
  480. * @param void
  481. * @return array
  482. */
  483. function getProjects() {
  484. if (is_null($this->projects)) {
  485. $this->projects = ProjectUsers::getProjectsByUser($this);
  486. } // if
  487. return $this->projects;
  488. } // getProjects
  489. /**
  490. * Return array of active main projects that this user have access
  491. *
  492. * @access public
  493. * @param void
  494. * @return array
  495. */
  496. function getActiveMainProjects($sort = 'name') {
  497. trace(__FILE__, "getActiveMainProjects($sort)");
  498. if (is_null($this->active_main_projects)) {
  499. trace(__FILE__, '- initialize cache: active_main_projects');
  500. $this->active_main_projects = array();
  501. } // if
  502. if (!isset($this->active_main_projects[$sort])) {
  503. $projects_table = Projects::instance()->getTableName(true);
  504. $empty_datetime = DB::escape(EMPTY_DATETIME);
  505. $this->active_main_projects[$sort] = ProjectUsers::getProjectsByUser($this, "$projects_table.`completed_on` = $empty_datetime AND $projects_table.`parent_id` = 0", $sort);
  506. } // if
  507. return $this->active_main_projects[$sort];
  508. } // getActiveMainProjects
  509. /**
  510. * Return array of active projects that this user have access
  511. *
  512. * @access public
  513. * @param void
  514. * @return array
  515. */
  516. function getActiveProjects($sort = 'name') {
  517. trace(__FILE__, 'getActiveProjects()');
  518. if (is_null($this->active_projects)) {
  519. trace(__FILE__, '- initialize cache: active_projects');
  520. $this->active_projects = array();
  521. } // if
  522. if (!isset($this->active_projects[$sort])) {
  523. $projects_table = Projects::instance()->getTableName(true);
  524. $empty_datetime = DB::escape(EMPTY_DATETIME);
  525. $this->active_projects[$sort] = ProjectUsers::getProjectsByUser($this, "$projects_table.`completed_on` = $empty_datetime", $sort);
  526. } // if
  527. return $this->active_projects[$sort];
  528. } // getActiveProjects
  529. /**
  530. * Return array of finished projects
  531. *
  532. * @access public
  533. * @param void
  534. * @return array
  535. */
  536. function getFinishedProjects() {
  537. if (is_null($this->finished_projects)) {
  538. $projects_table = Projects::instance()->getTableName(true);
  539. $this->finished_projects = ProjectUsers::getProjectsByUser($this, "$projects_table.`completed_on` > " . DB::escape(EMPTY_DATETIME));
  540. } // if
  541. return $this->finished_projects;
  542. } // getFinishedProjects
  543. /**
  544. * Return all active milestones assigned to this user
  545. *
  546. * @param void
  547. * @return array
  548. */
  549. function getActiveMilestones() {
  550. if (is_null($this->all_active_milestons)) {
  551. $this->all_active_milestons = ProjectMilestones::getActiveMilestonesByUser($this);
  552. } // if
  553. return $this->all_active_milestons;
  554. } // getActiveMilestones
  555. /**
  556. * Return late milestones that this user have access to
  557. *
  558. * @access public
  559. * @param void
  560. * @return array
  561. */
  562. function getLateMilestones() {
  563. if (is_null($this->late_milestones)) {
  564. $this->late_milestones = ProjectMilestones::getLateMilestonesByUser($this);
  565. } // if
  566. return $this->late_milestones;
  567. } // getLateMilestones
  568. /**
  569. * Return today milestones that this user have access to
  570. *
  571. * @access public
  572. * @param void
  573. * @return array
  574. */
  575. function getTodayMilestones() {
  576. if (is_null($this->today_milestones)) {
  577. $this->today_milestones = ProjectMilestones::getTodayMilestonesByUser($this);
  578. } // if
  579. return $this->today_milestones;
  580. } // getTodayMilestones
  581. /**
  582. * Return array of active projects that this user have access
  583. *
  584. * @access public
  585. * @param void
  586. * @return array
  587. */
  588. function getFiles($sort = 'name') {
  589. trace(__FILE__, 'getFiles()');
  590. if (is_null($this->files)) {
  591. trace(__FILE__, '- initialize cache: files');
  592. $this->files = array();
  593. } // if
  594. if (!isset($this->files[$sort])) {
  595. $files = array();
  596. $projects = $this->getActiveProjects();
  597. foreach($projects as $project) {
  598. $projectfiles = ProjectFiles::getAllFilesByProject($project);
  599. $i=0;
  600. while (isset($projectfiles[$i])){
  601. $files[] = $projectfiles[$i];
  602. unset($projectfiles[$i]);
  603. $i++;
  604. }
  605. }
  606. usort($files, "filenamecmp");
  607. $this->files[$sort] = $files;
  608. } // if
  609. return $this->files[$sort];
  610. } // getFiles
  611. /**
  612. * Return array of active projects that this user have access
  613. *
  614. * @access public
  615. * @param void
  616. * @return array
  617. */
  618. function getImportantFiles($sort = 'name') {
  619. trace(__FILE__, 'getImportantFiles()');
  620. if (is_null($this->importantfiles)) {
  621. trace(__FILE__, '- initialize cache: files');
  622. $this->importantfiles = array();
  623. } // if
  624. if (!isset($this->importantfiles[$sort])) {
  625. $files = array();
  626. $projects = $this->getActiveProjects();
  627. if (is_array($projects)) {
  628. foreach($projects as $project) {
  629. $projectfiles = ProjectFiles::getImportantProjectFiles($project);
  630. $i=0;
  631. while (isset($projectfiles[$i])){
  632. $files[] = $projectfiles[$i];
  633. unset($projectfiles[$i]);
  634. $i++;
  635. }
  636. }
  637. }
  638. usort($files, "filenamecmp");
  639. $this->importantfiles[$sort] = $files;
  640. } // if
  641. return $this->importantfiles[$sort];
  642. } // getImportantFiles
  643. /**
  644. * Return display name for this account. If there is no display name set username will be used
  645. *
  646. * @access public
  647. * @param void
  648. * @return string
  649. */
  650. function getDisplayName() {
  651. $display = $this->getContact()->getDisplayName();
  652. return trim($display) == '' ? $this->getUsername() : $display;
  653. } // getDisplayName
  654. // ---------------------------------------------------
  655. // Utils
  656. // ---------------------------------------------------
  657. /**
  658. * This function will generate new user password, set it and return it
  659. *
  660. * @param boolean $save Save object after the update
  661. * @return string
  662. */
  663. function resetPassword($save = true) {
  664. $new_password = substr(sha1(uniqid(rand(), true)), rand(0, 25), 13);
  665. $this->setPassword($new_password);
  666. if ($save) {
  667. $this->save();
  668. } // if
  669. return $new_password;
  670. } // resetPassword
  671. /**
  672. * Set password value
  673. *
  674. * @param string $value
  675. * @return boolean
  676. */
  677. function setPassword($value) {
  678. do {
  679. $salt = substr(sha1(uniqid(rand(), true)), rand(0, 25), 13);
  680. $token = sha1($salt . $value);
  681. } while (Users::tokenExists($token));
  682. $this->setToken($token);
  683. $this->setSalt($salt);
  684. $this->setTwister(StringTwister::getTwister());
  685. } // setPassword
  686. /**
  687. * Return twisted token
  688. *
  689. * @param void
  690. * @return string
  691. */
  692. function getTwistedToken() {
  693. return StringTwister::twistHash($this->getToken(), $this->getTwister());
  694. } // getTwistedToken
  695. /**
  696. * Check if $check_password is valid user password
  697. *
  698. * @param string $check_password
  699. * @return boolean
  700. */
  701. function isValidPassword($check_password) {
  702. if ($this->getUseLDAP()) {
  703. return $this->doLDAP($check_password);
  704. }
  705. return sha1($this->getSalt() . $check_password) == $this->getToken();
  706. } // isValidPassword
  707. /**
  708. * Check if $twisted_token is valid for this user account
  709. *
  710. * @param string $twisted_token
  711. * @return boolean
  712. */
  713. function isValidToken($twisted_token) {
  714. return StringTwister::untwistHash($twisted_token, $this->getTwister()) == $this->getToken();
  715. } // isValidToken
  716. /**
  717. * Authenticate using LDAP.
  718. *
  719. * @param string $pass
  720. * @param string config_option('ldap_domain')
  721. * @param string config_option('ldap_host')
  722. * @param string config_option('ldap_secure_connection')
  723. * @return boolean
  724. */
  725. function doLDAP($pass) {
  726. if (!function_exists('ldap_connect')) {
  727. return false;
  728. }
  729. $username = $this->getUsername();
  730. if (strlen(config_option('ldap_domain', '')) != 0) {
  731. //$username = $username . '@' . config_option('ldap_domain');
  732. $username = sprintf(config_option('ldap_domain'), $username);
  733. }
  734. $ldapconn = ldap_connect('ldap://' . config_option('ldap_host', ''));
  735. if (!$ldapconn) {
  736. return false;
  737. }
  738. ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
  739. $ldap_secure_connection = config_option('ldap_secure_connection', self::LDAP_SECURE_CONNECTION_NO);
  740. if ($ldap_secure_connection == self::LDAP_SECURE_CONNECTION_TLS) {
  741. if (!ldap_start_tls($ldapconn)) {
  742. ldap_close($ldapconn);
  743. return false;
  744. }
  745. }
  746. $ldapbind = ldap_bind($ldapconn, $username, $pass);
  747. ldap_close($ldapconn);
  748. return $ldapbind;
  749. } // doLDAP
  750. // ---------------------------------------------------
  751. // Permissions
  752. // ---------------------------------------------------
  753. /**
  754. * Can specific user add user to specific company
  755. *
  756. * @access public
  757. * @param User $user
  758. * @param Company $to Can user add user to this company
  759. * @return boolean
  760. */
  761. function canAdd(User $user, Company $to) {
  762. if ($user->isAccountOwner()) {
  763. return true;
  764. } // if
  765. return $user->isAdministrator();
  766. } // canAdd
  767. /**
  768. * Check if specific user can update this user account
  769. *
  770. * @access public
  771. * @param User $user
  772. * @return boolean
  773. */
  774. function canEdit(User $user) {
  775. if ($user->getId() == $this->getId()) {
  776. return true; // account owner
  777. } // if
  778. if ($user->isAccountOwner()) {
  779. return true;
  780. } // if
  781. return $user->isAdministrator();
  782. } // canEdit
  783. /**
  784. * Check if specific user can delete specific account
  785. *
  786. * @param User $user
  787. * @return boolean
  788. */
  789. function canDelete(User $user) {
  790. if ($this->isAccountOwner()) {
  791. return false; // can't delete accountowner
  792. } // if
  793. if ($this->getId() == $user->getId()) {
  794. return false; // can't delete self
  795. } // if
  796. return $user->isAdministrator();
  797. } // canDelete
  798. /**
  799. * Returns true if this user can see $user
  800. *
  801. * @param User $user
  802. * @return boolean
  803. */
  804. function canSeeUser(User $user) {
  805. if ($this->isMemberOfOwnerCompany()) {
  806. return true; // see all
  807. } // if
  808. if ($user->getCompanyId() == $this->getCompanyId()) {
  809. return true; // see members of your own company
  810. } // if
  811. if ($user->isMemberOfOwnerCompany()) {
  812. return true; // see members of owner company
  813. } // if
  814. return false;
  815. } // canSeeUser
  816. /**
  817. * Returns true if this user can see $contact
  818. * TODO shouldn't it be in the Contact model?
  819. *
  820. * @param Contact $contact
  821. * @return boolean
  822. */
  823. function canSeeContact(Contact $contact) {
  824. if ($this->isMemberOfOwnerCompany()) {
  825. return true; // see all
  826. } // if
  827. if ($contact->getCompanyId() == $this->getCompanyId()) {
  828. return true; // see members of your own company
  829. } // if
  830. if ($contact->isMemberOfOwnerCompany()) {
  831. return true; // see members of owner company
  832. } // if
  833. return false;
  834. } // canSeeContact
  835. /**
  836. * Returns true if this user can see $company. Members of owener company and
  837. * coworkers are visible without project check! Also, members of owner company
  838. * can see all clients without any prior check!
  839. *
  840. * @param Company $company
  841. * @return boolean
  842. */
  843. function canSeeCompany(Company $company) {
  844. if ($this->isMemberOfOwnerCompany()) {
  845. return true;
  846. } // if
  847. if ($company->isOwner()) {
  848. $this->visible_companies[$company->getId()] = true;
  849. return true;
  850. } // if
  851. if (isset($this->visible_companies[$company->getId()])) {
  852. return $this->visible_companies[$company->getId()];
  853. } // if
  854. if ($this->getCompanyId() == $company->getId()) {
  855. $this->visible_companies[$company->getId()] = true;
  856. return true;
  857. } // if
  858. // Lets company projects for company of this user and for $company and
  859. // compare if we have projects where both companies work together
  860. $projects_1 = DB::executeAll("SELECT `project_id` FROM " . ProjectCompanies::instance()->getTableName(true) . " WHERE `company_id` = ?", $this->getCompanyId());
  861. $projects_2 = DB::executeAll("SELECT `project_id` FROM " . ProjectCompanies::instance()->getTableName(true) . " WHERE `company_id` = ?", $company->getId());
  862. if (!is_array($projects_1) || !is_array($projects_2)) {
  863. $this->visible_companies[$company->getId()] = false;
  864. return false;
  865. } // if
  866. foreach ($projects_1 as $project_id) {
  867. if (in_array($project_id, $projects_2)) {
  868. $this->visible_companies[$company->getId()] = true;
  869. return true;
  870. } // if
  871. } // foreach
  872. $this->visible_companies[$company->getId()] = false;
  873. return false;
  874. } // canSeeCompany
  875. /**
  876. * Check if specific user can update this profile
  877. *
  878. * @param User $user
  879. * @return boolean
  880. */
  881. function canUpdateProfile(User $user) {
  882. if ($this->getId() == $user->getId()) {
  883. return true;
  884. } // if
  885. if ($user->isAdministrator()) {
  886. return true;
  887. } // if
  888. return false;
  889. } // canUpdateProfile
  890. /**
  891. * Check if this user can update this users permissions
  892. *
  893. * @param User $user
  894. * @return boolean
  895. */
  896. function canUpdatePermissions(User $user) {
  897. if ($this->isAccountOwner()) {
  898. return false; // noone will touch this
  899. } // if
  900. return $user->isAdministrator();
  901. } // canUpdatePermissions
  902. /**
  903. * Check if this user is company administration (used to check many other permissions). User must
  904. * be part of the company and have is_admin stamp set to true
  905. *
  906. * @access public
  907. * @param Company $company
  908. * @return boolean
  909. */
  910. function isCompanyAdmin(Company $company) {
  911. return ($this->getCompanyId() == $company->getId()) && $this->getIsAdmin();
  912. } // isCompanyAdmin
  913. // ---------------------------------------------------
  914. // URLs
  915. // ---------------------------------------------------
  916. /**
  917. * Return view account URL of this user
  918. *
  919. * @access public
  920. * @param void
  921. * @return string
  922. */
  923. function getAccountUrl() {
  924. return get_url('account', 'index');
  925. } // getAccountUrl
  926. /**
  927. * Show company card page
  928. *
  929. * @access public
  930. * @param void
  931. * @return null
  932. */
  933. function getCardUrl() {
  934. return get_url('contacts', 'card', $this->getContact()->getId());
  935. } // getCardUrl
  936. /**
  937. * Return edit user URL
  938. *
  939. * @access public
  940. * @param void
  941. * @return string
  942. */
  943. function getEditUrl() {
  944. return $this->getContact()->getEditUserAccountUrl();
  945. } // getEditUrl
  946. /**
  947. * Return delete user URL
  948. *
  949. * @access public
  950. * @param void
  951. * @return string
  952. */
  953. function getDeleteUrl() {
  954. return get_url('user', 'delete', $this->getId());
  955. } // getDeleteUrl
  956. /**
  957. * Return edit profile URL
  958. *
  959. * @param string $redirect_to URL where we need to redirect user when he updates profile
  960. * @return string
  961. */
  962. function getEditProfileUrl($redirect_to = null) {
  963. $attributes = array('id' => $this->getContact()->getId());
  964. if (trim($redirect_to) <> '') {
  965. $attributes['redirect_to'] = str_replace('&amp;', '&', trim($redirect_to));
  966. } // if
  967. return get_url('contacts', 'edit', $attributes);
  968. } // getEditProfileUrl
  969. /**
  970. * Edit users password
  971. *
  972. * @param string $redirect_to URL where we need to redirect user when he updates password
  973. * @return null
  974. */
  975. function getEditPasswordUrl($redirect_to = null) {
  976. $attributes = array('id' => $this->getId());
  977. if (trim($redirect_to) <> '') {
  978. $attributes['redirect_to'] = str_replace('&amp;', '&', trim($redirect_to));
  979. } // if
  980. return get_url('account', 'edit_password', $attributes);
  981. } // getEditPasswordUrl
  982. /**
  983. * Return edit user permissions page URL
  984. *
  985. * @param string $redirect_to
  986. * @return string
  987. */
  988. function getEditPermissionsUrl($redirect_to = null) {
  989. $attributes = array('id' => $this->getId());
  990. if (trim($redirect_to) <> '') {
  991. $attributes['redirect_to'] = str_replace('&amp;', '&', trim($redirect_to));
  992. } // if
  993. return get_url('account', 'edit_permissions', $attributes);
  994. } // getEditPermissionsUrl
  995. /**
  996. * Return radio URL
  997. *
  998. * @param string
  999. * @return string
  1000. */
  1001. function getRadioUrl() {
  1002. $attributes = array('id' => $this->getContact()->getId(), 'target' => '_blank');
  1003. return get_url('account', 'radio', $attributes);
  1004. } // getRadioUrl
  1005. /**
  1006. * Return update user permissions page URL
  1007. *
  1008. * @param string $redirect_to
  1009. * @return string
  1010. */
  1011. function getUpdatePermissionsUrl($redirect_to = null) {
  1012. $attributes = array('id' => $this->getId());
  1013. if (trim($redirect_to) <> '') {
  1014. $attributes['redirect_to'] = str_replace('&amp;', '&', trim($redirect_to));
  1015. } // if
  1016. return get_url('account', 'update_permissions', $attributes);
  1017. } // getUpdatePermissionsUrl
  1018. /**
  1019. * Return edit user URL
  1020. *
  1021. * @access public
  1022. * @param void
  1023. * @return string
  1024. */
  1025. function getEditProjectPermissionsUrl($project) {
  1026. $attributes = array('id' => $this->getId());
  1027. if ($project instanceof Project) {
  1028. $attributes['project_id'] = $project->getId();
  1029. }
  1030. return get_url('account', 'update_permissions', $attributes);
  1031. } // getEditUrl
  1032. /**
  1033. * Return recent activities feed URL
  1034. *
  1035. * If $project is valid project instance URL will be limited for that project only, else it will be returned for
  1036. * overal feed
  1037. *
  1038. * @param Project $project
  1039. * @return string
  1040. */
  1041. function getRecentActivitiesFeedUrl($project = null) {
  1042. $params = array(
  1043. 'id' => $this->getId(),
  1044. 'token' => $this->getTwistedToken(),
  1045. ); // array
  1046. if ($project instanceof Project) {
  1047. $params['project'] = $project->getId();
  1048. return get_url('feed', 'project_activities', $params, null, false);
  1049. } else {
  1050. return get_url('feed', 'recent_activities', $params, null, false);
  1051. } // if
  1052. } // getRecentActivitiesFeedUrl
  1053. /**
  1054. * Return iCalendar URL
  1055. *
  1056. * If $project is valid project instance calendar will be rendered just for that project, else it will be rendered
  1057. * for all active projects this user is involved with
  1058. *
  1059. * @param Project $project
  1060. * @return string
  1061. */
  1062. function getICalendarUrl($project = null) {
  1063. $params = array(
  1064. 'id' => $this->getId(),
  1065. 'token' => $this->getTwistedToken(),
  1066. ); // array
  1067. if ($project instanceof Project) {
  1068. $params['project'] = $project->getId();
  1069. return get_url('feed', 'project_ical', $params, null, false);
  1070. } else {
  1071. return get_url('feed', 'user_ical', $params, null, false);
  1072. } // if
  1073. } // getICalendarUrl
  1074. // ---------------------------------------------------
  1075. // System functions
  1076. // ---------------------------------------------------
  1077. /**
  1078. * Validate data before save
  1079. *
  1080. * @access public
  1081. * @param array $errors
  1082. * @return void
  1083. */
  1084. function validate(&$errors) {
  1085. // Validate username if present
  1086. if ($this->validatePresenceOf('username')) {
  1087. if (!$this->validateUniquenessOf('username')) {
  1088. $errors[] = lang('username must be unique');
  1089. }
  1090. } else {
  1091. $errors[] = lang('username value required');
  1092. } // if
  1093. if (!$this->validatePresenceOf('token')) {
  1094. $errors[] = lang('password value required');
  1095. }
  1096. // Validate email if present
  1097. if ($this->validatePresenceOf('email')) {
  1098. if (!$this->validateFormatOf('email', EMAIL_FORMAT)) {
  1099. $errors[] = lang('invalid email address');
  1100. }
  1101. } else {
  1102. $errors[] = lang('email value is required');
  1103. } // if
  1104. } // validate
  1105. /**
  1106. * Delete this object
  1107. *
  1108. * @param void
  1109. * @return boolean
  1110. */
  1111. function delete() {
  1112. if ($this->isAccountOwner()) {
  1113. return false;
  1114. } // if
  1115. ProjectUsers::clearByUser($this);
  1116. MessageSubscriptions::clearByUser($this);
  1117. return parent::delete();
  1118. } // delete
  1119. // ---------------------------------------------------
  1120. // ApplicationDataObject implementation
  1121. // ---------------------------------------------------
  1122. /**
  1123. * Return object name
  1124. *
  1125. * @access public
  1126. * @param void
  1127. * @return string
  1128. */
  1129. function getObjectName() {
  1130. return $this->getDisplayName();
  1131. } // getObjectName
  1132. /**
  1133. * Return object type name
  1134. *
  1135. * @param void
  1136. * @return string
  1137. */
  1138. function getObjectTypeName() {
  1139. return lang('user');
  1140. } // getObjectTypeName
  1141. /**
  1142. * Return object URl
  1143. *
  1144. * @access public
  1145. * @param void
  1146. * @return string
  1147. */
  1148. function getObjectUrl() {
  1149. return $this->getCardUrl();
  1150. } // getObjectUrl
  1151. } // User
  1152. ?>