BxTasksTemplate.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  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. require_once('BxTasksMenuTimer.php');
  11. class BxTasksTemplate extends BxBaseModTextTemplate
  12. {
  13. public function __construct(&$oConfig, &$oDb)
  14. {
  15. $this->MODULE = 'bx_tasks';
  16. parent::__construct($oConfig, $oDb);
  17. }
  18. public function getJsCode($sType, $aParams = [], $mixedWrap = true)
  19. {
  20. $aParams = array_merge([
  21. 'aHtmlIds' => $this->_oConfig->getHtmlIds()
  22. ], $aParams);
  23. return parent::getJsCode($sType, $aParams, $mixedWrap);
  24. }
  25. public function getJsCodeTimer($sType, $aParams = [], $mixedWrap = true)
  26. {
  27. $aParams = array_merge([
  28. 'aHtmlIds' => $this->_oConfig->getHtmlIds()
  29. ], $aParams);
  30. if(is_array($mixedWrap))
  31. return parent::getJsCode($sType, $aParams, [
  32. 'wrap' => true,
  33. 'mask' => "{var} {object} = new {class}({params}); {object}.init({content_id}, {profile_id}, {started});",
  34. 'mask_markers' => $mixedWrap
  35. ]);
  36. else
  37. parent::getJsCode($sType, $aParams, $mixedWrap);
  38. }
  39. public function getBlockMenuBrowse()
  40. {
  41. $CNF = &$this->_oConfig->CNF;
  42. $iProfileId = bx_get_logged_profile_id();
  43. $sMenuManage = '';
  44. if(($oMenu = BxDolMenu::getObjectInstance($CNF['OBJECT_MENU_MANAGE_TOOLS_SUBMENU'])) !== false)
  45. $sMenuManage = $oMenu->getCode();
  46. $sMenuBrowse = '';
  47. if(($oMenu = BxDolMenu::getObjectInstance($CNF['OBJECT_MENU_BROWSE'])) !== false) {
  48. $oMenu->setProfileId($iProfileId);
  49. $sMenuBrowse = $oMenu->getCode();
  50. }
  51. return $this->parseHtmlByName('menu_browse.html', [
  52. 'bx_if:show_menu_manage' => [
  53. 'condition' => $sMenuManage != '',
  54. 'content' => [
  55. 'menu_manage' => $sMenuManage
  56. ]
  57. ],
  58. 'bx_if:show_menu_browse' => [
  59. 'condition' => $sMenuBrowse != '',
  60. 'content' => [
  61. 'menu_browse' => $sMenuBrowse
  62. ]
  63. ]
  64. ]);
  65. }
  66. /**
  67. * Use Gallery image for both because currently there is no Unit types with small thumbnails.
  68. */
  69. protected function getUnitThumbAndGallery ($aData)
  70. {
  71. list($sPhotoThumb, $sPhotoGallery) = parent::getUnitThumbAndGallery($aData);
  72. return array($sPhotoGallery, $sPhotoGallery);
  73. }
  74. public function entryText ($aData, $sTemplateName = 'entry-text.html')
  75. {
  76. $CNF = &$this->_oConfig->CNF;
  77. $iContentId = (int)$aData[$CNF['FIELD_ID']];
  78. $sResult = '';
  79. if(!$this->_oModule->isAllowManage($iContentId)) {
  80. $aVars = $this->getTmplVarsText($aData);
  81. $sResult = $this->parseHtmlByName($sTemplateName, $aVars);
  82. }
  83. else
  84. $sResult = $this->getModule()->serviceEntityEdit($iContentId, $CNF['OBJECT_FORM_ENTRY_DISPLAY_EDIT_BODY']);
  85. return $sResult;
  86. }
  87. public function entryAssignments ($aProfiles)
  88. {
  89. $CNF = &$this->_oConfig->CNF;
  90. $aTmplVarsProfiles = [];
  91. foreach($aProfiles as $mixedProfile) {
  92. $bProfile = is_array($mixedProfile);
  93. $oProfile = BxDolProfile::getInstance($bProfile ? (int)$mixedProfile['id'] : (int)$mixedProfile);
  94. if(!$oProfile)
  95. continue;
  96. $aUnitParams = ['template' => ['name' => 'unit', 'size' => 'thumb']];
  97. if($bProfile && is_array($mixedProfile['info']))
  98. $aUnitParams['template']['vars'] = $mixedProfile['info'];
  99. $aTmplVarsProfiles[] = [
  100. 'unit' => $oProfile->getUnit(0, $aUnitParams)
  101. ];
  102. }
  103. return $aTmplVarsProfiles ? $this->parseHtmlByName('entry-assignments.html', [
  104. 'bx_repeat:profiles' => $aTmplVarsProfiles
  105. ]) : MsgBox(_t('_sys_txt_empty'));
  106. }
  107. public function entryTimer ($iContentId, $iProfileId)
  108. {
  109. $this->addCss(['timer.css']);
  110. $this->addJs(['timer.js']);
  111. return $this->getTimer($iContentId, $iProfileId) . $this->getJsCodeTimer('timer', [], [
  112. 'content_id' => $iContentId,
  113. 'profile_id' => $iProfileId,
  114. 'started' => $this->_oDb->isTimerStarted($iContentId, $iProfileId),
  115. ]);
  116. }
  117. public function getBlockTimers ($iProfileId)
  118. {
  119. $CNF = &$this->_oConfig->CNF;
  120. $oModule = $this->getModule();
  121. $sJsObject = $this->_oConfig->getJsObject('timer');
  122. $aTimers = $this->_oDb->getTimers(['sample' => 'profile_id', 'profile_id' => $iProfileId]);
  123. if(!$aTimers || !is_array($aTimers))
  124. return MsgBox(_t('_Empty'));
  125. $oPermalinks = BxDolPermalinks::getInstance();
  126. $aTmplVarsSections = [];
  127. foreach($aTimers as $aTimer) {
  128. $aContentInfo = $this->_oDb->getContentInfoById($aTimer['content_id']);
  129. if(!$aContentInfo && !is_array($aContentInfo))
  130. continue;
  131. $sContextType = $sContextTitle = $sContextUrl = '';
  132. if(($iAllowViewTo = (int)$aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]) < 0 && ($oContext = BxDolProfile::getInstance(abs($iAllowViewTo))) !== false) {
  133. $sContextType = $oContext->getModule();
  134. $sContextTitle = $oContext->getDisplayName();
  135. $sContextUrl = $oContext->getUrl();
  136. }
  137. if(!isset($aTmplVarsSections[$sContextType]))
  138. $aTmplVarsSections[$sContextType] = [
  139. 'section_title' => $oModule->getModuleTitle($sContextType),
  140. 'bx_repeat:timers' => []
  141. ];
  142. $aTmplVarsSections[$sContextType]['bx_repeat:timers'][] = [
  143. 'bx_if:show_context' => [
  144. 'condition' => $sContextTitle && $sContextUrl,
  145. 'content' => [
  146. 'title' => $sContextTitle,
  147. 'url' => $sContextUrl
  148. ]
  149. ],
  150. 'content_title' => $aContentInfo[$CNF['FIELD_TITLE']],
  151. 'content_url' => bx_absolute_url($oPermalinks->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']])),
  152. 'timer' => $this->getTimer($aTimer['content_id'], $iProfileId),
  153. 'js_code_timer' => $sJsObject . '.init(' . $aTimer['content_id'] . ', ' . $iProfileId . ', ' . ($aTimer['started'] != 0 ? 1 : 0) . ');'
  154. ];
  155. }
  156. $this->addCss(['timer.css']);
  157. $this->addJs(['timer.js']);
  158. return $this->parseHtmlByName('browse_timers.html', [
  159. 'js_code' => $this->getJsCode('timer', [
  160. 'bMulti' => true
  161. ]),
  162. 'bx_repeat:sections' => array_values($aTmplVarsSections)
  163. ]);
  164. }
  165. public function getTimer ($iContentId, $iProfileId)
  166. {
  167. $CNF = &$this->_oConfig->CNF;
  168. $sPrefix = str_replace('_', '-', $this->_oConfig->getName());
  169. $sJsObject = $this->_oConfig->getJsObject('timer');
  170. $aTimer = $this->_oDb->getTimers(['sample' => 'content_profile_ids', 'content_id' => $iContentId, 'profile_id' => $iProfileId]);
  171. $bTimer = $aTimer && is_array($aTimer);
  172. $bStarted = $bTimer && (int)$aTimer['started'] > 0;
  173. $iHours = $iMinutes = $iSeconds = 0;
  174. if($bTimer) {
  175. $iDuration = (int)$aTimer['duration'];
  176. if($bStarted)
  177. $iDuration += time() - (int)$aTimer['started'];
  178. list($iHours, $iMinutes, $iSeconds) = $this->_oConfig->timeI2A($iDuration, true);
  179. }
  180. $oActions = new BxTasksMenuTimer([
  181. 'object' => $sPrefix . '_timer',
  182. 'template' => 'menu_custom_hor.html',
  183. 'menu_id' => $this->_oConfig->getHtmlIds('timer_actions'),
  184. 'persistent' => 0
  185. ]);
  186. $oActions->setParams($iContentId, $iProfileId);
  187. return $this->parseHtmlByName('entry-timer.html', [
  188. 'html_id' => $this->_oConfig->getHtmlIds('timer') . $iContentId . '-' . $iProfileId,
  189. 'hours' => sprintf("%02d", $iHours),
  190. 'minutes' => sprintf("%02d", $iMinutes),
  191. 'seconds' => sprintf("%02d", $iSeconds),
  192. 'actions' => $oActions->getCode()
  193. ]);
  194. }
  195. public function getEntriesList($iContextId, $aParams = [])
  196. {
  197. $CNF = &$this->_oConfig->CNF;
  198. $sJsObject = $this->_oConfig->getJsObject('tasks');
  199. $oModule = $this->getModule();
  200. $_iContextId = abs($iContextId);
  201. $bAllowAdd = $oModule->isAllowAdd($_iContextId);
  202. $bAllowManage = $oModule->isAllowManageByContext($_iContextId);
  203. $aTmplVarsFilterItems = [];
  204. $aFilters = [];
  205. if(($sK = $CNF['COOKIE_SETTING_KEY']) && isset($_COOKIE[$sK]))
  206. $aFilters = json_decode($_COOKIE[$sK], true);
  207. $iFilterSelected = $aParams['filter'] ?? ($aFilters[$iContextId] ?? 0);
  208. $aFilterItems = array_merge([['id' => 0, 'title' => '_bx_tasks_filter_title_select']], $this->_oDb->getFilters(['sample' => 'active']));
  209. foreach($aFilterItems as $aFilterItem)
  210. $aTmplVarsFilterItems[] = [
  211. 'filter_id' => $aFilterItem['id'],
  212. 'filter_title' => _t($aFilterItem['title']),
  213. 'bx_if:show_filter_selected' => [
  214. 'condition' => $aFilterItem['id'] == $iFilterSelected,
  215. 'content' => [true]
  216. ]
  217. ];
  218. $this->addCssJs();
  219. $this->addJs([
  220. 'jquery-ui/jquery-ui.min.js',
  221. 'tasks.js',
  222. 'modules/base/general/js/|forms.js'
  223. ]);
  224. return $this->parseHtmlByName('browse_tasks.html', [
  225. 'bx_if:show_filters' => [
  226. 'condition' => !empty($aTmplVarsFilterItems),
  227. 'content' => [
  228. 'object' => $sJsObject,
  229. 'context_id' => $iContextId,
  230. 'bx_repeat:filter_items' => $aTmplVarsFilterItems
  231. ]
  232. ],
  233. 'bx_if:allow_add_list' => [
  234. 'condition' => $bAllowAdd,
  235. 'content' => [
  236. 'context_id' => $iContextId,
  237. 'object' => $sJsObject,
  238. ]
  239. ],
  240. 'bx_if:allow_manage_settings' => [
  241. 'condition' => $bAllowManage,
  242. 'content' => [
  243. 'context_id' => $iContextId,
  244. 'object' => $sJsObject,
  245. ]
  246. ],
  247. 'tasks' => $this->getEntries($iContextId, array_merge($aParams, [
  248. 'filter' => $iFilterSelected,
  249. ])),
  250. 'js_code' => $this->getJsCode('tasks', ['t_confirm_block_deletion' => _t('_bx_tasks_txt_msg_confirm_tasklist_deletion')])
  251. ]);
  252. }
  253. public function getEntries($iContextId, $aParams = [])
  254. {
  255. $CNF = &$this->_oConfig->CNF;
  256. $sJsObject = $this->_oConfig->getJsObject('tasks');
  257. $oModule = $this->getModule();
  258. $oPermalinks = BxDolPermalinks::getInstance();
  259. $oConnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTION']);
  260. $aTypes = BxDolFormQuery::getDataItems($CNF['OBJECT_PRE_LIST_TYPES']);
  261. $aPriorities = BxDolFormQuery::getDataItems($CNF['OBJECT_PRE_LIST_PRIORITIES']);
  262. $aStates = BxDolFormQuery::getDataItems($CNF['OBJECT_PRE_LIST_STATES']);
  263. $_iContextId = abs($iContextId);
  264. $bAllowAdd = $oModule->isAllowAdd($_iContextId);
  265. $bAllowManage = $oModule->isAllowManageByContext($_iContextId);
  266. $aTmplVarsLists = [];
  267. $aLists = $this->_oDb->getLists($iContextId);
  268. foreach($aLists as $aList) {
  269. $aTasks = $this->_oDb->getTasks($iContextId, $aList['id'], array_merge($aParams, [
  270. 'with_stats' => true
  271. ]));
  272. $aTmplVarsTasks = [];
  273. foreach($aTasks as $aTask) {
  274. $sTime = '';
  275. if(!empty($aTask['time_total']))
  276. $sTime = _t('_bx_tasks_txt_total', $this->_oConfig->timeI2S($aTask['time_total']) . (!empty($aTask['time']) ? ' (' . $this->_oConfig->timeI2S($aTask['time']) . ')' : ''));
  277. if(!empty($aTask['estimate']))
  278. $sTime .= ' ' . _t('_bx_tasks_txt_estimate', $this->_oConfig->timeI2S(60 * (int)$aTask['estimate']));
  279. $aMembers = $oConnection->getConnectedInitiators($aTask[$CNF['FIELD_ID']]);
  280. $aTmplVarsMembers = [];
  281. foreach($aMembers as $iMember)
  282. if(($oProfile = BxDolProfile::getInstance($iMember)) !== false && !($oProfile instanceof BxDolProfileUndefined))
  283. $aTmplVarsMembers[] = ['info' => $oProfile->getUnit(0, ['template' => 'unit_wo_info'])];
  284. $bCompleted = $aTask[$CNF['FIELD_COMPLETED']] == 1;
  285. $aTmplVarsTasks[] = [
  286. 'id' => $aTask[$CNF['FIELD_ID']],
  287. 'title' => bx_process_output($aTask[$CNF['FIELD_TITLE']]),
  288. 'created' => bx_time_js($aTask[$CNF['FIELD_ADDED']]),
  289. 'class' => $bCompleted ? 'completed' : 'uncompleted',
  290. 'due' => $aTask[$CNF['FIELD_DUE_DATE']] > 0 ? bx_time_js($aTask[$CNF['FIELD_DUE_DATE']]) : '',
  291. 'type' => $aTypes[$aTask[$CNF['FIELD_TYPE']]] ?? '',
  292. 'priority' => $aPriorities[$aTask[$CNF['FIELD_PRIORITY']]] ?? '',
  293. 'state' => $aStates[$aTask[$CNF['FIELD_STATE']]] ?? '',
  294. 'time' => $sTime,
  295. 'bx_repeat:members' => $aTmplVarsMembers,
  296. 'badges' => $oModule->serviceGetBadges($aTask[$CNF['FIELD_ID']], true),
  297. 'url' => bx_absolute_url($oPermalinks->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aTask[$CNF['FIELD_ID']])),
  298. 'object' => $sJsObject,
  299. 'bx_if:allow_manage' => [
  300. 'condition' => $bAllowManage,
  301. 'content' => [
  302. 'id' => $aTask[$CNF['FIELD_ID']],
  303. 'object' => $sJsObject,
  304. 'checked' => $bCompleted ? 'checked' : '',
  305. ]
  306. ],
  307. 'bx_if:deny_manage' => [
  308. 'condition' => !$bAllowManage,
  309. 'content' => [
  310. 'id' => $aTask[$CNF['FIELD_ID']],
  311. 'checked' => $bCompleted ? 'checked' : '',
  312. ]
  313. ]
  314. ];
  315. }
  316. $sClass = $sCompleted = $sAll = "";
  317. if (isset($aFilterValues[$aList[$CNF['FIELD_ID']]])){
  318. $sClass = $aFilterValues[$aList[$CNF['FIELD_ID']]];
  319. if ($sClass == 'completed')
  320. $sCompleted= 'selected';
  321. if ($sClass == 'all')
  322. $sAll = 'selected';
  323. }
  324. $aTmplVarsLists[] = [
  325. 'bx_if:allow_edit_list' => [
  326. 'condition' => $bAllowAdd,
  327. 'content' => [
  328. 'title' => $aList[$CNF['FIELD_TITLE']],
  329. 'context_id' => $iContextId,
  330. 'list_id' => $aList[$CNF['FIELD_ID']],
  331. 'object' => $sJsObject,
  332. ]
  333. ],
  334. 'bx_if:allow_add' => [
  335. 'condition' => $bAllowAdd,
  336. 'content' => [
  337. 'context_id' => $iContextId,
  338. 'list_id' => $aList[$CNF['FIELD_ID']],
  339. 'object' => $sJsObject,
  340. ]
  341. ],
  342. 'bx_if:allow_delete_list' => [
  343. 'condition' => $bAllowManage,
  344. 'content' => [
  345. 'context_id' => $iContextId,
  346. 'list_id' => $aList[$CNF['FIELD_ID']],
  347. 'object' => $sJsObject,
  348. ]
  349. ],
  350. 'bx_if:deny_edit_list' => [
  351. 'condition' => !$bAllowAdd,
  352. 'content' => [
  353. 'title' => $aList[$CNF['FIELD_TITLE']],
  354. ]
  355. ],
  356. 'id' => $aList['id'],
  357. 'bx_repeat:tasks' => $aTmplVarsTasks,
  358. 'context_id' => $iContextId,
  359. 'list_id' => $aList[$CNF['FIELD_ID']],
  360. 'object' => $sJsObject
  361. ];
  362. }
  363. return $this->parseHtmlByName('tasks.html', [
  364. 'html_id' => $this->_oConfig->getHtmlIds('tasks'),
  365. 'bx_repeat:task_lists' => $aTmplVarsLists,
  366. ]);
  367. }
  368. }
  369. /** @} */