<commit_before><?php

// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Comment is helper class to add/delete comments anywhere in moodle
 *
 * @package   comment
 * @copyright 2010 <NAME> <<EMAIL>>
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

class comment {
    /**
     * @var integer
     */
    private $page;
    /**
     * there may be several comment box in one page
     * so we need a client_id to recognize them
     * @var integer
     */
    private $cid;
    private $contextid;
    /**
     * commentarea is used to specify different
     * parts shared the same itemid
     * @var string
     */
    private $commentarea;
    /**
     * itemid is used to associate with commenting content
     * @var integer
     */
    private $itemid;

    /**
     * this html snippet will be used as a template
     * to build comment content
     * @var string
     */
    private $template;
    private $context;
    private $courseid;
    /**
     * course module object, only be used to help find pluginname automatically
     * if pluginname is specified, it won't be used at all
     * @var string
     */
    private $cm;
    private $plugintype;
    /**
     * When used in module, it is recommended to use it
     * @var string
     */
    private $pluginname;
    private $viewcap;
    private $postcap;
    /**
     * to tell comments api where it is used
     * @var string
     */
    private $env;
    /**
     * to costomize link text
     * @var string
     */
    private $linktext;

    // static variable will be used by non-js comments UI
    private static $nonjs = false;
    private static $comment_itemid = null;
    private static $comment_context = null;
    private static $comment_area = null;
    private static $comment_page = null;
    private static $comment_component = null;

    /**
     * Construct function of comment class, initialise
     * class members
     * @param object $options
     */
    public function __construct($options) {
        global $CFG, $DB;

        if (empty($CFG->commentsperpage)) {
            $CFG->commentsperpage = 15;
        }

        $this->viewcap = false;
        $this->postcap = false;

        // setup client_id
        if (!empty($options->client_id)) {
            $this->cid = $options->client_id;
        } else {
            $this->cid = uniqid();
        }

        // setup context
        if (!empty($options->context)) {
            $this->context = $options->context;
            $this->contextid = $this->context->id;
        } else if(!empty($options->contextid)) {
            $this->contextid = $options->contextid;
            $this->context = get_context_instance_by_id($this->contextid);
        } else {
            print_error('invalidcontext');
        }

        if (!empty($options->component)) {
            $this->set_component($options->component);
        }

        // setup course
        // course will be used to generate user profile link
        if (!empty($options->course)) {
            $this->courseid = $options->course->id;
        } else if (!empty($options->courseid)) {
            $this->courseid = $options->courseid;
        } else {
            $this->courseid = SITEID;
        }

        // setup coursemodule
        if (!empty($options->cm)) {
            $this->cm = $options->cm;
        } else {
            $this->cm = null;
        }

        // setup commentarea
        if (!empty($options->area)) {
            $this->commentarea = $options->area;
        }

        // setup itemid
        if (!empty($options->itemid)) {
            $this->itemid = $options->itemid;
        } else {
            $this->itemid = 0;
        }

        // setup env
        if (!empty($options->env)) {
            $this->env = $options->env;
        } else {
            $this->env = '';
        }

        // setup customized linktext
        if (!empty($options->linktext)) {
            $this->linktext = $options->linktext;
        } else {
            $this->linktext = get_string('comments');
        }

        if (!empty($options->ignore_permission)) {
            $this->ignore_permission = true;
        } else {
            $this->ignore_permission = false;
        }

        if (!empty($options->showcount)) {
            $count = $this->count();
            if (empty($count)) {
                $this->count = '';
            } else {
                $this->count = '('.$count.')';
            }
        } else {
            $this->count = '';
        }

        // setup options for callback functions
        $this->args = new stdClass();
        $this->args->context     = $this->context;
        $this->args->courseid    = $this->courseid;
        $this->args->cm          = $this->cm;
        $this->args->commentarea = $this->commentarea;
        $this->args->itemid      = $this->itemid;

        // setting post and view permissions
        $this->check_permissions();

        // load template
        $this->template = <<<EOD
<div class="comment-userpicture">___picture___</div>
<div class="comment-content">
    ___name___ - <span>___time___</span>
    <div>___content___</div>
</div>
EOD;
        if (!empty($this->plugintype)) {
            $this->template = plugin_callback($this->plugintype, $this->pluginname, FEATURE_COMMENT, 'template', $this->args, $this->template);
        }

        unset($options);
    }

    /**
     * Receive nonjs comment parameters
     */
    public static function init() {
        global $PAGE, $CFG;
        // setup variables for non-js interface
        self::$nonjs = optional_param('nonjscomment', '', PARAM_ALPHA);
        self::$comment_itemid  = optional_param('comment_itemid',  '', PARAM_INT);
        self::$comment_context = optional_param('comment_context', '', PARAM_INT);
        self::$comment_page    = optional_param('comment_page',    '', PARAM_INT);
        self::$comment_area    = optional_param('comment_area',    '', PARAM_ALPHAEXT);

        $PAGE->requires->string_for_js('addcomment', 'moodle');
        $PAGE->requires->string_for_js('deletecomment', 'moodle');
        $PAGE->requires->string_for_js('comments', 'moodle');
        $PAGE->requires->string_for_js('commentsrequirelogin', 'moodle');
    }

    public function set_component($component) {
        $this->component = $component;
        list($this->plugintype, $this->pluginname) = normalize_component($component);
        return null;
    }

    public function set_view_permission($value) {
        $this->viewcap = $value;
    }

    public function set_post_permission($value) {
        $this->postcap = $value;
    }

    /**
     * check posting comments permission
     * It will check based on user roles and ask modules
     * If you need to check permission by modules, a
     * function named $pluginname_check_comment_post must be implemented
     */
    private function check_permissions() {
        global $CFG;
        $this->postcap = has_capability('moodle/comment:post', $this->context);
        $this->viewcap = has_capability('moodle/comment:view', $this->context);
        if (!empty($this->plugintype)) {
            $permissions = plugin_callback($this->plugintype, $this->pluginname, FEATURE_COMMENT, 'permissions', array($this->args), array('post'=>true, 'view'=>true));
            if ($this->ignore_permission) {
                $this->postcap = $permissions['post'];
                $this->viewcap = $permissions['view'];
            } else {
                $this->postcap = $this->postcap && $permissions['post'];
                $this->viewcap = $this->viewcap && $permissions['view'];
            }
        }
    }

    /**
     * Gets a link for this page that will work with JS disabled.
     *
     * @global moodle_page $PAGE
     * @param moodle_page $page
     * @return moodle_url
     */
    public function get_nojslink(moodle_page $page = null) {
        if ($page === null) {
            global $PAGE;
            $page = $PAGE;
        }

        $link = new moodle_url($page->url, array(
            'nonjscomment'    => true,
            'comment_itemid'  => $this->itemid,
            'comment_context' => $this->context->id,
            'comment_area'    => $this->commentarea,
        ));
        $link->remove_params(array('nonjscomment', 'comment_page'));
        return $link;
    }

    /**
     * Prepare comment code in html
     * @param  boolean $return
     * @return mixed
     */
    public function output($return = true) {
        global $PAGE, $OUTPUT;
        static $template_printed;

        $options = new stdClass();
        $options->client_id = $this->cid;
        $options->commentarea = $this->commentarea;
        $options->itemid = $this->itemid;
        $options->page   = 0;
        $options->courseid = $this->courseid;
        $options->contextid = $this->contextid;
        $options->env = $this->env;
        $options->component = $this->component;
        if ($this->env == 'block_comments') {
            $options->notoggle = true;
            $options->autostart = true;
        }

        $PAGE->requires->js_init_call('M.core_comment.init', array($options), true);

        if (!empty(self::$nonjs)) {
            // return non js comments interface
            return $this->print_comments(self::$comment_page, $return, true);
        }

        $strsubmit = get_string('savecomment');
        $strcancel = get_string('cancel');
        $strshowcomments = get_string('showcommentsnonjs');
        $sesskey = sesskey();
        $html = '';
        // print html template
        // Javascript will use the template to render new comments
        if (empty($template_printed) && !empty($this->viewcap)) {
            $html .= '<div style="display:none" id="cmt-tmpl">' . $this->template . '</div>';
            $template_printed = true;
        }

        if (!empty($this->viewcap)) {
            // print commenting icon and tooltip
            $icon = $OUTPUT->pix_url('t/collapsed');
            $link = $this->get_nojslink($PAGE)->out();
            $html .= <<<EOD
<div class="mdl-left">
<a class="showcommentsnonjs" href="{$link}">{$strshowcomments}</a>
EOD;
            if ($this->env != 'block_comments') {
                $html .= <<<EOD
<a id="comment-link-{$this->cid}" class="comment-link" href="#">
    <img id="comment-img-{$this->cid}" src="$icon" alt="{$this->linktext}" title="{$this->linktext}" />
    <span id="comment-link-text-{$this->cid}">{$this->linktext} {$this->count}</span>
</a>
EOD;
            }

            $html .= <<<EOD
<div id="comment-ctrl-{$this->cid}" class="comment-ctrl">
    <ul id="comment-list-{$this->cid}" class="comment-list">
        <li class="first"></li>
EOD;
            // in comments block, we print comments list right away
            if ($this->env == 'block_comments') {
                $html .= $this->print_comments(0, true, false);
                $html .= '</ul>';
                $html .= $this->get_pagination(0);
            } else {
                $html .= <<<EOD
    </ul>
    <div id="comment-pagination-{$this->cid}" class="comment-pagination"></div>
EOD;
            }

            // print posting textarea
            if (!empty($this->postcap)) {
                $html .= <<<EOD
<div class='comment-area'>
    <div class="bd">
        <textarea name="content" rows="2" cols="20" id="dlg-content-{$this->cid}"></textarea>
    </div>
    <div class="fd" id="comment-action-{$this->cid}">
        <a href="#" id="comment-action-post-{$this->cid}"> {$strsubmit} </a>
EOD;
                if ($this->env != 'block_comments') {
                    $html .= "<span> | </span><a href=\"#\" id=\"comment-action-cancel-{$this->cid}\"> {$strcancel} </a>";
                }
                $html .= <<<EOD
    </div>
</div>
<div class="clearer"></div>
EOD;
            }

            $html .= <<<EOD
</div><!-- end of comment-ctrl -->
</div>
EOD;
        } else {
            $html = '';
        }

        if ($return) {
            return $html;
        } else {
            echo $html;
        }
    }

    /**
     * Return matched comments
     *
     * @param  int $page
     * @return mixed
     */
    public function get_comments($page = '') {
        global $DB, $CFG, $USER, $OUTPUT;
        if (empty($this->viewcap)) {
            return false;<commit_msg>comment MDL-27024 Cleaned up HTML output in comment class<commit_after><?php

// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Comment is helper class to add/delete comments anywhere in moodle
 *
 * @package   comment
 * @copyright 2010 <NAME> <<EMAIL>>
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

class comment {
    /**
     * @var integer
     */
    private $page;
    /**
     * there may be several comment box in one page
     * so we need a client_id to recognize them
     * @var integer
     */
    private $cid;
    private $contextid;
    /**
     * commentarea is used to specify different
     * parts shared the same itemid
     * @var string
     */
    private $commentarea;
    /**
     * itemid is used to associate with commenting content
     * @var integer
     */
    private $itemid;

    /**
     * this html snippet will be used as a template
     * to build comment content
     * @var string
     */
    private $template;
    private $context;
    private $courseid;
    /**
     * course module object, only be used to help find pluginname automatically
     * if pluginname is specified, it won't be used at all
     * @var string
     */
    private $cm;
    private $plugintype;
    /**
     * When used in module, it is recommended to use it
     * @var string
     */
    private $pluginname;
    private $viewcap;
    private $postcap;
    /**
     * to tell comments api where it is used
     * @var string
     */
    private $env;
    /**
     * to costomize link text
     * @var string
     */
    private $linktext;

    // static variable will be used by non-js comments UI
    private static $nonjs = false;
    private static $comment_itemid = null;
    private static $comment_context = null;
    private static $comment_area = null;
    private static $comment_page = null;
    private static $comment_component = null;

    /**
     * Construct function of comment class, initialise
     * class members
     * @param object $options
     */
    public function __construct($options) {
        global $CFG, $DB;

        if (empty($CFG->commentsperpage)) {
            $CFG->commentsperpage = 15;
        }

        $this->viewcap = false;
        $this->postcap = false;

        // setup client_id
        if (!empty($options->client_id)) {
            $this->cid = $options->client_id;
        } else {
            $this->cid = uniqid();
        }

        // setup context
        if (!empty($options->context)) {
            $this->context = $options->context;
            $this->contextid = $this->context->id;
        } else if(!empty($options->contextid)) {
            $this->contextid = $options->contextid;
            $this->context = get_context_instance_by_id($this->contextid);
        } else {
            print_error('invalidcontext');
        }

        if (!empty($options->component)) {
            $this->set_component($options->component);
        }

        // setup course
        // course will be used to generate user profile link
        if (!empty($options->course)) {
            $this->courseid = $options->course->id;
        } else if (!empty($options->courseid)) {
            $this->courseid = $options->courseid;
        } else {
            $this->courseid = SITEID;
        }

        // setup coursemodule
        if (!empty($options->cm)) {
            $this->cm = $options->cm;
        } else {
            $this->cm = null;
        }

        // setup commentarea
        if (!empty($options->area)) {
            $this->commentarea = $options->area;
        }

        // setup itemid
        if (!empty($options->itemid)) {
            $this->itemid = $options->itemid;
        } else {
            $this->itemid = 0;
        }

        // setup env
        if (!empty($options->env)) {
            $this->env = $options->env;
        } else {
            $this->env = '';
        }

        // setup customized linktext
        if (!empty($options->linktext)) {
            $this->linktext = $options->linktext;
        } else {
            $this->linktext = get_string('comments');
        }

        if (!empty($options->ignore_permission)) {
            $this->ignore_permission = true;
        } else {
            $this->ignore_permission = false;
        }

        if (!empty($options->showcount)) {
            $count = $this->count();
            if (empty($count)) {
                $this->count = '';
            } else {
                $this->count = '('.$count.')';
            }
        } else {
            $this->count = '';
        }

        // setup options for callback functions
        $this->args = new stdClass();
        $this->args->context     = $this->context;
        $this->args->courseid    = $this->courseid;
        $this->args->cm          = $this->cm;
        $this->args->commentarea = $this->commentarea;
        $this->args->itemid      = $this->itemid;

        // setting post and view permissions
        $this->check_permissions();

        // load template
        $this->template = <<<EOD
<div class="comment-userpicture">___picture___</div>
<div class="comment-content">
    ___name___ - <span>___time___</span>
    <div>___content___</div>
</div>
EOD;
        if (!empty($this->plugintype)) {
            $this->template = plugin_callback($this->plugintype, $this->pluginname, FEATURE_COMMENT, 'template', $this->args, $this->template);
        }

        unset($options);
    }

    /**
     * Receive nonjs comment parameters
     */
    public static function init() {
        global $PAGE, $CFG;
        // setup variables for non-js interface
        self::$nonjs = optional_param('nonjscomment', '', PARAM_ALPHA);
        self::$comment_itemid  = optional_param('comment_itemid',  '', PARAM_INT);
        self::$comment_context = optional_param('comment_context', '', PARAM_INT);
        self::$comment_page    = optional_param('comment_page',    '', PARAM_INT);
        self::$comment_area    = optional_param('comment_area',    '', PARAM_ALPHAEXT);

        $PAGE->requires->string_for_js('addcomment', 'moodle');
        $PAGE->requires->string_for_js('deletecomment', 'moodle');
        $PAGE->requires->string_for_js('comments', 'moodle');
        $PAGE->requires->string_for_js('commentsrequirelogin', 'moodle');
    }

    public function set_component($component) {
        $this->component = $component;
        list($this->plugintype, $this->pluginname) = normalize_component($component);
        return null;
    }

    public function set_view_permission($value) {
        $this->viewcap = $value;
    }

    public function set_post_permission($value) {
        $this->postcap = $value;
    }

    /**
     * check posting comments permission
     * It will check based on user roles and ask modules
     * If you need to check permission by modules, a
     * function named $pluginname_check_comment_post must be implemented
     */
    private function check_permissions() {
        global $CFG;
        $this->postcap = has_capability('moodle/comment:post', $this->context);
        $this->viewcap = has_capability('moodle/comment:view', $this->context);
        if (!empty($this->plugintype)) {
            $permissions = plugin_callback($this->plugintype, $this->pluginname, FEATURE_COMMENT, 'permissions', array($this->args), array('post'=>true, 'view'=>true));
            if ($this->ignore_permission) {
                $this->postcap = $permissions['post'];
                $this->viewcap = $permissions['view'];
            } else {
                $this->postcap = $this->postcap && $permissions['post'];
                $this->viewcap = $this->viewcap && $permissions['view'];
            }
        }
    }

    /**
     * Gets a link for this page that will work with JS disabled.
     *
     * @global moodle_page $PAGE
     * @param moodle_page $page
     * @return moodle_url
     */
    public function get_nojslink(moodle_page $page = null) {
        if ($page === null) {
            global $PAGE;
            $page = $PAGE;
        }

        $link = new moodle_url($page->url, array(
            'nonjscomment'    => true,
            'comment_itemid'  => $this->itemid,
            'comment_context' => $this->context->id,
            'comment_area'    => $this->commentarea,
        ));
        $link->remove_params(array('nonjscomment', 'comment_page'));
        return $link;
    }

    /**
     * Prepare comment code in html
     * @param  boolean $return
     * @return mixed
     */
    public function output($return = true) {
        global $PAGE, $OUTPUT;
        static $template_printed;

        $options = new stdClass();
        $options->client_id = $this->cid;
        $options->commentarea = $this->commentarea;
        $options->itemid = $this->itemid;
        $options->page   = 0;
        $options->courseid = $this->courseid;
        $options->contextid = $this->contextid;
        $options->env = $this->env;
        $options->component = $this->component;
        if ($this->env == 'block_comments') {
            $options->notoggle = true;
            $options->autostart = true;
        }

        $PAGE->requires->js_init_call('M.core_comment.init', array($options), true);

        if (!empty(self::$nonjs)) {
            // return non js comments interface
            return $this->print_comments(self::$comment_page, $return, true);
        }

        $html = '';

        // print html template
        // Javascript will use the template to render new comments
        if (empty($template_printed) && !empty($this->viewcap)) {
            $html .= html_writer::tag('div', $this->template, array('style' => 'display:none', 'id' => 'cmt-tmpl'));
            $template_printed = true;
        }

        if (!empty($this->viewcap)) {
            // print commenting icon and tooltip
            $html .= html_writer::start_tag('div', array('class' => 'mdl-left'));
            $html .= html_writer::link($this->get_nojslink($PAGE), get_string('showcommentsnonjs'), array('class' => 'showcommentsnonjs'));

            if ($this->env != 'block_comments') {
                $html .= html_writer::start_tag('a', array('class' => 'comment-link', 'id' => 'comment-link-'.$this->cid, 'href' => '#'));
                $html .= html_writer::empty_tag('img', array('id' => 'comment-img-'.$this->cid, 'src' => $OUTPUT->pix_url('t/collapsed'), 'alt' => $this->linktext, 'title' => $this->linktext));
                $html .= html_writer::tag('span', $this->linktext.' '.$this->count, array('id' => 'comment-link-text-'.$this->cid));
                $html .= html_writer::end_tag('a');
            }

            $html .= html_writer::start_tag('div', array('id' => 'comment-ctrl-'.$this->cid, 'class' => 'comment-ctrl'));
            $html .= html_writer::start_tag('ul', array('id' => 'comment-list-'.$this->cid, 'class' => 'comment-list'));
            $html .= html_writer::tag('li', '', array('class' => 'first'));

            if ($this->env == 'block_comments') {
                // in comments block, we print comments list right away
                $html .= $this->print_comments(0, true, false);
                $html .= html_writer::end_tag('ul'); // .comment-list
                $html .= $this->get_pagination(0);
            } else {
                $html .= html_writer::end_tag('ul'); // .comment-list
                $html .= html_writer::tag('div', '', array('id' => 'comment-pagination-'.$this->cid, 'class' => 'comment-pagination'));
            }

            if (!empty($this->postcap)) {
                // print posting textarea
                $html .= html_writer::start_tag('div', array('class' => 'comment-area'));
                $html .= html_writer::start_tag('div', array('class' => 'db'));
                $html .= html_writer::tag('textarea', '', array('name' => 'content', 'rows' => 2, 'cols' => 20, 'id' => 'dlg-content-'.$this->cid));
                $html .= html_writer::end_tag('div'); // .db

                $html .= html_writer::start_tag('div', array('class' => 'fd', 'id' => 'comment-action-'.$this->cid));
                $html .= html_writer::link('#', get_string('savecomment'), array('id' => 'comment-action-post-'.$this->cid));

                if ($this->env != 'block_comments') {
                    $html .= html_writer::tag('span', ' | ');
                    $html .= html_writer::link('#', get_string('cancel'), array('id' => 'comment-action-cancel-'.$this->cid));
                }

                $html .= html_writer::end_tag('div'); // .fd
                $html .= html_writer::end_tag('div'); // .comment-area
                $html .= html_writer::tag('div', '', array('class' => 'clearer'));
            }

            $html .= html_writer::end_tag('div'); // .comment-ctrl
            $html .= html_writer::end_tag('div'); // .mdl-left
        } else {
            $html = '';
        }

        if ($return) {
            return $html;
        } else {
            echo $html;
        }
    }

    /**
     * Return matched comments
     *
     * @param  int $page
     * @return mixed
     */
    public function get_comments($page = '') {
        global $DB, $CFG, $USER, $OUTPUT;
        if (empty($this->viewcap)) {
            return false;
{'fraction_non_alphanumeric': 0.1546625949649933, 'fraction_numerical': 0.0013034410844629822, 'mean_word_length': 2.0500908677873695, 'pattern_counts': {'":': 0, '<': 93, '<?xml version=': 0, '>': 431, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '178483', 'n_tokens_mistral': 7831, 'n_tokens_neox': 7669, 'n_words': 1834}