1: <?php
2: /**
3: * XOOPS comments
4: *
5: * You may not change or alter any portion of this comment or credits
6: * of supporting developers from this source code or any supporting source code
7: * which is considered copyrighted (c) material of the original comment or credit authors.
8: * This program is distributed in the hope that it will be useful,
9: * but WITHOUT ANY WARRANTY; without even the implied warranty of
10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11: *
12: * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org)
13: * @license GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
14: * @package kernel
15: * @since 2.0.0
16: * @author Kazumi Ono (AKA onokazu) http://www.myweb.ne.jp/, http://jp.xoops.org/
17: */
18:
19: defined('XOOPS_ROOT_PATH') || exit('Restricted access');
20:
21: include_once XOOPS_ROOT_PATH . '/class/xoopstree.php';
22: require_once XOOPS_ROOT_PATH . '/kernel/object.php';
23: include_once XOOPS_ROOT_PATH . '/language/' . $GLOBALS['xoopsConfig']['language'] . '/comment.php';
24:
25: $GLOBALS['xoopsLogger']->addDeprecated("'/class/xoopscommments.php' is deprecated since XOOPS 2.5.4, please use '/kernel/comment.php' instead.");
26:
27: /**
28: * Xoops Comments Object Class
29: *
30: * @author Kazumi Ono <onokazu@xoops.org>
31: * @author John Neill <catzwolf@xoops.org>
32: * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org)
33: * @package kernel
34: * @subpackage comments
35: * @access public
36: */
37: class XoopsComments extends XoopsObject
38: {
39: public $ctable;
40: /**
41: * @var \XoopsMySQLDatabase
42: */
43: public $db;
44: //PHP 8.2 Dynamic properties deprecated
45: public $comment_id;
46: public $item_id;
47: public $order;
48: public $mode;
49: public $subject;
50: public $comment;
51: public $ip;
52: public $pid;
53: public $date;
54: public $nohtml;
55: public $nosmiley;
56: public $noxcode;
57: public $user_id;
58: public $icon;
59: public $prefix;
60:
61: /**
62: * @param $ctable
63: * @param null|array $id
64: */
65: public function __construct($ctable, $id = null)
66: {
67: $this->ctable = $ctable;
68: $this->db = XoopsDatabaseFactory::getDatabaseConnection();
69: parent::__construct();
70: $this->initVar('comment_id', XOBJ_DTYPE_INT, null, false);
71: $this->initVar('item_id', XOBJ_DTYPE_INT, null, false);
72: $this->initVar('order', XOBJ_DTYPE_INT, null, false);
73: $this->initVar('mode', XOBJ_DTYPE_OTHER, null, false);
74: $this->initVar('subject', XOBJ_DTYPE_TXTBOX, null, false, 255);
75: $this->initVar('comment', XOBJ_DTYPE_TXTAREA, null, false, null);
76: $this->initVar('ip', XOBJ_DTYPE_OTHER, null, false);
77: $this->initVar('pid', XOBJ_DTYPE_INT, 0, false);
78: $this->initVar('date', XOBJ_DTYPE_INT, null, false);
79: $this->initVar('nohtml', XOBJ_DTYPE_INT, 1, false);
80: $this->initVar('nosmiley', XOBJ_DTYPE_INT, 0, false);
81: $this->initVar('noxcode', XOBJ_DTYPE_INT, 0, false);
82: $this->initVar('user_id', XOBJ_DTYPE_INT, null, false);
83: $this->initVar('icon', XOBJ_DTYPE_OTHER, null, false);
84: $this->initVar('prefix', XOBJ_DTYPE_OTHER, null, false);
85: if (!empty($id)) {
86: if (is_array($id)) {
87: $this->assignVars($id);
88: } else {
89: $this->load((int)$id);
90: }
91: }
92: }
93:
94: /**
95: * Load Comment by ID
96: *
97: * @param int $id
98: */
99: public function load($id)
100: {
101: $id = (int)$id;
102: $sql = 'SELECT * FROM ' . $this->ctable . ' WHERE comment_id=' . $id;
103: $result = $this->db->query($sql);
104: if (!$this->db->isResultSet($result)) {
105: throw new \RuntimeException(
106: \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(), E_USER_ERROR
107: );
108: }
109:
110: $arr = $this->db->fetchArray($result);
111: $this->assignVars($arr);
112: }
113:
114: /**
115: * Save Comment
116: *
117: * @return int|false
118: */
119: public function store()
120: {
121: if (!$this->cleanVars()) {
122: return false;
123: }
124: foreach ($this->cleanVars as $k => $v) {
125: $$k = $v;
126: }
127: $isnew = false;
128: if (empty($comment_id)) {
129: $isnew = true;
130: $comment_id = $this->db->genId($this->ctable . '_comment_id_seq');
131: $sql = sprintf("INSERT INTO %s (comment_id, pid, item_id, date, user_id, ip, subject, comment, nohtml, nosmiley, noxcode, icon) VALUES (%u, %u, %u, %u, %u, '%s', '%s', '%s', %u, %u, %u, '%s')", $this->ctable, $comment_id, $pid, $item_id, time(), $user_id, $ip, $subject, $comment, $nohtml, $nosmiley, $noxcode, $icon);
132: } else {
133: $sql = sprintf("UPDATE %s SET subject = '%s', comment = '%s', nohtml = %u, nosmiley = %u, noxcode = %u, icon = '%s' WHERE comment_id = %u", $this->ctable, $subject, $comment, $nohtml, $nosmiley, $noxcode, $icon, $comment_id);
134: }
135: if (!$result = $this->db->query($sql)) {
136: //echo $sql;
137: return false;
138: }
139: if (empty($comment_id)) {
140: $comment_id = $this->db->getInsertId();
141: }
142: if ($isnew != false) {
143: $sql = sprintf('UPDATE %s SET posts = posts+1 WHERE uid = %u', $this->db->prefix('users'), $user_id);
144: if (!$result = $this->db->query($sql)) {
145: echo 'Could not update user posts.';
146: }
147: }
148:
149: return $comment_id;
150: }
151:
152: /**
153: * Enter description here...
154: *
155: * @return int
156: */
157: public function delete()
158: {
159: $sql = sprintf('DELETE FROM %s WHERE comment_id = %u', $this->ctable, $this->getVar('comment_id'));
160: if (!$result = $this->db->query($sql)) {
161: return false;
162: }
163: $sql = sprintf('UPDATE %s SET posts = posts-1 WHERE uid = %u', $this->db->prefix('users'), $this->getVar('user_id'));
164: if (!$result = $this->db->query($sql)) {
165: echo 'Could not update user posts.';
166: }
167: $mytree = new XoopsTree($this->ctable, 'comment_id', 'pid');
168: $arr = $mytree->getAllChild($this->getVar('comment_id'), 'comment_id');
169: $size = count($arr);
170: if ($size > 0) {
171: for ($i = 0; $i < $size; ++$i) {
172: $sql = sprintf('DELETE FROM %s WHERE comment_bid = %u', $this->ctable, $arr[$i]['comment_id']);
173: if (!$result = $this->db->query($sql)) {
174: echo 'Could not delete comment.';
175: }
176: $sql = sprintf('UPDATE %s SET posts = posts-1 WHERE uid = %u', $this->db->prefix('users'), $arr[$i]['user_id']);
177: if (!$result = $this->db->query($sql)) {
178: echo 'Could not update user posts.';
179: }
180: }
181: }
182:
183: return ($size + 1);
184: }
185:
186: /**
187: * Get Comments Tree
188: *
189: * @return mixed
190: */
191: public function getCommentTree()
192: {
193: $mytree = new XoopsTree($this->ctable, 'comment_id', 'pid');
194: $ret = array();
195: $tarray = $mytree->getChildTreeArray($this->getVar('comment_id'), 'comment_id');
196: foreach ($tarray as $ele) {
197: $ret[] = new XoopsComments($this->ctable, $ele);
198: }
199:
200: return $ret;
201: }
202:
203: /**
204: * Get All Comments using criteria match
205: *
206: * @param array $criteria
207: * @param bool $asobject
208: * @param string $orderby
209: * @param int $limit
210: * @param int $start
211: * @return array
212: */
213: public function getAllComments($criteria = array(), $asobject = true, $orderby = 'comment_id ASC', $limit = 0, $start = 0)
214: {
215: $ret = array();
216: $where_query = '';
217: if (!empty($criteria) && \is_array($criteria)) {
218: $where_query = ' WHERE';
219: foreach ($criteria as $c) {
220: $where_query .= " $c AND";
221: }
222: $where_query = substr($where_query, 0, -4);
223: }
224: if (!$asobject) {
225: $sql = 'SELECT comment_id FROM ' . $this->ctable . "$where_query ORDER BY $orderby";
226: $result = $this->db->query($sql, $limit, $start);
227: if (!$this->db->isResultSet($result)) {
228: throw new \RuntimeException(
229: \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(), E_USER_ERROR
230: );
231: }
232: /** @var array $myrow */
233: while (false !== ($myrow = $this->db->fetchArray($result))) {
234: $ret[] = $myrow['comment_id'];
235: }
236: } else {
237: $sql = 'SELECT * FROM ' . $this->ctable . '' . $where_query . " ORDER BY $orderby";
238: $result = $this->db->query($sql, $limit, $start);
239: if (!$this->db->isResultSet($result)) {
240: throw new \RuntimeException(
241: \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(), E_USER_ERROR
242: );
243: }
244: /** @var array $myrow */
245: while (false !== ($myrow = $this->db->fetchArray($result))) {
246: $ret[] = new XoopsComments($this->ctable, $myrow);
247: }
248: }
249:
250: //echo $sql;
251: return $ret;
252: }
253:
254: /**
255: * Enter printNavBar
256: *
257: * @param int $item_id
258: * @param string $mode
259: * @param int $order
260: */
261: public function printNavBar($item_id, $mode = 'flat', $order = 1)
262: {
263: global $xoopsConfig, $xoopsUser;
264: echo "<form method='get' action='" . $_SERVER['PHP_SELF'] . "'><table width='100%' border='0' cellspacing='1' cellpadding='2'><tr><td class='bg1' align='center'><select name='mode'><option value='nocomments'";
265: if ($mode === 'nocomments') {
266: echo " selected";
267: }
268: echo '>' . _NOCOMMENTS . "</option><option value='flat'";
269: if ($mode === 'flat') {
270: echo " selected";
271: }
272: echo '>' . _FLAT . "</option><option value='thread'";
273: if ($mode === 'thread' || $mode == '') {
274: echo " selected";
275: }
276: echo '>' . _THREADED . "</option></select><select name='order'><option value='0'";
277: if ($order != 1) {
278: echo " selected";
279: }
280: echo '>' . _OLDESTFIRST . "</option><option value='1'";
281: if ($order == 1) {
282: echo " selected";
283: }
284: echo '>' . _NEWESTFIRST . "</option></select><input type='hidden' name='item_id' value='" . (int)$item_id . "' /><input type='submit' value='" . _CM_REFRESH . "' />";
285: if ($xoopsConfig['anonpost'] == 1 || $xoopsUser) {
286: if ($mode !== 'flat' || $mode !== 'nocomments' || $mode !== 'thread') {
287: $mode = 'flat';
288: }
289: echo "&nbsp;<input type='button' onclick='location=\"newcomment.php?item_id=" . (int)$item_id . '&amp;order=' . (int)$order . '&amp;mode=' . $mode . "\"' value='" . _CM_POSTCOMMENT . "' />";
290: }
291: echo '</td></tr></table></form>';
292: }
293:
294: /**
295: * Show Thread
296: *
297: */
298: public function showThreadHead()
299: {
300: openThread();
301: }
302:
303: /**
304: * Enter description here...
305: *
306: * @param string $order
307: * @param string $mode
308: * @param int $adminview
309: * @param int $color_num
310: */
311: public function showThreadPost($order, $mode, $adminview = 0, $color_num = 1)
312: {
313: global $xoopsConfig, $xoopsUser;
314: $edit_image = '';
315: $reply_image = '';
316: $delete_image = '';
317: $post_date = formatTimestamp($this->getVar('date'), 'm');
318: if ($this->getVar('user_id') != 0) {
319: $poster = new XoopsUser($this->getVar('user_id'));
320: if (!$poster->isActive()) {
321: $poster = 0;
322: }
323: } else {
324: $poster = 0;
325: }
326: if ($this->getVar('icon') != null && $this->getVar('icon') != '') {
327: $subject_image = "<a name='" . $this->getVar('comment_id') . "' id='" . $this->getVar('comment_id') . "'></a><img src='" . XOOPS_URL . '/images/subject/' . $this->getVar('icon') . "' alt='' />";
328: } else {
329: $subject_image = "<a name='" . $this->getVar('comment_id') . "' id='" . $this->getVar('comment_id') . "'></a><img src='" . XOOPS_URL . "/images/icons/no_posticon.gif' alt='' />";
330: }
331: if ($adminview) {
332: $ip_image = "<img src='" . XOOPS_URL . "/images/icons/ip.gif' alt='" . $this->getVar('ip') . "' />";
333: } else {
334: $ip_image = "<img src='" . XOOPS_URL . "/images/icons/ip.gif' alt='' />";
335: }
336: if ($adminview || ($xoopsUser && $this->getVar('user_id') == $xoopsUser->getVar('uid'))) {
337: $edit_image = "<a href='editcomment.php?comment_id=" . $this->getVar('comment_id') . '&amp;mode=' . $mode . '&amp;order=' . (int)$order . "'><img src='" . XOOPS_URL . "/images/icons/edit.gif' alt='" . _EDIT . "' /></a>";
338: }
339: if ($xoopsConfig['anonpost'] || $xoopsUser) {
340: $reply_image = "<a href='replycomment.php?comment_id=" . $this->getVar('comment_id') . '&amp;mode=' . $mode . '&amp;order=' . (int)$order . "'><img src='" . XOOPS_URL . "/images/icons/reply.gif' alt='" . _REPLY . "' /></a>";
341: }
342: if ($adminview) {
343: $delete_image = "<a href='deletecomment.php?comment_id=" . $this->getVar('comment_id') . '&amp;mode=' . $mode . '&amp;order=' . (int)$order . "'><img src='" . XOOPS_URL . "/images/icons/delete.gif' alt='" . _DELETE . "' /></a>";
344: }
345:
346: if ($poster) {
347: $text = $this->getVar('comment');
348: if ($poster->getVar('attachsig')) {
349: $text .= '<p><br>_________________<br>' . $poster->user_sig() . '</p>';
350: }
351: $reg_date = _CM_JOINED;
352: $reg_date .= formatTimestamp($poster->getVar('user_regdate'), 's');
353: $posts = _CM_POSTS;
354: $posts .= $poster->getVar('posts');
355: $user_from = _CM_FROM;
356: $user_from .= $poster->getVar('user_from');
357: $rank = $poster->rank();
358: if ($rank['image'] != '') {
359: $rank['image'] = "<img src='" . XOOPS_UPLOAD_URL . '/' . $rank['image'] . "' alt='' />";
360: }
361: $avatar_image = "<img src='" . XOOPS_UPLOAD_URL . '/' . $poster->getVar('user_avatar') . "' alt='' />";
362: $online_image = '';
363: if ($poster->isOnline()) {
364: $online_image = "<span style='color:#ee0000;font-weight:bold;'>" . _CM_ONLINE . '</span>';
365: }
366: $profile_image = "<a href='" . XOOPS_URL . '/userinfo.php?uid=' . $poster->getVar('uid') . "'><img src='" . XOOPS_URL . "/images/icons/profile.gif' alt='" . _PROFILE . "' /></a>";
367: $pm_image = '';
368: if ($xoopsUser) {
369: $pm_image = "<a href='javascript:openWithSelfMain(\"" . XOOPS_URL . '/pmlite.php?send2=1&amp;to_userid=' . $poster->getVar('uid') . "\",\"pmlite\",565,500);'><img src='" . XOOPS_URL . "/images/icons/pm.gif' alt='" . sprintf(_SENDPMTO, $poster->getVar('uname', 'E')) . "' /></a>";
370: }
371: $email_image = '';
372: if ($poster->getVar('user_viewemail')) {
373: $email_image = "<a href='mailto:" . $poster->getVar('email', 'E') . "'><img src='" . XOOPS_URL . "/images/icons/email.gif' alt='" . sprintf(_SENDEMAILTO, $poster->getVar('uname', 'E')) . "' /></a>";
374: }
375: $posterurl = $poster->getVar('url');
376: $www_image = '';
377: if ($posterurl != '') {
378: $www_image = "<a href='$posterurl' rel='external'><img src='" . XOOPS_URL . "/images/icons/www.gif' alt='" . _VISITWEBSITE . "' /></a>";
379: }
380: $icq_image = '';
381: if ($poster->getVar('user_icq') != '') {
382: $icq_image = "<a href='http://wwp.icq.com/scripts/search.dll?to=" . $poster->getVar('user_icq', 'E') . "'><img src='" . XOOPS_URL . "/images/icons/icq_add.gif' alt='" . _ADD . "' /></a>";
383: }
384: $aim_image = '';
385: if ($poster->getVar('user_aim') != '') {
386: $aim_image = "<a href='aim:goim?screenname=" . $poster->getVar('user_aim', 'E') . '&message=Hi+' . $poster->getVar('user_aim') . "+Are+you+there?'><img src='" . XOOPS_URL . "/images/icons/aim.gif' alt='aim' /></a>";
387: }
388: $yim_image = '';
389: if ($poster->getVar('user_yim') != '') {
390: $yim_image = "<a href='http://edit.yahoo.com/config/send_webmesg?.target=" . $poster->getVar('user_yim', 'E') . "&.src=pg'><img src='" . XOOPS_URL . "/images/icons/yim.gif' alt='yim' /></a>";
391: }
392: $msnm_image = '';
393: if ($poster->getVar('user_msnm') != '') {
394: $msnm_image = "<a href='" . XOOPS_URL . '/userinfo.php?uid=' . $poster->getVar('uid') . "'><img src='" . XOOPS_URL . "/images/icons/msnm.gif' alt='msnm' /></a>";
395: }
396: showThread($color_num, $subject_image, $this->getVar('subject'), $text, $post_date, $ip_image, $reply_image, $edit_image, $delete_image, $poster->getVar('uname'), $rank['title'], $rank['image'], $avatar_image, $reg_date, $posts, $user_from, $online_image, $profile_image, $pm_image, $email_image, $www_image, $icq_image, $aim_image, $yim_image, $msnm_image);
397: } else {
398: showThread($color_num, $subject_image, $this->getVar('subject'), $this->getVar('comment'), $post_date, $ip_image, $reply_image, $edit_image, $delete_image, $xoopsConfig['anonymous']);
399: }
400: }
401:
402: /**
403: * Show Thread Footer
404: *
405: */
406: public function showThreadFoot()
407: {
408: closeThread();
409: }
410:
411: /**
412: * Show Thread Head
413: *
414: * @param int|string $width
415: */
416: public function showTreeHead($width = '100%')
417: {
418: echo "<table border='0' class='outer' cellpadding='0' cellspacing='0' align='center' width='$width'><tr class='bg3' align='center'><td colspan='3'>" . _CM_REPLIES . "</td></tr><tr class='bg3' align='left'><td width='60%' class='fg2'>" . _CM_TITLE . "</td><td width='20%' class='fg2'>" . _CM_POSTER . "</td><td class='fg2'>" . _CM_POSTED . '</td></tr>';
419: }
420:
421: /**
422: * Show Tree Items
423: *
424: * @param string $order
425: * @param string $mode
426: * @param int $color_num
427: */
428: public function showTreeItem($order, $mode, $color_num)
429: {
430: $bg = 'odd';
431: if ($color_num == 1) {
432: $bg = 'even';
433: }
434: $prefix = str_replace('.', '&nbsp;&nbsp;&nbsp;&nbsp;', $this->getVar('prefix'));
435: $date = formatTimestamp($this->getVar('date'), 'm');
436: $icon = 'icons/no_posticon.gif';
437: if ($this->getVar('icon') != '') {
438: $icon = 'subject/' . $this->getVar('icon', 'E');
439: }
440: echo "<tr class='$bg' align='left'><td>" . $prefix . "<img src='" . XOOPS_URL . '/images/' . $icon . "'>&nbsp;<a href='" . $_SERVER['PHP_SELF'] . '?item_id=' . $this->getVar('item_id') . '&amp;comment_id=' . $this->getVar('comment_id') . '&amp;mode=' . $mode . '&amp;order=' . $order . '#' . $this->getVar('comment_id') . "'>" . $this->getVar('subject') . "</a></td><td><a href='" . XOOPS_URL . '/userinfo.php?uid=' . $this->getVar('user_id') . "'>" . XoopsUser::getUnameFromId($this->getVar('user_id')) . '</a></td><td>' . $date . '</td></tr>';
441: }
442:
443: /**
444: * Show Thread Foot
445: *
446: */
447: public function showTreeFoot()
448: {
449: echo '</table><br>';
450: }
451: }
452: