Seditio Source
Root |
./othercms/PHPFusion 9.10.20/includes/classes/PHPFusion/Comments.php
<?php
/*-------------------------------------------------------+
| PHPFusion Content Management System
| Copyright (C) PHP Fusion Inc
| https://phpfusion.com/
+--------------------------------------------------------+
| Filename: Comments.php
| Author: Frederick MC Chan (Chan)
+--------------------------------------------------------+
| This program is released as free software under the
| Affero GPL license. You can redistribute it and/or
| modify it under the terms of this license which you
| can read by viewing the included agpl.txt or online
| at www.gnu.org/licenses/agpl.html. Removal of this
| copyright header is strictly prohibited without
| written permission from the original author(s).
+--------------------------------------------------------*/

namespace PHPFusion;

/**
 * Class Comments
 *
 * @package PHPFusion
 *          Rating is not working
 *          Edit is not working
 */
class Comments {

    private static
$instances = NULL;
    private static
$key = 'Default';

   
/**
     * @var array
     * comment_item_type -
     * comment_db -
     * comment_item_id -
     * clink -
     * comment_allow_reply - enable or disable reply of others comments
     * comment_allow_post - enable or disable posting of comments
     * comment_allow_ratings - enable or disable ratings
     * comment_allow_vote - enable or disable voting
     * comment_once - each user can only comment once (replying a comment is unaffected)
     * comment_echo - to echo the output if true
     * comment_title - display the comment block title
     * comment_count - display the current comment count
     */
   
private static $params = [
       
'comment_user'                     => '',
       
'comment_item_type'                => '',
       
'comment_db'                       => '',
       
'comment_col'                      => '',
       
'comment_item_id'                  => '',
       
'clink'                            => '',
       
'comment_allow_subject'            => TRUE,
       
'comment_allow_reply'              => TRUE,
       
'comment_allow_post'               => TRUE,
       
'comment_allow_ratings'            => FALSE,
       
'comment_allow_vote'               => TRUE,
       
'comment_once'                     => FALSE,
       
'comment_echo'                     => FALSE,
       
'comment_title'                    => '',
       
'comment_form_title'               => '',
       
'comment_count'                    => TRUE,
       
'comment_bbcode'                   => TRUE,
       
'comment_tinymce'                  => FALSE,
       
'comment_tinymce_skin'             => 'lightgray',
       
'comment_custom_script'            => FALSE,
       
'comment_post_callback_function'   => '', // trigger custom functions during post comment event
       
'comment_edit_callback_function'   => '',  // trigger custom functions during reply event
       
'comment_delete_callback_function' => '' // trigger custom functions during delete event
   
];

    private
$locale;
    private
$userdata;
    private
$settings;

    private
$post_link;

    private
$c_arr = [
       
'c_con'  => [],
       
'c_info' => [
           
'c_makepagenav' => FALSE,
           
'admin_link'    => FALSE
       
]
    ];
    private
$comment_params = [];
    private
$comment_data = [];
    private
$cpp;

   
/**
     * Removes comment reply
     *
     * @param string $clink
     *
     * @return string
     */
   
private static $clink = [];

    private static
$c_start = 0;

    private function
__construct() {
       
// Set Settings
       
$this->settings = fusion_get_settings();
       
// Set Global Locale
       
$this->locale = fusion_get_locale('',
            [
               
LOCALE.LOCALESET."comments.php",
               
LOCALE.LOCALESET."user_fields.php",
               
LOCALE.LOCALESET."ratings.php"
           
]
        );

       
// Set current userdata
       
$this->userdata = fusion_get_userdata();
       
// Post link?
       
$this->post_link = FUSION_SELF.(FUSION_QUERY ? "?".FUSION_QUERY : "");
       
$this->post_link = preg_replace("^(&|\?)c_action=(edit|delete)&comment_id=\d*^", "", $this->post_link);
       
// Comments Per Page
       
$this->cpp = fusion_get_settings('comments_per_page');
    }

   
/**
     * Get an instance by key
     *
     * @param array  $params
     * @param string $key
     *
     * @return static
     */
   
public static function getInstance(array $params = [], $key = 'Default') {
        if (!isset(
self::$instances[$key])) {
           
self::$instances[$key] = new static();
           
self::$key = $key;
           
$params['comment_key'] = $key;
           
self::$params = $params + self::$params;
           
self::setInstance($key);
        }

        return
self::$instances[$key];
    }

   
/**
     * @param string $key
     */
   
private static function setInstance($key) {
       
$obj = self::getInstance([], $key);
       
$obj->setParams(self::$params);
       
$obj->setEmptyCommentData();
       
$obj->checkPermissions();
       
$obj->executeCommentUpdate();
       
$obj->getComments();
    }

   
/**
     * Displays Comments
     */
   
public function showComments() {

       
$comments_form = '';
       
$html = '';
        if (
$this->settings['comments_enabled'] == TRUE) {
           
$settings = fusion_get_settings();

           
$clink = $this->getParams('clink');

           
/**
             * Forms
             */
           
if ($this->getParams('comment_allow_post')) {
               
$edata = [
                   
'comment_cat'     => 0,
                   
'comment_subject' => '',
                   
'comment_message' => '',
                ];

                if (
iMEMBER && (isset($_GET['c_action']) && $_GET['c_action'] == "edit") && (isset($_GET['comment_id']) && isnum($_GET['comment_id']))) {
                   
$edit_query = "
                        SELECT tcm.*
                        FROM "
.DB_COMMENTS." tcm
                        WHERE comment_id=:comment_id AND comment_item_id=:comment_item_id AND comment_type=:comment_type AND comment_hidden=:comment_hidden"
;

                   
$edit_param = [
                       
':comment_id'      => $_GET['comment_id'],
                       
':comment_item_id' => $this->getParams('comment_item_id'),
                       
':comment_type'    => $this->getParams('comment_item_type'),
                       
':comment_hidden'  => 0,
                    ];
                   
$e_result = dbquery($edit_query, $edit_param);

                    if (
dbrows($e_result)) {
                       
$edata = dbarray($e_result);
                        if ((
iADMIN && checkrights("C")) || (iMEMBER && $edata['comment_name'] == fusion_get_userdata('user_id') && isset($edata['user_name']))) {
                           
$clink = $this->getParams('clink')."&c_action=edit&comment_id=".$edata['comment_id'];
                        }
                    }
                }

               
$can_post = iMEMBER || fusion_get_settings('guestposts');
               
// Comments form
                //$form_action = fusion_get_settings('site_path').str_replace('../', '', self::format_clink($clink));
               
$form_action = self::formatClink($clink);

               
$comments_form = openform('inputform', 'post', $form_action, ['form_id' => $this->getParams('comment_key').'-inputform']);
               
$ratings_input = '';
               
$_CAPTCHA_FORM_HTML = '';
               
$_CAPTCHA_HTML_INPUT = '';

                if (
$can_post) {
                   
$comments_form .= form_hidden('comment_id', '', '', ['input_id' => $this->getParams('comment_key').'-comment_id']);
                   
$comments_form .= form_hidden('comment_cat', '', $edata['comment_cat'], ['input_id' => $this->getParams('comment_key').'-comment_cat']);

                   
/*
                     * Ratings Selector
                     */
                   
if (fusion_get_settings('ratings_enabled') && $this->getParams('comment_allow_ratings') && $this->getParams('comment_allow_vote')) {
                       
$ratings_input .= form_select('comment_rating', $this->locale['r106'], '',
                            [
                               
'input_id' => $this->getParams('comment_key').'-comment_rating',
                               
'options'  => [
                                   
5 => $this->locale['r120'],
                                   
4 => $this->locale['r121'],
                                   
3 => $this->locale['r122'],
                                   
2 => $this->locale['r123'],
                                   
1 => $this->locale['r124']
                                ]
                            ]
                        );
                    }
                }
               
// Captcha for Guest
               
if (!iMEMBER && fusion_get_settings('guestposts') == TRUE && (!isset($_CAPTCHA_HIDE_INPUT) || (!$_CAPTCHA_HIDE_INPUT))) {
                   
$_CAPTCHA_HIDE_INPUT = FALSE;
                    include
INCLUDES.'captchas/'.$settings['captcha'].'/captcha_display.php';

                   
$_CAPTCHA_FORM_HTML = display_captcha([
                       
'captcha_id' => 'captcha_'.$this->getParams('comment_key'),
                       
'input_id'   => 'captcha_code_'.$this->getParams('comment_key'),
                       
'image_id'   => 'captcha_image_'.$this->getParams('comment_key')
                    ]);

                    if (!
$_CAPTCHA_HIDE_INPUT) {
                       
$_CAPTCHA_HTML_INPUT = form_text('captcha_code', $this->locale['global_151'], '', ['required' => TRUE, 'autocomplete_off' => TRUE, 'input_id' => 'captcha_code_'.$this->getParams('comment_key')]);
                    }
                }

               
$avatar = display_avatar(fusion_get_userdata(), "50px", "", FALSE);

               
$button = form_button('post_comment', $edata['comment_message'] ? $this->locale['c103'] : $this->locale['c102'], ($edata['comment_message'] ? $this->locale['c103'] : $this->locale['c102']),
                    [
'class' => 'btn-primary spacer-sm post_comment', 'input_id' => $this->getParams('comment_key').'-post_comment']
                );

               
$comments_form .= display_comments_form([
                   
'comment_form_title'     => ($this->getParams('comment_form_title') ?: $this->locale['c111']),
                   
'comment_form_id'        => $this->getParams('comment_key').'_edit_comment',
                   
'user_avatar'            => $can_post ? $avatar : '',
                   
'comment_name_input'     => ($can_post ? (iGUEST ? form_text('comment_name', $this->locale['c104'], '', ['max_length' => 30, 'required' => TRUE, 'input_id' => $this->getParams('comment_key').'-comment_name']) : '') : ''),
                   
'comment_subject_input'  => ($can_post ? $this->getParams('comment_allow_subject') ? form_text('comment_subject', $this->locale['c113'], $edata['comment_subject'], ['required' => TRUE, 'input_id' => $this->getParams('comment_key').'-comment_subject']) : '' : ''),
                   
'comment_message_input'  => ($can_post ? form_textarea($edata['comment_cat'] ? 'comment_message_reply' : 'comment_message', '', $edata['comment_message'],
                        [
                           
'input_id'     => $this->getParams('comment_key')."-comment_message",
                           
'required'     => 1,
                           
'autosize'     => TRUE,
                           
'form_name'    => 'inputform',
                           
"tinymce"      => "simple",
                           
'wordcount'    => TRUE,
                           
'type'         => $this->getParams('comment_bbcode') ? 'bbcode' : ($this->getParams('comment_tinymce') ? 'tinymce' : 'text'),
                           
'tinymce_skin' => $this->getParams('comment_tinymce_skin')
                        ]
                    ) :
$this->locale['c105']),
                   
'comments_ratings_input' => $ratings_input,
                   
'comments_captcha'       => ['captcha' => $_CAPTCHA_FORM_HTML, 'input' => $_CAPTCHA_HTML_INPUT],
                   
'comment_post'           => $can_post ? $button : '',
                   
'comment_type'           => $this->getParams('comment_item_type'),
                   
'clink'                  => $this->getParams('clink'),
                   
'comment_item_id'        => $this->getParams('comment_item_id'),
                   
'options'                => $this->getParams()
                ]);

               
$comments_form .= closeform();
            }

           
/**
             * Comments
             */
           
$ratings_html = '';
           
$c_info = $this->c_arr['c_info'];
            if (
fusion_get_settings('ratings_enabled') && $this->getParams('comment_allow_ratings')) {
                if (!empty(
$c_info['ratings_count'])) {
                   
$stars = '';
                   
$ratings = [];

                   
$remainder = 5 - (int)$c_info['ratings_count']['avg'];
                    for (
$i = 1; $i <= $c_info['ratings_count']['avg']; $i++) {
                       
$stars .= '<i class="fas fa-star text-warning"></i> ';
                    }
                    if (
$remainder) {
                        for (
$i = 1; $i <= $remainder; $i++) {
                           
$stars .= '<i class="far fa-star text-lighter"></i> ';
                        }
                    }

                    for (
$i = 5; $i >= 1; $i--) {
                       
$bal = 5 - $i;
                       
$stars_ = '';
                        for (
$x = 1; $x <= $i; $x++) {
                           
$stars_ .= '<i class="fas fa-star text-warning"></i> ';
                        }

                        for (
$b = 1; $b <= $bal; $b++) {
                           
$stars_ .= '<i class="far fa-star text-lighter"></i> ';
                        }

                       
$progress_num = $c_info['ratings_count'][$i] == 0 ? 0 : round((($c_info['ratings_count'][$i] / $c_info['ratings_count']['total']) * 100), 1);
                       
$progressbar = progress_bar($progress_num, '', ['height' => '10px', 'hide_info' => TRUE, 'progress_class' => 'm-0']);
                       
$ratings[] = [
                           
'stars'       => $stars_,
                           
'stars_count' => $c_info['ratings_count'][$i] ?: 0,
                           
'progressbar' => $progressbar
                       
];
                    }

                   
$ratings_html = display_comments_ratings([
                       
'stars'                 => $stars,
                       
'reviews'               => format_word($c_info['ratings_count']['total'], $this->locale['fmt_review']),
                       
'ratings'               => $ratings,
                       
'ratings_remove_button' => $c_info['ratings_remove_form'] ?: ''
                   
]);
                }
            }

           
// @bug: Split the array into page chunks. [0] for page 1, [1] for page 2
            // Display comments
           
$no_comments_text = display_no_comments($this->locale['c101']);
           
$comments = display_comments_listing([
               
'comments_page'       => ($this->c_arr['c_info']['c_makepagenav'] ? "<div class='text-left'>".$this->c_arr['c_info']['c_makepagenav']."</div>\n" : ''),
               
'comments_list'       => (!empty($this->c_arr['c_con']) ? $this->displayAllComments($this->c_arr['c_con'], 0, $this->getParams()) : $no_comments_text),
               
'comments_admin_link' => $this->c_arr['c_info']['admin_link'],
            ]);

           
$comments_listing = display_comments_section([
               
'comment_count'   => ($this->getParams('comment_count') ? $this->c_arr['c_info']['comments_count'] : ''),
               
'comment_ratings' => $ratings_html,
               
'comments'        => $comments,
               
'comments_form'   => $comments_form,
               
'c_data'          => $this->c_arr['c_con'],
               
'c_info'          => $this->c_arr['c_info'],
               
'options'         => $this->getParams()
            ]);

           
$html .= display_comments_ui([
               
'comment_title'             => $this->getParams('comment_title'),
               
'comment_count'             => ($this->getParams('comment_count') ? $this->c_arr['c_info']['comments_count'] : ''),
               
'comment_container_id'      => $this->getParams('comment_key'),
               
'comment_form_container_id' => $this->getParams('comment_key').'-comments_form',
               
'comments_listing'          => $comments_listing,
               
'comments_form'             => $comments_form
           
]);
        }

        if (
$this->getParams('comment_echo')) {
            echo
$html;
        }

        return
$html;
    }

   
/**
     * Comments Listing
     *
     * @param array        $c_data
     * @param int          $index
     * @param string|array $options
     *
     * @return string
     */
   
private function displayAllComments($c_data, $index, $options) {
       
$comments_html = '';
        foreach (
$c_data[$index] as $comments_id => $data) {
           
$data['comment_ratings'] = '';
            if (
fusion_get_settings('ratings_enabled') && $this->getParams('comment_allow_ratings')) {
               
$remainder = 5 - (int)$data['ratings'];
                for (
$i = 1; $i <= $data['ratings']; $i++) {
                   
$data['comment_ratings'] .= '<i class="fas fa-star text-warning"></i> ';
                }
                if (
$remainder) {
                    for (
$i = 1; $i <= $remainder; $i++) {
                       
$data['comment_ratings'] .= '<i class="far fa-star text-lighter"></i> ';
                    }
                }
            }

           
$data_api = \Defender::encode($options);

           
$data += [
               
'comment_list_id'      => 'c'.$data['comment_id'],
               
'user_avatar'          => $data['user_avatar'],
               
'user_name'            => $data['comment_name'],
               
'comment_date'         => $data['comment_datestamp'],
               
'comment_ratings'      => $data['comment_ratings'],
               
'comment_subject'      => $data['comment_subject'],
               
'comment_message'      => $data['comment_message'],
               
'comment_reply_link'   => ($data['reply_link'] ? "<a href='".$data['reply_link']."' class='comments-reply display-inline' data-id='$comments_id'>".$this->locale['c112']."</a>" : ''),
               
'comment_edit_link'    => ($data['edit_link'] ? "<a href='".$data['edit_link']['link']."' class='edit-comment display-inline' data-id='".$data['comment_id']."' data-api='$data_api' data-key='".$this->getParams('comment_key')."'>".$data['edit_link']['name']."</a>" : ''),
               
'comment_delete_link'  => ($data['delete_link'] ? "<a href='".$data['delete_link']['link']."' class='delete-comment display-inline' data-id='".$data['comment_id']."' data-api='$data_api' data-type='".$options['comment_item_type']."' data-item='".$options['comment_item_id']."' data-key='".$this->getParams('comment_key')."'>".$data['delete_link']['name']."</a>" : ''),
               
'comment_reply_form'   => ($data['reply_form'] ?: ''),
               
'comment_sub_comments' => (isset($c_data[$data['comment_id']]) ? $this->displayAllComments($c_data, $data['comment_id'], $options) : '')
            ];
           
$comments_html .= display_comments_list($data);
        }

        return
$comments_html;
    }

   
/**
     * Check permissions
     */
   
private function checkPermissions() {
       
$my_id = fusion_get_userdata('user_id');
        if (
dbcount("(rating_id)", DB_RATINGS, "
            rating_user='"
.$my_id."'
            AND rating_item_id='"
.$this->getParams('comment_item_id')."'
            AND rating_type='"
.$this->getParams('comment_item_type')."'
            "
       
)
        ) {
           
$this->replaceParam('comment_allow_vote', FALSE); // allow ratings
       
}
        if (
dbcount("(comment_id)", DB_COMMENTS, "
            comment_name='"
.$my_id."' AND comment_cat='0'
            AND comment_item_id='"
.$this->getParams('comment_item_id')."'
            AND comment_type='"
.$this->getParams('comment_item_type')."'
            "
           
)
            &&
$this->getParams('comment_once')
        ) {
           
$this->replaceParam('comment_allow_post', FALSE); // allow post
       
}
    }

   
/**
     * Get Comment Object Parameter
     *
     * @param null $key null for all array
     *
     * @return null
     */
   
public function getParams($key = NULL) {
        if (
$key !== NULL) {
            return isset(
$this->comment_params[self::$key][$key]) ? $this->comment_params[self::$key][$key] : NULL;
        }

        return
$this->comment_params[self::$key];
    }

   
/**
     * Replace Comment Object Parameter
     *
     * @param $param
     * @param $value
     */
   
public function replaceParam($param, $value) {
        if (isset(
$this->comment_params[self::$key][$param])) {
           
$this->comment_params[self::$key][$param] = $value;
        }
    }

   
/**
     * Set Comment Object Parameters
     *
     * @param array $params
     */
   
private function setParams(array $params = []) {
       
$this->comment_params[self::$key] = $params;
    }

   
/**
     * Set empty comment data
     */
   
private function setEmptyCommentData() {
       
$this->comment_data = [
           
'comment_id'        => isset($_GET['comment_id']) && isnum($_GET['comment_id']) ? $_GET['comment_id'] : 0,
           
'comment_name'      => '',
           
'comment_subject'   => '',
           
'comment_message'   => '',
           
'comment_datestamp' => time(),
           
'comment_item_id'   => $this->getParams('comment_item_id'),
           
'comment_type'      => $this->getParams('comment_item_type'),
           
'comment_cat'       => 0,
           
'comment_ip'        => USER_IP,
           
'comment_ip_type'   => USER_IP_TYPE,
           
'comment_hidden'    => 0,
        ];
    }

   
/**
     * Execute comment update
     */
   
private function executeCommentUpdate() {

       
$this->replaceParam('comment_user', $this->userdata['user_id']);

       
// Non Jquery Actions
       
if (isset($_GET['comment_reply'])) {
           
add_to_jquery("scrollTo('comments_reply_form');");
        }

       
/** Delete */
       
if (isset($_GET['c_action']) && iMEMBER) {
            if (
$_GET['c_action'] == 'delete') {
               
$delete_query = "
                SELECT tcm.*, tcu.user_name
                FROM "
.DB_COMMENTS." tcm
                LEFT JOIN "
.DB_USERS." tcu ON tcm.comment_name=tcu.user_id
                WHERE comment_id=:comment_id AND comment_hidden=:comment_hidden
                "
;
               
$delete_param = [
                   
':comment_id'     => intval(stripinput($_GET['comment_id'])),
                   
':comment_hidden' => 0,
                ];

               
$eresult = dbquery($delete_query, $delete_param);
                if (
dbrows($eresult)) {
                   
$edata = dbarray($eresult);
                   
$redirect_link = $this->getParams('clink').($this->settings['comments_sorting'] == "ASC" ? "" : "&c_start=0")."#c".$_GET['comment_id'];
                   
$child_query = "SELECT comment_id FROM ".DB_COMMENTS." WHERE comment_cat=:comment_cat_id";
                   
$child_param = [':comment_cat_id' => intval($_GET['comment_id'])];
                   
$result = dbquery($child_query, $child_param);
                    if (
dbrows($result)) {
                        while (
$child = dbarray($result)) {
                           
dbquery("UPDATE ".DB_COMMENTS." SET comment_cat='".$edata['comment_cat']."' WHERE comment_id='".$child['comment_id']."'");
                        }
                    }
                   
dbquery("DELETE FROM ".DB_COMMENTS." WHERE comment_id='".$edata['comment_id']."'".(iADMIN ? "" : "AND comment_name='".$this->userdata['user_id']."'"));
                   
$func = $this->getParams('comment_delete_callback_function');
                    if (
is_callable($func)) {
                       
$func($this->getParams());
                    }

                   
redirect($redirect_link);
                }
            }
        }

       
/** Update & Save */
        // Ratings Removal Update
        // post comment_type, comment_item_id, remove_ratings_vote;
       
if (iMEMBER && $this->getParams('comment_allow_ratings') && !$this->getParams('comment_allow_vote')) {
            if (isset(
$_POST['remove_ratings_vote'])) {
               
$my_id = fusion_get_userdata('user_id');
               
$delete_ratings = "DELETE FROM ".DB_RATINGS."
                WHERE rating_item_id='"
.$this->getParams('comment_item_id')."'
                AND rating_type = '"
.$this->getParams('comment_item_type')."'
                AND rating_user = '
$my_id'";
               
$result = dbquery($delete_ratings);
                if (
$result) {
                   
redirect(self::formatClink($this->getParams('clink')));
                }
            }
        }

       
/**
         * Post Comment, Reply Comment
         */
       
if ((iMEMBER || $this->settings['guestposts']) && isset($_POST['post_comment'])) {

            if (!
iMEMBER && $this->settings['guestposts']) {
               
// Process Captchas
               
$_CAPTCHA_IS_VALID = FALSE;
                include
INCLUDES."captchas/".$this->settings['captcha']."/captcha_check.php";
                if (!
$_CAPTCHA_IS_VALID) {
                   
fusion_stop();
                   
addnotice("danger", $this->locale['u194']);
                }
            }

           
$default_comment_id = isset($_POST['comment_id']) && isnum($_POST['comment_id']) ? intval($_POST['comment_id']) : 0;

           
$comment_data = [
               
'comment_id'      => isset($_GET['comment_id']) && isnum($_GET['comment_id']) ? $_GET['comment_id'] : $default_comment_id,
               
'comment_name'    => iMEMBER ? $this->userdata['user_id'] : form_sanitizer($_POST['comment_name'], '', 'comment_name'),
               
'comment_subject' => empty($_POST['comment_cat']) && isset($_POST['comment_subject']) ? form_sanitizer($_POST['comment_subject'], '', 'comment_subject') : '',
               
'comment_item_id' => $this->getParams('comment_item_id'),
               
'comment_type'    => $this->getParams('comment_item_type'),
               
'comment_cat'     => form_sanitizer($_POST['comment_cat'], 0, 'comment_cat'),
               
'comment_ip'      => USER_IP,
               
'comment_ip_type' => USER_IP_TYPE,
               
'comment_hidden'  => 0,
            ];

           
// there is a conflict. the form above and the form below is same?
           
$comment_data['comment_message'] = $comment_data['comment_cat'] ? form_sanitizer($_POST['comment_message_reply'], '', 'comment_message_reply') : form_sanitizer($_POST['comment_message'], '', 'comment_message');

           
$ratings_query = "
            SELECT rating_id FROM "
.DB_RATINGS." WHERE rating_item_id='".$comment_data['comment_item_id']."'
            AND rating_type='"
.$comment_data['comment_type']."' AND rating_user='".$comment_data['comment_name']."'
            "
;

           
$ratings_data = [];

           
$ratings_id = dbresult(dbquery($ratings_query), 0);
            if (
$this->getParams('comment_allow_ratings') && $this->getParams('comment_allow_vote') && isset($_POST['comment_rating'])) {
               
$ratings_data = [
                   
'rating_id'        => $ratings_id,
                   
'rating_item_id'   => $this->getParams('comment_item_id'),
                   
'rating_type'      => $this->getParams('comment_item_type'),
                   
'rating_user'      => $comment_data['comment_name'],
                   
'rating_vote'      => form_sanitizer($_POST['comment_rating'], 0, 'comment_rating'),
                   
'rating_datestamp' => time(),
                   
'rating_ip'        => USER_IP,
                   
'rating_ip_type'   => USER_IP_TYPE
               
];
            }

            if (
iMEMBER && $comment_data['comment_id']) {
               
// Update comment
               
if ((iADMIN && checkrights("C")) || (iMEMBER && dbcount("(comment_id)", DB_COMMENTS, "comment_id='".$comment_data['comment_id']."'
                        AND comment_item_id='"
.$this->getParams('comment_item_id')."'
                        AND comment_type='"
.$this->getParams('comment_item_type')."'
                        AND comment_name='"
.$this->userdata['user_id']."'
                        AND comment_hidden='0'"
)) && fusion_safe()
                ) {

                   
$c_name_query = "SELECT comment_name FROM ".DB_COMMENTS." WHERE comment_id='".$comment_data['comment_id']."'";
                   
$comment_data['comment_name'] = dbresult(dbquery($c_name_query), 0);

                   
dbquery_insert(DB_COMMENTS, $comment_data, 'update');
                   
$this->comment_params[self::$key]['post_id'] = $comment_data['comment_id'];

                   
$func = $this->getParams('comment_edit_callback_function');
                    if (
is_callable($func)) {
                       
$func($this->getParams());
                    }

                    if (
iMEMBER && $this->getParams('comment_allow_ratings') && $this->getParams('comment_allow_vote')) {
                       
dbquery_insert(DB_RATINGS, $ratings_data, ($ratings_data['rating_id'] ? 'update' : 'save'));
                    }

                    if (
$this->settings['comments_sorting'] == "ASC") {
                       
$c_operator = "<=";
                    } else {
                       
$c_operator = ">=";
                    }

                   
$c_count = dbcount("(comment_id)", DB_COMMENTS, "comment_id".$c_operator."'".$comment_data['comment_id']."'
                            AND comment_item_id='"
.$this->getParams('comment_item_id')."'
                            AND comment_type='"
.$this->getParams('comment_item_type')."'");

                   
$c_start = (ceil($c_count / $this->settings['comments_per_page']) - 1) * $this->settings['comments_per_page'];
                    if (
fusion_safe()) {
                       
addnotice("success", $this->locale['c114']);
                       
$_c = (isset($c_start) && isnum($c_start) ? $c_start : "");
                       
$c_link = $this->getParams('clink');
                       
redirect(self::formatClink("$c_link&c_start=$_c"));
                    }
                }
            } else {

               
$comment_data['comment_datestamp'] = time();

                if (
fusion_safe()) {

                   
$c_start = 0;

                    if (
$comment_data['comment_name'] && $comment_data['comment_message']) {

                        require_once
INCLUDES."flood_include.php";

                        if (!
flood_control("comment_datestamp", DB_COMMENTS, "comment_ip='".USER_IP."'")) {

                           
$id = dbquery_insert(DB_COMMENTS, $comment_data, 'save');

                           
$this->comment_params[self::$key]['post_id'] = $id;

                           
$func = $this->getParams('comment_post_callback_function');
                            if (
is_callable($func)) {
                               
$func($this->getParams());
                            }

                            if (
iMEMBER && fusion_get_settings('ratings_enabled') && $this->getParams('comment_allow_ratings') && $this->getParams('comment_allow_vote')) {
                               
dbquery_insert(DB_RATINGS, $ratings_data, ($ratings_data['rating_id'] ? 'update' : 'save'));
                            }

                            if (
$this->settings['comments_sorting'] == "ASC") {
                               
$c_count = dbcount("(comment_id)", DB_COMMENTS, "comment_item_id='".$this->getParams('comment_item_id')."' AND comment_type='".$this->getParams('comment_item_type')."'");
                               
$c_start = (ceil($c_count / $this->settings['comments_per_page']) - 1) * $this->settings['comments_per_page'];
                            }

                           
redirect(self::formatClink($this->getParams('clink'))."&c_start=".$c_start."#c".$id);
                        }
                    }
                }
            }
        }
    }

   
/**
     * @param string $clink
     *
     * @return string
     */
   
private static function formatClink($clink) {
        if (empty(
self::$clink[$clink])) {
           
$fusion_query = [];
           
$url = ((array)parse_url(htmlspecialchars_decode($clink))) + [
                   
'path'  => '',
                   
'query' => ''
               
];
            if (
$url['query']) {
               
parse_str($url['query'], $fusion_query); // this is original.
           
}
           
$fusion_query = array_diff_key($fusion_query, array_flip(["comment_reply"]));
           
$prefix = $fusion_query ? '?' : '';
           
self::$clink[$clink] = $url['path'].$prefix.http_build_query($fusion_query);
        }

        return (string)
self::$clink[$clink];
    }

   
/*
     * Fetches comment data
     */
   
private function getComments() {

        if (
fusion_get_settings('comments_enabled')) {

            if (
$this->getParams('comment_allow_ratings')) {
               
$ratings_query = "
                SELECT
                COUNT(rating_id) 'total',
                IF(avg(rating_vote), avg(rating_vote), 0) 'avg',
                SUM(IF(rating_vote='5', 1, 0)) '5',
                SUM(IF(rating_vote='4', 1, 0)) '4',
                SUM(IF(rating_vote='3', 1, 0)) '3',
                SUM(IF(rating_vote='2', 1, 0)) '2',
                SUM(IF(rating_vote='1', 1, 0)) '1'
                FROM "
.DB_RATINGS."
                WHERE rating_type=:ratings_type AND rating_item_id=:ratings_item_id
                "
;
               
$ratings_bind = [
                   
':ratings_type'    => $this->getParams('comment_item_type'),
                   
':ratings_item_id' => $this->getParams('comment_item_id')
                ];
               
$this->c_arr['c_info']['ratings_count'] = dbarray(dbquery($ratings_query, $ratings_bind));
               
$this->c_arr['c_info']['ratings_remove_form'] = '';
                if (
$this->getParams('comment_allow_ratings') && !$this->getParams('comment_allow_vote')) {
                   
$ratings_html = openform('remove_ratings_frm', 'post', $this->getParams('clink'), [
                           
'class'   => 'text-right',
                           
'form_id' => $this->getParams('comment_key')."-remove_ratings_frm",
                        ]
                    );
                   
$ratings_html .= form_hidden('comment_type', '', $this->getParams('comment_item_type'));
                   
$ratings_html .= form_hidden('comment_item_id', '', $this->getParams('comment_item_id'));
                   
$ratings_html .= form_button('remove_ratings_vote', $this->locale['r102'], 'remove_ratings_vote', ['input_id' => $this->getParams('comment_key')."-remove_ratings_vote", 'class' => 'btn-default btn-rmRatings']);
                   
$ratings_html .= closeform();
                   
$this->c_arr['c_info']['ratings_remove_form'] = $ratings_html;
                }
            }

           
$this->c_arr['c_info']['comments_count'] = format_word(0, $this->locale['fmt_comment']);
           
$this->c_arr['c_info']['total_comments'] = 0;

           
$c_rows = dbcount("('comment_id')", DB_COMMENTS, "comment_item_id=:comment_item_id AND comment_type=:comment_item_type AND comment_hidden=:comment_hidden",
                [
                   
':comment_item_id'   => $this->getParams('comment_item_id'),
                   
':comment_item_type' => $this->getParams('comment_item_type'),
                   
':comment_hidden'    => 0
               
]
            );

           
$this->c_arr['c_info']['total_comments'] = $c_rows;

           
$root_comment_rows = dbcount("(comment_id)", DB_COMMENTS, "comment_item_id=:comment_item_id AND comment_type=:comment_item_type AND comment_cat=:zero AND comment_hidden=:zero2",
                [
                   
':comment_item_type' => $this->getParams('comment_item_type'),
                   
':comment_item_id'   => $this->getParams('comment_item_id'),
                   
':zero'              => 0,
                   
':zero2'             => 0,
                ]);

            if (
$root_comment_rows) {

               
// Pagination control string
               
self::$c_start = isset($_GET['c_start_'.$this->getParams('comment_key')]) && isnum($_GET['c_start_'.$this->getParams('comment_key')]) ? $_GET['c_start_'.$this->getParams('comment_key')] : 0;
               
// Only applicable if sorting is Ascending. If descending, the default $c_start is always 0 as latest.
               
if (fusion_get_settings('comments_sorting') == 'ASC') {
                   
$getname = 'c_start_'.$this->getParams('comment_key');
                    if (!isset(
$_GET[$getname]) && $root_comment_rows > $this->cpp) {
                       
self::$c_start = (ceil($root_comment_rows / $this->cpp) - 1) * $this->cpp;
                    }
                }

               
$comment_query = "
                    SELECT tcm.* "
.($this->getParams('comment_allow_ratings') && fusion_get_settings('ratings_enabled') ? ", tcr.rating_vote 'ratings'" : '')."
                    FROM "
.DB_COMMENTS." tcm
                    "
.($this->getParams('comment_allow_ratings') && fusion_get_settings('ratings_enabled') ? "LEFT JOIN ".DB_RATINGS." tcr ON tcr.rating_item_id=tcm.comment_item_id AND tcr.rating_type=tcm.comment_type AND tcr.rating_user=tcm.comment_name" : '')."
                    WHERE comment_item_id=:comment_item_id AND comment_type=:comment_item_type AND comment_hidden=:comment_hidden AND comment_cat = 0
                    ORDER BY comment_datestamp "
.$this->settings['comments_sorting'].", comment_id ASC, comment_cat ASC LIMIT ".self::$c_start.", ".$this->cpp."
                "
;
               
$comment_bind = [
                   
':comment_item_id'   => $this->getParams('comment_item_id'),
                   
':comment_item_type' => $this->getParams('comment_item_type'),
                   
':comment_hidden'    => 0
               
];

               
$query = dbquery($comment_query, $comment_bind);

                if (
dbrows($query)) {

                   
$i = ($this->settings['comments_sorting'] == "ASC" ? self::$c_start + 1 : $root_comment_rows - self::$c_start);

                    if (
$root_comment_rows > $this->cpp) {
                       
$this->c_arr['c_info']['c_makepagenav'] = makepagenav(self::$c_start, $this->cpp, $root_comment_rows, 3, $this->getParams('clink').(stristr($this->getParams('clink'), '?') ? "&" : '?'), "c_start_".$this->getParams('comment_key'));
                    }

                    if (
iADMIN && checkrights('C')) {
                       
$this->c_arr['c_info']['admin_link'] = "<!--comment_admin-->\n";
                       
$this->c_arr['c_info']['admin_link'] .= "<a href='".ADMIN."comments.php".fusion_get_aidlink()."&ctype=".$this->getParams('comment_item_type')."&comment_item_id=".$this->getParams('comment_item_id')."'>".$this->locale['c106']."</a>";
                    }
                    while (
$row = dbarray($query)) {
                       
$this->parseCommentsData($row, $i);
                       
$this->settings['comments_sorting'] == "ASC" ? $i++ : $i--;
                    }
                   
$this->c_arr['c_info']['comments_per_page'] = $this->cpp;
                   
$this->c_arr['c_info']['comments_count'] = format_word(number_format($this->c_arr['c_info']['total_comments']), $this->locale['fmt_comment']);
                }
            }
        }
    }

   
/*
     * Parse comment results
     */
   
private function parseCommentsData($row, $i) {
       
$can_reply = iMEMBER || fusion_get_settings('guestposts');
       
$garray = [];

        if (!
isnum($row['comment_name'])) {
           
$garray = [
               
'user_id'     => 0,
               
'user_name'   => $row['comment_name'],
               
'user_avatar' => '',
               
'user_status' => 0,
            ];
        }

       
$row = array_merge_recursive($row, isnum($row['comment_name']) ? fusion_get_user($row['comment_name']) : $garray);

       
$actions = [
           
'edit_link'   => '',
           
'delete_link' => ''
       
];
        if ((
iADMIN && checkrights("C")) || (iMEMBER && $row['comment_name'] == $this->userdata['user_id'] && isset($row['user_name']))) {
           
$edit_link = $this->getParams('clink')."&c_action=edit&comment_id=".$row['comment_id']."#edit_comment"; //clean_request('c_action=edit&comment_id='.$row['comment_id'], array('c_action', 'comment_id'),FALSE)."#edit_comment";
           
$delete_link = $this->getParams('clink')."&c_action=delete&comment_id=".$row['comment_id']; //clean_request('c_action=delete&comment_id='.$row['comment_id'], array('c_action', 'comment_id'), FALSE);
           
$actions = [
               
"edit_link"   => ['link' => $edit_link, 'name' => $this->locale['edit']],
               
"delete_link" => ['link' => $delete_link, 'name' => $this->locale['delete']]
            ];
        }
       
// Reply Form
       
$reply_form = '';
        if (
$this->getParams('comment_allow_reply') && (isset($_GET['comment_reply']) && $_GET['comment_reply'] == $row['comment_id']) && $can_reply) {

           
$this->comment_data['comment_cat'] = $row['comment_id'];

           
$reply_form .= openform('comments_reply_frm-'.$row['comment_id'], 'post', self::formatClink($this->getParams('clink')));

           
$_CAPTCHA_HTML = '';
           
$_CAPTCHA_INPUT = '';

            if (
iGUEST && (!isset($_CAPTCHA_HIDE_INPUT) || (!$_CAPTCHA_HIDE_INPUT))) {
               
$_CAPTCHA_HIDE_INPUT = FALSE;
                include
INCLUDES.'captchas/'.fusion_get_settings('captcha').'/captcha_display.php';

               
$_CAPTCHA_HTML = display_captcha([
                   
'captcha_id' => 'reply_captcha_'.$this->getParams('comment_key'),
                   
'input_id'   => 'reply_captcha_code_'.$this->getParams('comment_key'),
                   
'image_id'   => 'reply_captcha_image_'.$this->getParams('comment_key')
                ]);

                if (!
$_CAPTCHA_HIDE_INPUT) {
                   
$_CAPTCHA_INPUT = form_text('captcha_code', $this->locale['global_151'], '', ['required' => TRUE, 'autocomplete_off' => TRUE, 'input_id' => 'captcha_code_'.$this->getParams('comment_key')]);
                }
            }

           
$reply_form .= display_comments_reply_form([
               
'comment_name'    => (iGUEST ? form_text('comment_name', fusion_get_locale('c104'), $this->comment_data['comment_name'],
                    [
                       
'max_length' => 30,
                       
'input_id'   => 'comment_name-'.$row['comment_id'],
                       
'form_name'  => 'comments_reply_frm-'.$row['comment_id']
                    ]
                ) :
''),
               
'comment_message' => form_textarea("comment_message_reply", "", $this->comment_data['comment_message'],
                    [
                       
"tinymce"   => "simple",
                       
'autosize'  => TRUE,
                       
"type"      => fusion_get_settings("tinymce_enabled") ? "tinymce" : "bbcode",
                       
"input_id"  => "comment_message-".$row['comment_id'],
                       
'form_name' => 'comments_reply_frm-'.$this->comment_data['comment_cat'],
                       
"required"  => TRUE
                   
]),
               
'comment_captcha' => ['captcha' => $_CAPTCHA_HTML, 'input' => $_CAPTCHA_INPUT],
               
'comment_post'    => form_button('post_comment', fusion_get_locale('c102'), $row['comment_id'], [
                       
'class'    => 'post_comment btn-success m-t-10',
                       
'input_id' => 'post_comment-'.$row['comment_id']
                    ]
                )
            ]);

           
$reply_form .= form_hidden("comment_cat", "", $this->comment_data['comment_cat'], ['input_id' => 'comment_cat-'.$row['comment_id']]);
           
$reply_form .= closeform();
        }
       
/** formats $row */
       
$row = [
               
"comment_id"        => $row['comment_id'],
               
"comment_cat"       => $row['comment_cat'],
               
"i"                 => $i,
               
"user_avatar"       => isnum($row['comment_name']) ? display_avatar($row, '50px', '', FALSE, 'm-t-5') : display_avatar([], '50px', '', FALSE, 'm-t-5'),
               
"user"              => [
                   
"user_id"     => $row['user_id'],
                   
"user_name"   => $row['user_name'],
                   
"user_avatar" => $row['user_avatar'],
                   
"status"      => $row['user_status'],
                ],
               
"reply_link"        => $can_reply == TRUE ? self::formatClink($this->getParams('clink')).'&comment_reply='.$row['comment_id'].'#c'.$row['comment_id'] : '',
               
"reply_form"        => $reply_form,
               
'ratings'           => isset($row['ratings']) ? $row['ratings'] : '',
               
'datestamp'         => $row['comment_datestamp'],
               
"comment_datestamp" => showdate('longdate', $row['comment_datestamp']),
               
"comment_time"      => timer($row['comment_datestamp']),
               
"comment_subject"   => $row['comment_subject'],
               
"comment_message"   => parse_text($row['comment_message'], ['decode' => FALSE, 'add_line_breaks' => TRUE]),
               
"comment_name"      => isnum($row['comment_name']) ? profile_link($row['comment_name'], $row['user_name'], $row['user_status']) : $row['comment_name']
            ] +
$actions;


       
$comment_query = "
            SELECT tcm.* "
.($this->getParams('comment_allow_ratings') && fusion_get_settings('ratings_enabled') ? ", tcr.rating_vote 'ratings'" : '')."
            FROM "
.DB_COMMENTS." tcm
            "
.($this->getParams('comment_allow_ratings') && fusion_get_settings('ratings_enabled') ? "LEFT JOIN ".DB_RATINGS." tcr ON tcr.rating_item_id=tcm.comment_item_id AND tcr.rating_type=tcm.comment_type AND tcr.rating_user=tcm.comment_name" : '')."
            WHERE comment_item_id=:comment_item_id AND comment_type=:comment_item_type AND comment_hidden=:comment_hidden AND comment_cat=:comment_cat
            ORDER BY comment_datestamp "
.$this->settings['comments_sorting'].", comment_id ASC, comment_cat ASC LIMIT ".self::$c_start.", ".$this->cpp."
        "
;
       
$comment_bind = [
           
':comment_item_id'   => $this->getParams('comment_item_id'),
           
':comment_item_type' => $this->getParams('comment_item_type'),
           
':comment_hidden'    => 0,
           
':comment_cat'       => $row['comment_id']
        ];

       
$c_result = dbquery($comment_query, $comment_bind);

       
//$c_result = dbquery("SELECT * FROM ".DB_COMMENTS." WHERE comment_cat=:comment_cat", [':comment_cat' => $row['comment_id']]);
       
if (dbrows($c_result)) {
           
$x = 1;
            while (
$c_rows = dbarray($c_result)) {
               
$this->parseCommentsData($c_rows, $x);
               
$this->settings['comments_sorting'] == "ASC" ? $x++ : $x--;
            }
        }

       
$id = $row['comment_id'];
       
$parent_id = $row['comment_cat'] === NULL ? "0" : $row['comment_cat'];
       
//$data[$id] = $row;
       
$this->c_arr['c_con'][$parent_id][$id] = $row;
    }

}

require_once
THEMES.'templates/global/comments.tpl.php';