From 057ad58603aa81198f8888343f3c068c18a0a558 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Thu, 20 Aug 2026 18:58:03 +0530 Subject: [PATCH 1/2] fix: improve component resolution handling --- .../Core/Builder/Abstract_Builder.php | 4 + header-footer-grid/functions-template.php | 2 +- .../templates/component-wrapper.php | 19 ++- .../components/component-footer-sidebar.php | 13 +- .../templates/components/component-logo.php | 9 +- .../templates/components/component-nav.php | 9 +- tests/test-neve-hfg-component-guards.php | 142 ++++++++++++++++++ 7 files changed, 186 insertions(+), 12 deletions(-) create mode 100644 tests/test-neve-hfg-component-guards.php diff --git a/header-footer-grid/Core/Builder/Abstract_Builder.php b/header-footer-grid/Core/Builder/Abstract_Builder.php index 7c8c0e4936..df32e60ea8 100644 --- a/header-footer-grid/Core/Builder/Abstract_Builder.php +++ b/header-footer-grid/Core/Builder/Abstract_Builder.php @@ -1710,6 +1710,10 @@ public function get_component( $id = null ) { $id = ( self::$current_component === null ) ? Abstract_Component::$current_component : self::$current_component; } + if ( $id === null || ! isset( $this->builder_components[ $id ] ) ) { + return null; + } + return $this->builder_components[ $id ]; } diff --git a/header-footer-grid/functions-template.php b/header-footer-grid/functions-template.php index 9b7cac48fd..4db9d6010f 100644 --- a/header-footer-grid/functions-template.php +++ b/header-footer-grid/functions-template.php @@ -51,7 +51,7 @@ function render_components( $builder_name = '', $device = null ) { * @param string $builder_name The builder id. * @param null $component_id The component id. * - * @return false|Core\Components\Abstract_Component + * @return false|null|Core\Components\Abstract_Component */ function current_component( $builder_name = '', $component_id = null ) { $builder = get_builder( $builder_name ); diff --git a/header-footer-grid/templates/component-wrapper.php b/header-footer-grid/templates/component-wrapper.php index 7ca9034eea..96f966779e 100644 --- a/header-footer-grid/templates/component-wrapper.php +++ b/header-footer-grid/templates/component-wrapper.php @@ -10,9 +10,16 @@ namespace HFG; -$_id = current_component()->get_id(); +$_component = current_component(); + +// Bail when the current component cannot be resolved on the current builder. +if ( ! $_component instanceof Core\Components\Abstract_Component ) { + return; +} + +$_id = $_component->get_id(); if ( isset( $args ) && ! empty( $args ) ) { - current_component()->set_args( $args ); + $_component->set_args( $args ); } $item_classes = array(); @@ -44,11 +51,11 @@ ?>
> + data-section="get_section_id() ); ?>" + data-item-id="get_id() ); ?>"> render_css(); - current_component()->render_component(); + $_component->render_css(); + $_component->render_component(); ?> diff --git a/header-footer-grid/templates/components/component-footer-sidebar.php b/header-footer-grid/templates/components/component-footer-sidebar.php index 7bffeb3a2a..3656e9c35e 100644 --- a/header-footer-grid/templates/components/component-footer-sidebar.php +++ b/header-footer-grid/templates/components/component-footer-sidebar.php @@ -10,7 +10,14 @@ namespace HFG; -$_id = current_component()->get_id(); +$_component = current_component(); + +// Bail when the current component cannot be resolved on the current builder. +if ( ! $_component instanceof Core\Components\Abstract_Component ) { + return; +} + +$_id = $_component->get_id(); if ( is_active_sidebar( $_id ) ) { ?> @@ -20,7 +27,7 @@
-

get_property( 'label' ) ); ?>

+

get_property( 'label' ) ); ?>

get_property( 'label' ) ) + esc_attr( $_component->get_property( 'label' ) ) ) ) ); diff --git a/header-footer-grid/templates/components/component-logo.php b/header-footer-grid/templates/components/component-logo.php index c3ac4c0684..78f717a136 100644 --- a/header-footer-grid/templates/components/component-logo.php +++ b/header-footer-grid/templates/components/component-logo.php @@ -12,7 +12,14 @@ use HFG\Core\Builder\Header as HeaderBuilder; use HFG\Core\Components\Logo; -$_id = current_component( HeaderBuilder::BUILDER_NAME )->get_id(); +$_component = current_component( HeaderBuilder::BUILDER_NAME ); + +// Bail when the current component cannot be resolved on the current builder. +if ( ! $_component instanceof Core\Components\Abstract_Component ) { + return; +} + +$_id = $_component->get_id(); $device = current_device( HeaderBuilder::BUILDER_NAME ); $show_name = component_setting( Logo::SHOW_TITLE ); diff --git a/header-footer-grid/templates/components/component-nav.php b/header-footer-grid/templates/components/component-nav.php index c89bf4daf4..9663a493e7 100644 --- a/header-footer-grid/templates/components/component-nav.php +++ b/header-footer-grid/templates/components/component-nav.php @@ -12,8 +12,15 @@ use HFG\Core\Components\Nav; use HFG\Core\Builder\Header as HeaderBuilder; +$_component = current_component( HeaderBuilder::BUILDER_NAME ); + +// Bail when the current component cannot be resolved on the current builder. +if ( ! $_component instanceof Core\Components\Abstract_Component ) { + return; +} + $device_class = isset( $args ) && ! empty( $args ) ? $args['device'] : ''; -$_id = current_component( HeaderBuilder::BUILDER_NAME )->get_id(); +$_id = $_component->get_id(); $style = component_setting( Nav::STYLE_ID, 'style-plain' ); $additional_menu_class = apply_filters( 'neve_additional_menu_class', ' menu-' . $device_class ); diff --git a/tests/test-neve-hfg-component-guards.php b/tests/test-neve-hfg-component-guards.php new file mode 100644 index 0000000000..c25270fb8e --- /dev/null +++ b/tests/test-neve-hfg-component-guards.php @@ -0,0 +1,142 @@ +previous_state = array( + 'builder' => Abstract_Builder::$current_builder, + 'builder_component' => Abstract_Builder::$current_component, + 'current_component' => Abstract_Component::$current_component, + ); + } + + /** + * Restore the static render state. + */ + public function tear_down() { + Abstract_Builder::$current_builder = $this->previous_state['builder']; + Abstract_Builder::$current_component = $this->previous_state['builder_component']; + Abstract_Component::$current_component = $this->previous_state['current_component']; + + parent::tear_down(); + } + + /** + * Get the header builder instance. + * + * @return Abstract_Builder + */ + private function header_builder() { + $builder = Main::get_instance()->get_builder( 'header' ); + + $this->assertInstanceOf( Abstract_Builder::class, $builder ); + + return $builder; + } + + /** + * An unknown component id resolves to null instead of raising a warning. + */ + public function test_get_component_returns_null_for_unknown_id() { + $this->assertNull( $this->header_builder()->get_component( 'neve-not-a-component' ) ); + } + + /** + * With no component in render context, get_component resolves to null. + */ + public function test_get_component_returns_null_without_render_context() { + Abstract_Builder::$current_component = null; + Abstract_Component::$current_component = null; + + $this->assertNull( $this->header_builder()->get_component() ); + } + + /** + * A stale component id left in the render context resolves to null. + */ + public function test_get_component_returns_null_for_stale_context() { + Abstract_Builder::$current_component = null; + Abstract_Component::$current_component = 'neve-stale-component'; + + $this->assertNull( $this->header_builder()->get_component() ); + } + + /** + * A registered component is still returned. + */ + public function test_get_component_returns_registered_component() { + $builder = $this->header_builder(); + $components = $builder->get_components(); + + if ( empty( $components ) ) { + $this->markTestSkipped( 'No header components registered.' ); + } + + $id = key( $components ); + + Abstract_Builder::$current_component = null; + Abstract_Component::$current_component = $id; + + $component = $builder->get_component(); + + $this->assertInstanceOf( Abstract_Component::class, $component ); + $this->assertSame( $id, $component->get_id() ); + } + + /** + * Templates that resolve the component from the render context. + * + * @return array + */ + public function component_template_provider() { + return array( + 'wrapper' => array( 'component-wrapper' ), + 'footer sidebar' => array( 'components/component-footer-sidebar' ), + 'logo' => array( 'components/component-logo' ), + 'nav' => array( 'components/component-nav' ), + ); + } + + /** + * Component templates render nothing when the component is unresolvable. + * + * @param string $template Template slug. + * + * @dataProvider component_template_provider + */ + public function test_component_template_renders_nothing_without_component( $template ) { + Abstract_Builder::$current_builder = 'header'; + Abstract_Builder::$current_component = null; + Abstract_Component::$current_component = 'neve-stale-component'; + + ob_start(); + Main::get_instance()->load( $template ); + $output = ob_get_clean(); + + $this->assertSame( '', trim( $output ) ); + } +} From 11aeb5c9df4dbcc48f9fb4526d735c86d04b5940 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Thu, 20 Aug 2026 19:21:42 +0530 Subject: [PATCH 2/2] fix: namespace to component instance checks --- header-footer-grid/functions-template.php | 4 ++-- header-footer-grid/templates/components/component-logo.php | 2 +- header-footer-grid/templates/components/component-nav.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/header-footer-grid/functions-template.php b/header-footer-grid/functions-template.php index 4db9d6010f..43fddc19f2 100644 --- a/header-footer-grid/functions-template.php +++ b/header-footer-grid/functions-template.php @@ -48,8 +48,8 @@ function render_components( $builder_name = '', $device = null ) { /** * Returns the current component. * - * @param string $builder_name The builder id. - * @param null $component_id The component id. + * @param string $builder_name The builder id. + * @param string|null $component_id The component id. * * @return false|null|Core\Components\Abstract_Component */ diff --git a/header-footer-grid/templates/components/component-logo.php b/header-footer-grid/templates/components/component-logo.php index 78f717a136..7a371697a5 100644 --- a/header-footer-grid/templates/components/component-logo.php +++ b/header-footer-grid/templates/components/component-logo.php @@ -15,7 +15,7 @@ $_component = current_component( HeaderBuilder::BUILDER_NAME ); // Bail when the current component cannot be resolved on the current builder. -if ( ! $_component instanceof Core\Components\Abstract_Component ) { +if ( ! $_component instanceof \HFG\Core\Components\Abstract_Component ) { return; } diff --git a/header-footer-grid/templates/components/component-nav.php b/header-footer-grid/templates/components/component-nav.php index 9663a493e7..64af59c306 100644 --- a/header-footer-grid/templates/components/component-nav.php +++ b/header-footer-grid/templates/components/component-nav.php @@ -15,7 +15,7 @@ $_component = current_component( HeaderBuilder::BUILDER_NAME ); // Bail when the current component cannot be resolved on the current builder. -if ( ! $_component instanceof Core\Components\Abstract_Component ) { +if ( ! $_component instanceof \HFG\Core\Components\Abstract_Component ) { return; }