diff --git a/composer.lock b/composer.lock index 2eb62496..3431a69f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,15 +4,15 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2515a741b96fa37d6948af9180e18465", + "content-hash": "4fb7f6fc290cb7d4d181f7dcb6c92c7b", "packages": [ { "name": "automattic/jetpack-mu-wpcom", - "version": "5.1.0-alpha.1700744018", + "version": "5.1.0-alpha.1700808594", "dist": { "type": "path", "url": "/tmp/jetpack-build/Automattic/jetpack-mu-wpcom", - "reference": "a7a749b593ee5863eb5d57a5ee75f7a2651b113b" + "reference": "4aafbcf87449fb5d560daffd92e75b50c323b8e4" }, "require": { "php": ">=7.0" @@ -81,7 +81,7 @@ "dist": { "type": "path", "url": "/tmp/jetpack-build/Automattic/jetpack-changelogger", - "reference": "3dd43eeeba411947bc3ea1b3f912c0a614bccebe" + "reference": "394cff87141319eed9726d2a8a496ef8af7aa5ac" }, "require": { "php": ">=7.0", diff --git a/vendor/automattic/jetpack-mu-wpcom/CHANGELOG.md b/vendor/automattic/jetpack-mu-wpcom/CHANGELOG.md index 8cb6277d..97b6de81 100644 --- a/vendor/automattic/jetpack-mu-wpcom/CHANGELOG.md +++ b/vendor/automattic/jetpack-mu-wpcom/CHANGELOG.md @@ -11,6 +11,7 @@ This is an alpha version! The changes listed here are not final. ### Added - Add dynamic titles to task lists +- Migrate Block Patterns ### Changed - Code Modernization: Replace usage of strpos() with str_contains() diff --git a/vendor/automattic/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php b/vendor/automattic/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php index d535f7d0..ee264a3b 100644 --- a/vendor/automattic/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php +++ b/vendor/automattic/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php @@ -66,6 +66,8 @@ public static function load_features() { require_once __DIR__ . '/features/100-year-plan/locked-mode.php'; require_once __DIR__ . '/features/media/heif-support.php'; + + require_once __DIR__ . '/features/block-patterns/block-patterns.php'; } /** diff --git a/vendor/automattic/jetpack-mu-wpcom/src/features/block-patterns/README.md b/vendor/automattic/jetpack-mu-wpcom/src/features/block-patterns/README.md new file mode 100644 index 00000000..41714edd --- /dev/null +++ b/vendor/automattic/jetpack-mu-wpcom/src/features/block-patterns/README.md @@ -0,0 +1,13 @@ +# Block Patterns + +## Adding a new pattern + +Please add any new block pattern to the `patterns` folder within this module. +Every file in that folder gets automatically included registered as a block pattern. + +There are two ways to add a new pattern, depending on whether it contains text or images that need to be localized: + +1. A json file for static block patterns. +1. A php file for dynamic block patterns that need localization. + +Please refer the Image and Description pattern as an example for a dynamic pattern that needs translation. diff --git a/vendor/automattic/jetpack-mu-wpcom/src/features/block-patterns/block-patterns.php b/vendor/automattic/jetpack-mu-wpcom/src/features/block-patterns/block-patterns.php new file mode 100644 index 00000000..a4eb7e47 --- /dev/null +++ b/vendor/automattic/jetpack-mu-wpcom/src/features/block-patterns/block-patterns.php @@ -0,0 +1,77 @@ +get_registered( $pattern_name ); + if ( $pattern ) { + unregister_block_pattern( $pattern_name ); + register_block_pattern( + $pattern_name, + $pattern + ); + } + } +} + +/** + * Return a function that loads and register block patterns from the API. This + * function can be registered to the `rest_dispatch_request` filter. + * + * @param Function $register_patterns_func A function that when called will + * register the relevant block patterns in the registry. + */ +function register_patterns_on_api_request( $register_patterns_func ) { + /** + * Load editing toolkit block patterns from the API. + * + * It will only register the patterns for certain allowed requests and + * return early otherwise. + * + * @param mixed $response + * @param WP_REST_Request $request + */ + return function ( $response, $request ) use ( $register_patterns_func ) { + /** + * Do nothing if it is loaded in the ETK. + */ + if ( class_exists( 'A8C\FSE\Block_Patterns_From_API' ) ) { + return $response; + } + + $route = $request->get_route(); + // Matches either /wp/v2/sites/123/block-patterns/patterns or /wp/v2/block-patterns/patterns + // to handle the API format of both WordPress.com and WordPress core. + $request_allowed = preg_match( '/^\/wp\/v2\/(sites\/[0-9]+\/)?block\-patterns\/(patterns|categories)$/', $route ); + + if ( ! $request_allowed || ! apply_filters( 'a8c_enable_block_patterns_api', false ) ) { + return $response; + } + + $register_patterns_func(); + + wpcom_reorder_curated_core_patterns(); + + return $response; + }; +} +add_filter( + 'rest_dispatch_request', + register_patterns_on_api_request( + function () { + require_once __DIR__ . '/class-wpcom-block-patterns-from-api.php'; + ( new Wpcom_Block_Patterns_From_Api() )->register_patterns(); + } + ), + 11, + 2 +); diff --git a/vendor/automattic/jetpack-mu-wpcom/src/features/block-patterns/class-wpcom-block-patterns-from-api.php b/vendor/automattic/jetpack-mu-wpcom/src/features/block-patterns/class-wpcom-block-patterns-from-api.php new file mode 100644 index 00000000..75410298 --- /dev/null +++ b/vendor/automattic/jetpack-mu-wpcom/src/features/block-patterns/class-wpcom-block-patterns-from-api.php @@ -0,0 +1,328 @@ +register_patterns() + * + * @var array + */ + private $core_to_wpcom_categories_dictionary; + + /** + * Block_Patterns constructor. + * + * @param Wpcom_Block_Patterns_Utils|null $utils A class dependency containing utils methods. + */ + public function __construct( Wpcom_Block_Patterns_Utils $utils = null ) { + $this->patterns_sources = array( 'block_patterns' ); + + $this->utils = empty( $utils ) ? new Wpcom_Block_Patterns_Utils() : $utils; + + // Add categories to this array using the core pattern name as the key for core patterns we wish to "recategorize". + $this->core_to_wpcom_categories_dictionary = array( + 'core/quote' => array( + 'quotes' => __( 'Quotes', 'jetpack-mu-wpcom' ), + 'text' => __( 'Text', 'jetpack-mu-wpcom' ), + ), + ); + } + + /** + * Register FSE block patterns and categories. + * + * @return array Results of pattern registration. + */ + public function register_patterns() { + // Used to track which patterns we successfully register. + $results = array(); + + // For every pattern source site, fetch the patterns. + foreach ( $this->patterns_sources as $patterns_source ) { + $patterns_cache_key = $this->utils->get_patterns_cache_key( $patterns_source ); + + $pattern_categories = array(); + $block_patterns = $this->get_patterns( $patterns_cache_key, $patterns_source ); + + foreach ( (array) $block_patterns as $pattern ) { + foreach ( (array) $pattern['categories'] as $slug => $category ) { + // Register categories from first pattern in each category. + if ( ! isset( $pattern_categories[ $slug ] ) ) { + $pattern_categories[ $slug ] = array( + 'label' => $category['title'], + 'description' => $category['description'], + ); + } + } + } + + // Unregister existing categories so that we can insert them in the desired order (alphabetically). + $existing_categories = array(); + foreach ( \WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered() as $existing_category ) { + $existing_categories[ $existing_category['name'] ] = $existing_category; + unregister_block_pattern_category( $existing_category['name'] ); + } + + // Existing categories are registered in Gutenberg or other plugins. + // We overwrite them with the categories from Dotcom patterns. + $pattern_categories = array_merge( $existing_categories, $pattern_categories ); + + // Order categories alphabetically by their label. + uasort( + $pattern_categories, + function ( $a, $b ) { + return strnatcasecmp( $a['label'], $b['label'] ); + } + ); + + // Move the Featured category to be the first category. + if ( isset( $pattern_categories['featured'] ) ) { + $featured_category = $pattern_categories['featured']; + $pattern_categories = array( 'featured' => $featured_category ) + $pattern_categories; + } + + // Register categories (and re-register existing categories). + foreach ( (array) $pattern_categories as $slug => &$category_properties ) { + // Rename category labels. + if ( 'posts' === $slug ) { + $category_properties['label'] = __( + 'Blog Posts', + 'jetpack-mu-wpcom' + ); + } elseif ( 'testimonials' === $slug ) { + $category_properties['label'] = __( + 'Quotes', + 'jetpack-mu-wpcom' + ); + } + register_block_pattern_category( $slug, $category_properties ); + } + + foreach ( (array) $block_patterns as &$pattern ) { + if ( $this->can_register_pattern( $pattern ) ) { + $is_premium = isset( $pattern['pattern_meta']['is_premium'] ) ? boolval( $pattern['pattern_meta']['is_premium'] ) : false; + + // Set custom viewport width for the pattern preview with a + // default width of 1280 and ensure a safe minimum width of 320. + $viewport_width = isset( $pattern['pattern_meta']['viewport_width'] ) ? intval( $pattern['pattern_meta']['viewport_width'] ) : 1280; + $viewport_width = $viewport_width < 320 ? 320 : $viewport_width; + $pattern_name = self::PATTERN_NAMESPACE . $pattern['name']; + $block_types = $this->utils->maybe_get_pattern_block_types_from_pattern_meta( $pattern ); + + $results[ $pattern_name ] = register_block_pattern( + $pattern_name, + array( + 'title' => $pattern['title'], + 'description' => $pattern['description'], + 'content' => $pattern['html'], + 'viewportWidth' => $viewport_width, + 'categories' => array_keys( + $pattern['categories'] + ), + 'isPremium' => $is_premium, + 'blockTypes' => $block_types, + ) + ); + } + } + } + + $this->update_core_patterns_with_wpcom_categories(); + $this->update_pattern_block_types(); + + // Temporarily removing the call to `update_pattern_post_types` while we investigate + // https://github.com/Automattic/wp-calypso/issues/79145. + + return $results; + } + + /** + * Returns a list of patterns. + * + * @param string $patterns_cache_key Key to store responses to and fetch responses from cache. + * @param string $patterns_source Slug for valid patterns source site, e.g., `block_patterns`. + * @return array The list of translated patterns. + */ + private function get_patterns( $patterns_cache_key, $patterns_source ) { + $override_source_site = apply_filters( 'a8c_override_patterns_source_site', false ); + if ( $override_source_site ) { + // Skip caching and request all patterns from a specified source site. + // This allows testing patterns in development with immediate feedback + // while avoiding polluting the cache. Note that this request gets + // all patterns on the source site, not just those with the 'pattern' tag. + $request_url = esc_url_raw( + add_query_arg( + array( + 'site' => $override_source_site, + 'tags' => 'pattern', + 'pattern_meta' => 'is_web', + ), + 'https://public-api.wordpress.com/rest/v1/ptk/patterns/' . $this->utils->get_block_patterns_locale() + ) + ); + + return $this->utils->remote_get( $request_url ); + } + + $block_patterns = $this->utils->cache_get( $patterns_cache_key, 'ptk_patterns' ); + + // Load fresh data if we don't have any patterns. + if ( false === $block_patterns || ( defined( 'WP_DISABLE_PATTERN_CACHE' ) && WP_DISABLE_PATTERN_CACHE ) ) { + $request_url = esc_url_raw( + add_query_arg( + array( + 'tags' => 'pattern', + 'pattern_meta' => 'is_web', + 'patterns_source' => $patterns_source, + ), + 'https://public-api.wordpress.com/rest/v1/ptk/patterns/' . $this->utils->get_block_patterns_locale() + ) + ); + + $block_patterns = $this->utils->remote_get( $request_url ); + + $this->utils->cache_add( $patterns_cache_key, $block_patterns, 'ptk_patterns', DAY_IN_SECONDS ); + } + + return $block_patterns; + } + + /** + * Check that the pattern is allowed to be registered. + * + * Checks for pattern_meta tags with a prefix of `requires-` in the name, and then attempts to match + * the remainder of the name to a theme feature. + * + * For example, to prevent patterns that depend on wide or full-width block alignment support + * from being registered in sites where the active theme does not have `align-wide` support, + * we can add the `requires-align-wide` pattern_meta tag to the pattern. This function will + * then match against that pattern_meta tag, and then return `false`. + * + * @param array $pattern A pattern with a 'pattern_meta' array where the key is the tag slug in English. + * + * @return bool + */ + private function can_register_pattern( $pattern ) { + if ( empty( $pattern['pattern_meta'] ) ) { + // Default to allowing patterns without metadata to be registered. + return true; + } + + foreach ( $pattern['pattern_meta'] as $pattern_meta => $value ) { + // Match against tags with a non-translated slug beginning with `requires-`. + $split_slug = preg_split( '/^requires-/', $pattern_meta ); + + // If the theme does not support the matched feature, then skip registering the pattern. + if ( isset( $split_slug[1] ) && false === get_theme_support( $split_slug[1] ) ) { + return false; + } + } + + return true; + } + + /** + * Update categories for core patterns if a records exists in $this->core_to_wpcom_categories_dictionary + * and re-registers them. + */ + private function update_core_patterns_with_wpcom_categories() { + if ( class_exists( 'WP_Block_Patterns_Registry' ) ) { + foreach ( \WP_Block_Patterns_Registry::get_instance()->get_all_registered() as $pattern ) { + $wpcom_categories = + $pattern['name'] && isset( $this->core_to_wpcom_categories_dictionary[ $pattern['name'] ] ) + ? $this->core_to_wpcom_categories_dictionary[ $pattern['name'] ] + : null; + if ( $wpcom_categories ) { + unregister_block_pattern( $pattern['name'] ); + $pattern_properties = array_merge( + $pattern, + array( 'categories' => array_keys( $wpcom_categories ) ) + ); + unset( $pattern_properties['name'] ); + register_block_pattern( + $pattern['name'], + $pattern_properties + ); + } + } + } + } + + /** + * Ensure that all patterns with a blockType property are registered with appropriate postTypes. + */ + private function update_pattern_post_types() { + if ( ! class_exists( 'WP_Block_Patterns_Registry' ) ) { + return; + } + foreach ( \WP_Block_Patterns_Registry::get_instance()->get_all_registered() as $pattern ) { + if ( array_key_exists( 'postTypes', $pattern ) && $pattern['postTypes'] ) { + continue; + } + + $post_types = $this->utils->get_pattern_post_types_from_pattern( $pattern ); + if ( $post_types ) { + unregister_block_pattern( $pattern['name'] ); + + $pattern['postTypes'] = $post_types; + $pattern_name = $pattern['name']; + unset( $pattern['name'] ); + register_block_pattern( $pattern_name, $pattern ); + } + } + } + + /** + * Ensure that all patterns with a blockType property are registered with appropriate postTypes. + */ + private function update_pattern_block_types() { + if ( ! class_exists( 'WP_Block_Patterns_Registry' ) ) { + return; + } + foreach ( \WP_Block_Patterns_Registry::get_instance()->get_all_registered() as $pattern ) { + if ( ! array_key_exists( 'blockTypes', $pattern ) || empty( $pattern['blockTypes'] ) ) { + continue; + } + + $post_content_offset = array_search( 'core/post-content', $pattern['blockTypes'], true ); + if ( $post_content_offset !== false ) { + unregister_block_pattern( $pattern['name'] ); + + $pattern['blockTypes'] = array_splice( $pattern['blockTypes'], $post_content_offset, 1 ); + $pattern_name = $pattern['name']; + unset( $pattern['name'] ); + register_block_pattern( $pattern_name, $pattern ); + } + } + } +} diff --git a/vendor/automattic/jetpack-mu-wpcom/src/features/block-patterns/class-wpcom-block-patterns-utils.php b/vendor/automattic/jetpack-mu-wpcom/src/features/block-patterns/class-wpcom-block-patterns-utils.php new file mode 100644 index 00000000..9e390f09 --- /dev/null +++ b/vendor/automattic/jetpack-mu-wpcom/src/features/block-patterns/class-wpcom-block-patterns-utils.php @@ -0,0 +1,151 @@ + 20 ); + + if ( function_exists( 'wpcom_json_api_get' ) ) { + $response = wpcom_json_api_get( $request_url, $args ); + } else { + $response = wp_remote_get( $request_url, $args ); + } + + if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { + return array(); + } + return json_decode( wp_remote_retrieve_body( $response ), true ); + } + + /** + * A wrapper for wp_cache_add. + * + * @param int|string $key The cache key to use for retrieval later. + * @param mixed $data The data to add to the cache. + * @param string $group The group to add the cache to. Enables the same key to be used across groups. Default empty. + * @param int $expire When the cache data should expire, in seconds. + * Default 0 (no expiration). + * @return bool True on success, false if cache key and group already exist. + */ + public function cache_add( $key, $data, $group, $expire ) { + return wp_cache_add( $key, $data, $group, $expire ); + } + + /** + * A wrapper for wp_cache_get. + * + * @param int|string $key The key under which the cache contents are stored. + * @param string $group Where the cache contents are grouped. Default empty. + * @return mixed|false The cache contents on success, false on failure to retrieve contents. + */ + public function cache_get( $key, $group ) { + return wp_cache_get( $key, $group ); + } + + /** + * Returns the sha1 hash of a concatenated string to use as a cache key. + * + * @param string $patterns_slug A slug for a patterns source site, e.g., `block_patterns`. + * @return string locale slug + */ + public function get_patterns_cache_key( $patterns_slug ) { + return sha1( + implode( + '_', + array( + $patterns_slug, + Jetpack_Mu_Wpcom::PACKAGE_VERSION, + $this->get_block_patterns_locale(), + ) + ) + ); + } + + /** + * Get the locale to be used for fetching block patterns + * + * @return string locale slug + */ + public function get_block_patterns_locale() { + // Block patterns display in the user locale. + $language = get_user_locale(); + return Common\get_iso_639_locale( $language ); + } + + /** + * Check for block type values in the pattern_meta tag. + * When tags have a prefix of `block_type_`, we expect the remaining suffix to be a blockType value. + * We'll add these values to the `(array) blockType` options property when registering the pattern + * via `register_block_pattern`. + * + * @param array $pattern A pattern with a 'pattern_meta' array. + * + * @return array An array of block types defined in pattern meta. + */ + public function maybe_get_pattern_block_types_from_pattern_meta( $pattern ) { + $block_types = array(); + + if ( ! isset( $pattern['pattern_meta'] ) || empty( $pattern['pattern_meta'] ) ) { + return $block_types; + } + + foreach ( $pattern['pattern_meta'] as $pattern_meta => $value ) { + // Match against tags starting with `block_type_`. + $split_slug = preg_split( '/^block_type_/', $pattern_meta ); + + if ( isset( $split_slug[1] ) ) { + $block_types[] = $split_slug[1]; + } + } + + return $block_types; + } + + /** + * Return pattern post types based on the pattern's blockTypes. + * + * @param array $pattern A pattern array such as is passed to `register_block_pattern`. + * + * @return array $postTypes An array of post type names such as is passed to `register_block_pattern`. + */ + public function get_pattern_post_types_from_pattern( $pattern ) { + $post_types = array_key_exists( 'postTypes', $pattern ) ? $pattern['postTypes'] : array(); + if ( $post_types ) { + // If some postTypes are explicitly set then respect the pattern author's intent. + return $post_types; + } + + $block_types = array_key_exists( 'blockTypes', $pattern ) ? $pattern['blockTypes'] : array(); + $block_types_count = count( $block_types ); + $template_parts = array_filter( + $block_types, + function ( $block_type ) { + return preg_match( '#core/template-part/#', $block_type ); + } + ); + // If all of a patterns blockTypes are template-parts then limit the postTypes to just + // the template related types and to pages - this is to avoid the pattern appearing in + // the inserter for posts and other post types. Pages are included because it's not unusual + // to use a blank template and add a specific header and footer to a page. + if ( $block_types_count && count( $template_parts ) === $block_types_count ) { + $post_types = array( 'wp_template', 'wp_template_part', 'page' ); + } + return $post_types; + } +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 038ca58e..341ffd6e 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -12,4 +12,6 @@ 'Marketplace_Products_Updater' => $vendorDir . '/automattic/jetpack-mu-wpcom/src/features/marketplace-products-updater/class-marketplace-products-updater.php', 'WPCOM_REST_API_V2_Endpoint_Launchpad' => $vendorDir . '/automattic/jetpack-mu-wpcom/src/features/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-launchpad.php', 'WPCOM_REST_API_V2_Endpoint_Launchpad_Navigator' => $vendorDir . '/automattic/jetpack-mu-wpcom/src/features/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-launchpad-navigator.php', + 'Wpcom_Block_Patterns_From_Api' => $vendorDir . '/automattic/jetpack-mu-wpcom/src/features/block-patterns/class-wpcom-block-patterns-from-api.php', + 'Wpcom_Block_Patterns_Utils' => $vendorDir . '/automattic/jetpack-mu-wpcom/src/features/block-patterns/class-wpcom-block-patterns-utils.php', ); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index d8b98342..d9639e51 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -13,6 +13,8 @@ class ComposerStaticInitd9d132a783958a00a2c7cccff60ca42d_jetpack_mu_wpcom_plugin 'Marketplace_Products_Updater' => __DIR__ . '/..' . '/automattic/jetpack-mu-wpcom/src/features/marketplace-products-updater/class-marketplace-products-updater.php', 'WPCOM_REST_API_V2_Endpoint_Launchpad' => __DIR__ . '/..' . '/automattic/jetpack-mu-wpcom/src/features/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-launchpad.php', 'WPCOM_REST_API_V2_Endpoint_Launchpad_Navigator' => __DIR__ . '/..' . '/automattic/jetpack-mu-wpcom/src/features/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-launchpad-navigator.php', + 'Wpcom_Block_Patterns_From_Api' => __DIR__ . '/..' . '/automattic/jetpack-mu-wpcom/src/features/block-patterns/class-wpcom-block-patterns-from-api.php', + 'Wpcom_Block_Patterns_Utils' => __DIR__ . '/..' . '/automattic/jetpack-mu-wpcom/src/features/block-patterns/class-wpcom-block-patterns-utils.php', ); public static function getInitializer(ClassLoader $loader) diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index c05a2276..fc2d295e 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -2,12 +2,12 @@ "packages": [ { "name": "automattic/jetpack-mu-wpcom", - "version": "5.1.0-alpha.1700744018", - "version_normalized": "5.1.0.0-alpha1700744018", + "version": "5.1.0-alpha.1700808594", + "version_normalized": "5.1.0.0-alpha1700808594", "dist": { "type": "path", "url": "/tmp/jetpack-build/Automattic/jetpack-mu-wpcom", - "reference": "a7a749b593ee5863eb5d57a5ee75f7a2651b113b" + "reference": "4aafbcf87449fb5d560daffd92e75b50c323b8e4" }, "require": { "php": ">=7.0" diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 9fbe100f..a4c04e86 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -11,9 +11,9 @@ ), 'versions' => array( 'automattic/jetpack-mu-wpcom' => array( - 'pretty_version' => '5.1.0-alpha.1700744018', - 'version' => '5.1.0.0-alpha1700744018', - 'reference' => 'a7a749b593ee5863eb5d57a5ee75f7a2651b113b', + 'pretty_version' => '5.1.0-alpha.1700808594', + 'version' => '5.1.0.0-alpha1700808594', + 'reference' => '4aafbcf87449fb5d560daffd92e75b50c323b8e4', 'type' => 'jetpack-library', 'install_path' => __DIR__ . '/../automattic/jetpack-mu-wpcom', 'aliases' => array(),