PluginProbe
Booktics – Appointment Booking Calendar for Service Businesses / 1.0.23
Booktics – Appointment Booking Calendar for Service Businesses v1.0.23
1.0.29 1.0.28 1.0.27 1.0.26 1.0.25 1.0.24 1.0.23 1.0.22 1.0.21 1.0.20 1.0.19 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.2 1.0.3 All 31 releases
booktics / core / assets / base-assets.php

base-assets.php in Booktics – Appointment Booking Calendar for Service Businesses 1.0.23, at core/assets/base-assets.php

341 lines 10.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Booktics\Assets;
3
4 if ( ! defined( 'ABSPATH' ) ) exit;
5
6 use Booktics\Contracts\Hookable_Service_Contract;
7
8 /**
9 * Main assets management class
10 */
11 abstract class Base_Assets implements Hookable_Service_Contract {
12 /**
13 * Get all scripts
14 *
15 * @return array list of script to register
16 */
17 abstract public function get_scripts(): array;
18
19 /**
20 * Get all styles
21 *
22 * @return array list of styles to regiser
23 */
24 abstract public function get_styles(): array;
25
26 /**
27 * Register scripts and styles
28 *
29 * @return void
30 */
31 public function register_styles_scripts() {
32 $this->register_global_scripts();
33 $this->register_scripts();
34 $this->register_styles();
35 }
36
37 /**
38 * Register scripts
39 *
40 * @return void
41 */
42 public function register_scripts() {
43 $scripts = $this->get_scripts();
44
45 foreach ( $scripts as $handle => $script ) {
46 $deps = isset( $script['deps'] ) ? $script['deps'] : [];
47 $in_footer = isset( $script['in_footer'] ) ? $script['in_footer'] : true;
48 $version = isset( $script['version'] ) ? $script['version'] : $this->get_version( $script['src'] );
49
50 $deps = $this->get_dependencies( $script['src'], $deps );
51
52 if ( in_array( 'wp-i18n', $deps, true ) ) {
53 $deps[] = 'booktics-i18n-loader';
54 }
55
56 wp_register_script( $handle, $script['src'], $deps, $version, $in_footer );
57
58 if ( function_exists( 'wp_set_script_translations' ) ) {
59 wp_set_script_translations( $handle, 'booktics' );
60 }
61
62 if ( 'booktics-packages' === $handle ) {
63 wp_add_inline_script(
64 'booktics-packages',
65 '(function(){try{if(window.bookticsPreloadedLocaleData && window.wp && window.wp.i18n && window.wp.i18n.setLocaleData){window.wp.i18n.setLocaleData(window.bookticsPreloadedLocaleData,"booktics");}}catch(e){}})();',
66 'before'
67 );
68 }
69 }
70 }
71
72 /**
73 * Register global scripts.
74 *
75 * @return void
76 */
77 private function register_global_scripts() {
78 $scripts = [
79 'booktics-i18n-loader' => [
80 'src' => booktics()->assets_url . '/build/js/i18n-loader.js',
81 'deps' => [],
82 'in_footer' => true,
83 ],
84 ];
85
86 foreach ( $scripts as $handle => $script ) {
87 $deps = isset( $script['deps'] ) ? $script['deps'] : [];
88 $in_footer = isset( $script['in_footer'] ) ? $script['in_footer'] : true;
89 $version = isset( $script['version'] ) ? $script['version'] : $this->get_version( $script['src'] );
90
91 $deps = $this->get_dependencies( $script['src'], $deps );
92
93 wp_register_script( $handle, $script['src'], $deps, $version, $in_footer );
94 }
95 }
96
97 /**
98 * Enqueue i18n loader and set its state.
99 *
100 * @return void
101 */
102 protected function enqueue_i18n_loader() {
103 $data = [
104 'baseUrl' => false,
105 'locale' => determine_locale(),
106 'domainMap' => [],
107 'domainPaths' => [],
108 'translationMap' => (object) [],
109 ];
110
111 $lang_dir = WP_LANG_DIR;
112 $content_dir = WP_CONTENT_DIR;
113 $abspath = ABSPATH;
114
115 if ( strpos( $lang_dir, $content_dir ) === 0 ) {
116 $data['baseUrl'] = content_url(
117 substr( trailingslashit( $lang_dir ), strlen( trailingslashit( $content_dir ) ) )
118 );
119 } elseif ( strpos( $lang_dir, $abspath ) === 0 ) {
120 $data['baseUrl'] = site_url(
121 substr( trailingslashit( $lang_dir ), strlen( untrailingslashit( $abspath ) ) )
122 );
123 }
124
125 $data['translationMap'] = (object) $this->get_translation_map();
126 $data['domainPaths'] = (object) $this->get_translation_directories();
127
128 wp_enqueue_script( 'booktics-i18n-loader' );
129
130 $data['domainMap'] = (object) $data['domainMap'];
131 $data['domainPaths'] = (object) $data['domainPaths'];
132
133 $preload = null;
134 $l10n_file = trailingslashit( WP_LANG_DIR ) . 'plugins/booktics-' . $data['locale'] . '.l10n.php';
135 $l10n_file_alt = trailingslashit( WP_LANG_DIR ) . 'plugins/booktics-' . str_replace( '-', '_', $data['locale'] ) . '.l10n.php';
136 $l10n_file_legacy = trailingslashit( WP_LANG_DIR ) . 'plugins/booktics-' . str_replace( '_', '-', $data['locale'] ) . '.l10n.php';
137 $l10n_candidates = array_unique( array_filter( [ $l10n_file, $l10n_file_alt, $l10n_file_legacy ] ) );
138
139 foreach ( $l10n_candidates as $candidate ) {
140 if ( file_exists( $candidate ) ) {
141 $preload = include $candidate;
142 break;
143 }
144 }
145
146 $inline = '(function(){var k="bookticsI18nLoader"; if (typeof window[k] === "undefined") { window[k] = {}; } window[k].state = ' . wp_json_encode( $data, JSON_UNESCAPED_SLASHES ) . ';';
147
148 if ( is_array( $preload ) && ! empty( $preload['messages'] ) && is_array( $preload['messages'] ) ) {
149 $messages = [];
150 foreach ( $preload['messages'] as $msgid => $msgstr ) {
151 if ( is_string( $msgid ) && is_string( $msgstr ) ) {
152 $messages[ $msgid ] = [ $msgstr ];
153 }
154 }
155
156 $locale_data = [
157 '' => [
158 'domain' => 'booktics',
159 'lang' => $data['locale'],
160 'plural-forms' => isset( $preload['plural-forms'] ) ? $preload['plural-forms'] : 'nplurals=2; plural=n != 1;',
161 ],
162 ] + $messages;
163
164 $encoded_locale_data = wp_json_encode( $locale_data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
165 $inline .= ' window[k].preloadedLocaleData = ' . $encoded_locale_data . '; window.bookticsPreloadedLocaleData = ' . $encoded_locale_data . ';';
166 }
167
168 $inline .= '})();';
169
170 wp_add_inline_script(
171 'booktics-i18n-loader',
172 $inline,
173 'before'
174 );
175 }
176
177 /**
178 * Register styles
179 *
180 * @return void
181 */
182 public function register_styles() {
183 $styles = $this->get_styles();
184
185 foreach ( $styles as $handle => $style ) {
186 $deps = isset( $style['deps'] ) ? $style['deps'] : false;
187 $version = booktics()->version;
188
189 wp_register_style( $handle, $style['src'], $deps, $version );
190 }
191 }
192
193 /**
194 * Get script and style file dependencies
195 *
196 * @param string $file_name
197 * @param array $deps
198 *
199 * @return array
200 */
201 private function get_dependencies( $file_name, $deps = [] ) {
202 $assets = $this->get_file_assets( $file_name );
203
204 $assets_deps = ! empty( $assets['dependencies'] ) ? $assets['dependencies'] : [];
205
206 $merged_deps = array_merge( $assets_deps, $deps );
207
208 return $merged_deps;
209 }
210
211 /**
212 * Get file assets
213 *
214 * @param string $file_name
215 *
216 * @return array
217 */
218 private function get_file_assets( $file_url ) {
219 $file = $this->get_file_path( $file_url );
220 $assets = [];
221
222 if ( file_exists( $file ) ) {
223 $assets = include $file;
224 }
225
226 return $assets;
227 }
228
229 /**
230 * Get script file version from .asset.php (generated by DependencyExtractionWebpackPlugin).
231 *
232 * @param string $file_name
233 *
234 * @return string
235 */
236 private function get_version( $file_name ) {
237 $assets = $this->get_file_assets( $file_name );
238 $assets_vers = ! empty( $assets['version'] ) ? $assets['version'] : booktics()->version;
239 return $assets_vers;
240 }
241
242 /**
243 * Get file path from url
244 *
245 * @param string $url
246 *
247 * @return string|false
248 */
249 private function get_file_path( $url ) {
250 if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
251 return false;
252 }
253
254 $url_parts = wp_parse_url( $url );
255
256 if ( ! isset( $url_parts['path'] ) ) {
257 return false;
258 }
259
260 $path = $url_parts['path'];
261 $path = preg_replace( '/\.js$/', '.asset.php', $path );
262
263 if ( isset( $_SERVER['DOCUMENT_ROOT'] ) ) {
264 $file_path = sanitize_text_field( wp_unslash( $_SERVER['DOCUMENT_ROOT'] ) ) . $path;
265 } else {
266 $file_path = '';
267 }
268
269 if ( ! file_exists( $file_path ) ) {
270 return false;
271 }
272
273 return $file_path;
274 }
275
276 /**
277 * Get map of translation file hashes to their URLs.
278 *
279 * @return array Hash => URL map.
280 */
281 private function get_translation_map() {
282 $map = [];
283 $locale = determine_locale();
284 $domain = 'booktics';
285
286 $locale_variants = array_unique( array_filter( [
287 $locale,
288 str_replace( '-', '_', $locale ),
289 str_replace( '_', '-', $locale ),
290 ] ) );
291
292 foreach ( $this->get_translation_directories() as $dir ) {
293 if ( ! is_dir( $dir['path'] ) || ! is_readable( $dir['path'] ) ) {
294 continue;
295 }
296
297 foreach ( $locale_variants as $variant ) {
298 $files = glob( $dir['path'] . $domain . '-' . $variant . '-*.json' );
299 if ( ! $files ) {
300 continue;
301 }
302
303 foreach ( $files as $file ) {
304 $filename = basename( $file );
305 $variant_prefix = $domain . '-' . $variant . '-';
306 if ( strpos( $filename, $variant_prefix ) === 0 ) {
307 $hash = substr( $filename, strlen( $variant_prefix ), -5 );
308 if ( $hash ) {
309 $map[ $hash ] = trailingslashit( $dir['url'] ) . $filename;
310 }
311 }
312 }
313 }
314 }
315
316 return $map;
317 }
318
319 /**
320 * Return translation directory paths and their corresponding URLs.
321 *
322 * @return array<int, array{path: string, url: string}>
323 */
324 private function get_translation_directories() {
325 return [
326 [
327 'path' => WP_CONTENT_DIR . '/languages/plugins/',
328 'url' => content_url( 'languages/plugins/' ),
329 ],
330 [
331 'path' => WP_CONTENT_DIR . '/languages/loco/plugins/',
332 'url' => content_url( 'languages/loco/plugins/' ),
333 ],
334 [
335 'path' => booktics()->plugin_directory . '/languages/',
336 'url' => booktics()->plugin_url . '/languages/',
337 ],
338 ];
339 }
340 }
341