/**
  * show the contents of the view
  */
 function render()
 {
     // load the comments and throw the correct event
     $comments = new ArticleComments();
     $postComments = $comments->getPostComments($this->_article->getId(), COMMENT_ORDER_NEWEST_FIRST, $this->_commentStatus, $this->_page, DEFAULT_ITEMS_PER_PAGE);
     $this->notifyEvent(EVENT_COMMENTS_LOADED, array("comments", &$postComments));
     // number of comments
     $numPostComments = $comments->getNumPostComments($this->_article->getId(), $this->_commentStatus);
     if ($this->_commentStatus > -1) {
         $pagerUrl = "?op=editComments&articleId=" . $this->_article->getId() . "&showStatus=" . $this->_commentStatus . "&page=";
     } else {
         $pagerUrl = "?op=editComments&articleId=" . $this->_article->getId() . "&page=";
     }
     // calculate the pager url
     $pager = new Pager($pagerUrl, $this->_page, $numPostComments, DEFAULT_ITEMS_PER_PAGE);
     // get a list with all the different comment status
     $statusList = ArticleCommentStatus::getStatusList(true);
     // and pass all the information to the templates
     $this->setValue("comments", $postComments);
     $this->setValue("commentstatus", $statusList);
     $this->setValue("currentstatus", $this->_commentStatus);
     // pass the pager to the view
     $this->setValue("pager", $pager);
     +$this->setValue("post", $this->_article);
     parent::render();
 }
 /**
  * cleans up spam comments. Returns true if successful or false otheriwse
  */
 function cleanupComments()
 {
     $comments = new ArticleComments();
     $comments->purgeSpamComments();
     $this->_message = $this->_locale->tr("spam_comments_purged_ok");
     return true;
 }
 /**
  * Returns the recent comments object of current blog
  */
 function getRecentComments($maxComments = 0, $based = 'BLOG')
 {
     $comments = new ArticleComments();
     $blogId = $this->blogInfo->getId();
     if ($based == 'BLOG') {
         $query = "SELECT " . $this->prefix . "articles_comments.* FROM " . $this->prefix . "articles_comments, " . $this->prefix . "articles";
         $query .= " WHERE " . $this->prefix . "articles_comments.article_id = " . $this->prefix . "articles.id AND " . $this->prefix . "articles.blog_id = " . $blogId . " AND " . $this->prefix . "articles.status=1";
         $query .= " AND " . $this->prefix . "articles_comments.status = 0";
         $query .= " ORDER BY " . $this->prefix . "articles_comments.date DESC";
     } elseif ($based == 'SITE') {
         $query = "SELECT " . $this->prefix . "articles_comments.* FROM " . $this->prefix . "articles_comments, " . $this->prefix . "articles";
         $query .= " WHERE " . $this->prefix . "articles_comments.article_id = " . $this->prefix . "articles.id AND " . $this->prefix . "articles.status=1";
         $query .= " AND " . $this->prefix . "articles_comments.status = 0";
         $query .= " ORDER BY " . $this->prefix . "articles_comments.date DESC";
     } else {
         return false;
     }
     if ($maxComments > 0) {
         $query .= " LIMIT " . $maxComments;
     } else {
         $query .= " LIMIT " . $this->maxComments;
     }
     $result = $comments->_db->Execute($query);
     if (!$result) {
         return false;
     }
     $recentcomments = array();
     while ($row = $result->FetchRow()) {
         array_push($recentcomments, $comments->_fillCommentInformation($row));
     }
     return $recentcomments;
 }
 function perform()
 {
     // fetch the data and make some arrangements if needed
     $this->_parentId = $this->_request->getValue("parentId");
     $this->_articleId = $this->_request->getValue("articleId");
     if ($this->_parentId < 0 || $this->_parentId == "") {
         $this->_parentId = 0;
     }
     // check if comments are enabled
     $blogSettings = $this->_blogInfo->getSettings();
     if (!$blogSettings->getValue("comments_enabled")) {
         $this->_view = new ErrorView($this->_blogInfo, "error_comments_not_enabled");
         $this->setCommonData();
         return false;
     }
     // fetch the article
     $blogs = new Blogs();
     $articles = new Articles();
     $article = $articles->getBlogArticle($this->_articleId, $this->_blogInfo->getId());
     // if there was a problem fetching the article, we give an error and quit
     if ($article == false) {
         $this->_view = new ErrorView($this->_blogInfo);
         $this->_view->setValue("message", "error_fetching_article");
         $this->setCommonData();
         return false;
     }
     $this->_view = new BlogView($this->_blogInfo, "commentarticle", SMARTY_VIEW_CACHE_CHECK, array("articleId" => $this->_articleId, "parentId" => $this->_parentId));
     // do nothing if the view was already cached
     if ($this->_view->isCached()) {
         return true;
     }
     // fetch the comments so far
     $comments = new ArticleComments();
     $postComments = $comments->getPostComments($article->getId());
     if ($this->_parentId > 0) {
         // get a pre-set string for the subject field, for those users interested
         $comment = $comments->getPostComment($article->getId(), $this->_parentId);
         // create the string
         if ($comment) {
             $replyString = $this->_locale->tr("reply_string") . $comment->getTopic();
             $this->_view->setValue("comment", $comment);
         }
     }
     // if everything's fine, we set up the article object for the view
     $this->_view->setValue("post", $article);
     $this->_view->setValue("parentId", $this->_parentId);
     $this->_view->setValue("comments", $postComments);
     $this->_view->setValue("postcomments", $postComments);
     $this->_view->setValue("topic", $replyString);
     $this->setCommonData();
     // and return everything normal
     return true;
 }
 /**
  * Processes incoming requests
  *
  * @return A positive PipelineResult object is the comment is not spam or a negative
  * one if it is.
  */
 function filter()
 {
     $config =& Config::getConfig();
     if (!$config->getValue("bayesian_filter_enabled")) {
         return new PipelineResult(true);
     }
     // get some info
     $blogInfo = $this->_pipelineRequest->getBlogInfo();
     $request = $this->_pipelineRequest->getHttpRequest();
     // we only have to filter the contents if the user is posting a comment
     // so there's no point in doing anything else if that's not the case
     if ($request->getValue("op") != "AddComment") {
         $result = new PipelineResult();
         return $result;
     }
     // text and topic of the comment
     $commentText = $request->getValue("commentText");
     $commentTopic = $request->getValue("commentTopic");
     $userName = $request->getValue("userName");
     $userEmail = $request->getValue("userEmail");
     $userUrl = $request->getValue("userUrl");
     $articleId = $request->getValue("articleId");
     $parentId = $request->getValue("parentId");
     if ($parentId == "") {
         $parentId = 0;
     }
     $spamicity = $this->getSpamProbability($blogInfo->getId(), $commentTopic, $commentText, $userName, $userEmail, $userUrl);
     if ($spamicity >= $config->getValue("bayesian_filter_spam_probability_treshold")) {
         $result = new PipelineResult(false, HIGH_SPAM_PROBABILITY, "You cannot post this message. Anti-spam filter has blocked it.");
         // now we need to check what we have to do with this comment... either throw it away
         // or keep it in the database
         // this piece of code shouldn't really go here, but it's easier than letting
         // the AddComment action that there was actually a comment and that it should
         // still be added but marked as spam and so on... sometimes breaking a few
         // rules makes things easier :)
         if ($config->getValue("bayesian_filter_spam_comments_action") == BAYESIAN_FILTER_KEEP_COMMENT_ACTION) {
             $comments = new ArticleComments();
             $clientIp = Client::getIp();
             $comment = new UserComment($articleId, $parentId, $commentTopic, $commentText, null, $userName, $userEmail, $userUrl, $clientIp, 0, COMMENT_STATUS_SPAM);
             $comments->addComment($comment);
         } else {
             // nothing to do here, simply throw the comment away
         }
         $spam = true;
     } else {
         $result = new PipelineResult(true);
         $spam = false;
     }
     // train the filter with the message, be it spam or not...
     BayesianFilterCore::train($blogInfo->getId(), $commentTopic, $commentText, $userName, $userEmail, $userUrl, $spam);
     //print "<h1>" . number_format($spamicity * 100, 0) . "% of spamicity</h1>";
     return $result;
 }
 /**
  * deletes comments
  * @private
  */
 function _deleteComments()
 {
     $comments = new ArticleComments();
     $errorMessage = "";
     $successMessage = "";
     $totalOk = 0;
     // if we can't even load the article, then forget it...
     $articles = new Articles();
     $article = $articles->getBlogArticle($this->_articleId, $this->_blogInfo->getId());
     if (!$article) {
         $this->_view = new AdminPostsListView($this->_blogInfo);
         $this->_view->setErrorMessage($this->_locale->tr("error_fetching_post"));
         $this->setCommonData();
         return false;
     }
     // loop through the comments and remove them
     foreach ($this->_commentIds as $commentId) {
         // fetch the comment
         $comment = $comments->getPostComment($this->_articleId, $commentId);
         if (!$comment) {
             $errorMessage .= $this->_locale->pr("error_deleting_comment2", $commentId);
         } else {
             // fire the pre-event
             $this->notifyEvent(EVENT_PRE_COMMENT_DELETE, array("comment" => &$comment));
             if (!$comments->deletePostComment($article->getId(), $commentId)) {
                 $errorMessage .= $this->_locale->pr("error_deleting_comment", $comment->getTopic()) . "<br/>";
             } else {
                 $totalOk++;
                 if ($totalOk < 2) {
                     $successMessage .= $this->_locale->pr("comment_deleted_ok", $comment->getTopic()) . "<br/>";
                 } else {
                     $successMessage = $this->_locale->pr("comments_deleted_ok", $totalOk);
                 }
                 // fire the post-event
                 $this->notifyEvent(EVENT_POST_COMMENT_DELETE, array("comment" => &$comment));
             }
         }
     }
     // if everything fine, then display the same view again with the feedback
     $this->_view = new AdminArticleCommentsListView($this->_blogInfo, array("article" => $article));
     if ($successMessage != "") {
         $this->_view->setSuccessMessage($successMessage);
         // clear the cache
         CacheControl::resetBlogCache($this->_blogInfo->getId());
     }
     if ($errorMessage != "") {
         $this->_view->setErrorMessage($errorMessage);
     }
     $this->setCommonData();
     // better to return true if everything fine
     return true;
 }
 /**
  * normally views do not meddle with data but in this case moving all
  * this data fetching here is benefitial from a coding point of view, because it
  * allows this code to be reused by several action classes... In the worst case
  * we would have to copy+paste the code or put in a separate class only for this bit
  * of code. By moving it here, the view itself can handle everything
  */
 function _loadViewData()
 {
     // for each blog, load some statistics
     $articles = new Articles();
     $comments = new ArticleComments();
     $trackbacks = new Trackbacks();
     $resources = new GalleryResources();
     $recentPosts = array();
     $recentComments = array();
     $recentResources = array();
     // load some statistics	for each one of the blogs
     foreach ($this->_userBlogs as $userBlog) {
         $recentPosts[$userBlog->getId()] = $articles->getBlogArticles($userBlog->getId(), -1, DASHBOARD_MAX_RECENT_ITEMS, 0, POST_STATUS_PUBLISHED);
         $recentComments[$userBlog->getId()] = $comments->getBlogComments($userBlog->getId(), DASHBOARD_MAX_RECENT_ITEMS);
         $recentTrackbacks[$userBlog->getId()] = $trackbacks->getBlogTrackbacks($userBlog->getId(), DASHBOARD_MAX_RECENT_ITEMS);
     }
     $this->_params->setValue("userblogs", $this->_userBlogs);
     $this->_params->setValue("recentposts", $recentPosts);
     $this->_params->setValue("recentcomments", $recentComments);
     $this->_params->setValue("recenttrackbacks", $recentTrackbacks);
 }
 function _addComment($data, $_debug)
 {
     if ($data["article_id"] == NULL) {
         $data["article_id"] = 1;
     }
     if ($data["parent_id"] == NULL) {
         $data["parent_id"] = 0;
     }
     if ($data["topic"] == NULL) {
         $data["topic"] = "No Topic";
     }
     if ($data["text"] == NULL) {
         $data["text"] = "No Comment";
     }
     if ($data["date"] == NULL) {
         $data["date"] = now();
     }
     if ($data["user_name"] == NULL) {
         $data["user_name"] = "";
     }
     if ($data["user_email"] == NULL) {
         $data["user_email"] = "";
     }
     if ($data["user_url"] == NULL) {
         $data["user_url"] = "";
     }
     if ($data["client_ip"] == NULL) {
         $data["client_ip"] = "0.0.0.0";
     }
     $coms = new ArticleComments();
     $com = $coms->getPostComments($data["article_id"]);
     if ($com) {
         foreach ($com as $artcom) {
             if ($artcom->getText() == $data["text"]) {
                 if ($_debug) {
                     print "--- --- comment already exists, abort.<br />\n\r";
                 }
                 return $artcom->getId();
             }
         }
     }
     //(article_id, `topic`, `text`, `date`, user_email, user_url, user_name, client_ip)
     $com = new UserComment($data["article_id"], $data["parent_id"], $data["topic"], $data["text"], $data["date"], $data["user_name"], $data["user_email"], $data["user_url"], $data["client_ip"]);
     $comments = new ArticleComments();
     $comment_id = $comments->addComment($com);
     $this->_stats["comments"]["write"]++;
     return $comment_id;
 }
 /**
  * @private
  */
 function _markCommentAsNonSpam()
 {
     // throw the pre-event
     $this->notifyEvent(EVENT_PRE_MARK_NO_SPAM_COMMENT, array("commentId" => $this->_commentId));
     $this->_view = new AdminArticleCommentsListView($this->_blogInfo, array("article" => $this->_article));
     $comments = new ArticleComments();
     if (!$comments->updateCommentStatus($this->_commentId, COMMENT_STATUS_NONSPAM)) {
         $this->_view->setErrorMessage($this->_locale->tr("error_marking_comment_as_nonspam"));
         $this->setCommonData();
         $res = false;
     } else {
         $this->_view->setSuccessMessage($this->_locale->tr("comment_marked_as_nonspam_ok"));
         $this->setCommonData();
         $res = true;
         // before exiting, we should get the comment and train the filter
         // to recognize this as spam...
         $comment = $comments->getPostComment($this->_articleId, $this->_commentId);
         $bayesian = new BayesianFilterCore();
         $bayesian->untrain($this->_blogInfo->getId(), $comment->getTopic(), $comment->getText(), $comment->getUserName(), $comment->getUserEmail(), $comment->getUserUrl(), true);
         $bayesian->train($this->_blogInfo->getId(), $comment->getTopic(), $comment->getText(), $comment->getUserName(), $comment->getUserEmail(), $comment->getUserUrl(), false);
         // throw the post-event if everythign went fine
         $this->notifyEvent(EVENT_POST_MARK_NO_SPAM_COMMENT, array("commentId" => $this->_commentId));
     }
     return $res;
 }
 /**
  * Returns an array of UserComment objects, with all the comments that have been received for
  * this article.
  *
  * @param onlyActive return only those comments that are not marked as spam
  * @return An array of UserComment objects.
  * @see UserComment
  */
 function getComments($onlyActive = true)
 {
     // load the comments if they haven't been loaded yet
     if ($this->_comments == null) {
         $userComments = new ArticleComments();
         $blogSettings = $this->_blogInfo->getSettings();
         $this->setComments($userComments->getPostComments($this->getId(), $blogSettings->getValue('comments_order'), COMMENT_STATUS_ALL));
     }
     // if we only want to return the active ones, then we have to loop through
     // the array once more
     if ($onlyActive) {
         $comments = array();
         foreach ($this->_comments as $comment) {
             if ($comment->getStatus() == COMMENT_STATUS_NONSPAM) {
                 $comments[] = $comment;
             }
         }
     } else {
         $comments = $this->_comments;
     }
     return $comments;
 }
 /**
  * Carries out the action
  */
 function perform()
 {
     // need to check the ip of the client
     $clientIp = Client::getIp();
     // fetch the same article again so that we can have all the comments from
     // the database, plus this last one
     $articles = new Articles();
     $article = $articles->getBlogArticle($this->_articleId, $this->_blogInfo->getId());
     // check if the user wanted to receive comments for this article
     // or not...
     if ($article->getCommentsEnabled() == false) {
         $this->_view = new ErrorView($this->_blogInfo);
         $this->_view->setValue("message", "Comments have been disabled for this article.");
         $this->setCommonData();
         return false;
     }
     $this->notifyEvent(EVENT_POST_LOADED, array("article" => &$article));
     // we have already checked all the data, so we are sure that everything's in place
     $comments = new ArticleComments();
     $comment = new UserComment($this->_articleId, $this->_parentId, $this->_commentTopic, $this->_commentText, null, $this->_userName, $this->_userEmail, $this->_userUrl, $clientIp);
     // check if there is already a comment with the same text, topic and made from the same
     // IP already in the database because if so, then we will not add the comment that
     // the user is trying to add (a reload button mistake, perhaps?)
     if (!$comments->getIdenticalComment($this->_commentTopic, $this->_commentText, $this->_articleId, $this->_parentId, $this->_userName, $this->_userEmail, $this->_userUrl, $clientIp)) {
         // fire an event
         $this->notifyEvent(EVENT_PRE_COMMENT_ADD, array("comment" => &$comment));
         if (!$comments->addComment($comment)) {
             // show an error message if problems
             $this->_view = new ErrorView($this->_blogInfo);
             $this->_view->setValue("message", "error_adding_comment");
             $this->setCommonData();
             return false;
         }
     }
     // finally, check if there was any user who wanted to be notified of new comments
     // to this post...
     $notifier = new ArticleNotifications();
     $notifier->notifyUsers($article->getId(), $this->_blogInfo);
     // fire the post event...
     $this->notifyEvent(EVENT_POST_COMMENT_ADD, array("comment" => &$comment));
     //
     // clear caches. This should be done in a more granular way, because right now
     // we're either removing *all* of them or none. I guess we should only remove the
     // cache whose identifier corresponds with the blog and article that we just removed,
     // but let's leave it as it is for the time being...
     //
     CacheControl::resetBlogCache($this->_blogInfo->getId());
     // clean up the request, there's a parameter called 'userName' also used by
     // ViewArticleAction but that doesn't have the same meaning so we better remove it
     // before it's too late! We also need to add a new request commentUserName to replace
     // original userName, in case developer need it in filter or event plugin.
     $request = HttpVars::getRequest();
     $request["commentUserName"] = $request["userName"];
     $request["userName"] = "";
     HttpVars::setRequest($request);
     // forward the action to ViewArticleAction
     return BlogController::setForwardAction("ViewArticle");
 }
 /**
  * Removes an article from the database
  *
  * If forever == true, the article is physically removed from the database.
  * Otherwise, the 'status' field is set to 'deleted'
  *
  * Problem is, that MySQL will automatically update the 'date' field because he feels
  * like it... even if we explicitely say date = old_date... grrreat :P
  *
  * Valid article identifier, blog identifier and user identifier are required to remove an
  * article. It was done for security reasons and to make perfectly clear that we are removing
  * an article (so that we wouldn't be deleting the wrong one if there was any bug!)
  *
  * @param artId A valid article identifier
  * @param userid A valid user identifier
  * @param blogId A valid blog identifier
  * @param forever A boolean meaning whether the post should be removed forever or simply its status
  * should be set to 'deleted'
  * @return Returns true if successful or false otherwise.
  */
 function deleteArticle($artId, $userId, $blogId, $forever = false)
 {
     if ($forever) {
         $query = "DELETE FROM " . $this->getPrefix() . "articles WHERE id = " . $artId . " AND user_id = " . $userId . " AND blog_id = " . $blogId . ";";
         // -- text --
         $this->deleteArticleText($artId);
         // we also have to remove its comments and trackbacks if the article is being deleted forever
         // -- comments --
         $comments = new ArticleComments();
         $comments->deletePostComments($artId);
         // -- trackbacks --
         $trackbacks = new Trackbacks();
         $trackbacks->deletePostTrackbacks($artId);
         // -- post-to-categories mappings --
         $this->deletePostCategoriesLink($artId);
         // -- custom fields --
         $customFields = new CustomFieldsValues();
         $customFields->removeArticleCustomFields($artId);
     } else {
         $query = "UPDATE " . $this->getPrefix() . "articles SET date = date, status = 3 WHERE id = " . $artId . " AND user_id = " . $userId . " AND blog_id = " . $blogId . ";";
     }
     $result = $this->Execute($query);
     if (!$result) {
         return false;
     }
     if ($this->_db->Affected_Rows() == 0) {
         return false;
     }
     return true;
 }