=== Init Review System – Reactions, Multi-Criteria, Guest-Friendly === Contributors: brokensmile.2103 Tags: review, rating, vote, reaction, schema Requires at least: 5.5 Tested up to: 7.0 Requires PHP: 7.4 Stable tag: 1.18.2 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Fast 5-star rating plugin with schema, REST API, shortcode control, localStorage voting. Now with multi-criteria review support. == Description == **Init Review System** adds a clean and customizable 5-star rating system to your WordPress site. Votes are stored via REST API, tracked with `localStorage`, and the average score is auto-calculated and optionally displayed with schema markup. Built to be lightweight, developer-friendly, and easy to integrate into any theme or custom UI. Now with **multi-criteria reviews** and an **emoji reactions system** for richer user interaction. This plugin is part of the [Init Plugin Suite](https://en.inithtml.com/init-plugin-suite-minimalist-powerful-and-free-wordpress-plugins/) — a collection of minimalist, fast, and developer-focused tools for WordPress. GitHub repository: [https://github.com/brokensmile2103/init-review-system](https://github.com/brokensmile2103/init-review-system) **Highlights:** - 5-star voting via frontend - **NEW: Multi-criteria review support** - **NEW: Emoji Reactions with Login Enforcement** - Average score display - Optional login requirement - Optional strict IP checking - REST API for vote submission - JSON-LD schema for SEO - Works with any post type - Minimal, theme-friendly UI == Features == - 5-star rating system - Multi-criteria review scoring (up to 5 custom criteria) - Emoji-based reactions bar with live counts (requires login) - REST API endpoint for reactions: `/wp-json/initrsys/v1/reactions/toggle` - Reactions stored in both post meta and dedicated user↔post mapping table - Accessibility-ready with `aria-pressed` + `aria-live` updates - Shortcode-based integration - Auto-insert blocks before/after content or comments - Optional login + IP check to prevent abuse - REST API endpoint: `/wp-json/initrsys/v1/vote` - Developer filters and extensible architecture - No jQuery, only minimal assets loaded when needed == Usage == === [init_review_system] === Displays interactive 5-star voting block. Attributes: - `id`: Post ID (default: current post) - `class`: Custom CSS class - `schema`: `true|false` – Output JSON-LD schema markup === [init_review_score] === Displays average score (read-only). Attributes: - `id`: Post ID (default: current post) - `icon`: `true|false` – Show star icon (default: false) - `sub`: `true|false` – Show `/5` subtext (default: true) - `class`: Custom CSS class - `hide_if_empty`: `true|false` – Hide if no reviews (default: false) === [init_review_criteria] === Displays multi-criteria review block. Attributes: - `id`: Post ID (default: current post) - `class`: Custom CSS class - `schema`: `true|false` – Output schema markup (default: false) - `per_page`: Number of reviews to show (default: 0 = all) - `paged`: Current review page number (default: 1) === [init_reactions] === Displays emoji reactions bar under a post. Attributes: - `id`: Post ID (default: current post) - `class`: Custom CSS class - `require_login`: Always true (login required) == Filters for Developers == This plugin provides filters and actions to let developers customize auto-insert behavior, schema output, review permissions, and REST API logic. **`init_plugin_suite_review_system_auto_insert_enabled_score`** Enable or disable automatic score output (before/after content). **Applies to:** Frontend filter **Params:** `bool $enabled`, `string $position`, `string $post_type` **`init_plugin_suite_review_system_auto_insert_enabled_vote`** Enable or disable automatic voting block insertion. **Applies to:** Frontend filter **Params:** `bool $enabled`, `string $position`, `string $post_type` **`init_plugin_suite_review_system_default_score_shortcode`** Change the default shortcode used for score auto-insertion. **Applies to:** Frontend **Params:** `string $shortcode` **`init_plugin_suite_review_system_default_vote_shortcode`** Change the default shortcode used for voting block auto-insertion. **Applies to:** Frontend **Params:** `string $shortcode` **`init_plugin_suite_review_system_require_login`** Force login for submitting reviews, even if disabled in settings. **Applies to:** REST `/submit-criteria-review` **Params:** `bool $require_login` **`init_plugin_suite_review_system_min_len_for_ws_check`** Adjust minimum length threshold for triggering no-whitespace check. **Applies to:** Backend + JS precheck **Params:** `int $threshold` (default `20`) **`init_plugin_suite_review_system_repetition_threshold`** Adjust repetition threshold for detecting excessive word repetition. **Applies to:** Backend + JS precheck **Params:** `int $threshold` (default `8`) **`init_plugin_suite_review_system_schema_type`** Customize schema.org type (e.g., `Book`, `Product`, `Course`). **Applies to:** Shortcode output **Params:** `string $type`, `string $post_type` **`init_plugin_suite_review_system_schema_data`** Modify JSON-LD schema output array. **Applies to:** Shortcode output **Params:** `array $data`, `int $post_id`, `string $schema_type` **`init_plugin_suite_review_system_after_vote`** Run custom logic after a single-star vote is submitted. **Applies to:** REST `/vote` **Params:** `int $post_id`, `float $score`, `float $avg_score`, `int $total_votes` **`init_plugin_suite_review_system_after_criteria_review`** Trigger custom logic after a multi-criteria review is submitted. **Applies to:** REST `/submit-criteria-review` **Params:** `int $post_id`, `int $user_id`, `float $avg_score`, `string $review_content`, `array $scores` **`init_plugin_suite_review_system_get_reaction_types`** Customize available reaction types (labels + emojis). **Applies to:** Reactions system **Params:** `array $types` **`init_plugin_suite_review_system_reaction_meta_key`** Customize the meta key used for storing reaction counts. **Applies to:** Reaction counts storage **Params:** `string $meta_key`, `string $rx_key` **`init_plugin_suite_review_system_ttl`** Set TTL (in seconds) for object cache on review queries. Defaults to `0` (cache disabled). Set a value greater than `0` to enable caching via `wp_cache_set` with group `init_review_system`. **Applies to:** REST get reviews, get total reviews **Params:** `int $ttl` (default `0`) == Screenshots == 1. **Plugin Settings Page** – Configure general options like login requirement, IP restriction, auto-display position, and up to 5 custom criteria fields. 2. **Single-Star Rating Display** – Star-based rating shown on a post with average score and vote count. 3. **Multi-Criteria Review Display** – Frontend layout showing score breakdown per criteria and full user review content. 4. **Reactions Bar** – Emoji-based reactions under the post, showing total counts, current user reaction highlight, and requiring login to interact. == Installation == 1. Upload plugin to `/wp-content/plugins/` 2. Activate via Plugins menu 3. Go to **Settings > Init Review System** to configure options == FAQ == = Is login required to vote? = Not by default. You can enable it in plugin settings. = Does it support IP protection? = Yes. You can enable strict IP check to prevent duplicate votes. = Can I use this with custom post types? = Yes, it works with any post type that uses `the_content()` or `comment_form()`. = Does it support multi-criteria reviews? = Yes. You can define up to 5 custom criteria and show them using the provided shortcode. = Does it support 10-star ratings? = No. The plugin currently supports only a 5-star scale. == Changelog == = 1.18 – April 21, 2026 = - Fixed `admin_init` running database table checks on every admin page load - Introduced `irs_plugin_db_version` option flag to gate table checks behind a version comparison - Table creation now only runs when stored DB version is lower than current plugin version - Added `register_activation_hook` to handle fresh installs and multisite network activation - Added `wpmu_new_blog` hook to provision tables automatically on new multisite subsite creation - Added `upgrader_process_complete` hook to reset version flag after plugin update, triggering re-check on next admin load = 1.17 – March 25, 2026 = - Added object cache (1 hour TTL) to `init_plugin_suite_review_system_get_score_summary_by_post_id()` - Added object cache (1 hour TTL) to `init_plugin_suite_review_system_has_user_reviewed()` - Added object cache (1 hour TTL) to `init_plugin_suite_review_system_get_user_reaction()` - Cache for `has_user_reviewed` and `get_user_reaction` stores sentinel values to distinguish cache miss from negative results - Cache invalidation for score summary and has-reviewed fires on `init_plugin_suite_review_system_after_insert` action hook - Cache invalidation for user reaction fires inside `init_plugin_suite_review_system_apply_user_reaction()` after each write = 1.16 – March 1, 2026 = - Fixed Load More showing wrong user avatar and display name - Fixed post-submit review rendering hardcoded HTML incompatible with custom templates - Added `review-item.php` as standalone overridable template - Added `init_plugin_suite_review_system_get_criteria_by_post_id()` helper - Added `init_plugin_suite_review_system_get_review_by_id()` helper - REST endpoints now server-render review HTML; JS only injects, no longer builds DOM - Removed unused `insertNewReview()` JS function = 1.15 – February 25, 2026 = - Added `$per_page` cap (max 100) in REST endpoint to prevent excessive data queries - Added `init_plugin_suite_review_system_ttl` filter (default `0`) to opt-in object cache for review queries - When TTL > 0, query results are cached via `wp_cache_set` with group `init_review_system` - Cache invalidation can be handled via `init_plugin_suite_review_system_after_insert` action hook = 1.14 – January 29, 2026 = - Introduced **Bayesian Weighted Rating** for reliable ranking calculations - New derived meta key `_init_review_weighted` generated **on vote submission** - Prevents low-sample bias (e.g. 1×5★ no longer outranks 1000×4.9★) - Uses configurable minimum vote threshold via filter `init_plugin_suite_review_system_min_votes_threshold` - Rating architecture improvements: - Weighted score is calculated **on-write** (at REST endpoint), not at query time - Establishes clear separation between **raw data** and **ranking data** - Plugin now acts as the single source of truth for rating-based sorting - Performance & stability: - Global average rating is cached using **transients** for cross-environment reliability - Automatic transient invalidation on new vote to prevent stale calculations - Developer experience: - Enhanced `init_plugin_suite_review_system_after_vote` hook now passes: - New average score - Total vote count - Weighted ranking score - Fully backward compatible — no changes required for existing consumers - No UI or frontend behavior changes - No breaking changes to REST API responses = 1.13 – January 19, 2026 = - Added `.dark` modifier for `.init-reaction-bar` to support Dark Mode - Improved visual contrast for reactions in dark environments - Polished hover, active and disabled states in Dark Mode - Pure CSS enhancement, no JS or logic changes = 1.12 – November 14, 2025 = - Added **anti–double-submit protection** to the front-end rating widget - New `isSubmitting` state prevents rapid multi-clicks from firing multiple requests - Fully compatible with both **single-click** and **double-click confirmation** modes - Pending hover logic (`.hovering`) remains intact with zero behavior changes - Improved client-side stability: - Ensures only **one** vote request is sent at a time - Allows retrying when the API returns an error (non-blocking UX) - No changes to REST API, server logic, or existing rating flow — fully backward compatible = 1.11 – November 5, 2025 = - Added **User Review Fetching API** - New function `init_plugin_suite_review_system_get_reviews_by_user_id()` - Supports pagination (`paged`, `per_page`) just like the post-based fetcher - Automatically joins with `wp_posts` to **exclude orphaned reviews** - Returns unserialized `criteria_scores` for direct UI rendering - Added **Total Pages Counter for User Reviews** - New function `init_plugin_suite_review_system_get_total_pages_by_user_id()` - Counts reviews belonging to a specific user (filtered by `status`) - Returns the total number of pages (minimum value: `1` for UX consistency) - Performance and internal improvements: - Consistent sanitization and safety (`absint()`, `max()`, typed values) - All SQL queries use `$wpdb->prepare()` — no unbound parameters - PHPCS/WPCS compliant and follows plugin prefix standard = 1.10 – November 3, 2025 = - Added **Admin Reset & Manual Score Adjustment Metabox** - Visible **only when a post already has rating data** - New UI: compact **stat chips** showing Avg / Votes / Total (premium-style mini cards) - Supports manual override: admin can set **Average (0–5)** and **Vote Count** - Internal logic auto-calculates `Total = Avg × Count` (rounded to 2 decimals) - All displayed values are fully escaped (`esc_html() / esc_attr()`) following PHPCS - Metabox is registered **per-post**, not globally — zero UI clutter - Security and permissions: - Only users with capability `edit_others_posts` (**Editor+**) can view or interact with the metabox - `save_post` handler validates **nonce + capability**, protects against unauthorized POST submissions - Input sanitized: `sanitize_text_field( wp_unslash() )` before casting to float/int - UX improvements: - No inline `