diff --git a/blocks/comments/block_comments.php b/blocks/comments/block_comments.php index 25d3e9a26a7..21aea13d6fb 100644 --- a/blocks/comments/block_comments.php +++ b/blocks/comments/block_comments.php @@ -1,6 +1,6 @@ libdir . '/commentlib.php'); +require_once($CFG->dirroot . '/comment/lib.php'); class block_comments extends block_base { @@ -11,7 +11,7 @@ class block_comments extends block_base { function specialization() { // require js for commenting - comment::js(); + comment::init(); } function applicable_formats() { return array('all' => true); diff --git a/blog/index.php b/blog/index.php index 3dd54a01b29..2a42025122c 100755 --- a/blog/index.php +++ b/blog/index.php @@ -11,7 +11,7 @@ require_once($CFG->dirroot .'/blog/lib.php'); require_once($CFG->dirroot .'/blog/locallib.php'); require_once($CFG->dirroot .'/course/lib.php'); require_once($CFG->dirroot .'/tag/lib.php'); -require_once($CFG->libdir .'/commentlib.php'); +require_once($CFG->dirroot .'/comment/lib.php'); $id = optional_param('id', null, PARAM_INT); $start = optional_param('formstart', 0, PARAM_INT); @@ -24,7 +24,7 @@ $groupid = optional_param('groupid', null, PARAM_INT); $courseid = optional_param('courseid', null, PARAM_INT); $search = optional_param('search', null, PARAM_RAW); -comment::js(); +comment::init(); $url_params = compact('id', 'start', 'tag', 'userid', 'tagid', 'modid', 'entryid', 'groupid', 'courseid', 'search'); foreach ($url_params as $var => $val) { diff --git a/comment/comment_ajax.php b/comment/comment_ajax.php index b904befbd45..c6827166c6a 100644 --- a/comment/comment_ajax.php +++ b/comment/comment_ajax.php @@ -19,7 +19,7 @@ * Handling all ajax request for comments API */ require_once('../config.php'); -require_once($CFG->libdir.'/commentlib.php'); +require_once($CFG->dirroot . '/comment/lib.php'); $courseid = optional_param('courseid', SITEID, PARAM_INT); $contextid = optional_param('contextid', SYSCONTEXTID, PARAM_INT); diff --git a/comment/comment_post.php b/comment/comment_post.php index f4d7e0cf636..1b90d0160aa 100644 --- a/comment/comment_post.php +++ b/comment/comment_post.php @@ -19,7 +19,7 @@ * Handling all ajax request for comments API */ require_once('../config.php'); -require_once($CFG->libdir.'/commentlib.php'); +require_once($CFG->libdir.'/comment/lib.php'); $courseid = optional_param('courseid', SITEID, PARAM_INT); $contextid = optional_param('contextid', SYSCONTEXTID, PARAM_INT); diff --git a/comment/index.php b/comment/index.php index c4cd28a10df..c2f6221f765 100644 --- a/comment/index.php +++ b/comment/index.php @@ -20,7 +20,7 @@ */ require_once('../config.php'); require_once($CFG->libdir.'/adminlib.php'); -require_once('lib.php'); +require_once('locallib.php'); require_login(); admin_externalpage_setup('comments'); diff --git a/comment/lib.php b/comment/lib.php index 85e71608f7b..d4159256774 100644 --- a/comment/lib.php +++ b/comment/lib.php @@ -1,45 +1,185 @@ . + /** - * comment_manager is class to manage moodle comments + * Comment is helper class to add/delete comments anywhere in moodle * - * @package moodlecore - * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} + * @package comment + * @copyright 2010 Dongsheng Cai * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class comment_manager { + +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; /** - * Return comments by pages - * @param int $page - * @return mixed + * this html snippet will be used as a template + * to build comment content + * @var string */ - function get_comments($page) { - global $DB, $CFG, $USER; - $params = array(); - if ($page == 0) { - $start = 0; + private $template; + private $context; + private $course; + /** + * course module object + * @var string + */ + private $cm; + private $plugintype; + 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; + private static $nonjs = false; + // will be used by non-js comments UI + private static $comment_itemid = null; + private static $comment_context = null; + private static $comment_area = null; + /** + * Construct function of comment class, initilize + * class members + * @param object $options + */ + public function __construct($options) { + global $CFG, $DB; + $this->viewcap = false; + $this->postcap = false; + if (!empty($options->client_id)) { + $this->cid = $options->client_id; } else { - $start = $page*$this->perpage; + $this->cid = uniqid(); + } + 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->area)) { + $this->commentarea = $options->area; + } + if (!empty($options->itemid)) { + $this->itemid = $options->itemid; + } + if (!empty($options->env)) { + $this->env = $options->env; + } else { + $this->env = ''; } - $sql = "SELECT c.id, c.contextid, c.itemid, c.commentarea, c.userid, c.content, u.username, u.firstname, u.lastname, c.timecreated - FROM {comments} c, {user} u - WHERE u.id=c.userid ORDER BY c.timecreated ASC"; - $comments = array(); - if ($records = $DB->get_records_sql($sql, array(), $start, $this->perpage)) { - foreach ($records as $item) { - $item->username = fullname($item); - $item->time = userdate($item->timecreated); - $item->content = format_text($item->content); - $comments[] = $item; - unset($item->firstname); - unset($item->lastname); - unset($item->timecreated); + if (!empty($options->linktext)) { + $this->linktext = $options->linktext; + } else { + $this->linktext = get_string('comments'); + } + + $this->_setup_plugin(); + + $this->options = new stdclass; + $this->options->context = $this->context; + $this->options->commentarea = $this->commentarea; + $this->options->itemid = $this->itemid; + + // load template + $this->template = <<___picture___ +
+ ___name___ - ___time___ +
___content___
+
+EOD; + if (!empty($this->plugintype)) { + $this->template = plugin_callback($this->plugintype, $this->pluginname, FEATURE_COMMENT, 'template', $this->options, $this->template); + } + + // setting post and view permissions + $this->_check_permissions(); + + // setup course + if (!empty($options->course)) { + $this->course = $options->course; + } else if (!empty($options->courseid)) { + $courseid = $options->courseid; + $this->_setup_course($courseid); + } else { + $courseid = SITEID; + $this->_setup_course($courseid); + } + if (!empty($options->showcount)) { + $count = $this->count(); + if (empty($count)) { + $this->count = ''; + } else { + $this->count = '('.$count.')'; } + } else { + $this->count = ''; } - return $comments; + 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_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'); } private function _setup_course($courseid) { @@ -55,9 +195,22 @@ class comment_manager { } } - private function _setup_plugin($comment) { + /** + * Setting module info + * + */ + private function _setup_plugin() { global $DB; - $this->context = get_context_instance_by_id($comment->contextid); + // blog needs to set env as "blog" + if ($this->env == 'blog') { + $this->plugintype = 'moodle'; + $this->pluginname = 'blog'; + } + // tag page needs to set env as "tag" + if ($this->env == 'tag') { + $this->plugintype = 'moodle'; + $this->pluginname = 'tag'; + } if ($this->context->contextlevel == CONTEXT_BLOCK) { if ($block = $DB->get_record('block_instances', array('id'=>$this->context->instanceid))) { $this->plugintype = 'block'; @@ -74,62 +227,345 @@ class comment_manager { } /** - * Print comments - * @param int $page + * 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 */ - function print_comments($page=0) { - global $CFG, $OUTPUT, $DB; - $this->perpage = 10; - $count = $DB->count_records_sql('SELECT COUNT(*) FROM {comments} c'); - $comments = $this->get_comments($page); - $table = new html_table(); - $table->head = array ('', 'author', 'content', 'action'); - $table->align = array ('left', 'left', 'left', 'left'); - $table->width = "95%"; - $table->data = array(); - foreach ($comments as $c) { - $this->_setup_plugin($c); - if (!empty($this->plugintype)) { - $url = plugin_callback($this->plugintype, $this->pluginname, FEATURE_COMMENT, 'url', array($c)); - } - $checkbox = ''; - $action = ''; - $action .= "".get_string('delete').''; - $action .= "
"; - if (!empty($url)) { - $action .= "".get_string('commentincontext').''; - } - $table->data[] = array($checkbox, $c->username, $c->content, $action); + 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', $this->options, array('post'=>true, 'view'=>true)); + $this->postcap = $this->postcap && $permissions['post']; + $this->viewcap = $this->viewcap && $permissions['view']; } - echo $OUTPUT->table($table); - echo $OUTPUT->paging_bar($count, $page, $this->perpage, $CFG->wwwroot.'/comment/index.php'); } /** - * delete a comment - * @param int $commentid + * Prepare comment code in html + * @param boolean $return + * @return mixed */ - public function delete_comment($commentid) { - global $DB; - if ($comment = $DB->get_record('comments', array('id'=>$commentid))) { - return $DB->delete_records('comments', array('id'=>$commentid)); + public function output($return = true) { + global $CFG, $COURSE, $PAGE; + + + $this->link = qualified_me(); + $murl = new moodle_url($this->link); + $murl->remove_params('nonjscomment'); + $murl->param('nonjscomment', 'true'); + $murl->param('comment_itemid', $this->options->itemid); + $murl->param('comment_context', $this->options->context->id); + $murl->param('comment_area', $this->options->commentarea); + $murl->remove_params('page'); + $this->link = $murl->out(); + $options = new stdclass; + $options->client_id = $this->cid; + $options->commentarea = $this->commentarea; + $options->itemid = $this->itemid; + $options->page = 0; + $options->courseid = $this->course->id; + $options->contextid = $this->contextid; + if ($this->env == 'block_comments') { + $options->autostart = true; + $options->notoggle = true; + } + + $PAGE->requires->js_init_call('M.core_comment.init', array($options), true); + + if (!empty(self::$nonjs)) { + return $this->print_comments($this->page, $return); + } + $strsubmit = get_string('submit'); + $strcancel = get_string('cancel'); + $sesskey = sesskey(); + + // print html template + if (empty($CFG->commentcommentcode) && !empty($this->viewcap)) { + echo ''; + $CFG->commentcommentcode = true; + } + + if (!empty($this->viewcap)) { + // print commenting icon and tooltip + $html = << + +{$this->linktext} +{$this->linktext} {$this->count} + +
+
    +
+
+EOD; + + // print posting textarea + if (!empty($this->postcap)) { + $html .= << +
+ +
+
+ {$strsubmit} +EOD; + if ($this->env != 'block_comments') { + $html .= << | + {$strcancel} +EOD; + } + + $html .= << +
+
+EOD; + } + + $html .= << +
+EOD; + } else { + $html = ''; + } + + if ($return) { + return $html; + } else { + echo $html; } - return false; } + /** - * delete comments - * @param int $commentid + * Return matched comments + * @param int $page + * @return mixed */ - public function delete_comments($list) { - global $DB; - $ids = explode('-', $list); - foreach ($ids as $id) { - if (is_int((int)$id)) { - if ($comment = $DB->get_record('comments', array('id'=>$id))) { - $DB->delete_records('comments', array('id'=>$comment->id)); + public function get_comments($page = '') { + global $DB, $CFG, $USER, $OUTPUT; + if (empty($this->viewcap)) { + return false; + } + $CFG->commentsperpage = 15; + if (!is_numeric($page)) { + $page = 0; + } + $this->page = $page; + $params = array(); + $start = $page * $CFG->commentsperpage; + $sql = "SELECT c.id, c.userid, c.content, c.format, c.timecreated, u.picture, u.imagealt, u.username, u.firstname, u.lastname + FROM {comments} c, {user} u WHERE u.id=c.userid AND c.contextid=? AND c.commentarea=? AND c.itemid=? + ORDER BY c.timecreated DESC"; + $params[] = $this->contextid; + $params[] = $this->commentarea; + $params[] = $this->itemid; + + $comments = array(); + $candelete = has_capability('moodle/comment:delete', $this->context); + if ($records = $DB->get_records_sql($sql, $params, $start, $CFG->commentsperpage)) { + foreach ($records as &$c) { + $url = $CFG->httpswwwroot.'/user/view.php?id='.$c->userid.'&course='.$this->course->id; + $c->username = ''.fullname($c).''; + $c->time = userdate($c->timecreated, get_string('strftimerecent', 'langconfig')); + $user = new stdclass; + $user->id = $c->userid; + $user->picture = $c->picture; + $user->firstname = $c->firstname; + $user->lastname = $c->lastname; + $user->imagealt = $c->imagealt; + $c->content = format_text($c->content, $c->format); + $c->avatar = $OUTPUT->user_picture($user, array('size'=>18)); + if (($USER->id == $c->userid) || !empty($candelete)) { + $c->delete = true; } + $comments[] = $c; } } - return true; + + if (!empty($this->plugintype)) { + // moodle module will filter comments + plugin_callback($this->plugintype, $this->pluginname, FEATURE_COMMENT, 'display', array(&$comments, $this->options)); + } + + return $comments; + } + + public function count() { + global $DB; + if ($count = $DB->count_records('comments', array('itemid'=>$this->itemid, 'commentarea'=>$this->commentarea, 'contextid'=>$this->context->id))) { + return $count; + } else { + return 0; + } + } + + public function get_pagination($page = 0) { + global $DB, $CFG, $OUTPUT; + $count = $this->count(); + $pages = (int)ceil($count/$CFG->commentsperpage); + if ($pages == 1 || $pages == 0) { + return ''; + } + if (!empty(self::$nonjs)) { + // used in non-js interface + return $OUTPUT->paging_bar($count, $page, $CFG->commentsperpage, $this->link); + } else { + // return ajax paging bar + $str = ''; + $str .= '
'; + for ($p=0; $p<$pages; $p++) { + $extra = ''; + if ($p == $page) { + $extra = ' style="border:1px solid grey" '; + } + $str .= ''.($p+1).' '; + } + $str .= '
'; + } + return $str; + } + + /** + * Add a new comment + * @param string $content + * @return mixed + */ + public function add($content, $format = FORMAT_MOODLE) { + global $CFG, $DB, $USER, $OUTPUT; + if (empty($this->postcap)) { + throw new comment_exception('nopermissiontocomment'); + } + $now = time(); + $newcmt = new stdclass; + $newcmt->contextid = $this->contextid; + $newcmt->commentarea = $this->commentarea; + $newcmt->itemid = $this->itemid; + $newcmt->content = $content; + $newcmt->format = $format; + $newcmt->userid = $USER->id; + $newcmt->timecreated = $now; + + if (!empty($this->plugintype)) { + // moodle module will check content + $ret = plugin_callback($this->plugintype, $this->pluginname, FEATURE_COMMENT, 'add', array(&$newcmt, $this->options), true); + if (!$ret) { + throw new comment_exception('modulererejectcomment'); + } + } + + $cmt_id = $DB->insert_record('comments', $newcmt); + if (!empty($cmt_id)) { + $newcmt->id = $cmt_id; + $newcmt->time = userdate($now, get_string('strftimerecent', 'langconfig')); + $newcmt->username = fullname($USER); + $newcmt->content = format_text($newcmt->content); + $newcmt->avatar = $OUTPUT->user_picture($USER, array('size'=>16)); + return $newcmt; + } else { + throw new comment_exception('dbupdatefailed'); + } + } + + /** + * delete by context, commentarea and itemid + * + */ + public function delete_comments() { + global $DB; + return $DB->delete_records('comments', array( + 'contextid'=>$this->context->id, + 'commentarea'=>$this->commentarea, + 'itemid'=>$this->itemid) + ); + } + + /** + * Delete a comment + * @param int $commentid + * @return mixed + */ + public function delete($commentid) { + global $DB, $USER; + $candelete = has_capability('moodle/comment:delete', $this->context); + if (!$comment = $DB->get_record('comments', array('id'=>$commentid))) { + throw new comment_exception('dbupdatefailed'); + } + if (!($USER->id == $comment->userid || !empty($candelete))) { + throw new comment_exception('nopermissiontocomment'); + } + return $DB->delete_records('comments', array('id'=>$commentid)); + } + + public function print_comments($page = 0, $return = true) { + global $DB, $CFG; + $html = ''; + if (!(self::$comment_itemid == $this->options->itemid && + self::$comment_context == $this->options->context->id && + self::$comment_area == $this->options->commentarea)) { + $page = 0; + } + $comments = $this->get_comments($page); + + $html .= '

'.get_string('comments').'

'; + $html .= "
    "; + $results = array(); + $list = ''; + foreach ($comments as $cmt) { + $list = $this->print_comment($cmt, $this->contextid, $this->commentarea, $this->itemid) . $list; + } + $html .= $list; + $html .= '
'; + $html .= $this->get_pagination($page); + $sesskey = sesskey(); + $returnurl = qualified_me(); + $strsubmit = get_string('submit'); + $html .= << + + + + + + + + + + +EOD; + if ($return) { + return $html; + } else { + echo $html; + } + } + + public function print_comment($cmt) { + $patterns = array(); + $replacements = array(); + + $patterns[] = '___picture___'; + $patterns[] = '___name___'; + $patterns[] = '___content___'; + $patterns[] = '___time___'; + $replacements[] = $cmt->avatar; + $replacements[] = fullname($cmt); + $replacements[] = $cmt->content; + $replacements[] = userdate($cmt->timecreated, get_string('strftimerecent', 'langconfig')); + + // use html template to format a single comment. + return str_replace($patterns, $replacements, $this->template); + } +} + +class comment_exception extends moodle_exception { + public $message; + function __construct($errorcode) { + $this->errorcode = $errorcode; + $this->message = get_string($errorcode, 'error'); } } diff --git a/comment/locallib.php b/comment/locallib.php new file mode 100644 index 00000000000..4842c58c5d7 --- /dev/null +++ b/comment/locallib.php @@ -0,0 +1,137 @@ +Comments) + * + * @package comment + * @copyright 2010 Dongsheng Cai + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class comment_manager { + + /** + * Return comments by pages + * @param int $page + * @return mixed + */ + function get_comments($page) { + global $DB, $CFG, $USER; + $params = array(); + if ($page == 0) { + $start = 0; + } else { + $start = $page*$this->perpage; + } + $sql = "SELECT c.id, c.contextid, c.itemid, c.commentarea, c.userid, c.content, u.username, u.firstname, u.lastname, c.timecreated + FROM {comments} c, {user} u + WHERE u.id=c.userid ORDER BY c.timecreated ASC"; + + $comments = array(); + if ($records = $DB->get_records_sql($sql, array(), $start, $this->perpage)) { + foreach ($records as $item) { + $item->username = fullname($item); + $item->time = userdate($item->timecreated); + $item->content = format_text($item->content); + $comments[] = $item; + unset($item->firstname); + unset($item->lastname); + unset($item->timecreated); + } + } + + return $comments; + } + + private function _setup_course($courseid) { + global $COURSE, $DB; + if (!empty($this->course)) { + // already set, stop + return; + } + if ($courseid == $COURSE->id) { + $this->course = $COURSE; + } else if (!$this->course = $DB->get_record('course', array('id'=>$courseid))) { + $this->course = null; + } + } + + private function _setup_plugin($comment) { + global $DB; + $this->context = get_context_instance_by_id($comment->contextid); + if (!is_object($this->context)) { + return; + } + if ($this->context->contextlevel == CONTEXT_BLOCK) { + if ($block = $DB->get_record('block_instances', array('id'=>$this->context->instanceid))) { + $this->plugintype = 'block'; + $this->pluginname = $block->blockname; + } + } + if ($this->context->contextlevel == CONTEXT_MODULE) { + $this->plugintype = 'mod'; + $this->cm = get_coursemodule_from_id('', $this->context->instanceid); + $this->_setup_course($this->cm->course); + $this->modinfo = get_fast_modinfo($this->course); + $this->pluginname = $this->modinfo->cms[$this->cm->id]->modname; + } + } + + /** + * Print comments + * @param int $page + */ + function print_comments($page=0) { + global $CFG, $OUTPUT, $DB; + $this->perpage = 10; + $count = $DB->count_records_sql('SELECT COUNT(*) FROM {comments} c'); + $comments = $this->get_comments($page); + $table = new html_table(); + $table->head = array ('', 'author', 'content', 'action'); + $table->align = array ('left', 'left', 'left', 'left'); + $table->width = "95%"; + $table->data = array(); + foreach ($comments as $c) { + $this->_setup_plugin($c); + if (!empty($this->plugintype)) { + $url = plugin_callback($this->plugintype, $this->pluginname, FEATURE_COMMENT, 'url', array($c)); + } + $checkbox = ''; + $action = ''; + $action .= "".get_string('delete').''; + $action .= "
"; + if (!empty($url)) { + $action .= "".get_string('commentincontext').''; + } + $table->data[] = array($checkbox, $c->username, $c->content, $action); + } + echo $OUTPUT->table($table); + echo $OUTPUT->paging_bar($count, $page, $this->perpage, $CFG->wwwroot.'/comment/index.php'); + } + + /** + * delete a comment + * @param int $commentid + */ + public function delete_comment($commentid) { + global $DB; + if ($comment = $DB->get_record('comments', array('id'=>$commentid))) { + return $DB->delete_records('comments', array('id'=>$commentid)); + } + return false; + } + /** + * delete comments + * @param int $commentid + */ + public function delete_comments($list) { + global $DB; + $ids = explode('-', $list); + foreach ($ids as $id) { + if (is_int((int)$id)) { + if ($comment = $DB->get_record('comments', array('id'=>$id))) { + $DB->delete_records('comments', array('id'=>$comment->id)); + } + } + } + return true; + } +} diff --git a/lib/commentlib.php b/lib/commentlib.php index 4c921aa573f..e69de29bb2d 100644 --- a/lib/commentlib.php +++ b/lib/commentlib.php @@ -1,572 +0,0 @@ -. - -/** - * comment is class to process moodle comments - * - * @package moodlecore - * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} - * @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 $course; - /** - * course module object - * @var string - */ - private $cm; - private $plugintype; - 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; - private static $nonjs = false; - // will be used by non-js comments UI - private static $comment_itemid = null; - private static $comment_context = null; - private static $comment_area = null; - /** - * Construct function of comment class, initilize - * class members - * @param object $options - */ - public function __construct($options) { - global $CFG, $DB; - $this->viewcap = false; - $this->postcap = false; - if (!empty($options->client_id)) { - $this->cid = $options->client_id; - } else { - $this->cid = uniqid(); - } - 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->area)) { - $this->commentarea = $options->area; - } - if (!empty($options->itemid)) { - $this->itemid = $options->itemid; - } - if (!empty($options->env)) { - $this->env = $options->env; - } else { - $this->env = ''; - } - - if (!empty($options->linktext)) { - $this->linktext = $options->linktext; - } else { - $this->linktext = get_string('comments'); - } - - $this->_setup_plugin(); - - $this->options = new stdclass; - $this->options->context = $this->context; - $this->options->commentarea = $this->commentarea; - $this->options->itemid = $this->itemid; - - // load template - $this->template = <<___picture___ -
- ___name___ - ___time___ -
___content___
-
-EOD; - if (!empty($this->plugintype)) { - $this->template = plugin_callback($this->plugintype, $this->pluginname, FEATURE_COMMENT, 'template', $this->options, $this->template); - } - - // setting post and view permissions - $this->_check_permissions(); - - // setup course - if (!empty($options->course)) { - $this->course = $options->course; - } else if (!empty($options->courseid)) { - $courseid = $options->courseid; - $this->_setup_course($courseid); - } else { - $courseid = SITEID; - $this->_setup_course($courseid); - } - if (!empty($options->showcount)) { - $count = $this->count(); - if (empty($count)) { - $this->count = ''; - } else { - $this->count = '('.$count.')'; - } - } else { - $this->count = ''; - } - - unset($options); - } - - /** - * Print required YUI libraries, must be called before html head printed - * @return boolean - */ - public static function js() { - 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_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'); - } - - private function _setup_course($courseid) { - global $COURSE, $DB; - if (!empty($this->course)) { - // already set, stop - return; - } - if ($courseid == $COURSE->id) { - $this->course = $COURSE; - } else if (!$this->course = $DB->get_record('course', array('id'=>$courseid))) { - $this->course = null; - } - } - - /** - * Setting module info - * - */ - private function _setup_plugin() { - global $DB; - // blog needs to set env as "blog" - if ($this->env == 'blog') { - $this->plugintype = 'moodle'; - $this->pluginname = 'blog'; - } - // tag page needs to set env as "tag" - if ($this->env == 'tag') { - $this->plugintype = 'moodle'; - $this->pluginname = 'tag'; - } - if ($this->context->contextlevel == CONTEXT_BLOCK) { - if ($block = $DB->get_record('block_instances', array('id'=>$this->context->instanceid))) { - $this->plugintype = 'block'; - $this->pluginname = $block->blockname; - } - } - if ($this->context->contextlevel == CONTEXT_MODULE) { - $this->plugintype = 'mod'; - $this->cm = get_coursemodule_from_id('', $this->context->instanceid); - $this->_setup_course($this->cm->course); - $this->modinfo = get_fast_modinfo($this->course); - $this->pluginname = $this->modinfo->cms[$this->cm->id]->modname; - } - } - - /** - * 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', $this->options, array('post'=>true, 'view'=>true)); - $this->postcap = $this->postcap && $permissions['post']; - $this->viewcap = $this->viewcap && $permissions['view']; - } - } - - /** - * Prepare comment code in html - * @param boolean $return - * @return mixed - */ - public function init($return = true) { - global $CFG, $COURSE, $PAGE; - - - $this->link = qualified_me(); - $murl = new moodle_url($this->link); - $murl->remove_params('nonjscomment'); - $murl->param('nonjscomment', 'true'); - $murl->param('comment_itemid', $this->options->itemid); - $murl->param('comment_context', $this->options->context->id); - $murl->param('comment_area', $this->options->commentarea); - $murl->remove_params('page'); - $this->link = $murl->out(); - $options = new stdclass; - $options->client_id = $this->cid; - $options->commentarea = $this->commentarea; - $options->itemid = $this->itemid; - $options->page = 0; - $options->courseid = $this->course->id; - $options->contextid = $this->contextid; - if ($this->env == 'block_comments') { - $options->autostart = true; - $options->notoggle = true; - } - - $PAGE->requires->js_init_call('M.core_comment.init', array($options), true); - - if (!empty(self::$nonjs)) { - return $this->print_comments($this->page, $return); - } - $strsubmit = get_string('submit'); - $strcancel = get_string('cancel'); - $sesskey = sesskey(); - - // print html template - if (empty($CFG->commentcommentcode) && !empty($this->viewcap)) { - echo ''; - $CFG->commentcommentcode = true; - } - - if (!empty($this->viewcap)) { - // print commenting icon and tooltip - $html = << - -{$this->linktext} -{$this->linktext} {$this->count} - -
-
    -
-
-EOD; - - // print posting textarea - if (!empty($this->postcap)) { - $html .= << -
- -
-
- {$strsubmit} -EOD; - if ($this->env != 'block_comments') { - $html .= << | - {$strcancel} -EOD; - } - - $html .= << -
-
-EOD; - } - - $html .= << -
-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; - } - $CFG->commentsperpage = 15; - if (!is_numeric($page)) { - $page = 0; - } - $this->page = $page; - $params = array(); - $start = $page * $CFG->commentsperpage; - $sql = "SELECT c.id, c.userid, c.content, c.format, c.timecreated, u.picture, u.imagealt, u.username, u.firstname, u.lastname - FROM {comments} c, {user} u WHERE u.id=c.userid AND c.contextid=? AND c.commentarea=? AND c.itemid=? - ORDER BY c.timecreated DESC"; - $params[] = $this->contextid; - $params[] = $this->commentarea; - $params[] = $this->itemid; - - $comments = array(); - $candelete = has_capability('moodle/comment:delete', $this->context); - if ($records = $DB->get_records_sql($sql, $params, $start, $CFG->commentsperpage)) { - foreach ($records as &$c) { - $url = $CFG->httpswwwroot.'/user/view.php?id='.$c->userid.'&course='.$this->course->id; - $c->username = ''.fullname($c).''; - $c->time = userdate($c->timecreated, get_string('strftimerecent', 'langconfig')); - $user = new stdclass; - $user->id = $c->userid; - $user->picture = $c->picture; - $user->firstname = $c->firstname; - $user->lastname = $c->lastname; - $user->imagealt = $c->imagealt; - $c->content = format_text($c->content, $c->format); - $c->avatar = $OUTPUT->user_picture($user, array('size'=>18)); - if (($USER->id == $c->userid) || !empty($candelete)) { - $c->delete = true; - } - $comments[] = $c; - } - } - - if (!empty($this->plugintype)) { - // moodle module will filter comments - plugin_callback($this->plugintype, $this->pluginname, FEATURE_COMMENT, 'display', array(&$comments, $this->options)); - } - - return $comments; - } - - public function count() { - global $DB; - if ($count = $DB->count_records('comments', array('itemid'=>$this->itemid, 'commentarea'=>$this->commentarea, 'contextid'=>$this->context->id))) { - return $count; - } else { - return 0; - } - } - - public function get_pagination($page = 0) { - global $DB, $CFG, $OUTPUT; - $count = $this->count(); - $pages = (int)ceil($count/$CFG->commentsperpage); - if ($pages == 1 || $pages == 0) { - return ''; - } - if (!empty(self::$nonjs)) { - // used in non-js interface - return $OUTPUT->paging_bar($count, $page, $CFG->commentsperpage, $this->link); - } else { - // return ajax paging bar - $str = ''; - $str .= '
'; - for ($p=0; $p<$pages; $p++) { - $extra = ''; - if ($p == $page) { - $extra = ' style="border:1px solid grey" '; - } - $str .= ''.($p+1).' '; - } - $str .= '
'; - } - return $str; - } - - /** - * Add a new comment - * @param string $content - * @return mixed - */ - public function add($content, $format = FORMAT_MOODLE) { - global $CFG, $DB, $USER, $OUTPUT; - if (empty($this->postcap)) { - throw new comment_exception('nopermissiontocomment'); - } - $now = time(); - $newcmt = new stdclass; - $newcmt->contextid = $this->contextid; - $newcmt->commentarea = $this->commentarea; - $newcmt->itemid = $this->itemid; - $newcmt->content = $content; - $newcmt->format = $format; - $newcmt->userid = $USER->id; - $newcmt->timecreated = $now; - - if (!empty($this->plugintype)) { - // moodle module will check content - $ret = plugin_callback($this->plugintype, $this->pluginname, FEATURE_COMMENT, 'add', array(&$newcmt, $this->options), true); - if (!$ret) { - throw new comment_exception('modulererejectcomment'); - } - } - - $cmt_id = $DB->insert_record('comments', $newcmt); - if (!empty($cmt_id)) { - $newcmt->id = $cmt_id; - $newcmt->time = userdate($now, get_string('strftimerecent', 'langconfig')); - $newcmt->username = fullname($USER); - $newcmt->content = format_text($newcmt->content); - $newcmt->avatar = $OUTPUT->user_picture($USER, array('size'=>16)); - return $newcmt; - } else { - throw new comment_exception('dbupdatefailed'); - } - } - - /** - * delete by context, commentarea and itemid - * - */ - public function delete_comments() { - global $DB; - return $DB->delete_records('comments', array( - 'contextid'=>$this->context->id, - 'commentarea'=>$this->commentarea, - 'itemid'=>$this->itemid) - ); - } - - /** - * Delete a comment - * @param int $commentid - * @return mixed - */ - public function delete($commentid) { - global $DB, $USER; - $candelete = has_capability('moodle/comment:delete', $this->context); - if (!$comment = $DB->get_record('comments', array('id'=>$commentid))) { - throw new comment_exception('dbupdatefailed'); - } - if (!($USER->id == $comment->userid || !empty($candelete))) { - throw new comment_exception('nopermissiontocomment'); - } - return $DB->delete_records('comments', array('id'=>$commentid)); - } - - public function print_comments($page = 0, $return = true) { - global $DB, $CFG; - $html = ''; - if (!(self::$comment_itemid == $this->options->itemid && - self::$comment_context == $this->options->context->id && - self::$comment_area == $this->options->commentarea)) { - $page = 0; - } - $comments = $this->get_comments($page); - - $html .= '

'.get_string('comments').'

'; - $html .= "
    "; - $results = array(); - $list = ''; - foreach ($comments as $cmt) { - $list = $this->print_comment($cmt, $this->contextid, $this->commentarea, $this->itemid) . $list; - } - $html .= $list; - $html .= '
'; - $html .= $this->get_pagination($page); - $sesskey = sesskey(); - $returnurl = qualified_me(); - $strsubmit = get_string('submit'); - $html .= << - - - - - - - - - - -EOD; - if ($return) { - return $html; - } else { - echo $html; - } - } - - public function print_comment($cmt) { - $patterns = array(); - $replacements = array(); - - $patterns[] = '___picture___'; - $patterns[] = '___name___'; - $patterns[] = '___content___'; - $patterns[] = '___time___'; - $replacements[] = $cmt->avatar; - $replacements[] = fullname($cmt); - $replacements[] = $cmt->content; - $replacements[] = userdate($cmt->timecreated, get_string('strftimerecent', 'langconfig')); - - // use html template to format a single comment. - return str_replace($patterns, $replacements, $this->template); - } -} - -class comment_exception extends moodle_exception { - public $message; - function __construct($errorcode) { - $this->errorcode = $errorcode; - $this->message = get_string($errorcode, 'error'); - } -} diff --git a/lib/weblib.php b/lib/weblib.php index adc2388855e..df19a1c1af4 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -951,7 +951,7 @@ function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL if (!empty($options->comments) && !empty($CFG->usecomments)) { require_once($CFG->libdir . '/commentlib.php'); $comment = new comment($options->comments); - $cmt = $comment->init(true); + $cmt = $comment->output(true); } else { $cmt = ''; } diff --git a/mod/data/db/upgrade.php b/mod/data/db/upgrade.php index 10c43edd998..c17373da8d2 100644 --- a/mod/data/db/upgrade.php +++ b/mod/data/db/upgrade.php @@ -181,7 +181,7 @@ function xmldb_data_upgrade($oldversion) { } if ($result && $oldversion < 2009111701) { - require_once($CFG->libdir . '/commentlib.php'); + require_once($CFG->dirroot . '/comment/lib.php'); upgrade_set_timeout(60*20); /// Define table data_comments to be dropped diff --git a/mod/data/lib.php b/mod/data/lib.php index 64fea2b4457..814ce0de032 100755 --- a/mod/data/lib.php +++ b/mod/data/lib.php @@ -1277,7 +1277,7 @@ function data_print_template($template, $records, $data, $search='', $page=0, $r if (($template == 'listtemplate') && ($data->comments)) { if (!empty($CFG->usecomments)) { - require_once($CFG->libdir . '/commentlib.php'); + require_once($CFG->dirroot . '/comment/lib.php'); $cmt = new stdclass; $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id); $cmt->area = 'database_entry'; @@ -1285,7 +1285,7 @@ function data_print_template($template, $records, $data, $search='', $page=0, $r $cmt->itemid = $record->id; $cmt->showcount = true; $comment = new comment($cmt); - $replacement[] = $comment->init(true); + $replacement[] = $comment->output(true); } } else { $replacement[] = ''; @@ -1313,7 +1313,7 @@ function data_print_template($template, $records, $data, $search='', $page=0, $r *********************************/ if (($template == 'singletemplate') && ($data->comments)) { //prints ratings options if (!empty($CFG->usecomments)) { - require_once($CFG->libdir . '/commentlib.php'); + require_once($CFG->dirroot . '/comment/lib.php'); $cmt = new stdclass; $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id); $cmt->area = 'database_entry'; @@ -1321,7 +1321,7 @@ function data_print_template($template, $records, $data, $search='', $page=0, $r $cmt->itemid = $record->id; $cmt->showcount = true; $comment = new comment($cmt); - $comment->init(false); + $comment->output(false); } } } diff --git a/mod/data/view.php b/mod/data/view.php index e16935fd29d..21ec53d0b0d 100755 --- a/mod/data/view.php +++ b/mod/data/view.php @@ -81,8 +81,8 @@ require_course_login($course, true, $cm); - require_once($CFG->libdir . '/commentlib.php'); - comment::js(); + require_once($CFG->dirroot . '/comment/lib.php'); + comment::init(); $context = get_context_instance(CONTEXT_MODULE, $cm->id); require_capability('mod/data:viewentry', $context); diff --git a/mod/glossary/db/upgrade.php b/mod/glossary/db/upgrade.php index 7840a82afa2..5df0485653a 100644 --- a/mod/glossary/db/upgrade.php +++ b/mod/glossary/db/upgrade.php @@ -205,7 +205,7 @@ function xmldb_glossary_upgrade($oldversion) { upgrade_mod_savepoint($result, 2009042006, 'glossary'); } if ($result && $oldversion < 2009110800) { - require_once($CFG->libdir . '/commentlib.php'); + require_once($CFG->dirroot . '/comment/lib.php'); upgrade_set_timeout(60*20); /// Define table glossary_comments to be dropped diff --git a/mod/glossary/lib.php b/mod/glossary/lib.php index aeb456d9625..30cd93a4bea 100644 --- a/mod/glossary/lib.php +++ b/mod/glossary/lib.php @@ -1007,7 +1007,7 @@ function glossary_print_entry_icons($course, $cm, $glossary, $entry, $mode='',$h if (has_capability('mod/glossary:comment', $context) and $glossary->allowcomments) { $output = true; if (!empty($CFG->usecomments)) { - require_once($CFG->libdir . '/commentlib.php'); + require_once($CFG->dirroot . '/comment/lib.php'); $cmt = new stdclass; $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id); $cmt->area = 'glossary_entry'; @@ -1015,7 +1015,7 @@ function glossary_print_entry_icons($course, $cm, $glossary, $entry, $mode='',$h $cmt->itemid = $entry->id; $cmt->showcount = true; $comment = new comment($cmt); - $return .= '
'.$comment->init(true).'
'; + $return .= '
'.$comment->output(true).'
'; } } diff --git a/mod/glossary/view.php b/mod/glossary/view.php index 7c55e599184..e98652bfce0 100644 --- a/mod/glossary/view.php +++ b/mod/glossary/view.php @@ -49,8 +49,9 @@ if (!empty($id)) { require_course_login($course->id, true, $cm); $context = get_context_instance(CONTEXT_MODULE, $cm->id); - require_once($CFG->libdir . '/commentlib.php'); - comment::js(); +require_once($CFG->dirroot . '/comment/lib.php'); +comment::init(); + /// Loading the textlib singleton instance. We are going to need it. $textlib = textlib_get_instance();