PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/web/system/GroupsModule/Api/UserApi.php

https://github.com/antoniom/core
PHP | 696 lines | 396 code | 123 blank | 177 comment | 108 complexity | eac314960aa2d1d1dc72753ff8c8736f MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0, MIT
  1. <?php
  2. /**
  3. * Copyright Zikula Foundation 2009 - Zikula Application Framework
  4. *
  5. * This work is contributed to the Zikula Foundation under one or more
  6. * Contributor Agreements and licensed to You under the following license:
  7. *
  8. * @license GNU/LGPLv3 (or at your option, any later version).
  9. * @package Zikula
  10. *
  11. * Please see the NOTICE file distributed with this source code for further
  12. * information regarding copyright and licensing.
  13. */
  14. namespace GroupsModule\Api;
  15. use Zikula\Core\Event\GenericEvent;
  16. use SecurityUtil, LogUtil, UserUtil, ModUtil;
  17. use GroupsModule\Helper\CommonHelper;
  18. use GroupsModule\Entity\GroupApplication;
  19. use GroupsModule\Entity\GroupMembership;
  20. /**
  21. * Groups_Api_User class.
  22. */
  23. class UserApi extends \Zikula\Framework\Api\AbstractApi
  24. {
  25. /**
  26. * Get all group items.
  27. *
  28. * @param int $args['startnum'] record number to start get from.
  29. * @param int $args['numitems'] number of items to get.
  30. *
  31. * @return mixed array of group items, or false on failure.
  32. */
  33. public function getall($args)
  34. {
  35. $items = array();
  36. // Security check
  37. if (!SecurityUtil::checkPermission('Groups::', '::', ACCESS_READ)) {
  38. return $items;
  39. }
  40. // create a QueryBuilder instance
  41. $qb = $this->entityManager->createQueryBuilder();
  42. // add select and from params
  43. $qb->select('g')
  44. ->from('GroupsModule\Entity\Group', 'g');
  45. // add clause for ordering
  46. $qb->addOrderBy('g.name', 'ASC');
  47. // add limit and offset
  48. $startnum = (!isset($args['startnum']) || !is_numeric($args['startnum'])) ? 0 : (int)$args['startnum'];
  49. $numitems = (!isset($args['numitems']) || !is_numeric($args['numitems'])) ? 0 : (int)$args['numitems'];
  50. if ($numitems > 0) {
  51. $qb->setFirstResult($startnum)
  52. ->setMaxResults($numitems);
  53. }
  54. // convert querybuilder instance into a Query object
  55. $query = $qb->getQuery();
  56. // execute query
  57. $objArray = $query->getResult();
  58. // Check for an error with the database code
  59. if ($objArray === false) {
  60. return LogUtil::registerError($this->__('Error! Could not load data.'));
  61. }
  62. // Return the items
  63. return $objArray;
  64. }
  65. /**
  66. * Get a specific group item.
  67. *
  68. * @param int $args['gid'] id of group item to get.
  69. * @param int $args['startnum'] record number to start get from (group membership).
  70. * @param int $args['numitems'] number of items to get (group membership).
  71. *
  72. * @return mixed item array, or false on failure.
  73. */
  74. public function get($args)
  75. {
  76. // Argument check
  77. if (!isset($args['gid'])) {
  78. throw new \InvalidArgumentException('Missing or invalid arguments');
  79. }
  80. // get item
  81. $result = $this->entityManager->find('GroupsModule\Entity\Group', $args['gid']);
  82. if (!$result) {
  83. return false;
  84. }
  85. // convert to array
  86. $result = $result->toArray();
  87. // Get group membership
  88. // Optional arguments.
  89. if (!isset($args['startnum']) || !is_numeric($args['startnum'])) {
  90. $args['startnum'] = null;
  91. }
  92. if (!isset($args['numitems']) || !is_numeric($args['numitems'])) {
  93. $args['numitems'] = null;
  94. }
  95. $groupmembership = $this->entityManager->getRepository('GroupsModule\Entity\GroupMembership')->findBy(array('gid' => $args['gid']), array(), $args['numitems'], $args['startnum']);
  96. // Check for an error with the database code
  97. if ($groupmembership === false) {
  98. return false;
  99. }
  100. $uidsArray = array();
  101. foreach ($groupmembership as $gm) {
  102. $gm = $gm->toArray();
  103. $uidsArray[$gm['uid']] = $gm;
  104. }
  105. // Security check
  106. if (!SecurityUtil::checkPermission('Groups::', $result['gid'] . '::', ACCESS_READ)) {
  107. return false;
  108. }
  109. // Create the item array
  110. $result['nbuser'] = count($uidsArray);
  111. $result['members'] = $uidsArray;
  112. $uid = UserUtil::getVar('uid');
  113. if ($uid != 0) {
  114. $result['status'] = ModUtil::apiFunc('GroupsModule', 'user', 'isuserpending', array('gid' => $args['gid'], 'uid' => $uid));
  115. } else {
  116. $result['status'] = false;
  117. }
  118. // Return the item array
  119. return $result;
  120. }
  121. /**
  122. * Utility function to count the number of items held by this module.
  123. *
  124. * @return int number of items held by this module
  125. */
  126. public function countitems()
  127. {
  128. $dql = "SELECT count(g.gid) FROM GroupsModule\Entity\Group g WHERE g.gtype <> " . CommonHelper::GTYPE_CORE;
  129. if ($this->getVar('hideclosed')) {
  130. $dql .= " AND g.state <> " . CommonHelper::STATE_CLOSED;
  131. }
  132. $query = $this->entityManager->createQuery($dql);
  133. return (int)$query->getSingleScalarResult();
  134. }
  135. /**
  136. * Utility function to count the number of items held by this module.
  137. *
  138. * @param int $args['gid'] id of group item to get.
  139. *
  140. * @return int number of items held by this module.
  141. */
  142. public function countgroupmembers($args)
  143. {
  144. // Argument check
  145. if (!isset($args['gid'])) {
  146. throw new \InvalidArgumentException('Missing or invalid arguments');
  147. }
  148. $dql = "SELECT count(m.gid) FROM GroupsModule\Entity\GroupMembership m WHERE m.gid = {$args['gid']}";
  149. $query = $this->entityManager->createQuery($dql);
  150. return (int)$query->getSingleScalarResult();
  151. }
  152. /**
  153. * Get all of a user's group memberships.
  154. *
  155. * @param int $args['uid'] user id.
  156. * @param int $args['clean'] flag to return an array of GIDs.
  157. *
  158. * @return mixed array of group items, or false on failure.
  159. */
  160. public function getusergroups($args)
  161. {
  162. // Optional arguments.
  163. if (!isset($args['uid'])) {
  164. $args['uid'] = UserUtil::getVar('uid');
  165. }
  166. if (!isset($args['uid'])) {
  167. throw new \InvalidArgumentException('Missing or invalid arguments');
  168. }
  169. $items = array();
  170. // Security check
  171. if (!SecurityUtil::checkPermission('Groups::', '::', ACCESS_READ)) {
  172. return $items;
  173. }
  174. $groupmembership = $this->entityManager->getRepository('GroupsModule\Entity\GroupMembership')->findBy(array('uid' => $args['uid']));
  175. // Check for an error with the database code
  176. if ($groupmembership === false) {
  177. return LogUtil::registerError($this->__('Error! Could not load data.'));
  178. }
  179. $objArray = array();
  180. foreach ($groupmembership as $gm) {
  181. $objArray[] = $gm->toArray();
  182. }
  183. if (isset($args['clean']) && $args['clean']) {
  184. $newArray = array();
  185. foreach ($objArray as $obj) {
  186. $newArray[] = $obj['gid'];
  187. }
  188. $objArray = $newArray;
  189. }
  190. // Return the items
  191. return $objArray;
  192. }
  193. /**
  194. * Get all groups.
  195. *
  196. * @param array $args
  197. *
  198. * @return array of groups.
  199. */
  200. public function getallgroups($args)
  201. {
  202. $items = array();
  203. if (!SecurityUtil::checkPermission('Groups::', 'ANY', ACCESS_OVERVIEW)) {
  204. return $items;
  205. }
  206. // create a QueryBuilder instance
  207. $qb = $this->entityManager->createQueryBuilder();
  208. // add select and from params
  209. $qb->select('g')
  210. ->from('GroupsModule\Entity\Group', 'g');
  211. // add clause for filtering type
  212. $qb->andWhere($qb->expr()->neq('g.gtype', $qb->expr()->literal(CommonHelper::GTYPE_CORE)));
  213. // add clause for filtering state
  214. if ($this->getVar('hideclosed')) {
  215. $qb->andWhere($qb->expr()->neq('g.state', $qb->expr()->literal(CommonHelper::STATE_CLOSED)));
  216. }
  217. // add clause for ordering
  218. $qb->addOrderBy('g.name', 'ASC');
  219. // add limit and offset
  220. $startnum = (!isset($args['startnum']) || !is_numeric($args['startnum'])) ? 0 : (int)$args['startnum'];
  221. $numitems = (!isset($args['numitems']) || !is_numeric($args['numitems'])) ? 0 : (int)$args['numitems'];
  222. if ($numitems > 0) {
  223. $qb->setFirstResult($startnum)
  224. ->setMaxResults($numitems);
  225. }
  226. // convert querybuilder instance into a Query object
  227. $query = $qb->getQuery();
  228. // execute query
  229. $objArray = $query->getResult();
  230. if ($objArray === false) {
  231. return LogUtil::registerError($this->__('Error! Could not load data.'));
  232. }
  233. $uid = UserUtil::getVar('uid');
  234. if ($uid != 0) {
  235. $memberships = ModUtil::apiFunc('GroupsModule', 'user', 'getusergroups',
  236. array('uid' => $uid,
  237. 'clean' => true));
  238. } else {
  239. $memberships = false;
  240. }
  241. $row = 1;
  242. foreach ($objArray as $obj) {
  243. $obj = $obj->toArray();
  244. $gid = $obj['gid'];
  245. $name = $obj['name'];
  246. $gtype = $obj['gtype'];
  247. $description = $obj['description'];
  248. $state = $obj['state'];
  249. $nbumax = $obj['nbumax'];
  250. if (SecurityUtil::checkPermission('Groups::', $gid . '::', ACCESS_OVERVIEW)) {
  251. if (!isset($gtype) || is_null($gtype)) {
  252. $gtype = CommonHelper::GTYPE_CORE;
  253. }
  254. if (is_null($state)) {
  255. $state = CommonHelper::STATE_CLOSED;
  256. }
  257. $ismember = false;
  258. if (is_array($memberships) && in_array($gid, $memberships)) {
  259. $ismember = true;
  260. }
  261. if ($uid != 0) {
  262. $status = ModUtil::apiFunc('GroupsModule', 'user', 'isuserpending', array('gid' => $gid, 'uid' => $uid));
  263. } else {
  264. $status = false;
  265. }
  266. $nbuser = ModUtil::apiFunc('GroupsModule', 'user', 'countgroupmembers', array('gid' => $gid));
  267. if (SecurityUtil::checkPermission('Groups::', $gid . '::', ACCESS_READ)) {
  268. $canview = true;
  269. $canapply = true;
  270. } else {
  271. $canview = false;
  272. $canapply = false;
  273. }
  274. // Anon users or non-members should not be able to see private groups.
  275. if ($gtype == CommonHelper::GTYPE_PRIVATE) {
  276. if (!$uid || !$this->isgroupmember(array('uid' => $uid, 'gid' => $gid))) {
  277. continue;
  278. }
  279. }
  280. $items[] = array(
  281. 'gid' => $gid,
  282. 'name' => $name,
  283. 'gtype' => $gtype,
  284. 'description' => $description,
  285. 'state' => $state,
  286. 'nbuser' => (($nbuser <> false) ? $nbuser : 0),
  287. 'nbumax' => $nbumax,
  288. 'ismember' => $ismember,
  289. 'status' => $status,
  290. 'canview' => $canview,
  291. 'canapply' => $canapply,
  292. 'islogged' => UserUtil::isLoggedIn(),
  293. 'row' => $row);
  294. if ($row == 1) {
  295. $row = 2;
  296. } else {
  297. $row = 1;
  298. }
  299. }
  300. }
  301. return $items;
  302. }
  303. /**
  304. * Save application.
  305. *
  306. * @param int $args['uid'] user id.
  307. * @param int $args['gid'] group id.
  308. *
  309. * @return boolean
  310. */
  311. public function saveapplication($args)
  312. {
  313. if (!isset($args['gid']) || !isset($args['uid'])) {
  314. throw new \InvalidArgumentException('Missing or invalid arguments');
  315. }
  316. $item = ModUtil::apiFunc('GroupsModule', 'user', 'get', array('gid' => $args['gid']));
  317. if (!$item) {
  318. return LogUtil::registerError($this->__('Sorry! No such item found.'));
  319. }
  320. if (!SecurityUtil::checkPermission('Groups::', $args['gid'] . '::', ACCESS_READ)) {
  321. throw new \Zikula\Framework\Exception\ForbiddenException();
  322. }
  323. // Check in case the user already applied
  324. $pending = ModUtil::apiFunc('GroupsModule', 'user', 'isuserpending',
  325. array('gid' => $args['gid'],
  326. 'uid' => $args['uid']));
  327. if ($pending) {
  328. return LogUtil::registerError($this->__('Error! You have already applied for membership of this group.'));
  329. }
  330. $application = new GroupApplication;
  331. $application['uid'] = $args['uid'];
  332. $application['gid'] = $args['gid'];
  333. $application['application'] = $args['applytext'];
  334. $application['status'] = 1;
  335. $this->entityManager->persist($application);
  336. $this->entityManager->flush();
  337. return true;
  338. }
  339. /**
  340. * Delete app from group_applications.
  341. *
  342. * @param array $args
  343. *
  344. * @return boolean
  345. */
  346. public function cancelapp($args)
  347. {
  348. if (!isset($args['gid']) || !isset($args['uid'])) {
  349. throw new \InvalidArgumentException('Missing or invalid arguments');
  350. }
  351. // Checking first if this user is really pending.
  352. $ispending = ModUtil::apiFunc('GroupsModule', 'user', 'isuserpending',
  353. array('gid' => $args['gid'],
  354. 'uid' => $args['uid']));
  355. if ($ispending == true) {
  356. $application = $this->entityManager->getRepository('GroupsModule\Entity\GroupApplication')->findOneBy(array('gid' => $args['gid'], 'uid' => $args['uid']));
  357. $this->entityManager->remove($application);
  358. $this->entityManager->flush();
  359. }
  360. return true;
  361. }
  362. /**
  363. * Check if user is pending.
  364. *
  365. * @param int $args['uid'] user id.
  366. * @param int $args['gid'] group id.
  367. *
  368. * @return boolean
  369. */
  370. public function isuserpending($args)
  371. {
  372. if (!isset($args['gid']) || !isset($args['uid'])) {
  373. throw new \InvalidArgumentException('Missing or invalid arguments');
  374. }
  375. $applications = $this->entityManager->getRepository('GroupsModule\Entity\GroupApplication')->findBy(array('gid' => $args['gid'], 'uid' => $args['uid']));
  376. if (count($applications) >= 1) {
  377. return true;
  378. }
  379. return false;
  380. }
  381. /**
  382. * Update user.
  383. *
  384. * @param int $args['uid'] user id.
  385. * @param int $args['gtype'].
  386. * @param string $args['action'].
  387. *
  388. * @return boolean
  389. */
  390. public function userupdate($args)
  391. {
  392. if (!isset($args['gid']) || !isset($args['action']) || !isset($args['gtype'])) {
  393. throw new \InvalidArgumentException('Missing or invalid arguments');
  394. }
  395. if ($args['action'] != 'subscribe' && $args['action'] != 'unsubscribe' && $args['action'] != 'cancel') {
  396. throw new \InvalidArgumentException('Missing or invalid arguments');
  397. }
  398. if (!UserUtil::isLoggedIn()) {
  399. LogUtil::registerError($this->__('Error! You must register for a user account on this site before you can apply for membership of a group.'));
  400. }
  401. $userid = UserUtil::getVar('uid');
  402. if ($args['action'] == 'subscribe') {
  403. if ($args['gtype'] == CommonHelper::GTYPE_PRIVATE) {
  404. if (!isset($args['applytext'])) {
  405. throw new \InvalidArgumentException('Missing or invalid arguments');
  406. }
  407. // We save the user in the application table
  408. $save = ModUtil::apiFunc('GroupsModule', 'user', 'saveapplication',
  409. array('gid' => $args['gid'],
  410. 'uid' => $userid,
  411. 'applytext' => $args['applytext']));
  412. if ($save == false) {
  413. return false;
  414. }
  415. if ($this->getVar('mailwarning')) {
  416. $uname = UserUtil::getVar('uname', $userid);
  417. $send = ModUtil::apiFunc('MailerModule', 'user', 'sendmessage',
  418. array('toname' => $this->__('Administrator'),
  419. 'toaddress' => System::getVar('adminmail'),
  420. 'subject' => $this->__('Group membership application registered'),
  421. 'body' => $this->__f('The registered user %1$s has applied for membership of a group. The details of the application are as follows: %2$s', array($uname, $args['applytext']))));
  422. }
  423. } else {
  424. // We save the user into the groups
  425. $save = ModUtil::apiFunc('GroupsModule', 'user', 'adduser',
  426. array('gid' => $args['gid'],
  427. 'uid' => $userid));
  428. if ($save == false) {
  429. return LogUtil::registerError($this->__('Error! Could not add the user to the group.'));
  430. }
  431. }
  432. } elseif ($args['action'] == 'cancel') {
  433. $save = ModUtil::apiFunc('GroupsModule', 'user', 'cancelapp',
  434. array('gid' => $args['gid'],
  435. 'uid' => $userid));
  436. if ($save == false) {
  437. return LogUtil::registerError($this->__('Error! Could not remove the user from the group.'));
  438. }
  439. } else {
  440. $save = ModUtil::apiFunc('GroupsModule', 'user', 'removeuser',
  441. array('gid' => $args['gid'],
  442. 'uid' => $userid));
  443. if ($save == false) {
  444. return LogUtil::registerError($this->__('Error! Could not remove the user from the group.'));
  445. }
  446. }
  447. return true;
  448. }
  449. /**
  450. * Add a user to a group item.
  451. *
  452. * @param int $args['gid'] the ID of the item.
  453. * @param int $args['uid'] the ID of the user.
  454. *
  455. * @return bool true if successful, false otherwise.
  456. */
  457. public function adduser($args)
  458. {
  459. // Argument check
  460. if (!isset($args['gid']) || !isset($args['uid'])) {
  461. throw new \InvalidArgumentException('Missing or invalid arguments');
  462. }
  463. // get group
  464. $group = ModUtil::apiFunc('GroupsModule', 'user', 'get', array('gid' => $args['gid']));
  465. if (!$group) {
  466. return LogUtil::registerError($this->__('Sorry! No such item found.'));
  467. }
  468. // Security check
  469. if (!SecurityUtil::checkPermission('Groups::', $args['gid'] . '::', ACCESS_READ)) {
  470. throw new \Zikula\Framework\Exception\ForbiddenException();
  471. }
  472. // verify if the user is alredy a member of this group
  473. $is_member = ModUtil::apiFunc('GroupsModule', 'user', 'isgroupmember', array('gid' => $args['gid'], 'uid' => $args['uid']));
  474. // Add item
  475. if (!$is_member) {
  476. $membership = new GroupMembership;
  477. $membership['gid'] = $args['gid'];
  478. $membership['uid'] = $args['uid'];
  479. $this->entityManager->persist($membership);
  480. $this->entityManager->flush();
  481. // Let other modules know that we have updated a group.
  482. $adduserEvent = new GenericEvent($membership);
  483. $this->dispatcher->dispatch('group.adduser', $adduserEvent);
  484. } else {
  485. if (isset($args['verbose']) && !$args['verbose']) {
  486. return false;
  487. }
  488. return LogUtil::registerError($this->__('Error! You are already a member of this group.'));
  489. }
  490. // Let the calling process know that we have finished successfully
  491. return true;
  492. }
  493. /**
  494. * Remove a user from a group item.
  495. *
  496. * @param int $args['gid'] the ID of the item.
  497. * @param int $args['uid'] the ID of the user.
  498. *
  499. * @return bool true if successful, false otherwise.
  500. */
  501. public function removeuser($args)
  502. {
  503. if (!isset($args['gid']) || !isset($args['uid'])) {
  504. throw new \InvalidArgumentException('Missing or invalid arguments');
  505. }
  506. // get group
  507. $group = ModUtil::apiFunc('GroupsModule', 'user', 'get', array('gid' => $args['gid']));
  508. if (!$group) {
  509. return LogUtil::registerError($this->__('Sorry! No such item found.'));
  510. }
  511. // Security check
  512. if (!SecurityUtil::checkPermission('Groups::', $args['gid'] . '::', ACCESS_READ)) {
  513. throw new \Zikula\Framework\Exception\ForbiddenException();
  514. }
  515. // delete user from group
  516. $membership = $this->entityManager->getRepository('GroupsModule\Entity\GroupMembership')->findOneBy(array('gid' => $args['gid'], 'uid' => $args['uid']));
  517. $this->entityManager->remove($membership);
  518. $this->entityManager->flush();
  519. // Let other modules know we have updated a group
  520. $removeuserEvent = new GenericEvent(null, array('gid' => $args['gid'], 'uid' => $args['uid']));
  521. $this->dispatcher->dispatch('group.removeuser', $removeuserEvent);
  522. // Let the calling process know that we have finished successfully
  523. return true;
  524. }
  525. /**
  526. * Find who is online.
  527. *
  528. * @param unknown_type $args
  529. *
  530. * @return mixed array of users, or false.
  531. */
  532. public function whosonline()
  533. {
  534. $activetime = time() - (\System::getVar('secinactivemins') * 60);
  535. $dql = "SELECT DISTINCT(s.uid) FROM Users\Entity\UserSession s WHERE s.lastused > ' " . $activetime . "' AND s.uid <> 0";
  536. $query = $this->entityManager->createQuery($dql);
  537. $items = $query->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
  538. return $items;
  539. }
  540. /**
  541. * Check if a user is a member of a group.
  542. *
  543. * @param int $args['uid'] user id.
  544. * @param int $args['gid'] group id.
  545. *
  546. * @return boolean true if member of a group, false otherwise.
  547. */
  548. public function isgroupmember($args)
  549. {
  550. if (!isset($args['uid']) || !is_numeric($args['uid']) ||
  551. !isset($args['gid']) || !is_numeric($args['gid'])) {
  552. throw new \InvalidArgumentException('Missing or invalid arguments');
  553. }
  554. // Security check
  555. if (!SecurityUtil::checkPermission('Groups::', '::', ACCESS_READ)) {
  556. return false;
  557. }
  558. // Get the group
  559. $group = ModUtil::apiFunc('GroupsModule', 'user', 'get', array('gid' => $args['gid']));
  560. // check if group exists
  561. if (!$group) {
  562. // report failiure
  563. return false;
  564. }
  565. // check if the user exists in the group
  566. if (!isset($group['members'][$args['uid']])) {
  567. // report failiure
  568. return false;
  569. }
  570. // report the user is a member of the group
  571. return true;
  572. }
  573. }