diff options
Diffstat (limited to 'modules/comment')
-rw-r--r-- | modules/comment/controllers/comments.php | 57 | ||||
-rw-r--r-- | modules/comment/helpers/comment.php | 40 | ||||
-rw-r--r-- | modules/comment/models/comment.php | 89 | ||||
-rw-r--r-- | modules/comment/tests/Comment_Event_Test.php | 17 | ||||
-rw-r--r-- | modules/comment/tests/Comment_Helper_Test.php | 34 | ||||
-rw-r--r-- | modules/comment/tests/Comment_Model_Test.php | 19 |
6 files changed, 143 insertions, 113 deletions
diff --git a/modules/comment/controllers/comments.php b/modules/comment/controllers/comments.php index 068152a2..6c546321 100644 --- a/modules/comment/controllers/comments.php +++ b/modules/comment/controllers/comments.php @@ -26,50 +26,39 @@ class Comments_Controller extends Controller { access::required("view", $item); $form = comment::get_add_form($item); - $valid = $form->validate(); - if ($valid) { - if (identity::active_user()->guest && !$form->add_comment->inputs["name"]->value) { - $form->add_comment->inputs["name"]->add_error("missing", 1); - $valid = false; - } - - if (!$form->add_comment->text->value) { - $form->add_comment->text->add_error("missing", 1); - $valid = false; + try { + $valid = $form->validate(); + $comment = ORM::factory("comment"); + $comment->item_id = $id; + $comment->author_id = identity::active_user()->id; + $comment->text = $form->add_comment->text->value; + $comment->guest_name = $form->add_comment->inputs["name"]->value; + $comment->guest_email = $form->add_comment->email->value; + $comment->guest_url = $form->add_comment->url->value; + $comment->validate(); + } catch (ORM_Validation_Exception $e) { + // Translate ORM validation errors into form error messages + foreach ($e->validation->errors() as $key => $error) { + switch ($key) { + case "guest_name": $key = "name"; break; + case "guest_email": $key = "email"; break; + } + $form->add_comment->inputs[$key]->add_error($error, 1); } + $valid = false; } if ($valid) { - $comment = comment::create( - $item, identity::active_user(), - $form->add_comment->text->value, - $form->add_comment->inputs["name"]->value, - $form->add_comment->email->value, - $form->add_comment->url->value); - - $active = identity::active_user(); - if ($active->guest) { - $form->add_comment->inputs["name"]->value(""); - $form->add_comment->email->value(""); - $form->add_comment->url->value(""); - } else { - $form->add_comment->inputs["name"]->value($active->full_name); - $form->add_comment->email->value($active->email); - $form->add_comment->url->value($active->url); - } - - $form->add_comment->text->value(""); + $comment->save(); $view = new Theme_View("comment.html", "other", "comment-fragment"); $view->comment = $comment; print json_encode( array("result" => "success", - "view" => $view->__toString(), - "form" => $form->__toString())); + "view" => (string) $view, + "form" => (string) comment::get_add_form($item))); } else { - print json_encode( - array("result" => "error", - "form" => $form->__toString())); + print json_encode(array("result" => "error", "form" => (string) $form)); } } diff --git a/modules/comment/helpers/comment.php b/modules/comment/helpers/comment.php index 1e1e7d2f..389c8922 100644 --- a/modules/comment/helpers/comment.php +++ b/modules/comment/helpers/comment.php @@ -24,46 +24,6 @@ * Note: by design, this class does not do any permission checking. */ class comment_Core { - /** - * Create a new comment. - * @param Item_MOdel $item the parent item - * @param User_Model $author the author User_Model - * @param string $text comment body - * @param string $guest_name guest's name (if the author is a guest user, default empty) - * @param string $guest_email guest's email (if the author is a guest user, default empty) - * @param string $guest_url guest's url (if the author is a guest user, default empty) - * @return Comment_Model - */ - static function create($item, $author, $text, $guest_name=null, - $guest_email=null, $guest_url=null) { - $comment = ORM::factory("comment"); - $comment->author_id = $author->id; - $comment->guest_email = $guest_email; - $comment->guest_name = $guest_name; - $comment->guest_url = $guest_url; - $comment->item_id = $item->id; - $comment->text = $text; - $comment->state = "published"; - - // These values are useful for spam fighting, so save them with the comment. - $input = Input::instance(); - $comment->server_http_accept = substr($input->server("HTTP_ACCEPT"), 0, 128); - $comment->server_http_accept_charset = substr($input->server("HTTP_ACCEPT_CHARSET"), 0, 64); - $comment->server_http_accept_encoding = substr($input->server("HTTP_ACCEPT_ENCODING"), 0, 64); - $comment->server_http_accept_language = substr($input->server("HTTP_ACCEPT_LANGUAGE"), 0, 64); - $comment->server_http_connection = substr($input->server("HTTP_CONNECTION"), 0, 64); - $comment->server_http_host = substr($input->server("HTTP_HOST"), 0, 64); - $comment->server_http_referer = substr($input->server("HTTP_REFERER"), 0, 255); - $comment->server_http_user_agent = substr($input->server("HTTP_USER_AGENT"), 0, 128); - $comment->server_query_string = substr($input->server("QUERY_STRING"), 0, 64); - $comment->server_remote_addr = substr($input->server("REMOTE_ADDR"), 0, 32); - $comment->server_remote_host = substr($input->server("REMOTE_HOST"), 0, 64); - $comment->server_remote_port = substr($input->server("REMOTE_PORT"), 0, 16); - $comment->save(); - - return $comment; - } - static function get_add_form($item) { $form = new Forge("comments/create/{$item->id}", "", "post", array("id" => "g-comment-form")); $group = $form->group("add_comment")->label(t("Add comment")); diff --git a/modules/comment/models/comment.php b/modules/comment/models/comment.php index e0b82039..43c4148f 100644 --- a/modules/comment/models/comment.php +++ b/modules/comment/models/comment.php @@ -54,24 +54,63 @@ class Comment_Model extends ORM { } /** + * Add some custom per-instance rules. + */ + public function validate($array=null) { + // validate() is recursive, only modify the rules on the outermost call. + if (!$array) { + $this->rules = array( + "guest_name" => array("callbacks" => array(array($this, "valid_author"))), + "guest_email" => array("rules" => array("email")), + "guest_url" => array("rules" => array("url")), + "item_id" => array("callbacks" => array(array($this, "valid_item"))), + "state" => array("rules" => array("Comment_Model::valid_state")), + "text" => array("rules" => array("required")), + ); + } + + parent::validate($array); + } + + /** * @see ORM::save() */ public function save() { - if (!empty($this->changed)) { - $this->updated = time(); - if (!$this->loaded() && empty($this->created)) { - $this->created = $this->updated; - $created = true; + $this->updated = time(); + if (!$this->loaded()) { + // New comment + $this->created = $this->updated; + if (empty($this->state)) { + $this->state = "published"; } - } - $visible_change = $this->original()->state == "published" || $this->state == "published"; - $original = clone $this->original(); - parent::save(); + // These values are useful for spam fighting, so save them with the comment. It's painful to + // check each one to see if it already exists before setting it, so just use server_http_host + // as a semaphore for now (we use that in g2_import.php) + if (empty($this->server_http_host)) { + $input = Input::instance(); + $this->server_http_accept = substr($input->server("HTTP_ACCEPT"), 0, 128); + $this->server_http_accept_charset = substr($input->server("HTTP_ACCEPT_CHARSET"), 0, 64); + $this->server_http_accept_encoding = substr($input->server("HTTP_ACCEPT_ENCODING"), 0, 64); + $this->server_http_accept_language = substr($input->server("HTTP_ACCEPT_LANGUAGE"), 0, 64); + $this->server_http_connection = substr($input->server("HTTP_CONNECTION"), 0, 64); + $this->server_http_host = substr($input->server("HTTP_HOST"), 0, 64); + $this->server_http_referer = substr($input->server("HTTP_REFERER"), 0, 255); + $this->server_http_user_agent = substr($input->server("HTTP_USER_AGENT"), 0, 128); + $this->server_query_string = substr($input->server("QUERY_STRING"), 0, 64); + $this->server_remote_addr = substr($input->server("REMOTE_ADDR"), 0, 32); + $this->server_remote_host = substr($input->server("REMOTE_HOST"), 0, 64); + $this->server_remote_port = substr($input->server("REMOTE_PORT"), 0, 16); + } - if (isset($created)) { + $visible_change = $this->state == "published"; + parent::save(); module::event("comment_created", $this); } else { + // Updated comment + $original = ORM::factory("comment")->where("id", "=", $this->id)->find(); + $visible_change = $original->state == "published" || $this->state == "published"; + parent::save(); module::event("comment_updated", $original, $this); } @@ -92,4 +131,34 @@ class Comment_Model extends ORM { $this->join("items", "items.id", "comments.item_id"); return item::viewable($this); } + + /** + * Make sure we have an appropriate author id set, or a guest name. + */ + public function valid_author(Validation $v, $field) { + if (empty($this->author_id)) { + $v->add_error("author_id", "required"); + } else if ($this->author_id == identity::guest()->id && empty($this->guest_name)) { + $v->add_error("guest_name", "required"); + } + } + + /** + * Make sure we have a valid associated item id. + */ + public function valid_item(Validation $v, $field) { + if (db::build() + ->from("items") + ->where("id", "=", $this->item_id) + ->count_records() != 1) { + $v->add_error("item_id", "invalid"); + } + } + + /** + * Make sure that the state is legal. + */ + static function valid_state($value) { + return in_array($value, array("published", "unpublished", "spam", "deleted")); + } } diff --git a/modules/comment/tests/Comment_Event_Test.php b/modules/comment/tests/Comment_Event_Test.php index ff7f1c26..27272055 100644 --- a/modules/comment/tests/Comment_Event_Test.php +++ b/modules/comment/tests/Comment_Event_Test.php @@ -17,16 +17,19 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Comment_Event_Test extends Unit_Test_Case { +class Comment_Event_Test extends Gallery_Unit_Test_Case { public function deleting_an_item_deletes_its_comments_too_test() { - $rand = rand(); - $album = album::create(ORM::factory("item", 1), "test_$rand", "test_$rand"); - $comment = comment::create( - $album, identity::guest(), "text_$rand", "name_$rand", "email_$rand", "url_$rand"); + $album = test::random_album(); + + $comment = ORM::factory("comment"); + $comment->item_id = $album->id; + $comment->author_id = identity::guest()->id; + $comment->guest_name = "test"; + $comment->text = "text"; + $comment->save(); $album->delete(); - $deleted_comment = ORM::factory("comment", $comment->id); - $this->assert_false($deleted_comment->loaded()); + $this->assert_false(ORM::factory("comment")->where("id", "=", $comment->id)->find()->loaded()); } } diff --git a/modules/comment/tests/Comment_Helper_Test.php b/modules/comment/tests/Comment_Helper_Test.php index 8e726869..7ba024c7 100644 --- a/modules/comment/tests/Comment_Helper_Test.php +++ b/modules/comment/tests/Comment_Helper_Test.php @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Comment_Helper_Test extends Unit_Test_Case { +class Comment_Helper_Test extends Gallery_Unit_Test_Case { private $_ip_address; private $_user_agent; @@ -48,15 +48,19 @@ class Comment_Helper_Test extends Unit_Test_Case { } public function create_comment_for_guest_test() { - $rand = rand(); - $root = ORM::factory("item", 1); - $comment = comment::create( - $root, identity::guest(), "text_$rand", "name_$rand", "email_$rand", "url_$rand"); + $comment = ORM::factory("comment"); + $comment->item_id = item::root()->id; + $comment->text = "text"; + $comment->author_id = identity::guest()->id; + $comment->guest_name = "name"; + $comment->guest_email = "email@email.com"; + $comment->guest_url = "http://url.com"; + $comment->save(); - $this->assert_equal("name_$rand", $comment->author_name()); - $this->assert_equal("email_$rand", $comment->author_email()); - $this->assert_equal("url_$rand", $comment->author_url()); - $this->assert_equal("text_$rand", $comment->text); + $this->assert_equal("name", $comment->author_name()); + $this->assert_equal("email@email.com", $comment->author_email()); + $this->assert_equal("http://url.com", $comment->author_url()); + $this->assert_equal("text", $comment->text); $this->assert_equal(1, $comment->item_id); $this->assert_equal("REMOTE_ADDR", $comment->server_remote_addr); @@ -78,16 +82,18 @@ class Comment_Helper_Test extends Unit_Test_Case { } public function create_comment_for_user_test() { - $rand = rand(); - $root = ORM::factory("item", 1); $admin = identity::admin_user(); - $comment = comment::create( - $root, $admin, "text_$rand", "name_$rand", "email_$rand", "url_$rand"); + + $comment = ORM::factory("comment"); + $comment->item_id = item::root()->id; + $comment->text = "text"; + $comment->author_id = $admin->id; + $comment->save(); $this->assert_equal($admin->full_name, $comment->author_name()); $this->assert_equal($admin->email, $comment->author_email()); $this->assert_equal($admin->url, $comment->author_url()); - $this->assert_equal("text_$rand", $comment->text); + $this->assert_equal("text", $comment->text); $this->assert_equal(1, $comment->item_id); $this->assert_equal("REMOTE_ADDR", $comment->server_remote_addr); diff --git a/modules/comment/tests/Comment_Model_Test.php b/modules/comment/tests/Comment_Model_Test.php index aa91d6f2..f0449c05 100644 --- a/modules/comment/tests/Comment_Model_Test.php +++ b/modules/comment/tests/Comment_Model_Test.php @@ -17,24 +17,27 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Comment_Model_Test extends Unit_Test_Case { +class Comment_Model_Test extends Gallery_Unit_Test_Case { public function cant_view_comments_for_unviewable_items_test() { - $root = ORM::factory("item", 1); - $album = album::create($root, rand(), rand(), rand()); - $comment = comment::create($album, identity::guest(), "text", "name", "email", "url"); + $album = test::random_album(); + + $comment = ORM::factory("comment"); + $comment->item_id = $album->id; + $comment->author_id = identity::admin_user()->id; + $comment->text = "text"; + $comment->save(); + identity::set_active_user(identity::guest()); // We can see the comment when permissions are granted on the album access::allow(identity::everybody(), "view", $album); - $this->assert_equal( - 1, + $this->assert_true( ORM::factory("comment")->viewable()->where("comments.id", "=", $comment->id)->count_all()); // We can't see the comment when permissions are denied on the album access::deny(identity::everybody(), "view", $album); - $this->assert_equal( - 0, + $this->assert_false( ORM::factory("comment")->viewable()->where("comments.id", "=", $comment->id)->count_all()); } } |