BxDolCmts.php 67 KB

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