BxDolCmts.php 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959
  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 UnaCore UNA Core
  7. * @{
  8. */
  9. bx_import('BxDolAcl');
  10. bx_import('BxDolPrivacy');
  11. define('BX_DOL_CMT_TYPE_COMMENT', 'comment');
  12. define('BX_DOL_CMT_TYPE_REVIEW', 'review');
  13. define('BX_CMT_OLD_VOTES', 365*86400); ///< comment votes older than this number of seconds will be deleted automatically
  14. define('BX_CMT_ACTION_POST', 'post');
  15. define('BX_CMT_ACTION_EDIT', 'edit');
  16. define('BX_CMT_DISPLAY_FLAT', 'flat');
  17. define('BX_CMT_DISPLAY_THREADED', 'threaded');
  18. define('BX_CMT_BROWSE_HEAD', 'head');
  19. define('BX_CMT_BROWSE_TAIL', 'tail');
  20. define('BX_CMT_BROWSE_POPULAR', 'popular');
  21. define('BX_CMT_BROWSE_CONNECTION', 'connection');
  22. define('BX_CMT_ORDER_BY_DATE', 'date');
  23. define('BX_CMT_ORDER_BY_POPULAR', 'popular');
  24. define('BX_CMT_FILTER_ALL', 'all');
  25. define('BX_CMT_FILTER_OTHERS', 'others');
  26. define('BX_CMT_FILTER_FRIENDS', 'friends');
  27. define('BX_CMT_FILTER_SUBSCRIPTIONS', 'subscriptions');
  28. define('BX_CMT_ORDER_WAY_ASC', 'asc');
  29. define('BX_CMT_ORDER_WAY_DESC', 'desc');
  30. define('BX_CMT_PFP_TOP', 'top');
  31. define('BX_CMT_PFP_BOTTOM', 'bottom');
  32. define('BX_CMT_RATE_VALUE_PLUS', 1);
  33. define('BX_CMT_RATE_VALUE_MINUS', -1);
  34. define('BX_CMT_USAGE_BLOCK', 'block');
  35. define('BX_CMT_USAGE_INLINE', 'inline');
  36. define('BX_CMT_USAGE_DEFAULT', BX_CMT_USAGE_BLOCK);
  37. /**
  38. * Comments for any content
  39. *
  40. * Related classes:
  41. * - BxDolCmtsQuery - comments database queries
  42. * - BxBaseCmts - comments base representation
  43. * - BxTemplCmts - custom template representation
  44. *
  45. * AJAX comments for any content.
  46. * Self moderated - users rate all comments, and if comment is
  47. * below viewing treshold it is hidden by default.
  48. *
  49. * To add comments section to your module you need to add a record to 'sys_objects_cmts' table:
  50. *
  51. * - ID - autoincremented id for internal usage
  52. * - ObjectName - your unique module name, with vendor prefix, lowercase and spaces are underscored
  53. * - TableCmts - table name where comments are stored
  54. * - Html - 0 - convert new lines to <br /> on saving, 1 - standard(default) visual editor, 2 - full visual editor, 3 - mini visual editor.
  55. * - PerView - number of comments on a page
  56. * - IsRatable - 0 or 1 allow to rate comments or not
  57. * - ViewingThreshold - comment viewing treshost, if comment is below this number it is hidden by default
  58. * - IsOn - is this comment object enabled
  59. * - RootStylePrefix - toot comments style prefix, if you need root comments look different\
  60. * - ObjectVote - Vote object name to process comments' votes. May be empty if Comment Vote is not needed.
  61. * - TriggerTable - table to be updated upon each comment
  62. * - TriggerFieldId - TriggerTable table field with unique record id of
  63. * - TriggerFieldComments - TriggerTable table field with comments count, it will be updated automatically upon eaech comment
  64. * - ClassName - your custom class name if you need to override default class, this class must have the same constructor arguments
  65. * - ClassFile - file where your ClassName is stored.
  66. *
  67. * You can refer to BoonEx modules for sample record in this table.
  68. *
  69. *
  70. *
  71. * @section example Example of usage:
  72. * After filling in the table you can show comments section in any place, using the following code:
  73. *
  74. * @code
  75. * $o = new BxTemplCmts('value of ObjectName field', $iYourEntryId);
  76. * if ($o->isEnabled())
  77. * echo $o->getCommentsBlock ();
  78. * @endcode
  79. *
  80. * Please note that you never need to use BxDolCmts class directly, use BxTemplCmts instead.
  81. * Also if you override comments class with your own then make it child of BxTemplCmts class.
  82. *
  83. *
  84. *
  85. * @section acl Memberships/ACL:
  86. * - comments post
  87. * - comments edit own
  88. * - comments remove own
  89. * - comments edit all
  90. *
  91. *
  92. *
  93. * @section alerts Alerts:
  94. * Alerts type/unit - every module has own type/unit, it equals to ObjectName.
  95. *
  96. * The following alerts are rised
  97. *
  98. * - commentPost - comment was posted
  99. * - $iObjectId - entry id
  100. * - $iSenderId - author of comment
  101. * - $aExtra['comment_id'] - just added comment id
  102. *
  103. * - commentRemoved - comments was removed
  104. * - $iObjectId - entry id
  105. * - $iSenderId - comment deleter id
  106. * - $aExtra['comment_id'] - removed comment id
  107. *
  108. * - commentUpdated - comments was updated
  109. * - $iObjectId - entry id
  110. * - $iSenderId - comment deleter id
  111. * - $aExtra['comment_id'] - updated comment id
  112. *
  113. * - commentRated - comments was rated
  114. * - $iObjectId - entry id
  115. * - $iSenderId - comment rater id
  116. * - $aExtra['comment_id'] - rated comment id
  117. * - $aExtra['rate'] - comment rate 1 or -1
  118. *
  119. */
  120. class BxDolCmts extends BxDolFactory implements iBxDolReplaceable, iBxDolContentInfoService
  121. {
  122. /**
  123. * System tables which are UNITED for all
  124. * comment systems and cannot be overwritten.
  125. */
  126. public static $sTableSystems = 'sys_objects_cmts';
  127. public static $sTableIds = 'sys_cmts_ids';
  128. /**
  129. * System tables which are used by default and
  130. * can be overwritten in comment systems.
  131. * @see BxDolCmts::getTableNameImages and BxDolCmts::getTableNameImages2Entries
  132. */
  133. protected $_sTableImages = 'sys_cmts_images';
  134. protected $_sTableImages2Entries = 'sys_cmts_images2entries';
  135. protected $_sType;
  136. protected $_oQuery = null;
  137. protected $_oTemplate = null;
  138. protected $_bPostQuote;
  139. protected $_bMinPostForm;
  140. protected $_sFormObject;
  141. protected $_sFormDisplayPost;
  142. protected $_sFormDisplayEdit;
  143. protected $_sConnObjFriends;
  144. protected $_sConnObjSubscriptions;
  145. protected $_sMenuObjManage;
  146. protected $_sMenuObjActions;
  147. protected $_sMenuObjMeta;
  148. protected $_sMetatagsObj;
  149. protected $_sViewUrl = '';
  150. protected $_sBaseUrl = '';
  151. protected $_sListAnchor = '';
  152. protected $_sItemAnchor = '';
  153. protected $_sSystem = 'profile'; ///< current comment system name
  154. protected $_aSystem = array (); ///< current comments system array
  155. protected $_iId = 0; ///< obect id to be commented
  156. protected $_iAuthorId = 0; ///< currently logged in user who browse, post, etc.
  157. protected $_aT = array (); ///< an array of lang keys
  158. protected $_aMarkers = array ();
  159. protected $_sDisplayType = '';
  160. protected $_sDpSessionKey = '';
  161. protected $_iDpMaxLevel = 0;
  162. protected $_sBrowseType = '';
  163. protected $_bBrowseFilter = false;
  164. protected $_sBrowseFilter = '';
  165. protected $_sBpSessionKeyType = '';
  166. protected $_sBpSessionKeyFilter = '';
  167. protected $_aOrder = array();
  168. protected $_sSnippetLenthLiveSearch = 50;
  169. protected $_iRememberTime = 2592000;
  170. /**
  171. * Constructor
  172. * $sSystem - comments system name
  173. * $iId - obect id to be commented
  174. */
  175. protected function __construct($sSystem, $iId, $iInit = true, $oTemplate = false)
  176. {
  177. parent::__construct();
  178. $this->_sType = BX_DOL_CMT_TYPE_COMMENT;
  179. $this->_aSystems = $this->getSystems();
  180. if(!isset($this->_aSystems[$sSystem]))
  181. return;
  182. $this->_sSystem = $sSystem;
  183. $this->_aSystem = $this->_aSystems[$sSystem];
  184. $this->_aSystem['is_browse_filter'] = (int)$this->_bBrowseFilter;
  185. $this->_iAuthorId = $this->_getAuthorId();
  186. $this->_iDpMaxLevel = (int)$this->_aSystem['number_of_levels'];
  187. $this->_sDisplayType = $this->_iDpMaxLevel == 0 ? BX_CMT_DISPLAY_FLAT : BX_CMT_DISPLAY_THREADED;
  188. $this->_sDpSessionKey = 'bx_' . $this->_sSystem . '_dp_';
  189. $this->_sBrowseType = $this->_aSystem['browse_type'];
  190. $this->_sBrowseFilter = BX_CMT_FILTER_ALL;
  191. $this->_sBpSessionKeyType = 'bx_' . $this->_sSystem . '_bpt_';
  192. $this->_sBpSessionKeyFilter = 'bx_' . $this->_sSystem . '_bpf_';
  193. $this->_aOrder = array(
  194. 'by' => BX_CMT_ORDER_BY_DATE,
  195. 'way' => BX_CMT_ORDER_WAY_ASC
  196. );
  197. list($mixedUserDp, $mixedUserBpType, $mixedUserBpFilter) = $this->_getUserChoice();
  198. if(!empty($mixedUserDp))
  199. $this->_sDisplayType = $mixedUserDp;
  200. if(!empty($mixedUserBpType))
  201. $this->_sBrowseType = $mixedUserBpType;
  202. if(!empty($mixedUserBpFilter))
  203. $this->_sBrowseFilter = $mixedUserBpFilter;
  204. $this->_sViewUrl = BX_DOL_URL_ROOT . 'page.php?i=cmts-view';
  205. $this->_sBaseUrl = BxDolPermalinks::getInstance()->permalink($this->_aSystem['base_url']);
  206. if(get_mb_substr($this->_sBaseUrl, 0, 4) != 'http')
  207. $this->_sBaseUrl = BX_DOL_URL_ROOT . $this->_sBaseUrl;
  208. $this->_sListAnchor = "cmts-anchor-%s-%d";
  209. $this->_sItemAnchor = "cmt-anchor-%s-%d-%d";
  210. $this->_oQuery = new BxDolCmtsQuery($this);
  211. $this->_bPostQuote = false;
  212. $this->_bMinPostForm = true;
  213. $this->_sFormObject = 'sys_comment';
  214. $this->_sFormDisplayPost = 'sys_comment_post';
  215. $this->_sFormDisplayEdit = 'sys_comment_edit';
  216. $this->_sConnObjFriends = 'sys_profiles_friends';
  217. $this->_sConnObjSubscriptions = 'sys_profiles_subscriptions';
  218. $this->_sMenuObjManage = 'sys_cmts_item_manage';
  219. $this->_sMenuObjActions = 'sys_cmts_item_actions';
  220. $this->_sMenuObjMeta = 'sys_cmts_item_meta';
  221. $this->_sMetatagsObj = 'sys_cmts';
  222. $this->_aT = array(
  223. 'block_comments_title' => '_cmt_block_comments_title',
  224. 'txt_sample_single' => '_cmt_txt_sample_comment_single',
  225. 'txt_sample_vote_single' => '_cmt_txt_sample_vote_single',
  226. 'txt_sample_reaction_single' => '_cmt_txt_sample_reaction_single',
  227. 'txt_sample_score_up_single' => '_cmt_txt_sample_score_up_single',
  228. 'txt_sample_score_down_single' => '_cmt_txt_sample_score_down_single',
  229. 'txt_min_form_placeholder' => '_cmt_txt_min_form_placeholder'
  230. );
  231. if ($iInit)
  232. $this->init($iId);
  233. if ($oTemplate)
  234. $this->_oTemplate = $oTemplate;
  235. else
  236. $this->_oTemplate = BxDolTemplate::getInstance();
  237. }
  238. /**
  239. * get comments object instanse
  240. * @param $sSys comments object name
  241. * @param $iId associated content id, where comments are postred in
  242. * @param $iInit perform initialization
  243. * @return null on error, or ready to use class instance
  244. */
  245. public static function getObjectInstance($sSys, $iId, $iInit = true, $oTemplate = false)
  246. {
  247. if(isset($GLOBALS['bxDolClasses']['BxDolCmts!' . $sSys . $iId]))
  248. return $GLOBALS['bxDolClasses']['BxDolCmts!' . $sSys . $iId];
  249. $aSystems = self::getSystems();
  250. if (!isset($aSystems[$sSys]))
  251. return null;
  252. $sClassName = 'BxTemplCmts';
  253. if(!empty($aSystems[$sSys]['class_name'])) {
  254. $sClassName = $aSystems[$sSys]['class_name'];
  255. if(!empty($aSystems[$sSys]['class_file']))
  256. require_once(BX_DIRECTORY_PATH_ROOT . $aSystems[$sSys]['class_file']);
  257. }
  258. $o = new $sClassName($sSys, $iId, $iInit, $oTemplate);
  259. return ($GLOBALS['bxDolClasses']['BxDolCmts!' . $sSys . $iId] = $o);
  260. }
  261. /**
  262. * get comments object instanse
  263. * @param $iUniqId unique comment id
  264. * @return null on error, or ready to use class instance
  265. */
  266. public static function getObjectInstanceByUniqId($iUniqId, $iInit = true, $oTemplate = false)
  267. {
  268. $aData = BxDolCmtsQuery::getCommentByUniq($iUniqId);
  269. if(empty($aData) || !is_array($aData))
  270. return null;
  271. return self::getObjectInstance($aData['system_name'], $aData['cmt_object_id']);
  272. }
  273. public static function &getSystems ()
  274. {
  275. $sKey = 'bx_dol_cache_memory_cmts_systems';
  276. if (!isset($GLOBALS[$sKey])) {
  277. $GLOBALS[$sKey] = BxDolDb::getInstance()->fromCache('sys_objects_cmts', 'getAllWithKey', '
  278. SELECT
  279. `ID` as `system_id`,
  280. `Name` AS `name`,
  281. `Module` AS `module`,
  282. `Table` AS `table`,
  283. `CharsPostMin` AS `chars_post_min`,
  284. `CharsPostMax` AS `chars_post_max`,
  285. `CharsDisplayMax` AS `chars_display_max`,
  286. `Html` AS `html`,
  287. `PerView` AS `per_view`,
  288. `PerViewReplies` AS `per_view_replies`,
  289. `BrowseType` AS `browse_type`,
  290. `IsBrowseSwitch` AS `is_browse_switch`,
  291. `PostFormPosition` AS `post_form_position`,
  292. `NumberOfLevels` AS `number_of_levels`,
  293. `IsDisplaySwitch` AS `is_display_switch`,
  294. `IsRatable` AS `is_ratable`,
  295. `ViewingThreshold` AS `viewing_threshold`,
  296. `IsOn` AS `is_on`,
  297. `RootStylePrefix` AS `root_style_prefix`,
  298. `BaseUrl` AS `base_url`,
  299. `ObjectVote` AS `object_vote`,
  300. `ObjectReaction` AS `object_reaction`,
  301. `ObjectScore` AS `object_score`,
  302. `ObjectReport` AS `object_report`,
  303. `TriggerTable` AS `trigger_table`,
  304. `TriggerFieldId` AS `trigger_field_id`,
  305. `TriggerFieldAuthor` AS `trigger_field_author`,
  306. `TriggerFieldTitle` AS `trigger_field_title`,
  307. `TriggerFieldComments` AS `trigger_field_comments`,
  308. `ClassName` AS `class_name`,
  309. `ClassFile` AS `class_file`
  310. FROM `' . self::$sTableSystems . '`', 'name');
  311. }
  312. return $GLOBALS[$sKey];
  313. }
  314. public static function getGlobalInfo ($iUniqueId)
  315. {
  316. return BxDolDb::getInstance()->getRow("SELECT `ti`.*, `ts`.`Name` AS `system_name` FROM `" . self::$sTableIds . "` AS `ti` LEFT JOIN `" . self::$sTableSystems . "` AS `ts` ON `ti`.`system_id`=`ts`.`ID` WHERE `ti`.`id`=:id LIMIT 1", array(
  317. 'id' => (int)$iUniqueId
  318. ));
  319. }
  320. public function init ($iId)
  321. {
  322. if (empty($this->iId) && $iId)
  323. $this->setId($iId);
  324. $this->addMarkers(array(
  325. 'object_id' => $this->getId(),
  326. 'user_id' => $this->_getAuthorId()
  327. ));
  328. }
  329. public function getId ()
  330. {
  331. return $this->_iId;
  332. }
  333. public function isEnabled ()
  334. {
  335. return isset($this->_aSystem['is_on']) && $this->_aSystem['is_on'];
  336. }
  337. public function getSystemId()
  338. {
  339. return $this->_aSystem['system_id'];
  340. }
  341. public function getSystemName()
  342. {
  343. return $this->_sSystem;
  344. }
  345. public function getSystemInfo()
  346. {
  347. return $this->_aSystem;
  348. }
  349. public function getStorageObjectName()
  350. {
  351. return $this->_getFormObject()->getStorageObjectName();
  352. }
  353. public function getTranscoderPreviewName()
  354. {
  355. return $this->_getFormObject()->getTranscoderPreviewName();
  356. }
  357. public function getTableNameImages()
  358. {
  359. return $this->_sTableImages;
  360. }
  361. public function getTableNameImages2Entries()
  362. {
  363. return $this->_sTableImages2Entries;
  364. }
  365. public function getLanguageKey($sIndex)
  366. {
  367. return isset($this->_aT[$sIndex]) ? $this->_aT[$sIndex] : '';
  368. }
  369. public function getMaxLevel()
  370. {
  371. return $this->_iDpMaxLevel;
  372. }
  373. public function getOrder ()
  374. {
  375. return $this->_sOrder;
  376. }
  377. public function getPerView ($iCmtParentId = 0)
  378. {
  379. return $iCmtParentId == 0 ? $this->_aSystem['per_view'] : $this->_aSystem['per_view_replies'];
  380. }
  381. public function getViewUrl($iCmtId)
  382. {
  383. if(empty($this->_aSystem['trigger_field_title']))
  384. return '';
  385. return BxDolPermalinks::getInstance()->permalink($this->_sViewUrl, array(
  386. 'sys' => $this->_sSystem,
  387. 'id' => $this->_iId,
  388. 'cmt_id' => $iCmtId
  389. ));
  390. }
  391. public function getViewText($mixedItem)
  392. {
  393. if(!is_array($mixedItem))
  394. $mixedItem = $this->getCommentSimple((int)$mixedItem);
  395. if(empty($mixedItem) || !is_array($mixedItem))
  396. return '';
  397. return $this->_prepareTextForOutput($mixedItem['cmt_text'], (int)$mixedItem['cmt_id']);
  398. }
  399. public function getBaseUrl()
  400. {
  401. return $this->_replaceMarkers($this->_sBaseUrl);
  402. }
  403. public function getListUrl()
  404. {
  405. $sBaseUrl = $this->getBaseUrl();
  406. if(empty($sBaseUrl))
  407. return '';
  408. return $sBaseUrl . $this->getListAnchor(true);
  409. }
  410. public function getItemUrl($iItemId)
  411. {
  412. $sBaseUrl = $this->getBaseUrl();
  413. if(empty($sBaseUrl))
  414. return '';
  415. return $sBaseUrl . $this->getItemAnchor($iItemId, true);
  416. }
  417. public function getListAnchor($bWithHash = false)
  418. {
  419. return ($bWithHash ? '#' : '') . sprintf($this->_sListAnchor, str_replace('_', '-', $this->getSystemName()), $this->getId());
  420. }
  421. public function getItemAnchor($iItemId, $bWithHash = false)
  422. {
  423. return ($bWithHash ? '#' : '') . sprintf($this->_sItemAnchor, str_replace('_', '-', $this->getSystemName()), $this->getId(), $iItemId);
  424. }
  425. public function getAttachments($iCmtId)
  426. {
  427. $aResult = array();
  428. if(!$this->isAttachImageEnabled())
  429. return $aResult;
  430. $aFiles = $this->_oQuery->getFiles($this->_aSystem['system_id'], $iCmtId);
  431. if(empty($aFiles) || !is_array($aFiles))
  432. return $aResult;
  433. $oStorage = BxDolStorage::getObjectInstance($this->getStorageObjectName());
  434. $oTranscoder = BxDolTranscoderImage::getObjectInstance($this->getTranscoderPreviewName());
  435. foreach($aFiles as $aFile) {
  436. $bImage = $oTranscoder && $oTranscoder->isMimeTypeSupported($aFile['mime_type']);
  437. $sPreview = '';
  438. if($bImage)
  439. $sPreview = $oTranscoder->getFileUrl($aFile['image_id']);
  440. if(!$sPreview)
  441. $sPreview = $this->_oTemplate->getIconUrl($oStorage->getIconNameByFileName($aFile['file_name']));
  442. $sUrl = $oStorage->getFileUrlById($aFile['image_id']);
  443. $aResult[] = array(
  444. 'id' => $aFile['image_id'],
  445. 'src' => $sPreview,
  446. 'src_orig' => $bImage ? $sUrl : '',
  447. 'url' => !$bImage ? $sUrl : ''
  448. );
  449. }
  450. return $aResult;
  451. }
  452. public function getConnectionObject($sType)
  453. {
  454. $sResult = '';
  455. switch($sType) {
  456. case BX_CMT_FILTER_FRIENDS:
  457. $sResult = $this->_sConnObjFriends;
  458. break;
  459. case BX_CMT_FILTER_SUBSCRIPTIONS:
  460. $sResult = $this->_sConnObjSubscriptions;
  461. break;
  462. }
  463. return $sResult;
  464. }
  465. public function getVoteObject($iId)
  466. {
  467. if(empty($this->_aSystem['object_vote']))
  468. $this->_aSystem['object_vote'] = 'sys_cmts';
  469. $oVote = BxDolVote::getObjectInstance($this->_aSystem['object_vote'], $iId, true, $this->_oTemplate);
  470. if(!$oVote || !$oVote->isEnabled())
  471. return false;
  472. return $oVote;
  473. }
  474. public function getReactionObject($iId)
  475. {
  476. if(empty($this->_aSystem['object_reaction']))
  477. $this->_aSystem['object_reaction'] = 'sys_cmts_reactions';
  478. $oReaction = BxDolVote::getObjectInstance($this->_aSystem['object_reaction'], $iId, true, $this->_oTemplate);
  479. if(!$oReaction || !$oReaction->isEnabled())
  480. return false;
  481. return $oReaction;
  482. }
  483. public function getScoreObject($iId)
  484. {
  485. if(empty($this->_aSystem['object_score']))
  486. $this->_aSystem['object_score'] = 'sys_cmts';
  487. $oScore = BxDolScore::getObjectInstance($this->_aSystem['object_score'], $iId, true, $this->_oTemplate);
  488. if(!$oScore || !$oScore->isEnabled())
  489. return false;
  490. return $oScore;
  491. }
  492. public function getReportObject($iId)
  493. {
  494. if(empty($this->_aSystem['object_report']))
  495. $this->_aSystem['object_report'] = 'sys_cmts';
  496. $oReport = BxDolReport::getObjectInstance($this->_aSystem['object_report'], $iId, true, $this->_oTemplate);
  497. if(!$oReport || !$oReport->isEnabled())
  498. return false;
  499. return $oReport;
  500. }
  501. public function getNotificationId()
  502. {
  503. return 'cmts-notification-' . $this->_sSystem . '-' . $this->_iId;
  504. }
  505. /**
  506. * @deprecated since version 10.0.0-B3 and can be removed in later versions.
  507. */
  508. public function setTableNameFiles($sTable)
  509. {
  510. $this->_sTableImages = $sTable;
  511. $this->_oQuery->setTableNameFiles($sTable);
  512. }
  513. /**
  514. * @deprecated since version 10.0.0-B3 and can be removed in later versions.
  515. */
  516. public function setTableNameFiles2Entries($sTable)
  517. {
  518. $this->_sTableImages2Entries = $sTable;
  519. $this->_oQuery->setTableNameFiles2Entries($sTable);
  520. }
  521. public function isHtml ()
  522. {
  523. return $this->_aSystem['html'] > 0;
  524. }
  525. public function isRatable ()
  526. {
  527. return $this->_aSystem['is_ratable'];
  528. }
  529. public function isAttachImageEnabled()
  530. {
  531. return true;
  532. }
  533. /**
  534. * set id to operate with votes
  535. */
  536. public function setId ($iId)
  537. {
  538. if ($iId == $this->getId()) return;
  539. $this->_iId = $iId;
  540. }
  541. /**
  542. * Add replace markers.
  543. * @param $a array of markers as key => value
  544. * @return true on success or false on error
  545. */
  546. public function addMarkers ($a)
  547. {
  548. if (empty($a) || !is_array($a))
  549. return false;
  550. $this->_aMarkers = array_merge ($this->_aMarkers, $a);
  551. return true;
  552. }
  553. /**
  554. * Database functions
  555. */
  556. public function getQueryObject ()
  557. {
  558. return $this->_oQuery;
  559. }
  560. public function getCommentsTableName ()
  561. {
  562. return $this->_oQuery->getTableName ();
  563. }
  564. public function getObjectAuthorId ($iObjectId = 0)
  565. {
  566. if(empty($this->_aSystem['trigger_field_author']))
  567. return 0;
  568. return $this->_oQuery->getObjectAuthorId ($iObjectId ? $iObjectId : $this->getId());
  569. }
  570. public function getObjectTitle ($iObjectId = 0)
  571. {
  572. if(empty($this->_aSystem['trigger_field_title']))
  573. return '';
  574. $sTitle = $this->_oQuery->getObjectTitle ($iObjectId ? $iObjectId : $this->getId());
  575. if(get_mb_substr($sTitle, 0, 1) == '_')
  576. $sTitle = _t($sTitle);
  577. return $sTitle;
  578. }
  579. public function getObjectPrivacyView ($iObjectId = 0)
  580. {
  581. if(empty($iObjectId))
  582. $iObjectId = $this->getId();
  583. $sFieldPrivacyView = '';
  584. if(!empty($this->_aSystem['trigger_field_privacy_view']))
  585. $sFieldPrivacyView = $this->_aSystem['trigger_field_privacy_view'];
  586. if(($iPrivacyView = $this->_oQuery->getObjectPrivacyView($iObjectId, $sFieldPrivacyView)) !== false)
  587. return $iPrivacyView;
  588. return BX_DOL_PG_ALL;
  589. }
  590. public function getCommentsCountAll ($iObjectId = 0)
  591. {
  592. return $this->_oQuery->getCommentsCountAll ($iObjectId ? $iObjectId : $this->getId());
  593. }
  594. public function getCommentsCount ($iObjectId = 0, $iCmtVParentId = -1, $sFilter = '')
  595. {
  596. return $this->_oQuery->getCommentsCount ($iObjectId ? $iObjectId : $this->getId(), $iCmtVParentId, $this->_getAuthorId(), $sFilter);
  597. }
  598. public function getCommentsArray ($iVParentId, $sFilter, $aOrder, $iStart = 0, $iCount = -1)
  599. {
  600. return $this->_oQuery->getComments ($this->getId(), $iVParentId, $this->_getAuthorId(), $sFilter, $aOrder, $iStart, $iCount);
  601. }
  602. /**
  603. * Get comment's unique id.
  604. */
  605. public function getCommentUniqId($iCmtId, $iAuthorId = 0)
  606. {
  607. return $this->_oQuery->getUniqId($this->getSystemId(), $iCmtId, $iAuthorId);
  608. }
  609. /**
  610. * Get comment's short info.
  611. */
  612. public function getCommentSimple ($iCmtId)
  613. {
  614. return $this->_oQuery->getCommentSimple ($this->getId(), $iCmtId);
  615. }
  616. /**
  617. * Get comment's full info.
  618. */
  619. public function getCommentRow ($iCmtId)
  620. {
  621. return $this->_oQuery->getComment ($this->getId(), $iCmtId);
  622. }
  623. public function onObjectDelete ($iObjectId = 0)
  624. {
  625. // delete comments
  626. $aFiles = $aCmtIds = array();
  627. $this->_oQuery->deleteObjectComments ($iObjectId ? $iObjectId : $this->getId(), $aFiles, $aCmtIds);
  628. // delete meta info
  629. $this->deleteMetaInfo($aCmtIds);
  630. // delete files
  631. if ($aFiles) {
  632. $oStorage = BxDolStorage::getObjectInstance($this->getStorageObjectName());
  633. if ($oStorage)
  634. $oStorage->queueFilesForDeletion($aFiles);
  635. }
  636. }
  637. public static function onAuthorDelete ($iAuthorId)
  638. {
  639. $aSystems = self::getSystems();
  640. foreach($aSystems as $sSystem => $aSystem) {
  641. $o = self::getObjectInstance($sSystem, 0);
  642. $oQuery = $o->getQueryObject();
  643. // delete comments
  644. $aFiles = $aCmtIds = array ();
  645. $oQuery->deleteAuthorComments($iAuthorId, $aFiles, $aCmtIds);
  646. // delete meta info
  647. $o->deleteMetaInfo($aCmtIds);
  648. // delete files
  649. $oStorage = BxDolStorage::getObjectInstance($o->getStorageObjectName());
  650. if ($oStorage)
  651. $oStorage->queueFilesForDeletion($aFiles);
  652. }
  653. return true;
  654. }
  655. public static function onModuleEnable ($sModuleName)
  656. {
  657. $aSystems = self::getSystems();
  658. foreach($aSystems as $sSystem => $aSystem) {
  659. if ($sModuleName !== $aSystem['module'])
  660. continue;
  661. $o = self::getObjectInstance($sSystem, 0);
  662. $o->registerTranscoders();
  663. }
  664. return true;
  665. }
  666. public static function onModuleDisable ($sModuleName)
  667. {
  668. $aSystems = self::getSystems();
  669. foreach($aSystems as $sSystem => $aSystem) {
  670. if ($sModuleName !== $aSystem['module'])
  671. continue;
  672. $o = self::getObjectInstance($sSystem, 0);
  673. $o->unregisterTranscoders();
  674. }
  675. return true;
  676. }
  677. public static function onModuleUninstall ($sModuleName, &$iFiles = null)
  678. {
  679. $aSystems = self::getSystems();
  680. foreach($aSystems as $sSystem => $aSystem) {
  681. if ($sModuleName !== $aSystem['module'])
  682. continue;
  683. $o = self::getObjectInstance($sSystem, 0);
  684. $oQuery = $o->getQueryObject();
  685. // delete comments
  686. $aFiles = $aCmtIds = array ();
  687. $oQuery->deleteAll($aSystem['system_id'], $aFiles, $aCmtIds);
  688. // delete meta info
  689. $o->deleteMetaInfo($aCmtIds);
  690. // delete files
  691. $oStorage = BxDolStorage::getObjectInstance($o->getStorageObjectName());
  692. if ($oStorage && $aFiles)
  693. $oStorage->queueFilesForDeletion($aFiles);
  694. if (null !== $iFiles)
  695. $iFiles += count($aFiles);
  696. }
  697. return true;
  698. }
  699. public function deleteMetaInfo ($mixedCmtId)
  700. {
  701. if(!is_array($mixedCmtId))
  702. $mixedCmtId = array($mixedCmtId);
  703. $oMetatags = false;
  704. if(!empty($this->_sMetatagsObj))
  705. $oMetatags = BxDolMetatags::getObjectInstance($this->_sMetatagsObj);
  706. foreach($mixedCmtId as $iCmtId) {
  707. if($oMetatags)
  708. $oMetatags->onDeleteContent($this->_oQuery->getUniqId($this->_aSystem['system_id'], $iCmtId));
  709. $this->_oQuery->deleteCmtIds($this->_aSystem['system_id'], $iCmtId);
  710. }
  711. }
  712. /**
  713. * Permissions functions
  714. */
  715. public function isAdmin($iCmtAuthorId)
  716. {
  717. return BxDolAcl::getInstance()->isMemberLevelInSet(array(MEMBERSHIP_ID_MODERATOR, MEMBERSHIP_ID_ADMINISTRATOR), $iCmtAuthorId);
  718. }
  719. public function checkAction ($sAction, $isPerformAction = false)
  720. {
  721. $iId = $this->_getAuthorId();
  722. $a = checkActionModule($iId, $sAction, 'system', $isPerformAction);
  723. return $a[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED;
  724. }
  725. public function checkActionErrorMsg ($sAction)
  726. {
  727. $iId = $this->_getAuthorId();
  728. $a = checkActionModule($iId, $sAction, 'system');
  729. return $a[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $a[CHECK_ACTION_MESSAGE] : '';
  730. }
  731. public function isViewAllowed ($isPerformAction = false)
  732. {
  733. if (BxDolRequest::serviceExists($this->_aSystem['module'], 'check_allowed_comments_view')) {
  734. $mixedResult = BxDolService::call($this->_aSystem['module'], 'check_allowed_comments_view', array($this->getId(), $this->getSystemName()));
  735. if($mixedResult !== CHECK_ACTION_RESULT_ALLOWED)
  736. return $mixedResult;
  737. }
  738. return CHECK_ACTION_RESULT_ALLOWED;
  739. }
  740. public function isVoteAllowed ($aCmt, $isPerformAction = false)
  741. {
  742. if(!$this->isRatable())
  743. return false;
  744. $oVote = $this->getVoteObject($aCmt['cmt_id']);
  745. if($oVote === false)
  746. return false;
  747. $iUserId = (int)$this->_getAuthorId();
  748. if($iUserId == 0)
  749. return false;
  750. if(isAdmin())
  751. return true;
  752. return $oVote->isAllowedVote($isPerformAction);
  753. }
  754. public function isScoreAllowed ($aCmt, $isPerformAction = false)
  755. {
  756. if(!$this->isRatable())
  757. return false;
  758. $oScore = $this->getScoreObject($aCmt['cmt_id']);
  759. if($oScore === false)
  760. return false;
  761. $iUserId = (int)$this->_getAuthorId();
  762. if($iUserId == 0)
  763. return false;
  764. if(isAdmin())
  765. return true;
  766. return $oScore->isAllowedVote($isPerformAction);
  767. }
  768. public function isReportAllowed ($aCmt, $isPerformAction = false)
  769. {
  770. $oReport = $this->getReportObject($aCmt['cmt_id']);
  771. if($oReport === false)
  772. return false;
  773. $iUserId = (int)$this->_getAuthorId();
  774. if($iUserId == 0)
  775. return false;
  776. if(isAdmin())
  777. return true;
  778. return $oReport->isAllowedReport($isPerformAction);
  779. }
  780. public function isPostAllowed ($isPerformAction = false)
  781. {
  782. if (BxDolRequest::serviceExists($this->_aSystem['module'], 'check_allowed_comments_post')) {
  783. $mixedResult = BxDolService::call($this->_aSystem['module'], 'check_allowed_comments_post', array($this->getId(), $this->getSystemName()));
  784. if($mixedResult !== CHECK_ACTION_RESULT_ALLOWED)
  785. return false;
  786. }
  787. return $this->checkAction ('comments post', $isPerformAction);
  788. }
  789. public function msgErrPostAllowed ()
  790. {
  791. return $this->checkActionErrorMsg('comments post');
  792. }
  793. /**
  794. * Determines whether a 'reply' action allowed or not.
  795. * @param integer or array $mixedCmt - ID or an array which describes the comment to be replied
  796. * @param boolean $isPerformAction
  797. * @return boolean
  798. */
  799. public function isReplyAllowed ($mixedCmt, $isPerformAction = false)
  800. {
  801. return $this->isPostAllowed($isPerformAction);
  802. }
  803. public function msgErrReplyAllowed ()
  804. {
  805. return $this->msgErrPostAllowed ();
  806. }
  807. public function isQuoteAllowed ($mixedCmt, $isPerformAction = false)
  808. {
  809. return $this->_bPostQuote && $this->isReplyAllowed ($mixedCmt, $isPerformAction);
  810. }
  811. public function msgErrQuoteAllowed ()
  812. {
  813. return $this->msgErrReplyAllowed ();
  814. }
  815. public function isPinAllowed ($aCmt, $isPerformAction = false)
  816. {
  817. if((int)$aCmt['cmt_pinned'] != 0)
  818. return false;
  819. if(isAdmin())
  820. return true;
  821. return $this->checkAction ('comments pin', $isPerformAction);
  822. }
  823. public function msgErrPinAllowed ()
  824. {
  825. return $this->checkActionErrorMsg('comments pin');
  826. }
  827. public function isUnpinAllowed ($aCmt, $isPerformAction = false)
  828. {
  829. if((int)$aCmt['cmt_pinned'] == 0)
  830. return false;
  831. if(isAdmin())
  832. return true;
  833. return $this->checkAction ('comments pin', $isPerformAction);
  834. }
  835. public function msgErrUnpinAllowed ()
  836. {
  837. return $this->checkActionErrorMsg('comments pin');
  838. }
  839. public function isEditAllowed ($aCmt, $isPerformAction = false)
  840. {
  841. if(isAdmin())
  842. return true;
  843. if($this->isEditAllowedAll($isPerformAction))
  844. return true;
  845. $mixedResult = BxDolService::call($this->_aSystem['module'], 'check_allowed_comments_post', array($this->getId(), $this->getSystemName()));
  846. if($mixedResult !== CHECK_ACTION_RESULT_ALLOWED)
  847. return false;
  848. return abs($aCmt['cmt_author_id']) == $this->_getAuthorId() && $this->checkAction ('comments edit own', $isPerformAction);
  849. }
  850. public function msgErrEditAllowed ()
  851. {
  852. return $this->checkActionErrorMsg ('comments edit own');
  853. }
  854. public function isEditAllowedAll ($isPerformAction = false)
  855. {
  856. return $this->checkAction('comments edit all', $isPerformAction);
  857. }
  858. public function isRemoveAllowed ($aCmt, $isPerformAction = false)
  859. {
  860. if(isAdmin())
  861. return true;
  862. if($this->isRemoveAllowedAll($isPerformAction))
  863. return true;
  864. return abs($aCmt['cmt_author_id']) == $this->_getAuthorId() && $this->checkAction ('comments remove own', $isPerformAction);
  865. }
  866. public function isRemoveAllowedAll ($isPerformAction = false)
  867. {
  868. return $this->checkAction ('comments remove all', $isPerformAction);
  869. }
  870. public function msgErrRemoveAllowed ()
  871. {
  872. return $this->checkActionErrorMsg('comments remove own');
  873. }
  874. public function isMoreAllowed ($aCmt, $isPerformAction = false)
  875. {
  876. $oMenuManage = BxDolMenu::getObjectInstance($this->_sMenuObjManage);
  877. $oMenuManage->setCmtsData($this, $aCmt['cmt_id']);
  878. return $oMenuManage->isVisible();
  879. }
  880. public function isModerator()
  881. {
  882. return $this->isEditAllowedAll() || $this->isRemoveAllowedAll();
  883. }
  884. /**
  885. * Actions functions
  886. */
  887. public function actionPin ()
  888. {
  889. if (!$this->isEnabled())
  890. return echoJson(array());
  891. $iCmtId = 0;
  892. if(bx_get('Cmt') !== false)
  893. $iCmtId = bx_process_input(bx_get('Cmt'), BX_DATA_INT);
  894. $aCmt = $this->getCommentRow($iCmtId);
  895. if(empty($aCmt) || !is_array($aCmt))
  896. return echoJson(array());
  897. $iWay = 0;
  898. if(bx_get('way') !== false)
  899. $iWay = bx_process_input(bx_get('way'), BX_DATA_INT);
  900. if(!$this->_oQuery->updateComments(array('cmt_pinned' => $iWay ? time() : 0), array('cmt_id' => $iCmtId)))
  901. return echoJson(array());
  902. $aBp = $aDp = array();
  903. $this->_getParams($aBp, $aDp);
  904. $this->_prepareParams($aBp, $aDp);
  905. echoJson(array(
  906. 'parent_id' => $aCmt['cmt_parent_id'],
  907. 'per_view' => $aBp['per_view']
  908. ));
  909. }
  910. public function actionGetFormPost ()
  911. {
  912. if (!$this->isEnabled())
  913. return '';
  914. $iCmtParentId = bx_get('CmtParent');
  915. $iCmtParentId = $iCmtParentId !== false ? bx_process_input($iCmtParentId, BX_DATA_INT) : 0;
  916. $sCmtBrowse = bx_get('CmtBrowse');
  917. $sCmtBrowse = $sCmtBrowse !== false ? bx_process_input($sCmtBrowse, BX_DATA_TEXT) : '';
  918. $sCmtDisplay = bx_get('CmtDisplay');
  919. $sCmtDisplay = $sCmtDisplay !== false ? bx_process_input($sCmtDisplay, BX_DATA_TEXT) : '';
  920. $bQuote = bx_get('CmtQuote');
  921. $bQuote = $bQuote !== false ? bx_process_input($bQuote, BX_DATA_INT) == 1 : false;
  922. $bMinPostForm = bx_get('CmtMinPostForm');
  923. $bMinPostForm = $bMinPostForm !== false ? bx_process_input($bMinPostForm, BX_DATA_INT) == 1 : $this->_bMinPostForm;
  924. return $this->getFormBoxPost(array('parent_id' => $iCmtParentId, 'type' => $sCmtBrowse), array('type' => $sCmtDisplay, 'dynamic_mode' => true, 'quote' => $bQuote, 'min_post_form' => $bMinPostForm));
  925. }
  926. public function actionGetFormEdit ()
  927. {
  928. if (!$this->isEnabled())
  929. return echoJson(array());
  930. $iCmtId = bx_process_input(bx_get('Cmt'), BX_DATA_INT);
  931. echoJson($this->getFormEdit($iCmtId, array('dynamic_mode' => true)));
  932. }
  933. public function actionGetCmt ()
  934. {
  935. if (!$this->isEnabled())
  936. return '';
  937. if($this->isViewAllowed() !== CHECK_ACTION_RESULT_ALLOWED)
  938. return '';
  939. $iCmtId = bx_process_input($_REQUEST['Cmt'], BX_DATA_INT);
  940. $sCmtBrowse = isset($_REQUEST['CmtBrowse']) ? bx_process_input($_REQUEST['CmtBrowse'], BX_DATA_TEXT) : '';
  941. $sCmtDisplay = isset($_REQUEST['CmtDisplay']) ? bx_process_input($_REQUEST['CmtDisplay'], BX_DATA_TEXT) : '';
  942. $aCmt = $this->getCommentRow($iCmtId);
  943. echoJson(array(
  944. 'parent_id' => $aCmt['cmt_parent_id'],
  945. 'vparent_id' => $aCmt['cmt_parent_id'],
  946. 'content' => $this->getComment($aCmt, array('type' => $sCmtBrowse), array('type' => $sCmtDisplay, 'dynamic_mode' => true))
  947. ));
  948. }
  949. public function actionGetCmts ()
  950. {
  951. if (!$this->isEnabled())
  952. return '';
  953. if($this->isViewAllowed() !== CHECK_ACTION_RESULT_ALLOWED)
  954. return '';
  955. $aBp = $aDp = array();
  956. $this->_getParams($aBp, $aDp);
  957. $aDp['dynamic_mode'] = true;
  958. //--- Beg: Using pregenerated structure
  959. if(isset($aDp['structure']) && $aDp['structure'] === true) {
  960. $iCmtId = isset($aBp['parent_id']) ? (int)$aBp['parent_id'] : 0;
  961. $mixedStructure = $this->getCommentStructure($iCmtId, $aBp, $aDp);
  962. if($mixedStructure === false || empty($mixedStructure[$iCmtId]['items']))
  963. return '';
  964. $aDp['structure'] = $mixedStructure[$iCmtId]['items'];
  965. return $this->getCommentsByStructure($aBp, $aDp);
  966. }
  967. //--- End: Using pregenerated structure
  968. else
  969. return $this->getComments($aBp, $aDp);
  970. }
  971. public function actionSubmitPostForm()
  972. {
  973. if(!$this->isEnabled())
  974. return echoJson(array());
  975. $iCmtParentId = 0;
  976. if(bx_get('cmt_parent_id') !== false)
  977. $iCmtParentId = bx_process_input(bx_get('cmt_parent_id'), BX_DATA_INT);
  978. echoJson($this->getFormPost($iCmtParentId, array('dynamic_mode' => true)));
  979. }
  980. public function actionSubmitEditForm()
  981. {
  982. if (!$this->isEnabled()) {
  983. echoJson(array());
  984. return;
  985. };
  986. $iCmtId = 0;
  987. if(bx_get('cmt_id') !== false)
  988. $iCmtId = bx_process_input(bx_get('cmt_id'), BX_DATA_INT);
  989. echoJson($this->getFormEdit($iCmtId, array('dynamic_mode' => true)));
  990. }
  991. public function actionRemove()
  992. {
  993. if (!$this->isEnabled()) {
  994. echoJson(array());
  995. return;
  996. };
  997. $iCmtId = 0;
  998. if(bx_get('Cmt') !== false)
  999. $iCmtId = bx_process_input(bx_get('Cmt'), BX_DATA_INT);
  1000. echoJson($this->remove($iCmtId));
  1001. }
  1002. public function remove($iCmtId)
  1003. {
  1004. $aCmt = $this->_oQuery->getCommentsBy(array('type' => 'id', 'id' => $iCmtId));
  1005. if(!$aCmt)
  1006. return array('msg' => _t('_No such comment'));
  1007. $iObjId = $this->getId();
  1008. if(!$iObjId){
  1009. $this->setId($aCmt['cmt_object_id']);
  1010. $iObjId = $aCmt['cmt_object_id'];
  1011. }
  1012. $iObjAthrId = $this->getObjectAuthorId($iObjId);
  1013. $iObjAthrPrivacyView = $this->getObjectPrivacyView($iObjId);
  1014. if($aCmt['cmt_replies'] > 0) {
  1015. if(!$this->isModerator())
  1016. return array('msg' => _t('_Can not delete comments with replies'));
  1017. $aReplies = $this->_oQuery->getCommentsBy(array('type' => 'parent_id', 'parent_id' => $iCmtId));
  1018. foreach($aReplies as $aReply)
  1019. $this->remove($aReply['cmt_id']);
  1020. }
  1021. $iPerformerId = $this->_getAuthorId();
  1022. if(!$this->isRemoveAllowed($aCmt))
  1023. return array('msg' => $aCmt['cmt_author_id'] == $iPerformerId ? strip_tags($this->msgErrRemoveAllowed()) : _t('_Access denied'));
  1024. $iCmtPrntId = (int)$aCmt['cmt_parent_id'];
  1025. if(!$this->_oQuery->removeComment($iObjId, $iCmtId, $iCmtPrntId))
  1026. return array('msg' => _t('_cmt_err_cannot_perform_action'));
  1027. $this->_triggerComment();
  1028. $oStorage = BxDolStorage::getObjectInstance($this->getStorageObjectName());
  1029. $aImages = $this->_oQuery->getFiles($this->_aSystem['system_id'], $iCmtId);
  1030. foreach($aImages as $aImage)
  1031. $oStorage->deleteFile($aImage['image_id']);
  1032. $this->_oQuery->deleteImages($this->_aSystem['system_id'], $iCmtId);
  1033. $this->isRemoveAllowed($aCmt, true);
  1034. $this->deleteMetaInfo($iCmtId);
  1035. $aAuditParams = $this->_prepareAuditParams($iCmtId, array('comment_author_id' => $aCmt['cmt_author_id'], 'comment_text' => $aCmt['cmt_text']));
  1036. bx_audit($iObjId, $this->_aSystem['module'], '_sys_audit_action_delete_comment', $aAuditParams);
  1037. $aAlertParams = $this->_prepareAlertParams($aCmt);
  1038. bx_alert($this->_sSystem, 'commentRemoved', $iObjId, $iPerformerId, $aAlertParams);
  1039. bx_alert('comment', 'deleted', $iCmtId, $iPerformerId, $aAlertParams);
  1040. if(!empty($iCmtPrntId)) {
  1041. $aCmtPrnt = $this->_oQuery->getCommentSimple($iObjId, $iCmtPrntId);
  1042. if(!empty($aCmtPrnt) && is_array($aCmtPrnt)) {
  1043. $aAlertParamsReply = $this->_prepareAlertParamsReply($aCmt, $aCmtPrnt);
  1044. bx_alert($this->_sSystem, 'replyRemoved', $iCmtPrntId, $iPerformerId, $aAlertParamsReply);
  1045. bx_alert('reply', 'deleted', $iCmtId, $iPerformerId, $aAlertParamsReply);
  1046. }
  1047. }
  1048. return array('id' => $iCmtId);
  1049. }
  1050. public function add($aValues)
  1051. {
  1052. return $this->_getFormAdd($aValues);
  1053. }
  1054. public function actionResumeLiveUpdate()
  1055. {
  1056. $sKey = $this->getNotificationId();
  1057. bx_import('BxDolSession');
  1058. BxDolSession::getInstance()->unsetValue($sKey);
  1059. }
  1060. public function actionPauseLiveUpdate()
  1061. {
  1062. $sKey = $this->getNotificationId();
  1063. bx_import('BxDolSession');
  1064. BxDolSession::getInstance()->setValue($sKey, 1);
  1065. }
  1066. public function onPostAfter($iCmtId)
  1067. {
  1068. $iObjId = (int)$this->getId();
  1069. $aCmt = $this->_oQuery->getCommentSimple($iObjId, $iCmtId);
  1070. if(empty($aCmt) || !is_array($aCmt))
  1071. return false;
  1072. $iCmtPrntId = (int)$aCmt['cmt_parent_id'];
  1073. $iPerformerId = (int)$aCmt['cmt_author_id'];
  1074. $aAlertParams = $this->_prepareAlertParams($aCmt);
  1075. bx_alert($this->_sSystem, 'commentPost', $iObjId, $iPerformerId, $aAlertParams);
  1076. bx_alert('comment', 'added', $iCmtId, $iPerformerId, $aAlertParams);
  1077. $aAuditParams = $this->_prepareAuditParams($iCmtId, array('comment_author_id' => $aCmt['cmt_author_id'], 'comment_text' => $aCmt['cmt_text']));
  1078. bx_audit($iObjId, $this->_aSystem['module'], '_sys_audit_action_add_comment', $aAuditParams);
  1079. if(!empty($iCmtPrntId)) {
  1080. $aCmtPrnt = $this->_oQuery->getCommentSimple($iObjId, $iCmtPrntId);
  1081. if(!empty($aCmtPrnt) && is_array($aCmtPrnt)) {
  1082. $aAlertParamsReply = $this->_prepareAlertParamsReply($aCmt, $aCmtPrnt);
  1083. bx_alert($this->_sSystem, 'replyPost', $iCmtPrntId, $iPerformerId, $aAlertParamsReply);
  1084. bx_alert('comment', 'replied', $iCmtId, $iPerformerId, $aAlertParamsReply);
  1085. }
  1086. }
  1087. return array('id' => $iCmtId, 'parent_id' => $iCmtPrntId);
  1088. }
  1089. public function onEditAfter($iCmtId)
  1090. {
  1091. $aCmt = $this->getCommentRow($iCmtId);
  1092. if(empty($aCmt) || !is_array($aCmt))
  1093. return false;
  1094. $iObjId = (int)$this->getId();
  1095. $iPerformerId = $this->_getAuthorId();
  1096. $aAlertParams = $this->_prepareAlertParams($aCmt);
  1097. bx_alert($this->_sSystem, 'commentUpdated', $iObjId, $iPerformerId, $aAlertParams);
  1098. bx_alert('comment', 'edited', $iCmtId, $iPerformerId, $aAlertParams);
  1099. $aAuditParams = $this->_prepareAuditParams($iCmtId, array('comment_author_id' => $aCmt['cmt_author_id'], 'comment_text' => $aCmt['cmt_text']));
  1100. bx_audit($iObjId, $this->_aSystem['module'], '_sys_audit_action_edit_comment', $aAuditParams);
  1101. return array('id' => $iCmtId, 'content' => $this->_getContent($aCmt));
  1102. }
  1103. public function serviceGetAuthor ($iContentId)
  1104. {
  1105. $aComment = $this->_oQuery->getCommentsBy(array('type' => 'id', 'id' => $iContentId));
  1106. $this->setId($aComment['cmt_object_id']);
  1107. return $aComment['cmt_author_id'];
  1108. }
  1109. public function serviceGetDateAdded ($iContentId)
  1110. {
  1111. $aComment = $this->_oQuery->getCommentsBy(array('type' => 'id', 'id' => $iContentId));
  1112. $this->setId($aComment['cmt_object_id']);
  1113. return $aComment['cmt_time'];
  1114. }
  1115. public function serviceGetDateChanged ($iContentId)
  1116. {
  1117. return 0;
  1118. }
  1119. public function serviceGetLink ($iContentId)
  1120. {
  1121. $aComment = $this->_oQuery->getCommentsBy(array('type' => 'id', 'id' => $iContentId));
  1122. $this->setId($aComment['cmt_object_id']);
  1123. return $this->getViewUrl($iContentId);
  1124. }
  1125. public function serviceGetTitle ($iContentId)
  1126. {
  1127. return '';
  1128. }
  1129. public function serviceGetText ($iContentId)
  1130. {
  1131. $aComment = $this->_oQuery->getCommentsBy(array('type' => 'id', 'id' => $iContentId));
  1132. $this->setId($aComment['cmt_object_id']);
  1133. return $aComment['cmt_text'];
  1134. }
  1135. public function serviceGetThumb ($iContentId)
  1136. {
  1137. return '';
  1138. }
  1139. public function serviceGetInfo ($iContentId, $bSearchableFieldsOnly = true)
  1140. {
  1141. $aComment = $this->_oQuery->getCommentsBy(array('type' => 'id', 'id' => $iContentId));
  1142. $this->setId($aComment['cmt_object_id']);
  1143. return BxDolContentInfo::formatFields($aComment);
  1144. }
  1145. public function serviceGetSearchResultUnit ($iContentId, $sUnitTemplate = '')
  1146. {
  1147. $aComment = $this->_oQuery->getCommentsBy(array('type' => 'id', 'id' => $iContentId));
  1148. if(empty($aComment) || !is_array($aComment))
  1149. return '';
  1150. $this->setId($aComment['cmt_object_id']);
  1151. return $this->getComment($aComment, array(), array('type' => BX_CMT_DISPLAY_FLAT, 'view_only' => true));
  1152. }
  1153. public function serviceGetAll ($aParams = array())
  1154. {
  1155. if(empty($aParams) || !is_array($aParams))
  1156. $aParams = array('type' => 'all');
  1157. return $this->_oQuery->getCommentsBy($aParams);
  1158. }
  1159. public function serviceGetSearchableFieldsExtended($aInputsAdd = array())
  1160. {
  1161. $oForm = BxDolForm::getObjectInstance('sys_comment', 'sys_comment_post', $this->_oTemplate);
  1162. if(!$oForm)
  1163. return array();
  1164. $aSrchNamesExcept = array();
  1165. $aSrchCaptionsSystem = array(
  1166. 'cmt_author_id' => '_sys_form_comment_input_caption_system_cmt_author_id',
  1167. 'cmt_text' => '_sys_form_comment_input_caption_system_cmt_text'
  1168. );
  1169. $aSrchCaptions = array(
  1170. 'cmt_author_id' => '_sys_form_comment_input_caption_cmt_author_id',
  1171. 'cmt_text' => '_sys_form_comment_input_caption_cmt_text'
  1172. );
  1173. $aResult = array(
  1174. 'cmt_author_id' => array(
  1175. 'type' => 'text_auto',
  1176. 'caption_system' => $aSrchCaptionsSystem['cmt_author_id'],
  1177. 'caption' => $aSrchCaptions['cmt_author_id'],
  1178. 'info' => '',
  1179. 'value' => '',
  1180. 'values' => '',
  1181. 'pass' => ''
  1182. )
  1183. );
  1184. $aInputs = $oForm->aInputs;
  1185. if(!empty($aInputsAdd) && is_array($aInputsAdd))
  1186. $aInputs = array_merge($aInputs, $aInputsAdd);
  1187. foreach($aInputs as $aInput)
  1188. if(in_array($aInput['type'], BxDolSearchExtended::$SEARCHABLE_TYPES) && !in_array($aInput['name'], $aSrchNamesExcept))
  1189. $aResult[$aInput['name']] = array(
  1190. 'type' => $aInput['type'],
  1191. 'caption_system' => !empty($aInput['caption_system_src']) ? $aInput['caption_system_src'] : '',
  1192. 'caption' => !empty($aInput['caption_src']) ? $aInput['caption_src'] : (!empty($aSrchCaptions[$aInput['name']]) ? $aSrchCaptions[$aInput['name']] : ''),
  1193. 'info' => !empty($aInput['info_src']) ? $aInput['info_src'] : '',
  1194. 'value' => !empty($aInput['value']) ? $aInput['value'] : '',
  1195. 'values' => !empty($aInput['values_src']) ? $aInput['values_src'] : '',
  1196. 'pass' => !empty($aInput['db']['pass']) ? $aInput['db']['pass'] : ''
  1197. );
  1198. return $aResult;
  1199. }
  1200. /**
  1201. * Overwrite this method and register transcoder(s) if comments object uses custom transcoder(s),
  1202. * which differs from default one 'sys_cmts_images_preview'
  1203. */
  1204. public function registerTranscoders()
  1205. {}
  1206. /**
  1207. * Overwrite this method and unregister transcoder(s) if comments object uses custom transcoder(s),
  1208. * which differs from default one 'sys_cmts_images_preview'
  1209. */
  1210. public function unregisterTranscoders()
  1211. {}
  1212. public function serviceGetSearchResultExtended($aParams, $iStart = 0, $iPerPage = 0, $bFilterMode = false)
  1213. {
  1214. if((empty($aParams) || !is_array($aParams)) && !$bFilterMode)
  1215. return array();
  1216. return $this->_oQuery->getCommentsBy(array('type' => 'search_ids', 'search_params' => $aParams, 'start' => $iStart, 'per_page' => $iPerPage));
  1217. }
  1218. public function getAuthorInfo($iAuthorId = 0)
  1219. {
  1220. return $this->_getAuthorInfo($iAuthorId);
  1221. }
  1222. /**
  1223. * Internal functions
  1224. */
  1225. protected function _getAuthorId ()
  1226. {
  1227. return isMember() ? bx_get_logged_profile_id() : 0;
  1228. }
  1229. protected function _getAuthorPassword ()
  1230. {
  1231. return isMember() ? $_COOKIE['memberPassword'] : "";
  1232. }
  1233. protected function _getAuthorIp ()
  1234. {
  1235. return getVisitorIP();
  1236. }
  1237. protected function _getAuthorInfo($iAuthorId = 0)
  1238. {
  1239. $iUserId = $this->_getAuthorId();
  1240. $iAuthorId = (int)$iAuthorId;
  1241. $oProfile = $this->_getAuthorObject($iAuthorId);
  1242. return array(
  1243. $oProfile->getDisplayName(),
  1244. $oProfile->getUrl(),
  1245. $oProfile->getThumb(),
  1246. $oProfile->getUnit(0, array('template' => 'unit_wo_info')),
  1247. $oProfile->getBadges()
  1248. );
  1249. }
  1250. protected function _getAuthorObject($iAuthorId = 0)
  1251. {
  1252. return BxDolProfile::getInstanceMagic($iAuthorId);
  1253. }
  1254. protected function _getFormObject($sAction = BX_CMT_ACTION_POST)
  1255. {
  1256. $sDisplayName = '_sFormDisplay' . ucfirst($sAction);
  1257. return BxDolForm::getObjectInstance($this->_sFormObject, $this->$sDisplayName, false, $this->_sSystem);
  1258. }
  1259. protected function _getParams(&$aBp, &$aDp)
  1260. {
  1261. //--- Process 'Browse' params.
  1262. $aBp['parent_id'] = isset($aBp['parent_id']) ? (int)$aBp['parent_id'] : 0;
  1263. $aBp['vparent_id'] = isset($aBp['vparent_id']) ? (int)$aBp['vparent_id'] : 0;
  1264. if(bx_get('CmtParent') !== false)
  1265. $aBp['vparent_id'] = bx_process_input(bx_get('CmtParent'), BX_DATA_INT);
  1266. $aBp['type'] = isset($aBp['type']) ? $aBp['type'] : '';
  1267. if(bx_get('CmtBrowse') !== false)
  1268. $aBp['type'] = bx_process_input(bx_get('CmtBrowse'), BX_DATA_TEXT);
  1269. $aBp['filter'] = isset($aBp['filter']) ? $aBp['filter'] : '';
  1270. if(bx_get('CmtFilter') !== false)
  1271. $aBp['filter'] = bx_process_input(bx_get('CmtFilter'), BX_DATA_TEXT);
  1272. $aBp['start'] = isset($aBp['start']) ? (int)$aBp['start'] : -1;
  1273. if(bx_get('CmtStart') !== false)
  1274. $aBp['start'] = bx_process_input($_REQUEST['CmtStart'], BX_DATA_INT);
  1275. $aBp['per_view'] = isset($aBp['per_view']) ? (int)$aBp['per_view'] : -1;
  1276. if(bx_get('CmtPerView') !== false)
  1277. $aBp['per_view'] = bx_process_input($_REQUEST['CmtPerView'], BX_DATA_INT);
  1278. //--- Process 'Display' params.
  1279. $aDp['type'] = isset($aDp['type']) ? $aDp['type'] : '';
  1280. if(bx_get('CmtDisplay') !== false)
  1281. $aDp['type'] = bx_process_input($_REQUEST['CmtDisplay'], BX_DATA_TEXT);
  1282. if(bx_get('CmtDisplayStructure') !== false) {
  1283. $aDp['structure'] = bx_process_input($_REQUEST['CmtDisplayStructure'], BX_DATA_INT) == 1;
  1284. if($aDp['structure'] && bx_get('CmtParent') !== false)
  1285. $aBp['parent_id'] = bx_process_input(bx_get('CmtParent'), BX_DATA_INT);
  1286. }
  1287. $aDp['blink'] = isset($aDp['blink']) ? $aDp['blink'] : '';
  1288. if(bx_get('CmtBlink') !== false)
  1289. $aDp['blink'] = bx_process_input($_REQUEST['CmtBlink'], BX_DATA_TEXT);
  1290. $aDp['quote'] = isset($aDp['quote']) ? (int)$aDp['quote'] : 0;
  1291. if(bx_get('CmtQuote') !== false)
  1292. $aDp['quote'] = bx_process_input($_REQUEST['CmtQuote'], BX_DATA_INT);
  1293. $aDp['min_post_form'] = isset($aDp['min_post_form']) ? (bool)$aDp['min_post_form'] : $this->_bMinPostForm;
  1294. if(bx_get('CmtMinPostForm') !== false)
  1295. $aDp['min_post_form'] = bx_process_input(bx_get('CmtMinPostForm'), BX_DATA_INT) == 1;
  1296. $aDp['in_designbox'] = isset($aDp['in_designbox']) ? (bool)$aDp['in_designbox'] : true;
  1297. $aDp['dynamic_mode'] = isset($aDp['dynamic_mode']) ? (bool)$aDp['dynamic_mode'] : false;
  1298. $aDp['show_empty'] = isset($aDp['show_empty']) ? (bool)$aDp['show_empty'] : false;
  1299. }
  1300. protected function _prepareAlertParams($aCmt)
  1301. {
  1302. $iObjId = (int)$this->getId();
  1303. $iObjAthrId = $this->getObjectAuthorId($iObjId);
  1304. $iObjAthrPrivacyView = $this->getObjectPrivacyView($iObjId);
  1305. $iCmtId = (int)$aCmt['cmt_id'];
  1306. $iCmtUniqId = $this->getCommentUniqId($iCmtId);
  1307. return array(
  1308. 'object_system' => $this->_sSystem,
  1309. 'object_id' => $iObjId,
  1310. 'object_author_id' => $iObjAthrId,
  1311. 'comment_id' => $iCmtId,
  1312. 'comment_uniq_id' => $iCmtUniqId,
  1313. 'comment_author_id' => $aCmt['cmt_author_id'],
  1314. 'comment_text' => $aCmt['cmt_text'],
  1315. 'privacy_view' => $iObjAthrPrivacyView,
  1316. );
  1317. }
  1318. protected function _prepareAlertParamsReply($aCmt, $aCmtPrnt)
  1319. {
  1320. $iObjId = (int)$this->getId();
  1321. $iObjAthrId = $this->getObjectAuthorId($iObjId);
  1322. $iObjAthrPrivacyView = $this->getObjectPrivacyView($iObjId);
  1323. $iCmtPrntId = (int)$aCmt['cmt_parent_id'];
  1324. $iCmtPrntUniqId = $this->getCommentUniqId($iCmtPrntId);
  1325. $iCmtId = (int)$aCmt['cmt_id'];
  1326. $iCmtUniqId = $this->getCommentUniqId($iCmtId);
  1327. return array(
  1328. 'object_system' => $this->_sSystem,
  1329. 'object_id' => $iObjId,
  1330. 'object_author_id' => $iObjAthrId,
  1331. 'parent_id' => $iCmtPrntId,
  1332. 'parent_uniq_id' => $iCmtPrntUniqId,
  1333. 'parent_author_id' => $aCmtPrnt['cmt_author_id'],
  1334. 'comment_id' => $iCmtId,
  1335. 'comment_uniq_id' => $iCmtUniqId,
  1336. 'comment_author_id' => $aCmt['cmt_author_id'],
  1337. 'comment_text' => $aCmt['cmt_text'],
  1338. 'privacy_view' => $iObjAthrPrivacyView,
  1339. );
  1340. }
  1341. protected function _prepareAuditParams($iId, $aData)
  1342. {
  1343. $sModule = $this->_aSystem['module'];
  1344. $oModule = BxDolModule::getInstance($sModule);
  1345. $CNF = isset($oModule->_oConfig->CNF) ? $oModule->_oConfig->CNF : array();
  1346. $aContentInfo = BxDolRequest::serviceExists($sModule, 'get_all') ? BxDolService::call($sModule, 'get_all', array(array('type' => 'id', 'id' => $this->getId()))) : array();
  1347. $iContextId = 0;
  1348. if (!empty($aContentInfo)){
  1349. $iContextId = isset($CNF['FIELD_ALLOW_VIEW_TO']) && (!empty($aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]) && (int)$aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']] < 0) ? - $aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']] : 0;
  1350. }
  1351. $AuditParams = array(
  1352. 'content_title' => $this->getObjectTitle() ,
  1353. 'context_profile_id' => $iContextId,
  1354. 'content_info_object' => isset($CNF['OBJECT_CMTS_CONTENT_INFO']) ? $CNF['OBJECT_CMTS_CONTENT_INFO'] : '',
  1355. 'data' => array_merge(array('comment_id' => $iId), $aData)
  1356. );
  1357. if ($iContextId > 0)
  1358. $AuditParams['context_profile_title'] = BxDolProfile::getInstance($iContextId)->getDisplayName();
  1359. return $AuditParams;
  1360. }
  1361. protected function _prepareTextForOutput ($s, $iCmtId = 0)
  1362. {
  1363. $iDataAction = !$this->isHtml() ? BX_DATA_TEXT_MULTILINE : BX_DATA_HTML;
  1364. $s = bx_process_output($s, $iDataAction);
  1365. $s = bx_linkify_html($s, 'class="' . BX_DOL_LINK_CLASS . '"');
  1366. if($iCmtId && $this->_sMetatagsObj && ($oMetatags = BxDolMetatags::getObjectInstance($this->_sMetatagsObj)) !== false)
  1367. $s = $oMetatags->metaParse($this->_oQuery->getUniqId($this->_aSystem['system_id'], $iCmtId), $s);
  1368. return $s;
  1369. }
  1370. protected function _prepareStructureBp($sDType, &$aBp)
  1371. {
  1372. $aBp['type'] = !empty($aBp['type']) ? $aBp['type'] : $this->_sBrowseType;
  1373. $aBp['filter'] = !empty($aBp['filter']) ? $aBp['filter'] : $this->_sBrowseFilter;
  1374. $aBp['parent_id'] = isset($aBp['parent_id']) ? $aBp['parent_id'] : 0;
  1375. $aBp['start'] = isset($aBp['start']) ? $aBp['start'] : -1;
  1376. $aBp['per_view'] = isset($aBp['per_view']) ? $aBp['per_view'] : -1;
  1377. $aBp['order']['by'] = isset($aBp['order_by']) ? $aBp['order_by'] : $this->_aOrder['by'];
  1378. $aBp['order']['way'] = isset($aBp['order_way']) ? $aBp['order_way'] : $this->_aOrder['way'];
  1379. if($aBp['per_view'] == -1)
  1380. switch($sDType) {
  1381. case BX_CMT_DISPLAY_FLAT:
  1382. $aBp['per_view'] = $this->getPerView(0);
  1383. break;
  1384. case BX_CMT_DISPLAY_THREADED:
  1385. $aBp['per_view'] = $this->getPerView($aBp['parent_id']);
  1386. break;
  1387. }
  1388. }
  1389. protected function _prepareParams(&$aBp, &$aDp)
  1390. {
  1391. $aBp['type'] = !empty($aBp['type']) ? $aBp['type'] : $this->_sBrowseType;
  1392. $aBp['filter'] = !empty($aBp['filter']) ? $aBp['filter'] : $this->_sBrowseFilter;
  1393. $aBp['parent_id'] = isset($aBp['parent_id']) ? $aBp['parent_id'] : 0;
  1394. $aBp['start'] = isset($aBp['start']) ? $aBp['start'] : -1;
  1395. $aBp['per_view'] = isset($aBp['per_view']) ? $aBp['per_view'] : -1;
  1396. $aBp['order']['by'] = isset($aBp['order_by']) ? $aBp['order_by'] : $this->_aOrder['by'];
  1397. $aBp['order']['way'] = isset($aBp['order_way']) ? $aBp['order_way'] : $this->_aOrder['way'];
  1398. $aDp['type'] = !empty($aDp['type']) ? $aDp['type'] : $this->_sDisplayType;
  1399. $aDp['blink'] = !empty($aDp['blink']) ? $aDp['blink'] : array();
  1400. if(!is_array($aDp['blink']))
  1401. $aDp['blink'] = explode(',', $aDp['blink']);
  1402. $aDp['quote'] = !empty($aDp['quote']) ? (int)$aDp['quote'] : 0;
  1403. if(!isset($aDp['min_post_form']))
  1404. $aDp['min_post_form'] = $this->_bMinPostForm;
  1405. switch($aDp['type']) {
  1406. case BX_CMT_DISPLAY_FLAT:
  1407. $aBp['vparent_id'] = -1;
  1408. $aBp['per_view'] = $aBp['per_view'] != -1 ? $aBp['per_view'] : $this->getPerView(0);
  1409. break;
  1410. case BX_CMT_DISPLAY_THREADED:
  1411. $iParent = 0;
  1412. if(isset($aBp['vparent_id']))
  1413. $iParent = $aBp['vparent_id'];
  1414. else if(isset($aBp['parent_id']))
  1415. $iParent = $aBp['parent_id'];
  1416. $aBp['per_view'] = $aBp['per_view'] != -1 ? $aBp['per_view'] : $this->getPerView($iParent);
  1417. break;
  1418. }
  1419. switch ($aBp['type']) {
  1420. case BX_CMT_BROWSE_POPULAR:
  1421. $aBp['order'] = array(
  1422. 'by' => BX_CMT_ORDER_BY_POPULAR,
  1423. 'way' => BX_CMT_ORDER_WAY_DESC
  1424. );
  1425. break;
  1426. }
  1427. if(!isset($aBp['count']))
  1428. $aBp['count'] = $this->getCommentsCount($this->_iId, $aBp['vparent_id'], $aBp['filter']);
  1429. if($aBp['start'] != -1)
  1430. return;
  1431. $aBp['start'] = 0;
  1432. if($aBp['type'] == BX_CMT_BROWSE_TAIL) {
  1433. $aBp['start'] = $aBp['count'] - $aBp['per_view'];
  1434. if($aBp['start'] < 0) {
  1435. $aBp['per_view'] += $aBp['start'];
  1436. $aBp['start'] = 0;
  1437. }
  1438. }
  1439. $this->_setUserChoice($aDp['type'], $aBp['type'], $aBp['filter']);
  1440. }
  1441. protected function _triggerComment()
  1442. {
  1443. if(!$this->_aSystem['trigger_table'] || !$this->_aSystem['trigger_field_id'] || !$this->_aSystem['trigger_field_comments'])
  1444. return false;
  1445. $iId = $this->getId();
  1446. if(!$iId)
  1447. return false;
  1448. $iCount = $this->getCommentsCount($iId);
  1449. return $this->_oQuery->updateTriggerTable($iId, $iCount);
  1450. }
  1451. /**
  1452. * Replace provided markers in a string
  1453. * @param $mixed string or array to replace markers in
  1454. * @return string where all occured markers are replaced
  1455. */
  1456. protected function _replaceMarkers ($mixed)
  1457. {
  1458. return bx_replace_markers($mixed, $this->_aMarkers);
  1459. }
  1460. protected function _getUserChoice()
  1461. {
  1462. $mixedDp = $mixedBpType = $mixedBpFilter = false;
  1463. if(!isLogged())
  1464. return array($mixedDp, $mixedBpType, $mixedBpFilter);
  1465. $iUserId = $this->_getAuthorId();
  1466. $oSession = BxDolSession::getInstance();
  1467. $mixedDp = $oSession->getValue($this->_sDpSessionKey . $iUserId);
  1468. $mixedBpType = $oSession->getValue($this->_sBpSessionKeyType . $iUserId);
  1469. $mixedBpFilter = $oSession->getValue($this->_sBpSessionKeyFilter . $iUserId);
  1470. return array($mixedDp, $mixedBpType, $mixedBpFilter);
  1471. }
  1472. protected function _setUserChoice($sDp, $sBpType, $sBpFilter)
  1473. {
  1474. if(!isLogged())
  1475. return;
  1476. $iUserId = $this->_getAuthorId();
  1477. $oSession = BxDolSession::getInstance();
  1478. if(!empty($sDp))
  1479. $oSession->setValue($this->_sDpSessionKey . $iUserId, $sDp);
  1480. if(!empty($sBpType))
  1481. $oSession->setValue($this->_sBpSessionKeyType . $iUserId, $sBpType);
  1482. if(!empty($sBpFilter))
  1483. $oSession->setValue($this->_sBpSessionKeyFilter . $iUserId, $sBpFilter);
  1484. }
  1485. protected function _sendNotificationEmail($iCmtId, $iCmtParentId)
  1486. {
  1487. $aCmt = $this->getCommentRow($iCmtId);
  1488. $aCmtParent = $this->getCommentRow($iCmtParentId);
  1489. if(empty($aCmt) || !is_array($aCmt) || empty($aCmtParent) || !is_array($aCmtParent) || (int)$aCmt['cmt_author_id'] == (int)$aCmtParent['cmt_author_id'])
  1490. return;
  1491. $oProfile = $this->_getAuthorObject($aCmtParent['cmt_author_id']);
  1492. if($oProfile instanceof BxDolProfileUndefined)
  1493. return;
  1494. $iAccount = $oProfile->getAccountId();
  1495. $aAccount = BxDolAccount::getInstance($iAccount)->getInfo();
  1496. $aPlus = array();
  1497. $aPlus['sender_display_name'] = $oProfile->getDisplayName();
  1498. $aPlus['reply_text'] = $this->_prepareTextForOutput($aCmt['cmt_text'], $iCmtId);
  1499. $sPageUrl = $this->getBaseUrl();
  1500. if(empty($sPageUrl))
  1501. $sPageUrl = $this->getViewUrl($iCmtParentId);
  1502. else
  1503. $sPageUrl .= $this->getItemAnchor($iCmtParentId, true);
  1504. $aPlus['page_url'] = $sPageUrl;
  1505. $sPageTitle = $this->getObjectTitle();
  1506. if(empty($sPageTitle))
  1507. $sPageTitle = _t('_Content');
  1508. $aPlus['page_title'] = $sPageTitle;
  1509. $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('t_CommentReplied', $aPlus);
  1510. return $aTemplate && sendMail($aAccount['email'], $aTemplate['Subject'], $aTemplate['Body']);
  1511. }
  1512. protected function _isShowDoComment($aParams, $isAllowedComment, $bCount)
  1513. {
  1514. $bShowDoComment = !isset($aParams['show_do_comment']) || $aParams['show_do_comment'] == true;
  1515. return $bShowDoComment && ($isAllowedComment || $bCount);
  1516. }
  1517. protected function _isShowCounter($aParams, $isAllowedComment, $bCount)
  1518. {
  1519. $bShowCounter = isset($aParams['show_counter']) && $aParams['show_counter'] === true;
  1520. return $bShowCounter && ($isAllowedComment || $bCount);
  1521. }
  1522. /**
  1523. * Note. By default image based controls aren't used.
  1524. * Therefore it can be overwritten in custom template.
  1525. */
  1526. protected function _getImageDo()
  1527. {
  1528. return '';
  1529. }
  1530. protected function _getIconDo()
  1531. {
  1532. return 'far comment';
  1533. }
  1534. protected function _getTitleDo()
  1535. {
  1536. return '_cmt_txt_do';
  1537. }
  1538. public function _getStructure($mixedItem, $aBp, &$iLevel, &$aStructure)
  1539. {
  1540. $bItem = !empty($mixedItem) && is_array($mixedItem);
  1541. if($bItem) {
  1542. $iI = $mixedItem['cmt_id'];
  1543. $aStructure[$iI] = array(
  1544. 'id' => $mixedItem['cmt_id'],
  1545. 'order' => isset($mixedItem['cmt_order']) ? $mixedItem['cmt_order'] : 0,
  1546. 'items' => array(),
  1547. );
  1548. }
  1549. if(!$bItem || (int)$mixedItem['cmt_replies'] > 0) {
  1550. $aItems = $this->_oQuery->getStructure($this->_iId, $this->_iAuthorId, $bItem ? $mixedItem['cmt_id'] : 0, $aBp['filter'], $aBp['order']);
  1551. if(!empty($aItems)) {
  1552. if($bItem && $iLevel < (int)$this->_aSystem['number_of_levels']) {
  1553. $iPassLevel = $iLevel + 1;
  1554. $aPassStructure = &$aStructure[$iI]['items'];
  1555. }
  1556. else {
  1557. $iPassLevel = $iLevel;
  1558. $aPassStructure = &$aStructure;
  1559. }
  1560. foreach($aItems as $aItem)
  1561. $this->_getStructure($aItem, $aBp, $iPassLevel, $aPassStructure);
  1562. //--- Sort subitems
  1563. $iWay = isset($aBp['order']['way']) && $aBp['order']['way'] == 'desc' ? -1 : 1;
  1564. uasort($aPassStructure, function($aItem1, $aItem2) use ($iWay) {
  1565. if($aItem1['order'] == $aItem2['order'])
  1566. return 0;
  1567. return $iWay * ($aItem1['order'] < $aItem2['order'] ? -1 : 1);
  1568. });
  1569. }
  1570. }
  1571. }
  1572. }
  1573. /** @} */