BxTimelineMenuItemActions.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  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 Timeline Timeline
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. /**
  12. * 'Item' menu.
  13. */
  14. class BxTimelineMenuItemActions extends BxTemplMenuCustom
  15. {
  16. protected static $_sModeActions = 'actions';
  17. protected static $_sModeCounters = 'counters';
  18. protected $_sModule;
  19. protected $_oModule;
  20. protected $_iEvent;
  21. protected $_aEvent;
  22. protected $_sType;
  23. protected $_sView;
  24. protected $_bIsApi;
  25. protected $_sMode;
  26. protected $_bShowTitles;
  27. protected $_bShowCounters;
  28. protected $_bShowCountersEmpty;
  29. protected $_bShowCountersIcons;
  30. protected $_sTmplNameItem;
  31. protected $_aItem2CheckFunc;
  32. public function __construct($aObject, $oTemplate = false)
  33. {
  34. $this->_sModule = 'bx_timeline';
  35. $this->_oModule = BxDolModule::getInstance($this->_sModule);
  36. parent::__construct($aObject, $this->_oModule->_oTemplate);
  37. $this->_setBrowseParams();
  38. $this->_bIsApi = bx_is_api();
  39. $this->_sMode = self::$_sModeActions;
  40. $this->_bShowTitles = true;
  41. $this->_bShowCounters = false;
  42. $this->_bShowCountersEmpty = false;
  43. $this->_bShowCountersIcons = true;
  44. $this->_sTmplNameItem = 'menu_custom_item_hor.html';
  45. $this->_aItem2CheckFunc = array(
  46. 'item-view' => 'isAllowedViewCounter',
  47. 'item-comment' => 'isAllowedComment',
  48. 'item-vote' => 'isAllowedVote',
  49. 'item-reaction' => 'isAllowedReaction',
  50. 'item-score' => 'isAllowedScore',
  51. 'item-report' => 'isAllowedReport',
  52. 'item-mute' => 'isAllowedMute',
  53. 'item-more' => 'isAllowedMore',
  54. 'item-pin' => 'isAllowedPin',
  55. 'item-unpin' => 'isAllowedUnpin',
  56. 'item-stick' => 'isAllowedStick',
  57. 'item-unstick' => 'isAllowedUnstick',
  58. 'item-promote' => 'isAllowedPromote',
  59. 'item-unpromote' => 'isAllowedUnpromote',
  60. 'item-edit' => 'isAllowedEdit',
  61. 'item-delete' => 'isAllowedDelete',
  62. 'item-notes' => 'isAllowedNotes',
  63. );
  64. }
  65. public function setEvent($aEvent, $aBrowseParams = array())
  66. {
  67. if(empty($aEvent) || !is_array($aEvent))
  68. return false;
  69. $this->_aEvent = $aEvent;
  70. $this->_iEvent = (int)$this->_aEvent['id'];
  71. $sType = $this->_aEvent['type'];
  72. $sAction = $this->_aEvent['action'];
  73. $this->_setBrowseParams($aBrowseParams);
  74. //--- Comment item
  75. $iCommentsObject = 0;
  76. $sCommentsSystem = $sCommentsOnclick = '';
  77. if(isset($aEvent['comments']) && is_array($aEvent['comments']) && isset($aEvent['comments']['system'])) {
  78. $sCommentsSystem = $aEvent['comments']['system'];
  79. $iCommentsObject = $aEvent['comments']['object_id'];
  80. $sCommentsOnclick = bx_replace_markers("{js_object_view}.commentItem(this, '" . $sCommentsSystem . "', " . $iCommentsObject . ")", $this->_aMarkers);
  81. }
  82. //--- Repost item
  83. $iOwnerId = $this->_oModule->getUserId(); //--- in whose timeline the content will be reposted
  84. $iObjectId = $this->_oModule->_oConfig->isSystem($sType, $sAction) ? $this->_aEvent['object_id'] : $this->_aEvent['id'];
  85. $sRepostOnclick = $this->_oModule->serviceGetRepostJsClick($iOwnerId, $sType, $sAction, $iObjectId);
  86. $bSystem = $this->_oModule->_oConfig->isSystem($sType, $sAction);
  87. $this->addMarkers(array(
  88. 'content_id' => $this->_iEvent,
  89. 'comment_system' => $sCommentsSystem,
  90. 'comment_object' => $iCommentsObject,
  91. 'comment_onclick' => $sCommentsOnclick,
  92. 'repost_onclick' => $sRepostOnclick,
  93. 'delete_title' => _t('_bx_timeline_menu_item_title_item_delete_' . ($bSystem || $this->_oModule->_oConfig->isHideUponDelete() ? 'system' : 'common'))
  94. ));
  95. return true;
  96. }
  97. public function setEventById($iEventId, $aBrowseParams = array())
  98. {
  99. $aEvent = $this->_oModule->_oDb->getEvents(array('browse' => 'id', 'value' => $iEventId));
  100. if(empty($aEvent) || !is_array($aEvent))
  101. return;
  102. $aEventData = $this->_oModule->_oTemplate->getDataCached($aEvent);
  103. if($aEventData === false)
  104. return;
  105. $aEvent['views'] = $aEventData['views'];
  106. $aEvent['votes'] = $aEventData['votes'];
  107. $aEvent['reactions'] = $aEventData['reactions'];
  108. $aEvent['scores'] = $aEventData['scores'];
  109. $aEvent['reports'] = $aEventData['reports'];
  110. $aEvent['comments'] = $aEventData['comments'];
  111. $this->setEvent($aEvent, $aBrowseParams);
  112. }
  113. public function setTemplateNameItem($sName)
  114. {
  115. $this->_sTmplNameItem = $sName;
  116. }
  117. protected function _setBrowseParams($aBrowseParams = array())
  118. {
  119. $this->_sType = !empty($aBrowseParams['type']) ? $aBrowseParams['type'] : BX_TIMELINE_TYPE_DEFAULT;
  120. $this->_sView = !empty($aBrowseParams['view']) ? $aBrowseParams['view'] : BX_TIMELINE_VIEW_DEFAULT;
  121. $aMarkers = array();
  122. foreach($aBrowseParams as $sKey => $mixedValue)
  123. if(!is_array($mixedValue))
  124. $aMarkers[$sKey] = $mixedValue;
  125. $this->addMarkers($aMarkers);
  126. $this->addMarkers(array(
  127. 'js_object_view' => $this->_oModule->_oConfig->getJsObjectView($aBrowseParams)
  128. ));
  129. }
  130. protected function _getMenuItemItemView($aItem)
  131. {
  132. if(!isset($this->_aEvent['views']) || !is_array($this->_aEvent['views']) || !isset($this->_aEvent['views']['system']))
  133. return false;
  134. $sViewsSystem = $this->_aEvent['views']['system'];
  135. $iViewsObject = $this->_aEvent['views']['object_id'];
  136. $aViewsParams = array(
  137. 'show_do_view_label' => $this->_bShowTitles,
  138. 'show_counter' => $this->_bShowCounters,
  139. 'show_counter_label_icon' => $this->_bShowCountersIcons,
  140. 'dynamic_mode' => $this->_bDynamicMode
  141. );
  142. switch($this->_sMode) {
  143. case self::$_sModeActions:
  144. $sViewsMethod = 'getElementInline';
  145. break;
  146. case self::$_sModeCounters:
  147. $sViewsMethod = 'getCounter';
  148. break;
  149. }
  150. $oObject = $this->_oModule->getViewObject($sViewsSystem, $iViewsObject);
  151. if($this->_bIsApi)
  152. return $this->_getMenuItemElementApi($aItem, $oObject->getElementApi(array_merge($aViewsParams, [
  153. 'show_counter' => true,
  154. ])));
  155. return $oObject->$sViewsMethod($aViewsParams);
  156. }
  157. protected function _getMenuItemItemComment($aItem)
  158. {
  159. /**
  160. * For now use the default link (not Object based) for non-api calls.
  161. */
  162. if(!$this->_bIsApi)
  163. return true;
  164. if(!isset($this->_aEvent['comments']) || !is_array($this->_aEvent['comments']) || !isset($this->_aEvent['comments']['system']))
  165. return false;
  166. $sCommentsSystem = $this->_aEvent['comments']['system'];
  167. $iCommentsObject = $this->_aEvent['comments']['object_id'];
  168. $aCommentsParams = array(
  169. 'show_do_comment_label' => $this->_bShowTitles,
  170. 'show_counter' => $this->_bShowCounters,
  171. 'show_counter_empty' => $this->_bShowCountersEmpty,
  172. 'show_counter_label_icon' => $this->_bShowCountersIcons,
  173. 'dynamic_mode' => $this->_bDynamicMode
  174. );
  175. switch($this->_sMode) {
  176. case self::$_sModeActions:
  177. $sCommentsMethod = 'getElementInline';
  178. break;
  179. case self::$_sModeCounters:
  180. $sCommentsMethod = 'getCounter';
  181. break;
  182. }
  183. $oObject = $this->_oModule->getCmtsObject($sCommentsSystem, $iCommentsObject);
  184. if($this->_bIsApi)
  185. return $this->_getMenuItemElementApi($aItem, $oObject->getElementApi(array_merge($aCommentsParams, [
  186. 'show_counter' => true,
  187. ])));
  188. return $oObject->$sCommentsMethod($aCommentsParams);
  189. }
  190. protected function _getMenuItemItemVote($aItem)
  191. {
  192. if(!isset($this->_aEvent['votes']) || !is_array($this->_aEvent['votes']) || !isset($this->_aEvent['votes']['system']))
  193. return false;
  194. $sVotesSystem = $this->_aEvent['votes']['system'];
  195. $iVotesObject = $this->_aEvent['votes']['object_id'];
  196. $aVotesParams = array(
  197. 'show_do_vote_label' => $this->_bShowTitles,
  198. 'show_counter' => $this->_bShowCounters,
  199. 'show_counter_empty' => $this->_bShowCountersEmpty,
  200. 'show_counter_label_icon' => $this->_bShowCountersIcons,
  201. 'dynamic_mode' => $this->_bDynamicMode
  202. );
  203. switch($this->_sMode) {
  204. case self::$_sModeActions:
  205. $sVotesMethod = 'getElementInline';
  206. break;
  207. case self::$_sModeCounters:
  208. $sVotesMethod = 'getCounter';
  209. break;
  210. }
  211. $oObject = $this->_oModule->getVoteObject($sVotesSystem, $iVotesObject);
  212. if($this->_bIsApi)
  213. return $this->_getMenuItemElementApi($aItem, $oObject->getElementApi(array_merge($aVotesParams, [
  214. 'show_counter' => true,
  215. ])));
  216. return $oObject->$sVotesMethod($aVotesParams);
  217. }
  218. protected function _getMenuItemItemReaction($aItem)
  219. {
  220. if(!isset($this->_aEvent['reactions']) || !is_array($this->_aEvent['reactions']) || !isset($this->_aEvent['reactions']['system']))
  221. return false;
  222. $sReactionsSystem = $this->_aEvent['reactions']['system'];
  223. $iReactionsObject = $this->_aEvent['reactions']['object_id'];
  224. $aReactionsParams = array(
  225. 'show_do_vote_label' => $this->_bShowTitles,
  226. 'show_counter' => $this->_bShowCounters,
  227. 'show_counter_empty' => $this->_bShowCountersEmpty,
  228. 'show_counter_style' => 'compound',
  229. 'show_counter_label_icon' => $this->_bShowCountersIcons,
  230. 'dynamic_mode' => $this->_bDynamicMode
  231. );
  232. switch($this->_sMode) {
  233. case self::$_sModeActions:
  234. $sReactionsMethod = 'getElementInline';
  235. break;
  236. case self::$_sModeCounters:
  237. $sReactionsMethod = 'getCounter';
  238. break;
  239. }
  240. $oObject = $this->_oModule->getReactionObject($sReactionsSystem, $iReactionsObject);
  241. if($this->_bIsApi)
  242. return $this->_getMenuItemElementApi($aItem, $oObject->getElementApi(array_merge($aReactionsParams, [
  243. 'show_counter' => true,
  244. ])));
  245. return $oObject->$sReactionsMethod($aReactionsParams);
  246. }
  247. protected function _getMenuItemItemScore($aItem)
  248. {
  249. if(!isset($this->_aEvent['scores']) || !is_array($this->_aEvent['scores']) || !isset($this->_aEvent['scores']['system']))
  250. return false;
  251. $sScoresSystem = $this->_aEvent['scores']['system'];
  252. $iScoresObject = $this->_aEvent['scores']['object_id'];
  253. $aScoresParams = array(
  254. 'show_do_vote_label' => $this->_bShowTitles,
  255. 'show_counter' => $this->_bShowCounters,
  256. 'show_counter_empty' => $this->_bShowCountersEmpty,
  257. 'show_counter_label_icon' => $this->_bShowCountersIcons,
  258. 'dynamic_mode' => $this->_bDynamicMode
  259. );
  260. switch($this->_sMode) {
  261. case self::$_sModeActions:
  262. $sScoresMethod = 'getElementInline';
  263. break;
  264. case self::$_sModeCounters:
  265. $sScoresMethod = 'getCounter';
  266. break;
  267. }
  268. $oObject = $this->_oModule->getScoreObject($sScoresSystem, $iScoresObject);
  269. if($this->_bIsApi)
  270. return $this->_getMenuItemElementApi($aItem, $oObject->getElementApi(array_merge($aScoresParams, [
  271. 'show_counter' => true,
  272. ])));
  273. return $oObject->$sScoresMethod($aScoresParams);
  274. }
  275. protected function _getMenuItemItemReport($aItem)
  276. {
  277. if(!isset($this->_aEvent['reports']) || !is_array($this->_aEvent['reports']) || !isset($this->_aEvent['reports']['system']))
  278. return false;
  279. $sReportsSystem = $this->_aEvent['reports']['system'];
  280. $iReportsObject = $this->_aEvent['reports']['object_id'];
  281. $aReportsParams = array(
  282. 'show_do_report_label' => $this->_bShowTitles,
  283. 'show_counter' => $this->_bShowCounters,
  284. 'dynamic_mode' => $this->_bDynamicMode
  285. );
  286. switch($this->_sMode) {
  287. case self::$_sModeActions:
  288. $sReportsMethod = 'getElementInline';
  289. break;
  290. case self::$_sModeCounters:
  291. $sReportsMethod = 'getCounter';
  292. break;
  293. }
  294. $oObject = $this->_oModule->getReportObject($sReportsSystem, $iReportsObject);
  295. if($this->_bIsApi)
  296. return $this->_getMenuItemElementApi($aItem, $oObject->getElementApi(array_merge($aReportsParams, [
  297. 'show_counter' => true,
  298. ])));
  299. return $oObject->$sReportsMethod($aReportsParams);
  300. }
  301. protected function _getMenuItemItemRepost($aItem)
  302. {
  303. if(!isset($this->_aEvent['reposts']))
  304. return false;
  305. $aRepostsParams = [
  306. 'show_do_repost_text' => $this->_bShowTitles,
  307. 'show_counter' => $this->_bShowCounters,
  308. 'show_counter_label_icon' => $this->_bShowCountersIcons,
  309. 'dynamic_mode' => $this->_bDynamicMode
  310. ];
  311. $iOwnerId = $this->_aEvent['owner_id'];
  312. $sType = $this->_aEvent['type'];
  313. $sAction = $this->_aEvent['action'];
  314. $iObjectId = $this->_oModule->_oConfig->isSystem($sType, $sAction) ? $this->_aEvent['object_id'] : $this->_aEvent['id'];
  315. $iAuthorId = $this->_oModule->getUserId();
  316. if($this->_oModule->isReposted($iAuthorId, $iOwnerId, $sType, $sAction, $iObjectId))
  317. return false;
  318. if($this->_bIsApi)
  319. return [
  320. 'id' => $aItem['id'],
  321. 'name' => $aItem['name'],
  322. 'display_type' => 'element',
  323. 'data' => $this->_oModule->serviceGetRepostElementBlockApi($iOwnerId, $sType, $sAction, $iObjectId, $aRepostsParams)
  324. ];
  325. $sMethodName = '';
  326. $aMethodParams = [];
  327. switch($this->_sMode) {
  328. case self::$_sModeActions:
  329. $sMethodName = 'serviceGetRepostElementBlock';
  330. $aMethodParams = [$iOwnerId, $sType, $sAction, $iObjectId, $aRepostsParams];
  331. break;
  332. case self::$_sModeCounters:
  333. $sMethodName = 'serviceGetRepostCounter';
  334. $aMethodParams = [$sType, $sAction, $iObjectId, $aRepostsParams];
  335. break;
  336. }
  337. return call_user_func_array([$this->_oModule, $sMethodName], $aMethodParams);
  338. }
  339. protected function _getMenuItemDefault ($aItem)
  340. {
  341. if(!isset($aItem['class_link']))
  342. $aItem['class_link'] = '';
  343. $aItem['class_link'] = 'bx-menu-item-link' . (!empty($aItem['class_link']) ? ' ' : '') . $aItem['class_link'];
  344. return parent::_getMenuItemDefault ($aItem);
  345. }
  346. protected function _getMenuItemDefaultApi ($aItem)
  347. {
  348. if(!empty($aItem['submenu']) && ($oSubmenu = BxDolMenu::getObjectInstance($aItem['submenu'])) !== false) {
  349. $sMethod = 'setEventById';
  350. if(method_exists($oSubmenu, $sMethod))
  351. $oSubmenu->$sMethod($this->_iEvent);
  352. $aItem = array_merge($aItem, [
  353. 'content_type' => 'submenu',
  354. 'submenu' => $oSubmenu->getCodeAPI()
  355. ]);
  356. }
  357. switch($aItem['name'] ?? '') {
  358. case 'item-pin':
  359. case 'item-unpin':
  360. $aItem = $this->_getMenuItemCallbackApi($aItem, 'pin');
  361. break;
  362. case 'item-stick':
  363. case 'item-unstick':
  364. $aItem = $this->_getMenuItemCallbackApi($aItem, 'stick');
  365. break;
  366. case 'item-promote':
  367. case 'item-unpromote':
  368. $aItem = $this->_getMenuItemCallbackApi($aItem, 'promote');
  369. break;
  370. }
  371. return $aItem;
  372. }
  373. protected function _getMenuItemCallbackApi($aItem, $sService)
  374. {
  375. if(!empty($aItem['link']) && strpos($aItem['link'], 'javascript:') === 0)
  376. $aItem['link'] = '';
  377. return array_merge($aItem, [
  378. 'display_type' => 'callback',
  379. 'data' => [
  380. 'request_url' => $this->_sModule . '/' . $sService . '/&params[]=' . $this->_iEvent
  381. ]
  382. ]);
  383. }
  384. protected function _getMenuItemElementApi($aItem, $aElement)
  385. {
  386. if(!$this->_bIsApi)
  387. return $aItem;
  388. return [
  389. 'id' => $aItem['id'],
  390. 'name' => $aItem['name'],
  391. 'display_type' => 'element',
  392. 'data' => $aElement
  393. ];
  394. }
  395. /**
  396. * Check if menu items is visible.
  397. * @param $a menu item array
  398. * @return boolean
  399. */
  400. protected function _isVisible ($a)
  401. {
  402. if(!parent::_isVisible($a) || empty($this->_aEvent) || !is_array($this->_aEvent))
  403. return false;
  404. $sCheckFuncName = '';
  405. $aCheckFuncParams = array($this->_aEvent);
  406. switch ($a['name']) {
  407. case 'item-comment':
  408. if($this->_sView == BX_TIMELINE_VIEW_ITEM && !$this->_bIsApi)
  409. return false;
  410. $sCheckFuncName = $this->_aItem2CheckFunc[$a['name']];
  411. break;
  412. case 'item-pin':
  413. if($this->_sType != BX_BASE_MOD_NTFS_TYPE_OWNER)
  414. return false;
  415. $sCheckFuncName = $this->_aItem2CheckFunc[$a['name']];
  416. break;
  417. case 'item-unpin':
  418. if($this->_sType != BX_BASE_MOD_NTFS_TYPE_OWNER)
  419. return false;
  420. $sCheckFuncName = $this->_aItem2CheckFunc[$a['name']];
  421. break;
  422. }
  423. if(empty($sCheckFuncName) && isset($this->_aItem2CheckFunc[$a['name']]))
  424. $sCheckFuncName = $this->_aItem2CheckFunc[$a['name']];
  425. if(!$sCheckFuncName || !method_exists($this->_oModule, $sCheckFuncName))
  426. return true;
  427. return call_user_func_array(array($this->_oModule, $sCheckFuncName), $aCheckFuncParams) === true;
  428. }
  429. protected function _getTmplContentItem()
  430. {
  431. if(empty($this->_sTmplNameItem))
  432. return parent::_getTmplContentItem();
  433. return $this->_oModule->_oTemplate->getHtml($this->_sTmplNameItem);
  434. }
  435. }
  436. /** @} */