Tightened input handling in handle_save_booking and handle_save_service: status fields constrained to whitelisted values, wp_unslash() applied to all reads, defensive isset() checks before every $_POST access.
Cleaned up dozens of stale phpcs:ignore directives that were emitted before per-handler check_ajax_referer() calls were added; the remaining ones are limited to legitimate direct-DB-query and unlink() annotations.
Service assignment arrays (staff_ids, location_ids) now go through wp_unslash() and absint() before being persisted.
1.5.4
Restructured the image upload handler so wp_generate_attachment_metadata() is the first function called immediately after require_once wp-admin/includes/image.php.
Strict validation of the image_data data: URL with a tight regex (only image/jpeg, image/png, image/webp + base64 charset) before any decoding.
Refactored the admin bookings list view: filter conditions, pagination and counts now build a single SQL string and arguments array passed through one $wpdb->prepare() call.
Simplified the bookings filter nonce flow into a single straight-line check; filter parameters are only read when the nonce verifies.
1.5.3
Replaced indirect nonce helper calls with direct check_ajax_referer() calls at the top of every AJAX handler so static analysers can detect the nonce check without tracing through helper methods.
Added an explicit wp_nonce_field() / wp_verify_nonce() pair around the admin bookings list filter form; filter parameters are ignored when the nonce is missing or invalid.
Hardened admin/views/email-templates.php with a capability check and a whitelist for the “tab” query argument.
1.5.2
Print receipt now loads via admin-post.php with standard WordPress enqueue pipeline.
Tightened nonce and capability checks on admin AJAX endpoints.
Refactored location-filtered queries to use $wpdb->prepare() with placeholders.
Escape-late applied on upgrade page and frontend service card output.
Renamed internal helper classes to use a plugin-specific 4+ character prefix.
1.5.1
First release prepared for the WordPress.org plugin directory.
Removed all numeric caps (services, staff, categories, locations) — the free plugin is now fully-featured with no limits.
Bundled Chart.js, FullCalendar and Cropper.js locally; no remote CDN calls.
Converted inline JavaScript and CSS to properly enqueued assets.
Replaced json_encode usages with wp_localize_script for chart data.
Multi-step booking form with Gutenberg block.
Admin dashboard with stats and interactive calendar.
Services, staff, categories, and locations management.
Automated booking confirmation emails to customer and admin.
Staff roles & access control (Admin, Manager, Staff).