Skip to content

Releases: wpraffle/wpraffle

1.1.0 - Security Improvement

12 Jun 16:57
a94dc2c

Choose a tag to compare

WPRaffle v1.1.0 Release Notes

Release Date: June 2026
Version: 1.1.0
Previous Version: 1.0.0


Security Audit Fixes

This release includes a comprehensive security audit with fixes across the entire codebase, following WordPress Coding Standards and OWASP best practices.

Input Sanitisation

  • SEC-01: All $_POST, $_GET, and $_REQUEST values now use appropriate sanitisation functions (sanitize_text_field, absint, floatval, sanitize_email, esc_url_raw, sanitize_hex_color, wp_kses_post)
  • SEC-02: Added wp_unslash() before sanitisation to prevent double-escaping from WordPress magic quotes
  • SEC-03: Explicit (array) casts on $_POST fields expected to be arrays (categories, tags, FAQ items)

Output Escaping

  • SEC-04: All dynamic output in admin views and public views now uses esc_html(), esc_attr(), esc_url(), and esc_textarea()
  • SEC-05: JavaScript inline data properly escaped with esc_attr()
  • SEC-06: CSS background-image URLs escaped with esc_url()

CSRF Protection

  • SEC-07: All admin forms use wp_nonce_field() with verification via wp_verify_nonce()
  • SEC-08: All AJAX endpoints verify nonces before processing
  • SEC-09: Unique nonce action names per form to prevent cross-form replay attacks

SQL Injection Prevention

  • SEC-10: All queries use $wpdb->prepare() with proper placeholders
  • SEC-11: Table names derived from $wpdb->prefix (never user input)
  • SEC-12: Dynamic IN() clauses use array_fill() with prepared placeholders instead of string concatenation

Access Control

  • SEC-13: All admin handlers verify current_user_can('manage_options')
  • SEC-14: AJAX handlers check authentication context appropriately
  • SEC-15: Direct PHP file access prevented via ABSPATH constant checks

Privacy & Data Protection

  • SEC-16: New class-raffle-privacy.php — WordPress Privacy API integration
    • Personal data export (wp_privacy_personal_data_exporters hook)
    • Personal data erasure (wp_privacy_personal_data_erasers hook)
    • Covers all 5 tables containing user data (purchases, tickets, instant wins, referrals, free entries)
    • Supports email-based GDPR subject access requests

Rate Limiting

  • SEC-17: New class-raffle-rate-limiter.php — Standalone rate limiter class
    • Per-IP, per-action rate limiting using WordPress transients
    • Configurable window and limit
    • Applied to purchase AJAX, free entry submission, and other public endpoints

Bug Fixes

Critical

  • BUG-1: Raffle referrals table schema mismatch — column renamed from user_id to user_email to match activator schema and all code usage
  • BUG-2: Cron job scheduling moved from plugin constructor to admin_init hook, preventing premature scheduling during plugin load
  • BUG-3: Raffle form — ticket selection mode and draw type fields were missing from edit form, now correctly pre-populate
  • BUG-4: Raffle form — start_date and draw_date NULL handling fixed; empty dates now correctly stored as NULL instead of empty string
  • BUG-5: WooCommerce product categories and tags — new fields added to raffle form for proper product categorisation
  • BUG-6: Free entries table schema — columns aligned with actual INSERT statements (buyer_name, buyer_email, status)

Moderate

  • BUG-7: Duplicate sync tab in settings navigation removed
  • BUG-8: Instant win prizes — prize image field added to form and save handler
  • BUG-9: WooCommerce cart integration — improved raffle_quantity meta handling for reliable quantity enforcement
  • BUG-10: Settings save handlers — explicit (array) casts prevent PHP warnings when POST fields are missing

Minor

  • BUG-11: Dashboard chart — currency symbol localisation improved
  • BUG-12: Admin CSS — card and table styling consistency fixes
  • BUG-13: Public JS — improved error handling for failed AJAX requests

New Features

Settings: Legal Tab

  • FAQ Management — Dynamic FAQ editor with add/remove buttons instead of raw text editing
  • Individual question and answer fields with validation
  • Automatic migration from legacy text-based FAQ template to structured array format
  • Placeholder Reference — Full table of available template placeholders ({{max_tickets}}, {{total_tickets}}, etc.)

Settings: Winners Page Tab Visibility

  • Control which tabs appear on the winners page ([raffle_ended_list])
  • Three configurable tabs: Live Draw, Auto-Draw, Instant Wins
  • At least one tab must be enabled (enforced)
  • Configured in Settings → General

Settings: Shortcode Customisation

  • New "Shortcode Customisation" section in Settings → Pages
  • Toggle-based panels for each configurable shortcode:
    • [raffle_ended_list] — Grid columns, show/hide: prize image, winner box, watch draw button, verified draw button, date badge, entry count
    • [raffle_entry_list] — Layout (grid/list), columns, button text, button colours (with color pickers), border radius, show/hide prize image
    • [raffle_list] — Default status filter (active, finished, draft, all)
  • Toggle switches with visual "Customised" / "Default" indicator
  • Inline shortcode attributes still override stored settings
  • Settings stored in wpraffle_shortcode_settings option

Settings: Pages Tab Improvements

  • Page Assignments — Dropdown page selectors for each feature (Raffles, Past Raffles, Entry Lists, Live Draw)
  • Create Page button for unassigned features
  • Edit / View links for assigned pages
  • My Raffles row with automatic endpoint explanation
  • All tables now full-width for better readability

Settings: Sync Tab (New)

  • Raffle & WooCommerce Product Sync tool
  • Full status table showing sync state for every raffle
  • Detects: missing products, deleted products, status mismatches, price mismatches, meta mismatches
  • Sync All button — batch fix all issues
  • Individual Fix — per-raffle sync
  • Create Product — generate missing WooCommerce products for raffles
  • Visual health indicator (green "All in sync" or yellow warning with issue count)

WooCommerce Product Integration

  • Product Categories — Assign WooCommerce product categories to raffle products
  • Product Tags — Assign WooCommerce product tags to raffle products
  • Catalog Visibility — Raffle products no longer hidden from shop/catalog
  • Block Theme Compatibility — WooCommerce Interactivity API scripts deregistered for raffle products to prevent module resolution errors

Shortcode: Entry List Downloads ([raffle_entry_list])

  • New dedicated shortcode for downloading entry lists as PDFs
  • Configurable layout (grid or list), columns, button styling
  • Color picker integration for button background and text colour
  • Border radius control
  • PDF generation via built-in lightweight PDF class (WPRaffle_PDF)

Shortcode: Raffle List ([raffle_list])

  • Shop page countdown timers for each raffle card
  • New shop-countdown.js asset for frontend countdown
  • Responsive card grid with raffle loop card template

Shortcode: Ended Raffles ([raffle_ended_list])

  • Tabbed winners page — Three tabs: Live Draw, Auto-Draw, Instant Wins
  • Per-tab configurable visibility
  • Instant wins grouped by date with winner initials and ticket numbers
  • Auto-draw badge distinguishing auto vs manual draws
  • Draw video and verified result links

Privacy & GDPR

  • Personal Data Export — Export all user data by email (purchases, tickets, instant wins, referrals, free entries)
  • Personal Data Erasure — Anonymise or delete user data with configurable retention
  • Integrated with WordPress core privacy tools (Tools → Export/Erase Personal Data)

Improvements

Admin UI

  • Settings tabs renamed and reorganised (General, Pages, Email, Legal, Sync, Advanced, Updates)
  • Full-width tables throughout settings pages
  • Improved card-based layout for settings sections
  • Better visual hierarchy with icon-enhanced headings

Code Quality

  • Consistent use of wp_unslash() before all sanitisation
  • Type-safe format specifiers in $wpdb->prepare() calls (%d, %f, %s)
  • Atomic database transactions for delete operations (START TRANSACTION / COMMIT)
  • Migration version flags prevent unnecessary SHOW COLUMNS queries
  • All new classes follow WordPress naming conventions

Performance

  • Migration checks use option flags to avoid repeated SHOW COLUMNS queries
  • Transient-based rate limiting (no additional database tables)
  • Shortcode customisation settings cached in single option

Frontend

  • Improved raffle loop card design for shop pages
  • Countdown timer on shop/raffle list pages
  • Better responsive grid layouts
  • WooCommerce block theme compatibility

New Files

File Purpose
includes/class-raffle-rate-limiter.php Standalone rate limiting class
includes/class-raffle-privacy.php WordPress Privacy API integration (GDPR)

Updated Shortcode Reference

Shortcode What's New
[raffle_list] Customisable default status from settings
[raffle_ended_list] 7 new attributes, tabbed layout, settings integration
[raffle_entry_list] 7 attributes for button styling and layout, PDF downloads
[raffle_live_draw] No changes
[raffle] No changes
[raffle_lookup] No changes

Upgrade Guide

  1. Backup your database and plugin files
  2. Replace the wpraffle plugin folder with the new version
  3. Visit WordPress Admin → Plugins — the plugin will auto-update database schema
  4. New settings are available at Raffles → Settings:
    • Legal tab — Con...
Read more

Initial Release

11 Jun 13:37
e9758bb

Choose a tag to compare

Version WordPress PHP WooCommerce License

🎟️ WPRaffle

A comprehensive WordPress plugin for running online raffles and competitions.
Built on WooCommerce with full ticket management, live draws, instant wins, and UK compliance features.


✨ Features

Core

  • 🎫 Configurable Raffles — Title, description, prize image, ticket count, price, packages
  • 🛒 WooCommerce Integration — Full checkout with any payment gateway, cart & order management
  • 🎰 Random Ticket Assignment — Cryptographically secure (random_int()) unique ticket numbers
  • 📧 Automated Emails — Purchase confirmation, winner notification, instant win alerts, draw reminders, sold out alerts
  • 🔢 User-Selected Numbers — Optional mode where buyers pick their own ticket numbers

Competition Features

  • 🏆 Instant Wins — Prizes automatically awarded at specific ticket numbers
  • 🎯 Multi-Winner Draws — Multiple winners with configurable prize tiers
  • 📺 Live Draw — Animated draw page with spinning numbers and confetti
  • Skill Questions — Multiple-choice questions required before purchase (UK Gambling Act compliance)
  • 🆓 Free / Postal Entry — Alternative entry route for compliance
  • 🌍 Geo-Restriction — Restrict entry by country via IP geolocation
  • 🔗 Referral System — Unique referral codes with bonus entries

Admin

  • 📊 Analytics Dashboard — Revenue charts, sales trends, activity feed
  • 📝 Audit Log — Complete action log with actor, IP, and timestamps
  • 📋 Templates & Clone — Reusable raffle templates and one-click duplication
  • 🎫 Ticket Reservations — Temporary holds during checkout with auto-cleanup
  • 🔍 Duplicate Detection — Automatic detection and correction of duplicate tickets
  • 🏪 Shop Integration — Custom raffle cards in WooCommerce shop pages

Security

  • 🔒 Multi-layer quantity validation — Cart lock, checkout validation, payment-time clamping
  • 🛡️ WordPress nonces on all forms and AJAX (CSRF protection)
  • 🧹 Input sanitization & output escaping throughout
  • 📐 Prepared SQL statements — No raw queries
  • ⏱️ Rate limiting — Configurable per-minute per-IP

Developer

  • 🧩 Elementor Widgets — 18 custom widgets for visual page building
  • 📐 Shortcodes — Display raffles, lists, lookup, and live draws anywhere
  • 🔄 GitHub Auto-Updates — Push updates from GitHub releases
  • 🪝 Hooks & Filters — Extensible via WordPress actions and filters

📦 Installation

Requirements

Component Minimum
WordPress 6.0+
PHP 8.0+
WooCommerce 8.0+
MySQL 5.7+
Elementor Optional

Setup

  1. Download the latest release .zip from the Releases page
  2. Go to WordPress Admin → Plugins → Add New → Upload Plugin
  3. Upload the .zip and click Install Now
  4. Activate the plugin
  5. WPRaffle will automatically:
    • Create all required database tables (10 tables)
    • Create a WooCommerce shadow product
    • Create pages with shortcodes (Raffles, Past Raffles, Live Draw)
    • Schedule cron jobs for auto-draw, reminders, and cleanup
  6. Configure settings at Raffles → Settings

Manual Install

git clone https://github.com/wpraffle/wpraffle.git
# Copy to wp-content/plugins/wpraffle/
# Activate from WordPress Plugins page

🚀 Quick Start

  1. Go to Raffles → Create Raffle
  2. Fill in title, description, prize details, ticket count, price, and packages
  3. Configure optional features (instant wins, skill question, geo-restriction, etc.)
  4. Publish — copy the shortcode [raffle id="X"] to any page
  5. Buyers select packages, complete WooCommerce checkout, and receive tickets by email
  6. Draw winner from Raffles → View Details when ready

📄 Shortcodes

Shortcode Description
[raffle id="X"] Display a single raffle with full UI
[raffle_list columns="3" per_page="12"] Active raffles in a responsive grid
[raffle_ended_list columns="3"] Completed/finished raffles
[raffle_lookup] Ticket lookup form by email
[raffle_live_draw raffle_id="X"] Live animated draw page
[raffle_entry_list raffle_id="X"] Entry/ticket list for a raffle

🧩 Elementor Widgets

When Elementor is active, 18 custom widgets are available:

Widget Description
Raffle Full Page Complete all-in-one raffle layout
Raffle Title Raffle title with styling
Raffle Image Prize image with lightbox
Raffle Price Ticket price display
Raffle Progress Sales progress bar
Raffle Countdown Live countdown timer
Raffle Quantity Selector Package selection grid
Raffle Enter Button CTA button
Raffle Description Raffle description text
Raffle Stats Header Key stats (sold, remaining, price)
Raffle Tabs Tabbed content
Raffle Instant Wins Instant win prizes grid
Raffle Question Skill question form
Raffle Trust Badge Trust/verification badge
Raffle Modal Purchase/entry modal
All Competitions Raffle list/grid
Ended Raffles Past competitions grid
Entry List Ticket/entry list

📁 Project Structure

wpraffle/
├── raffle-system.php                  # Plugin entry point
├── README.md                          # This file
├── DOCUMENTATION.md                   # Full documentation
├── .gitignore
│
├── admin/
│   ├── class-raffle-admin.php         # Admin menus, CRUD, settings
│   ├── class-raffle-analytics.php     # Analytics data API
│   └── views/
│       ├── dashboard.php              # Dashboard view
│       ├── raffle-list.php            # All raffles table
│       ├── raffle-form.php            # Create/edit form
│       ├── raffle-details.php         # Raffle details & stats
│       ├── audit-log.php              # Audit log viewer
│       └── settings.php              # Settings (6 tabs)
│
├── includes/
│   ├── functions-icons.php            # SVG sprite icon system
│   ├── class-raffle-activator.php     # Activation: tables, pages, cron
│   ├── class-raffle-tickets.php       # Ticket generation
│   ├── class-raffle-purchase.php      # Purchase processing
│   ├── class-raffle-draw.php          # Winner selection & draw
│   ├── class-raffle-email.php         # Email system (5 types)
│   ├── class-raffle-woocommerce.php   # WooCommerce integration
│   ├── class-raffle-instant-wins.php  # Instant win logic
│   ├── class-raffle-audit.php         # Audit logging
│   ├── class-raffle-prizes.php        # Multi-prize management
│   ├── class-raffle-duplicates.php    # Duplicate detection
│   ├── class-raffle-referrals.php     # Referral system
│   ├── class-raffle-free-entry.php    # Free/postal entry
│   ├── class-raffle-templates.php     # Templates & clone
│   ├── class-raffle-reservations.php  # Ticket reservations
│   ├── class-raffle-geo.php           # Geo-restriction
│   ├── class-raffle-live-draw.php     # Live draw page
│   ├── class-raffle-pdf.php           # PDF generation
│   ├── class-raffle-dashboard-widgets.php
│   ├── class-raffle-elementor.php     # Elementor registration
│   ├── class-raffle-updater.php       # GitHub auto-updates
│   └── elementor-widgets/             # 18 Elementor widgets
│
├── public/
│   ├── class-raffle-public.php        # Shortcodes, assets, frontend
│   └── views/
│       ├── single-raffle.php          # Single raffle template
│       ├── raffle-display.php         # Raffle display (shortcode)
│       ├── raffle-loop-card.php       # Card for grids/shop
│       ├── entry-list.php             # Entry list view
│       └── my-raffles.php             # My Raffles page
│
└── assets/
    ├── css/
    │   ├── admin.css                  # Admin styles
    │   ├── public.css                 # Frontend styles
    │   └── icons.css                  # Icon styles
    ├── js/
    │   ├── admin.js                   # Admin JavaScript
    │   ├── dashboard.js               # Dashboard charts
    │   ├── public.js                  # Frontend JavaScript
    │   └── shop-countdown.js          # Shop page countdown
    └── icons/
        └── wpraffle-icons.svg         # SVG sprite

⚙️ Configuration

Settings Tabs

Tab Description
General Company name, address, currency, default limits
Pages Auto-created pages status, shortcode reference
Email Sender details, branding, accent colour, test sender
Payment WooCommerce gateway configuration (Stripe, PayPal, etc.)
Advanced Auto-fix, rate limiting, audit log, cron overview
Updates GitHub auto-updates, version check

Database Tables

The plugin creates 10 custom tables:

Table Purpose
wp_raffles Main raffle data
wp_raffle_purchases Purchase records
wp_raffle_tickets Individual ticket numbers
wp_raffle_instant_wins Instant win prizes
wp_raffle_prizes Multi-winner prize tiers
wp_raffle_referrals Referral tracking
wp_raffle_reservations Temporary ticket holds
`wp_raf...
Read more