PluginProbe
Sky Addons for Elementor / trunk
Sky Addons for Elementor vtrunk
3.8.5 3.8.4 3.8.3 3.8.2 3.8.0 3.8.1 3.3.3 3.3.2 trunk 1.0.0 1.0.10 1.0.2 1.0.6 1.0.7 1.0.8 1.0.9 1.5.0 2.0.0 2.0.8 2.5.10 2.5.11 2.5.12 2.5.13 2.5.15 2.5.16 All 52 releases
sky-elementor-addons / includes / custom-scripts / class-custom-scripts-loader.php

class-custom-scripts-loader.php in Sky Addons for Elementor trunk, at includes/custom-scripts/class-custom-scripts-loader.php

318 lines 7.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Custom Scripts Loader Class
4 * Handles conditional loading of custom scripts/styles on the frontend
5 *
6 * @package Sky_Addons\CustomScripts
7 * @since 3.3.0
8 */
9
10 namespace Sky_Addons\CustomScripts;
11
12 defined( 'ABSPATH' ) || exit;
13
14 class Custom_Scripts_Loader {
15 private static $instance = null;
16
17 private function __construct() {
18 add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_custom_scripts' ], 999 );
19 }
20
21 public static function instance() {
22 if ( is_null( self::$instance ) ) {
23 self::$instance = new self();
24 }
25 return self::$instance;
26 }
27
28 public function __clone() {}
29
30 public function __wakeup() {}
31
32 /**
33 * Enqueue custom scripts and styles based on conditions
34 */
35 public function enqueue_custom_scripts() {
36 $scripts = $this->get_enabled_scripts();
37
38 if ( empty( $scripts ) ) {
39 return;
40 }
41
42 foreach ( $scripts as $script ) {
43 if ( ! $this->should_load_script( $script ) ) {
44 continue;
45 }
46
47 $this->load_script( $script );
48 }
49 }
50
51 /**
52 * Get all enabled custom scripts
53 *
54 * @return array
55 */
56 private function get_enabled_scripts() {
57 $args = [
58 'post_type' => 'sky-custom-scripts',
59 'post_status' => 'publish',
60 'posts_per_page' => -1,
61 'meta_query' => [
62 [
63 'key' => 'sky_script_status',
64 'value' => 'enabled',
65 'compare' => '=',
66 ],
67 ],
68 ];
69
70 $query = new \WP_Query( $args );
71 return $query->posts;
72 }
73
74 /**
75 * Check if script should be loaded based on conditions
76 *
77 * @param \WP_Post $script
78 * @return bool
79 */
80 private function should_load_script( $script ) {
81 // Check date range first
82 $start_date = get_post_meta( $script->ID, 'sky_script_start_date', true );
83 $end_date = get_post_meta( $script->ID, 'sky_script_end_date', true );
84 $current_time = current_time( 'timestamp' );
85
86 // If start date is set and current time is before start date, don't load
87 if ( ! empty( $start_date ) && $current_time < strtotime( $start_date ) ) {
88 return false;
89 }
90
91 // If end date is set and current time is after end date, don't load
92 if ( ! empty( $end_date ) && $current_time > strtotime( $end_date . ' 23:59:59' ) ) {
93 return false;
94 }
95
96 $display_on = get_post_meta( $script->ID, 'sky_script_display_on', true ) ?: [];
97 $not_display_on = get_post_meta( $script->ID, 'sky_script_not_display_on', true ) ?: [];
98 $display_special_pages = get_post_meta( $script->ID, 'sky_script_display_special_pages', true ) ?: [];
99 $not_display_special_pages = get_post_meta( $script->ID, 'sky_script_not_display_special_pages', true ) ?: [];
100 $display_custom_pages = get_post_meta( $script->ID, 'sky_script_display_custom_pages', true ) ?: [];
101 $not_display_custom_pages = get_post_meta( $script->ID, 'sky_script_not_display_custom_pages', true ) ?: [];
102 $display_roles = get_post_meta( $script->ID, 'sky_script_display_roles', true ) ?: [];
103
104 // Check exclusion rules first
105 if ( $this->matches_conditions( $not_display_on, $not_display_special_pages, $not_display_custom_pages ) ) {
106 return false;
107 }
108
109 // Check inclusion rules
110 if ( empty( $display_on ) ) {
111 return true; // No conditions set, load everywhere
112 }
113
114 if ( ! $this->matches_conditions( $display_on, $display_special_pages, $display_custom_pages ) ) {
115 return false;
116 }
117
118 // Check user roles
119 if ( ! empty( $display_roles ) && ! $this->matches_user_role( $display_roles ) ) {
120 return false;
121 }
122
123 return true;
124 }
125
126 /**
127 * Check if current page matches display conditions
128 *
129 * @param array $display_on
130 * @param array $special_pages
131 * @param array $custom_pages
132 * @return bool
133 */
134 private function matches_conditions( $display_on, $special_pages, $custom_pages ) {
135 if ( empty( $display_on ) ) {
136 return false;
137 }
138
139 // Check entire site
140 if ( in_array( 'entire_site', $display_on ) ) {
141 return true;
142 }
143
144 // Check all pages
145 if ( in_array( 'all_pages', $display_on ) && is_page() ) {
146 return true;
147 }
148
149 // Check all posts
150 if ( in_array( 'all_posts', $display_on ) && is_single() ) {
151 return true;
152 }
153
154 // Check special pages
155 if ( in_array( 'special_pages', $display_on ) && ! empty( $special_pages ) ) {
156 if ( in_array( 'front_page', $special_pages ) && is_front_page() ) {
157 return true;
158 }
159 if ( in_array( 'blog_page', $special_pages ) && is_home() ) {
160 return true;
161 }
162 if ( in_array( 'archive_page', $special_pages ) && is_archive() ) {
163 return true;
164 }
165 if ( in_array( '404_page', $special_pages ) && is_404() ) {
166 return true;
167 }
168 }
169
170 // Check custom pages
171 if ( in_array( 'custom_pages', $display_on ) && ! empty( $custom_pages ) ) {
172 $current_page_id = get_the_ID();
173 if ( in_array( (string) $current_page_id, $custom_pages ) ) {
174 return true;
175 }
176 }
177
178 return false;
179 }
180
181 /**
182 * Check if current user matches role conditions
183 *
184 * @param array $roles
185 * @return bool
186 */
187 private function matches_user_role( $roles ) {
188 if ( empty( $roles ) ) {
189 return true;
190 }
191
192 if ( in_array( 'all_users', $roles ) ) {
193 return true;
194 }
195
196 $is_logged_in = is_user_logged_in();
197
198 if ( in_array( 'logged_in', $roles ) && $is_logged_in ) {
199 return true;
200 }
201
202 if ( in_array( 'logged_out', $roles ) && ! $is_logged_in ) {
203 return true;
204 }
205
206 if ( $is_logged_in ) {
207 $user = wp_get_current_user();
208 foreach ( $roles as $role ) {
209 if ( in_array( $role, $user->roles ) ) {
210 return true;
211 }
212 }
213 }
214
215 return false;
216 }
217
218 /**
219 * Load script or style
220 *
221 * @param \WP_Post $script
222 */
223 private function load_script( $script ) {
224 $script_type = get_post_meta( $script->ID, 'sky_script_type', true );
225 $script_content = get_post_meta( $script->ID, 'sky_script_content', true );
226 $script_position = get_post_meta( $script->ID, 'sky_script_position', true ) ?: 'footer';
227
228 if ( empty( $script_content ) ) {
229 return;
230 }
231
232 $handle = 'sky-custom-script-' . $script->ID;
233
234 if ( $script_type === 'css' ) {
235 $this->load_css( $handle, $script_content, $script_position );
236 } else {
237 $this->load_js( $handle, $script_content, $script_position );
238 }
239 }
240
241 /**
242 * Strip a single outer wrapper tag if the snippet was pasted with one.
243 *
244 * Snippets are stored as RAW code — the loader adds the <style>/<script>
245 * wrapper itself. If an author pastes the wrapper too, this removes it so
246 * the output never double-wraps.
247 *
248 * @param string $content
249 * @param string $tag 'style' or 'script'
250 * @return string
251 */
252 private function strip_wrapper_tags( $content, $tag ) {
253 $content = trim( $content );
254
255 if ( '' === $content ) {
256 return '';
257 }
258
259 if ( preg_match( '#^<' . $tag . '\b[^>]*>(.*)</' . $tag . '>$#is', $content, $matches ) ) {
260 $content = trim( $matches[1] );
261 }
262
263 return $content;
264 }
265
266 /**
267 * Load CSS
268 *
269 * @param string $handle
270 * @param string $content
271 * @param string $position
272 */
273 private function load_css( $handle, $content, $position ) {
274 $content = $this->strip_wrapper_tags( $content, 'style' );
275
276 if ( '' === $content ) {
277 return;
278 }
279
280 if ( $position === 'header' ) {
281 add_action( 'wp_head', function () use ( $content ) {
282 echo '<style type="text/css">' . "\n" . $content . "\n" . '</style>' . "\n";
283 }, 999 );
284 } else {
285 add_action( 'wp_footer', function () use ( $content ) {
286 echo '<style type="text/css">' . "\n" . $content . "\n" . '</style>' . "\n";
287 }, 999 );
288 }
289 }
290
291 /**
292 * Load JavaScript
293 *
294 * @param string $handle
295 * @param string $content
296 * @param string $position
297 */
298 private function load_js( $handle, $content, $position ) {
299 $content = $this->strip_wrapper_tags( $content, 'script' );
300
301 if ( '' === $content ) {
302 return;
303 }
304
305 if ( $position === 'header' ) {
306 add_action( 'wp_head', function () use ( $content ) {
307 echo '<script type="text/javascript">' . "\n" . $content . "\n" . '</script>' . "\n";
308 }, 999 );
309 } else {
310 add_action( 'wp_footer', function () use ( $content ) {
311 echo '<script type="text/javascript">' . "\n" . $content . "\n" . '</script>' . "\n";
312 }, 999 );
313 }
314 }
315 }
316
317 Custom_Scripts_Loader::instance();
318