BxDolCmts.php 53 KB

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