BxForumModule.php 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982
  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 Forum Forum
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. class BxForumModule extends BxBaseModTextModule
  12. {
  13. function __construct(&$aModule)
  14. {
  15. parent::__construct($aModule);
  16. }
  17. public function sortParticipants ($aParticipants, $iProfileIdLastComment, $iProfileIdAuthor, $iProfileIdCurrent = 0)
  18. {
  19. if (!$iProfileIdCurrent)
  20. $iProfileIdCurrent = bx_get_logged_profile_id();
  21. $aMoveUp = array($iProfileIdCurrent, $iProfileIdLastComment, $iProfileIdAuthor);
  22. asort($aParticipants, SORT_NUMERIC);
  23. foreach ($aMoveUp as $iProfileId) {
  24. if (!isset($aParticipants[$iProfileId]))
  25. continue;
  26. $a = array($iProfileId => $aParticipants[$iProfileId]);
  27. unset($aParticipants[$iProfileId]);
  28. $aParticipants = $a + $aParticipants;
  29. }
  30. return $aParticipants;
  31. }
  32. /**
  33. * Action methods
  34. */
  35. public function actionUpdateStatus($sAction = '', $iContentId = 0)
  36. {
  37. if(empty($sAction) && bx_get('action') !== false)
  38. $sAction = bx_process_input(bx_get('action'));
  39. if(empty($iContentId) && bx_get('id') !== false)
  40. $iContentId = (int)bx_get('id');
  41. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  42. if(empty($aContentInfo) || !is_array($aContentInfo))
  43. return echoJson(array('code' => 1, 'message' => _t('_bx_forum_err_not_found')));
  44. $sMethodCheck = 'checkAllowed' . bx_gen_method_name($sAction) . 'AnyEntry';
  45. $sResult = $this->$sMethodCheck($aContentInfo);
  46. if($sResult !== CHECK_ACTION_RESULT_ALLOWED)
  47. return echoJson(array('code' => 2, 'message' => $sResult));
  48. bx_audit(
  49. $iContentId,
  50. $this->getName(),
  51. '_sys_audit_action_' . $sAction,
  52. $this->_prepareAuditParams($aContentInfo, false)
  53. );
  54. if(!$this->_oDb->updateStatus($sAction, $aContentInfo))
  55. return echoJson(array('code' => 3, 'message' => _t('_error occured')));
  56. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  57. $this->alertAfterEdit($aContentInfo);
  58. echoJson(array('code' => 0, 'id' => $iContentId, 'reload' => 1));
  59. }
  60. public function actionAjaxGetAuthors()
  61. {
  62. $aResult = BxDolService::call('system', 'profiles_search', array(bx_get('term')), 'TemplServiceProfiles');
  63. header('Content-Type:text/javascript; charset=utf-8');
  64. echo json_encode($aResult);
  65. }
  66. /**
  67. * Service methods
  68. */
  69. /**
  70. * @page service Service Calls
  71. * @section bx_forum Discussions
  72. * @subsection bx_forum-other Other
  73. * @subsubsection bx_forum-get_searchable_fields get_searchable_fields
  74. *
  75. * @code bx_srv('bx_forum', 'get_searchable_fields', [...]); @endcode
  76. *
  77. * Get searchable fields for Studio settings.
  78. *
  79. * @return an array with key-value pairs to be used in settings dropdown field.
  80. *
  81. * @see BxForumModule::serviceGetSearchableFields
  82. */
  83. /**
  84. * @ref bx_forum-get_searchable_fields "get_searchable_fields"
  85. */
  86. public function serviceGetSearchableFields ($aInputsAdd = array())
  87. {
  88. $CNF = &$this->_oConfig->CNF;
  89. $aResult = parent::serviceGetSearchableFields($aInputsAdd);
  90. $aResult[$CNF['FIELD_TEXT_COMMENTS']] = _t('_bx_forum_form_entry_input_text_comments');
  91. return $aResult;
  92. }
  93. /**
  94. * Service methods
  95. */
  96. /**
  97. * @page service Service Calls
  98. * @section bx_forum Discussions
  99. * @subsection bx_forum-other Other
  100. * @subsubsection bx_forum-get_info get_info
  101. *
  102. * @code bx_srv('bx_forum', 'get_info', [...]); @endcode
  103. *
  104. * Get content info by content ID. Is used in "Content Info Objects" system.
  105. *
  106. * @param $iContentId integer value with content ID.
  107. * @param $bSearchableFieldsOnly (optional) boolean value determining all info or "searchable fields" only will be returned.
  108. * @return an array with content info. Empty array is returned if something is wrong.
  109. *
  110. * @see BxForumModule::serviceGetInfo
  111. */
  112. /**
  113. * @ref bx_forum-get_info "get_info"
  114. */
  115. public function serviceGetInfo ($iContentId, $bSearchableFieldsOnly = true)
  116. {
  117. $aContentInfo = $this->_getFields($iContentId);
  118. if(empty($aContentInfo))
  119. return array();
  120. return $aContentInfo;
  121. }
  122. /**
  123. * @page service Service Calls
  124. * @section bx_forum Discussions
  125. * @subsection bx_forum-page_blocks Page Blocks
  126. * @subsubsection bx_forum-browse_new browse_new
  127. *
  128. * @code bx_srv('bx_forum', 'browse_new', [...]); @endcode
  129. *
  130. * Get page block with a list of items ordered by newness and represented as table.
  131. *
  132. * @param $sUnitView (optional) string with unit view type.
  133. * @param $bEmptyMessage (optional) boolean value determining whether an "Empty" message should be returned or not.
  134. * @param $bAjaxPaginate (optional) boolean value determining whether an Ajax based pagination should be used or not.
  135. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  136. *
  137. * @see BxForumModule::serviceBrowseNew
  138. */
  139. /**
  140. * @ref bx_forum-browse_new "browse_new"
  141. */
  142. public function serviceBrowseNew ($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = false)
  143. {
  144. $sType = 'new';
  145. if($sUnitView != 'table')
  146. return $this->_serviceBrowse($sType, $sUnitView ? array('unit_view' => $sUnitView) : false, BX_DB_PADDING_DEF, $bEmptyMessage, $bAjaxPaginate);
  147. return $this->_serviceBrowseTable(array('type' => $sType), $bShowHeader);
  148. }
  149. /**
  150. * @page service Service Calls
  151. * @section bx_forum Discussions
  152. * @subsection bx_forum-page_blocks Page Blocks
  153. * @subsubsection bx_forum-browse_latest browse_latest
  154. *
  155. * @code bx_srv('bx_forum', 'browse_latest', [...]); @endcode
  156. *
  157. * Get page block with a list of items ordered by Recent Posts in them and represented as table.
  158. *
  159. * @param $sUnitView (optional) string with unit view type.
  160. * @param $bEmptyMessage (optional) boolean value determining whether an "Empty" message should be returned or not.
  161. * @param $bAjaxPaginate (optional) boolean value determining whether an Ajax based pagination should be used or not.
  162. * @param $bShowHeader (optional) boolean value determining whether a resulting table should have Header section or not.
  163. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  164. *
  165. * @see BxForumModule::serviceBrowseNew
  166. */
  167. /**
  168. * @ref bx_forum-browse_latest "browse_latest"
  169. */
  170. public function serviceBrowseLatest($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = false)
  171. {
  172. $sType = 'latest';
  173. if($sUnitView != 'table')
  174. return $this->_serviceBrowse($sType, $sUnitView ? array('unit_view' => $sUnitView) : false, BX_DB_PADDING_DEF, $bEmptyMessage, $bAjaxPaginate);
  175. return $this->_serviceBrowseTable(array('type' => $sType), $bShowHeader);
  176. }
  177. /**
  178. * @page service Service Calls
  179. * @section bx_forum Discussions
  180. * @subsection bx_forum-page_blocks Page Blocks
  181. * @subsubsection bx_forum-browse_featured browse_featured
  182. *
  183. * @code bx_srv('bx_forum', 'browse_featured', [...]); @endcode
  184. *
  185. * Get page block with a list of featured items represented as table.
  186. *
  187. * @param $sUnitView (optional) string with unit view type.
  188. * @param $bEmptyMessage (optional) boolean value determining whether an "Empty" message should be returned or not.
  189. * @param $bAjaxPaginate (optional) boolean value determining whether an Ajax based pagination should be used or not.
  190. * @param $bShowHeader (optional) boolean value determining whether a resulting table should have Header section or not.
  191. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  192. *
  193. * @see BxForumModule::serviceBrowseFeatured
  194. */
  195. /**
  196. * @ref bx_forum-browse_featured "browse_featured"
  197. */
  198. public function serviceBrowseFeatured($sUnitView = false, $bEmptyMessage = false, $bAjaxPaginate = true, $bShowHeader = false)
  199. {
  200. $CNF = &$this->_oConfig->CNF;
  201. $sType = 'featured';
  202. if($sUnitView != 'table')
  203. return $this->_serviceBrowse($sType, $sUnitView ? array('unit_view' => $sUnitView) : false, BX_DB_PADDING_DEF, $bEmptyMessage, $bAjaxPaginate);
  204. return $this->_serviceBrowseTable(array(
  205. 'grid' => $CNF['OBJECT_GRID_FEATURE'],
  206. 'type' => $sType,
  207. 'where' => array('fld' => 'featured', 'val' => 0, 'opr' => '<>'),
  208. 'empty_message' => $bEmptyMessage
  209. ), $bShowHeader);
  210. }
  211. /**
  212. * @page service Service Calls
  213. * @section bx_forum Discussions
  214. * @subsection bx_forum-page_blocks Page Blocks
  215. * @subsubsection bx_forum-browse_top browse_top
  216. *
  217. * @code bx_srv('bx_forum', 'browse_top', [...]); @endcode
  218. *
  219. * Get page block with a list of items ordered by a number of comments and represented as table.
  220. *
  221. * @param $sUnitView (optional) string with unit view type.
  222. * @param $bEmptyMessage (optional) boolean value determining whether an "Empty" message should be returned or not.
  223. * @param $bAjaxPaginate (optional) boolean value determining whether an Ajax based pagination should be used or not.
  224. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  225. *
  226. * @see BxForumModule::serviceBrowseTop
  227. */
  228. /**
  229. * @ref bx_forum-browse_top "browse_top"
  230. */
  231. public function serviceBrowseTop($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = false)
  232. {
  233. $sType = 'top';
  234. if($sUnitView != 'table')
  235. return $this->_serviceBrowse($sType, $sUnitView ? array('unit_view' => $sUnitView) : false, BX_DB_PADDING_DEF, $bEmptyMessage, $bAjaxPaginate);
  236. return $this->_serviceBrowseTable(array('type' => $sType), $bShowHeader);
  237. }
  238. /**
  239. * @page service Service Calls
  240. * @section bx_forum Discussions
  241. * @subsection bx_forum-page_blocks Page Blocks
  242. * @subsubsection bx_forum-browse_popular browse_popular
  243. *
  244. * @code bx_srv('bx_forum', 'browse_popular', [...]); @endcode
  245. *
  246. * Get page block with a list of items ordered by a number of views and represented as table.
  247. *
  248. * @param $sUnitView (optional) string with unit view type.
  249. * @param $bEmptyMessage (optional) boolean value determining whether an "Empty" message should be returned or not.
  250. * @param $bAjaxPaginate (optional) boolean value determining whether an Ajax based pagination should be used or not.
  251. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  252. *
  253. * @see BxForumModule::serviceBrowsePopular
  254. */
  255. /**
  256. * @ref bx_forum-browse_popular "browse_popular"
  257. */
  258. public function serviceBrowsePopular ($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = false)
  259. {
  260. $sType = 'popular';
  261. if($sUnitView != 'table')
  262. return $this->_serviceBrowse($sType, $sUnitView ? array('unit_view' => $sUnitView) : false, BX_DB_PADDING_DEF, $bEmptyMessage, $bAjaxPaginate);
  263. return $this->_serviceBrowseTable(array('type' => $sType), $bShowHeader);
  264. }
  265. /**
  266. * @page service Service Calls
  267. * @section bx_forum Discussions
  268. * @subsection bx_forum-page_blocks Page Blocks
  269. * @subsubsection bx_forum-browse_updated browse_updated
  270. *
  271. * @code bx_srv('bx_forum', 'browse_updated', [...]); @endcode
  272. *
  273. * Get page block with a list of updated items represented as table.
  274. *
  275. * @param $sUnitView (optional) string with unit view type.
  276. * @param $bEmptyMessage (optional) boolean value determining whether an "Empty" message should be returned or not.
  277. * @param $bAjaxPaginate (optional) boolean value determining whether an Ajax based pagination should be used or not.
  278. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  279. *
  280. * @see BxForumModule::serviceBrowseUpdated
  281. */
  282. /**
  283. * @ref bx_forum-browse_updated "browse_updated"
  284. */
  285. public function serviceBrowseUpdated ($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = false)
  286. {
  287. $sType = 'updated';
  288. if($sUnitView != 'table')
  289. return $this->_serviceBrowse($sType, $sUnitView ? array('unit_view' => $sUnitView) : false, BX_DB_PADDING_DEF, $bEmptyMessage, $bAjaxPaginate);
  290. return $this->_serviceBrowseTable(array('type' => $sType), $bShowHeader);
  291. }
  292. /**
  293. * @page service Service Calls
  294. * @section bx_forum Discussions
  295. * @subsection bx_forum-page_blocks Page Blocks
  296. * @subsubsection bx_forum-browse_partaken browse_partaken
  297. *
  298. * @code bx_srv('bx_forum', 'browse_partaken', [...]); @endcode
  299. *
  300. * Get page block with a list of partaken items represented as table.
  301. *
  302. * @param $sUnitView (optional) string with unit view type.
  303. * @param $bEmptyMessage (optional) boolean value determining whether an "Empty" message should be returned or not.
  304. * @param $bAjaxPaginate (optional) boolean value determining whether an Ajax based pagination should be used or not.
  305. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  306. *
  307. * @see BxForumModule::serviceBrowsePartaken
  308. */
  309. /**
  310. * @ref bx_forum-browse_partaken "browse_partaken"
  311. */
  312. public function serviceBrowsePartaken ($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = false)
  313. {
  314. $sType = 'partaken';
  315. if($sUnitView != 'table')
  316. return $this->_serviceBrowse($sType, $sUnitView ? array('unit_view' => $sUnitView) : false, BX_DB_PADDING_DEF, $bEmptyMessage, $bAjaxPaginate);
  317. $aSelect = array(
  318. 'tbla' => 'tco',
  319. 'fld' => 'cmt_author_id',
  320. );
  321. $aJoin = array(
  322. 'tp' => 'INNER',
  323. 'tbl1' => 'bx_forum_cmts',
  324. 'tbl1a' => 'tco',
  325. 'fld1' => 'cmt_object_id',
  326. 'tbl2' => 'bx_forum_discussions',
  327. 'fld2' => 'id'
  328. );
  329. $aWhere = array(
  330. 'tbl' => 'tco',
  331. 'fld' => 'cmt_author_id',
  332. 'val' => bx_get_logged_profile_id(),
  333. 'opr' => '='
  334. );
  335. $aGroupBy = array(
  336. 'tbl' => 'bx_forum_discussions',
  337. 'fld' => 'id',
  338. );
  339. return $this->_serviceBrowseTable(array(
  340. 'type' => $sType,
  341. 'select' => $aSelect,
  342. 'join' => $aJoin,
  343. 'where' => $aWhere,
  344. 'group_by' => $aGroupBy,
  345. 'empty_message' => $bEmptyMessage
  346. ), $bShowHeader);
  347. }
  348. /**
  349. * @page service Service Calls
  350. * @section bx_forum Discussions
  351. * @subsection bx_forum-page_blocks Page Blocks
  352. * @subsubsection bx_forum-browse_index browse_index
  353. *
  354. * @code bx_srv('bx_forum', 'browse_index', [...]); @endcode
  355. *
  356. * Get page block for Site's Home page with a list of items ordered by newness and represented as table.
  357. *
  358. * @param $sUnitView (optional) string with unit view type.
  359. * @param $bEmptyMessage (optional) boolean value determining whether an "Empty" message should be returned or not.
  360. * @param $bAjaxPaginate (optional) boolean value determining whether an Ajax based pagination should be used or not.
  361. * @param $bShowHeader (optional) boolean value determining whether a resulting table should have Header section or not.
  362. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  363. *
  364. * @see BxForumModule::serviceBrowseIndex
  365. */
  366. /**
  367. * @ref bx_forum-browse_index "browse_index"
  368. */
  369. public function serviceBrowseIndex($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = false)
  370. {
  371. $sType = 'index';
  372. if($sUnitView != 'table')
  373. return $this->_serviceBrowse($sType, $sUnitView ? array('unit_view' => $sUnitView) : false, BX_DB_PADDING_DEF, $bEmptyMessage, $bAjaxPaginate);
  374. return $this->_serviceBrowseTable(array(
  375. 'type' => $sType,
  376. 'per_page' => (int)$this->_oDb->getParam('bx_forum_per_page_index'),
  377. 'empty_message' => $bEmptyMessage
  378. ), $bShowHeader);
  379. }
  380. /**
  381. * @page service Service Calls
  382. * @section bx_forum Discussions
  383. * @subsection bx_forum-page_blocks Page Blocks
  384. * @subsubsection bx_forum-browse_author browse_author
  385. *
  386. * @code bx_srv('bx_forum', 'browse_author', [...]); @endcode
  387. *
  388. * Get page block with a list of items filtered by Author and represented as table.
  389. *
  390. * @param $iProfileId (optional) integer value with author ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
  391. * @param $aParams (optional) an array of additional params. It's not used for now.
  392. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  393. *
  394. * @see BxForumModule::serviceBrowseAuthor
  395. */
  396. /**
  397. * @ref bx_forum-browse_author "browse_author"
  398. */
  399. public function serviceBrowseAuthor ($iProfileId = 0, $aParams = array())
  400. {
  401. if(!$iProfileId)
  402. $iProfileId = bx_process_input(bx_get('profile_id'), BX_DATA_INT);
  403. if(!$iProfileId)
  404. return '';
  405. $bEmptyMessage = true;
  406. if(isset($aParams['empty_message'])) {
  407. $bEmptyMessage = (bool)$aParams['empty_message'];
  408. unset($aParams['empty_message']);
  409. }
  410. return $this->_serviceBrowseTable(array(
  411. 'type' => 'author',
  412. 'author' => $iProfileId,
  413. 'where' => array('fld' => 'author', 'val' => $iProfileId, 'opr' => '='),
  414. 'per_page' => (int)$this->_oDb->getParam('bx_forum_per_page_profile'),
  415. 'empty_message' => $bEmptyMessage
  416. ), false);
  417. }
  418. /**
  419. * @page service Service Calls
  420. * @section bx_forum Discussions
  421. * @subsection bx_forum-page_blocks Page Blocks
  422. * @subsubsection bx_forum-browse_favorite browse_favorite
  423. *
  424. * @code bx_srv('bx_forum', 'browse_favorite', [...]); @endcode
  425. *
  426. * Get page block with a list of favorited items by some profile and represented as table.
  427. *
  428. * @param $iProfileId (optional) integer value with profile ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
  429. * @param $aParams (optional) an array of additional params. It's not used for now.
  430. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  431. *
  432. * @see BxForumModule::serviceBrowseFavorite
  433. */
  434. /**
  435. * @ref bx_forum-browse_favorite "browse_favorite"
  436. */
  437. public function serviceBrowseFavorite ($iProfileId = 0, $aParams = array())
  438. {
  439. $CNF = &$this->_oConfig->CNF;
  440. $oProfile = null;
  441. if((int)$iProfileId)
  442. $oProfile = BxDolProfile::getInstance($iProfileId);
  443. if(!$oProfile && bx_get('profile_id') !== false)
  444. $oProfile = BxDolProfile:: getInstance(bx_process_input(bx_get('profile_id'), BX_DATA_INT));
  445. if(!$oProfile)
  446. $oProfile = BxDolProfile::getInstance();
  447. if(!$oProfile)
  448. return '';
  449. $iProfileAuthor = $oProfile->id();
  450. $oFavorite = $this->getObjectFavorite();
  451. if(!$oFavorite->isPublic() && $iProfileAuthor != bx_get_logged_profile_id())
  452. return '';
  453. $bEmptyMessage = false;
  454. if(isset($aParams['empty_message'])) {
  455. $bEmptyMessage = (bool)$aParams['empty_message'];
  456. unset($aParams['empty_message']);
  457. }
  458. $aConditions = $oFavorite->getConditionsTrack($CNF['TABLE_ENTRIES'], 'id', $iProfileAuthor);
  459. if(empty($aConditions) || !is_array($aConditions))
  460. return '';
  461. $aJoinGroup = array('grp' => true, 'cnds' => array());
  462. if(!empty($aConditions['join']))
  463. foreach($aConditions['join'] as $aCondition)
  464. $aJoinGroup['cnds'][] = array(
  465. 'tp' => $aCondition['type'],
  466. 'tbl1' => $aCondition['table'],
  467. 'fld1' => $aCondition['onField'],
  468. 'tbl2' => $aCondition['mainTable'],
  469. 'fld2' => $aCondition['mainField']
  470. );
  471. $aWhereGroup = array('grp' => true, 'opr' => 'AND', 'cnds' => array());
  472. if(!empty($aConditions['restriction']))
  473. foreach($aConditions['restriction'] as $aCondition)
  474. $aWhereGroup['cnds'][] = array(
  475. 'tbl' => (!empty($aCondition['table']) ? $aCondition['table'] : ''),
  476. 'fld' => $aCondition['field'],
  477. 'val' => $aCondition['value'],
  478. 'opr' => $aCondition['operator']
  479. );
  480. return $this->_serviceBrowseTable(array(
  481. 'grid' => $CNF['OBJECT_GRID_FAVORITE'],
  482. 'type' => 'favorite',
  483. 'author' => $iProfileId,
  484. 'join' => $aJoinGroup,
  485. 'where' => $aWhereGroup,
  486. 'per_page' => (int)$this->_oDb->getParam('bx_forum_per_page_profile'),
  487. 'empty_message' => $bEmptyMessage
  488. ), false);
  489. }
  490. /**
  491. * @page service Service Calls
  492. * @section bx_forum Discussions
  493. * @subsection bx_forum-page_blocks Page Blocks
  494. * @subsubsection bx_forum-browse_category browse_category
  495. *
  496. * @code bx_srv('bx_forum', 'browse_category', [...]); @endcode
  497. *
  498. * Get page block with a list of items filter by some category and represented as table.
  499. *
  500. * @param $sUnitView (optional) string with unit view type.
  501. * @param $bEmptyMessage (optional) boolean value determining whether an "Empty" message should be returned or not.
  502. * @param $bAjaxPaginate (optional) boolean value determining whether an Ajax based pagination should be used or not.
  503. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  504. *
  505. * @see BxForumModule::serviceBrowseCategory
  506. */
  507. /**
  508. * @ref bx_forum-browse_category "browse_category"
  509. */
  510. public function serviceBrowseCategory($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = false)
  511. {
  512. $sType = 'category';
  513. $iCategory = bx_process_input(bx_get('category'), BX_DATA_INT);
  514. $aCategory = $this->_oDb->getCategories(array('type' => 'by_category', 'category' => $iCategory));
  515. if(!empty($aCategory['visible_for_levels']) && !BxDolAcl::getInstance()->isMemberLevelInSet($aCategory['visible_for_levels']))
  516. return $bEmptyMessage ? MsgBox(_t('_sys_txt_access_denied')) : '';
  517. if($sUnitView != 'table')
  518. return $this->_serviceBrowse($sType, $sUnitView ? array('unit_view' => $sUnitView) : false, BX_DB_PADDING_DEF, $bEmptyMessage, $bAjaxPaginate);
  519. return $this->_serviceBrowseTable(array('type' => $sType, 'where' => array('fld' => 'cat', 'val' => $iCategory, 'opr' => '=')), $bShowHeader);
  520. }
  521. /**
  522. * @page service Service Calls
  523. * @section bx_forum Discussions
  524. * @subsection bx_forum-page_blocks Page Blocks
  525. * @subsubsection bx_forum-browse_keyword browse_keyword
  526. *
  527. * @code bx_srv('bx_forum', 'browse_keyword', [...]); @endcode
  528. *
  529. * Get page block with a list of items filter by some keyword and represented as table.
  530. *
  531. * @param $sUnitView (optional) string with unit view type.
  532. * @param $bEmptyMessage (optional) boolean value determining whether an "Empty" message should be returned or not.
  533. * @param $bAjaxPaginate (optional) boolean value determining whether an Ajax based pagination should be used or not.
  534. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  535. *
  536. * @see BxForumModule::serviceBrowseKeyword
  537. */
  538. /**
  539. * @ref bx_forum-browse_keyword "browse_keyword"
  540. */
  541. public function serviceBrowseKeyword($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = false)
  542. {
  543. $sType = 'keyword';
  544. $sKeyword = bx_process_input(bx_get('keyword'));
  545. if($sUnitView != 'table')
  546. return $this->_serviceBrowse($sType, $sUnitView ? array('unit_view' => $sUnitView) : false, BX_DB_PADDING_DEF, $bEmptyMessage, $bAjaxPaginate);
  547. return $this->_serviceBrowseTable(array('type' => $sType, 'where' => $this->_getSearchKeywordDescriptor('#' . $sKeyword)), $bShowHeader);
  548. }
  549. /**
  550. * @page service Service Calls
  551. * @section bx_forum Discussions
  552. * @subsection bx_forum-page_blocks Page Blocks
  553. * @subsubsection bx_forum-browse_search_results browse_search_results
  554. *
  555. * @code bx_srv('bx_forum', 'browse_search_results', [...]); @endcode
  556. *
  557. * Get page block with search results by Author(s), Category, Keyword represented as table.
  558. *
  559. * @param $sUnitView (optional) string with unit view type.
  560. * @param $bEmptyMessage (optional) boolean value determining whether an "Empty" message should be returned or not.
  561. * @param $bAjaxPaginate (optional) boolean value determining whether an Ajax based pagination should be used or not.
  562. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  563. *
  564. * @see BxForumModule::serviceBrowseSearchResults
  565. */
  566. /**
  567. * @ref bx_forum-browse_search_results "browse_search_results"
  568. */
  569. public function serviceBrowseSearchResults($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true)
  570. {
  571. $sType = 'search';
  572. $aAuthors = bx_process_input(bx_get('author'));
  573. $iCategory = bx_process_input(bx_get('category'), BX_DATA_INT);
  574. $sKeyword = bx_process_input(bx_get('keyword'));
  575. $aCategory = $this->_oDb->getCategories(array('type' => 'by_category', 'category' => $iCategory));
  576. if(!empty($aCategory['visible_for_levels']) && !BxDolAcl::getInstance()->isMemberLevelInSet($aCategory['visible_for_levels']))
  577. return $bEmptyMessage ? MsgBox(_t('_sys_txt_access_denied')) : '';
  578. if($sUnitView != 'table')
  579. return $this->_serviceBrowse('', $sUnitView ? array('unit_view' => $sUnitView) : false, BX_DB_PADDING_DEF, $bEmptyMessage, $bAjaxPaginate);
  580. $aWhereGroupAnd = array('grp' => true, 'opr' => 'AND', 'cnds' => array());
  581. if(!empty($aAuthors) && is_array($aAuthors))
  582. $aWhereGroupAnd['cnds'][] = $this->_getSearchAuthorDescriptor($aAuthors);
  583. if(!empty($iCategory))
  584. $aWhereGroupAnd['cnds'][] = array('fld' => 'cat', 'val' => $iCategory, 'opr' => '=');
  585. if(!empty($sKeyword))
  586. $aWhereGroupAnd['cnds'][] = $this->_getSearchKeywordDescriptor($sKeyword);
  587. return $this->_serviceBrowseTable(array('type' => $sType, 'where' => $aWhereGroupAnd), false);
  588. }
  589. /**
  590. * @page service Service Calls
  591. * @section bx_forum Discussions
  592. * @subsection bx_forum-other Other
  593. * @subsubsection bx_forum-get_discussions_num get_discussions_num
  594. *
  595. * @code bx_srv('bx_forum', 'get_discussions_num', [...]); @endcode
  596. *
  597. * Get number of discussions for some profile.
  598. *
  599. * @param $iProfileId (optional) profile to get discussions for, if omitted then currently logged in profile is used.
  600. * @return integer value with a number of discussions.
  601. *
  602. * @see BxForumModule::serviceGetDiscussionsNum
  603. */
  604. /**
  605. * @ref bx_forum-get_discussions_num "get_discussions_num"
  606. */
  607. public function serviceGetDiscussionsNum ($iProfileId = 0)
  608. {
  609. if (!$iProfileId)
  610. $iProfileId = bx_get_logged_profile_id();
  611. return $this->_oDb->getEntriesNumByAuthor((int)$iProfileId);
  612. }
  613. /**
  614. * @page service Service Calls
  615. * @section bx_forum Discussions
  616. * @subsection bx_forum-other Other
  617. * @subsubsection bx_forum-get_unreplied_discussions_num get_unreplied_discussions_num
  618. *
  619. * @code bx_srv('bx_forum', 'get_unreplied_discussions_num', [...]); @endcode
  620. *
  621. * Get number of unreplied discussions for some profile.
  622. *
  623. * @param $iProfileId (optional) profile to get unreplied discussions for, if omitted then currently logged is profile is used.
  624. * @return integer value with a number of discussions.
  625. *
  626. * @see BxForumModule::serviceGetUnrepliedDiscussionsNum
  627. */
  628. /**
  629. * @ref bx_forum-get_unreplied_discussions_num "get_unreplied_discussions_num"
  630. */
  631. public function serviceGetUnrepliedDiscussionsNum ($iProfileId = 0)
  632. {
  633. if (!$iProfileId)
  634. $iProfileId = bx_get_logged_profile_id();
  635. return $this->_oDb->getUnrepliedDiscussionsNum((int)$iProfileId);
  636. }
  637. /**
  638. *
  639. */
  640. /**
  641. * @page service Service Calls
  642. * @section bx_forum Discussions
  643. * @subsection bx_forum-other Other
  644. * @subsubsection bx_forum-trigger_comment_post trigger_comment_post
  645. *
  646. * @code bx_srv('bx_forum', 'trigger_comment_post', [...]); @endcode
  647. *
  648. * Update last comment time and author when new comment was added in the discussion.
  649. *
  650. * @param $iContentId integer value with content ID.
  651. * @param $iProfileId integer value with profile ID.
  652. * @param $iCommentId integer value with comment ID.
  653. * @param $iTimestamp (optional) date in UNIX Timestamp format, if omitted then current date is used.
  654. * @param $sCommentText (optional) string value with text of comment.
  655. * @return boolean value determining where the operation is successful or not.
  656. *
  657. * @see BxForumModule::serviceTriggerCommentPost
  658. */
  659. /**
  660. * @ref bx_forum-trigger_comment_post "trigger_comment_post"
  661. */
  662. public function serviceTriggerCommentPost ($iContentId, $iProfileId, $iCommentId, $iTimestamp = 0, $sCommentText = '')
  663. {
  664. $CNF = $this->_oConfig->CNF;
  665. $iContentId = (int)$iContentId;
  666. if(!$iContentId)
  667. return false;
  668. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  669. if(!$aContentInfo)
  670. return false;
  671. $oCmts = BxDolCmts::getObjectInstance($CNF['OBJECT_COMMENTS'], $iContentId);
  672. if(!$oCmts)
  673. return false;
  674. if(!$iTimestamp)
  675. $iTimestamp = time();
  676. if(!$this->_oDb->updateLastCommentTimeProfile((int)$iContentId, (int)$iProfileId, $iCommentId, $iTimestamp))
  677. return false;
  678. // send notification to author
  679. if($iProfileId != $aContentInfo[$CNF['FIELD_AUTHOR']]) {
  680. $oProfile = BxDolProfile::getInstanceMagic($iProfileId);
  681. if($oProfile)
  682. sendMailTemplate('bx_forum_new_reply', 0, $aContentInfo[$CNF['FIELD_AUTHOR']], array(
  683. 'SenderDisplayName' => $oProfile->getDisplayName(),
  684. 'SenderUrl' => $oProfile->getUrl(),
  685. 'PageUrl' => $oCmts->getItemUrl($iCommentId),
  686. 'PageTitle' => $oCmts->getObjectTitle(),
  687. 'Message' => $sCommentText,
  688. ), BX_EMAIL_NOTIFY);
  689. }
  690. return true;
  691. }
  692. /**
  693. * @page service Service Calls
  694. * @section bx_forum Discussions
  695. * @subsection bx_forum-page_blocks Page Blocks
  696. * @subsubsection bx_forum-entity_participants entity_participants
  697. *
  698. * @code bx_srv('bx_forum', 'entity_participants', [...]); @endcode
  699. *
  700. * Get page block with discussion's collaborators.
  701. *
  702. * @param $iContentId (optional) content ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
  703. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  704. *
  705. * @see BxForumModule::serviceEntityParticipants
  706. */
  707. /**
  708. * @ref bx_forum-entity_participants "entity_participants"
  709. */
  710. public function serviceEntityParticipants ($iContentId = 0)
  711. {
  712. if (!$iContentId)
  713. $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
  714. if (!$iContentId)
  715. return false;
  716. $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
  717. if (!$aContentInfo)
  718. return false;
  719. return $this->_oTemplate->entryParticipants ($aContentInfo, 5, 'right');
  720. }
  721. /**
  722. * @page service Service Calls
  723. * @section bx_forum Discussions
  724. * @subsection bx_forum-page_blocks Page Blocks
  725. * @subsubsection bx_forum-search search
  726. *
  727. * @code bx_srv('bx_forum', 'search', [...]); @endcode
  728. *
  729. * Get page block with search form.
  730. *
  731. * @return HTML string with block content to display on the site or false if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
  732. *
  733. * @see BxForumModule::serviceSearch
  734. */
  735. /**
  736. * @ref bx_forum-search "search"
  737. */
  738. public function serviceSearch()
  739. {
  740. $CNF = $this->_oConfig->CNF;
  741. $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_SEARCH'], $CNF['OBJECT_FORM_SEARCH_DISPLAY_FULL'], $this->_oTemplate);
  742. $oForm->initChecker();
  743. return $oForm->getCode();
  744. }
  745. public function checkAllowedSubscribe(&$aDataEntry, $isPerformAction = false)
  746. {
  747. $CNF = &$this->_oConfig->CNF;
  748. $sMsg = $this->checkAllowedView($aDataEntry);
  749. if($sMsg !== CHECK_ACTION_RESULT_ALLOWED)
  750. return $sMsg;
  751. return $this->_checkAllowedConnect ($aDataEntry, $isPerformAction, $CNF['OBJECT_CONNECTION_SUBSCRIBERS'], false, false);
  752. }
  753. public function checkAllowedUnsubscribe(&$aDataEntry, $isPerformAction = false)
  754. {
  755. $CNF = &$this->_oConfig->CNF;
  756. return $this->_checkAllowedConnect ($aDataEntry, $isPerformAction, $CNF['OBJECT_CONNECTION_SUBSCRIBERS'], false, true);
  757. }
  758. public function checkAllowedStickAnyEntry($aDataEntry, $isPerformAction = false)
  759. {
  760. $CNF = &$this->_oConfig->CNF;
  761. if((int)$aDataEntry[$CNF['FIELD_STICK']] != 0)
  762. return false;
  763. return $this->_checkAllowedAction('stick any entry', $aDataEntry, $isPerformAction);
  764. }
  765. public function checkAllowedUnstickAnyEntry($aDataEntry, $isPerformAction = false)
  766. {
  767. $CNF = $this->_oConfig->CNF;
  768. if((int)$aDataEntry[$CNF['FIELD_STICK']] != 1)
  769. return false;
  770. return $this->_checkAllowedAction('stick any entry', $aDataEntry, $isPerformAction);
  771. }
  772. public function checkAllowedLockAnyEntry($aDataEntry, $isPerformAction = false)
  773. {
  774. $CNF = $this->_oConfig->CNF;
  775. if((int)$aDataEntry[$CNF['FIELD_LOCK']] != 0)
  776. return false;
  777. return $this->_checkAllowedAction('lock any entry', $aDataEntry, $isPerformAction);
  778. }
  779. public function checkAllowedUnlockAnyEntry($aDataEntry, $isPerformAction = false)
  780. {
  781. $CNF = $this->_oConfig->CNF;
  782. if((int)$aDataEntry[$CNF['FIELD_LOCK']] != 1)
  783. return false;
  784. return $this->_checkAllowedAction('lock any entry', $aDataEntry, $isPerformAction);
  785. }
  786. public function checkAllowedHideAnyEntry($aDataEntry, $isPerformAction = false)
  787. {
  788. $CNF = $this->_oConfig->CNF;
  789. if($aDataEntry[$CNF['FIELD_STATUS_ADMIN']] == 'hidden')
  790. return false;
  791. return $this->_checkAllowedAction('hide any entry', $aDataEntry, $isPerformAction);
  792. }
  793. public function checkAllowedUnhideAnyEntry($aDataEntry, $isPerformAction = false)
  794. {
  795. $CNF = &$this->_oConfig->CNF;
  796. if($aDataEntry[$CNF['FIELD_STATUS_ADMIN']] != 'hidden')
  797. return false;
  798. return $this->_checkAllowedAction('hide any entry', $aDataEntry, $isPerformAction);
  799. }
  800. protected function _checkAllowedConnect (&$aDataEntry, $isPerformAction, $sObjConnection, $isMutual, $isInvertResult)
  801. {
  802. $CNF = &$this->_oConfig->CNF;
  803. if(!$this->_iProfileId)
  804. return _t('_sys_txt_access_denied');
  805. $isConnected = BxDolConnection::getObjectInstance($sObjConnection)->isConnected($this->_iProfileId, $aDataEntry[$CNF['FIELD_ID']], $isMutual);
  806. if($isInvertResult)
  807. $isConnected = !$isConnected;
  808. return $isConnected ? _t('_sys_txt_access_denied') : CHECK_ACTION_RESULT_ALLOWED;
  809. }
  810. /**
  811. * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
  812. */
  813. protected function _checkAllowedAction($sAction, $aDataEntry, $isPerformAction = false)
  814. {
  815. if($this->_isModerator($isPerformAction))
  816. return CHECK_ACTION_RESULT_ALLOWED;
  817. $aCheck = checkActionModule($this->_iProfileId, $sAction, $this->getName(), $isPerformAction);
  818. if($aCheck[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED)
  819. return CHECK_ACTION_RESULT_ALLOWED;
  820. return _t('_sys_txt_access_denied');
  821. }
  822. protected function _serviceBrowseTable($aParams, $isDisplayHeader = true)
  823. {
  824. $sGrid = $this->_oConfig->CNF['OBJECT_GRID'];
  825. if(!empty($aParams['grid'])) {
  826. $sGrid = $aParams['grid'];
  827. unset($aParams['grid']);
  828. }
  829. $oGrid = BxDolGrid::getObjectInstance($sGrid);
  830. if(!$oGrid)
  831. return false;
  832. $oGrid->setBrowseParams($aParams);
  833. return $oGrid->getCode($isDisplayHeader);
  834. }
  835. protected function _getSearchAuthorDescriptor($aAutor)
  836. {
  837. return array('grp' => true, 'opr' => 'OR', 'cnds' => array(
  838. array('fld' => 'author', 'val' => $aAutor, 'opr' => 'IN'),
  839. array('fld' => 'author_comment', 'val' => $aAutor, 'opr' => 'IN'),
  840. ));
  841. }
  842. protected function _getSearchKeywordDescriptor($sKeyword)
  843. {
  844. return array('grp' => true, 'opr' => 'OR', 'cnds' => array(
  845. array('fld' => 'title', 'val' => $sKeyword, 'opr' => 'LIKE'),
  846. array('fld' => 'text', 'val' => $sKeyword, 'opr' => 'LIKE'),
  847. array('fld' => 'text_comments', 'val' => $sKeyword, 'opr' => 'LIKE')
  848. ));
  849. }
  850. }
  851. /** @} */