Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
43.75% covered (danger)
43.75%
21 / 48
12.50% covered (danger)
12.50%
1 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
Wpcom_Block_Patterns_Utils
43.75% covered (danger)
43.75%
21 / 48
12.50% covered (danger)
12.50%
1 / 8
136.24
0.00% covered (danger)
0.00%
0 / 1
 remote_get
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 cache_add
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 cache_get
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 get_patterns_cache_key
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 get_block_patterns_locale
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 maybe_get_pattern_block_types_from_pattern_meta
87.50% covered (warning)
87.50%
7 / 8
0.00% covered (danger)
0.00%
0 / 1
5.05
 get_block_types_from_categories
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
56
 get_pattern_post_types_from_pattern
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
6
1<?php
2/**
3 * Block Patterns Utils.
4 *
5 * @package automattic/jetpack-mu-wpcom
6 */
7
8use Automattic\Jetpack\Jetpack_Mu_Wpcom\Common;
9
10/**
11 * Class Wpcom_Block_Patterns_Utils
12 */
13class Wpcom_Block_Patterns_Utils {
14    /**
15     * Make remote get requests.
16     *
17     * @param string $request_url The request URL.
18     * @return array              The response.
19     */
20    public function remote_get( $request_url ) {
21        $args = array( 'timeout' => 20 );
22
23        if ( function_exists( 'wpcom_json_api_get' ) ) {
24            $response = wpcom_json_api_get( $request_url, $args );
25        } else {
26            $response = wp_remote_get( $request_url, $args );
27        }
28
29        if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
30            return array();
31        }
32        return json_decode( wp_remote_retrieve_body( $response ), true );
33    }
34
35    /**
36     * A wrapper for wp_cache_add.
37     *
38     * @param  int|string $key    The cache key to use for retrieval later.
39     * @param  mixed      $data   The data to add to the cache.
40     * @param  string     $group  The group to add the cache to. Enables the same key to be used across groups. Default empty.
41     * @param  int        $expire When the cache data should expire, in seconds.
42     *                            Default 0 (no expiration).
43     * @return bool               True on success, false if cache key and group already exist.
44     */
45    public function cache_add( $key, $data, $group, $expire ) {
46        return wp_cache_add( $key, $data, $group, $expire );
47    }
48
49    /**
50     * A wrapper for wp_cache_get.
51     *
52     * @param int|string $key   The key under which the cache contents are stored.
53     * @param string     $group Where the cache contents are grouped. Default empty.
54     * @return mixed|false      The cache contents on success, false on failure to retrieve contents.
55     */
56    public function cache_get( $key, $group ) {
57        return wp_cache_get( $key, $group );
58    }
59
60    /**
61     * Returns a cache key per locale.
62     *
63     * @return string locale slug
64     */
65    public function get_patterns_cache_key() {
66        return 'wpcom_block_patterns_' . $this->get_block_patterns_locale();
67    }
68
69    /**
70     * Get the locale to be used for fetching block patterns
71     *
72     * @return string locale slug
73     */
74    public function get_block_patterns_locale() {
75        // Block patterns display in the user locale.
76        $language = get_user_locale();
77        return Common\get_iso_639_locale( $language );
78    }
79
80    /**
81     * Check for block type values in the pattern_meta tag.
82     * When tags have a prefix of `block_type_`, we expect the remaining suffix to be a blockType value.
83     * We'll add these values to the `(array) blockType` options property when registering the pattern
84     * via `register_block_pattern`.
85     *
86     * @param array $pattern A pattern with a 'pattern_meta' array.
87     *
88     * @return array         An array of block types defined in pattern meta.
89     */
90    public function maybe_get_pattern_block_types_from_pattern_meta( $pattern ) {
91        $block_types = array();
92
93        if ( ! isset( $pattern['pattern_meta'] ) || empty( $pattern['pattern_meta'] ) ) {
94            return $block_types;
95        }
96
97        foreach ( $pattern['pattern_meta'] as $pattern_meta => $value ) {
98            // Match against tags starting with `block_type_`.
99            $split_slug = preg_split( '/^block_type_/', $pattern_meta );
100
101            if ( isset( $split_slug[1] ) ) {
102                $block_types[] = $split_slug[1];
103            }
104        }
105
106        return $block_types;
107    }
108
109    /**
110     * Using the pattern categories, generate the `blockTypes` property for
111     * registering the pattern via `register_block_pattern`.
112     *
113     * @param array $pattern A pattern with categories.
114     *
115     * @return array         An array of block types.
116     */
117    public function get_block_types_from_categories( $pattern ) {
118        $block_types = array();
119
120        if ( ! isset( $pattern['categories'] ) || empty( $pattern['categories'] ) ) {
121            return $block_types;
122        }
123
124        foreach ( $pattern['categories'] as $key => $value ) {
125            switch ( $key ) {
126                case 'header':
127                    $block_types[] = 'core/template-part/header';
128                    break;
129                case 'footer':
130                    $block_types[] = 'core/template-part/footer';
131                    break;
132                case 'posts':
133                    $block_types[] = 'core/query';
134                    break;
135            }
136        }
137
138        return $block_types;
139    }
140
141    /**
142     * Return pattern post types based on the pattern's blockTypes.
143     *
144     * @param array $pattern A pattern array such as is passed to `register_block_pattern`.
145     *
146     * @return array $postTypes An array of post type names such as is passed to `register_block_pattern`.
147     */
148    public function get_pattern_post_types_from_pattern( $pattern ) {
149        $post_types = array_key_exists( 'postTypes', $pattern ) ? $pattern['postTypes'] : array();
150        if ( $post_types ) {
151            // If some postTypes are explicitly set then respect the pattern author's intent.
152            return $post_types;
153        }
154
155        $block_types       = array_key_exists( 'blockTypes', $pattern ) ? $pattern['blockTypes'] : array();
156        $block_types_count = count( $block_types );
157        $template_parts    = array_filter(
158            $block_types,
159            function ( $block_type ) {
160                return preg_match( '#core/template-part/#', $block_type );
161            }
162        );
163        // If all of a patterns blockTypes are template-parts then limit the postTypes to just
164        // the template related types and to pages - this is to avoid the pattern appearing in
165        // the inserter for posts and other post types. Pages are included because it's not unusual
166        // to use a blank template and add a specific header and footer to a page.
167        if ( $block_types_count && count( $template_parts ) === $block_types_count ) {
168            $post_types = array( 'wp_template', 'wp_template_part', 'page' );
169        }
170        return $post_types;
171    }
172}