BxTimelineTemplate.php 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068
  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. class BxTimelineTemplate extends BxBaseModNotificationsTemplate
  12. {
  13. function __construct(&$oConfig, &$oDb)
  14. {
  15. parent::__construct($oConfig, $oDb);
  16. }
  17. public function getCssJs()
  18. {
  19. parent::getCssJs();
  20. $this->addCss(array(
  21. BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'flickity/|flickity.css',
  22. 'jquery-ui/jquery-ui.css',
  23. 'post.css',
  24. 'share.css',
  25. ));
  26. $this->addJs(array(
  27. 'jquery-ui/jquery-ui.custom.min.js',
  28. 'jquery.form.min.js',
  29. 'jquery.ba-resize.min.js',
  30. 'autosize.min.js',
  31. 'masonry.pkgd.min.js',
  32. 'flickity/flickity.pkgd.min.js',
  33. 'post.js',
  34. 'share.js',
  35. ));
  36. }
  37. public function getPostBlock($iOwnerId)
  38. {
  39. $aForm = $this->getModule()->getFormPost();
  40. return $this->parseHtmlByName('block_post.html', array (
  41. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  42. 'js_object' => $this->_oConfig->getJsObject('post'),
  43. 'js_content' => $this->getJsCode('post', array(
  44. 'oRequestParams' => array('owner_id' => $iOwnerId)
  45. )),
  46. 'form' => $aForm['form']
  47. ));
  48. }
  49. public function getViewBlock($aParams)
  50. {
  51. list($sContent, $sLoadMore, $sBack) = $this->getPosts($aParams);
  52. return $this->parseHtmlByName('block_view.html', array(
  53. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  54. 'html_id' => $this->_oConfig->getHtmlIds('view', 'main_' . $aParams['view']),
  55. 'view' => $aParams['view'],
  56. 'back' => $sBack,
  57. 'content' => $sContent,
  58. 'load_more' => $sLoadMore,
  59. 'view_image_popup' => $this->_getImagePopup($aParams),
  60. 'js_content' => $this->getJsCode('view', array(
  61. 'oRequestParams' => array(
  62. 'type' => $aParams['type'],
  63. 'owner_id' => $aParams['owner_id'],
  64. 'start' => $aParams['start'],
  65. 'per_page' => $aParams['per_page'],
  66. 'filter' => $aParams['filter'],
  67. 'modules' => $aParams['modules'],
  68. 'timeline' => $aParams['timeline'],
  69. )
  70. )) . $this->getJsCode('share')
  71. ));
  72. }
  73. public function getItemBlock($iId)
  74. {
  75. $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
  76. if(empty($aEvent))
  77. return '';
  78. $aParams = array(
  79. 'view' => BX_TIMELINE_VIEW_DEFAULT,
  80. 'type' => BX_TIMELINE_TYPE_ITEM
  81. );
  82. $sContent = $this->getJsCode('view');
  83. $sContent .= $this->getPost($aEvent, $aParams);
  84. $sContent .= $this->_getImagePopup($aParams);
  85. return $sContent;
  86. }
  87. public function getPost(&$aEvent, $aBrowseParams = array())
  88. {
  89. $aResult = $this->_oConfig->isSystem($aEvent['type'], $aEvent['action']) ? $this->_getSystemData($aEvent) : $this->_getCommonData($aEvent);
  90. if(empty($aResult) || empty($aResult['owner_id']) || empty($aResult['content']))
  91. return '';
  92. list($sUserName) = $this->getModule()->getUserInfo($aResult['owner_id']);
  93. if(empty($aEvent['title']) || empty($aEvent['description'])) {
  94. $sTitle = !empty($aResult['title']) ? $aResult['title'] : '';
  95. if($sTitle == '') {
  96. $sSample = !empty($aResult['content']['sample']) ? $aResult['content']['sample'] : '_bx_timeline_txt_sample';
  97. $sTitle = _t('_bx_timeline_txt_user_added_sample', $sUserName, _t($sSample));
  98. }
  99. $sDescription = !empty($aResult['description']) ? $aResult['description'] : '';
  100. if($sDescription == '' && !empty($aResult['content']['text']))
  101. $sDescription = $aResult['content']['text'];
  102. $this->_oDb->updateEvent(array(
  103. 'title' => bx_process_input(strip_tags($sTitle)),
  104. 'description' => bx_process_input(strip_tags($sDescription))
  105. ), array('id' => $aEvent['id']));
  106. }
  107. $aEvent['object_owner_id'] = $aResult['owner_id'];
  108. $aEvent['icon'] = !empty($aResult['icon']) ? $aResult['icon'] : '';
  109. $aEvent['content'] = $aResult['content'];
  110. $aEvent['votes'] = $aResult['votes'];
  111. $aEvent['reports'] = $aResult['reports'];
  112. $aEvent['comments'] = $aResult['comments'];
  113. $sType = !empty($aResult['content_type']) ? $aResult['content_type'] : BX_TIMELINE_PARSE_TYPE_DEFAULT;
  114. return $this->_getPost($sType, $aEvent, $aBrowseParams);
  115. }
  116. public function getPosts($aParams)
  117. {
  118. $bViewTimeline = $aParams['view'] == BX_TIMELINE_VIEW_TIMELINE;
  119. $iStart = $aParams['start'];
  120. $iPerPage = $aParams['per_page'];
  121. $aParamsDb = $aParams;
  122. //--- Check for Previous
  123. $iDays = -1;
  124. $bPrevious = false;
  125. if($iStart - 1 >= 0) {
  126. $aParamsDb['start'] -= 1;
  127. $aParamsDb['per_page'] += 1;
  128. $bPrevious = true;
  129. }
  130. //--- Check for Next
  131. $aParamsDb['per_page'] += 1;
  132. $aEvents = $this->_oDb->getEvents($aParamsDb);
  133. //--- Check for Previous
  134. if($bPrevious) {
  135. $aEvent = array_shift($aEvents);
  136. $iDays = (int)$aEvent['days'];
  137. }
  138. //--- Check for Next
  139. $bNext = false;
  140. if(count($aEvents) > $iPerPage) {
  141. $aEvent = array_pop($aEvents);
  142. $bNext = true;
  143. }
  144. $iEvents = count($aEvents);
  145. $sContent = $this->getEmpty($iEvents <= 0);
  146. if($bViewTimeline && $iEvents <= 0)
  147. $sContent .= $this->getDividerToday();
  148. $bFirst = true;
  149. foreach($aEvents as $aEvent) {
  150. $sEvent = $this->getPost($aEvent, $aParams);
  151. $bEvent = !empty($sEvent);
  152. if(!$bEvent)
  153. continue;
  154. if($bViewTimeline && $bFirst) {
  155. $sContent .= $this->getDividerToday($aEvent);
  156. $bFirst = false;
  157. }
  158. $sContent .= $bViewTimeline && $bEvent ? $this->getDivider($iDays, $aEvent) : '';
  159. $sContent .= $sEvent;
  160. }
  161. $sBack = $this->getBack($aParams);
  162. $sLoadMore = $this->getLoadMore($aParams, $bNext, $iEvents > 0);
  163. return array($sContent, $sLoadMore, $sBack);
  164. }
  165. public function getEmpty($bVisible)
  166. {
  167. return $this->parseHtmlByName('empty.html', array(
  168. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  169. 'visible' => $bVisible ? 'block' : 'none',
  170. 'content' => MsgBox(_t('_bx_timeline_txt_msg_no_results'))
  171. ));
  172. }
  173. public function getDivider(&$iDays, &$aEvent)
  174. {
  175. if($iDays == $aEvent['days'])
  176. return "";
  177. $iDays = $aEvent['days'];
  178. $iDaysAgo = (int)$aEvent['ago_days'];
  179. if($aEvent['today'] == $aEvent['days'] || (($aEvent['today'] - $aEvent['days']) == 1 && $iDaysAgo == 0))
  180. return "";
  181. return $this->parseHtmlByName('divider.html', array(
  182. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  183. 'type' => 'common',
  184. 'bx_if:show_hidden' => array(
  185. 'condition' => false,
  186. 'content' => array()
  187. ),
  188. 'content' => bx_time_js($aEvent['date'])
  189. ));
  190. }
  191. public function getDividerToday($aEvent = array())
  192. {
  193. $bToday = !empty($aEvent) && ($aEvent['today'] == $aEvent['days'] || (($aEvent['today'] - $aEvent['days']) == 1 && (int)$aEvent['ago_days'] == 0));
  194. return $this->parseHtmlByName('divider.html', array(
  195. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  196. 'type' => 'today',
  197. 'bx_if:show_hidden' => array(
  198. 'condition' => !$bToday,
  199. 'content' => array()
  200. ),
  201. 'content' => _t('_bx_timeline_txt_today')
  202. ));
  203. }
  204. public function getBack($aParams)
  205. {
  206. $iYearSel = (int)$aParams['timeline'];
  207. if($iYearSel == 0)
  208. return '';
  209. $sStylePrefix = $this->_oConfig->getPrefix('style');
  210. $sJsObject = $this->_oConfig->getJsObject('view');
  211. $iYearNow = date('Y', time());
  212. return $this->parseHtmlByName('back.html', array(
  213. 'style_prefix' => $sStylePrefix,
  214. 'href' => 'javascript:void(0)',
  215. 'title' => _t('_bx_timeline_txt_jump_to_n_year', $iYearNow),
  216. 'bx_repeat:attrs' => array(
  217. array('key' => 'onclick', 'value' => 'javascript:' . $sJsObject . '.changeTimeline(this, 0)')
  218. ),
  219. 'content' => _t('_bx_timeline_txt_jump_to_recent')
  220. ));
  221. }
  222. public function getLoadMore($aParams, $bEnabled, $bVisible = true)
  223. {
  224. $iStart = $aParams['start'];
  225. $iPerPage = $aParams['per_page'];
  226. $iYearSel = (int)$aParams['timeline'];
  227. $iYearMin = $this->_oDb->getMaxDuration($aParams);
  228. $sStylePrefix = $this->_oConfig->getPrefix('style');
  229. $sJsObject = $this->_oConfig->getJsObject('view');
  230. $sYears = '';
  231. if(!empty($iYearMin)) {
  232. $iYearMax = date('Y', time()) - 1;
  233. for($i = $iYearMax; $i >= $iYearMin; $i--)
  234. $sYears .= ($i != $iYearSel ? $this->parseHtmlByName('bx_a.html', array(
  235. 'href' => 'javascript:void(0)',
  236. 'title' => _t('_bx_timeline_txt_jump_to_n_year', $i),
  237. 'bx_repeat:attrs' => array(
  238. array('key' => 'onclick', 'value' => 'javascript:' . $sJsObject . '.changeTimeline(this, ' . $i . ')')
  239. ),
  240. 'content' => $i
  241. )) : $i) . ', ';
  242. $sYears = substr($sYears, 0, -2);
  243. }
  244. $aTmplVars = array(
  245. 'style_prefix' => $sStylePrefix,
  246. 'visible' => ($aParams['view'] == BX_TIMELINE_VIEW_TIMELINE && $bVisible) || ($aParams['view'] == BX_TIMELINE_VIEW_OUTLINE && $bEnabled && $bVisible) ? 'block' : 'none',
  247. 'bx_if:is_disabled' => array(
  248. 'condition' => !$bEnabled,
  249. 'content' => array()
  250. ),
  251. 'bx_if:show_on_click' => array(
  252. 'condition' => $bEnabled,
  253. 'content' => array(
  254. 'on_click' => 'javascript:' . $sJsObject . '.changePage(this, ' . ($iStart + $iPerPage) . ', ' . $iPerPage . ')'
  255. )
  256. ),
  257. 'bx_if:show_jump_to' => array(
  258. 'condition' => !empty($sYears),
  259. 'content' => array(
  260. 'style_prefix' => $sStylePrefix,
  261. 'years' => $sYears
  262. )
  263. )
  264. );
  265. return $this->parseHtmlByName('load_more.html', $aTmplVars);
  266. }
  267. public function getComments($sSystem, $iId)
  268. {
  269. $oModule = $this->getModule();
  270. $sStylePrefix = $this->_oConfig->getPrefix('style');
  271. $oCmts = $oModule->getCmtsObject($sSystem, $iId);
  272. if($oCmts === false)
  273. return '';
  274. $aComments = $oCmts->getCommentsBlock(0, 0, false);
  275. return $this->parseHtmlByName('comments.html', array(
  276. 'style_prefix' => $sStylePrefix,
  277. 'id' => $iId,
  278. 'content' => $aComments['content']
  279. ));
  280. }
  281. public function getShareElement($iOwnerId, $sType, $sAction, $iObjectId, $aParams = array())
  282. {
  283. $aShared = $this->_oDb->getShared($sType, $sAction, $iObjectId);
  284. if(empty($aShared) || !is_array($aShared))
  285. return '';
  286. $oModule = $this->getModule();
  287. $bDisabled = $oModule->isAllowedShare($aShared) !== true || $this->_oDb->isShared($aShared['id'], $iOwnerId, $oModule->getUserId());
  288. if($bDisabled && (int)$aShared['shares'] == 0)
  289. return '';
  290. $sStylePrefix = $this->_oConfig->getPrefix('style');
  291. $sStylePrefixShare = $sStylePrefix . '-share-';
  292. $bShowDoShareAsButtonSmall = isset($aParams['show_do_share_as_button_small']) && $aParams['show_do_share_as_button_small'] == true;
  293. $bShowDoShareAsButton = !$bShowDoShareAsButtonSmall && isset($aParams['show_do_share_as_button']) && $aParams['show_do_share_as_button'] == true;
  294. $bShowDoShareIcon = isset($aParams['show_do_share_icon']) && $aParams['show_do_share_icon'] == true;
  295. $bShowDoShareLabel = isset($aParams['show_do_share_label']) && $aParams['show_do_share_label'] == true;
  296. $bShowCounter = isset($aParams['show_counter']) && $aParams['show_counter'] === true;
  297. //--- Do share link ---//
  298. $sClass = $sStylePrefixShare . 'do-share';
  299. if($bShowDoShareAsButton)
  300. $sClass .= ' bx-btn';
  301. else if($bShowDoShareAsButtonSmall)
  302. $sClass .= ' bx-btn bx-btn-small';
  303. $sOnClick = '';
  304. if(!$bDisabled) {
  305. $sCommonPrefix = $this->_oConfig->getPrefix('common_post');
  306. if(str_replace($sCommonPrefix, '', $sType) == BX_TIMELINE_PARSE_TYPE_SHARE) {
  307. $aSharedData = $this->_getCommonData($aShared);
  308. $sOnClick = $this->getShareJsClick($iOwnerId, $aSharedData['content']['type'], $aSharedData['content']['action'], $aSharedData['content']['object_id']);
  309. }
  310. else
  311. $sOnClick = $this->getShareJsClick($iOwnerId, $sType, $sAction, $iObjectId);
  312. }
  313. else
  314. $sClass .= $bShowDoShareAsButton || $bShowDoShareAsButtonSmall ? ' bx-btn-disabled' : ' ' . $sStylePrefixShare . 'disabled';
  315. $aOnClickAttrs = array();
  316. if(!empty($sClass))
  317. $aOnClickAttrs[] = array('key' => 'class', 'value' => $sClass);
  318. if(!empty($sOnClick))
  319. $aOnClickAttrs[] = array('key' => 'onclick', 'value' => $sOnClick);
  320. $sDoShare = '';
  321. if($bShowDoShareIcon)
  322. $sDoShare .= $this->parseHtmlByName('bx_icon.html', array('name' => 'repeat'));
  323. if($bShowDoShareLabel)
  324. $sDoShare .= ($sDoShare != '' ? ' ' : '') . _t('_bx_timeline_txt_do_share');
  325. return $this->parseHtmlByName('share_element_block.html', array(
  326. 'style_prefix' => $sStylePrefix,
  327. 'html_id' => $this->_oConfig->getHtmlIds('share', 'main') . $aShared['id'],
  328. 'class' => ($bShowDoShareAsButton ? $sStylePrefixShare . 'button' : '') . ($bShowDoShareAsButtonSmall ? $sStylePrefixShare . 'button-small' : ''),
  329. 'count' => $aShared['shares'],
  330. 'do_share' => $this->parseHtmlByName('bx_a.html', array(
  331. 'href' => 'javascript:void(0)',
  332. 'title' => _t('_bx_timeline_txt_do_share'),
  333. 'bx_repeat:attrs' => $aOnClickAttrs,
  334. 'content' => $sDoShare
  335. )),
  336. 'bx_if:show_counter' => array(
  337. 'condition' => $bShowCounter,
  338. 'content' => array(
  339. 'style_prefix' => $sStylePrefix,
  340. 'bx_if:show_hidden' => array(
  341. 'condition' => (int)$aShared['shares'] == 0,
  342. 'content' => array()
  343. ),
  344. 'counter' => $this->getShareCounter($aShared, $aParams)
  345. )
  346. ),
  347. 'script' => $this->getShareJsScript()
  348. ));
  349. }
  350. public function getShareCounter($aEvent, $aParams = array())
  351. {
  352. $sStylePrefix = $this->_oConfig->getPrefix('style');
  353. $sJsObject = $this->_oConfig->getJsObject('share');
  354. $bShowDoShareAsButtonSmall = isset($aParams['show_do_share_as_button_small']) && $aParams['show_do_share_as_button_small'] == true;
  355. $bShowDoShareAsButton = !$bShowDoShareAsButtonSmall && isset($aParams['show_do_share_as_button']) && $aParams['show_do_share_as_button'] == true;
  356. $sClass = $sStylePrefix . '-share-counter';
  357. if($bShowDoShareAsButtonSmall)
  358. $sClass .= ' bx-btn-small-height';
  359. if($bShowDoShareAsButton)
  360. $sClass .= ' bx-btn-height';
  361. return $this->parseHtmlByName('share_counter.html', array(
  362. 'href' => 'javascript:void(0)',
  363. 'title' => _t('_bx_timeline_txt_shared_by'),
  364. 'bx_repeat:attrs' => array(
  365. array('key' => 'id', 'value' => $this->_oConfig->getHtmlIds('share', 'counter') . $aEvent['id']),
  366. array('key' => 'class', 'value' => $sClass),
  367. array('key' => 'onclick', 'value' => 'javascript:' . $sJsObject . '.toggleByPopup(this, ' . $aEvent['id'] . ')')
  368. ),
  369. 'content' => !empty($aEvent['shares']) && (int)$aEvent['shares'] > 0 ? $aEvent['shares'] : ''
  370. ));
  371. }
  372. public function getSharedBy($iId)
  373. {
  374. $aTmplUsers = array();
  375. $oModule = $this->getModule();
  376. $sStylePrefix = $this->_oConfig->getPrefix('style');
  377. $aUserIds = $this->_oDb->getSharedBy($iId);
  378. foreach($aUserIds as $iUserId) {
  379. list($sUserName, $sUserUrl, $sUserIcon, $sUserUnit) = $oModule->getUserInfo($iUserId);
  380. $aTmplUsers[] = array(
  381. 'style_prefix' => $sStylePrefix,
  382. 'user_unit' => $sUserUnit
  383. );
  384. }
  385. if(empty($aTmplUsers))
  386. $aTmplUsers = MsgBox(_t('_Empty'));
  387. return $this->parseHtmlByName('share_by_list.html', array(
  388. 'style_prefix' => $sStylePrefix,
  389. 'bx_repeat:list' => $aTmplUsers
  390. ));
  391. }
  392. public function getShareJsScript()
  393. {
  394. $this->addCss(array('share.css'));
  395. $this->addJs(array('main.js', 'share.js'));
  396. return $this->getJsCode('share');
  397. }
  398. public function getShareJsClick($iOwnerId, $sType, $sAction, $iObjectId)
  399. {
  400. $sJsObject = $this->_oConfig->getJsObject('share');
  401. $sFormat = "%s.shareItem(this, %d, '%s', '%s', %d);";
  402. $iOwnerId = !empty($iOwnerId) ? (int)$iOwnerId : $this->getModule()->getUserId(); //--- in whose timeline the content will be shared
  403. return sprintf($sFormat, $sJsObject, $iOwnerId, $sType, $sAction, (int)$iObjectId);
  404. }
  405. public function getAttachLinkForm()
  406. {
  407. $sStylePrefix = $this->_oConfig->getPrefix('style');
  408. $sJsObject = $this->_oConfig->getJsObject('post');
  409. $aForm = $this->getModule()->getFormAttachLink();
  410. return $this->parseHtmlByName('attach_link_form.html', array(
  411. 'style_prefix' => $sStylePrefix,
  412. 'js_object' => $sJsObject,
  413. 'form_id' => $aForm['form_id'],
  414. 'form' => $aForm['form'],
  415. ));
  416. }
  417. public function getAttachLinkField($iUserId)
  418. {
  419. $sStylePrefix = $this->_oConfig->getPrefix('style');
  420. $aLinks = $this->_oDb->getUnusedLinks($iUserId);
  421. $sLinks = '';
  422. foreach($aLinks as $aLink)
  423. $sLinks .= $this->getAttachLinkItem($iUserId, $aLink);
  424. return $this->parsePageByName('attach_link_form_field.html', array(
  425. 'html_id' => $this->_oConfig->getHtmlIds('post', 'attach_link_form_field'),
  426. 'style_prefix' => $sStylePrefix,
  427. 'links' => $sLinks
  428. ));
  429. }
  430. public function getAttachLinkItem($iUserId, $mixedLink)
  431. {
  432. $aLink = is_array($mixedLink) ? $mixedLink : $this->_oDb->getUnusedLinks($iUserId, (int)$mixedLink);
  433. if(empty($aLink) || !is_array($aLink))
  434. return '';
  435. $sStylePrefix = $this->_oConfig->getPrefix('style');
  436. $sJsObject = $this->_oConfig->getJsObject('post');
  437. $sLinkIdPrefix = $this->_oConfig->getHtmlIds('post', 'attach_link_item');
  438. $aLinkAttrs = array();
  439. if(!$this->_oConfig->isEqualUrls(BX_DOL_URL_ROOT, $aLink['url'])) {
  440. $aLinkAttrs[] = array('key' => 'target', 'value' => '_blank');
  441. if($this->_oDb->getParam('sys_add_nofollow') == 'on')
  442. $aLinkAttrs[] = array('key' => 'rel', 'value' => 'nofollow');
  443. }
  444. $sThumbnail = '';
  445. if((int)$aLink['media_id'] != 0)
  446. $sThumbnail = BxDolTranscoderImage::getObjectInstance($this->_oConfig->getObject('transcoder_photos_preview'))->getFileUrl($aLink['media_id']);
  447. return $this->parsePageByName('attach_link_item.html', array(
  448. 'html_id' => $sLinkIdPrefix . $aLink['id'],
  449. 'style_prefix' => $sStylePrefix,
  450. 'js_object' => $sJsObject,
  451. 'id' => $aLink['id'],
  452. 'url' => $aLink['url'],
  453. 'link' => $this->parsePageByName('bx_a.html', array(
  454. 'href' => $aLink['url'],
  455. 'title' => $aLink['title'],
  456. 'bx_repeat:attrs' => $aLinkAttrs,
  457. 'content' => $aLink['title'],
  458. )),
  459. 'bx_if:show_thumbnail' => array(
  460. 'condition' => !empty($sThumbnail),
  461. 'content' => array(
  462. 'style_prefix' => $sStylePrefix,
  463. 'thumbnail' => $sThumbnail
  464. )
  465. )
  466. ));
  467. }
  468. protected function _getPost($sType, $aEvent, $aBrowseParams = array())
  469. {
  470. $oModule = $this->getModule();
  471. $sStylePrefix = $this->_oConfig->getPrefix('style');
  472. $sJsObject = $this->_oConfig->getJsObject('view');
  473. list($sAuthorName, $sAuthorUrl, $sAuthorIcon) = $oModule->getUserInfo($aEvent['object_owner_id']);
  474. $bAuthorIcon = !empty($sAuthorIcon);
  475. $aTmplVarsMenuItemActions = $this->_getTmplVarsMenuItemActions($aEvent, $aBrowseParams);
  476. $aTmplVarsTimelineOwner = array();
  477. if(isset($aBrowseParams['type']) && $aBrowseParams['type'] == BX_BASE_MOD_NTFS_TYPE_CONNECTIONS)
  478. $aTmplVarsTimelineOwner = $this->_getTmplVarsTimelineOwner($aEvent);
  479. $bBrowseItem = isset($aBrowseParams['type']) && $aBrowseParams['type'] == BX_TIMELINE_TYPE_ITEM;
  480. $bViewTimeline = isset($aBrowseParams['view']) && $aBrowseParams['view'] == BX_TIMELINE_VIEW_TIMELINE;
  481. $oMetatags = BxDolMetatags::getObjectInstance($this->_oConfig->getObject('metatags'));
  482. $sLocation = $oMetatags->locationsString($aEvent['id']);
  483. $aTmplVars = array (
  484. 'style_prefix' => $sStylePrefix,
  485. 'js_object' => $sJsObject,
  486. 'html_id' => $this->_oConfig->getHtmlIds('view', 'item_' . $aBrowseParams['view']) . $aEvent['id'],
  487. 'class' => $bBrowseItem || $bViewTimeline ? 'bx-tl-view-sizer' : 'bx-tl-grid-sizer',
  488. 'class_content' => $bBrowseItem ? 'bx-def-color-bg-block' : 'bx-def-color-bg-box',
  489. 'id' => $aEvent['id'],
  490. 'bx_if:show_owner_icon' => array(
  491. 'condition' => $bAuthorIcon,
  492. 'content' => array(
  493. 'owner_icon' => $sAuthorIcon
  494. )
  495. ),
  496. 'bx_if:show_owner_icon_empty' => array(
  497. 'condition' => !$bAuthorIcon,
  498. 'content' => array()
  499. ),
  500. 'bx_if:show_item_icon' => array(
  501. 'condition' => !empty($aEvent['icon']),
  502. 'content' => array(
  503. 'style_prefix' => $sStylePrefix,
  504. 'item_icon' => $aEvent['icon'],
  505. )
  506. ),
  507. 'item_owner_url' => $sAuthorUrl,
  508. 'item_owner_title' => bx_html_attribute($sAuthorName),
  509. 'item_owner_name' => $sAuthorName,
  510. 'bx_if:show_timeline_owner' => array(
  511. 'condition' => !empty($aTmplVarsTimelineOwner),
  512. 'content' => $aTmplVarsTimelineOwner
  513. ),
  514. 'item_view_url' => $this->_oConfig->getItemViewUrl($aEvent),
  515. 'item_date' => bx_time_js($aEvent['date']),
  516. 'bx_if:show_pinned' => array(
  517. 'condition' => (int)$aEvent['pinned'] != 0,
  518. 'content' => array(
  519. 'style_prefix' => $sStylePrefix,
  520. )
  521. ),
  522. 'content' => is_string($aEvent['content']) ? $aEvent['content'] : $this->_getContent($sType, $aEvent, $aBrowseParams),
  523. 'bx_if:show_location' => array(
  524. 'condition' => !empty($sLocation),
  525. 'content' => array(
  526. 'style_prefix' => $sStylePrefix,
  527. 'location' => $sLocation
  528. )
  529. ),
  530. 'bx_if:show_menu_item_actions' => array(
  531. 'condition' => !empty($aTmplVarsMenuItemActions),
  532. 'content' => $aTmplVarsMenuItemActions
  533. ),
  534. 'comments' => $bBrowseItem ? $this->_getComments($aEvent['comments']) : '',
  535. );
  536. return $this->parseHtmlByName('item_' . $aBrowseParams['view'] . '.html', $aTmplVars);
  537. }
  538. protected function _getContent($sType, $aEvent, $aBrowseParams = array())
  539. {
  540. $sMethod = '_getTmplVarsContent' . ucfirst($sType);
  541. if(!method_exists($this, $sMethod))
  542. return '';
  543. $aTmplVars = $this->$sMethod($aEvent, $aBrowseParams);
  544. return $this->parseHtmlByName('type_' . $sType . '.html', $aTmplVars);
  545. }
  546. protected function _getComments($aComments)
  547. {
  548. $mixedComments = $this->getModule()->getCommentsData($aComments);
  549. if($mixedComments === false)
  550. return '';
  551. list($sSystem, $iObjectId, $iCount) = $mixedComments;
  552. return $this->getComments($sSystem, $iObjectId);
  553. }
  554. protected function _getImagePopup($aParams)
  555. {
  556. $sViewImagePopupId = $this->_oConfig->getHtmlIds('view', 'photo_popup_' . $aParams['view']);
  557. $sViewImagePopupContent = $this->parseHtmlByName('popup_image.html', array(
  558. 'image_url' => ''
  559. ));
  560. return BxTemplFunctions::getInstance()->transBox($sViewImagePopupId, $sViewImagePopupContent, true);
  561. }
  562. protected function _getTmplVarsMenuItemActions(&$aEvent, $aBrowseParams = array())
  563. {
  564. $oMenu = BxDolMenu::getObjectInstance($this->_oConfig->getObject('menu_item_actions'));
  565. $oMenu->setEvent($aBrowseParams['view'], $aEvent);
  566. $oMenu->setDynamicMode(isset($aBrowseParams['dynamic_mode']) && $aBrowseParams['dynamic_mode'] === true);
  567. $sMenu = $oMenu->getCode();
  568. if(empty($sMenu))
  569. return array();
  570. return array(
  571. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  572. 'js_object' => $this->_oConfig->getJsObject('view'),
  573. 'menu_item_actions' => $sMenu
  574. );
  575. }
  576. protected function _getTmplVarsTimelineOwner(&$aEvent)
  577. {
  578. $oModule = $this->getModule();
  579. $aTmplVarsTimelineOwner = array();
  580. if((int)$aEvent['owner_id'] != (int)$aEvent['object_owner_id']) {
  581. list($sTimelineAuthorName, $sTimelineAuthorUrl) = $oModule->getUserInfo($aEvent['owner_id']);
  582. $aTmplVarsTimelineOwner = array(
  583. 'owner_url' => $sTimelineAuthorUrl,
  584. 'owner_username' => $sTimelineAuthorName,
  585. );
  586. }
  587. return $aTmplVarsTimelineOwner;
  588. }
  589. protected function _getTmplVarsContentPost($aEvent, $aBrowseParams = array())
  590. {
  591. $aContent = &$aEvent['content'];
  592. $sStylePrefix = $this->_oConfig->getPrefix('style');
  593. $sJsObject = $this->_oConfig->getJsObject('view');
  594. $bBrowseItem = isset($aBrowseParams['type']) && $aBrowseParams['type'] == BX_TIMELINE_TYPE_ITEM;
  595. //--- Process Text ---//
  596. $sUrl = isset($aContent['url']) ? bx_html_attribute($aContent['url']) : '';
  597. $sTitle = $sTitleAttr = '';
  598. if(isset($aContent['title'])) {
  599. $sTitle = bx_process_output($aContent['title']);
  600. $sTitleAttr = bx_html_attribute($aContent['title']);
  601. }
  602. if(!empty($sUrl) && !empty($sTitle))
  603. $sTitle = $this->parseHtmlByName('bx_a.html', array(
  604. 'href' => $sUrl,
  605. 'title' => $sTitleAttr,
  606. 'bx_repeat:attrs' => array(
  607. array('key' => 'class', 'value' => $sStylePrefix . '-title')
  608. ),
  609. 'content' => $sTitle
  610. ));
  611. $sText = isset($aContent['text']) ? $aContent['text'] : '';
  612. $sTextMore = '';
  613. if($bBrowseItem)
  614. $sText = strip_tags($sText, '<br><br/><p>');
  615. else {
  616. $sText = strip_tags($sText);
  617. $iMaxLength = $this->_oConfig->getCharsDisplayMax();
  618. if(strlen($sText) > $iMaxLength) {
  619. $iLength = strpos($sText, ' ', $iMaxLength);
  620. $sTextMore = trim(substr($sText, $iLength));
  621. $sText = trim(substr($sText, 0, $iLength));
  622. }
  623. $sTextMore = nl2br($sTextMore);
  624. $sText = nl2br($sText);
  625. }
  626. $sText = $this->_prepareTextForOutput($sText, $aEvent['id']);
  627. $sTextMore = $this->_prepareTextForOutput($sTextMore, $aEvent['id']);
  628. //--- Process Links ---//
  629. $bAddNofollow = $this->_oDb->getParam('sys_add_nofollow') == 'on';
  630. $aTmplVarsLinks = array();
  631. if(!empty($aContent['links']))
  632. foreach($aContent['links'] as $aLink) {
  633. $aLinkAttrs = array();
  634. if(!$this->_oConfig->isEqualUrls(BX_DOL_URL_ROOT, $aLink['url'])) {
  635. $aLinkAttrs[] = array('key' => 'target', 'value' => '_blank');
  636. if($bAddNofollow)
  637. $aLinkAttrs[] = array('key' => 'rel', 'value' => 'nofollow');
  638. }
  639. $aTmplVarsLinks[] = array(
  640. 'style_prefix' => $sStylePrefix,
  641. 'bx_if:show_thumbnail' => array(
  642. 'condition' => !empty($aLink['thumbnail']),
  643. 'content' => array(
  644. 'style_prefix' => $sStylePrefix,
  645. 'thumbnail' => $aLink['thumbnail']
  646. )
  647. ),
  648. 'link' => $this->parsePageByName('bx_a.html', array(
  649. 'href' => $aLink['url'],
  650. 'title' => $aLink['title'],
  651. 'bx_repeat:attrs' => $aLinkAttrs,
  652. 'content' => $aLink['title'],
  653. )),
  654. 'bx_if:show_text' => array(
  655. 'condition' => !empty($aLink['text']),
  656. 'content' => array(
  657. 'style_prefix' => $sStylePrefix,
  658. 'text' => $aLink['text']
  659. )
  660. )
  661. );
  662. }
  663. //--- Process Photos ---//
  664. $aTmplVarsImages = array();
  665. if(!empty($aContent['images'])) {
  666. foreach($aContent['images'] as $aImage) {
  667. $sImage = '';
  668. if(!empty($aImage['src']))
  669. $sImage = $this->parseHtmlByName('bx_img.html', array(
  670. 'src' => $bBrowseItem && !empty($aImage['src_orig']) ? $aImage['src_orig'] : $aImage['src'],
  671. 'bx_repeat:attrs' => array(
  672. array('key' => 'class', 'value' => $sStylePrefix . '-item-img')
  673. )
  674. ));
  675. if(!empty($sImage) && (isset($aImage['url']) || isset($aImage['onclick']))) {
  676. $aAttrs = array();
  677. if(isset($aImage['onclick']))
  678. $aAttrs[] = array('key' => 'onclick', 'value' => $aImage['onclick']);
  679. $sImage = $this->parseHtmlByName('bx_a.html', array(
  680. 'href' => isset($aImage['url']) ? $aImage['url'] : 'javascript:void(0)',
  681. 'title' => '',
  682. 'bx_repeat:attrs' => $aAttrs,
  683. 'content' => $sImage
  684. ));
  685. }
  686. $aTmplVarsImages[] = array(
  687. 'style_prefix' => $sStylePrefix,
  688. 'image' => $sImage
  689. );
  690. }
  691. }
  692. //--- Process Videos ---//
  693. $aTmplVarsVideos = array();
  694. if(!empty($aContent['videos']))
  695. foreach($aContent['videos'] as $aVideo) {
  696. $aTmplVarsVideos[] = array(
  697. 'style_prefix' => $sStylePrefix,
  698. 'video' => BxTemplFunctions::getInstance()->videoPlayer($aVideo['src_poster'], $aVideo['src_mp4'], $aVideo['src_webm'])
  699. );
  700. }
  701. return array(
  702. 'style_prefix' => $sStylePrefix,
  703. 'bx_if:show_title' => array(
  704. 'condition' => !empty($sTitle),
  705. 'content' => array(
  706. 'style_prefix' => $sStylePrefix,
  707. 'title' => $sTitle,
  708. )
  709. ),
  710. 'bx_if:show_content' => array(
  711. 'condition' => !empty($sText),
  712. 'content' => array(
  713. 'style_prefix' => $sStylePrefix,
  714. 'item_content' => $sText,
  715. 'bx_if:show_more' => array(
  716. 'condition' => !empty($sTextMore),
  717. 'content' => array(
  718. 'style_prefix' => $sStylePrefix,
  719. 'js_object' => $sJsObject,
  720. 'item_content_more' => $sTextMore
  721. )
  722. ),
  723. )
  724. ),
  725. 'bx_if:show_links' => array(
  726. 'condition' => !empty($aTmplVarsLinks),
  727. 'content' => array(
  728. 'style_prefix' => $sStylePrefix,
  729. 'bx_repeat:links' => $aTmplVarsLinks
  730. )
  731. ),
  732. 'bx_if:show_images' => array(
  733. 'condition' => !empty($aTmplVarsImages),
  734. 'content' => array(
  735. 'style_prefix' => $sStylePrefix,
  736. 'bx_repeat:images' => $aTmplVarsImages
  737. )
  738. ),
  739. 'bx_if:show_videos' => array(
  740. 'condition' => !empty($aTmplVarsVideos),
  741. 'content' => array(
  742. 'style_prefix' => $sStylePrefix,
  743. 'bx_repeat:videos' => $aTmplVarsVideos
  744. )
  745. )
  746. );
  747. }
  748. protected function _getTmplVarsContentShare($aEvent, $aBrowseParams = array())
  749. {
  750. $aContent = &$aEvent['content'];
  751. $sStylePrefix = $this->_oConfig->getPrefix('style');
  752. $sOwnerLink = $this->parseHtmlByName('bx_a.html', array(
  753. 'href' => $aContent['owner_url'],
  754. 'title' => '',
  755. 'bx_repeat:attrs' => array(),
  756. 'content' => $aContent['owner_name']
  757. ));
  758. $sSample = _t($aContent['sample']);
  759. $sSampleLink = empty($aContent['url']) ? $sSample : $this->parseHtmlByName('bx_a.html', array(
  760. 'href' => $aContent['url'],
  761. 'title' => '',
  762. 'bx_repeat:attrs' => array(),
  763. 'content' => $sSample
  764. ));
  765. $sTitle = _t('_bx_timeline_txt_shared', $sOwnerLink, $sSampleLink);
  766. $sText = $this->_getContent($aContent['parse_type'], $aEvent);
  767. return array(
  768. 'bx_if:show_title' => array(
  769. 'condition' => !empty($sTitle),
  770. 'content' => array(
  771. 'style_prefix' => $sStylePrefix,
  772. 'title' => $sTitle,
  773. )
  774. ),
  775. 'bx_if:show_content' => array(
  776. 'condition' => !empty($sText),
  777. 'content' => array(
  778. 'style_prefix' => $sStylePrefix,
  779. 'content' => $sText,
  780. )
  781. )
  782. );
  783. }
  784. protected function _getSystemData(&$aEvent)
  785. {
  786. $mixedResult = $this->_oConfig->getSystemData($aEvent);
  787. if($mixedResult !== false)
  788. return $mixedResult;
  789. $sMethod = 'display' . bx_gen_method_name($aEvent['type'] . '_' . $aEvent['action']);
  790. if(!method_exists($this, $sMethod))
  791. return '';
  792. return $this->$sMethod($aEvent);
  793. }
  794. protected function _getCommonData(&$aEvent)
  795. {
  796. $oModule = $this->getModule();
  797. $sJsObject = $this->_oConfig->getJsObject('view');
  798. $sPrefix = $this->_oConfig->getPrefix('common_post');
  799. $sType = str_replace($sPrefix, '', $aEvent['type']);
  800. $aResult = array(
  801. 'owner_id' => $aEvent['object_id'],
  802. 'content_type' => $sType,
  803. 'content' => array(
  804. 'sample' => '_bx_timeline_txt_sample',
  805. 'url' => $this->_oConfig->getItemViewUrl($aEvent)
  806. ), //a string to display or array to parse default template before displaying.
  807. 'votes' => '',
  808. 'reports' => '',
  809. 'comments' => '',
  810. 'title' => '', //may be empty.
  811. 'description' => '' //may be empty.
  812. );
  813. switch($sType) {
  814. case BX_TIMELINE_PARSE_TYPE_POST:
  815. if(!empty($aEvent['content']))
  816. $aResult['content'] = array_merge($aResult['content'], unserialize($aEvent['content']));
  817. $aLinks = $this->_oDb->getLinks($aEvent['id']);
  818. if(!empty($aLinks) && is_array($aLinks))
  819. $oTranscoder = BxDolTranscoderImage::getObjectInstance($this->_oConfig->getObject('transcoder_photos_preview'));
  820. foreach($aLinks as $aLink)
  821. $aResult['content']['links'][] = array(
  822. 'url' => $aLink['url'],
  823. 'title' => $aLink['title'],
  824. 'text' => $aLink['text'],
  825. 'thumbnail' => (int)$aLink['media_id'] != 0 ? $oTranscoder->getFileUrl($aLink['media_id']) : ''
  826. );
  827. $aPhotos = $this->_oDb->getMedia(BX_TIMELINE_MEDIA_PHOTO, $aEvent['id']);
  828. if(!empty($aPhotos) && is_array($aPhotos)) {
  829. $oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_photos'));
  830. $oTranscoder = BxDolTranscoderImage::getObjectInstance($this->_oConfig->getObject('transcoder_photos_view'));
  831. foreach($aPhotos as $iPhotoId) {
  832. $sPhotoSrcOrig = $oStorage->getFileUrlById($iPhotoId);
  833. $aResult['content']['images'][] = array(
  834. 'src' => $oTranscoder->getFileUrl($iPhotoId),
  835. 'src_orig' => $sPhotoSrcOrig,
  836. 'title' => '',
  837. 'onclick' => $sJsObject . '.showPhoto(this, \'' . $sPhotoSrcOrig . '\')'
  838. );
  839. }
  840. }
  841. $aVideos = $this->_oDb->getMedia(BX_TIMELINE_MEDIA_VIDEO, $aEvent['id']);
  842. if(!empty($aVideos) && is_array($aVideos)) {
  843. $oTranscoderPoster = BxDolTranscoderVideo::getObjectInstance($this->_oConfig->getObject('transcoder_videos_poster'));
  844. $oTranscoderMp4 = BxDolTranscoderVideo::getObjectInstance($this->_oConfig->getObject('transcoder_videos_mp4'));
  845. $oTranscoderWebm = BxDolTranscoderVideo::getObjectInstance($this->_oConfig->getObject('transcoder_videos_webm'));
  846. foreach($aVideos as $iVideoId) {
  847. $aResult['content']['videos'][] = array(
  848. 'src_poster' => $oTranscoderPoster->getFileUrl($iVideoId),
  849. 'src_mp4' => $oTranscoderMp4->getFileUrl($iVideoId),
  850. 'src_webm' => $oTranscoderWebm->getFileUrl($iVideoId),
  851. );
  852. }
  853. }
  854. break;
  855. case BX_TIMELINE_PARSE_TYPE_SHARE:
  856. if(empty($aEvent['content']))
  857. return array();
  858. $aContent = unserialize($aEvent['content']);
  859. if(!$this->_oConfig->isSystem($aContent['type'] , $aContent['action'])) {
  860. $aShared = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $aContent['object_id']));
  861. $aShared = $this->_getCommonData($aShared);
  862. }
  863. else
  864. $aShared = $this->_getSystemData($aContent);
  865. if(empty($aShared) || !is_array($aShared))
  866. return array();
  867. $aResult['content'] = array_merge($aContent, $aShared['content']);
  868. $aResult['content']['parse_type'] = !empty($aShared['content_type']) ? $aShared['content_type'] : BX_TIMELINE_PARSE_TYPE_DEFAULT;
  869. $aResult['content']['owner_id'] = $aShared['owner_id'];
  870. list($aResult['content']['owner_name'], $aResult['content']['owner_url']) = $oModule->getUserInfo($aShared['owner_id']);
  871. list($sUserName) = $oModule->getUserInfo($aEvent['object_id']);
  872. $sSample = !empty($aResult['content']['sample']) ? $aResult['content']['sample'] : '_bx_timeline_txt_sample';
  873. $aResult['title'] = _t('_bx_timeline_txt_user_shared_sample', $sUserName, $aResult['content']['owner_name'], _t($sSample));
  874. $aResult['description'] = '';
  875. break;
  876. }
  877. $sSystem = $this->_oConfig->getObject('vote');
  878. if($oModule->getVoteObject($sSystem, $aEvent['id']) !== false)
  879. $aResult['votes'] = array(
  880. 'system' => $sSystem,
  881. 'object_id' => $aEvent['id'],
  882. 'count' => $aEvent['votes']
  883. );
  884. $sSystem = $this->_oConfig->getObject('report');
  885. if($oModule->getReportObject($sSystem, $aEvent['id']) !== false)
  886. $aResult['reports'] = array(
  887. 'system' => $sSystem,
  888. 'object_id' => $aEvent['id'],
  889. 'count' => $aEvent['reports']
  890. );
  891. $sSystem = $this->_oConfig->getObject('comment');
  892. if($oModule->getCmtsObject($sSystem, $aEvent['id']) !== false)
  893. $aResult['comments'] = array(
  894. 'system' => $sSystem,
  895. 'object_id' => $aEvent['id'],
  896. 'count' => $aEvent['comments']
  897. );
  898. return $aResult;
  899. }
  900. protected function _prepareTextForOutput($s, $iEventId = 0)
  901. {
  902. $s = bx_process_output($s, BX_DATA_HTML);
  903. $s = bx_linkify_html($s, 'class="' . BX_DOL_LINK_CLASS . '"');
  904. $oMetatags = BxDolMetatags::getObjectInstance($this->_oConfig->getObject('metatags'));
  905. $s = $oMetatags->keywordsParse($iEventId, $s);
  906. return $s;
  907. }
  908. }
  909. /** @} */