*/ class Comment extends Model { public $no_results = false; public $belongs_to = array("post", "user"); /** * Function: __construct * See Also: * */ public function __construct($comment_id, $options = array()) { parent::grab($this, $comment_id, $options); if ($this->no_results) return false; $this->body_unfiltered = $this->body; $group = ($this->user_id and !$this->user->no_results) ? $this->user->group : new Group(Config::current()->guest_group) ; $this->filtered = !isset($options["filter"]) or $options["filter"]; $trigger = Trigger::current(); $trigger->filter($this, "comment"); if ($this->filtered) { if (($this->status != "pingback" and $this->status != "trackback") and !$group->can("code_in_comments")) $this->body = strip_tags($this->body, "<".join("><", Config::current()->allowed_comment_html).">"); $this->body_unfiltered = $this->body; $trigger->filter($this->body, array("markup_text", "markup_comment_text")); $trigger->filter($this, "filter_comment"); } } /** * Function: find * See Also: * */ static function find($options = array(), $options_for_object = array()) { return parent::search(get_class(), $options, $options_for_object); } /** * Function: create * Attempts to create a comment using the passed information. If a Defensio API key is present, it will check it. * * Parameters: * $author - The name of the commenter. * $email - The commenter's email. * $url - The commenter's website. * $body - The comment. * $post - The they're commenting on. * $type - The type of comment. Optional, used for trackbacks/pingbacks. */ static function create($author, $email, $url, $body, $post, $type = null) { if (!self::user_can($post->id) and !in_array($type, array("trackback", "pingback"))) return; $config = Config::current(); $route = Route::current(); $visitor = Visitor::current(); if (!$type) { $status = ($post->user_id == $visitor->id) ? "approved" : $config->default_comment_status ; $type = "comment"; } else $status = $type; if (!empty($config->akismet_api_key)) { $akismet = new Akismet($config->url, $config->akismet_api_key); $akismet->setCommentAuthor($author); $akismet->setCommentAuthorEmail($email); $akismet->setCommentAuthorURL($url); $akismet->setCommentContent($body); $akismet->setPermalink($post->url()); $akismet->setCommentType($type); $akismet->setReferrer($_SERVER['HTTP_REFERER']); $akismet->setUserIP($_SERVER['REMOTE_ADDR']); if ($akismet->isCommentSpam()) { self::add($body, $author, $url, $email, $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT'], "spam", null, null, $post, $visitor->id); error(__("Spam Comment"), __("Your comment has been marked as spam. It will have to be approved before it will show up.", "comments")); } else { $comment = self::add($body, $author, $url, $email, $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT'], $status, null, null, $post, $visitor->id); fallback($_SESSION['comments'], array()); $_SESSION['comments'][] = $comment->id; if (isset($_POST['ajax'])) exit("{ \"comment_id\": \"".$comment->id."\", \"comment_timestamp\": \"".$comment->created_at."\" }"); Flash::notice(__("Comment added."), $post->url()."#comment_".$comment->id); } } else { $comment = self::add($body, $author, $url, $email, $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT'], $status, null, null, $post, $visitor->id); fallback($_SESSION['comments'], array()); $_SESSION['comments'][] = $comment->id; if (isset($_POST['ajax'])) exit("{ \"comment_id\": \"".$comment->id."\", \"comment_timestamp\": \"".$comment->created_at."\" }"); Flash::notice(__("Comment added."), $post->url()."#comment_".$comment->id); } } /** * Function: add * Adds a comment to the database. * * Parameters: * $body - The comment. * $author - The name of the commenter. * $url - The commenter's website. * $email - The commenter's email. * $ip - The commenter's IP address. * $agent - The commenter's user agent. * $status - The new comment's status. * $created_at - The new comment's "created" timestamp. * $updated_at - The new comment's "last updated" timestamp. * $post - The they're commenting on. * $user_id - The ID of this this comment was made by. */ static function add($body, $author, $url, $email, $ip, $agent, $status, $created_at = null, $updated_at = null, $post, $user_id) { if (!empty($url)) # Add the http:// if it isn't there. if (!@parse_url($url, PHP_URL_SCHEME)) $url = "http://".$url; $ip = ip2long($ip); if ($ip === false) $ip = 0; $sql = SQL::current(); $sql->insert("comments", array("body" => $body, "author" => strip_tags($author), "author_url" => strip_tags($url), "author_email" => strip_tags($email), "author_ip" => $ip, "author_agent" => $agent, "status" => $status, "created_at" => oneof($created_at, datetime()), "updated_at" => oneof($updated_at, "0000-00-00 00:00:00"), "post_id" => $post->id, "user_id"=> $user_id)); $new = new self($sql->latest("comments")); Trigger::current()->call("add_comment", $new); return $new; } public function update($author, $author_email, $author_url, $body, $status, $timestamp, $update_timestamp = true) { $sql = SQL::current(); $sql->update("comments", array("id" => $this->id), array("author" => strip_tags($author), "author_email" => strip_tags($author_email), "author_url" => strip_tags($author_url), "body" => $body, "status" => $status, "created_at" => $timestamp, "updated_at" => ($update_timestamp) ? datetime() : $this->updated_at)); Trigger::current()->call("update_comment", $this, $author, $author_email, $author_url, $body, $status, $timestamp, $update_timestamp); } static function delete($comment_id) { $trigger = Trigger::current(); if ($trigger->exists("delete_comment")) $trigger->call("delete_comment", new self($comment_id)); SQL::current()->delete("comments", array("id" => $comment_id)); } public function editable($user = null) { fallback($user, Visitor::current()); return ($user->group->can("edit_comment") or ($user->group->can("edit_own_comment") and $user->id == $this->user_id)); } public function deletable($user = null) { fallback($user, Visitor::current()); return ($user->group->can("delete_comment") or ($user->group->can("delete_own_comment") and $user->id == $this->user_id)); } /** * Function: any_editable * Checks if the can edit any comments. */ static function any_editable() { $visitor = Visitor::current(); # Can they edit comments? if ($visitor->group->can("edit_comment")) return true; # Can they edit their own comments, and do they have any? if ($visitor->group->can("edit_own_comment") and SQL::current()->count("comments", array("user_id" => $visitor->id))) return true; return false; } /** * Function: any_deletable * Checks if the can delete any comments. */ static function any_deletable() { $visitor = Visitor::current(); # Can they delete comments? if ($visitor->group->can("delete_comment")) return true; # Can they delete their own comments, and do they have any? if ($visitor->group->can("delete_own_comment") and SQL::current()->count("comments", array("user_id" => $visitor->id))) return true; return false; } public function author_link() { if ($this->author_url != "") # If a URL is set return ''.$this->author.''; else # If not, just return their name return $this->author; } static function user_can($post) { $visitor = Visitor::current(); if (!$visitor->group->can("add_comment")) return false; // assume allowed comments by default return empty($post->comment_status) or !($post->comment_status == "closed" or ($post->comment_status == "registered_only" and !logged_in()) or ($post->comment_status == "private" and !$visitor->group->can("add_comment_private"))); } static function user_count($user_id) { $count = SQL::current()->count("comments", array("user_id" => $user_id)); return $count; } # !! DEPRECATED AFTER 2.0 !! public function post() { return new Post($this->post_id); } # !! DEPRECATED AFTER 2.0 !! public function user() { if ($this->user_id) return new User($this->user_id); else return false; } }