BxTimelineTemplate.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
  4. * CC-BY License - http://creativecommons.org/licenses/by/3.0/
  5. *
  6. * @defgroup Timeline Timeline
  7. * @ingroup DolphinModules
  8. *
  9. * @{
  10. */
  11. bx_import('BxDolModuleTemplate');
  12. class BxTimelineTemplate extends BxDolModuleTemplate
  13. {
  14. function __construct(&$oConfig, &$oDb)
  15. {
  16. parent::__construct($oConfig, $oDb);
  17. }
  18. protected function getModule()
  19. {
  20. $sName = $this->_oConfig->getName();
  21. return BxDolModule::getInstance($sName);
  22. }
  23. public function getCssJs()
  24. {
  25. $this->addCss(array(
  26. 'jquery-ui/jquery-ui.css',
  27. 'view.css',
  28. 'view-media-tablet.css',
  29. 'view-media-desktop.css',
  30. 'post.css',
  31. 'share.css',
  32. ));
  33. $this->addJs(array(
  34. 'jquery-ui/jquery-ui.custom.min.js',
  35. 'jquery.form.min.js',
  36. 'jquery.ba-resize.min.js',
  37. 'masonry.pkgd.min.js',
  38. 'jquery.anim.js',
  39. 'main.js',
  40. 'view.js',
  41. 'post.js',
  42. 'share.js',
  43. ));
  44. }
  45. public function getJsCode($sType, $aRequestParams = array(), $bWrap = true)
  46. {
  47. $oModule = $this->getModule();
  48. $sBaseUri = $this->_oConfig->getBaseUri();
  49. $sJsClass = $this->_oConfig->getJsClass($sType);
  50. $sJsObject = $this->_oConfig->getJsObject($sType);
  51. $aParams = array(
  52. 'sActionUri' => $sBaseUri,
  53. 'sActionUrl' => BX_DOL_URL_ROOT . $sBaseUri,
  54. 'sObjName' => $sJsObject,
  55. 'iOwnerId' => $oModule->_iOwnerId,
  56. 'sAnimationEffect' => $this->_oConfig->getAnimationEffect(),
  57. 'iAnimationSpeed' => $this->_oConfig->getAnimationSpeed(),
  58. 'aHtmlIds' => $this->_oConfig->getHtmlIds($sType),
  59. 'oRequestParams' => !empty($aRequestParams) ? $aRequestParams : array()
  60. );
  61. $sContent = "var " . $sJsObject . " = new " . $sJsClass . "(" . json_encode($aParams) . ");";
  62. $this->getCssJs();
  63. return !$bWrap ? $sContent : $this->_wrapInTagJsCode($sContent);
  64. }
  65. public function getPostBlock($iOwnerId)
  66. {
  67. $aForm = $this->getModule()->getFormPost();
  68. return $this->parseHtmlByName('block_post.html', array (
  69. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  70. 'js_object' => $this->_oConfig->getJsObject('post'),
  71. 'js_content' => $this->getJsCode('post', array(
  72. 'owner_id' => $iOwnerId
  73. )),
  74. 'form' => $aForm['form']
  75. ));
  76. }
  77. public function getViewBlock($aParams)
  78. {
  79. list($sContent, $sLoadMore, $sBack) = $this->getPosts($aParams);
  80. return $this->parseHtmlByName('block_view.html', array(
  81. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  82. 'back' => $sBack,
  83. 'content' => $sContent,
  84. 'load_more' => $sLoadMore,
  85. 'js_content' => $this->getJsCode('view', array(
  86. 'type' => $aParams['type'],
  87. 'owner_id' => $aParams['owner_id'],
  88. 'start' => $aParams['start'],
  89. 'per_page' => $aParams['per_page'],
  90. 'filter' => $aParams['filter'],
  91. 'modules' => $aParams['modules'],
  92. 'timeline' => $aParams['timeline'],
  93. )) . $this->getJsCode('share')
  94. ));
  95. }
  96. public function getItemBlock($iId)
  97. {
  98. $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
  99. if(empty($aEvent))
  100. return '';
  101. $sContent = $this->getJsCode('view');
  102. $sContent .= $this->getPost($aEvent, array('type' => BX_TIMELINE_TYPE_ITEM));
  103. return $sContent;
  104. }
  105. public function getItemPopup($iId)
  106. {
  107. return $this->getItemBlock($iId);
  108. }
  109. public function getPhotoPopup($iEventId, $iStart)
  110. {
  111. $sStylePrefix = $this->_oConfig->getPrefix('style');
  112. $sJsObject = $this->_oConfig->getJsObject('view');
  113. $aPhotos = $this->_oDb->getPhotos($iEventId);
  114. $iPhotos = count($aPhotos);
  115. if(empty($aPhotos[$iStart]))
  116. return MsgBox(_t('_Empty'));
  117. $sPaginate = '';
  118. if($iPhotos > 1) {
  119. bx_import('BxTemplPaginate');
  120. $oPaginate = new BxTemplPaginate(array(
  121. 'start' => $iStart,
  122. 'num' => (isset($aPhotos[$iStart + 1]) ? 2 : 1),
  123. 'per_page' => 1,
  124. 'on_change_page' => $sJsObject . '.showPhoto(this, ' . $iEventId . ', {start})'
  125. ));
  126. $sPaginate = $oPaginate->getSimplePaginate();
  127. }
  128. return $this->parseHtmlByName('attach_photo_popup.html', array(
  129. 'style_prefix' => $sStylePrefix,
  130. 'photo' => $this->_getPhoto($aPhotos[$iStart]),
  131. 'bx_if:show_paginate' => array(
  132. 'condition' => !empty($sPaginate),
  133. 'content' => array(
  134. 'style_prefix' => $sStylePrefix,
  135. 'paginate' => $sPaginate
  136. )
  137. )
  138. ));
  139. }
  140. public function getPost(&$aEvent, $aBrowseParams = array())
  141. {
  142. $aResult = $this->_oConfig->isSystem($aEvent['type'], $aEvent['action']) ? $this->_getSystemData($aEvent) : $this->_getCommonData($aEvent);
  143. if(empty($aResult) || empty($aResult['owner_id']) || empty($aResult['content']))
  144. return '';
  145. list($sUserName) = $this->getModule()->getUserInfo($aResult['owner_id']);
  146. if(empty($aEvent['title']) || empty($aEvent['description'])) {
  147. $sTitle = !empty($aResult['title']) ? $aResult['title'] : '';
  148. if($sTitle == '') {
  149. $sSample = !empty($aResult['content']['sample']) ? $aResult['content']['sample'] : '_bx_timeline_txt_sample';
  150. $sTitle = _t('_bx_timeline_txt_user_added_sample', $sUserName, _t($sSample));
  151. }
  152. $sDescription = !empty($aResult['description']) ? $aResult['description'] : '';
  153. if($sDescription == '' && !empty($aResult['content']['text']))
  154. $sDescription = $aResult['content']['text'];
  155. $this->_oDb->updateEvent(array(
  156. 'title' => bx_process_input(strip_tags($sTitle)),
  157. 'description' => bx_process_input(strip_tags($sDescription))
  158. ), array('id' => $aEvent['id']));
  159. }
  160. $aEvent['object_owner_id'] = $aResult['owner_id'];
  161. $aEvent['content'] = $aResult['content'];
  162. $aEvent['votes'] = $aResult['votes'];
  163. $aEvent['comments'] = $aResult['comments'];
  164. $sType = !empty($aResult['content_type']) ? $aResult['content_type'] : BX_TIMELINE_PARSE_TYPE_DEFAULT;
  165. return $this->_getPost($sType, $aEvent, $aBrowseParams);
  166. }
  167. public function getPosts($aParams)
  168. {
  169. $iStart = $aParams['start'];
  170. $iPerPage = $aParams['per_page'];
  171. $aParamsDb = $aParams;
  172. //--- Check for Previous
  173. $bPrevious = false;
  174. if($iStart - 1 >= 0) {
  175. $aParamsDb['start'] -= 1;
  176. $aParamsDb['per_page'] += 1;
  177. $bPrevious = true;
  178. }
  179. //--- Check for Next
  180. $aParamsDb['per_page'] += 1;
  181. $aEvents = $this->_oDb->getEvents($aParamsDb);
  182. //--- Check for Previous
  183. if($bPrevious)
  184. $aEvent = array_shift($aEvents);
  185. //--- Check for Next
  186. $bNext = false;
  187. if(count($aEvents) > $iPerPage) {
  188. $aEvent = array_pop($aEvents);
  189. $bNext = true;
  190. }
  191. $iEvents = count($aEvents);
  192. $sContent = $this->getEmpty($iEvents <= 0);
  193. foreach($aEvents as $aEvent) {
  194. $sEvent = $this->getPost($aEvent, $aParams);
  195. if(empty($sEvent))
  196. continue;
  197. $sContent .= $sEvent;
  198. }
  199. $iYearSel = (int)$aParams['timeline'];
  200. $iYearMin = $this->_oDb->getMaxDuration($aParams);
  201. $sBack = $this->getBack($iYearSel);
  202. $sLoadMore = $this->getLoadMore($iStart, $iPerPage, $bNext, $iYearSel, $iYearMin, $iEvents > 0);
  203. return array($sContent, $sLoadMore, $sBack);
  204. }
  205. public function getEmpty($bVisible)
  206. {
  207. return $this->parseHtmlByName('empty.html', array(
  208. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  209. 'visible' => $bVisible ? 'block' : 'none',
  210. 'content' => MsgBox(_t('_bx_timeline_txt_msg_no_results'))
  211. ));
  212. }
  213. public function getBack($iYearSel)
  214. {
  215. if($iYearSel == 0)
  216. return '';
  217. $sStylePrefix = $this->_oConfig->getPrefix('style');
  218. $sJsObject = $this->_oConfig->getJsObject('view');
  219. $iYearNow = date('Y', time());
  220. return $this->parseHtmlByName('back.html', array(
  221. 'style_prefix' => $sStylePrefix,
  222. 'href' => 'javascript:void(0)',
  223. 'title' => _t('_bx_timeline_txt_jump_to_n_year', $iYearNow),
  224. 'bx_repeat:attrs' => array(
  225. array('key' => 'onclick', 'value' => 'javascript:' . $sJsObject . '.changeTimeline(this, 0)')
  226. ),
  227. 'content' => _t('_bx_timeline_txt_jump_to_recent')
  228. ));
  229. }
  230. public function getLoadMore($iStart, $iPerPage, $bEnabled, $iYearSel, $iYearMin, $bVisible = true)
  231. {
  232. $sStylePrefix = $this->_oConfig->getPrefix('style');
  233. $sJsObject = $this->_oConfig->getJsObject('view');
  234. $sYears = '';
  235. if(!empty($iYearMin)) {
  236. $iYearMax = date('Y', time()) - 1;
  237. for($i = $iYearMax; $i >= $iYearMin; $i--)
  238. $sYears .= ($i != $iYearSel ? $this->parseHtmlByName('bx_a.html', array(
  239. 'href' => 'javascript:void(0)',
  240. 'title' => _t('_bx_timeline_txt_jump_to_n_year', $i),
  241. 'bx_repeat:attrs' => array(
  242. array('key' => 'onclick', 'value' => 'javascript:' . $sJsObject . '.changeTimeline(this, ' . $i . ')')
  243. ),
  244. 'content' => $i
  245. )) : $i) . ', ';
  246. $sYears = substr($sYears, 0, -2);
  247. }
  248. $aTmplVars = array(
  249. 'style_prefix' => $sStylePrefix,
  250. 'visible' => $bEnabled && $bVisible ? 'block' : 'none',
  251. 'bx_if:is_disabled' => array(
  252. 'condition' => !$bEnabled,
  253. 'content' => array()
  254. ),
  255. 'bx_if:show_on_click' => array(
  256. 'condition' => $bEnabled,
  257. 'content' => array(
  258. 'on_click' => 'javascript:' . $sJsObject . '.changePage(this, ' . ($iStart + $iPerPage) . ', ' . $iPerPage . ')'
  259. )
  260. ),
  261. 'bx_if:show_jump_to' => array(
  262. 'condition' => !empty($sYears),
  263. 'content' => array(
  264. 'style_prefix' => $sStylePrefix,
  265. 'years' => $sYears
  266. )
  267. )
  268. );
  269. return $this->parseHtmlByName('load_more.html', $aTmplVars);
  270. }
  271. public function getComments($sSystem, $iId)
  272. {
  273. $oModule = $this->getModule();
  274. $sStylePrefix = $this->_oConfig->getPrefix('style');
  275. $oCmts = $oModule->getCmtsObject($sSystem, $iId);
  276. if($oCmts === false)
  277. return '';
  278. $aComments = $oCmts->getCommentsBlock(0, 0, false);
  279. return $this->parseHtmlByName('comments.html', array(
  280. 'style_prefix' => $sStylePrefix,
  281. 'id' => $iId,
  282. 'content' => $aComments['content']
  283. ));
  284. }
  285. public function getShareElement($iOwnerId, $sType, $sAction, $iObjectId, $aParams = array())
  286. {
  287. $aShared = $this->_oDb->getShared($sType, $sAction, $iObjectId);
  288. if(empty($aShared) || !is_array($aShared))
  289. return '';
  290. if($this->getModule()->isAllowedShare($aShared) !== true)
  291. return '';
  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. $sDoShare = '';
  298. if($bShowDoShareIcon)
  299. $sDoShare .= $this->parseHtmlByName('bx_icon.html', array('name' => 'share'));
  300. if($bShowDoShareLabel)
  301. $sDoShare .= ($sDoShare != '' ? ' ' : '') . _t('_bx_timeline_txt_do_share');
  302. $sDoShare = $this->parseHtmlByName('bx_a.html', array(
  303. 'href' => 'javascript:void(0)',
  304. 'title' => _t('_bx_timeline_txt_do_share'),
  305. 'bx_repeat:attrs' => array(
  306. array('key' => 'class', 'value' => ($bShowDoShareAsButton ? 'bx-btn' : '') . ($bShowDoShareAsButtonSmall ? 'bx-btn bx-btn-small' : '')),
  307. array('key' => 'onclick', 'value' => $this->getShareJsClick($iOwnerId, $sType, $sAction, $iObjectId))
  308. ),
  309. 'content' => $sDoShare
  310. ));
  311. $sStylePrefix = $this->_oConfig->getPrefix('style');
  312. $sStylePrefixShare = $sStylePrefix . '-share-';
  313. return $this->parseHtmlByName('share_element_block.html', array(
  314. 'style_prefix' => $sStylePrefix,
  315. 'html_id' => $this->_oConfig->getHtmlIds('share', 'main') . $aShared['id'],
  316. 'class' => ($bShowDoShareAsButton ? $sStylePrefixShare . 'button' : '') . ($bShowDoShareAsButtonSmall ? $sStylePrefixShare . 'button-small' : ''),
  317. 'count' => $aShared['shares'],
  318. 'do_share' => $sDoShare,
  319. 'bx_if:show_counter' => array(
  320. 'condition' => $bShowCounter,
  321. 'content' => array(
  322. 'style_prefix' => $sStylePrefix,
  323. 'counter' => $this->getShareCounter($sType, $sAction, $iObjectId)
  324. )
  325. ),
  326. 'script' => $this->getShareJsScript()
  327. ));
  328. }
  329. public function getShareCounter($sType, $sAction, $iObjectId)
  330. {
  331. $sStylePrefix = $this->_oConfig->getPrefix('style');
  332. $sJsObject = $this->_oConfig->getJsObject('share');
  333. $aEvent = $this->_oDb->getShared($sType, $sAction, $iObjectId);
  334. return $this->parseHtmlByName('share_counter.html', array(
  335. 'href' => 'javascript:void(0)',
  336. 'title' => _t('_bx_timeline_txt_shared_by'),
  337. 'bx_repeat:attrs' => array(
  338. array('key' => 'id', 'value' => $this->_oConfig->getHtmlIds('share', 'counter') . $aEvent['id']),
  339. array('key' => 'class', 'value' => $sStylePrefix . '-counter'),
  340. array('key' => 'onclick', 'value' => 'javascript:' . $sJsObject . '.toggleByPopup(this, ' . $aEvent['id'] . ')')
  341. ),
  342. 'content' => !empty($aEvent['shares']) && (int)$aEvent['shares'] > 0 ? $aEvent['shares'] : ''
  343. ));
  344. }
  345. public function getSharedBy($iId)
  346. {
  347. $aTmplUsers = array();
  348. $oModule = $this->getModule();
  349. $sStylePrefix = $this->_oConfig->getPrefix('style');
  350. $aUserIds = $this->_oDb->getSharedBy($iId);
  351. foreach($aUserIds as $iUserId) {
  352. list($sUserName, $sUserUrl, $sUserIcon, $sUserUnit) = $oModule->getUserInfo($iUserId);
  353. $aTmplUsers[] = array(
  354. 'style_prefix' => $sStylePrefix,
  355. 'user_unit' => $sUserUnit
  356. );
  357. }
  358. if(empty($aTmplUsers))
  359. $aTmplUsers = MsgBox(_t('_Empty'));
  360. return $this->parseHtmlByName('share_by_list.html', array(
  361. 'style_prefix' => $sStylePrefix,
  362. 'bx_repeat:list' => $aTmplUsers
  363. ));
  364. }
  365. public function getShareJsScript()
  366. {
  367. $this->addCss(array('share.css'));
  368. $this->addJs(array('main.js', 'share.js'));
  369. return $this->getJsCode('share');
  370. }
  371. public function getShareJsClick($iOwnerId, $sType, $sAction, $iObjectId)
  372. {
  373. $sJsObject = $this->_oConfig->getJsObject('share');
  374. $sFormat = "%s.shareItem(this, %d, '%s', '%s', %d);";
  375. $iOwnerId = !empty($iOwnerId) ? (int)$iOwnerId : $this->getModule()->getUserId(); //--- in whose timeline the content will be shared
  376. return sprintf($sFormat, $sJsObject, $iOwnerId, $sType, $sAction, (int)$iObjectId);
  377. }
  378. public function getAttachLinkForm()
  379. {
  380. $sStylePrefix = $this->_oConfig->getPrefix('style');
  381. $sJsObject = $this->_oConfig->getJsObject('post');
  382. $aForm = $this->getModule()->getFormAttachLink();
  383. return $this->parseHtmlByName('attach_link_form.html', array(
  384. 'style_prefix' => $sStylePrefix,
  385. 'js_object' => $sJsObject,
  386. 'form_id' => $aForm['form_id'],
  387. 'form' => $aForm['form'],
  388. ));
  389. }
  390. public function getAttachLinkField($iUserId)
  391. {
  392. $sStylePrefix = $this->_oConfig->getPrefix('style');
  393. $aLinks = $this->_oDb->getUnusedLinks($iUserId);
  394. $sLinks = '';
  395. foreach($aLinks as $aLink)
  396. $sLinks .= $this->getAttachLinkItem($iUserId, $aLink);
  397. return $this->parsePageByName('attach_link_form_field.html', array(
  398. 'html_id' => $this->_oConfig->getHtmlIds('post', 'attach_link_form_field'),
  399. 'style_prefix' => $sStylePrefix,
  400. 'links' => $sLinks
  401. ));
  402. }
  403. public function getAttachLinkItem($iUserId, $mixedLink)
  404. {
  405. $aLink = is_array($mixedLink) ? $mixedLink : $this->_oDb->getUnusedLinks($iUserId, (int)$mixedLink);
  406. if(empty($aLink) || !is_array($aLink))
  407. return '';
  408. $sStylePrefix = $this->_oConfig->getPrefix('style');
  409. $sJsObject = $this->_oConfig->getJsObject('post');
  410. $sLinkIdPrefix = $this->_oConfig->getHtmlIds('post', 'attach_link_item');
  411. return $this->parsePageByName('attach_link_item.html', array(
  412. 'html_id' => $sLinkIdPrefix . $aLink['id'],
  413. 'style_prefix' => $sStylePrefix,
  414. 'js_object' => $sJsObject,
  415. 'id' => $aLink['id'],
  416. 'url' => $aLink['url'],
  417. 'title' => $aLink['title'],
  418. ));
  419. }
  420. protected function _getPost($sType, $aEvent, $aBrowseParams = array())
  421. {
  422. $oModule = $this->getModule();
  423. $sStylePrefix = $this->_oConfig->getPrefix('style');
  424. $sJsObject = $this->_oConfig->getJsObject('view');
  425. list($sAuthorName, $sAuthorUrl, $sAuthorIcon) = $oModule->getUserInfo($aEvent['object_owner_id']);
  426. $bAuthorIcon = !empty($sAuthorIcon);
  427. $aTmplVarsMenuItemManage = $this->_getTmplVarsMenuItemManage($aEvent, $aBrowseParams);
  428. $aTmplVarsMenuItemActions = $this->_getTmplVarsMenuItemActions($aEvent, $aBrowseParams);
  429. $aTmplVarsTimelineOwner = array();
  430. if(isset($aBrowseParams['type']) && $aBrowseParams['type'] == BX_TIMELINE_TYPE_CONNECTIONS)
  431. $aTmplVarsTimelineOwner = $this->_getTmplVarsTimelineOwner($aEvent);
  432. $bBrowseItem = isset($aBrowseParams['type']) && $aBrowseParams['type'] == BX_TIMELINE_TYPE_ITEM;
  433. $aTmplVars = array (
  434. 'style_prefix' => $sStylePrefix,
  435. 'js_object' => $sJsObject,
  436. 'class' => $bBrowseItem ? 'bx-tl-view-sizer' : 'bx-tl-grid-sizer',
  437. 'id' => $aEvent['id'],
  438. 'bx_if:show_menu_item_manage' => array(
  439. 'condition' => !empty($aTmplVarsMenuItemManage),
  440. 'content' => $aTmplVarsMenuItemManage
  441. ),
  442. 'bx_if:show_icon' => array(
  443. 'condition' => $bAuthorIcon,
  444. 'content' => array(
  445. 'author_icon' => $sAuthorIcon
  446. )
  447. ),
  448. 'bx_if:show_icon_empty' => array(
  449. 'condition' => !$bAuthorIcon,
  450. 'content' => array()
  451. ),
  452. 'item_owner_url' => $sAuthorUrl,
  453. 'item_owner_name' => $sAuthorName,
  454. 'bx_if:show_timeline_owner' => array(
  455. 'condition' => !empty($aTmplVarsTimelineOwner),
  456. 'content' => $aTmplVarsTimelineOwner
  457. ),
  458. 'item_view_url' => $this->_oConfig->getItemViewUrl($aEvent),
  459. 'item_date' => bx_time_js($aEvent['date']),
  460. 'content' => is_string($aEvent['content']) ? $aEvent['content'] : $this->_getContent($sType, $aEvent['content'], $aBrowseParams),
  461. 'bx_if:show_menu_item_actions' => array(
  462. 'condition' => !empty($aTmplVarsMenuItemActions),
  463. 'content' => $aTmplVarsMenuItemActions
  464. ),
  465. 'comments' => $bBrowseItem ? $this->_getComments($aEvent['comments']) : '',
  466. 'votes' => $this->_getVotes($aEvent['votes'])
  467. );
  468. return $this->parseHtmlByName('item.html', $aTmplVars);
  469. }
  470. protected function _getContent($sType, $aContent, $aBrowseParams = array())
  471. {
  472. $sMethod = '_getTmplVarsContent' . ucfirst($sType);
  473. if(!method_exists($this, $sMethod))
  474. return '';
  475. $aTmplVars = $this->$sMethod($aContent, $aBrowseParams);
  476. return $this->parseHtmlByName('type_' . $sType . '.html', $aTmplVars);
  477. }
  478. protected function _getComments($aComments)
  479. {
  480. $mixedComments = $this->getModule()->getCommentsData($aComments);
  481. if($mixedComments === false)
  482. return '';
  483. list($sSystem, $iObjectId, $iCount) = $mixedComments;
  484. return $this->getComments($sSystem, $iObjectId);
  485. }
  486. protected function _getVotes($aVotes)
  487. {
  488. $oModule = $this->getModule();
  489. $mixedVotes = $oModule->getVotesData($aVotes);
  490. if($mixedVotes === false)
  491. return '';
  492. list($sSystem, $iObjectId, $iCount) = $mixedVotes;
  493. $oVote = $oModule->getVoteObject($sSystem, $iObjectId);
  494. if($oVote === false)
  495. return '';
  496. return $oVote->getJsScript();
  497. }
  498. protected function _getPhoto($iPhotoId)
  499. {
  500. $sStylePrefix = $this->_oConfig->getPrefix('style');
  501. $sJsObject = $this->_oConfig->getJsObject('view');
  502. bx_import('BxDolStorage');
  503. $oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage'));
  504. return $this->parsePageByName('bx_img.html', array(
  505. 'src' => $oStorage->getFileUrlById($iPhotoId),
  506. 'bx_repeat:attrs' => array(
  507. array('key' => 'onclick', 'value' => $sJsObject . '.hidePhoto(this)'),
  508. array('key' => 'class', 'value' => $sStylePrefix . '-attached-image')
  509. ),
  510. ));
  511. }
  512. protected function _getTmplVarsMenuItemManage(&$aEvent) {
  513. bx_import('BxDolMenu');
  514. $oMenu = BxDolMenu::getObjectInstance($this->_oConfig->getObject('menu_item_manage'));
  515. $oMenu->setEvent($aEvent);
  516. bx_import('BxTemplFunctions');
  517. $sMenu = BxTemplFunctions::getInstance()->designBoxMenu($oMenu);
  518. if(empty($sMenu))
  519. return array();
  520. return array(
  521. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  522. 'js_object' => $this->_oConfig->getJsObject('view'),
  523. 'menu_item_manage' => $sMenu
  524. );
  525. }
  526. protected function _getTmplVarsMenuItemActions(&$aEvent) {
  527. bx_import('BxDolMenu');
  528. $oMenu = BxDolMenu::getObjectInstance($this->_oConfig->getObject('menu_item_actions'));
  529. $oMenu->setEvent($aEvent);
  530. $sMenu = $oMenu->getCode();
  531. if(empty($sMenu))
  532. return array();
  533. return array(
  534. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  535. 'js_object' => $this->_oConfig->getJsObject('view'),
  536. 'menu_item_actions' => $sMenu
  537. );
  538. }
  539. protected function _getTmplVarsTimelineOwner(&$aEvent)
  540. {
  541. $oModule = $this->getModule();
  542. $aTmplVarsTimelineOwner = array();
  543. if((int)$aEvent['owner_id'] != (int)$aEvent['object_owner_id']) {
  544. list($sTimelineAuthorName, $sTimelineAuthorUrl) = $oModule->getUserInfo($aEvent['owner_id']);
  545. $aTmplVarsTimelineOwner = array(
  546. 'owner_url' => $sTimelineAuthorUrl,
  547. 'owner_username' => $sTimelineAuthorName,
  548. );
  549. }
  550. return $aTmplVarsTimelineOwner;
  551. }
  552. protected function _getTmplVarsContentPost($aContent, $aBrowseParams = array())
  553. {
  554. $sStylePrefix = $this->_oConfig->getPrefix('style');
  555. $sJsObject = $this->_oConfig->getJsObject('view');
  556. //--- Process Text ---//
  557. $sUrl = isset($aContent['url']) ? bx_html_attribute($aContent['url']) : '';
  558. $sTitle = $sTitleAttr = '';
  559. if(isset($aContent['title'])) {
  560. $sTitle = bx_process_output($aContent['title']);
  561. $sTitleAttr = bx_html_attribute($aContent['title']);
  562. }
  563. if(!empty($sUrl) && !empty($sTitle))
  564. $sTitle = $this->parseHtmlByName('bx_a.html', array(
  565. 'href' => $sUrl,
  566. 'title' => $sTitleAttr,
  567. 'bx_repeat:attrs' => array(
  568. array('key' => 'class', 'value' => $sStylePrefix . '-title')
  569. ),
  570. 'content' => $sTitle
  571. ));
  572. $sText = isset($aContent['text']) ? strip_tags($aContent['text'], '<p><br>') : '';
  573. $sTextMore = '';
  574. $iMaxLength = $this->_oConfig->getCharsDisplayMax();
  575. if(strlen($sText) > $iMaxLength) {
  576. $iLength = strpos($sText, ' ', $iMaxLength);
  577. $sTextMore = trim(substr($sText, $iLength));
  578. $sText = trim(substr($sText, 0, $iLength));
  579. }
  580. $sText = $this->_prepareTextForOutput($sText);
  581. $sTextMore = $this->_prepareTextForOutput($sTextMore);
  582. //--- Process Links ---//
  583. $aTmplVarsLinks = array();
  584. if(!empty($aContent['links']))
  585. foreach($aContent['links'] as $aLink)
  586. $aTmplVarsLinks[] = array(
  587. 'style_prefix' => $sStylePrefix,
  588. 'url' => $aLink['url'],
  589. 'title' => $aLink['title'],
  590. 'bx_if:show_text' => array(
  591. 'condition' => !empty($aLink['text']),
  592. 'content' => array(
  593. 'style_prefix' => $sStylePrefix,
  594. 'text' => $aLink['text']
  595. )
  596. )
  597. );
  598. //--- Process Photos ---//
  599. $aTmplVarsImages = array();
  600. if(!empty($aContent['images'])) {
  601. $bBrowseItem = isset($aBrowseParams['type']) && $aBrowseParams['type'] == BX_TIMELINE_TYPE_ITEM;
  602. foreach($aContent['images'] as $aImage) {
  603. $sImage = '';
  604. if(!empty($aImage['src']))
  605. $sImage = $this->parseHtmlByName('bx_img.html', array(
  606. 'src' => $bBrowseItem && !empty($aImage['src_orig']) ? $aImage['src_orig'] : $aImage['src'],
  607. 'bx_repeat:attrs' => array(
  608. array('key' => 'class', 'value' => $sStylePrefix . '-item-image')
  609. )
  610. ));
  611. if(!empty($sImage) && (isset($aImage['url']) || isset($aImage['onclick']))) {
  612. $aAttrs = array();
  613. if(isset($aImage['onclick']))
  614. $aAttrs[] = array('key' => 'onclick', 'value' => $aImage['onclick']);
  615. $sImage = $this->parseHtmlByName('bx_a.html', array(
  616. 'href' => isset($aImage['url']) ? $aImage['url'] : 'javascript:void(0)',
  617. 'title' => '',
  618. 'bx_repeat:attrs' => $aAttrs,
  619. 'content' => $sImage
  620. ));
  621. }
  622. $aTmplVarsImages[] = array(
  623. 'style_prefix' => $sStylePrefix,
  624. 'image' => $sImage
  625. );
  626. }
  627. }
  628. return array(
  629. 'style_prefix' => $sStylePrefix,
  630. 'bx_if:show_title' => array(
  631. 'condition' => !empty($sTitle),
  632. 'content' => array(
  633. 'style_prefix' => $sStylePrefix,
  634. 'title' => $sTitle,
  635. )
  636. ),
  637. 'bx_if:show_content' => array(
  638. 'condition' => !empty($sText),
  639. 'content' => array(
  640. 'style_prefix' => $sStylePrefix,
  641. 'item_content' => $sText,
  642. 'bx_if:show_more' => array(
  643. 'condition' => !empty($sTextMore),
  644. 'content' => array(
  645. 'style_prefix' => $sStylePrefix,
  646. 'js_object' => $sJsObject,
  647. 'item_content_more' => $sTextMore
  648. )
  649. ),
  650. )
  651. ),
  652. 'bx_if:show_links' => array(
  653. 'condition' => !empty($aTmplVarsLinks),
  654. 'content' => array(
  655. 'style_prefix' => $sStylePrefix,
  656. 'bx_repeat:links' => $aTmplVarsLinks
  657. )
  658. ),
  659. 'bx_if:show_images' => array(
  660. 'condition' => !empty($aTmplVarsImages),
  661. 'content' => array(
  662. 'style_prefix' => $sStylePrefix,
  663. 'bx_repeat:images' => $aTmplVarsImages
  664. )
  665. )
  666. );
  667. }
  668. protected function _getTmplVarsContentShare($aContent, $aBrowseParams = array())
  669. {
  670. $sStylePrefix = $this->_oConfig->getPrefix('style');
  671. $sOwnerLink = $this->parseHtmlByName('bx_a.html', array(
  672. 'href' => $aContent['owner_url'],
  673. 'title' => '',
  674. 'bx_repeat:attrs' => array(),
  675. 'content' => $aContent['owner_name']
  676. ));
  677. $sSample = _t($aContent['sample']);
  678. $sSampleLink = empty($aContent['url']) ? $sSample : $this->parseHtmlByName('bx_a.html', array(
  679. 'href' => $aContent['url'],
  680. 'title' => '',
  681. 'bx_repeat:attrs' => array(),
  682. 'content' => $sSample
  683. ));
  684. $sTitle = _t('_bx_timeline_txt_shared', $sOwnerLink, $sSampleLink);
  685. $sText = $this->_getContent($aContent['parse_type'], $aContent);
  686. return array(
  687. 'bx_if:show_title' => array(
  688. 'condition' => !empty($sTitle),
  689. 'content' => array(
  690. 'style_prefix' => $sStylePrefix,
  691. 'title' => $sTitle,
  692. )
  693. ),
  694. 'bx_if:show_content' => array(
  695. 'condition' => !empty($sText),
  696. 'content' => array(
  697. 'style_prefix' => $sStylePrefix,
  698. 'content' => $sText,
  699. )
  700. )
  701. );
  702. }
  703. protected function _getSystemData(&$aEvent)
  704. {
  705. $sHandler = $aEvent['type'] . '_' . $aEvent['action'];
  706. if(!$this->_oConfig->isHandler($sHandler))
  707. return '';
  708. $mixedResult = array();
  709. $aHandler = $this->_oConfig->getHandlers($sHandler);
  710. if(empty($aHandler['module_uri']) && empty($aHandler['module_class']) && empty($aHandler['module_method'])) {
  711. $sMethod = 'display' . bx_gen_method_name($aHandler['alert_unit'] . '_' . $aHandler['alert_action']);
  712. if(!method_exists($this, $sMethod))
  713. return '';
  714. $mixedResult = $this->$sMethod($aEvent);
  715. }
  716. else {
  717. $aEvent['js_mode'] = $this->_oConfig->getJsMode();
  718. $mixedResult = BxDolService::call($aHandler['module_name'], $aHandler['module_method'], array($aEvent), $aHandler['module_class']);
  719. }
  720. return $mixedResult;
  721. }
  722. protected function _getCommonData(&$aEvent)
  723. {
  724. $oModule = $this->getModule();
  725. $sJsObject = $this->_oConfig->getJsObject('view');
  726. $sPrefix = $this->_oConfig->getPrefix('common_post');
  727. $sType = str_replace($sPrefix, '', $aEvent['type']);
  728. $aResult = array(
  729. 'owner_id' => $aEvent['object_id'],
  730. 'content_type' => $sType,
  731. 'content' => array(
  732. 'sample' => '_bx_timeline_txt_sample',
  733. 'url' => $this->_oConfig->getItemViewUrl($aEvent)
  734. ), //a string to display or array to parse default template before displaying.
  735. 'votes' => '',
  736. 'comments' => '',
  737. 'title' => '', //may be empty.
  738. 'description' => '' //may be empty.
  739. );
  740. switch($sType) {
  741. case BX_TIMELINE_PARSE_TYPE_POST:
  742. if(!empty($aEvent['content']))
  743. $aResult['content'] = array_merge($aResult['content'], unserialize($aEvent['content']));
  744. $aLinks = $this->_oDb->getLinks($aEvent['id']);
  745. if(!empty($aLinks) && is_array($aLinks))
  746. foreach($aLinks as $aLink)
  747. $aResult['content']['links'][] = array(
  748. 'url' => $aLink['url'],
  749. 'title' => $aLink['title'],
  750. 'text' => $aLink['text']
  751. );
  752. $aPhotos = $this->_oDb->getPhotos($aEvent['id']);
  753. if(!empty($aPhotos) && is_array($aPhotos)) {
  754. bx_import('BxDolStorage');
  755. $oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage'));
  756. bx_import('BxDolImageTranscoder');
  757. $oTranscoder = BxDolImageTranscoder::getObjectInstance($this->_oConfig->getObject('transcoder_view'));
  758. foreach($aPhotos as $iPhotoId) {
  759. $iPhotoIndex = array_search($iPhotoId, $aPhotos);
  760. $aResult['content']['images'][] = array(
  761. 'src' => $oTranscoder->getImageUrl($iPhotoId),
  762. 'src_orig' => $oStorage->getFileUrlById($iPhotoId),
  763. 'title' => '',
  764. 'onclick' => $sJsObject . '.showPhoto(this, ' . $aEvent['id'] . ', ' . $iPhotoIndex . ')'
  765. );
  766. }
  767. }
  768. break;
  769. case BX_TIMELINE_PARSE_TYPE_SHARE:
  770. if(empty($aEvent['content']))
  771. break;
  772. $aContent = unserialize($aEvent['content']);
  773. if(!$this->_oConfig->isSystem($aContent['type'] , $aContent['action'])) {
  774. $aShared = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $aContent['object_id']));
  775. $aShared = $this->_getCommonData($aShared);
  776. }
  777. else
  778. $aShared = $this->_getSystemData($aContent);
  779. $aResult['content'] = array_merge($aContent, $aShared['content']);
  780. $aResult['content']['parse_type'] = !empty($aShared['content_type']) ? $aShared['content_type'] : BX_TIMELINE_PARSE_TYPE_DEFAULT;
  781. $aResult['content']['owner_id'] = $aShared['owner_id'];
  782. list($aResult['content']['owner_name'], $aResult['content']['owner_url']) = $oModule->getUserInfo($aShared['owner_id']);
  783. list($sUserName) = $oModule->getUserInfo($aEvent['object_id']);
  784. $sSample = !empty($aResult['content']['sample']) ? $aResult['content']['sample'] : '_bx_timeline_txt_sample';
  785. $aResult['title'] = _t('_bx_timeline_txt_user_shared_sample', $sUserName, $aResult['content']['owner_name'], _t($sSample));
  786. $aResult['description'] = '';
  787. break;
  788. }
  789. $sSystem = $this->_oConfig->getSystemName('vote');
  790. if($oModule->getVoteObject($sSystem, $aEvent['id']) !== false)
  791. $aResult['votes'] = array(
  792. 'system' => $sSystem,
  793. 'object_id' => $aEvent['id'],
  794. 'count' => $aEvent['votes']
  795. );
  796. $sSystem = $this->_oConfig->getSystemName('comment');
  797. if($oModule->getCmtsObject($sSystem, $aEvent['id']) !== false)
  798. $aResult['comments'] = array(
  799. 'system' => $sSystem,
  800. 'object_id' => $aEvent['id'],
  801. 'count' => $aEvent['comments']
  802. );
  803. return $aResult;
  804. }
  805. protected function _prepareTextForOutput($s)
  806. {
  807. $sHttp = '';
  808. $sPattern = $this->_oConfig->getPregPattern('url');
  809. $aMatches = array();
  810. if(preg_match($sPattern, $s, $aMatches) && empty($aMatches[1]))
  811. $sHttp = 'http://';
  812. $s = bx_process_output($s, BX_DATA_TEXT_MULTILINE);
  813. $s = preg_replace($sPattern, '<a href="' . $sHttp . '$0" target="_blank">$0</a>', $s);
  814. return $s;
  815. }
  816. }
  817. /** @} */