@@ -75,6 +75,10 @@ public function register_hooks() {
7575 * @return void
7676 */
7777 public function replace_background_images_in_css ( $ post_css , $ element ) {
78+ if ( ! method_exists ( $ element , 'get_settings_for_display ' ) ) {
79+ return ;
80+ }
81+
7882 $ settings = $ element ->get_settings_for_display ();
7983 $ media = $ this ->plugin ->get_component ( 'media ' );
8084 $ delivery = $ this ->plugin ->get_component ( 'delivery ' );
@@ -117,8 +121,11 @@ public function replace_background_images_in_css( $post_css, $element ) {
117121 continue ;
118122 }
119123
120- // Build the CSS selector and rule.
121- $ unique_selector = $ post_css ->get_element_unique_selector ( $ element );
124+ $ unique_selector = $ this ->find_unique_selector ( $ post_css , $ element );
125+ // If we can't find a unique selector via Elementor's internal API, we can't do any replacement.
126+ if ( null === $ unique_selector ) {
127+ return ;
128+ }
122129
123130 // Elementor applies this suffix rule to container background images to avoid conflicts with motion effects backgrounds.
124131 $ default_suffix = $ is_container ? ':not(.elementor-motion-effects-element-type-background) ' : '' ;
@@ -131,8 +138,11 @@ public function replace_background_images_in_css( $post_css, $element ) {
131138 $ media_query = array ( 'max ' => $ background_data ['device ' ] );
132139 }
133140
134- // Override the CSS rule in Elementor.
135- $ post_css ->get_stylesheet ()->add_rules ( $ css_selector , $ css_rule , $ media_query );
141+ $ success = $ this ->override_elementor_css_rule ( $ post_css , $ css_selector , $ css_rule , $ media_query );
142+ if ( ! $ success ) {
143+ // If we couldn't override the CSS rule, likely due to Elementor internal API changes, we should stop further processing.
144+ return ;
145+ }
136146 }
137147 }
138148
@@ -148,4 +158,46 @@ public function clear_elementor_css_cache() {
148158 $ elementor ->files_manager ->clear_cache ();
149159 }
150160 }
161+
162+ /**
163+ * Find the unique selector for an Elementor element.
164+ * Double-checks if the method exists before calling it, to ensure compatibility with different Elementor versions.
165+ *
166+ * @param Post $post_css The post CSS object.
167+ * @param Element_Base $element The Elementor element.
168+ *
169+ * @return string|null
170+ */
171+ private function find_unique_selector ( $ post_css , $ element ) {
172+ if ( ! method_exists ( $ element , 'get_unique_selector ' ) ) {
173+ return null ;
174+ }
175+
176+ return $ post_css ->get_element_unique_selector ( $ element );
177+ }
178+
179+ /**
180+ * Override the Elementor CSS rule for a specific selector.
181+ * Double-checks if the method exists before calling it, to ensure compatibility with different Elementor versions.
182+ *
183+ * @param Post $post_css The post CSS object.
184+ * @param string $css_selector The CSS selector.
185+ * @param array $css_rule The CSS rule to apply.
186+ * @param array|null $media_query The media query conditions. Null for default (desktop) styles.
187+ *
188+ * @return bool True if the rule could be overridden, false if the internal Elementor methods aren't available.
189+ */
190+ private function override_elementor_css_rule ( $ post_css , $ css_selector , $ css_rule , $ media_query ) {
191+ if ( ! method_exists ( $ post_css , 'get_stylesheet ' ) ) {
192+ return false ;
193+ }
194+
195+ $ stylesheet = $ post_css ->get_stylesheet ();
196+ if ( ! method_exists ( $ stylesheet , 'add_rules ' ) ) {
197+ return false ;
198+ }
199+
200+ $ stylesheet ->add_rules ( $ css_selector , $ css_rule , $ media_query );
201+ return true ;
202+ }
151203}
0 commit comments