diff --git a/CHANGELOG.md b/CHANGELOG.md index 5363d2e..a168196 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Planned - Continue importing native React blocks from the Nynaeve theme (e.g. contact-section, two-column-card, content-image-text-card, multi-column-content, related-articles), re-namespaced from `imagewize/*` to `aludra/*`. See `docs/PLAN-OF-ACTION.md` for the full gap analysis and import order. +## [2.9.4] - 2026-07-13 + +### Fixed +- The Settings → Aludra page showed the "Settings saved." notice twice after saving. The page manually added its own notice on top of the one the Settings API already queues via `options.php`; the redundant manual notice has been removed. + +### Security +- Added a direct-file-access guard (`if ( ! defined( 'ABSPATH' ) ) { exit; }`) to all eight `patterns/mega-menu-*.php` files, resolving the `missing_direct_file_access_protection` errors reported by Plugin Check. The pattern files ship in the distribution (mega-menu needs them), so excluding them from the check was not an option; the guard is a no-op when the files are loaded normally via `include`. + ## [2.9.3] - 2026-07-13 ### Changed diff --git a/CLAUDE.md b/CLAUDE.md index 0225540..0cc98ee 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -10,7 +10,8 @@ Aludra is a shared custom block library for Imagewize block themes (Nynaeve, Ela - **mega-menu** — Interactivity API mega menu backed by template parts - **faq-tabs** / **faq-tab-answer** — tabbed FAQ with answer children - **search-overlay-trigger** — search icon that opens a full-screen search overlay -- **feature-cards**, **icon-grid**, **trust-bar**, **pricing-tiers**, **testimonial-grid**, **cta-columns**, **feature-list-grid** — static content/marketing blocks +- **testimonial-grid** — testimonial cards that conditionally initialize a Slick carousel based on card count (view.js) +- **feature-cards**, **icon-grid**, **trust-bar**, **pricing-tiers**, **cta-columns**, **feature-list-grid** — static content/marketing blocks Blocks can be individually enabled/disabled via an admin settings page (Settings → Aludra), stored in the `aludra_enabled` option. See `blocks/` for the current, authoritative list. @@ -256,6 +257,26 @@ add_filter( 'default_wp_template_part_areas', function( $areas ) { ## Pattern Development Guidelines +### Direct-File-Access Guard + +**Required:** Every pattern PHP file in `patterns/` must start with a direct-access guard, immediately after the header doc-block and before the closing `?>`: + +```php + + +``` + +Pattern files ship in the distribution (they are `include`d at runtime to capture their markup — see `aludra.php`), so Plugin Check scans them and flags any without this guard (`missing_direct_file_access_protection`). They cannot be excluded via `.distignore` because the plugin needs them at runtime. The guard is a no-op on the normal `include` path (ABSPATH is always defined) and does not affect `get_file_data()` header parsing. Apply this to page patterns too, not just mega-menu patterns. + ### Separator Blocks in Patterns **Important:** When adding separator blocks to patterns, use the WordPress 6.7+ compatible format to avoid block validation errors: diff --git a/aludra.php b/aludra.php index e20ce48..2df53a3 100644 --- a/aludra.php +++ b/aludra.php @@ -3,7 +3,7 @@ * Plugin Name: Aludra * Plugin URI: https://github.com/imagewize/aludra * Description: Shared custom block library for Imagewize block themes (Nynaeve, Elayne, Aviendha) — Mega Menu, Carousel, FAQ Tabs, and content blocks (Feature Cards, Pricing Tiers, Testimonial Grid, and more). Built with React, block.json, and @wordpress/scripts. - * Version: 2.9.3 + * Version: 2.9.4 * Requires at least: 6.9 * Requires PHP: 7.4 * Author: Jasper Frumau @@ -23,7 +23,7 @@ exit; } -define( 'ALUDRA_VERSION', '2.9.3' ); +define( 'ALUDRA_VERSION', '2.9.4' ); define( 'ALUDRA_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); define( 'ALUDRA_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); diff --git a/includes/admin/settings-page.php b/includes/admin/settings-page.php index 4fd0d24..bf78325 100644 --- a/includes/admin/settings-page.php +++ b/includes/admin/settings-page.php @@ -306,18 +306,10 @@ function aludra_settings_page_html() { return; } - // Add error/success messages. - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- WordPress Settings API handles nonce verification. - if ( isset( $_GET['settings-updated'] ) ) { - add_settings_error( - 'aludra_messages', - 'aludra_message', - __( 'Settings saved.', 'aludra' ), - 'success' - ); - } - - settings_errors( 'aludra_messages' ); + // Render the "Settings saved." notice queued by the Settings API on save. + // We deliberately do not add our own message here — options.php already + // queues one, and adding a second causes a duplicate notice. + settings_errors(); $blocks = aludra_get_available_blocks(); $categories = aludra_get_block_categories(); diff --git a/patterns/mega-menu-featured-content.php b/patterns/mega-menu-featured-content.php index 9d7e56f..7afaae7 100644 --- a/patterns/mega-menu-featured-content.php +++ b/patterns/mega-menu-featured-content.php @@ -6,6 +6,10 @@ * Block Types: core/template-part * Description: Two column layout with featured image and links */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly. +} ?>
diff --git a/patterns/mega-menu-icon-features.php b/patterns/mega-menu-icon-features.php index e60a723..7470687 100644 --- a/patterns/mega-menu-icon-features.php +++ b/patterns/mega-menu-icon-features.php @@ -6,6 +6,10 @@ * Block Types: core/template-part * Description: Feature grid with styled icon containers and descriptions */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly. +} ?>
diff --git a/patterns/mega-menu-icon-grid.php b/patterns/mega-menu-icon-grid.php index ef5cef3..8470846 100644 --- a/patterns/mega-menu-icon-grid.php +++ b/patterns/mega-menu-icon-grid.php @@ -6,6 +6,10 @@ * Block Types: core/template-part * Description: Grid layout with icons and service links */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly. +} ?>
diff --git a/patterns/mega-menu-image-links.php b/patterns/mega-menu-image-links.php index e8a2073..e33f42a 100644 --- a/patterns/mega-menu-image-links.php +++ b/patterns/mega-menu-image-links.php @@ -6,6 +6,10 @@ * Block Types: core/template-part * Description: Promotional content with featured image and links */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly. +} ?>
diff --git a/patterns/mega-menu-multi-column.php b/patterns/mega-menu-multi-column.php index d22aaec..964e39f 100644 --- a/patterns/mega-menu-multi-column.php +++ b/patterns/mega-menu-multi-column.php @@ -6,6 +6,10 @@ * Block Types: core/template-part * Description: Full-width multi-column organized link layout */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly. +} ?>
diff --git a/patterns/mega-menu-services-showcase.php b/patterns/mega-menu-services-showcase.php index c4e538f..a24dfef 100644 --- a/patterns/mega-menu-services-showcase.php +++ b/patterns/mega-menu-services-showcase.php @@ -7,6 +7,10 @@ * Description: Sophisticated three-column services showcase with nested cards * Inserter: true */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly. +} ?>
diff --git a/patterns/mega-menu-simple-list.php b/patterns/mega-menu-simple-list.php index 28a86f3..f138aa5 100644 --- a/patterns/mega-menu-simple-list.php +++ b/patterns/mega-menu-simple-list.php @@ -6,6 +6,10 @@ * Block Types: core/template-part * Description: Clean two column list of links */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly. +} ?>
diff --git a/patterns/mega-menu-three-column.php b/patterns/mega-menu-three-column.php index e3cd0b2..bd3c0d7 100644 --- a/patterns/mega-menu-three-column.php +++ b/patterns/mega-menu-three-column.php @@ -6,6 +6,10 @@ * Block Types: core/template-part * Description: Three column layout with product categories and links */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly. +} ?>
diff --git a/readme.txt b/readme.txt index 2458035..3f04811 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: blocks, gutenberg, carousel, mega-menu, slider Requires at least: 6.9 Tested up to: 7.0 Requires PHP: 7.4 -Stable tag: 2.9.3 +Stable tag: 2.9.4 License: GPL v3 or later License URI: https://www.gnu.org/licenses/gpl-3.0.html @@ -171,6 +171,10 @@ It's WordPress's official frontend reactivity system. The mega menu block uses i == Changelog == += 2.9.4 = +* Fixed: Settings → Aludra showed the "Settings saved." notice twice after saving; removed the redundant manual notice on top of the one the Settings API already queues +* Security: Added a direct-file-access guard to all eight mega-menu pattern files, resolving the `missing_direct_file_access_protection` errors from Plugin Check while keeping the patterns in the distributed plugin + = 2.9.3 = * Changed: Redesigned the Settings → Aludra page as a categorized grid of block cards (Carousel, Interactive, Marketing & Content) with toggle switches, replacing the single-column checkbox list * Added: Live "enabled / total" counter in the settings header, plus per-card dependency chips ("Requires Carousel", "Requires FAQ Tabs")