functions.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. <?php
  2. /**
  3. * All helper functions for the questions plugin can be found in this file.
  4. */
  5. /**
  6. * This function checks if expert roles are enabled in the plugin settings
  7. *
  8. * @return bool
  9. */
  10. function questions_experts_enabled() {
  11. static $result;
  12. if (isset($result)) {
  13. return $result;
  14. }
  15. $result = false;
  16. if (elgg_get_plugin_setting('experts_enabled', 'questions') === 'yes') {
  17. $result = true;
  18. }
  19. return $result;
  20. }
  21. /**
  22. * This function checks if only experts are allowed to answer in the plugin settings
  23. *
  24. * @return bool
  25. */
  26. function questions_experts_only_answer() {
  27. static $result;
  28. if (isset($result)) {
  29. return $result;
  30. }
  31. $result = false;
  32. if (!questions_experts_enabled()) {
  33. return $result;
  34. }
  35. $setting = elgg_get_plugin_setting('experts_answer', 'questions');
  36. if ($setting === 'yes') {
  37. $result = true;
  38. }
  39. return $result;
  40. }
  41. /**
  42. * Check if a user is an expert
  43. *
  44. * @param ElggEntity $container the container where a question was asked, leave empty for any relationship
  45. * @param ElggUser $user the user to check (defaults to current user)
  46. *
  47. * @return bool
  48. */
  49. function questions_is_expert(ElggEntity $container = null, ElggUser $user = null) {
  50. $result = false;
  51. // make sure we have a user
  52. if (!($user instanceof ElggUser)) {
  53. $user = elgg_get_logged_in_user_entity();
  54. }
  55. if (empty($user)) {
  56. return false;
  57. }
  58. if ($container instanceof ElggEntity) {
  59. if ($container instanceof ElggUser) {
  60. $container = elgg_get_site_entity();
  61. }
  62. if (($container instanceof ElggSite) || ($container instanceof ElggGroup)) {
  63. if (check_entity_relationship($user->getGUID(), QUESTIONS_EXPERT_ROLE, $container->getGUID())) {
  64. // user has the expert role
  65. $result = true;
  66. }
  67. }
  68. } else {
  69. $expert_options =[
  70. 'count' => true,
  71. 'relationship' => QUESTIONS_EXPERT_ROLE,
  72. 'relationship_guid' => $user->getGUID(),
  73. ];
  74. if (elgg_get_entities_from_relationship($expert_options)) {
  75. // check if user has any expert relationship with entity on this site
  76. $result = true;
  77. }
  78. if (!$result) {
  79. // added specific check for Subsite Manager plugin where site has no current site entity set as entity_guid
  80. if (check_entity_relationship($user->getGUID(), QUESTIONS_EXPERT_ROLE, elgg_get_site_entity()->getGUID())) {
  81. // user has the expert role for this site
  82. $result = true;
  83. }
  84. }
  85. }
  86. return $result;
  87. }
  88. /**
  89. * Check if the user can mark this answer as the correct one
  90. *
  91. * @param ElggAnswer $entity the answer to check
  92. * @param ElggUser $user the use who is wants to do the action (defaults to current user)
  93. *
  94. * @return bool
  95. */
  96. function questions_can_mark_answer(ElggAnswer $entity, ElggUser $user = null) {
  97. $result = false;
  98. static $experts_only;
  99. // check if we have a user
  100. if (empty($user) || !($user instanceof ElggUser)) {
  101. $user = elgg_get_logged_in_user_entity();
  102. }
  103. if (empty($user) || empty($entity) || !($entity instanceof ElggAnswer)) {
  104. return false;
  105. }
  106. $container = $entity->getContainerEntity();
  107. // are experts enabled
  108. if (!questions_experts_enabled()) {
  109. // no, so only question owner can mark
  110. if ($user->getGUID() == $container->getOwnerGUID()) {
  111. $result = true;
  112. }
  113. } else {
  114. // get plugin setting for who can mark the answer
  115. if (!isset($experts_only)) {
  116. $experts_only = false;
  117. $setting = elgg_get_plugin_setting('experts_mark', 'questions');
  118. if ($setting == 'yes') {
  119. $experts_only = true;
  120. }
  121. }
  122. // are only experts allowed to mark
  123. if (!$experts_only) {
  124. // no, so the owner of a question can also mark
  125. if ($user->getGUID() == $container->getOwnerGUID()) {
  126. $result = true;
  127. }
  128. }
  129. // is the user an expert
  130. if (!$result && questions_is_expert($container->getContainerEntity(), $user)) {
  131. $result = true;
  132. }
  133. }
  134. return $result;
  135. }
  136. /**
  137. * Make sure the provided access_id is valid for this container
  138. *
  139. * @param int $access_id the current access_id
  140. * @param int $container_guid the container where the entity will be placed
  141. *
  142. * @return int
  143. */
  144. function questions_validate_access_id($access_id, $container_guid) {
  145. $access_id = sanitise_int($access_id);
  146. if ($access_id === ACCESS_DEFAULT) {
  147. $access_id = get_default_access();
  148. }
  149. if (empty($container_guid)) {
  150. return $access_id;
  151. }
  152. $container = get_entity($container_guid);
  153. if (empty($container)) {
  154. return $access_id;
  155. }
  156. if ($container instanceof ElggUser) {
  157. // is a default level defined in the plugin settings
  158. $personal_access_id = questions_get_personal_access_level();
  159. if ($personal_access_id !== false) {
  160. $access_id = $personal_access_id;
  161. } else {
  162. // make sure access_id is not a group acl
  163. $acl = get_access_collection($access_id);
  164. if (!empty($acl) && ($acl->owner_guid != $container->getGUID())) {
  165. // this acl is a group acl, so set to something else
  166. $access_id = ACCESS_LOGGED_IN;
  167. }
  168. }
  169. } elseif ($container instanceof ElggGroup) {
  170. // is a default level defined in the plugin settings
  171. $group_access_id = questions_get_group_access_level($container);
  172. if ($group_access_id !== false) {
  173. $access_id = $group_access_id;
  174. } else {
  175. // friends access not allowed in groups
  176. if ($access_id === ACCESS_FRIENDS) {
  177. // so set it to group access
  178. $access_id = (int) $container->group_acl;
  179. }
  180. // check if access is an acl
  181. $acl = get_access_collection($access_id);
  182. if (!empty($acl) && ($acl->owner_guid != $container->getGUID())) {
  183. // this acl is an acl, make sure it's the group acl
  184. $access_id = (int) $container->group_acl;
  185. }
  186. }
  187. }
  188. return $access_id;
  189. }
  190. /**
  191. * Get the default defined peronal access setting.
  192. *
  193. * @return false|int
  194. */
  195. function questions_get_personal_access_level() {
  196. static $result;
  197. if (!isset($result)) {
  198. $result = false;
  199. $setting = elgg_get_plugin_setting('access_personal', 'questions');
  200. if (!empty($setting) && ($setting !== 'user_defined')) {
  201. $result = (int) $setting;
  202. }
  203. }
  204. return $result;
  205. }
  206. /**
  207. * Get the default defined group access setting.
  208. *
  209. * @param ElggGroup $group the group if the setting is group_acl
  210. *
  211. * @return false|int
  212. */
  213. function questions_get_group_access_level(ElggGroup $group) {
  214. static $plugin_setting;
  215. $result = false;
  216. if (!isset($plugin_setting)) {
  217. $plugin_setting = false;
  218. $setting = elgg_get_plugin_setting('access_group', 'questions');
  219. if (!empty($setting) && ($setting != 'user_defined')) {
  220. $plugin_setting = $setting;
  221. }
  222. }
  223. if ($plugin_setting) {
  224. if ($plugin_setting == 'group_acl') {
  225. $result = (int) $group->group_acl;
  226. } else {
  227. $result = (int) $plugin_setting;
  228. }
  229. }
  230. return $result;
  231. }
  232. /**
  233. * This function checks of the plugin setting to close a question on a marked answer is set
  234. *
  235. * @return bool
  236. */
  237. function questions_close_on_marked_answer() {
  238. static $result;
  239. if (!isset($result)) {
  240. $result = false;
  241. $setting = elgg_get_plugin_setting('close_on_marked_answer', 'questions');
  242. if ($setting === 'yes') {
  243. $result = true;
  244. }
  245. }
  246. return $result;
  247. }
  248. /**
  249. * Return the number of days it should take to solve a question.
  250. *
  251. * @param ElggEntity $container if a group is provided, first the setting of the group is checked, then the default setting of the site
  252. *
  253. * @return int
  254. */
  255. function questions_get_solution_time(ElggEntity $container) {
  256. static $plugin_setting;
  257. if (!isset($plugin_setting)) {
  258. $plugin_setting = (int) elgg_get_plugin_setting('site_solution_time', 'questions');
  259. }
  260. // get site setting
  261. $result = $plugin_setting;
  262. // check is group
  263. if (($container instanceof ElggGroup) && questions_can_groups_set_solution_time()) {
  264. // get group setting
  265. $group_setting = $container->getPrivateSetting('questions_solution_time');
  266. if (($group_setting !== false) && ($group_setting !== null)) {
  267. // we have a valid group setting
  268. $result = (int) $group_setting;
  269. }
  270. }
  271. return $result;
  272. }
  273. /**
  274. * Check the plugin setting if questions are limited to groups.
  275. *
  276. * @return bool
  277. */
  278. function questions_limited_to_groups() {
  279. static $result;
  280. if (!isset($result)) {
  281. $result = false;
  282. $setting = elgg_get_plugin_setting('limit_to_groups', 'questions');
  283. if ($setting === 'yes') {
  284. $result = true;
  285. }
  286. }
  287. return $result;
  288. }
  289. /**
  290. * Return the GUID from a database row.
  291. *
  292. * @param stdObject $row the database row
  293. *
  294. * @return int
  295. */
  296. function questions_row_to_guid($row) {
  297. return (int) $row->guid;
  298. }
  299. /**
  300. * Checks if a question can be moved to the discussion in the container.
  301. *
  302. * @param ElggEntity $container the container where the question should become a discussion
  303. * @param ElggUser $user the user trying to move the question, defaults to current user
  304. *
  305. * @return bool
  306. */
  307. function questions_can_move_to_discussions(ElggEntity $container, ElggUser $user = null) {
  308. // make sure we have a user
  309. if (!($user instanceof ElggUser)) {
  310. $user = elgg_get_logged_in_user_entity();
  311. }
  312. if (empty($user)) {
  313. return false;
  314. }
  315. // only if container is a group
  316. if (!($container instanceof ElggGroup)) {
  317. return false;
  318. }
  319. // only experts can move
  320. if (!questions_is_expert($container, $user)) {
  321. return false;
  322. }
  323. // are discussions enabled
  324. if ($container->forum_enable === 'no') {
  325. return false;
  326. }
  327. return true;
  328. }
  329. /**
  330. * Backdate an entity, since this can't be done by Elgg core functions
  331. *
  332. * @param int $entity_guid the entity to update
  333. * @param int $time_created the new time_created
  334. *
  335. * @access private
  336. *
  337. * @return bool
  338. */
  339. function questions_backdate_entity($entity_guid, $time_created) {
  340. $entity_guid = sanitise_int($entity_guid, false);
  341. $time_created = sanitise_int($time_created);
  342. if (empty($entity_guid)) {
  343. return false;
  344. }
  345. $dbprefix = elgg_get_config('dbprefix');
  346. $query = "UPDATE {$dbprefix}entities
  347. SET time_created = {$time_created}
  348. WHERE guid = {$entity_guid}";
  349. return (bool) update_data($query);
  350. }
  351. /**
  352. * Check if a user can ask a question in a container
  353. *
  354. * @param ElggEntity $container the container to check (default: page_owner)
  355. * @param ElggUser $user the user askting the question (default: current user)
  356. *
  357. * @return bool
  358. */
  359. function questions_can_ask_question(ElggEntity $container = null, ElggUser $user = null) {
  360. // default to page owner
  361. if (!($container instanceof ElggEntity)) {
  362. $container = elgg_get_page_owner_entity();
  363. }
  364. // default to current user
  365. if (!($user instanceof ElggUser)) {
  366. $user = elgg_get_logged_in_user_entity();
  367. }
  368. if (empty($user)) {
  369. // not logged in
  370. return false;
  371. }
  372. if (!($container instanceof ElggGroup)) {
  373. // personal questions
  374. return !questions_limited_to_groups();
  375. }
  376. if ($container->questions_enable !== 'yes') {
  377. // group option not enabled
  378. return false;
  379. }
  380. if (!questions_experts_enabled() || ($container->getPrivateSetting('questions_who_can_ask') !== 'experts')) {
  381. // no experts enabled, or not limited to experts
  382. return can_write_to_container($user->getGUID(), $container->getGUID(), 'object', ElggQuestion::SUBTYPE);
  383. }
  384. if (!questions_is_expert($container, $user)) {
  385. // limited to expert, and user isn't one
  386. return false;
  387. }
  388. return can_write_to_container($user->getGUID(), $container->getGUID(), 'object', ElggQuestion::SUBTYPE);
  389. }
  390. /**
  391. * Check if a user can answer a question
  392. *
  393. * @param ElggQuestion $question the question that needs answer
  394. * @param ElggUser $user the user askting the question (default: current user)
  395. *
  396. * @return bool
  397. */
  398. function questions_can_answer_question(ElggQuestion $question, ElggUser $user = null) {
  399. static $general_experts_only;
  400. // default to page owner
  401. if (!($question instanceof ElggQuestion)) {
  402. return false;
  403. }
  404. // default to current user
  405. if (!($user instanceof ElggUser)) {
  406. $user = elgg_get_logged_in_user_entity();
  407. }
  408. if (empty($user)) {
  409. // not logged in
  410. return false;
  411. }
  412. $container = $question->getContainerEntity();
  413. if (!questions_experts_enabled()) {
  414. return questions_can_ask_question($container, $user);
  415. }
  416. // get plugin setting
  417. if (!isset($general_experts_only)) {
  418. $general_experts_only = questions_experts_only_answer();
  419. }
  420. $is_expert = questions_is_expert($container, $user);
  421. // check general setting
  422. if ($general_experts_only && !$is_expert) {
  423. return false;
  424. }
  425. if (!($container instanceof ElggGroup)) {
  426. return true;
  427. }
  428. // check group settings
  429. $group_experts_only = false;
  430. if ($container->getPrivateSetting('questions_who_can_answer') === 'experts') {
  431. $group_experts_only = true;
  432. }
  433. if ($group_experts_only && !$is_expert) {
  434. return false;
  435. }
  436. // are you a group member or can you edit the group
  437. return ($container->isMember($user) || $container->canEdit($user->getGUID()));
  438. }
  439. /**
  440. * Can group owners set the solution time
  441. *
  442. * @return bool
  443. */
  444. function questions_can_groups_set_solution_time() {
  445. static $result;
  446. if (isset($result)) {
  447. return $result;
  448. }
  449. $result = true;
  450. if (elgg_get_plugin_setting('solution_time_group', 'questions') === 'no') {
  451. $result = false;
  452. }
  453. return $result;
  454. }
  455. /**
  456. * Automaticly mark an answer as the correct answer, when created by an expert
  457. *
  458. * NOTE: for now this is only supported in groups
  459. *
  460. * @param ElggEntity $container the container of the questions (group or user)
  461. * @param ElggUser $user the user doing the action (default: current user)
  462. *
  463. * @return bool
  464. */
  465. function questions_auto_mark_answer_correct(ElggEntity $container, ElggUser $user = null) {
  466. if (!($container instanceof ElggGroup)) {
  467. // for now only supported in groups
  468. return false;
  469. }
  470. if (!($user instanceof ElggUser)) {
  471. $user = elgg_get_logged_in_user_entity();
  472. }
  473. if (!($user instanceof ElggUser)) {
  474. return false;
  475. }
  476. if (!questions_experts_enabled()) {
  477. // only applies to experts
  478. return false;
  479. }
  480. if (!questions_is_expert($container, $user)) {
  481. // not an expert
  482. return false;
  483. }
  484. // check group setting
  485. $group_setting = $container->getPrivateSetting('questions_auto_mark_correct');
  486. return ($group_setting === 'yes');
  487. }