11<?php
22
3+ declare ( strict_types = 1 );
4+
35namespace Kntnt \Popup ;
46
57/**
6- * Class Assets.
7- * Handles registration and conditional enqueueing of CSS and JavaScript assets.
8+ * Handles registration and conditional enqueueing of CSS and JavaScript assets for the plugin.
89 */
910final class Assets {
1011
12+ /**
13+ * Flag indicating whether assets (CSS/JS) are needed for the current page.
14+ *
15+ * @var bool
16+ */
17+ private bool $ assets_are_needed = false ;
1118
12- private bool $ assets_needed = false ;
13-
14- private array $ popup_configs = [];
19+ /**
20+ * Stores configurations for each popup instance to be passed to JavaScript.
21+ * Each configuration is an associative array.
22+ *
23+ * @var array<int, array<string, mixed>>
24+ */
25+ private array $ popup_configurations = [];
1526
1627 /**
17- * Registers CSS and JS files.
28+ * Registers CSS and JavaScript files with WordPress.
29+ * These assets are not enqueued immediately but are made available for later conditional enqueueing.
30+ *
31+ * @return void
1832 */
1933 public function register_assets (): void {
2034
21- wp_register_script ( Plugin::slug () . '-micromodal ' , Plugin::plugin_url () . 'js/micromodal.min.js ' , [], Plugin::version (), true );
22- wp_register_script ( Plugin::slug () . '-script ' , Plugin::plugin_url () . 'js/kntnt-popup.js ' , [ Plugin::slug () . '-micromodal ' ], Plugin::version (), true );
23- wp_script_add_data ( Plugin::slug () . '-script ' , 'defer ' , true );
24-
25- wp_register_style ( Plugin::slug () . '-style ' , Plugin::plugin_url () . 'css/kntnt-popup.css ' , [], Plugin::version () );
35+ // Register Micromodal library script (dependency for main script).
36+ wp_register_script ( Plugin::get_slug () . '-micromodal ' , // Handle
37+ Plugin::get_plugin_url () . 'js/micromodal.min.js ' , // Source URL
38+ [], // Dependencies
39+ Plugin::get_version (), // Version
40+ true // In footer
41+ );
42+
43+ // Register the main plugin JavaScript file.
44+ wp_register_script ( Plugin::get_slug () . '-script ' , // Handle
45+ Plugin::get_plugin_url () . 'js/kntnt-popup.js ' , // Source URL
46+ [ Plugin::get_slug () . '-micromodal ' ], // Dependencies
47+ Plugin::get_version (), // Version
48+ true // In footer
49+ );
50+ // Add 'defer' attribute to the main plugin script for optimized loading.
51+ wp_script_add_data ( Plugin::get_slug () . '-script ' , 'defer ' , true );
52+
53+ // Register the plugin's stylesheet.
54+ wp_register_style ( Plugin::get_slug () . '-style ' , // Handle
55+ Plugin::get_plugin_url () . 'css/kntnt-popup.css ' , // Source URL
56+ [], // Dependencies
57+ Plugin::get_version () // Version
58+ );
2659
2760 }
2861
2962 /**
30- * Checks if any post on the current page contains the popup shortcode.
31- * Called during wp_enqueue_scripts hook (priority 15).
63+ * Checks if any post content on the current page contains the popup shortcode.
64+ * Sets a flag if the shortcode is found. This method is hooked to 'wp_enqueue_scripts'.
65+ *
66+ * @return void
3267 */
33- public function check_for_shortcode (): void {
68+ public function check_for_shortcode_presence (): void {
3469
35- // Skip if assets are already flagged as needed (e.g., by shortcode execution if it happens earlier)
36- if ( $ this ->assets_needed ) {
37- return ;
70+ // Exit early if assets are already marked as needed.
71+ if ( $ this ->assets_are_needed ) {
72+ return ; // No further checks necessary.
3873 }
3974
40- // Check in global post first (single post/page view)
75+ // Check the main global $ post object, typically for single views.
4176 global $ post ;
42- if ( is_singular () && is_a ( $ post , 'WP_Post ' ) && isset ( $ post ->post_content ) ) {
43-
44- // Check both traditional content and blocks
45- if ( has_shortcode ( $ post ->post_content , 'popup ' )
46- || $ this ->has_popup_shortcode_in_blocks ( $ post ->post_content )
47- ) {
48- $ this ->mark_assets_needed ();
49- return ;
77+ if ( is_singular () && $ post instanceof \WP_Post && property_exists ( $ post , 'post_content ' ) ) {
78+
79+ // Determine if shortcode exists in post_content or within its blocks.
80+ if ( has_shortcode ( $ post ->post_content , 'popup ' ) || $ this ->has_popup_shortcode_in_blocks ( $ post ->post_content ) ) {
81+ $ this ->mark_assets_as_needed ();
82+ return ; // Assets are needed, no need to continue.
5083 }
84+
5185 }
5286
53- // For archive pages, home page, or when global post isn't the primary query object.
54- // We check the posts found by the main query.
55- // Note: This runs *during* wp_enqueue_scripts. The main query has likely run,
56- // but content filters haven't necessarily. We might need to access query vars.
87+ // Check posts within the global $wp_query, for archives or other loops.
5788 global $ wp_query ;
58- if ( isset ( $ wp_query ) && $ wp_query ->posts ) {
89+ if ( isset ( $ wp_query-> posts ) && is_array ( $ wp_query ->posts ) ) {
5990 foreach ( $ wp_query ->posts as $ queried_post ) {
60- if ( is_a ( $ queried_post , 'WP_Post ' ) && isset ( $ queried_post ->post_content ) ) {
61- if ( has_shortcode ( $ queried_post ->post_content , 'popup ' )
62- || $ this ->has_popup_shortcode_in_blocks ( $ queried_post ->post_content )
63- ) {
64- $ this ->mark_assets_needed ();
65- // error_log('KNTNT DEBUG: Shortcode found in $wp_query->posts'); // Optional debug
66- // No need to break, just set the flag once.
91+ if ( $ queried_post instanceof \WP_Post && property_exists ( $ queried_post , 'post_content ' ) ) {
92+
93+ // Determine if shortcode exists in queried post or its blocks.
94+ if ( has_shortcode ( $ queried_post ->post_content , 'popup ' ) || $ this ->has_popup_shortcode_in_blocks ( $ queried_post ->post_content ) ) {
95+
96+ // Mark assets as needed if shortcode is found.
97+ $ this ->mark_assets_as_needed ();
98+
99+ // Asset requirement determined, exit the check process.
67100 return ;
101+
68102 }
69103 }
70104 }
@@ -73,88 +107,112 @@ public function check_for_shortcode(): void {
73107 }
74108
75109 /**
76- * Helper method to check if a post with blocks contains popup shortcode .
110+ * Recursively checks for the 'popup' shortcode within block-based content .
77111 *
78- * @param string $content The post content to check .
112+ * @param string $content The post content, potentially containing blocks .
79113 *
80- * @return bool True if popup shortcode is found in blocks .
114+ * @return bool True if the ' popup' shortcode is found within any block, false otherwise .
81115 */
82116 private function has_popup_shortcode_in_blocks ( string $ content ): bool {
83117
118+ // Return early if block functions are unavailable or content has no blocks.
84119 if ( ! function_exists ( 'parse_blocks ' ) || ! has_blocks ( $ content ) ) {
85120 return false ;
86121 }
87122
123+ // Parse content into an array of blocks.
88124 $ blocks = parse_blocks ( $ content );
89125
90- // Using a recursive approach is safer
91- $ found = false ;
92- $ check_blocks = function ( array $ blocks ) use ( &$ check_blocks , &$ found ) {
93- foreach ( $ blocks as $ block ) {
126+ // Initialize state and define recursive block checking function.
127+ $ found_shortcode = false ; // Flag to indicate if the shortcode has been found.
128+ $ check_blocks_recursively = function ( array $ blocks_to_check ) use ( &$ check_blocks_recursively , &$ found_shortcode ): void {
129+
130+ // Iterate through each block in the current list to check for the shortcode.
131+ foreach ( $ blocks_to_check as $ block_item ) {
94132
95- // Stop searching if already found
96- if ( $ found ) {
133+ // If shortcode is already found, cease further checks within this recursion.
134+ if ( $ found_shortcode ) {
97135 return ;
98136 }
99137
100- // Check Shortcode blocks specifically looking for 'popup'
101- if ( $ block ['blockName ' ] === 'core/shortcode ' && isset ( $ block ['attrs ' ]['text ' ] ) && has_shortcode ( $ block ['attrs ' ]['text ' ], 'popup ' ) ) {
102- $ found = true ;
138+ // Check if the block is a 'core/shortcode' block containing the target shortcode.
139+ if ( isset ( $ block_item ['blockName ' ], $ block_item ['attrs ' ]['text ' ] )
140+ && $ block_item ['blockName ' ] === 'core/shortcode '
141+ && has_shortcode ( $ block_item ['attrs ' ]['text ' ], 'popup ' ) ) {
142+ $ found_shortcode = true ;
103143 return ;
104144 }
105145
106- // Check for shortcodes in inner HTML of any block (less specific, might catch nested ones)
107- if ( ! empty ( $ block ['innerHTML ' ] ) && has_shortcode ( $ block ['innerHTML ' ], 'popup ' ) ) {
108- $ found = true ;
146+ // Check if the block's inner HTML (rendered content) contains the target shortcode.
147+ if ( ! empty ( $ block_item ['innerHTML ' ] ) && has_shortcode ( $ block_item ['innerHTML ' ], 'popup ' ) ) {
148+ $ found_shortcode = true ;
109149 return ;
110150 }
111151
112- // Recursively check inner blocks
113- if ( ! empty ( $ block ['innerBlocks ' ] ) ) {
114- $ check_blocks ( $ block ['innerBlocks ' ] );
152+ // If the block has inner blocks, recursively call this function to check them.
153+ if ( ! empty ( $ block_item ['innerBlocks ' ] ) ) {
154+ $ check_blocks_recursively ( $ block_item ['innerBlocks ' ] );
115155 }
116156
117157 }
118158
119159 };
120160
121- $ check_blocks ( $ blocks );
122- return $ found ;
161+ // Execute the recursive check starting with the top-level blocks.
162+ $ check_blocks_recursively ( $ blocks );
163+
164+ // Return the result of the search.
165+ return $ found_shortcode ;
123166
124167 }
125168
126169
127170 /**
128- * Marks that assets should be enqueued for the current page.
171+ * Marks that assets (CSS/JS) should be enqueued for the current page.
172+ *
173+ * @return void
129174 */
130- public function mark_assets_needed (): void {
131- $ this ->assets_needed = true ;
175+ public function mark_assets_as_needed (): void {
176+ $ this ->assets_are_needed = true ;
132177 }
133178
134179 /**
135- * Adds configuration for a specific popup instance to be localized.
180+ * Adds configuration data for a specific popup instance.
181+ * This data will be localized and made available to the frontend JavaScript.
182+ *
183+ * @param array<string, mixed> $configuration The configuration array for a popup.
184+ *
185+ * @return void
136186 */
137- public function add_popup_config ( array $ config ): void {
138- $ this ->popup_configs [] = $ config ;
187+ public function add_popup_configuration ( array $ configuration ): void {
188+ $ this ->popup_configurations [] = $ configuration ;
139189 }
140190
141191 /**
142- * Enqueues assets if assets_needed flag is true.
143- * Hooked to wp_enqueue_scripts (priority 20).
192+ * Enqueues registered assets (CSS and JavaScript) if they are marked as needed.
193+ * Localizes popup configurations for use by the JavaScript.
194+ * This method is hooked to 'wp_enqueue_scripts'.
195+ *
196+ * @return void
144197 */
145198 public function enqueue_assets_conditionally (): void {
146199
147- if ( $ this ->assets_needed ) {
200+ // Proceed only if assets have been flagged as necessary for the current page.
201+ if ( $ this ->assets_are_needed ) {
148202
149- // Localize script data *before* enqueuing the script
150- wp_localize_script ( Plugin::slug () . '-script ' , 'kntntPopupData ' , [ 'popups ' => $ this ->popup_configs ] );
203+ // Make popup configurations available to the main JavaScript file via localization.
204+ wp_localize_script ( Plugin::get_slug () . '-script ' , // Script handle to attach data to
205+ 'kntntPopupData ' , // JavaScript object name where data will be available
206+ [ 'popups ' => $ this ->popup_configurations ] // Data to pass
207+ );
151208
152- // Enqueue script (micromodal will be loaded automatically as a dependency)
153- wp_enqueue_script ( Plugin::slug () . '-script ' );
209+ // Enqueue the main plugin script; Micromodal will be enqueued as its dependency.
210+ wp_enqueue_script ( Plugin::get_slug () . '-script ' );
154211
155- // Enqueue style
156- wp_enqueue_style ( Plugin::slug () . '-style ' );
212+ // Enqueue the plugin stylesheet.
213+ wp_enqueue_style ( Plugin::get_slug () . '-style ' );
157214
158215 }
159216 }
217+
160218}
0 commit comments