1<?php
2/**
3 * XOOPS Kernel Class
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 (http://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 */
18defined('XOOPS_ROOT_PATH') || exit('Restricted access');
19
20/**
21 * A Comment
22 *
23 * @package             kernel
24 *
25 * @author              Kazumi Ono    <onokazu@xoops.org>
26 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
27 */
28class XoopsComment extends XoopsObject
29{
30    /**
31     * Constructor
32     **/
33    public function __construct()
34    {
35        parent::__construct();
36        $this->initVar('com_id', XOBJ_DTYPE_INT, null, false);
37        $this->initVar('com_pid', XOBJ_DTYPE_INT, 0, false);
38        $this->initVar('com_modid', XOBJ_DTYPE_INT, null, false);
39        $this->initVar('com_icon', XOBJ_DTYPE_OTHER, null, false);
40        $this->initVar('com_title', XOBJ_DTYPE_TXTBOX, null, true, 255, true);
41        $this->initVar('com_text', XOBJ_DTYPE_TXTAREA, null, true, null, true);
42        $this->initVar('com_created', XOBJ_DTYPE_INT, 0, false);
43        $this->initVar('com_modified', XOBJ_DTYPE_INT, 0, false);
44        $this->initVar('com_uid', XOBJ_DTYPE_INT, 0, true);
45        // Start Add by voltan
46        $this->initVar('com_user', XOBJ_DTYPE_TXTBOX, null, false, 60);
47        $this->initVar('com_email', XOBJ_DTYPE_TXTBOX, null, false, 60);
48        $this->initVar('com_url', XOBJ_DTYPE_TXTBOX, null, false, 60);
49        // End Add by voltan
50        $this->initVar('com_ip', XOBJ_DTYPE_OTHER, null, false);
51        $this->initVar('com_sig', XOBJ_DTYPE_INT, 0, false);
52        $this->initVar('com_itemid', XOBJ_DTYPE_INT, 0, false);
53        $this->initVar('com_rootid', XOBJ_DTYPE_INT, 0, false);
54        $this->initVar('com_status', XOBJ_DTYPE_INT, 0, false);
55        $this->initVar('com_exparams', XOBJ_DTYPE_OTHER, null, false, 255);
56        $this->initVar('dohtml', XOBJ_DTYPE_INT, 0, false);
57        $this->initVar('dosmiley', XOBJ_DTYPE_INT, 0, false);
58        $this->initVar('doxcode', XOBJ_DTYPE_INT, 0, false);
59        $this->initVar('doimage', XOBJ_DTYPE_INT, 0, false);
60        $this->initVar('dobr', XOBJ_DTYPE_INT, 0, false);
61    }
62
63    /**
64     * Returns Class Base Variable com_id
65     * @param string $format
66     * @return mixed
67     */
68    public function id($format = 'N')
69    {
70        return $this->getVar('com_id', $format);
71    }
72
73    /**
74     * Returns Class Base Variable com_id
75     * @param string $format
76     * @return mixed
77     */
78    public function com_id($format = '')
79    {
80        return $this->getVar('com_id', $format);
81    }
82
83    /**
84     * Returns Class Base Variable com_pid
85     * @param string $format
86     * @return mixed
87     */
88    public function com_pid($format = '')
89    {
90        return $this->getVar('com_pid', $format);
91    }
92
93    /**
94     * Returns Class Base Variable com_modid
95     * @param string $format
96     * @return mixed
97     */
98    public function com_modid($format = '')
99    {
100        return $this->getVar('com_modid', $format);
101    }
102
103    /**
104     * Returns Class Base Variable com_icon
105     * @param string $format
106     * @return mixed
107     */
108    public function com_icon($format = '')
109    {
110        return $this->getVar('com_icon', $format);
111    }
112
113    /**
114     * Returns Class Base Variable bid
115     * @param string $format
116     * @return mixed
117     */
118    public function com_title($format = '')
119    {
120        return $this->getVar('com_title', $format);
121    }
122
123    /**
124     * Returns Class Base Variable com_text
125     * @param string $format
126     * @return mixed
127     */
128    public function com_text($format = '')
129    {
130        return $this->getVar('com_text', $format);
131    }
132
133    /**
134     * Returns Class Base Variable com_created
135     * @param string $format
136     * @return mixed
137     */
138    public function com_created($format = '')
139    {
140        return $this->getVar('com_created', $format);
141    }
142
143    /**
144     * Returns Class Base Variable com_modified
145     * @param string $format
146     * @return mixed
147     */
148    public function com_modified($format = '')
149    {
150        return $this->getVar('com_modified', $format);
151    }
152
153    /**
154     * Returns Class Base Variable com_uid
155     * @param string $format
156     * @return mixed
157     */
158    public function com_uid($format = '')
159    {
160        return $this->getVar('com_uid', $format);
161    }
162
163    // Start Add by voltan
164    /**
165     * Returns Class Base Variable com_user
166     * @param string $format
167     * @return mixed
168     */
169    public function com_user($format = '')
170    {
171        return $this->getVar('com_user', $format);
172    }
173
174    /**
175     * Returns Class Base Variable com_email
176     * @param string $format
177     * @return mixed
178     */
179    public function com_email($format = '')
180    {
181        return $this->getVar('com_email', $format);
182    }
183
184    /**
185     * Returns Class Base Variable com_url
186     * @param string $format
187     * @return mixed
188     */
189    public function com_url($format = '')
190    {
191        return $this->getVar('com_url', $format);
192    }
193    // End Add by voltan
194
195    /**
196     * Returns Class Base Variable com_ip
197     * @param string $format
198     * @return mixed
199     */
200    public function com_ip($format = '')
201    {
202        return $this->getVar('com_ip', $format);
203    }
204
205    /**
206     * Returns Class Base Variable com_sig
207     * @param string $format
208     * @return mixed
209     */
210    public function com_sig($format = '')
211    {
212        return $this->getVar('com_sig', $format);
213    }
214
215    /**
216     * Returns Class Base Variable com_itemid
217     * @param string $format
218     * @return mixed
219     */
220    public function com_itemid($format = '')
221    {
222        return $this->getVar('com_itemid', $format);
223    }
224
225    /**
226     * Returns Class Base Variable com_rootid
227     * @param string $format
228     * @return mixed
229     */
230    public function com_rootid($format = '')
231    {
232        return $this->getVar('com_rootid', $format);
233    }
234
235    /**
236     * Returns Class Base Variable com_status
237     * @param string $format
238     * @return mixed
239     */
240    public function com_status($format = '')
241    {
242        return $this->getVar('com_status', $format);
243    }
244
245    /**
246     * Returns Class Base Variable com_exparams
247     * @param string $format
248     * @return mixed
249     */
250    public function com_exparams($format = '')
251    {
252        return $this->getVar('com_exparams', $format);
253    }
254
255    /**
256     * Returns Class Base Variable bid
257     * @param string $format
258     * @return mixed
259     */
260    public function dohtml($format = '')
261    {
262        return $this->getVar('dohtml', $format);
263    }
264
265    /**
266     * Returns Class Base Variable dosmiley
267     * @param string $format
268     * @return mixed
269     */
270    public function dosmiley($format = '')
271    {
272        return $this->getVar('dosmiley', $format);
273    }
274
275    /**
276     * Returns Class Base Variable doxcode
277     * @param string $format
278     * @return mixed
279     */
280    public function doxcode($format = '')
281    {
282        return $this->getVar('doxcode', $format);
283    }
284
285    /**
286     * Returns Class Base Variable doimage
287     * @param string $format
288     * @return mixed
289     */
290    public function doimage($format = '')
291    {
292        return $this->getVar('doimage', $format);
293    }
294
295    /**
296     * Returns Class Base Variable dobr
297     * @param string $format
298     * @return mixed
299     */
300    public function dobr($format = '')
301    {
302        return $this->getVar('dobr', $format);
303    }
304
305    /**
306     * Is this comment on the root level?
307     *
308     * @return bool
309     */
310    public function isRoot()
311    {
312        return ($this->getVar('com_id') == $this->getVar('com_rootid'));
313    }
314}
315
316/**
317 * XOOPS comment handler class.
318 *
319 * This class is responsible for providing data access mechanisms to the data source
320 * of XOOPS comment class objects.
321 *
322 *
323 * @package             kernel
324 * @subpackage          comment
325 *
326 * @author              Kazumi Ono    <onokazu@xoops.org>
327 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
328 *
329 * @todo Why is this not a XoopsPersistableObjectHandler?
330 */
331class XoopsCommentHandler extends XoopsObjectHandler
332{
333    /**
334     * Create a {@link XoopsComment}
335     *
336     * @param bool $isNew Flag the object as "new"?
337     *
338     * @return XoopsComment
339     */
340    public function create($isNew = true)
341    {
342        $comment = new XoopsComment();
343        if ($isNew) {
344            $comment->setNew();
345        }
346
347        return $comment;
348    }
349
350    /**
351     * Retrieve a {@link XoopsComment}
352     *
353     * @param int $id ID
354     *
355     * @return XoopsComment {@link XoopsComment}, FALSE on fail
356     **/
357    public function get($id)
358    {
359        $comment = false;
360        $id      = (int)$id;
361        if ($id > 0) {
362            $sql = 'SELECT * FROM ' . $this->db->prefix('xoopscomments') . ' WHERE com_id=' . $id;
363            if (!$result = $this->db->query($sql)) {
364                return $comment;
365            }
366            $numrows = $this->db->getRowsNum($result);
367            if ($numrows == 1) {
368                $comment = new XoopsComment();
369                $comment->assignVars($this->db->fetchArray($result));
370            }
371        }
372
373        return $comment;
374    }
375
376    /**
377     * Write a comment to database
378     *
379     * @param XoopsObject|XoopsComment $comment a XoopsComment object
380     *
381     * @return bool true on success, otherwise false
382     **/
383    public function insert(XoopsObject $comment)
384    {
385        $className = 'XoopsComment';
386        if (!($comment instanceof $className)) {
387            return false;
388        }
389        if (!$comment->isDirty()) {
390            return true;
391        }
392        if (!$comment->cleanVars()) {
393            return false;
394        }
395        foreach ($comment->cleanVars as $k => $v) {
396            ${$k} = $v;
397        }
398        // Start edit by voltan
399        if ($comment->isNew()) {
400            $com_id = $this->db->genId('xoopscomments_com_id_seq');
401            $sql    = sprintf('INSERT INTO %s (com_id, com_pid, com_modid, com_icon, com_title, com_text, com_created, com_modified, com_uid, com_user, com_email, com_url, com_ip, com_sig, com_itemid, com_rootid, com_status, com_exparams, dohtml, dosmiley, doxcode, doimage, dobr) VALUES (%u, %u, %u, %s, %s, %s, %u, %u, %u, %s, %s, %s, %s, %u, %u, %u, %u, %s, %u, %u, %u, %u, %u)', $this->db->prefix('xoopscomments'), $com_id, $com_pid, $com_modid, $this->db->quoteString($com_icon), $this->db->quoteString($com_title), $this->db->quoteString($com_text), $com_created, $com_modified, $com_uid, $this->db->quoteString($com_user), $this->db->quoteString($com_email), $this->db->quoteString($com_url), $this->db->quoteString($com_ip), $com_sig, $com_itemid, $com_rootid, $com_status, $this->db->quoteString($com_exparams), $dohtml, $dosmiley, $doxcode, $doimage, $dobr);
402        } else {
403            $sql = sprintf('UPDATE %s SET com_pid = %u, com_icon = %s, com_title = %s, com_text = %s, com_created = %u, com_modified = %u, com_uid = %u, com_user = %s, com_email = %s, com_url = %s, com_ip = %s, com_sig = %u, com_itemid = %u, com_rootid = %u, com_status = %u, com_exparams = %s, dohtml = %u, dosmiley = %u, doxcode = %u, doimage = %u, dobr = %u WHERE com_id = %u', $this->db->prefix('xoopscomments'), $com_pid, $this->db->quoteString($com_icon), $this->db->quoteString($com_title), $this->db->quoteString($com_text), $com_created, $com_modified, $com_uid, $this->db->quoteString($com_user), $this->db->quoteString($com_email), $this->db->quoteString($com_url), $this->db->quoteString($com_ip), $com_sig, $com_itemid, $com_rootid, $com_status, $this->db->quoteString($com_exparams), $dohtml, $dosmiley, $doxcode, $doimage, $dobr, $com_id);
404        }
405        // End edit by voltan
406        if (!$result = $this->db->query($sql)) {
407            return false;
408        }
409        if (empty($com_id)) {
410            $com_id = $this->db->getInsertId();
411        }
412        $comment->assignVar('com_id', $com_id);
413
414        return true;
415    }
416
417    /**
418     * Delete a {@link XoopsComment} from the database
419     *
420     * @param XoopsObject|XoopsComment $comment a XoopsComment object
421     *
422     * @return bool true on success, otherwise false
423     **/
424    public function delete(XoopsObject $comment)
425    {
426        $className = 'XoopsComment';
427        if (!($comment instanceof $className)) {
428            return false;
429        }
430        $sql = sprintf('DELETE FROM %s WHERE com_id = %u', $this->db->prefix('xoopscomments'), $comment->getVar('com_id'));
431        if (!$result = $this->db->query($sql)) {
432            return false;
433        }
434
435        return true;
436    }
437
438    /**
439     * Get some {@link XoopsComment}s
440     *
441     * @param CriteriaElement|CriteriaCompo $criteria
442     * @param bool   $id_as_key Use IDs as keys into the array?
443     *
444     * @return array Array of {@link XoopsComment} objects
445     **/
446    public function getObjects(CriteriaElement $criteria = null, $id_as_key = false)
447    {
448        $ret   = array();
449        $limit = $start = 0;
450        $sql   = 'SELECT * FROM ' . $this->db->prefix('xoopscomments');
451        if (isset($criteria) && is_subclass_of($criteria, 'CriteriaElement')) {
452            $sql .= ' ' . $criteria->renderWhere();
453            $sort = ($criteria->getSort() != '') ? $criteria->getSort() : 'com_id';
454            $sql .= ' ORDER BY ' . $sort . ' ' . $criteria->getOrder();
455            $limit = $criteria->getLimit();
456            $start = $criteria->getStart();
457        }
458        $result = $this->db->query($sql, $limit, $start);
459        if (!$result) {
460            return $ret;
461        }
462        while (false !== ($myrow = $this->db->fetchArray($result))) {
463            $comment = new XoopsComment();
464            $comment->assignVars($myrow);
465            if (!$id_as_key) {
466                $ret[] =& $comment;
467            } else {
468                $ret[$myrow['com_id']] = &$comment;
469            }
470            unset($comment);
471        }
472
473        return $ret;
474    }
475
476    /**
477     * Count Comments
478     *
479     * @param CriteriaElement|CriteriaCompo $criteria {@link CriteriaElement}
480     *
481     * @return int Count
482     **/
483    public function getCount(CriteriaElement $criteria = null)
484    {
485        $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix('xoopscomments');
486        if (isset($criteria) && is_subclass_of($criteria, 'CriteriaElement')) {
487            $sql .= ' ' . $criteria->renderWhere();
488        }
489        if (!$result = $this->db->query($sql)) {
490            return 0;
491        }
492        list($count) = $this->db->fetchRow($result);
493
494        return $count;
495    }
496
497    /**
498     * Delete multiple comments
499     *
500     * @param CriteriaElement|CriteriaCompo $criteria {@link CriteriaElement}
501     *
502     * @return bool
503     **/
504    public function deleteAll(CriteriaElement $criteria = null)
505    {
506        $sql = 'DELETE FROM ' . $this->db->prefix('xoopscomments');
507        if (isset($criteria) && is_subclass_of($criteria, 'CriteriaElement')) {
508            $sql .= ' ' . $criteria->renderWhere();
509        }
510        if (!$result = $this->db->query($sql)) {
511            return false;
512        }
513
514        return true;
515    }
516
517    /**
518     * Get a list of comments
519     *
520     * @param CriteriaElement $criteria {@link CriteriaElement}
521     *
522     * @return array Array of raw database records
523     **/
524    public function getList(CriteriaElement $criteria = null)
525    {
526        $comments = $this->getObjects($criteria, true);
527        $ret      = array();
528        foreach (array_keys($comments) as $i) {
529            $ret[$i] = $comments[$i]->getVar('com_title');
530        }
531
532        return $ret;
533    }
534
535    /**
536     * Retrieves comments for an item
537     *
538     * @param int    $module_id Module ID
539     * @param int    $item_id   Item ID
540     * @param string $order     Sort order
541     * @param int    $status    Status of the comment
542     * @param int    $limit     Max num of comments to retrieve
543     * @param int    $start     Start offset
544     *
545     * @return array Array of {@link XoopsComment} objects
546     **/
547    public function getByItemId($module_id, $item_id, $order = null, $status = null, $limit = null, $start = 0)
548    {
549        $criteria = new CriteriaCompo(new Criteria('com_modid', (int)$module_id));
550        $criteria->add(new Criteria('com_itemid', (int)$item_id));
551        if (isset($status)) {
552            $criteria->add(new Criteria('com_status', (int)$status));
553        }
554        if (isset($order)) {
555            $criteria->setOrder($order);
556        }
557        if (isset($limit)) {
558            $criteria->setLimit($limit);
559            $criteria->setStart($start);
560        }
561
562        return $this->getObjects($criteria);
563    }
564
565    /**
566     * Gets total number of comments for an item
567     *
568     * @param int $module_id Module ID
569     * @param int $item_id   Item ID
570     * @param int $status    Status of the comment
571     *
572     * @return array Array of {@link XoopsComment} objects
573     **/
574    public function getCountByItemId($module_id, $item_id, $status = null)
575    {
576        $criteria = new CriteriaCompo(new Criteria('com_modid', (int)$module_id));
577        $criteria->add(new Criteria('com_itemid', (int)$item_id));
578        if (isset($status)) {
579            $criteria->add(new Criteria('com_status', (int)$status));
580        }
581
582        return $this->getCount($criteria);
583    }
584
585    /**
586     * Get the top {@link XoopsComment}s
587     *
588     * @param int    $module_id
589     * @param int    $item_id
590     * @param string $order
591     * @param int    $status
592     *
593     * @return array Array of {@link XoopsComment} objects
594     **/
595    public function getTopComments($module_id, $item_id, $order, $status = null)
596    {
597        $criteria = new CriteriaCompo(new Criteria('com_modid', (int)$module_id));
598        $criteria->add(new Criteria('com_itemid', (int)$item_id));
599        $criteria->add(new Criteria('com_pid', 0));
600        if (isset($status)) {
601            $criteria->add(new Criteria('com_status', (int)$status));
602        }
603        $criteria->setOrder($order);
604
605        return $this->getObjects($criteria);
606    }
607
608    /**
609     * Retrieve a whole thread
610     *
611     * @param int $comment_rootid
612     * @param int $comment_id
613     * @param int $status
614     *
615     * @return array Array of {@link XoopsComment} objects
616     **/
617    public function getThread($comment_rootid, $comment_id, $status = null)
618    {
619        $criteria = new CriteriaCompo(new Criteria('com_rootid', (int)$comment_rootid));
620        $criteria->add(new Criteria('com_id', (int)$comment_id, '>='));
621        if (isset($status)) {
622            $criteria->add(new Criteria('com_status', (int)$status));
623        }
624
625        return $this->getObjects($criteria);
626    }
627
628    /**
629     * Update
630     *
631     * @param XoopsComment $comment    {@link XoopsComment} object
632     * @param string $field_name  Name of the field
633     * @param mixed  $field_value Value to write
634     *
635     * @return bool
636     **/
637    public function updateByField(XoopsComment $comment, $field_name, $field_value)
638    {
639        $comment->unsetNew();
640        $comment->setVar($field_name, $field_value);
641
642        return $this->insert($comment);
643    }
644
645    /**
646     * Delete all comments for one whole module
647     *
648     * @param  int $module_id ID of the module
649     * @return bool
650     **/
651    public function deleteByModule($module_id)
652    {
653        return $this->deleteAll(new Criteria('com_modid', (int)$module_id));
654    }
655}
656