BxDolCmts.php 54 KB

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