| 1 | efrain | 1 | <?php
 | 
        
           |  |  | 2 |   | 
        
           |  |  | 3 | // This file is part of Moodle - http://moodle.org/
 | 
        
           |  |  | 4 | //
 | 
        
           |  |  | 5 | // Moodle is free software: you can redistribute it and/or modify
 | 
        
           |  |  | 6 | // it under the terms of the GNU General Public License as published by
 | 
        
           |  |  | 7 | // the Free Software Foundation, either version 3 of the License, or
 | 
        
           |  |  | 8 | // (at your option) any later version.
 | 
        
           |  |  | 9 | //
 | 
        
           |  |  | 10 | // Moodle is distributed in the hope that it will be useful,
 | 
        
           |  |  | 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
        
           |  |  | 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
        
           |  |  | 13 | // GNU General Public License for more details.
 | 
        
           |  |  | 14 | //
 | 
        
           |  |  | 15 | // You should have received a copy of the GNU General Public License
 | 
        
           |  |  | 16 | // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 | 
        
           |  |  | 17 |   | 
        
           |  |  | 18 | /**
 | 
        
           |  |  | 19 |  * comment_manager is helper class to manage moodle comments in admin page (Reports->Comments)
 | 
        
           |  |  | 20 |  *
 | 
        
           |  |  | 21 |  * @package   core_comment
 | 
        
           |  |  | 22 |  * @copyright 2010 Dongsheng Cai {@link http://dongsheng.org}
 | 
        
           |  |  | 23 |  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 24 |  */
 | 
        
           |  |  | 25 | class comment_manager {
 | 
        
           |  |  | 26 |   | 
        
           |  |  | 27 |     /** @var int The number of comments to display per page */
 | 
        
           |  |  | 28 |     private $perpage;
 | 
        
           |  |  | 29 |   | 
        
           |  |  | 30 |     /** @var stdClass Course data. */
 | 
        
           |  |  | 31 |     protected $course;
 | 
        
           |  |  | 32 |   | 
        
           |  |  | 33 |     /** @var context|bool To store the context object or false if not found. */
 | 
        
           |  |  | 34 |     protected $context;
 | 
        
           |  |  | 35 |   | 
        
           |  |  | 36 |     /** @var stdClass Course module. */
 | 
        
           |  |  | 37 |     protected $cm;
 | 
        
           |  |  | 38 |   | 
        
           |  |  | 39 |     /** @var course_modinfo Module information for course, or null if resetting. */
 | 
        
           |  |  | 40 |     protected $modinfo;
 | 
        
           |  |  | 41 |   | 
        
           |  |  | 42 |     /** @var string plugin type. */
 | 
        
           |  |  | 43 |     protected $plugintype;
 | 
        
           |  |  | 44 |   | 
        
           |  |  | 45 |     /** @var string plugin name. */
 | 
        
           |  |  | 46 |     protected $pluginname;
 | 
        
           |  |  | 47 |   | 
        
           |  |  | 48 |     /**
 | 
        
           |  |  | 49 |      * Constructs the comment_manage object
 | 
        
           |  |  | 50 |      */
 | 
        
           |  |  | 51 |     public function __construct() {
 | 
        
           |  |  | 52 |         global $CFG;
 | 
        
           |  |  | 53 |         $this->perpage = $CFG->commentsperpage;
 | 
        
           |  |  | 54 |     }
 | 
        
           |  |  | 55 |   | 
        
           |  |  | 56 |     /**
 | 
        
           |  |  | 57 |      * Return comments by pages
 | 
        
           |  |  | 58 |      *
 | 
        
           |  |  | 59 |      * @global moodle_database $DB
 | 
        
           |  |  | 60 |      * @param int $page
 | 
        
           |  |  | 61 |      * @return array An array of comments
 | 
        
           |  |  | 62 |      */
 | 
        
           |  |  | 63 |     function get_comments($page) {
 | 
        
           |  |  | 64 |         global $DB;
 | 
        
           |  |  | 65 |   | 
        
           |  |  | 66 |         if ($page == 0) {
 | 
        
           |  |  | 67 |             $start = 0;
 | 
        
           |  |  | 68 |         } else {
 | 
        
           |  |  | 69 |             $start = $page * $this->perpage;
 | 
        
           |  |  | 70 |         }
 | 
        
           |  |  | 71 |         $comments = array();
 | 
        
           |  |  | 72 |   | 
        
           |  |  | 73 |         $userfieldsapi = \core_user\fields::for_name();
 | 
        
           |  |  | 74 |         $usernamefields = $userfieldsapi->get_sql('u', false, '', '', false)->selects;
 | 
        
           |  |  | 75 |         $sql = "SELECT c.id, c.contextid, c.itemid, c.component, c.commentarea, c.userid, c.content, $usernamefields, c.timecreated
 | 
        
           |  |  | 76 |                   FROM {comments} c
 | 
        
           |  |  | 77 |                   JOIN {user} u
 | 
        
           |  |  | 78 |                        ON u.id=c.userid
 | 
        
           |  |  | 79 |               ORDER BY c.timecreated ASC";
 | 
        
           |  |  | 80 |         $rs = $DB->get_recordset_sql($sql, null, $start, $this->perpage);
 | 
        
           |  |  | 81 |         $formatoptions = array('overflowdiv' => true, 'blanktarget' => true);
 | 
        
           |  |  | 82 |         foreach ($rs as $item) {
 | 
        
           |  |  | 83 |             // Set calculated fields
 | 
        
           |  |  | 84 |             $item->fullname = fullname($item);
 | 
        
           |  |  | 85 |             $item->time = userdate($item->timecreated);
 | 
        
           |  |  | 86 |             $item->content = format_text($item->content, FORMAT_MOODLE, $formatoptions);
 | 
        
           |  |  | 87 |             // Unset fields not related to the comment
 | 
        
           |  |  | 88 |             foreach (\core_user\fields::get_name_fields() as $namefield) {
 | 
        
           |  |  | 89 |                 unset($item->$namefield);
 | 
        
           |  |  | 90 |             }
 | 
        
           |  |  | 91 |             unset($item->timecreated);
 | 
        
           |  |  | 92 |             // Record the comment
 | 
        
           |  |  | 93 |             $comments[] = $item;
 | 
        
           |  |  | 94 |         }
 | 
        
           |  |  | 95 |         $rs->close();
 | 
        
           |  |  | 96 |   | 
        
           |  |  | 97 |         return $comments;
 | 
        
           |  |  | 98 |     }
 | 
        
           |  |  | 99 |   | 
        
           |  |  | 100 |     /**
 | 
        
           |  |  | 101 |      * Records the course object
 | 
        
           |  |  | 102 |      *
 | 
        
           |  |  | 103 |      * @global moodle_page $PAGE
 | 
        
           |  |  | 104 |      * @global moodle_database $DB
 | 
        
           |  |  | 105 |      * @param int $courseid
 | 
        
           |  |  | 106 |      */
 | 
        
           |  |  | 107 |     private function setup_course($courseid) {
 | 
        
           |  |  | 108 |         global $PAGE, $DB;
 | 
        
           |  |  | 109 |         if (!empty($this->course) && $this->course->id == $courseid) {
 | 
        
           |  |  | 110 |             // already set, stop
 | 
        
           |  |  | 111 |             return;
 | 
        
           |  |  | 112 |         }
 | 
        
           |  |  | 113 |         if ($courseid == $PAGE->course->id) {
 | 
        
           |  |  | 114 |             $this->course = $PAGE->course;
 | 
        
           |  |  | 115 |         } else if (!$this->course = $DB->get_record('course', array('id' => $courseid))) {
 | 
        
           |  |  | 116 |             $this->course = null;
 | 
        
           |  |  | 117 |         }
 | 
        
           |  |  | 118 |     }
 | 
        
           |  |  | 119 |   | 
        
           |  |  | 120 |     /**
 | 
        
           |  |  | 121 |      * Sets up the module or block information for a comment
 | 
        
           |  |  | 122 |      *
 | 
        
           |  |  | 123 |      * @global moodle_database $DB
 | 
        
           |  |  | 124 |      * @param stdClass $comment
 | 
        
           |  |  | 125 |      * @return bool
 | 
        
           |  |  | 126 |      */
 | 
        
           |  |  | 127 |     private function setup_plugin($comment) {
 | 
        
           |  |  | 128 |         global $DB;
 | 
        
           |  |  | 129 |         $this->context = context::instance_by_id($comment->contextid, IGNORE_MISSING);
 | 
        
           |  |  | 130 |         if (!$this->context) {
 | 
        
           |  |  | 131 |             return false;
 | 
        
           |  |  | 132 |         }
 | 
        
           |  |  | 133 |         switch ($this->context->contextlevel) {
 | 
        
           |  |  | 134 |             case CONTEXT_BLOCK:
 | 
        
           |  |  | 135 |                 if ($block = $DB->get_record('block_instances', array('id' => $this->context->instanceid))) {
 | 
        
           |  |  | 136 |                     $this->plugintype = 'block';
 | 
        
           |  |  | 137 |                     $this->pluginname = $block->blockname;
 | 
        
           |  |  | 138 |                 } else {
 | 
        
           |  |  | 139 |                     return false;
 | 
        
           |  |  | 140 |                 }
 | 
        
           |  |  | 141 |                 break;
 | 
        
           |  |  | 142 |             case CONTEXT_MODULE:
 | 
        
           |  |  | 143 |                 $this->plugintype = 'mod';
 | 
        
           |  |  | 144 |                 $this->cm = get_coursemodule_from_id('', $this->context->instanceid);
 | 
        
           |  |  | 145 |                 $this->setup_course($this->cm->course);
 | 
        
           |  |  | 146 |                 $this->modinfo = get_fast_modinfo($this->course);
 | 
        
           |  |  | 147 |                 $this->pluginname = $this->modinfo->cms[$this->cm->id]->modname;
 | 
        
           |  |  | 148 |                 break;
 | 
        
           |  |  | 149 |         }
 | 
        
           |  |  | 150 |         return true;
 | 
        
           |  |  | 151 |     }
 | 
        
           |  |  | 152 |   | 
        
           |  |  | 153 |     /**
 | 
        
           |  |  | 154 |      * Print comments
 | 
        
           |  |  | 155 |      * @param int $page
 | 
        
           |  |  | 156 |      * @return bool return false if no comments available
 | 
        
           |  |  | 157 |      *
 | 
        
           |  |  | 158 |      * @deprecated since Moodle 4.2 - please do not use this function any more
 | 
        
           |  |  | 159 |      */
 | 
        
           |  |  | 160 |     public function print_comments($page = 0) {
 | 
        
           |  |  | 161 |         global $OUTPUT, $CFG, $OUTPUT, $DB;
 | 
        
           |  |  | 162 |   | 
        
           |  |  | 163 |         debugging('The function ' . __FUNCTION__ . '() is deprecated, please do not use it any more. ' .
 | 
        
           |  |  | 164 |             'See \'comments\' system report class for replacement', DEBUG_DEVELOPER);
 | 
        
           |  |  | 165 |   | 
        
           |  |  | 166 |         $count = $DB->count_records('comments');
 | 
        
           |  |  | 167 |         $comments = $this->get_comments($page);
 | 
        
           |  |  | 168 |         if (count($comments) == 0) {
 | 
        
           |  |  | 169 |             echo $OUTPUT->notification(get_string('nocomments', 'moodle'));
 | 
        
           |  |  | 170 |             return false;
 | 
        
           |  |  | 171 |         }
 | 
        
           |  |  | 172 |   | 
        
           |  |  | 173 |         $table = new html_table();
 | 
        
           |  |  | 174 |         $table->head = array (
 | 
        
           |  |  | 175 |             html_writer::checkbox('selectall', '', false, get_string('selectall'), array('id' => 'comment_select_all',
 | 
        
           |  |  | 176 |                 'class' => 'mr-1')),
 | 
        
           |  |  | 177 |             get_string('author', 'search'),
 | 
        
           |  |  | 178 |             get_string('content'),
 | 
        
           |  |  | 179 |             get_string('action')
 | 
        
           |  |  | 180 |         );
 | 
        
           |  |  | 181 |         $table->colclasses = array ('leftalign', 'leftalign', 'leftalign', 'leftalign');
 | 
        
           |  |  | 182 |         $table->attributes = array('class'=>'admintable generaltable');
 | 
        
           |  |  | 183 |         $table->id = 'commentstable';
 | 
        
           |  |  | 184 |         $table->data = array();
 | 
        
           |  |  | 185 |   | 
        
           |  |  | 186 |         $link = new moodle_url('/comment/index.php', array('action' => 'delete', 'sesskey' => sesskey()));
 | 
        
           |  |  | 187 |         foreach ($comments as $c) {
 | 
        
           |  |  | 188 |             $userdata = html_writer::link(new moodle_url('/user/profile.php', ['id' => $c->userid]), $c->fullname);
 | 
        
           |  |  | 189 |             $this->setup_plugin($c);
 | 
        
           |  |  | 190 |             if (!empty($this->plugintype)) {
 | 
        
           |  |  | 191 |                 $context_url = plugin_callback($this->plugintype, $this->pluginname, 'comment', 'url', array($c));
 | 
        
           |  |  | 192 |             }
 | 
        
           |  |  | 193 |             $checkbox = html_writer::checkbox('comments', $c->id, false);
 | 
        
           |  |  | 194 |             $action = html_writer::link(new moodle_url($link, array('commentid' => $c->id)), get_string('delete'));
 | 
        
           |  |  | 195 |             if (!empty($context_url)) {
 | 
        
           |  |  | 196 |                 $action .= html_writer::empty_tag('br');
 | 
        
           |  |  | 197 |                 $action .= html_writer::link($context_url, get_string('commentincontext'), array('target'=>'_blank'));
 | 
        
           |  |  | 198 |             }
 | 
        
           |  |  | 199 |             $table->data[] = array($checkbox, $userdata, $c->content, $action);
 | 
        
           |  |  | 200 |         }
 | 
        
           |  |  | 201 |         echo html_writer::table($table);
 | 
        
           |  |  | 202 |         echo $OUTPUT->paging_bar($count, $page, $this->perpage, $CFG->wwwroot.'/comment/index.php');
 | 
        
           |  |  | 203 |         return true;
 | 
        
           |  |  | 204 |     }
 | 
        
           |  |  | 205 |   | 
        
           |  |  | 206 |     /**
 | 
        
           |  |  | 207 |      * Delete a comment
 | 
        
           |  |  | 208 |      *
 | 
        
           |  |  | 209 |      * @param int $commentid
 | 
        
           |  |  | 210 |      * @return bool
 | 
        
           |  |  | 211 |      */
 | 
        
           |  |  | 212 |     public function delete_comment($commentid) {
 | 
        
           |  |  | 213 |         global $DB;
 | 
        
           |  |  | 214 |         if ($DB->record_exists('comments', array('id' => $commentid))) {
 | 
        
           |  |  | 215 |             $DB->delete_records('comments', array('id' => $commentid));
 | 
        
           |  |  | 216 |             return true;
 | 
        
           |  |  | 217 |         }
 | 
        
           |  |  | 218 |         return false;
 | 
        
           |  |  | 219 |     }
 | 
        
           |  |  | 220 |     /**
 | 
        
           |  |  | 221 |      * Delete comments
 | 
        
           |  |  | 222 |      *
 | 
        
           |  |  | 223 |      * @param string $list A list of comment ids separated by hyphens
 | 
        
           |  |  | 224 |      * @return bool
 | 
        
           |  |  | 225 |      */
 | 
        
           |  |  | 226 |     public function delete_comments($list) {
 | 
        
           |  |  | 227 |         global $DB;
 | 
        
           |  |  | 228 |         $ids = explode('-', $list);
 | 
        
           |  |  | 229 |         foreach ($ids as $id) {
 | 
        
           |  |  | 230 |             $id = (int)$id;
 | 
        
           |  |  | 231 |             if ($DB->record_exists('comments', array('id' => $id))) {
 | 
        
           |  |  | 232 |                 $DB->delete_records('comments', array('id' => $id));
 | 
        
           |  |  | 233 |             }
 | 
        
           |  |  | 234 |         }
 | 
        
           |  |  | 235 |         return true;
 | 
        
           |  |  | 236 |     }
 | 
        
           |  |  | 237 |   | 
        
           |  |  | 238 |     /**
 | 
        
           |  |  | 239 |      * Get comments created since a given time.
 | 
        
           |  |  | 240 |      *
 | 
        
           |  |  | 241 |      * @param  stdClass $course    course object
 | 
        
           |  |  | 242 |      * @param  stdClass $context   context object
 | 
        
           |  |  | 243 |      * @param  string $component   component name
 | 
        
           |  |  | 244 |      * @param  int $since          the time to check
 | 
        
           |  |  | 245 |      * @param  stdClass|\cm_info|null $cm course module object
 | 
        
           |  |  | 246 |      * @return array list of comments db records since the given timelimit
 | 
        
           |  |  | 247 |      * @since Moodle 3.2
 | 
        
           |  |  | 248 |      */
 | 
        
           |  |  | 249 |     public function get_component_comments_since($course, $context, $component, $since, $cm = null) {
 | 
        
           |  |  | 250 |         global $DB;
 | 
        
           |  |  | 251 |   | 
        
           |  |  | 252 |         $commentssince = array();
 | 
        
           |  |  | 253 |         $where = 'contextid = ? AND component = ? AND timecreated > ?';
 | 
        
           |  |  | 254 |         $comments = $DB->get_records_select('comments', $where, array($context->id, $component, $since));
 | 
        
           |  |  | 255 |         // Check item by item if we have permissions.
 | 
        
           |  |  | 256 |         $managersviewstatus = array();
 | 
        
           |  |  | 257 |         foreach ($comments as $comment) {
 | 
        
           |  |  | 258 |             // Check if the manager for the item is cached.
 | 
        
           |  |  | 259 |             if (!isset($managersviewstatus[$comment->commentarea]) or
 | 
        
           |  |  | 260 |                     !isset($managersviewstatus[$comment->commentarea][$comment->itemid])) {
 | 
        
           |  |  | 261 |   | 
        
           |  |  | 262 |                 $args = new stdClass;
 | 
        
           |  |  | 263 |                 $args->area      = $comment->commentarea;
 | 
        
           |  |  | 264 |                 $args->itemid    = $comment->itemid;
 | 
        
           |  |  | 265 |                 $args->context   = $context;
 | 
        
           |  |  | 266 |                 $args->course    = $course;
 | 
        
           |  |  | 267 |                 $args->client_id = 0;
 | 
        
           |  |  | 268 |                 $args->component = $component;
 | 
        
           |  |  | 269 |                 if (!empty($cm)) {
 | 
        
           |  |  | 270 |                     $args->cm = $cm;
 | 
        
           |  |  | 271 |                 }
 | 
        
           |  |  | 272 |   | 
        
           |  |  | 273 |                 $manager = new comment($args);
 | 
        
           |  |  | 274 |                 $managersviewstatus[$comment->commentarea][$comment->itemid] = $manager->can_view();
 | 
        
           |  |  | 275 |             }
 | 
        
           |  |  | 276 |   | 
        
           |  |  | 277 |             if ($managersviewstatus[$comment->commentarea][$comment->itemid]) {
 | 
        
           |  |  | 278 |                 $commentssince[$comment->id] = $comment;
 | 
        
           |  |  | 279 |             }
 | 
        
           |  |  | 280 |         }
 | 
        
           |  |  | 281 |         return $commentssince;
 | 
        
           |  |  | 282 |     }
 | 
        
           |  |  | 283 | }
 |