BxForumModule.php 35 KB

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