BxCoursesTemplate.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  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. *
  6. * @defgroup Courses Courses
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. /*
  12. * Courses module representation.
  13. */
  14. class BxCoursesTemplate extends BxBaseModGroupsTemplate
  15. {
  16. protected $_iProfileId;
  17. public function __construct(&$oConfig, &$oDb)
  18. {
  19. $this->MODULE = 'bx_courses';
  20. parent::__construct($oConfig, $oDb);
  21. $this->_iProfileId = bx_get_logged_profile_id();
  22. }
  23. public function unit ($aData, $isCheckPrivateContent = true, $mixedTemplate = false, $aParams = [])
  24. {
  25. if(!empty($aParams['context']) && in_array($aParams['context'], ['favorite', 'joined_entries']))
  26. $aParams['template_name'] = 'unit_personal.html';
  27. return parent::unit($aData, $isCheckPrivateContent, $mixedTemplate, $aParams);
  28. }
  29. public function unitVars($aData, $isCheckPrivateContent = true, $mixedTemplate = false, $aParams = [])
  30. {
  31. $CNF = &$this->_oConfig->CNF;
  32. $aVars = parent::unitVars($aData, $isCheckPrivateContent, $mixedTemplate, $aParams);
  33. $bVarsShowProgress = $bVarsShoStats = false;
  34. $aVarsShowProgress = $aVarsShowStats = [true];
  35. if(!empty($aParams['context']) && in_array($aParams['context'], ['favorite', 'joined_entries'])) {
  36. $aLevelToNode = $this->_oConfig->getContentLevel2Node(false);
  37. $sTxtProgress = _t('_bx_courses_txt_n_m_progress');
  38. list($iPassPercent, $aPassDetails, $sPassStatus, $sPassTitle) = $this->_oModule->getEntryPass($this->_iProfileId, $aData[$CNF['FIELD_ID']]);
  39. $bVarsShowProgress = true;
  40. $aVarsShowProgress = [
  41. 'progress' => $iPassPercent
  42. ];
  43. $aTmplVarsCounters = [];
  44. foreach($aPassDetails as $iLevel => $aDetails) {
  45. $aTmplVarsCounters[] = [
  46. 'cn_title' => $aLevelToNode[$iLevel],
  47. 'cn_passed' => $aDetails['passed'],
  48. 'cn_total' => $aDetails['total'],
  49. 'cn_progress' => bx_replace_markers($sTxtProgress, $aDetails)
  50. ];
  51. }
  52. $bVarsShoStats = true;
  53. $aVarsShowStats = [
  54. 'status' => $sPassStatus,
  55. 'bx_repeat:counters' => $aTmplVarsCounters,
  56. 'bx_if:show_pass' => [
  57. 'condition' => $iPassPercent > 0 && $iPassPercent < 100,
  58. 'content' => [
  59. 'pass_link' => $aVars['content_url'],
  60. 'pass_title' => $sPassTitle
  61. ]
  62. ]
  63. ];
  64. }
  65. return array_merge($aVars, [
  66. 'bx_if:show_pass_progress' => [
  67. 'condition' => $bVarsShowProgress,
  68. 'content' => $aVarsShowProgress
  69. ],
  70. 'bx_if:show_pass_stats' => [
  71. 'condition' => $bVarsShoStats,
  72. 'content' => $aVarsShowStats
  73. ]
  74. ]);
  75. }
  76. public function getCounters($aCounters)
  77. {
  78. $aTmplVars = [];
  79. foreach([BX_COURSES_CND_USAGE_ST, BX_COURSES_CND_USAGE_AT] as $iUsage) {
  80. $sUsage = $this->_oConfig->getUsageI2S($iUsage);
  81. $aTmplVarsCounters = [true];
  82. $bTmplVarsCounters = !empty($aCounters[$sUsage]) && is_array($aCounters[$sUsage]);
  83. if($bTmplVarsCounters) {
  84. $aTmplVarsCounters['bx_repeat:counters_' . $sUsage] = [];
  85. foreach($aCounters[$sUsage] as $sModule => $iCount) {
  86. $aCounter = [
  87. 'title' => _t('_' . $sModule),
  88. 'value' => $iCount
  89. ];
  90. if($this->_bIsApi)
  91. $aTmplVars[$sUsage][] = $aCounter;
  92. else
  93. $aTmplVarsCounters['bx_repeat:counters_' . $sUsage][] = $aCounter;
  94. }
  95. }
  96. if($this->_bIsApi)
  97. continue;
  98. $aTmplVars['bx_if:show_' . $sUsage] = [
  99. 'condition' => $bTmplVarsCounters,
  100. 'content' => $aTmplVarsCounters
  101. ];
  102. }
  103. return $this->_bIsApi ? $aTmplVars : $this->parseHtmlByName('counters.html', $aTmplVars);
  104. }
  105. public function getJoinedEntriesSummary($iProfileId)
  106. {
  107. $CNF = &$this->_oConfig->CNF;
  108. $oConnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTIONS']);
  109. if(!$oConnection)
  110. return false;
  111. $aEntries = $oConnection->getConnectedContent($iProfileId);
  112. $iJoined = count($aEntries);
  113. $iStarted = 0;
  114. $iPassed = 0;
  115. foreach($aEntries as $iEntryId) {
  116. $aEntryInfo = $this->_oDb->getContentInfoByProfileId($iEntryId);
  117. list($iPassPercent) = $this->_oModule->getEntryPass($iProfileId, $aEntryInfo[$CNF['FIELD_ID']]);
  118. if($iPassPercent > 0 && $iPassPercent < 100)
  119. $iStarted += 1;
  120. else if($iPassPercent == 100)
  121. $iPassed +=1;
  122. }
  123. $aTmplVars = [
  124. 'joined' => $iJoined,
  125. 'passed' => $iPassed,
  126. 'not_passed' => $iJoined - $iPassed,
  127. 'passed_percent' => $iJoined != 0 ? (int)round(100 * $iPassed/$iJoined) : 0
  128. ];
  129. return $this->_bIsApi ? $aTmplVars : $this->parseHtmlByName('entries_summary.html', $aTmplVars);
  130. }
  131. public function entryStructureByLevel($aContentInfo, $aParams = [])
  132. {
  133. $CNF = &$this->_oConfig->CNF;
  134. if(!isset($aParams['level']))
  135. return '';
  136. $iProfileId = bx_get_logged_profile_id();
  137. $iContentId = (int)$aContentInfo[$CNF['FIELD_ID']];
  138. $bEditable = $this->_oModule->checkAllowedEdit($aContentInfo) === CHECK_ACTION_RESULT_ALLOWED;
  139. $oPermalink = BxDolPermalinks::getInstance();
  140. $iLevel = (int)$aParams['level'];
  141. $iSelected = (int)$aParams['selected'];
  142. $iStart = isset($aParams['start']) ? (int)$aParams['start'] : 0;
  143. $iPerPage = isset($aParams['per_page']) ? (int)$aParams['per_page'] : 2;
  144. $aNodes = $this->_oDb->getContentStructure([
  145. 'sample' => 'entry_id_full',
  146. 'entry_id' => $iContentId,
  147. 'level' => $iLevel,
  148. 'status' => 'active',
  149. 'start' => $iStart,
  150. 'per_page' => $iPerPage ? $iPerPage + 1 : 0
  151. ]);
  152. if(empty($aNodes) || !is_array($aNodes))
  153. return $this->_bIsApi ? [
  154. 'items' => [],
  155. 'isEditable' => $bEditable,
  156. 'entry_id' => $iContentId
  157. ] : '';
  158. $iLevelMax = $this->_oConfig->getContentLevelMax();
  159. $aLevelToNode = $this->_oConfig->getContentLevel2Node(false);
  160. $sTxtProgress = _t('_bx_courses_txt_n_m_progress');
  161. $sTmplKeysSelected = $this->_bIsApi ? 'selected' : 'bx_if:selected';
  162. $sTmplKeysCounters = $this->_bIsApi ? 'counters' : 'bx_repeat:counters';
  163. $aTmplVarsNodes = [];
  164. foreach($aNodes as $iKey => $aNode) {
  165. $aNodeStats = [];
  166. $this->_oModule->getNodePassByChildren($iProfileId, $iContentId, $aNode, $aNodeStats);
  167. $aTmplVarsCounters = [];
  168. for($i = $iLevel + 1; $i <= $iLevelMax; $i++) {
  169. if(!isset($aNodeStats[$i]))
  170. continue;
  171. $aTmplVarsCounters[] = [
  172. 'cn_title' => $aLevelToNode[$i],
  173. 'cn_passed' => $aNodeStats[$i]['passed'],
  174. 'cn_total' => $aNodeStats[$i]['total'],
  175. 'cn_progress' => bx_replace_markers($sTxtProgress, $aNodeStats[$i])
  176. ];
  177. }
  178. $bSelected = $aNode['node_id'] == $iSelected;
  179. $sLink = BX_DOL_URL_ROOT . $oPermalink->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&' . $CNF['FIELD_ID'] . '=' . $iContentId, [
  180. 'parent_id' => $aNode['node_id']
  181. ]);
  182. $aNode = array_merge($aNode, [
  183. $sTmplKeysSelected => $this->_bIsApi ? $bSelected : [
  184. 'condition' => $bSelected,
  185. 'content' => [true]
  186. ],
  187. 'index' => $iKey + 1,
  188. 'link' => $this->_bIsApi ? bx_api_get_relative_url($sLink) : $sLink,
  189. 'percent' => isset($aNodeStats[$iLevelMax]) && ($aStats = $aNodeStats[$iLevelMax]) && $aStats['total'] ? round(100 * $aStats['passed']/$aStats['total']) : 0,
  190. 'status' => $this->_getNodeStatus($iProfileId, $iContentId, $aNode['node_id']),
  191. $sTmplKeysCounters => $aTmplVarsCounters
  192. ]);
  193. $aTmplVarsNodes[] = $this->_bIsApi ? $aNode : [
  194. 'node' => $this->parseHtmlByName('node_l' . $iLevel . '.html', $aNode)
  195. ];
  196. }
  197. if($this->_bIsApi)
  198. return [
  199. 'items' => $aTmplVarsNodes,
  200. 'isEditable' => $bEditable,
  201. 'entry_id' => $iContentId
  202. ];
  203. $oPaginate = new BxTemplPaginate([
  204. 'start' => $iStart,
  205. 'per_page' => $iPerPage,
  206. 'on_change_page' => "return !loadDynamicBlockAutoPaginate(this, '{start}', '{per_page}')"
  207. ]);
  208. $oPaginate->setNumFromDataArray($aTmplVarsNodes);
  209. return $this->parseHtmlByName('nodes_l' . $iLevel . '.html', [
  210. 'level' => $iLevel,
  211. 'bx_repeat:nodes' => $aTmplVarsNodes,
  212. 'paginate' => $oPaginate->getSimplePaginate()
  213. ]);
  214. }
  215. /**
  216. * For 1 level bases structure ( Max Level = 1)
  217. */
  218. public function entryStructureByParentMl1($aContentInfo, $aParams = [])
  219. {
  220. $CNF = &$this->_oConfig->CNF;
  221. $iContentId = (int)$aContentInfo[$CNF['FIELD_ID']];
  222. $iParentId = isset($aParams['parent_id']) ? (int)$aParams['parent_id'] : 0;
  223. $iProfileId = bx_get_logged_profile_id();
  224. $aNodes = $this->_oDb->getContentStructure([
  225. 'sample' => 'entry_id_full',
  226. 'entry_id' => $iContentId,
  227. 'parent_id' => $iParentId,
  228. 'status' => 'active'
  229. ]);
  230. if((empty($aNodes) || !is_array($aNodes)) && !$this->_bIsApi)
  231. return '';
  232. $sJsObject = $this->_oConfig->getJsObject('entry');
  233. $oPermalink = BxDolPermalinks::getInstance();
  234. $iLevelMax = $this->_oConfig->getContentLevelMax();
  235. $sTmplKeysShowPass = $this->_bIsApi ? 'show_pass' : 'bx_if:show_pass';
  236. $aTmplVarsNodes = [];
  237. foreach($aNodes as $iKey => $aNode) {
  238. list($iPassPercent, $sPassProgress, $sPassStatus, $sPassTitle) = $this->_oModule->getNodePassByData($iProfileId, $iContentId, $aNode);
  239. $sLink = BX_DOL_URL_ROOT . $oPermalink->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY_NODE'] . '&id=' . $iContentId, [
  240. 'node_id' => $aNode['node_id']
  241. ]);
  242. $bShowPass = !empty($sPassTitle);
  243. $aNode = array_merge($aNode, [
  244. 'level_max' => $iLevelMax,
  245. 'index' => $iKey + 1,
  246. 'link' => $sLink,
  247. 'pass_percent' => $iPassPercent,
  248. 'pass_progress' => $sPassProgress,
  249. 'pass_status' => $sPassStatus,
  250. $sTmplKeysShowPass => $this->_bIsApi ? $bShowPass : [
  251. 'condition' => $bShowPass,
  252. 'content' => [
  253. 'js_object' => $sJsObject,
  254. 'id' => $aNode['node_id'],
  255. 'pass_href' => $sLink,
  256. 'pass_title' => $sPassTitle,
  257. ]
  258. ]
  259. ]);
  260. if($this->_bIsApi) {
  261. if(!empty($aNode['counters']) && ($aCounters = json_decode($aNode['counters'], true)))
  262. $aNode['counters'] = $this->getCounters($aCounters);
  263. $aNode = array_merge($aNode, [
  264. 'link' => bx_api_get_relative_url($aNode['link']),
  265. 'pass_title' => $sPassTitle,
  266. 'pass_callback' => $this->MODULE . '/pass_node&params[]=' . $aNode['node_id'],
  267. ]);
  268. }
  269. $aTmplVarsNodes[] = $this->_bIsApi ? $aNode : [
  270. 'node' => $this->parseHtmlByName('ml' . $iLevelMax . '_node_l' . $aNode['level'] . '.html', $aNode)
  271. ];
  272. }
  273. if($this->_bIsApi)
  274. return [
  275. 'items' => $aTmplVarsNodes,
  276. 'isEditable' => $this->_oModule->checkAllowedEdit($aContentInfo) === CHECK_ACTION_RESULT_ALLOWED,
  277. 'entry_id' => $iContentId,
  278. 'parent_id' => $iParentId
  279. ];
  280. return $this->parseHtmlByName('ml' . $iLevelMax . '_nodes_l' . $aNode['level'] . '.html', [
  281. 'level_max' => $iLevelMax,
  282. 'level' => $aNode['level'],
  283. 'bx_repeat:nodes' => $aTmplVarsNodes
  284. ]);
  285. }
  286. /**
  287. * For 2 levels bases structure ( Max Level = 2)
  288. */
  289. public function entryStructureByParentMl2($aContentInfo, $aParams = [])
  290. {
  291. if(empty($aParams['parent_id']))
  292. return $this->_bIsApi ? [] : '';
  293. return $this->entryStructureByParentMl1($aContentInfo, $aParams);
  294. }
  295. /**
  296. * For 3 levels bases structure ( Max Level = 3)
  297. */
  298. public function entryStructureByParentMl3($aContentInfo, $aParams = [])
  299. {
  300. $CNF = &$this->_oConfig->CNF;
  301. if(empty($aParams['parent_id']))
  302. return $this->_bIsApi ? [] : '';
  303. $iContentId = (int)$aContentInfo[$CNF['FIELD_ID']];
  304. $iParentId = (int)$aParams['parent_id'];
  305. $iProfileId = bx_get_logged_profile_id();
  306. $aNodes = $this->_oDb->getContentStructure([
  307. 'sample' => 'entry_id_full',
  308. 'entry_id' => $iContentId,
  309. 'parent_id' => $iParentId,
  310. 'status' => 'active'
  311. ]);
  312. if(empty($aNodes) || !is_array($aNodes))
  313. return $this->_bIsApi ? [] : '';
  314. $sJsObject = $this->_oConfig->getJsObject('entry');
  315. $oPermalink = BxDolPermalinks::getInstance();
  316. $iLevelMax = $this->_oConfig->getContentLevelMax();
  317. $aInputs = [];
  318. foreach($aNodes as $aNode) {
  319. $aInputs['node_' . $aNode['node_id']] = [
  320. 'type' => 'block_header',
  321. 'caption' => bx_process_output($aNode['title']),
  322. 'collapsed' => false,
  323. 'attrs' => ['id' => 'node_' . $aNode['node_id'], 'class' => ''],
  324. ];
  325. $aSubNodes = $this->_oDb->getContentStructure([
  326. 'sample' => 'entry_id_full',
  327. 'entry_id' => $iContentId,
  328. 'parent_id' => (int)$aNode['node_id'],
  329. 'status' => 'active'
  330. ]);
  331. if(!empty($aSubNodes) && is_array($aSubNodes)) {
  332. $sTmplKeysShowPass = $this->_bIsApi ? 'show_pass' : 'bx_if:show_pass';
  333. $aTmplVarsNodes = [];
  334. foreach($aSubNodes as $iKey => $aSubNode) {
  335. list($iPassPercent, $sPassProgress, $sPassStatus, $sPassTitle) = $this->_oModule->getNodePassByData($iProfileId, $iContentId, $aSubNode);
  336. $sLink = BX_DOL_URL_ROOT . $oPermalink->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY_NODE'] . '&id=' . $iContentId, [
  337. 'node_id' => $aSubNode['node_id']
  338. ]);
  339. $bShowPass = !empty($sPassTitle);
  340. $aSubNode = array_merge($aSubNode, [
  341. 'level_max' => $iLevelMax,
  342. 'index' => $iKey + 1,
  343. 'link' => $this->_bIsApi ? bx_api_get_relative_url($sLink) : $sLink,
  344. 'pass_percent' => $iPassPercent,
  345. 'pass_progress' => $sPassProgress,
  346. 'pass_status' => $sPassStatus,
  347. $sTmplKeysShowPass => $this->_bIsApi ? $bShowPass : [
  348. 'condition' => $sPassTitle,
  349. 'content' => [
  350. 'js_object' => $sJsObject,
  351. 'id' => $aSubNode['node_id'],
  352. 'pass_href' => $sLink,
  353. 'pass_title' => $sPassTitle,
  354. ]
  355. ]
  356. ]);
  357. $aTmplVarsNodes[] = $this->_bIsApi ? $aSubNode : [
  358. 'node' => $this->parseHtmlByName('ml3_node_l' . $aSubNode['level'] . '.html', $aSubNode)
  359. ];
  360. }
  361. $sInput = 'node_' . $aNode['node_id'] . '_subnodes';
  362. $aInputs[$sInput] = [
  363. 'type' => 'custom',
  364. 'name' => $sInput,
  365. 'caption' => '',
  366. 'content' => $this->_bIsApi ? $aTmplVarsNodes : $this->parseHtmlByName('ml3_nodes_l' . $aSubNode['level'] . '.html', [
  367. 'level_max' => $iLevelMax,
  368. 'level' => $aSubNode['level'],
  369. 'bx_repeat:nodes' => $aTmplVarsNodes
  370. ]),
  371. ];
  372. }
  373. else
  374. $aInputs['node_' . $aNode['node_id']]['collapsed'] = true;
  375. }
  376. $oForm = new BxTemplFormView([
  377. 'form_attrs' => [
  378. 'id' => 'bx-courses-structure-by-parent-' . $iParentId,
  379. ],
  380. 'inputs' => $aInputs,
  381. ]);
  382. $oForm->setShowEmptySections(true);
  383. return $this->_bIsApi ? $oForm->getCodeAPI() : $oForm->getCode();
  384. }
  385. public function entryNode($aContentInfo, $aParams = [])
  386. {
  387. $CNF = &$this->_oConfig->CNF;
  388. if(!isset($aParams['node_id']))
  389. return '';
  390. $iContentId = (int)$aContentInfo[$CNF['FIELD_ID']];
  391. $iNodeId = (int)$aParams['node_id'];
  392. $iUsage = isset($aParams['usage']) && $aParams['usage'] !== false ? (int)$aParams['usage'] : BX_COURSES_CND_USAGE_ST;
  393. $iProfileId = bx_get_logged_profile_id();
  394. $aNode = $this->_oDb->getContentNodes([
  395. 'sample' => 'id_full',
  396. 'id' => $iNodeId,
  397. ]);
  398. $aTmplVars = [
  399. 'index' => $aNode['order'],
  400. 'sample' => $this->_oConfig->getContentNodeTitle($aNode['level']),
  401. 'title' => $aNode['title'],
  402. 'text' => $aNode['text'],
  403. 'passing' => $aNode['passing']
  404. ];
  405. if($this->_bIsApi)
  406. return array_merge($aTmplVars, [
  407. 'steps' => $this->_entryNodeItems($iProfileId, $iContentId, $aNode, BX_COURSES_CND_USAGE_ST),
  408. 'attachments' => $this->_entryNodeItems($iProfileId, $iContentId, $aNode, BX_COURSES_CND_USAGE_AT)
  409. ]);
  410. else
  411. $aTmplVars['bx_repeat:items'] = $this->_entryNodeItems($iProfileId, $iContentId, $aNode, $iUsage);
  412. $sMiName = 'node-data-';
  413. $sMiLink = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY_NODE'] . '&id=' . $iContentId, [
  414. 'node_id' => $iNodeId,
  415. 'usage' => ''
  416. ]);
  417. $oMenu = new BxTemplMenu([
  418. 'template' => 'menu_block_submenu_ver.html',
  419. 'menu_id'=> 'node-data',
  420. 'menu_items' => [
  421. ['id' => $sMiName . 'st', 'name' => $sMiName . 'st', 'class' => '', 'link' => $sMiLink . '0', 'target' => '_self', 'title' => _t('_bx_courses_menu_item_title_node_data_steps')],
  422. ['id' => $sMiName . 'at', 'name' => $sMiName . 'at', 'class' => '', 'link' => $sMiLink . '1', 'target' => '_self', 'title' => _t('_bx_courses_menu_item_title_node_data_attachments')]
  423. ]
  424. ]);
  425. $oMenu->setSelected('', $sMiName . $this->_oConfig->getUsageI2S($iUsage));
  426. return [
  427. 'content' => $this->parseHtmlByName('node_view.html', $aTmplVars),
  428. 'menu' => $oMenu
  429. ];
  430. }
  431. public function entryData($aData, $sView)
  432. {
  433. $sJsObject = $this->_oConfig->getJsObject('entry');
  434. $aNode = $this->_oDb->getContentNodes([
  435. 'sample' => 'id',
  436. 'id' => $aData['node_id']
  437. ]);
  438. $iOrder = (int)$aData['order'];
  439. $aSiblings = $this->_oDb->getContentData([
  440. 'sample' => 'siblings',
  441. 'entry_id' => $aData['entry_id'],
  442. 'node_id' => $aData['node_id'],
  443. 'usage' => BX_COURSES_CND_USAGE_ST,
  444. 'order' => $iOrder
  445. ]);
  446. $bTmplVarsBack = false;
  447. $aTmplVarsBack = ($iOrderB = $iOrder - 1) && ($bTmplVarsBack = !empty($aSiblings[$iOrderB]) && is_array($aSiblings[$iOrderB])) ? [
  448. 'js_object' => $sJsObject,
  449. 'id_back' => $aSiblings[$iOrderB]['id']
  450. ] : [true];
  451. $bTmplVarsNext = false;
  452. $aTmplVarsNext = ($iOrderN = $iOrder + 1) && ($bTmplVarsNext = !empty($aSiblings[$iOrderN]) && is_array($aSiblings[$iOrderN])) ? [
  453. 'js_object' => $sJsObject,
  454. 'id_next' => $aSiblings[$iOrderN]['id']
  455. ] : [true];
  456. return ['popup' => [
  457. 'html' => BxTemplFunctions::getInstance()->popupBox($this->_oConfig->getHtmlIds('popup_content_data'), $aNode['title'], $this->parseHtmlByName('node_data_view.html', [
  458. 'js_object' => $sJsObject,
  459. 'view' => $sView,
  460. 'bx_if:show_back' => [
  461. 'condition' => $bTmplVarsBack,
  462. 'content' => $aTmplVarsBack
  463. ],
  464. 'bx_if:show_next' => [
  465. 'condition' => $bTmplVarsNext,
  466. 'content' => $aTmplVarsNext
  467. ]
  468. ]), true),
  469. 'options' => [
  470. 'onHide' => 'document.location = document.location'
  471. ]
  472. ]];
  473. }
  474. protected function _entryNodeItems($iProfileId, $iContentId, $aNode, $iUsage)
  475. {
  476. $sJsObject = $this->_oConfig->getJsObject('entry');
  477. $aDataItems = $this->_oDb->getContentData([
  478. 'sample' => 'entry_node_ids',
  479. 'entry_id' => $iContentId,
  480. 'node_id' => $aNode['id'],
  481. 'usage' => $iUsage
  482. ]);
  483. $sTxtUndefined = _t('_undefined');
  484. $sTxtPass = _t('_bx_courses_txt_pass');
  485. $bUsageSt = $iUsage == BX_COURSES_CND_USAGE_ST;
  486. $bUsageAt = $iUsage == BX_COURSES_CND_USAGE_AT;
  487. $aResults = [];
  488. if(!empty($aDataItems) && is_array($aDataItems))
  489. foreach($aDataItems as $iIndex => $aDataItem) {
  490. $sImageUrl = '';
  491. if(($sMethod = 'get_thumb') && bx_is_srv($aDataItem['content_type'], $sMethod))
  492. $sImageUrl = bx_srv($aDataItem['content_type'], $sMethod, [$aDataItem['content_id']]);
  493. $sVideoUrl = '';
  494. if(($sMethod = 'get_video') && bx_is_srv($aDataItem['content_type'], $sMethod))
  495. $sVideoUrl = bx_srv($aDataItem['content_type'], $sMethod, [$aDataItem['content_id']]);
  496. $sLink = '';
  497. if(($sMethod = 'get_link') && bx_is_srv($aDataItem['content_type'], $sMethod))
  498. $sLink = bx_srv($aDataItem['content_type'], $sMethod, [$aDataItem['content_id']]);
  499. $bPassed = $bUsageSt && $this->_oModule->isDataPassed($iProfileId, $aDataItem);
  500. $aTmplVarsPass = [true];
  501. $bTmplVarsPass = $bUsageSt && !$bPassed && $sLink && ((int)$aNode['passing'] == BX_COURSES_CND_PASSING_ALL || $iIndex == 0 || $this->_oModule->isDataPassed($iProfileId, $aDataItems[$iIndex - 1]));
  502. if($bTmplVarsPass) {
  503. $aTmplVarsPass = [
  504. 'js_object' => $sJsObject,
  505. 'id' => $aDataItem['id'],
  506. 'link' => $sLink,
  507. 'title' => $sTxtPass
  508. ];
  509. }
  510. $sType = _t('_bx_courses_txt_data_type_' . $aDataItem['content_type']);
  511. $sTitle = '';
  512. if(($sMethod = 'get_title') && bx_is_srv($aDataItem['content_type'], $sMethod))
  513. $sTitle = bx_srv($aDataItem['content_type'], $sMethod, [$aDataItem['content_id']]);
  514. if(!$sTitle && ($sMethod = 'get_text') && bx_is_srv($aDataItem['content_type'], $sMethod))
  515. $sTitle = bx_srv($aDataItem['content_type'], $sMethod, [$aDataItem['content_id']]);
  516. if(!$sTitle)
  517. $sTitle = $sTxtUndefined;
  518. $bTmplVarsShowLink = $bUsageAt && $sLink;
  519. $aTmplVarsShowLink = $bTmplVarsShowLink ? [
  520. 'link' => $sLink,
  521. 'title' => $sTitle
  522. ] : false;
  523. $bTmplVarsShowSize = $aTmplVarsShowSize = false;
  524. $bTmplVarsShowDownload = $aTmplVarsShowDownload = false;
  525. if($bUsageAt && ($bTmplVarsShowSize = ($sMethod = 'get_file') && bx_is_srv($aDataItem['content_type'], $sMethod))) {
  526. $aFileInfo = bx_srv($aDataItem['content_type'], $sMethod, [$aDataItem['content_id']]);
  527. if(!empty($aFileInfo) && is_array($aFileInfo)) {
  528. $aTmplVarsShowSize = [
  529. 'size' => _t_format_size($aFileInfo['size'])
  530. ];
  531. if(($bTmplVarsShowDownload = !empty($aFileInfo['url_download'])))
  532. $aTmplVarsShowDownload = [
  533. 'link' => $aFileInfo['url_download']
  534. ];
  535. }
  536. }
  537. if($this->_bIsApi) {
  538. $sText = '';
  539. if(($sMethod = 'get_text') && bx_is_srv($aDataItem['content_type'], $sMethod))
  540. $sText = bx_srv($aDataItem['content_type'], $sMethod, [$aDataItem['content_id']]);
  541. $aResults[] = array_merge([
  542. 'id' => $aDataItem['id'],
  543. 'type' => $sType,
  544. 'title' => $sTitle,
  545. 'text' => $sText,
  546. 'image' => $sImageUrl,
  547. 'video' => $sVideoUrl
  548. ], ($bUsageSt ? [
  549. 'pass_link' => $bTmplVarsPass ? bx_api_get_relative_url($sLink) : '',
  550. 'pass_title' => $sTxtPass,
  551. 'passed' => $bPassed
  552. ] : [
  553. 'size' => $bTmplVarsShowSize ? $aTmplVarsShowSize['size'] : '',
  554. 'view_link' => $bTmplVarsShowLink ? bx_api_get_relative_url($sLink) : '',
  555. 'download_link' => $bTmplVarsShowDownload ? $aTmplVarsShowDownload['link'] : '',
  556. ]));
  557. }
  558. else
  559. $aResults[] = [
  560. 'bx_if:show_image' => [
  561. 'condition' => $sImageUrl,
  562. 'content' => [
  563. 'image' => $sImageUrl
  564. ]
  565. ],
  566. 'bx_if:show_image_empty' => [
  567. 'condition' => !$sImageUrl,
  568. 'content' => [
  569. 'type' => $sType
  570. ]
  571. ],
  572. 'bx_if:show_video' => [
  573. 'condition' => $sVideoUrl,
  574. 'content' => [
  575. 'video' => $sVideoUrl
  576. ]
  577. ],
  578. 'type' => $sType,
  579. 'bx_if:show_link' => [
  580. 'condition' => $bTmplVarsShowLink,
  581. 'content' => $aTmplVarsShowLink
  582. ],
  583. 'bx_if:show_text' => [
  584. 'condition' => !$bTmplVarsShowLink,
  585. 'content' => [
  586. 'title' => $sTitle,
  587. ]
  588. ],
  589. 'bx_if:show_size' => [
  590. 'condition' => $bTmplVarsShowSize,
  591. 'content' => $aTmplVarsShowSize
  592. ],
  593. 'bx_if:show_pass' => [
  594. 'condition' => $bTmplVarsPass,
  595. 'content' => $aTmplVarsPass
  596. ],
  597. 'bx_if:show_download' => [
  598. 'condition' => $bTmplVarsShowDownload,
  599. 'content' => $aTmplVarsShowDownload
  600. ],
  601. ];
  602. }
  603. return $aResults;
  604. }
  605. protected function _getNodeStatus($iProfileId, $iContentId, $iNodeId)
  606. {
  607. if($this->_oModule->isNodePassed($iProfileId, $iNodeId))
  608. return _t('_bx_courses_txt_status_completed');
  609. if($this->_oModule->isNodeStarted($iProfileId, $iNodeId))
  610. return _t('_bx_courses_txt_status_in_process');
  611. return _t('_bx_courses_txt_status_not_started');
  612. }
  613. }
  614. /** @} */