diff --git a/CHANGELOG.md b/CHANGELOG.md index e94b17f42..24801d75b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ * Fixed featured Community Cloud snippets failing to load with some cloud API responses. (PRO) * Fixed bulk actions in Community Cloud running against an empty selection, so selected snippets were never downloaded. (PRO) +* Fixed a fatal error in the Elementor editor on Elementor versions older than 3.19. ## [3.10.2] (2026-09-01) diff --git a/src/php/Integration/Promotions/Other/Elementor_Editor.php b/src/php/Integration/Promotions/Other/Elementor_Editor.php index 5151590be..ba3ff488e 100644 --- a/src/php/Integration/Promotions/Other/Elementor_Editor.php +++ b/src/php/Integration/Promotions/Other/Elementor_Editor.php @@ -23,6 +23,10 @@ public function __construct() { * Promotion on the Custom CSS section, inside the Elementor Editor. */ public function promotion_in_custom_css_section() { + if ( ! $this->supports_notice_control() ) { + return; + } + // Elementor Core. add_action( 'elementor/element/common/section_custom_css/after_section_start', @@ -40,6 +44,20 @@ function ( $element ) { ); } + /** + * Check whether this version of Elementor offers the notice control type. + * + * The type arrived in Elementor 3.19. On anything older the constant does + * not exist, and reading it while the editor builds its controls raises an + * Error that leaves the editor unusable, so the promotion is skipped + * rather than degraded. + * + * @return bool + */ + protected function supports_notice_control(): bool { + return defined( Controls_Manager::class . '::NOTICE' ); + } + /** * Register promotion section in the Custom CSS section. * diff --git a/tests/unit/Integration/Promotions/Other/Elementor_Editor_Test.php b/tests/unit/Integration/Promotions/Other/Elementor_Editor_Test.php new file mode 100644 index 000000000..1787d0159 --- /dev/null +++ b/tests/unit/Integration/Promotions/Other/Elementor_Editor_Test.php @@ -0,0 +1,86 @@ +promotion_in_custom_css_section(); + + foreach ( self::PROMOTION_HOOKS as $hook ) { + $this->assertFalse( + has_action( $hook ), + "the promotion should not be registered on $hook without the notice control type" + ); + } + } + + /** + * The promotion is still registered on a version that offers the control type. + * + * @return void + */ + public function test_promotion_is_registered_when_the_notice_control_exists(): void { + $promotion = new class() extends Elementor_Editor { + /** + * Stand in for an Elementor new enough to offer the control type. + * + * @return bool + */ + protected function supports_notice_control(): bool { + return true; + } + }; + + $promotion->promotion_in_custom_css_section(); + + foreach ( self::PROMOTION_HOOKS as $hook ) { + $this->assertNotFalse( + has_action( $hook ), + "the promotion should still be registered on $hook when the control type exists" + ); + } + } +}