Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-3998: class.WpdiscuzHelperAjax.php in wpdiscuz/trunk/utils – WordPress Plugin Repository

The wpDiscuz plugin for WordPress is vulnerable to unauthorized modification of data due to a missing authorization check on the userRate function in versions up to, and including, 7.6.3. This makes it possible for unauthenticated attackers to increase or decrease the rating of a post.

CVE
#mac#js#wordpress#php#pdf#auth#ssl

1<?php2if (!defined(“ABSPATH”)) {3 exit();4}56class WpdiscuzHelperAjax implements WpDiscuzConstants {78 private $options;910 /**11 * @var WpdiscuzDBManager12 */13 private $dbManager;14 private $helper;15 private $helperEmail;16 private $wpdiscuzForm;1718 public function __construct($options, $dbManager, $helper, $helperEmail, $wpdiscuzForm) {19 $this->options = $options;20 $this->dbManager = $dbManager;21 $this->helper = $helper;22 $this->helperEmail = $helperEmail;23 $this->wpdiscuzForm = $wpdiscuzForm;24 add_action("wp_ajax_wpdStickComment", [&$this, “stickComment”]);25 add_action("wp_ajax_wpdCloseThread", [&$this, “closeThread”]);26 add_action("wp_ajax_wpdDeactivate", [&$this, “deactivate”]);27 add_action("wp_ajax_wpdImportSTCR", [&$this, “importSTCR”]);28 add_action("wp_ajax_wpdImportLSTC", [&$this, “importLSTC”]);2930 add_action("wp_ajax_wpdFollowUser", [&$this, “followUser”]);31 add_action("wp_ajax_wpdRegenerateVoteMetas", [&$this, “regenerateVoteMetas”]);32 add_action("wp_ajax_wpdRegenerateClosedComments", [&$this, “regenerateClosedComments”]);33 add_action("wp_ajax_wpdRegenerateVoteData", [&$this, “regenerateVoteData”]);34 add_action("wp_ajax_wpdSyncCommenterData", [&$this, “syncCommenterData”]);35 add_action("wp_ajax_wpdRebuildRatings", [&$this, “rebuildRatings”]);36 add_action("wp_ajax_wpdFixTables", [&$this, “fixTables”]);37 if ($this->options->login[“showActivityTab”] || $this->options->login[“showSubscriptionsTab”] || $this->options->login[“showFollowsTab”]) {38 add_action("wp_ajax_wpdDeleteComment", [&$this, “deleteComment”]);39 add_action("wp_ajax_wpdCancelSubscription", [&$this, “deleteSubscription”]);40 add_action("wp_ajax_wpdCancelFollow", [&$this, “deleteFollow”]);41 add_action("wp_ajax_wpdEmailDeleteLinks", [&$this->helperEmail, “emailDeleteLinksAction”]);42 add_action("wp_ajax_nopriv_wpdGuestAction", [&$this, “guestAction”]);43 }44 if ($this->options->content[“commentReadMoreLimit”]) {45 add_action("wp_ajax_wpdReadMore", [&$this, “readMore”]);46 add_action("wp_ajax_nopriv_wpdReadMore", [&$this, “readMore”]);47 }48 add_action("wp_ajax_wpdRedirect", [&$this, “redirect”]);49 add_action("wp_ajax_nopriv_wpdRedirect", [&$this, “redirect”]);50 if ($this->options->thread_layouts[“showVotingButtons”]) {51 add_action("wp_ajax_wpdVoteOnComment", [&$this, “voteOnComment”]);52 add_action("wp_ajax_nopriv_wpdVoteOnComment", [&$this, “voteOnComment”]);53 }54 add_action("wp_ajax_wpdGetInlineCommentForm", [&$this, “getInlineCommentForm”]);55 add_action("wp_ajax_nopriv_wpdGetInlineCommentForm", [&$this, “getInlineCommentForm”]);56 add_action("wp_ajax_wpdGetLastInlineComments", [&$this, “getLastInlineComments”]);57 add_action("wp_ajax_nopriv_wpdGetLastInlineComments", [&$this, “getLastInlineComments”]);58 add_action("wp_ajax_wpdEditComment", [&$this, “editComment”]);59 add_action("wp_ajax_nopriv_wpdEditComment", [&$this, “editComment”]);60 add_action("wp_ajax_wpdUserRate", [&$this, “userRate”]);61 add_action("wp_ajax_nopriv_wpdUserRate", [&$this, “userRate”]);62 add_action("wp_ajax_wpdUnsubscribe", [&$this, “unsubscribe”]);63 add_action("wp_ajax_nopriv_wpdUnsubscribe", [&$this, “unsubscribe”]);64 add_action("wp_ajax_wpd_stat_brief", [&$this, “wpd_stat_brief”]);65 add_action("wp_ajax_wpd_stat_subs", [&$this, “wpd_stat_subs”]);66 add_action("wp_ajax_wpd_stat_graph", [&$this, “wpd_stat_graph”]);67 add_action("wp_ajax_wpd_stat_user", [&$this, “wpd_stat_user”]);68 add_action("wp_ajax_searchOption", [&$this, “searchOption”]);69 add_action("wp_ajax_wpdResetPostRating", [&$this, “resetPostRating”]);70 add_action("wp_ajax_wpdResetFieldsRatings", [&$this, “resetFieldsRatings”]);71 }7273 public function stickComment() {74 $this->helper->validateNonce();75 $postId = WpdiscuzHelper::sanitize(INPUT_POST, "postId", FILTER_SANITIZE_NUMBER_INT, 0);76 $commentId = WpdiscuzHelper::sanitize(INPUT_POST, "commentId", FILTER_SANITIZE_NUMBER_INT, 0);77 if ($postId && $commentId) {78 $comment = get_comment($commentId);79 $userCanStickComment = current_user_can(“moderate_comments”);80 if (!$userCanStickComment) {81 $post = get_post($postId);82 $currentUser = WpdiscuzHelper::getCurrentUser();83 $userCanStickComment = $post && isset($post->post_author) && $currentUser && isset($currentUser->ID) && $post->post_author == $currentUser->ID;84 }85 if ($userCanStickComment && $comment && isset($comment->comment_ID) && $comment->comment_ID && !$comment->comment_parent) {86 $commentarr = [“comment_ID” => $commentId];87 if ($comment->comment_type === self::WPDISCUZ_STICKY_COMMENT) {88 $commentarr[“comment_type”] = WpdiscuzCore::$DEFAULT_COMMENT_TYPE;89 $response = esc_html($this->options->getPhrase("wc_stick_comment", [“comment” => $comment]));90 } else {91 $commentarr[“comment_type”] = self::WPDISCUZ_STICKY_COMMENT;92 $response = esc_html($this->options->getPhrase("wc_unstick_comment", [“comment” => $comment]));93 }94 $commentarr[“wpdiscuz_comment_update”] = true;95 if (wp_update_comment(wp_slash($commentarr))) {96 do_action("wpdiscuz_reset_comments_cache", $comment->comment_post_ID);97 wp_send_json_success($response);98 }99 }100 }101 }102103 public function closeThread() {104 $this->helper->validateNonce();105 $postId = WpdiscuzHelper::sanitize(INPUT_POST, "postId", FILTER_SANITIZE_NUMBER_INT, 0);106 $commentId = WpdiscuzHelper::sanitize(INPUT_POST, "commentId", FILTER_SANITIZE_NUMBER_INT, 0);107 if ($postId && $commentId) {108 $comment = get_comment($commentId);109 $userCanCloseComment = current_user_can(“moderate_comments”);110 if (!$userCanCloseComment) {111 $post = get_post($postId);112 $currentUser = WpdiscuzHelper::getCurrentUser();113 $userCanCloseComment = !empty($post->post_author) && !empty($currentUser->ID) && $post->post_author == $currentUser->ID;114 }115 if ($userCanCloseComment && !empty($comment->comment_ID) && !$comment->comment_parent) {116 $children = $comment->get_children([117 “format” => "flat",118 “status” => "all",119 “post_id” => $postId,120 ]);121 $response = [];122 $isClosed = intval(get_comment_meta($comment->comment_ID, self::META_KEY_CLOSED, true));123 if ($isClosed) {124 $response[“data”] = esc_html($this->options->getPhrase("wc_close_comment", [“comment” => $comment]));125 $response[“icon”] = esc_attr(“fa-unlock”);126 } else {127 $response[“data”] = esc_html($this->options->getPhrase("wc_open_comment", [“comment” => $comment]));128 $response[“icon”] = esc_attr(“fa-lock”);129 }130 update_comment_meta($comment->comment_ID, self::META_KEY_CLOSED, intval(!$isClosed));131 if ($children && is_array($children)) {132 foreach ($children as $k => $child) {133 update_comment_meta($child->comment_ID, self::META_KEY_CLOSED, intval(!$isClosed));134 }135 }136 do_action("wpdiscuz_reset_comments_cache", $comment->comment_post_ID);137 wp_send_json_success($response);138 }139 }140 }141142 public function deactivate() {143 $response = [“code” => 0];144 $json = filter_input(INPUT_POST, “deactivateData”);145 if ($json) {146 parse_str($json, $data);147 if (isset($data[“never_show”]) && ($v = intval($data[“never_show”]))) {148 update_option(self::OPTION_SLUG_DEACTIVATION, $v);149 $response[“code”] = "dismiss_and_deactivate";150 } else if (isset($data[“deactivation_reason”]) && ($reason = trim($data[“deactivation_reason”]))) {151 if ($reason !== “I’ll reactivate it later”) {152 $pluginData = get_plugin_data(WPDISCUZ_DIR_PATH . “/class.WpdiscuzCore.php”);153 $blogTitle = get_option(“blogname”);154 $to = "[email protected]";155 $subject = "[wpDiscuz Feedback - " . $pluginData[“Version”] . "] - " . $reason;156 $headers = [];157 $contentType = "text/html";158 $fromName = html_entity_decode($blogTitle, ENT_QUOTES);159 $siteUrl = get_site_url();160 $parsedUrl = parse_url($siteUrl);161 $domain = isset($parsedUrl[“host”]) ? WpdiscuzHelper::fixEmailFrom($parsedUrl[“host”]) : "";162 $fromEmail = “no-reply@” . $domain;163 $headers[] = "Content-Type: $contentType; charset=UTF-8";164 $headers[] = “From: " . $fromName . " <” . $fromEmail . "> \r\n";165 $message = "<strong>Deactivation subject:</strong> " . $reason . “\r\n” . "<br/>";166 if (isset($data[“deactivation_reason_desc”]) && ($reasonDesc = trim($data[“deactivation_reason_desc”]))) {167 $message .= "<strong>Deactivation reason:</strong> " . $reasonDesc . “\r\n” . "<br/>";168 }169 if (isset($data[“deactivation_feedback_email”]) && ($feedback_email = trim($data[“deactivation_feedback_email”]))) {170 if (filter_var($feedback_email, FILTER_VALIDATE_EMAIL) === false) {171 $response[“code”] = "send_and_deactivate";172 wp_die(json_encode($response));173 }174 $to = "[email protected]";175 $message .= "<strong>Feedback Email:</strong> " . $feedback_email . “\r\n” . "<br/>";176 }177 $subject = html_entity_decode($subject, ENT_QUOTES);178 $message = html_entity_decode($message, ENT_QUOTES);179 $sent = wp_mail($to, $subject, do_shortcode($message), $headers);180 }181 $response[“code”] = "send_and_deactivate";182 }183 }184 wp_die(json_encode($response));185 }186187 /**188 * Import subscriptions from “Subscribe To Comments Reloaded” plugin189 */190 public function importSTCR() {191 $this->helper->validateNonce();192 $response = [“progress” => 0];193 $stcrData = isset($_POST[“stcrData”]) ? sanitize_textarea_field($_POST[“stcrData”]) : "";194 if ($stcrData) {195 parse_str($stcrData, $data);196 $limit = 50;197 $step = isset($data[“stcr-step”]) ? intval($data[“stcr-step”]) : 0;198 $stcrSubscriptionsCount = isset($data[“stcr-subscriptions-count”]) ? intval($data[“stcr-subscriptions-count”]) : 0;199 $nonce = isset($data[“wpd-stcr-subscriptions”]) ? trim($data[“wpd-stcr-subscriptions”]) : "";200 if (wp_verify_nonce($nonce, “wc_tools_form”) && $stcrSubscriptionsCount) {201 $offset = $limit * $step;202 if ($limit && $offset >= 0) {203 $subscriptions = $this->dbManager->getStcrSubscriptions($limit, $offset);204 if ($subscriptions) {205 $this->dbManager->addStcrSubscriptions($subscriptions);206 ++$step;207 $response[“step”] = $step;208 $progress = $offset ? $offset * 100 / $stcrSubscriptionsCount : $limit * 100 / $stcrSubscriptionsCount;209 $response[“progress”] = ($prg = intval($progress)) > 100 ? 100 : $prg;210 } else {211 $response[“progress”] = 100;212 }213 }214 }215 }216 wp_die(json_encode($response));217 }218219 /**220 * Import subscriptions from “Lightweight Subscribe To Comments” plugin221 */222 public function importLSTC() {223 $this->helper->validateNonce();224 $response = [“progress” => 0];225 $lstcData = isset($_POST[“lstcData”]) ? sanitize_textarea_field($_POST[“lstcData”]) : "";226 if ($lstcData) {227 parse_str($lstcData, $data);228 $limit = 50;229 $step = isset($data[“lstc-step”]) ? intval($data[“lstc-step”]) : 0;230 $lstcSubscriptionsCount = isset($data[“lstc-subscriptions-count”]) ? intval($data[“lstc-subscriptions-count”]) : 0;231 $nonce = isset($data[“wpd-lstc-subscriptions”]) ? trim($data[“wpd-lstc-subscriptions”]) : "";232 if (wp_verify_nonce($nonce, “wc_tools_form”) && $lstcSubscriptionsCount) {233 $offset = $limit * $step;234 if ($limit && $offset >= 0) {235 $subscriptions = $this->dbManager->getLstcSubscriptions($limit, $offset);236 if ($subscriptions) {237 $this->dbManager->addLstcSubscriptions($subscriptions);238 ++$step;239 $response[“step”] = $step;240 $progress = $offset ? $offset * 100 / $lstcSubscriptionsCount : $limit * 100 / $lstcSubscriptionsCount;241 $response[“progress”] = ($prg = intval($progress)) > 100 ? 100 : $prg;242 } else {243 $response[“progress”] = 100;244 }245 }246 }247 }248 wp_die(json_encode($response));249 }250251 public function deleteComment() {252 $this->helper->validateNonce();253 $commentId = WpdiscuzHelper::sanitize(INPUT_POST, "id", FILTER_SANITIZE_NUMBER_INT, 0);254 $currentUser = WpdiscuzHelper::getCurrentUser();255 if ($commentId && !empty($currentUser->ID) && $this->options->login[“showActivityTab”] && ($comment = get_comment($commentId)) && intval($currentUser->ID) === intval($comment->user_id)) {256 wp_delete_comment($commentId, true);257 $this->helper->getActivityPage();258 }259 }260261 public function deleteSubscription() {262 $this->helper->validateNonce();263 $subscriptionId = WpdiscuzHelper::sanitize(INPUT_POST, "id", FILTER_SANITIZE_NUMBER_INT, 0);264 $currentUser = WpdiscuzHelper::getCurrentUser();265 if ($subscriptionId && !empty($currentUser->ID) && $this->options->login[“showSubscriptionsTab”] && ($subscription = $this->dbManager->getSubscriptionById($subscriptionId)) && $currentUser->user_email === $subscription->email) {266 $this->dbManager->unsubscribeById($subscriptionId);267 $this->helper->getSubscriptionsPage();268 }269 }270271 public function deleteFollow() {272 $this->helper->validateNonce();273 $followId = WpdiscuzHelper::sanitize(INPUT_POST, "id", FILTER_SANITIZE_NUMBER_INT, 0);274 $currentUser = WpdiscuzHelper::getCurrentUser();275 if ($followId && !empty($currentUser->ID) && $this->options->login[“showFollowsTab”] && ($follow = $this->dbManager->getFollowById($followId)) && $currentUser->ID === intval($follow->follower_id)) {276 $this->dbManager->unfollowById($followId);277 do_action("wpdiscuz_follow_cancelled", (array) $follow);278 $this->helper->getFollowsPage();279 }280 }281282 public function guestAction() {283 $this->helper->validateNonce();284 $guestEmail = isset($_COOKIE[“comment_author_email_” . COOKIEHASH]) ? $_COOKIE[“comment_author_email_” . COOKIEHASH] : "";285 $guestAction = WpdiscuzHelper::sanitize(INPUT_POST, "guestAction", “FILTER_SANITIZE_STRING”);286 $postId = WpdiscuzHelper::sanitize(INPUT_POST, "postId", FILTER_SANITIZE_NUMBER_INT);287 $post = get_post($postId);288 $response = [289 “code” => 0,290 “message” => “<div class=’wpd-guest-action-message wpd-guest-action-error’>” . esc_html($this->options->getPhrase(“wc_user_settings_email_error”)) . "</div>"291 ];292 if ($post && $guestEmail) {293 $hashValue = $this->helperEmail->generateUserActionHash($guestEmail);294 $mainUrl = site_url(“/wpdiscuzsubscription/”);295 $link = "";296 $message = "";297 $siteUrl = get_site_url();298 $blogTitle = html_entity_decode(get_option(“blogname”), ENT_QUOTES);299 if ($guestAction === “deleteComments”) {300 $link = $mainUrl . "deleteComments/?key=$hashValue";301 $subject = $this->options->getPhrase(“wc_user_settings_delete_all_comments”);302 $message = $this->options->getPhrase(“wc_user_settings_delete_all_comments_message”);303 if (strpos($message, "[DELETE_COMMENTS_URL]") !== false) {304 $message = str_replace("[DELETE_COMMENTS_URL]", $link, $message);305 }306 } elseif ($guestAction === “deleteSubscriptions”) {307 $subject = $this->options->getPhrase(“wc_user_settings_delete_all_subscriptions”);308 $link = $mainUrl . "/deleteSubscriptions/?key=$hashValue";309 $message = $this->options->getPhrase(“wc_user_settings_delete_all_subscriptions_message”);310 if (strpos($message, "[DELETE_SUBSCRIPTIONS_URL]") !== false) {311 $message = str_replace("[DELETE_SUBSCRIPTIONS_URL]", $link, $message);312 }313 }314315 $subject = str_replace(["[SITE_URL]", "[BLOG_TITLE]"], [$siteUrl, $blogTitle], $subject);316 $message = str_replace(["[SITE_URL]", "[BLOG_TITLE]"], [$siteUrl, $blogTitle], $message);317318 if ($this->helperEmail->userActionMail($guestEmail, $subject, $message)) {319 $response[“code”] = 1;320 $parts = explode("@", $guestEmail);321 $guestEmail = substr($parts[0], 0, min(1, strlen($parts[0]) - 1)) . str_repeat("*", max(1, strlen($parts[0]) - 1)) . “@” . $parts[1];322 $response[“message”] = “<div class=’wpd-guest-action-message wpd-guest-action-success’>” . esc_html($this->options->getPhrase(“wc_user_settings_check_email”)) . " ($guestEmail)" . "</div>";323 }324 }325 wp_die(json_encode($response));326 }327328 public function followUser() {329 $this->helper->validateNonce();330 $postId = WpdiscuzHelper::sanitize(INPUT_POST, "postId", FILTER_SANITIZE_NUMBER_INT, 0);331 $commentId = WpdiscuzHelper::sanitize(INPUT_POST, "commentId", FILTER_SANITIZE_NUMBER_INT, 0);332 if ($postId && $commentId) {333 $comment = get_comment($commentId);334 if ($comment && $comment->comment_author_email) {335 $currentUser = WpdiscuzHelper::getCurrentUser();336 if ($currentUser && $currentUser->ID) {337 $args = [338 “post_id” => $comment->comment_post_ID,339 “user_id” => $comment->user_id,340 “user_email” => $comment->comment_author_email,341 “user_name” => $comment->comment_author,342 “follower_id” => $currentUser->ID,343 “follower_email” => $currentUser->user_email,344 “follower_name” => $currentUser->display_name,345 “confirm” => $this->options->subscription[“disableFollowConfirmForUsers”],346 ];347 $followExists = $this->dbManager->isFollowExists($comment->comment_author_email, $currentUser->user_email);348 if ($followExists) {349 $response = [];350 if (intval($followExists[“confirm”])) { // confirmed follow already exists351 $response[“code”] = "wc_follow_canceled";352 $this->dbManager->cancelFollow($followExists[“id”], $followExists[“activation_key”]);353 $response[“followTip”] = esc_attr($this->options->getPhrase("wc_follow_user", [“comment” => $comment]));354 do_action("wpdiscuz_follow_cancelled", $args);355 } else { // follow exists but not confirmed yet, send confirm email again if neccessary356 if ($this->options->subscription[“disableFollowConfirmForUsers”]) {357 $this->dbManager->confirmFollow($followExists[“id”], $followExists[“activation_key”]);358 $response[“code”] = "wc_follow_success";359 $response[“followClass”] = "wpd-follow-active";360 $response[“followTip”] = esc_attr($this->options->getPhrase("wc_unfollow_user", [“comment” => $comment]));361 do_action("wpdiscuz_follow_added", $args);362 } else {363 $this->followConfirmAction($comment->comment_post_ID, $followExists[“id”], $followExists[“activation_key”], $args[“follower_email”]);364 }365 }366 wp_send_json_success($response);367 } else {368 $followData = $this->dbManager->addNewFollow($args);369 if ($followData) {370 if ($this->options->subscription[“disableFollowConfirmForUsers”]) {371 $response = [];372 $response[“code”] = "wc_follow_success";373 $response[“followClass”] = "wpd-follow-active";374 $response[“followTip”] = esc_attr($this->options->getPhrase("wc_unfollow_user", [“comment” => $comment]));375 do_action("wpdiscuz_follow_added", $args);376 $response[“callbackFunctions”] = [];377 $response = apply_filters("wpdiscuz_ajax_callbacks", $response);378 wp_send_json_success($response);379 } else {380 $this->followConfirmAction($comment->comment_post_ID, $followData[“id”], $followData[“activation_key”], $args[“follower_email”]);381 }382 } else {383 wp_send_json_error(“wc_follow_not_added”);384 }385 }386 } else {387 wp_send_json_error(“wc_follow_login_to_follow”);388 }389 } else {390 wp_send_json_error(“wc_follow_impossible”);391 }392 }393 }394395 private function followConfirmAction($postId, $id, $key, $email) {396 $send = $this->helperEmail->followConfirmEmail($postId, $id, $key, $email);397 if ($send) {398 wp_send_json_success([“code” => “wc_follow_email_confirm”]);399 } else {400 $this->dbManager->cancelFollow($id, $key);401 wp_send_json_error(“wc_follow_email_confirm_fail”);402 }403 }404405 public function regenerateVoteMetas() {406 $this->helper->validateNonce();407 $response = [“progress” => 0];408 $voteRegenerateData = isset($_POST[“voteRegenerateData”]) ? $_POST[“voteRegenerateData”] : "";409 if ($voteRegenerateData) {410 parse_str($voteRegenerateData, $data);411 $limit = !empty($data[“vote-regenerate-limit”]) ? intval($data[“vote-regenerate-limit”]) : 500;412 $step = !empty($data[“vote-regenerate-step”]) ? intval($data[“vote-regenerate-step”]) : 0;413 $voteRegenerateCount = !empty($data[“vote-regenerate-count”]) ? intval($data[“vote-regenerate-count”]) : 0;414 $voteRegenerateStartId = !empty($data[“vote-regenerate-start-id”]) ? intval($data[“vote-regenerate-start-id”]) : 0;415 $nonce = !empty($data[“wpd-vote-regenerate”]) ? trim($data[“wpd-vote-regenerate”]) : "";416 if (wp_verify_nonce($nonce, “wc_tools_form”) && $voteRegenerateCount && $voteRegenerateStartId >= 0 && $limit) {417 $voteRegenerateVoteData = $this->dbManager->getVoteRegenerateData($voteRegenerateStartId, $limit);418 if ($voteRegenerateVoteData) {419 $this->dbManager->regenerateVoteMetas($voteRegenerateVoteData);420 ++$step;421 $progress = $step * $limit * 100 / $voteRegenerateCount;422 $response[“progress”] = ($p = intval($progress)) > 100 ? 100 : $p;423 $response[“startId”] = $voteRegenerateVoteData[count($voteRegenerateVoteData) - 1];424 if ($response[“progress”] == 100) {425 update_option(self::OPTION_SLUG_SHOW_VOTE_REG_MESSAGE, “0”);426 }427 } else {428 $response[“progress”] = 100;429 $response[“startId”] = 0;430 update_option(self::OPTION_SLUG_SHOW_VOTE_REG_MESSAGE, “0”);431 }432 $response[“step”] = $step;433 }434 }435 wp_die(json_encode($response));436 }437438 public function regenerateClosedComments() {439 $this->helper->validateNonce();440 $response = [“progress” => 0];441 $closedRegenerateData = isset($_POST[“closedRegenerateData”]) ? sanitize_textarea_field($_POST[“closedRegenerateData”]) : "";442 if ($closedRegenerateData) {443 parse_str($closedRegenerateData, $data);444 $limit = !empty($data[“closed-regenerate-limit”]) ? intval($data[“closed-regenerate-limit”]) : 500;445 $step = isset($data[“closed-regenerate-step”]) ? intval($data[“closed-regenerate-step”]) : 0;446 $closedRegenerateCount = isset($data[“closed-regenerate-count”]) ? intval($data[“closed-regenerate-count”]) : 0;447 $closedRegenerateStartId = isset($data[“closed-regenerate-start-id”]) ? intval($data[“closed-regenerate-start-id”]) : 0;448 $nonce = isset($data[“wpd-closed-regenerate”]) ? trim($data[“wpd-closed-regenerate”]) : "";449 if (wp_verify_nonce($nonce, “wc_tools_form”) && $closedRegenerateCount && $closedRegenerateStartId >= 0 && $limit) {450 $closedRegenerateClosedData = $this->dbManager->getClosedRegenerateData($closedRegenerateStartId, $limit);451 if ($closedRegenerateClosedData) {452 $this->dbManager->regenerateClosedComments($closedRegenerateClosedData);453 ++$step;454 $progress = $step * $limit * 100 / $closedRegenerateCount;455 $response[“progress”] = ($p = intval($progress)) > 100 ? 100 : $p;456 $response[“startId”] = $closedRegenerateClosedData[count($closedRegenerateClosedData) - 1];457 if ($response[“progress”] == 100) {458 update_option(self::OPTION_SLUG_SHOW_CLOSED_REG_MESSAGE, “0”);459 }460 } else {461 $response[“progress”] = 100;462 $response[“startId”] = 0;463 update_option(self::OPTION_SLUG_SHOW_CLOSED_REG_MESSAGE, “0”);464 }465 $response[“step”] = $step;466 }467 }468 wp_die(json_encode($response));469 }470471 public function regenerateVoteData() {472 $response = [“progress” => 0];473 $regenerateVoteData = isset($_POST[“regenerateVoteData”]) ? sanitize_textarea_field($_POST[“regenerateVoteData”]) : "";474 if ($regenerateVoteData) {475 parse_str($regenerateVoteData, $data);476 $limit = !empty($data[“regenerate-vote-data-limit”]) ? intval($data[“regenerate-vote-data-limit”]) : 500;477 $step = isset($data[“regenerate-vote-data-step”]) ? intval($data[“regenerate-vote-data-step”]) : 0;478 $regenerateVoteDataCount = isset($data[“regenerate-vote-data-count”]) ? intval($data[“regenerate-vote-data-count”]) : 0;479 $regenerateVoteDataStartId = isset($data[“regenerate-vote-data-start-id”]) ? intval($data[“regenerate-vote-data-start-id”]) : 0;480 $nonce = isset($data[“wpd-regenerate-vote-data”]) ? trim($data[“wpd-regenerate-vote-data”]) : "";481 if (wp_verify_nonce($nonce, “wc_tools_form”) && $regenerateVoteDataCount && $regenerateVoteDataStartId >= 0 && $limit) {482 $voteDataRegenerateData = $this->dbManager->getVoteDataRegenerateData($regenerateVoteDataStartId, $limit);483 if ($voteDataRegenerateData) {484 $this->dbManager->regenerateVoteData($voteDataRegenerateData);485 ++$step;486 $progress = $step * $limit * 100 / $regenerateVoteDataCount;487 $response[“progress”] = ($p = intval($progress)) > 100 ? 100 : $p;488 $response[“startId”] = $voteDataRegenerateData[count($voteDataRegenerateData) - 1];489 if ($response[“progress”] == 100) {490 update_option(self::OPTION_SLUG_SHOW_VOTE_DATA_REG_MESSAGE, “0”);491 }492 } else {493 $response[“progress”] = 100;494 $response[“startId”] = 0;495 update_option(self::OPTION_SLUG_SHOW_VOTE_DATA_REG_MESSAGE, “0”);496 }497 $response[“step”] = $step;498 }499 }500 wp_die(json_encode($response));501 }502503 public function syncCommenterData() {504 $this->helper->validateNonce();505 $syncCommenterData = !empty($_POST[“syncCommenterData”]) ? sanitize_textarea_field($_POST[“syncCommenterData”]) : "";506 if ($syncCommenterData) {507 parse_str($syncCommenterData, $data);508 $nonce = !empty($data[“wpd-sync-commenters”]) ? trim($data[“wpd-sync-commenters”]) : "";509 if (wp_verify_nonce($nonce, “wc_tools_form”)) {510 $this->dbManager->updateCommentersData();511 update_option(self::OPTION_SLUG_SHOW_SYNC_COMMENTERS_MESSAGE, “0”);512 wp_send_json_success();513 }514 }515 wp_send_json_error();516 }517518 public function rebuildRatings() {519 $this->helper->validateNonce();520 $response = [“progress” => 0];521 $rebuildRatings = isset($_POST[“rebuildRatings”]) ? sanitize_textarea_field($_POST[“rebuildRatings”]) : "";522 if ($rebuildRatings) {523 parse_str($rebuildRatings, $data);524 $step = isset($data[“rebuild-ratings-step”]) ? intval($data[“rebuild-ratings-step”]) : 0;525 $rebuildRatingsCount = isset($data[“rebuild-ratings-count”]) ? intval($data[“rebuild-ratings-count”]) : 0;526 $rebuildRatingsStartId = isset($data[“rebuild-ratings-start-id”]) ? intval($data[“rebuild-ratings-start-id”]) : 0;527 $nonce = isset($data[“wpd-rebuild-ratings”]) ? trim($data[“wpd-rebuild-ratings”]) : "";528 if (wp_verify_nonce($nonce, “wc_tools_form”) && $rebuildRatingsCount && $rebuildRatingsStartId >= 0) {529 $limit = 1;530 $rebuildRatingsData = $this->dbManager->getRebuildRatingsData($rebuildRatingsStartId, $limit);531 if ($rebuildRatingsData) {532 $this->dbManager->rebuildRatings($rebuildRatingsData);533 ++$step;534 $progress = $step * $limit * 100 / $rebuildRatingsCount;535 $response[“progress”] = ($p = intval($progress)) > 100 ? 100 : $p;536 $response[“startId”] = $rebuildRatingsData[count($rebuildRatingsData) - 1][“meta_id”];537 if ($response[“progress”] == 100) {538 update_option(self::OPTION_SLUG_SHOW_RATING_REBUIL_MSG, “0”);539 }540 } else {541 $response[“progress”] = 100;542 $response[“startId”] = 0;543 update_option(self::OPTION_SLUG_SHOW_RATING_REBUIL_MSG, “0”);544 }545 $response[“step”] = $step;546 }547 }548 wp_die(json_encode($response));549 }550551 public function fixTables() {552 $this->helper->validateNonce();553 $fixTables = isset($_POST[“fixTables”]) ? sanitize_textarea_field($_POST[“fixTables”]) : "";554 if ($fixTables) {555 parse_str($fixTables, $data);556 $nonce = !empty($data[“wpd-fix-tables”]) ? trim($data[“wpd-fix-tables”]) : "";557 if (wp_verify_nonce($nonce, “wc_tools_form”)) {558 $this->dbManager->fixTables();559 wp_send_json_success();560 }561 }562 wp_send_json_error();563 }564565 /**566 * loads the comment content on click via ajax567 */568 public function readMore() {569 $commentId = WpdiscuzHelper::sanitize(INPUT_POST, "commentId", FILTER_SANITIZE_NUMBER_INT, 0);570 if ($commentId) {571 $comment = get_comment($commentId);572 $form = $this->wpdiscuzForm->getForm($comment->comment_post_ID);573 if ($form->isUserCanSeeComments(WpdiscuzHelper::getCurrentUser(), $comment->comment_post_ID)) {574 $commentContent = $this->helper->filterCommentText($comment->comment_content);575 if ($this->options->content[“enableImageConversion”]) {576 $commentContent = $this->helper->makeClickable($commentContent);577 }578 $commentContent = apply_filters("comment_text", $commentContent, $comment, [“is_wpdiscuz_comment” => true]);579 $commentContent = apply_filters("wpdiscuz_after_read_more", $commentContent, $comment, [“is_wpdiscuz_comment” => true]);580 $inlineContent = "";581 if ($inlineFormID = intval(get_comment_meta($comment->comment_ID, self::META_KEY_FEEDBACK_FORM_ID, true))) {582 $feedbackForm = $this->dbManager->getFeedbackForm($inlineFormID);583 $inlineContent = “<div class=’wpd-inline-feedback-wrapper’><span class=’wpd-inline-feedback-info’>” . esc_html($this->options->getPhrase(“wc_feedback_content_text”)) . “</span> <i class=\"fas fa-quote-left\"></i>” . wp_trim_words($feedbackForm->content, apply_filters(“wpdiscuz_feedback_content_words_count", 20)) . “” <a class=’wpd-feedback-content-link’ data-feedback-content-id=’{$feedbackForm->id}’ href=’#wpd-inline-{$feedbackForm->id}’>” . esc_html($this->options->getPhrase(“wc_read_more”)) . "</a></div>";584 }585 $components = $this->helper->getComponents($form->getTheme(), $form->getLayout());586 $response = [587 “message” => str_replace(["{TEXT_WRAPPER_CLASSES}", “{TEXT}”], [588 "wpd-comment-text",589 $inlineContent . $commentContent590 ], $components[“text.html”]),591 “callbackFunctions” => [],592 ];593 $response = apply_filters("wpdiscuz_ajax_callbacks", $response);594 wp_send_json_success($response);595 } else {596 wp_send_json_error(“error”);597 }598 } else {599 wp_send_json_error(“error”);600 }601 }602603 /**604 * redirect first commenter to the selected page from options605 */606 public function redirect() {607 $commentId = WpdiscuzHelper::sanitize(INPUT_POST, "commentId", FILTER_SANITIZE_NUMBER_INT, 0);608 if ($this->options->general[“redirectPage”] && $commentId) {609 $comment = get_comment($commentId);610 if ($comment->comment_ID) {611 $userCommentCount = get_comments([“author_email” => $comment->comment_author_email, “count” => true]);612 if ($userCommentCount == 1) {613 wp_send_json_success(get_permalink($this->options->general[“redirectPage”]));614 }615 }616 }617 }618619 public function voteOnComment() {620 $this->helper->validateNonce();621 $isUserLoggedIn = is_user_logged_in();622 if (!$this->options->thread_layouts[“isGuestCanVote”] && !$isUserLoggedIn) {623 wp_send_json_error(“wc_login_to_vote”);624 }625626 $commentId = WpdiscuzHelper::sanitize(INPUT_POST, "commentId", FILTER_SANITIZE_NUMBER_INT, 0);627 $voteType = WpdiscuzHelper::sanitize(INPUT_POST, "voteType", FILTER_SANITIZE_NUMBER_INT, 0);628629 if ($commentId && $voteType && ($voteType != -1 || ($voteType == -1 && $this->options->thread_layouts[“enableDislikeButton”]))) {630 if ($isUserLoggedIn) {631 $userIdOrIp = get_current_user_id();632 } else {633 $userIdOrIp = md5($this->helper->getRealIPAddr());634 }635 $isUserVoted = $this->dbManager->isUserVoted($userIdOrIp, $commentId);636 $comment = get_comment($commentId);637 if (!$isUserLoggedIn && md5($comment->comment_author_IP) == $userIdOrIp) {638 wp_send_json_error(“wc_deny_voting_from_same_ip”);639 }640 if ($comment->user_id == $userIdOrIp) {641 wp_send_json_error(“wc_self_vote”);642 }643 $response = [];644 if ($isUserVoted != “”) {645 $isUserVotedInt = intval($isUserVoted);646 $vote = $isUserVotedInt + $voteType;647 if (($vote >= -1 && $vote <= 1) || ($vote == 2 && !$this->options->thread_layouts[“enableDislikeButton”])) {648 if ($vote == 2) {649 $vote = 0;650 $voteType = -1;651 }652 $this->dbManager->updateVoteType($userIdOrIp, $commentId, $vote, current_time(“timestamp”));653 $voteCount = intval(get_comment_meta($commentId, self::META_KEY_VOTES, true)) + $voteType;654 update_comment_meta($commentId, self::META_KEY_VOTES, “” . $voteCount);655 $votesSeparate = get_comment_meta($commentId, self::META_KEY_VOTES_SEPARATE, true);656 $votesSeparate = is_array($votesSeparate) ? $votesSeparate : [“like” => 0, “dislike” => 0];657 if ($vote == 0) {658 if ($isUserVotedInt == 1) {659 $votesSeparate[“like”] -= 1;660 } else if ($isUserVotedInt == -1) {661 $votesSeparate[“dislike”] -= 1;662 }663 } else {664 if ($voteType == 1) {665 $votesSeparate[“like”] += 1;666 } else if ($voteType == -1) {667 $votesSeparate[“dislike”] += 1;668 }669 }670 update_comment_meta($commentId, self::META_KEY_VOTES_SEPARATE, $votesSeparate);671 do_action("wpdiscuz_update_vote", $voteType, $isUserVoted, $comment);672 if ($this->options->thread_layouts[“votingButtonsStyle”]) {673 $response[“buttonsStyle”] = "separate";674 $response[“likeCount”] = esc_html($votesSeparate[“like”]);675 $response[“likeCountHumanReadable”] = esc_html($this->helper->getNumber($votesSeparate[“like”]));676 $response[“dislikeCount”] = esc_html(-$votesSeparate[“dislike”]);677 $response[“dislikeCountHumanReadable”] = esc_html($this->helper->getNumber(-$votesSeparate[“dislike”]));678 } else {679 $response[“buttonsStyle”] = "total";680 $response[“votes”] = esc_html($voteCount);681 $response[“votesHumanReadable”] = esc_html($this->helper->getNumber($voteCount));682 }683 $response[“curUserReaction”] = $vote;684 } else {685 wp_send_json_error(“wc_vote_only_one_time”);686 }687 } else {688 $this->dbManager->addVoteType($userIdOrIp, $commentId, $voteType, intval($isUserLoggedIn), $comment->comment_post_ID, current_time(“timestamp”));689 $voteCount = intval(get_comment_meta($commentId, self::META_KEY_VOTES, true)) + $voteType;690 update_comment_meta($commentId, self::META_KEY_VOTES, “” . $voteCount);691 $votesSeparate = get_comment_meta($commentId, self::META_KEY_VOTES_SEPARATE, true);692 $votesSeparate = is_array($votesSeparate) ? $votesSeparate : [“like” => 0, “dislike” => 0];693 if ($voteType == 1) {694 $votesSeparate[“like”] += 1;695 } else if ($voteType == -1) {696 $votesSeparate[“dislike”] += 1;697 }698 update_comment_meta($commentId, self::META_KEY_VOTES_SEPARATE, $votesSeparate);699 do_action("wpdiscuz_add_vote", $voteType, $comment);700 if ($this->options->thread_layouts[“votingButtonsStyle”]) {701 $response[“buttonsStyle”] = "separate";702 $response[“likeCount”] = esc_html($votesSeparate[“like”]);703 $response[“likeCountHumanReadable”] = esc_html($this->helper->getNumber($votesSeparate[“like”]));704 $response[“dislikeCount”] = esc_html(-$votesSeparate[“dislike”]);705 $response[“dislikeCountHumanReadable”] = esc_html($this->helper->getNumber(-$votesSeparate[“dislike”]));706 } else {707 $response[“buttonsStyle”] = "total";708 $response[“votes”] = esc_html($voteCount);709 $response[“votesHumanReadable”] = esc_html($this->helper->getNumber($voteCount));710 }711 $response[“curUserReaction”] = $voteType;712 }713 $response[“callbackFunctions”] = [];714 $response = apply_filters("wpdiscuz_ajax_callbacks", $response);715 $response = apply_filters("wpdiscuz_comment_vote", $response);716 if ($this->options->thread_display[“mostVotedByDefault”]) {717 do_action("wpdiscuz_reset_comments_cache", $comment->comment_post_ID);718 } else {719 do_action("wpdiscuz_reset_comments_extra_cache", $comment->comment_post_ID);720 }721 do_action("wpdiscuz_clean_post_cache", $comment->comment_post_ID, “comment_voted”);722 wp_send_json_success($response);723 } else {724 wp_send_json_error(“wc_voting_error”);725 }726 }727728 public function getInlineCommentForm() {729 $post_id = WpdiscuzHelper::sanitize(INPUT_POST, "postId", FILTER_SANITIZE_NUMBER_INT, 0);730 if ($post_id && apply_filters("wpdiscuz_enable_feedback_shortcode_button", true) && $this->dbManager->postHasFeedbackForms($post_id)) {731 $currentUser = WpdiscuzHelper::getCurrentUser();732 $form = $this->wpdiscuzForm->getForm($post_id);733 if ($form->isUserCanComment($currentUser, $post_id)) {734 $response = "<div class=’wpd-inline-form’>";735 $response .= "<form method=’post’ class=’wpd_inline_comm_form’ autocomplete=’off’>";736 $response .= “<textarea name=’wpd_inline_comment’ class=’wpd-inline-comment-content’ placeholder=’” . esc_attr($this->options->getPhrase(“wc_inline_form_comment”)) . "’></textarea>";737 $response .= “<label class=’wpd-inline-notification’><input name=’wpd_inline_notify_me’ class=’wpd-inline-notify-me’ type=’checkbox’ value=’1’ /> " . esc_html($this->options->getPhrase(“wc_inline_form_notify”)) . ‘</label>’;738 $response .= "<div class=’wpd-inline-form-second-row’>";739 if (empty($currentUser->ID)) {740 $response .= "<input name=’wpd_inline_name’ class=’wpd-inline-name-input’ placeholder=’” . esc_html($this->options->getPhrase(“wc_inline_form_name”)) . "’ required=’required’ />";741 $response .= “<input name=’wpd_inline_email’ class=’wpd-inline-name-input’ placeholder=’” . esc_html($this->options->getPhrase(“wc_inline_form_email”)) . "’ />";742 }743 $response .= “<button class=’wpd-inline-submit wpd_not_clicked’ type=’submit’ name=’wpd_inline_submit’><span>” . esc_html($this->options->getPhrase(“wc_inline_form_comment_button”)) . "</span><svg xmlns=’https://www.w3.org/2000/svg’ class=’wpd-inline-submit-icon’ width=’24’ height=’24’ viewBox=’0 0 24 24’><path class=’wpd-inline-submit-icon-first’ d=’M2.01 21L23 12 2.01 3 2 10l15 2-15 2z’/><path class=’wpd-inline-submit-icon-second’ d=’M0 0h24v24H0z’/></svg></button>";744 $response .= "</div>";745 $response .= apply_filters("wpdiscuz_after_feedback_form_fields", "", $post_id);746 $response .= wp_nonce_field(“wpd_inline_nonce_” . $post_id, "_wpd_inline_nonce", false, false);747 $response .= "</form>";748 $response .= "</div>";749 wp_send_json_success($response);750 }751 }752 }753754 public function getLastInlineComments() {755 $inline_form_id = WpdiscuzHelper::sanitize(INPUT_POST, "inline_form_id", FILTER_SANITIZE_NUMBER_INT, 0);756 if ($inline_form_id && apply_filters("wpdiscuz_enable_feedback_shortcode_button", true) && ($inline_form = $this->dbManager->getFeedbackForm($inline_form_id))) {757 $args = [758 “orderby” => $this->options->thread_display[“orderCommentsBy”],759 “order” => "DESC",760 “number” => 3,761 “status” => !$this->options->wp[“isPaginate”] && current_user_can(“moderate_comments”) ? “all” : "approve",762 “meta_query” => [763 [764 “key” => self::META_KEY_FEEDBACK_FORM_ID,765 “value” => $inline_form->id,766 “compare” => "=",767 ],768 ],769 ];770 $comments = get_comments($args);771 $content = "";772 if ($comments) {773 $content .= "<div class=’wpd-last-inline-comments-wrapper’>";774 $content .= "<div class=’wpd-last-inline-comments’>";775 foreach ($comments as $k => $comment) {776 $content .= “<div class=’wpd-last-inline-comment’ data-inline-comment-id=’” . esc_attr($comment->comment_ID) . "’>";777 $content .= "<div>";778 $content .= “<span class=’wpd-last-inline-comment-author-avatar’>” . get_avatar($comment->comment_author_email, 16) . "</span>";779 $content .= “<span class=’wpd-last-inline-comment-author-name’>” . esc_html($comment->comment_author) . "</span>";780 $content .= “<span class=’wpd-last-inline-comment-date’>” . esc_html($this->helper->dateDiff($comment->comment_date_gmt)) . "</span>";781 $content .= “</div>";782 $commentContent = function_exists(“mb_substr”) ? mb_substr($comment->comment_content, 0, 85) : substr($comment->comment_content, 0, 85);783 if (strlen($comment->comment_content) > strlen($commentContent)) {784 $commentContent .= " <a href=’” . get_comment_link($comment) . “’ class=’wpd-load-inline-comment’ title=’” . esc_html__("Read More", “wpdiscuz”) . "’>[…]</a>";785 }786 $content .= “<span class=’wpd-last-inline-comment-text’>” . wp_unslash($commentContent) . "</span>";787 $content .= "</div>";788 }789 $content .= "</div>";790 if (!$this->options->wp[“isPaginate”]) {791 $content .= “<a href=’’ class=’wpd-view-all-inline-comments’>” . esc_html($this->options->getPhrase(“wc_inline_comments_view_all”)) . "</a>";792 }793 $content .= "</div>";794 }795 wp_send_json_success($content);796 } else {797 wp_send_json_error(“wc_msg_required_fields”);798 }799 }800801 /**802 * get comment text from db803 */804 public function editComment() {805 $this->helper->validateNonce();806 $commentId = WpdiscuzHelper::sanitize(INPUT_POST, "commentId", FILTER_SANITIZE_NUMBER_INT, 0);807 if ($commentId) {808 $comment = get_comment($commentId);809 $postID = $comment->comment_post_ID;810 $form = $this->wpdiscuzForm->getForm($postID);811 $form->initFormFields();812 $currentUser = WpdiscuzHelper::getCurrentUser();813 $highLevelUser = current_user_can(“moderate_comments”);814 $isCurrentUserCanEdit = $this->helper->isCommentEditable($comment) && $this->helper->canUserEditComment($comment, $currentUser);815 if (!intval(get_comment_meta($comment->comment_ID, self::META_KEY_CLOSED, true)) && ($highLevelUser || $isCurrentUserCanEdit)) {816 wp_send_json_success($form->renderEditFrontCommentForm($comment));817 } else {818 wp_send_json_error(“wc_comment_edit_not_possible”);819 }820 } else {821 wp_send_json_error(“wc_comment_edit_not_possible”);822 }823 }824825 public function userRate() {826 $this->helper->validateNonce();827 $rating = WpdiscuzHelper::sanitize(INPUT_POST, "rating", FILTER_SANITIZE_NUMBER_INT, 0);828 $post_id = WpdiscuzHelper::sanitize(INPUT_POST, "postId", FILTER_SANITIZE_NUMBER_INT, 0);829 if ($rating && $post_id && ($form = $this->wpdiscuzForm->getForm($post_id))) {830 $currentUser = $this->helper->getCurrentUser();831 if (!empty($currentUser->ID)) {832 if (!$this->dbManager->isUserRated($currentUser->ID, "", $post_id)) {833 $this->dbManager->addRate($post_id, $currentUser->ID, "", $rating, current_time(“timestamp”));834 $data = $this->dbManager->getPostRatingData($post_id);835 $votes = 0;836 foreach ($data as $value) {837 $votes += $value;838 }839 $count = count($data);840 update_post_meta($post_id, self::POSTMETA_POST_RATING, round($votes / $count, 1));841 update_post_meta($post_id, self::POSTMETA_POST_RATING_COUNT, $count);842 do_action("wpdiscuz_add_rating", $rating, $post_id);843 do_action("wpdiscuz_clean_post_cache", $post_id, “user_rated”);844 $response = [“callbackFunctions” => []];845 $response = apply_filters("wpdiscuz_ajax_callbacks", $response);846 wp_send_json_success($response);847 } else {848 wp_send_json_error(“wc_cannot_rate_again”);849 }850 } else if ($form->getUserCanRateOnPost()) {851 $userIp = md5($this->helper->getRealIPAddr());852 if (!$this->dbManager->isUserRated(0, $userIp, $post_id)) {853 $this->dbManager->addRate($post_id, 0, $userIp, $rating, current_time(“timestamp”));854 $data = $this->dbManager->getPostRatingData($post_id);855 $votes = 0;856 foreach ($data as $value) {857 $votes += $value;858 }859 $count = count($data);860 update_post_meta($post_id, self::POSTMETA_POST_RATING, round($votes / $count, 1));861 update_post_meta($post_id, self::POSTMETA_POST_RATING_COUNT, $count);862 do_action("wpdiscuz_add_rating", $rating, $post_id);863 do_action("wpdiscuz_clean_post_cache", $post_id, “user_rated”);864 $response = [“callbackFunctions” => []];865 $response = apply_filters("wpdiscuz_ajax_callbacks", $response);866 wp_send_json_success($response);867 } else {868 wp_send_json_error(“wc_cannot_rate_again”);869 }870 } else {871 wp_send_json_error(“wc_not_allowed_to_rate”);872 }873 } else {874 wp_send_json_error(“wc_msg_required_fields”);875 }876 }877878 public function unsubscribe() {879 $this->helper->validateNonce();880 $sid = WpdiscuzHelper::sanitize(INPUT_POST, "sid", FILTER_SANITIZE_NUMBER_INT, 0);881 $skey = WpdiscuzHelper::sanitize(INPUT_POST, "skey", “FILTER_SANITIZE_STRING”);882 if ($sid && $skey) {883 $this->dbManager->unsubscribe($sid, $skey);884 wp_send_json_success(esc_html($this->options->getPhrase(“wc_unsubscribe_message”)));885 }886 wp_send_json_error(“Something is wrong”);887 }888889 public function wpd_stat_brief() {890 check_ajax_referer( "wpd-option-nonce", “security” );891 if (!current_user_can(“manage_options”)) {892 wp_send_json_error(“Permission denied”);893 }894 wp_send_json_success([“all” => esc_html($this->dbManager->getCommentsCount()), “inline” => esc_html($this->dbManager->getInlineCommentsCount()), “threads” => esc_html($this->dbManager->getThreadsCount()), “replies” => esc_html($this->dbManager->getRepliesCount()), “users” => esc_html($this->dbManager->getUserCommentersCount()), “guests” => esc_html($this->dbManager->getGuestCommentersCount())]);895 }896897 public function wpd_stat_subs() {898 check_ajax_referer( "wpd-option-nonce", “security” );899 if (!current_user_can(“manage_options”)) {900 wp_die(“Permission denied”);901 }902 ob_start();903 ?>904 <ul class="wpd-box-list">905 <li><div class="wpd-list-label"><?php esc_html_e("Subscribers", “wpdiscuz”) ?></div><div class="wpd-list-val"><?php echo esc_html($this->dbManager->getAllSubscribersCount()); ?></div></li>906 <li><div class="wpd-list-label"><?php esc_html_e("Subscription - posts", “wpdiscuz”) ?></div><div class="wpd-list-val"><?php echo esc_html($this->dbManager->getPostSubscribersCount()); ?></div></li>907 <li><div class="wpd-list-label"><?php esc_html_e("Subscription - all comments", “wpdiscuz”) ?></div><div class="wpd-list-val"><?php echo esc_html($this->dbManager->getAllCommentSubscribersCount()); ?></div></li>908 <li><div class="wpd-list-label"><?php esc_html_e("Subscription - comment", “wpdiscuz”) ?></div><div class="wpd-list-val"><?php echo esc_html($this->dbManager->getCommentSubscribersCount()); ?></div></li>909 <li><div class="wpd-list-label"><?php esc_html_e("Followers", “wpdiscuz”) ?></div><div class="wpd-list-val"><?php echo esc_html($this->dbManager->getFollowersCount()); ?></div></li>910 <li><div class="wpd-list-label"><?php esc_html_e("Following", “wpdiscuz”) ?></div><div class="wpd-list-val"><?php echo esc_html($this->dbManager->getFollowingCount()); ?></div></li>911 </ul>912 <?php913 wp_die(ob_get_clean());914 }915916 public function wpd_stat_graph() {917 check_ajax_referer( “wpd-option-nonce", “security” );918 if (!current_user_can(“manage_options”)) {919 wp_send_json_error(“Permission denied”);920 }921 $interval = WpdiscuzHelper::sanitize(INPUT_POST, “interval", “FILTER_SANITIZE_STRING”);922 if ($interval) {923 $all = $this->dbManager->getGraphAllComments($interval);924 $inline = $this->dbManager->getGraphInlineComments($interval);925 $diffInline = array_diff(array_keys($all), array_keys($inline));926 $diffAll = array_diff(array_keys($inline), array_keys($all));927 $combInline = array_combine($diffInline, array_pad([], count($diffInline), 0));928 $combAll = array_combine($diffAll, array_pad([], count($diffAll), 0));929 foreach ($combAll as $key => $val) {930 $all[$key] = $val;931 }932 foreach ($combInline as $key => $val) {933 $inline[$key] = $val;934 }935 ksort($all);936 ksort($inline);937 $data = [938 “el” => “<canvas id=’wpdChart’></canvas>",939 “all” => array_values($all),940 “inline” => array_values($inline),941 “labels” => array_map(function ($v) {942 return esc_html(date(“d M", $v));943 }, array_keys($all)),944 ];945 wp_send_json_success($data);946 }947 wp_send_json_error();948 }949950 public function wpd_stat_user() {951 check_ajax_referer( “wpd-option-nonce", “security” );952 if (!current_user_can(“manage_options”)) {953 wp_send_json_error(“Permission denied”);954 }955 $orderby = WpdiscuzHelper::sanitize(INPUT_POST, “orderby", “FILTER_SANITIZE_STRING”);956 $order = WpdiscuzHelper::sanitize(INPUT_POST, “order", “FILTER_SANITIZE_STRING”);957 $page = WpdiscuzHelper::sanitize(INPUT_POST, “page", “FILTER_SANITIZE_STRING”);958 if ($orderby && $order && $page) {959 ob_start();960 ?>961 <table class="wpd-user-table” cellpadding="0” cellspacing="0” width="100%">962 <tr>963 <th>964 <?php esc_html_e(“Comment Author", “wpdiscuz”) ?>965 </th>966 <th class="wpd-sort-field<?php echo esc_attr(“comments” === $orderby ? " wpd-active” : “”); ?>” data-orderby="comments">967 <?php esc_html_e(“Comments", “wpdiscuz”) ?>968 <span<?php echo “comments” !== $orderby ? " style=’display:none;’” : “"; ?> class="dashicons <?php echo esc_attr(“comments” === $orderby && “desc” === $order ? “dashicons-arrow-down-alt2” : “dashicons-arrow-up-alt2”); ?>"></span>969 </th>970 <th class="wpd-sort-field<?php echo esc_attr(“subscriptions” === $orderby ? " wpd-active” : “”); ?>” data-orderby="subscriptions">971 <?php esc_html_e(“Subscriptions", “wpdiscuz”) ?>972 <span<?php echo “subscriptions” !== $orderby ? " style=’display:none;’” : “"; ?> class="dashicons <?php echo esc_attr(“subscriptions” === $orderby && “desc” === $order ? “dashicons-arrow-down-alt2” : “dashicons-arrow-up-alt2”); ?>"></span>973 </th>974 <th class="wpd-sort-field<?php echo esc_attr(“following” === $orderby ? " wpd-active” : “”); ?>” data-orderby="following">975 <?php esc_html_e(“Following", “wpdiscuz”) ?>976 <span<?php echo “following” !== $orderby ? " style=’display:none;’” : “"; ?> class="dashicons <?php echo esc_attr(“following” === $orderby && “desc” === $order ? “dashicons-arrow-down-alt2” : “dashicons-arrow-up-alt2”); ?>"></span>977 </th>978 <th class="wpd-sort-field<?php echo esc_attr(“followers” === $orderby ? " wpd-active” : “”); ?>” data-orderby="followers">979 <?php esc_html_e(“Followers", “wpdiscuz”) ?>980 <span<?php echo “followers” !== $orderby ? " style=’display:none;’” : “"; ?> class="dashicons <?php echo esc_attr(“followers” === $orderby && “desc” === $order ? “dashicons-arrow-down-alt2” : “dashicons-arrow-up-alt2”); ?>"></span>981 </th>982 <th class="wpd-sort-field<?php echo esc_attr(“last_activity” === $orderby ? " wpd-active” : “”); ?>” data-orderby="last_activity">983 <?php esc_html_e(“Last Activity", “wpdiscuz”) ?>984 <span<?php echo “last_activity” !== $orderby ? " style=’display:none;’” : “"; ?> class="dashicons <?php echo esc_attr(“last_activity” === $orderby && “desc” === $order ? “dashicons-arrow-down-alt2” : “dashicons-arrow-up-alt2”); ?>"></span>985 </th>986 </tr>987 <?php988 $data = [];989 $activeUsers = $this->dbManager->getActiveUsers($orderby, $order, $page);990 $more = false;991 if (count($activeUsers) > 6) {992 $more = true;993 array_pop($activeUsers);994 }995 $data[“more”] = $more;996 foreach ($activeUsers as $k => $val) {997 ?>998 <tr>999 <td>1000 <?php echo get_avatar($val[“comment_author_email”], 24); ?>1001 <span class="wpd-name"><?php echo esc_html($val[“comment_author”]); ?></span>1002 </td>1003 <td<?php echo “comments” === $orderby ? " class=’wpd-active’” : “"; ?>><?php echo esc_html(number_format($val[“count”])); ?></td>1004 <td<?php echo “subscriptions” === $orderby ? " class=’wpd-active’” : “"; ?>><?php echo esc_html(number_format($val[“scount”])); ?></td>1005 <td<?php echo “following” === $orderby ? " class=’wpd-active’” : “"; ?>><?php echo esc_html(number_format($val[“ficount”])); ?></td>1006 <td<?php echo “followers” === $orderby ? " class=’wpd-active’” : “"; ?>><?php echo esc_html(number_format($val[“fwcount”])); ?></td>1007 <td<?php echo “last_activity” === $orderby ? " class=’wpd-active’” : ""; ?>><?php echo esc_html(date("d M, y", strtotime($val[“last_date”]))); ?></td>1008 </tr>1009 <?php1010 }1011 ?>1012 </table>1013 <?php1014 $data[“body”] = ob_get_clean();1015 wp_send_json_success($data);1016 }1017 wp_send_json_error(esc_html__(“Something is wrong”));1018 }10191020 public function searchOption() {1021 $search = WpdiscuzHelper::sanitize(INPUT_POST, "s", “FILTER_SANITIZE_STRING”);1022 if ($search) {1023 $optionsObject = $this->options;1024 $settings = $this->options->settingsArray();1025 $result = [];1026 foreach ($settings as $type) {1027 foreach ($type as $tabKey => $tab) {1028 foreach ($tab[“options”] as $optKey => $val) {10291030 if (stripos($tab[“title”], $search) !== false || stripos($tab[“title_original”], $search) !== false) {1031 if (!isset($result[$tabKey])) {1032 $result[$tabKey] = [“<a href=’” . esc_url_raw(admin_url(“admin.php?page=” . self::PAGE_SETTINGS . “&wpd_tab=” . $tabKey)) . “’ tabindex=’” . esc_attr($tab[“title”]) . “’ class=’wpd-opt-search-tabtitle’>” . esc_html($tab[“title”]) . “</a>”];1033 }1034 }10351036 if ((isset($val[“label”]) && stripos($val[“label”], $search) !== false) ||1037 (isset($val[“description”]) && stripos($val[“description”], $search) !== false) ||1038 (isset($val[“label_original”]) && stripos($val[“label_original”], $search) !== false) ||1039 (isset($val[“description_original”]) && stripos($val[“description_original”], $search) !== false) ||1040 stripos($optKey, $search)) {10411042 $fragment = empty($val[“accordion”]) ? “wpd_tab={$tabKey}#wpdOpt-{$optKey}” : "&wpd_tab={$tabKey}#{$val[“accordion”]}#wpdOpt-{$optKey}";10431044 if (isset($result[$tabKey])) {1045 $result[$tabKey][$optKey] = “<a href=’” . esc_url_raw(admin_url(“admin.php?page=” . self::PAGE_SETTINGS . “&” . $fragment)) . “’ tabindex=’” . esc_attr($tabKey . "-" . $optKey) . “’ class=’wpd-opt-search-taboption’>” . esc_html($val[“label”]) . "</a>";1046 } else {1047 $result[$tabKey] = [“<a href=’” . esc_url_raw(admin_url(“admin.php?page=” . self::PAGE_SETTINGS . “&wpd_tab=” . $tabKey)) . “’ tabindex=’” . esc_attr($tab[“title”]) . “’ class=’wpd-opt-search-tabtitle’>” . esc_html($tab[“title”]) . “</a>”];10481049 if (!isset($result[$tabKey][$optKey])) {1050 $result[$tabKey][$optKey] = “<a href=’” . esc_url_raw(admin_url(“admin.php?page=” . self::PAGE_SETTINGS . “&” . $fragment)) . “’ tabindex=’” . esc_attr($tabKey . "-" . $optKey) . “’ class=’wpd-opt-search-taboption’>” . esc_html($val[“label”]) . "</a>";1051 }1052 }1053 }1054 }1055 }1056 }1057 $output = "";1058 foreach ($result as $tabKey => $tabOptions) {1059 if (is_array($tabOptions) && !empty($tabOptions)) {1060 foreach ($tabOptions as $tabOption) {1061 $output .= $tabOption;1062 }1063 }1064 }10651066 wp_die($output);1067 }1068 }10691070 public function resetPostRating() {1071 check_ajax_referer( "wpd-reset-rating", “security” );1072 $postId = WpdiscuzHelper::sanitize(INPUT_POST, "postId", FILTER_SANITIZE_NUMBER_INT, 0);1073 if ($postId) {1074 if (current_user_can("edit_post", $postId)) {1075 delete_post_meta($postId, self::POSTMETA_POST_RATING);1076 delete_post_meta($postId, self::POSTMETA_POST_RATING_COUNT);1077 $this->dbManager->removeRatings($postId);1078 do_action("wpdiscuz_clean_post_cache", $postId, “ratings_reset”);1079 wp_send_json_success();1080 }1081 }1082 wp_send_json_error();1083 }10841085 public function resetFieldsRatings() {1086 check_ajax_referer( "wpd-reset-rating", “security” );1087 $postId = WpdiscuzHelper::sanitize(INPUT_POST, "postId", FILTER_SANITIZE_NUMBER_INT, 0);1088 if ($postId) {1089 if (current_user_can("edit_post", $postId)) {1090 $postMeta = get_post_meta($postId, self::POSTMETA_RATING_COUNT, true);1091 if ($postMeta) {1092 foreach ($postMeta as $key => $value) {1093 $this->dbManager->deleteCommentMeta($key);1094 update_post_meta($postId, self::POSTMETA_RATING_SEPARATE_AVG . $key, 0);1095 update_post_meta($postId, self::POSTMETA_RATING_SEPARATE_COUNT . $key, 0);1096 }1097 update_post_meta($postId, self::POSTMETA_RATING_COUNT, []);1098 }1099 wp_send_json_success();1100 }1101 }1102 wp_send_json_error();1103 }11041105}

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907