--- a/review-for-discount/admin/class-xswcrd-review-discounts-admin.php
+++ b/review-for-discount/admin/class-xswcrd-review-discounts-admin.php
@@ -161,22 +161,19 @@
'not_found' => esc_html__( 'No Review Discount found', 'review-for-discount' ),
'not_found_in_trash' => esc_html__( 'No Review Discount found in trash', 'review-for-discount' ),
),
- 'public' => true,
+ 'public' => false,
'supports' => array( 'title' ),
'show_ui' => true,
- 'capability_type' => 'post',
+ 'capability_type' => array( 'review_discount', 'review_discounts' ),
+ 'map_meta_cap' => true,
'show_in_menu' => true,
'menu_icon' => 'dashicons-awards',
- 'map_meta_cap' => true,
- 'publicly_queryable' => true,
- 'exclude_from_search' => false,
+ 'publicly_queryable' => false,
+ 'exclude_from_search' => true,
'hierarchical' => false,
- 'rewrite' => array(
- 'slug' => 'xswc-review-discount',
- 'with_front' => true,
- ),
+ 'rewrite' => false,
'query_var' => false,
- 'has_archive' => 'false',
+ 'has_archive' => false,
)
);
@@ -423,9 +420,15 @@
* @since 1.0.0
*/
public function xswcrd_send_test_email() {
+ // Verify nonce for CSRF protection.
if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ?? '' ) ), 'xswcrd_test_email' ) ) {
wp_die( 'Security check failed.' );
}
+
+ // Verify user has admin capabilities - fixes CVE-2025-14070.
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_die( 'Insufficient permissions.' );
+ }
global $current_user;
$email_common_strings = new XSWCRD_Review_Discounts_Email_Strings( $this->wc_review_discounts, $this->version );
$email_strings = $email_common_strings->get_email_strings();
@@ -599,6 +602,12 @@
* @since 1.0.0
*/
public function xs_send_mail() {
+ // Verify user has admin capabilities.
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_send_json( array( 'status' => false ) );
+ wp_die();
+ }
+
$data = array();
if ( isset( $_POST['nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'xswcrd_test_email' ) && isset( $_POST['data'] ) && ! empty( $_POST['data'] ) ) {
parse_str( sanitize_text_field( wp_unslash( $_POST['data'] ) ), $data );
--- a/review-for-discount/includes/class-xswcrd-review-discounts-activator.php
+++ b/review-for-discount/includes/class-xswcrd-review-discounts-activator.php
@@ -29,6 +29,29 @@
* @since 1.0.0
*/
public static function xswcrd_activate() {
+ $roles = array( 'administrator', 'shop_manager' );
+
+ $caps = array(
+ 'edit_review_discount',
+ 'read_review_discount',
+ 'delete_review_discount',
+ 'edit_review_discounts',
+ 'edit_others_review_discounts',
+ 'publish_review_discounts',
+ 'read_private_review_discounts',
+ 'delete_review_discounts',
+ );
+
+ foreach ( $roles as $role_name ) {
+ $role = get_role( $role_name );
+ if ( ! $role ) {
+ continue;
+ }
+
+ foreach ( $caps as $cap ) {
+ $role->add_cap( $cap );
+ }
+ }
$default_settings = array(
'enable' => 'on',
'email_notices' => array( '1', '2', '3', '4' ),
--- a/review-for-discount/includes/class-xswcrd-review-discounts.php
+++ b/review-for-discount/includes/class-xswcrd-review-discounts.php
@@ -66,8 +66,8 @@
* @since 1.0.0
*/
public function __construct() {
- if ( defined( 'WC_REVIEW_DISCOUNTS_VERSION' ) ) {
- $this->version = WC_REVIEW_DISCOUNTS_VERSION;
+ if ( defined( 'XSWCRD_REVIEW_DISCOUNTS_VERSION' ) ) {
+ $this->version = XSWCRD_REVIEW_DISCOUNTS_VERSION;
} else {
$this->version = '1.0.0';
}
--- a/review-for-discount/photo-review-diagnostic.php
+++ b/review-for-discount/photo-review-diagnostic.php
@@ -1,106 +0,0 @@
-<?php
-/**
- * Photo Review Diagnostic Script
- *
- * This script helps diagnose common issues with the photo review functionality
- * Run this by adding ?photo_debug=1 to any product page URL while logged in as admin
- *
- * @link https://xfinitysoft.com
- * @since 1.0.0
- * @package WC_Review_Discounts
- */
-
-if ( ! defined( 'ABSPATH' ) ) {
- exit;
-}
-
-if ( ! is_admin() && ! current_user_can( 'manage_options' ) ) {
- return;
-}
-//phpcs:ignore
-if ( ! isset( $_GET['photo_debug'] ) || '1' !== sanitize_text_field( $_GET['photo_debug'] ) ) {
- return;
-}
-
-echo '<div style="background: #fff; padding: 20px; border: 1px solid #ddd; margin: 20px 0;">';
-echo '<h2>Photo Review Diagnostic Report</h2>';
-
-// Check if photo reviews are enabled.
-$xswcrd_settings = get_option( 'xswcrd_photo_settings', array() );
-echo '<h3>Settings Status:</h3>';
-echo '<ul>';
-echo '<li><strong>Photo Reviews Enabled:</strong> ' . ( empty( $xswcrd_settings ) || ( isset( $xswcrd_settings['enable_photo_review'] ) && 'on' === $xswcrd_settings['enable_photo_review'] ) ? 'YES' : 'NO' ) . '</li>';
-echo '<li><strong>Max Files:</strong> ' . ( isset( $xswcrd_settings['max_files'] ) ? esc_html( $xswcrd_settings['max_files'] ) : '3 (default)' ) . '</li>';
-echo '<li><strong>Edit Enabled:</strong> ' . ( isset( $xswcrd_settings['enable_edit'] ) && 'on' === $xswcrd_settings['enable_edit'] ? 'YES' : 'NO' ) . '</li>';
-echo '<li><strong>Voting Enabled:</strong> ' . ( isset( $xswcrd_settings['enable_voting'] ) && 'on' === $xswcrd_settings['enable_voting'] ? 'YES' : 'NO' ) . '</li>';
-echo '</ul>';
-
-// Check file upload capabilities.
-echo '<h3>Server Configuration:</h3>';
-echo '<ul>';
-echo '<li><strong>Upload Max Filesize:</strong> ' . esc_html( ini_get( 'upload_max_filesize' ) ) . '</li>';
-echo '<li><strong>Post Max Size:</strong> ' . esc_html( ini_get( 'post_max_size' ) ) . '</li>';
-echo '<li><strong>Max File Uploads:</strong> ' . esc_html( ini_get( 'max_file_uploads' ) ) . '</li>';
-echo '<li><strong>Memory Limit:</strong> ' . esc_html( ini_get( 'memory_limit' ) ) . '</li>';
-echo '</ul>';
-
-// Check if required files exist.
-echo '<h3>Required Files:</h3>';
-$xswcrd_required_files = array(
- 'Photo Reviews Class' => plugin_dir_path( __DIR__ ) . 'includes/class-wc-photo-reviews.php',
- 'Photo Reviews CSS' => plugin_dir_path( __DIR__ ) . 'public/css/wc-photo-reviews-public.css',
- 'Photo Reviews JS' => plugin_dir_path( __DIR__ ) . 'public/js/wc-photo-reviews-public.js',
- 'Photo Reviews Summary' => plugin_dir_path( __DIR__ ) . 'public/partials/photo-reviews-summary.php',
- 'Admin Display' => plugin_dir_path( __DIR__ ) . 'admin/partials/wc-photo-reviews-admin-display.php',
-);
-
-echo '<ul>';
-foreach ( $xswcrd_required_files as $xswcrd_name => $xswcrd_path ) {
- echo '<li><strong>' . esc_html( $xswcrd_name ) . ':</strong> ' . ( file_exists( $xswcrd_path ) ? 'EXISTS' : '<span style="color:red;">MISSING</span>' ) . '</li>';
-}
-echo '</ul>';
-
-// Check WordPress media settings.
-echo '<h3>WordPress Media Settings:</h3>';
-echo '<ul>';
-$xswcrd_upload_dir = wp_upload_dir();
-echo '<li><strong>Upload Directory:</strong> ' . ( $xswcrd_upload_dir['error'] ? '<span style="color:red;">' . esc_html( $xswcrd_upload_dir['error'] ) . '</span>' : esc_html( $xswcrd_upload_dir['path'] ) ) . '</li>';
-//phpcs:ignore
-echo '<li><strong>Directory Writable:</strong> ' . ( is_writable( $xswcrd_upload_dir['path'] ) ? 'YES' : '<span style="color:red;">NO</span>' ) . '</li>';
-echo '</ul>';
-
-// Check for JavaScript errors (simple check).
-echo '<h3>JavaScript Check:</h3>';
-echo '<script>';
-echo 'console.log("Photo Review Debug: jQuery available -", typeof jQuery !== "undefined");';
-echo 'console.log("Photo Review Debug: PhotoReviews object -", typeof PhotoReviews !== "undefined");';
-echo 'console.log("Photo Review Debug: xswcrd_photo_ajax -", typeof xswcrd_photo_ajax !== "undefined");';
-echo '</script>';
-echo '<p><em>Check browser console for JavaScript diagnostic messages.</em></p>';
-
-// Test photo review statistics.
-global $wpdb;
-//phpcs:ignore
-$total_reviews = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->comments} WHERE comment_type = 'review' AND comment_approved = '1'" );
-//phpcs:ignore
-$photo_reviews = $wpdb->get_var( "SELECT COUNT(DISTINCT comment_id) FROM {$wpdb->commentmeta} WHERE meta_key = 'xswcrd_review_media_id'" );
-
-echo '<h3>Review Statistics:</h3>';
-echo '<ul>';
-echo '<li><strong>Total Reviews:</strong> ' . intval( $total_reviews ) . '</li>';
-echo '<li><strong>Reviews with Media:</strong> ' . intval( $photo_reviews ) . '</li>';
-echo '</ul>';
-
-// Quick fix suggestions.
-echo '<h3>Common Solutions:</h3>';
-echo '<ol>';
-echo '<li><strong>Enable Photo Reviews:</strong> Go to WooCommerce → Review Discounts → Photo Reviews and enable the feature.</li>';
-echo '<li><strong>Check File Permissions:</strong> Ensure wp-content/uploads directory is writable (755 or 777).</li>';
-echo '<li><strong>Clear Cache:</strong> Clear any caching plugins and browser cache.</li>';
-echo '<li><strong>JavaScript Errors:</strong> Check browser console for errors and resolve conflicts with other plugins.</li>';
-echo '<li><strong>Theme Compatibility:</strong> Ensure your theme supports WooCommerce review forms properly.</li>';
-echo '<li><strong>Server Limits:</strong> Increase PHP upload limits if files are being rejected.</li>';
-echo '</ol>';
-
-echo '<p><em>This diagnostic can be run by adding ?photo_debug=1 to any product page URL while logged in as admin.</em></p>';
-echo '</div>';
--- a/review-for-discount/review-for-review.php
+++ b/review-for-discount/review-for-review.php
@@ -14,7 +14,7 @@
* @wordpress-plugin
* Plugin Name: Reviewify — Review Discounts & Photo/Video Reviews for WooCommerce
* Description: Give customers discount coupons for reviews via automated emails and enable photo and video reviews for WooCommerce.
- * Version: 1.0.7
+ * Version: 1.0.8
* Author: XfinitySoft
* Author URI: https://xfinitysoft.com/
* Text Domain: review-for-discount
@@ -23,7 +23,7 @@
* Requires at least: 5.0
* Tested up to: 6.9
* WC requires at least: 5.0.
- * WC tested up to: 10.2
+ * WC tested up to: 10.4
* License: GPLv2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/
@@ -52,11 +52,8 @@
}
);
-if ( ! defined( 'WC_REVIEW_DISCOUNTS_VERSION' ) ) {
- define( 'WC_REVIEW_DISCOUNTS_VERSION', '1.0.6' );
-}
if ( ! defined( 'XSWCRD_REVIEW_DISCOUNTS_VERSION' ) ) {
- define( 'XSWCRD_REVIEW_DISCOUNTS_VERSION', '1.0.6' );
+ define( 'XSWCRD_REVIEW_DISCOUNTS_VERSION', '1.0.8' );
}
if ( ! defined( 'XSWCRD_ROOT_URL' ) ) {
define( 'XSWCRD_ROOT_URL', plugins_url( '', __FILE__ ) );