BxTasksModule.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. * @defgroup Tasks Tasks
  6. * @ingroup UnaModules
  7. *
  8. * @{
  9. */
  10. /**
  11. * Tasks module
  12. */
  13. class BxTasksModule extends BxBaseModTextModule implements iBxDolCalendarService
  14. {
  15. function __construct(&$aModule)
  16. {
  17. parent::__construct($aModule);
  18. $CNF = &$this->_oConfig->CNF;
  19. $this->_aSearchableNamesExcept = array_merge($this->_aSearchableNamesExcept, array(
  20. $CNF['FIELD_PUBLISHED'],
  21. $CNF['FIELD_DISABLE_COMMENTS']
  22. ));
  23. }
  24. /**
  25. * Action methods
  26. */
  27. /**
  28. * Get possible recipients for start conversation form
  29. */
  30. public function actionAjaxGetInitialMembers ()
  31. {
  32. $sTerm = bx_get('term');
  33. $a = BxDolService::call('system', 'profiles_search', array($sTerm), 'TemplServiceProfiles');
  34. header('Content-Type:text/javascript; charset=utf-8');
  35. echo(json_encode($a));
  36. }
  37. public function actionSetCompleted($iContentId, $iValue)
  38. {
  39. $CNF = &$this->_oConfig->CNF;
  40. $this->_oDb->updateEntriesBy(array($CNF['FIELD_COMPLETED'] => $iValue), array($CNF['FIELD_ID'] => (int)$iContentId));
  41. $sActionName = 'completed';
  42. if ($iValue == '0')
  43. $sActionName = 'reopened';
  44. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  45. $aParams = $this->_alertParams($aContentInfo);
  46. bx_alert($this->getName(), $sActionName, $iContentId, $aContentInfo[$CNF['FIELD_AUTHOR']], $aParams);
  47. echo 'ok';
  48. }
  49. public function actionSetFilterValue($iListId, $sValue)
  50. {
  51. $CNF = &$this->_oConfig->CNF;
  52. $aTmp = array();
  53. if (isset($_COOKIE[$CNF['COOKIE_SETTING_KEY']]))
  54. $aTmp = json_decode($_COOKIE[$CNF['COOKIE_SETTING_KEY']], true);
  55. $aUrl = parse_url(BX_DOL_URL_ROOT);
  56. $sPath = isset($aUrl['path']) && !empty($aUrl['path']) ? $aUrl['path'] : '/';
  57. if ($sValue != '')
  58. $aTmp[$iListId] = $sValue;
  59. else
  60. unset($aTmp[$iListId]);
  61. setcookie($CNF['COOKIE_SETTING_KEY'], json_encode($aTmp), time() + 60*60*24*365, $sPath);
  62. }
  63. public function actionProcessTaskListForm($iContextId, $iId)
  64. {
  65. $CNF = &$this->_oConfig->CNF;
  66. $oForm = null;
  67. $sPopupTitle = "";
  68. $aContentInfo = array();
  69. if ($iId == 0){
  70. $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_LIST_ENTRY'], $CNF['OBJECT_FORM_LIST_ENTRY_DISPLAY_ADD']);
  71. $sPopupTitle = _t('_bx_tasks_form_list_entry_display_add');
  72. }
  73. else{
  74. $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_LIST_ENTRY'], $CNF['OBJECT_FORM_LIST_ENTRY_DISPLAY_EDIT']);
  75. $aContentInfo = $this->_oDb->getList($iId);
  76. $sPopupTitle = _t('_bx_tasks_form_list_entry_display_edit');
  77. }
  78. $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'process_task_list_form/' . $iContextId . '/' . $iId . '/';
  79. if (!$oForm)
  80. return '';
  81. $oForm->initChecker($aContentInfo, array());
  82. if($oForm->isSubmittedAndValid()) {
  83. if ($iId == 0){
  84. $aValsToAdd['context_id'] = $iContextId;
  85. $iId = $oForm->insert($aValsToAdd);
  86. }
  87. else{
  88. $iId = $oForm->update($iId);
  89. }
  90. return echoJson(array(
  91. 'eval' => $this->_oConfig->getJsObject('tasks') . '.reloadData(oData)',
  92. ));
  93. }
  94. else {
  95. $sContent = $this->_oTemplate->parseHtmlByName('popup_form.html', array(
  96. 'form_id' => $oForm->getId(),
  97. 'form' => $oForm->getCode(true)
  98. ));
  99. if (!$oForm->isSubmitted()){
  100. echo $sContent;
  101. return;
  102. }
  103. return echoJson(array('form' => $sContent, 'form_id' => $oForm->getId()));;
  104. }
  105. }
  106. public function actionProcessTaskForm($iContextId, $iListId)
  107. {
  108. $CNF = &$this->_oConfig->CNF;
  109. $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $CNF['OBJECT_FORM_ENTRY_DISPLAY_ADD']);
  110. $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'process_task_form/' . $iContextId . '/' . $iListId . '/';
  111. if (!$oForm)
  112. return '';
  113. $oForm->initChecker();
  114. if($oForm->isSubmittedAndValid()) {
  115. $aValsToAdd[$CNF['FIELD_ALLOW_VIEW_TO']] = $iContextId;
  116. $aValsToAdd[$CNF['FIELD_TASKLIST']] = $iListId;
  117. $iContentId = $oForm->insert($aValsToAdd);
  118. $this->onPublished($iContentId);
  119. return echoJson(array(
  120. 'eval' => $this->_oConfig->getJsObject('tasks') . '.reloadData(oData)',
  121. ));
  122. }
  123. else {
  124. $sContent = $this->_oTemplate->parseHtmlByName('popup_form.html', array(
  125. 'form_id' => $oForm->getId(),
  126. 'form' => $oForm->getCode(true)
  127. ));
  128. if (!$oForm->isSubmitted()){
  129. echo $sContent;
  130. return;
  131. }
  132. return echoJson(array('form' => $sContent, 'form_id' => $oForm->getId()));;
  133. }
  134. }
  135. public function actionCalendarData()
  136. {
  137. // check permissions
  138. $aSQLPart = array();
  139. $iContextId = (int)bx_get('context_id');
  140. $oPrivacy = BxDolPrivacy::getObjectInstance($this->_oConfig->CNF['OBJECT_PRIVACY_VIEW']);
  141. if($iContextId){
  142. $aSQLPart = $oPrivacy ? $oPrivacy->getContentByGroupAsSQLPart(- $iContextId) : array();
  143. }
  144. // get entries
  145. $aEntries = $this->_oDb->getEntriesByDate(bx_get('start'), bx_get('end'), bx_get('event'), $aSQLPart);
  146. header('Content-Type: application/json; charset=utf-8');
  147. echo json_encode($aEntries);
  148. }
  149. /**
  150. * Data for Timeline module
  151. */
  152. public function serviceGetTimelineData()
  153. {
  154. $sModule = $this->_aModule['name'];
  155. return array(
  156. 'handlers' => array(
  157. array('group' => $sModule . '_object', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'added', 'module_name' => $sModule, 'module_method' => 'get_timeline_post', 'module_class' => 'Module', 'groupable' => 0, 'group_by' => ''),
  158. array('group' => $sModule . '_completed', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'completed', 'module_name' => $sModule, 'module_method' => 'get_timeline_completed', 'module_class' => 'Module', 'groupable' => 0, 'group_by' => ''),
  159. array('group' => $sModule . '_reopened', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'reopened', 'module_name' => $sModule, 'module_method' => 'get_timeline_reopened', 'module_class' => 'Module', 'groupable' => 0, 'group_by' => ''),
  160. array('group' => $sModule . '_object', 'type' => 'update', 'alert_unit' => $sModule, 'alert_action' => 'edited'),
  161. array('group' => $sModule . '_object', 'type' => 'delete', 'alert_unit' => $sModule, 'alert_action' => 'deleted'),
  162. ),
  163. 'alerts' => array(
  164. array('unit' => $sModule, 'action' => 'added'),
  165. array('unit' => $sModule, 'action' => 'completed'),
  166. array('unit' => $sModule, 'action' => 'reopened'),
  167. array('unit' => $sModule, 'action' => 'edited'),
  168. array('unit' => $sModule, 'action' => 'deleted'),
  169. )
  170. );
  171. }
  172. /**
  173. * Entry task for Timeline module
  174. */
  175. public function serviceGetTimelinePost($aEvent, $aBrowseParams = array())
  176. {
  177. $CNF = &$this->_oConfig->CNF;
  178. $aResult = parent::serviceGetTimelinePost($aEvent, $aBrowseParams);
  179. if(empty($aResult) || !is_array($aResult) || empty($aResult['date']))
  180. return $aResult;
  181. $aContentInfo = $this->_oDb->getContentInfoById($aEvent['object_id']);
  182. if($aContentInfo[$CNF['FIELD_PUBLISHED']] > $aResult['date'])
  183. $aResult['date'] = $aContentInfo[$CNF['FIELD_PUBLISHED']];
  184. return $aResult;
  185. }
  186. public function serviceGetTimelineCompleted($aEvent, $aBrowseParams = array())
  187. {
  188. $CNF = &$this->_oConfig->CNF;
  189. $aResult = parent::serviceGetTimelinePost($aEvent, $aBrowseParams);
  190. $aResult['sample_action'] = $aResult['content']['sample_action'] = _t('_bx_tasks_txt_action_completed');
  191. if(empty($aResult) || !is_array($aResult) || empty($aResult['date']))
  192. return $aResult;
  193. $aContentInfo = $this->_oDb->getContentInfoById($aEvent['object_id']);
  194. if($aContentInfo[$CNF['FIELD_PUBLISHED']] > $aResult['date'])
  195. $aResult['date'] = $aContentInfo[$CNF['FIELD_PUBLISHED']];
  196. return $aResult;
  197. }
  198. public function serviceGetTimelineReopened($aEvent, $aBrowseParams = array())
  199. {
  200. $CNF = &$this->_oConfig->CNF;
  201. $aResult = parent::serviceGetTimelinePost($aEvent, $aBrowseParams);
  202. $aResult['sample_action'] = $aResult['content']['sample_action'] = _t('_bx_tasks_txt_action_reopened');
  203. if(empty($aResult) || !is_array($aResult) || empty($aResult['date']))
  204. return $aResult;
  205. $aContentInfo = $this->_oDb->getContentInfoById($aEvent['object_id']);
  206. if($aContentInfo[$CNF['FIELD_PUBLISHED']] > $aResult['date'])
  207. $aResult['date'] = $aContentInfo[$CNF['FIELD_PUBLISHED']];
  208. return $aResult;
  209. }
  210. public function serviceIsCompleted($iContentId)
  211. {
  212. $CNF = &$this->_oConfig->CNF;
  213. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  214. return $aContentInfo[$CNF['FIELD_COMPLETED']] ? false: true;
  215. }
  216. public function serviceEntityAssignments($iContentId = 0, $bAsArray = false)
  217. {
  218. if (!$iContentId)
  219. $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
  220. if (!$iContentId)
  221. return false;
  222. $mixedResult = BxDolConnection::getObjectInstance($this->_oConfig->CNF['OBJECT_CONNECTION'])->getConnectedContent($iContentId);
  223. if(!$bAsArray) {
  224. $s = '';
  225. foreach ($mixedResult as $mixedProfile) {
  226. $bProfile = is_array($mixedProfile);
  227. $oProfile = BxDolProfile::getInstance($bProfile ? (int)$mixedProfile['id'] : (int)$mixedProfile);
  228. if(!$oProfile)
  229. continue;
  230. $aUnitParams = array('template' => array('name' => 'unit', 'size' => 'thumb'));
  231. if($bProfile && is_array($mixedProfile['info']))
  232. $aUnitParams['template']['vars'] = $mixedProfile['info'];
  233. $s .= $oProfile->getUnit(0, $aUnitParams);
  234. }
  235. $mixedResult = $s;
  236. if (!$mixedResult)
  237. return MsgBox(_t('_sys_txt_empty'));
  238. }
  239. return $mixedResult;
  240. }
  241. public function serviceIsUncompleted($iContentId)
  242. {
  243. $CNF = &$this->_oConfig->CNF;
  244. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  245. return $aContentInfo[$CNF['FIELD_COMPLETED']] ? true : false;
  246. }
  247. public function serviceCheckAllowedCommentsTask($iContentId, $sObjectComments)
  248. {
  249. $CNF = &$this->_oConfig->CNF;
  250. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  251. if ($aContentInfo[$CNF['FIELD_DISABLE_COMMENTS']] == 1)
  252. return false;
  253. return parent::serviceCheckAllowedCommentsTask($iContentId, $sObjectComments);
  254. }
  255. public function serviceCheckAllowedCommentsView($iContentId, $sObjectComments)
  256. {
  257. $CNF = &$this->_oConfig->CNF;
  258. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  259. if ($aContentInfo[$CNF['FIELD_DISABLE_COMMENTS']] == 1)
  260. return false;
  261. return parent::serviceCheckAllowedCommentsView($iContentId, $sObjectComments);
  262. }
  263. /**
  264. * @page service Service Calls
  265. * @section bx_tasks Tasks
  266. * @subsection bx_tasks-page_blocks Page Blocks
  267. * @subsubsection bx_tasks-calendar calendar
  268. *
  269. * @code bx_srv('bx_tasks', 'calendar', [...]); @endcode
  270. *
  271. * Shows tasks calendar baced on die date
  272. *
  273. * @param $aData additional data to point which events to show, leave empty to show all events, specify event's ID in 'event' array key to show calendar for one event only, specify context's ID in 'context_id' array key to show calendar for one context events only. If only one event is specified then it will show calendar only if it's repeating event.
  274. * @param $sTemplate template to use to show calendar, or leave empty for default template, possible options: calendar.html, calendar_compact.html
  275. * @return HTML string with calendar to display on the site, all necessary CSS and JS files are automatically added to the HEAD section of the site HTML. On error empty string is returned.
  276. *
  277. * @see BxTasksModule::serviceCalendar
  278. */
  279. /**
  280. * @ref bx_tasks-calendar "calendar"
  281. */
  282. public function serviceCalendar($aData = array(), $sTemplate = 'calendar.html')
  283. {
  284. $o = new BxTemplCalendar(array(
  285. 'eventSources' => array (
  286. bx_append_url_params(BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'calendar_data', $aData),
  287. ),
  288. ), $this->_oTemplate);
  289. return $o->display($sTemplate);
  290. }
  291. public function serviceGetCalendarEntries($iProfileId)
  292. {
  293. $CNF = &$this->_oConfig->CNF;
  294. $oConn = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTION']);
  295. $aData = $oConn->getConnectedInitiators($iProfileId);
  296. $aData2 = array(0);
  297. foreach($aData as $iProfileId2){
  298. $oProfile = BxDolProfile::getInstance($iProfileId2);
  299. array_push($aData2, $oProfile->getContentId());
  300. }
  301. $aSQLPart['where'] = " AND " . $CNF['TABLE_ENTRIES'] . ".`" . $CNF['FIELD_ID'] . "` IN(" . implode(',', $aData2) . ")";
  302. return $this->_oDb->getEntriesByDate(bx_get('start'), bx_get('end'), null, $aSQLPart);
  303. }
  304. public function serviceBrowseContext ($iProfileId = 0, $aParams = array())
  305. {
  306. if(!$iProfileId)
  307. $iProfileId = bx_process_input(bx_get('profile_id'), BX_DATA_INT);
  308. if(!$iProfileId)
  309. return '';
  310. return $this->serviceBrowseTasks (-$iProfileId, $aParams);
  311. }
  312. public function serviceBrowseTasks ($iContextId = 0, $aParams = array())
  313. {
  314. $CNF = &$this->_oConfig->CNF;
  315. $this->_oTemplate->addCssJs();
  316. $aVars = array();
  317. $aLists = $this->_oDb->getLists($iContextId);
  318. $aListsVars = array();
  319. $oConn = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTION']);
  320. $aFilterValues = array();
  321. if (isset($_COOKIE[$CNF['COOKIE_SETTING_KEY']]))
  322. $aFilterValues = json_decode($_COOKIE[$CNF['COOKIE_SETTING_KEY']], true);
  323. foreach($aLists as $aList) {
  324. $aTasks = $this->_oDb->getTasks($iContextId, $aList['id']);
  325. $aTasksVars = array();
  326. foreach($aTasks as $aTask) {
  327. $aMembers = $oConn->getConnectedContent($aTask[$CNF['FIELD_ID']]);
  328. $aMembersVars = array();
  329. foreach($aMembers as $iMember) {
  330. $oProfile = BxDolProfile::getInstance($iMember);
  331. $aMembersVars[] = array('info' => $oProfile->getUnit(0, array('template' => 'unit_wo_info')));
  332. }
  333. $aTasksVars[] = array(
  334. 'id' => $aTask[$CNF['FIELD_ID']],
  335. 'title' => $aTask[$CNF['FIELD_TITLE']],
  336. 'created' => bx_time_js($aTask[$CNF['FIELD_ADDED']]),
  337. 'checked' => $aTask[$CNF['FIELD_COMPLETED']] == 1 ? 'checked' : '',
  338. 'class' => $aTask[$CNF['FIELD_COMPLETED']] == 1 ? 'completed' : 'uncompleted',
  339. 'due' => $aTask[$CNF['FIELD_DUEDATE']] > 0 ? bx_time_js($aTask[$CNF['FIELD_DUEDATE']]) : '',
  340. 'bx_repeat:members' => $aMembersVars,
  341. 'badges' => $this->serviceGetBadges($aTask[$CNF['FIELD_ID']], true),
  342. 'url' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aTask[$CNF['FIELD_ID']]),
  343. 'object' => $this->_oConfig->getJsObject('tasks')
  344. );
  345. }
  346. $sClass = $sCompleted = $sUncompleted = "";
  347. if (isset($aFilterValues[$aList[$CNF['FIELD_ID']]])){
  348. $sClass = $aFilterValues[$aList[$CNF['FIELD_ID']]];
  349. if ($sClass == 'completed')
  350. $sCompleted= 'selected';
  351. if ($sClass == 'uncompleted')
  352. $sUncompleted= 'selected';
  353. }
  354. $aListsVars[] = array(
  355. 'title' => $aList[$CNF['FIELD_TITLE']],
  356. 'id' => $aList['id'],
  357. 'bx_repeat:tasks' => $aTasksVars,
  358. 'context_id' => $iContextId,
  359. 'list_id' => $aList[$CNF['FIELD_ID']],
  360. 'object' => $this->_oConfig->getJsObject('tasks'),
  361. 'class' => $sClass,
  362. 'completed' => $sCompleted,
  363. 'uncompleted' => $sUncompleted,
  364. );
  365. }
  366. $aVars = array(
  367. 'bx_repeat:task_lists' => $aListsVars,
  368. 'context_id' => $iContextId,
  369. 'object' => $this->_oConfig->getJsObject('tasks')
  370. );
  371. $this->_oTemplate->addJs(array(
  372. 'jquery-ui/jquery.ui.widget.min.js',
  373. 'jquery-ui/jquery.ui.menu.min.js',
  374. 'jquery-ui/jquery.ui.autocomplete.min.js',
  375. 'jquery-ui/jquery.ui.core.min.js',
  376. 'tasks.js',
  377. ));
  378. return $this->_oTemplate->getJsCode('tasks') . $this->_oTemplate->parseHtmlByName('browse_tasks.html', $aVars);
  379. }
  380. }
  381. /** @} */