Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
95.45% |
21 / 22 |
|
100.00% |
1 / 1 |
CRAP | n/a |
0 / 0 |
|
| wpcom_wp_build_script_translations | |
100.00% |
21 / 21 |
|
100.00% |
1 / 1 |
12 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Translations for mu-wpcom's wp-build pages. |
| 4 | * |
| 5 | * @package automattic/jetpack-mu-wpcom |
| 6 | */ |
| 7 | |
| 8 | if ( ! function_exists( 'wpcom_wp_build_script_translations' ) ) { |
| 9 | /** |
| 10 | * Inline JS that installs the translation catalogs of a page's wp-build bundles into `wp.i18n`. |
| 11 | * |
| 12 | * Core's `load_script_textdomain()` on a registered, never-enqueued handle per bundle picks up the |
| 13 | * platform filters that point this package's catalogs at `languages/mu-plugins/`, which no URL |
| 14 | * serves for the client-side loader the other wp-build dashboards use. |
| 15 | * |
| 16 | * @param string $manifest_file Path to the build's `i18n-manifest.json` (from `stamp-textdomains`). |
| 17 | * @param string $build_url URL of the build directory the bundles are served from. |
| 18 | * @param string|string[] $routes The wp-build route(s) whose bundles to cover, besides the shared modules and scripts. |
| 19 | * @param string $domain The text domain. |
| 20 | * @return string|null The inline script, or null when no bundle has a catalog for this locale. |
| 21 | */ |
| 22 | function wpcom_wp_build_script_translations( $manifest_file, $build_url, $routes, $domain = 'jetpack-mu-wpcom' ) { |
| 23 | if ( ! is_readable( $manifest_file ) ) { |
| 24 | return null; |
| 25 | } |
| 26 | $manifest = json_decode( (string) file_get_contents( $manifest_file ), true ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Local build artifact. |
| 27 | $bundles = is_array( $manifest ) && isset( $manifest['bundles'] ) && is_array( $manifest['bundles'] ) ? $manifest['bundles'] : array(); |
| 28 | |
| 29 | $pattern = implode( '|', array_map( static fn( $name ) => preg_quote( $name, '#' ), (array) $routes ) ); |
| 30 | $scripts = array(); |
| 31 | foreach ( $bundles as $index => $bundle ) { |
| 32 | // The manifest lists paths under the build directory's own name, e.g. `build/routes/x/content.js`. |
| 33 | if ( ! is_string( $bundle ) || ! preg_match( '#^[^/]+/(routes/(?:' . $pattern . ')|scripts|modules)/#', $bundle ) ) { |
| 34 | continue; |
| 35 | } |
| 36 | $handle = 'wpcom-wp-build-i18n-' . $index; |
| 37 | wp_register_script( $handle, trailingslashit( $build_url ) . substr( $bundle, strpos( $bundle, '/' ) + 1 ), array(), false, false ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NoExplicitVersion -- Never printed; only registered so core can locate its catalog. |
| 38 | $json = load_script_textdomain( $handle, $domain ); |
| 39 | wp_deregister_script( $handle ); |
| 40 | if ( ! $json ) { |
| 41 | continue; |
| 42 | } |
| 43 | |
| 44 | $data = json_decode( $json, true ); |
| 45 | $messages = $data['locale_data'][ $domain ] ?? $data['locale_data']['messages'] ?? null; |
| 46 | if ( ! is_array( $messages ) || array() === $messages ) { |
| 47 | continue; |
| 48 | } |
| 49 | // HEX_TAG keeps a literal "</script>" in a translation from closing the inline script tag. |
| 50 | $scripts[] = 'wp.i18n.setLocaleData( ' . wp_json_encode( $messages, JSON_HEX_TAG | JSON_HEX_AMP ) . ', ' . wp_json_encode( $domain, JSON_HEX_TAG | JSON_HEX_AMP ) . ' );'; |
| 51 | } |
| 52 | |
| 53 | return $scripts ? implode( "\n", $scripts ) : null; |
| 54 | } |
| 55 | } |