register_global_scripts(); $this->register_scripts(); $this->register_styles(); } /** * Register scripts * * @return void */ public function register_scripts() { $scripts = $this->get_scripts(); foreach ( $scripts as $handle => $script ) { $deps = isset( $script['deps'] ) ? $script['deps'] : []; $in_footer = isset( $script['in_footer'] ) ? $script['in_footer'] : true; $version = isset( $script['version'] ) ? $script['version'] : $this->get_version( $script['src'] ); $deps = $this->get_dependencies( $script['src'], $deps ); if ( in_array( 'wp-i18n', $deps, true ) ) { $deps[] = 'booktics-i18n-loader'; } wp_register_script( $handle, $script['src'], $deps, $version, $in_footer ); if ( function_exists( 'wp_set_script_translations' ) ) { wp_set_script_translations( $handle, 'booktics' ); } if ( 'booktics-packages' === $handle ) { wp_add_inline_script( 'booktics-packages', '(function(){try{if(window.bookticsPreloadedLocaleData && window.wp && window.wp.i18n && window.wp.i18n.setLocaleData){window.wp.i18n.setLocaleData(window.bookticsPreloadedLocaleData,"booktics");}}catch(e){}})();', 'before' ); } } } /** * Register global scripts. * * @return void */ private function register_global_scripts() { $scripts = [ 'booktics-i18n-loader' => [ 'src' => booktics()->assets_url . '/build/js/i18n-loader.js', 'deps' => [], 'in_footer' => true, ], ]; foreach ( $scripts as $handle => $script ) { $deps = isset( $script['deps'] ) ? $script['deps'] : []; $in_footer = isset( $script['in_footer'] ) ? $script['in_footer'] : true; $version = isset( $script['version'] ) ? $script['version'] : $this->get_version( $script['src'] ); $deps = $this->get_dependencies( $script['src'], $deps ); wp_register_script( $handle, $script['src'], $deps, $version, $in_footer ); } } /** * Enqueue i18n loader and set its state. * * @return void */ protected function enqueue_i18n_loader() { $data = [ 'baseUrl' => false, 'locale' => determine_locale(), 'domainMap' => [], 'domainPaths' => [], 'translationMap' => (object) [], ]; $lang_dir = WP_LANG_DIR; $content_dir = WP_CONTENT_DIR; $abspath = ABSPATH; if ( strpos( $lang_dir, $content_dir ) === 0 ) { $data['baseUrl'] = content_url( substr( trailingslashit( $lang_dir ), strlen( trailingslashit( $content_dir ) ) ) ); } elseif ( strpos( $lang_dir, $abspath ) === 0 ) { $data['baseUrl'] = site_url( substr( trailingslashit( $lang_dir ), strlen( untrailingslashit( $abspath ) ) ) ); } $data['translationMap'] = (object) $this->get_translation_map(); $data['domainPaths'] = (object) $this->get_translation_directories(); wp_enqueue_script( 'booktics-i18n-loader' ); $data['domainMap'] = (object) $data['domainMap']; $data['domainPaths'] = (object) $data['domainPaths']; $preload = null; $l10n_file = trailingslashit( WP_LANG_DIR ) . 'plugins/booktics-' . $data['locale'] . '.l10n.php'; $l10n_file_alt = trailingslashit( WP_LANG_DIR ) . 'plugins/booktics-' . str_replace( '-', '_', $data['locale'] ) . '.l10n.php'; $l10n_file_legacy = trailingslashit( WP_LANG_DIR ) . 'plugins/booktics-' . str_replace( '_', '-', $data['locale'] ) . '.l10n.php'; $l10n_candidates = array_unique( array_filter( [ $l10n_file, $l10n_file_alt, $l10n_file_legacy ] ) ); foreach ( $l10n_candidates as $candidate ) { if ( file_exists( $candidate ) ) { $preload = include $candidate; break; } } $inline = '(function(){var k="bookticsI18nLoader"; if (typeof window[k] === "undefined") { window[k] = {}; } window[k].state = ' . wp_json_encode( $data, JSON_UNESCAPED_SLASHES ) . ';'; if ( is_array( $preload ) && ! empty( $preload['messages'] ) && is_array( $preload['messages'] ) ) { $messages = []; foreach ( $preload['messages'] as $msgid => $msgstr ) { if ( is_string( $msgid ) && is_string( $msgstr ) ) { $messages[ $msgid ] = [ $msgstr ]; } } $locale_data = [ '' => [ 'domain' => 'booktics', 'lang' => $data['locale'], 'plural-forms' => isset( $preload['plural-forms'] ) ? $preload['plural-forms'] : 'nplurals=2; plural=n != 1;', ], ] + $messages; $encoded_locale_data = wp_json_encode( $locale_data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ); $inline .= ' window[k].preloadedLocaleData = ' . $encoded_locale_data . '; window.bookticsPreloadedLocaleData = ' . $encoded_locale_data . ';'; } $inline .= '})();'; wp_add_inline_script( 'booktics-i18n-loader', $inline, 'before' ); } /** * Register styles * * @return void */ public function register_styles() { $styles = $this->get_styles(); foreach ( $styles as $handle => $style ) { $deps = isset( $style['deps'] ) ? $style['deps'] : false; $version = booktics()->version; wp_register_style( $handle, $style['src'], $deps, $version ); } } /** * Get script and style file dependencies * * @param string $file_name * @param array $deps * * @return array */ private function get_dependencies( $file_name, $deps = [] ) { $assets = $this->get_file_assets( $file_name ); $assets_deps = ! empty( $assets['dependencies'] ) ? $assets['dependencies'] : []; $merged_deps = array_merge( $assets_deps, $deps ); return $merged_deps; } /** * Get file assets * * @param string $file_name * * @return array */ private function get_file_assets( $file_url ) { $file = $this->get_file_path( $file_url ); $assets = []; if ( file_exists( $file ) ) { $assets = include $file; } return $assets; } /** * Get script file version from .asset.php (generated by DependencyExtractionWebpackPlugin). * * @param string $file_name * * @return string */ private function get_version( $file_name ) { $assets = $this->get_file_assets( $file_name ); $assets_vers = ! empty( $assets['version'] ) ? $assets['version'] : booktics()->version; return $assets_vers; } /** * Get file path from url * * @param string $url * * @return string|false */ private function get_file_path( $url ) { if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) { return false; } $url_parts = wp_parse_url( $url ); if ( ! isset( $url_parts['path'] ) ) { return false; } $path = $url_parts['path']; $path = preg_replace( '/\.js$/', '.asset.php', $path ); if ( isset( $_SERVER['DOCUMENT_ROOT'] ) ) { $file_path = sanitize_text_field( wp_unslash( $_SERVER['DOCUMENT_ROOT'] ) ) . $path; } else { $file_path = ''; } if ( ! file_exists( $file_path ) ) { return false; } return $file_path; } /** * Get map of translation file hashes to their URLs. * * @return array Hash => URL map. */ private function get_translation_map() { $map = []; $locale = determine_locale(); $domain = 'booktics'; $locale_variants = array_unique( array_filter( [ $locale, str_replace( '-', '_', $locale ), str_replace( '_', '-', $locale ), ] ) ); foreach ( $this->get_translation_directories() as $dir ) { if ( ! is_dir( $dir['path'] ) || ! is_readable( $dir['path'] ) ) { continue; } foreach ( $locale_variants as $variant ) { $files = glob( $dir['path'] . $domain . '-' . $variant . '-*.json' ); if ( ! $files ) { continue; } foreach ( $files as $file ) { $filename = basename( $file ); $variant_prefix = $domain . '-' . $variant . '-'; if ( strpos( $filename, $variant_prefix ) === 0 ) { $hash = substr( $filename, strlen( $variant_prefix ), -5 ); if ( $hash ) { $map[ $hash ] = trailingslashit( $dir['url'] ) . $filename; } } } } } return $map; } /** * Return translation directory paths and their corresponding URLs. * * @return array */ private function get_translation_directories() { return [ [ 'path' => WP_CONTENT_DIR . '/languages/plugins/', 'url' => content_url( 'languages/plugins/' ), ], [ 'path' => WP_CONTENT_DIR . '/languages/loco/plugins/', 'url' => content_url( 'languages/loco/plugins/' ), ], [ 'path' => booktics()->plugin_directory . '/languages/', 'url' => booktics()->plugin_url . '/languages/', ], ]; } }