|
1 <?php |
|
2 /** |
|
3 * Templates registry functions. |
|
4 * |
|
5 * @package WordPress |
|
6 * @since 6.7.0 |
|
7 */ |
|
8 |
|
9 /** |
|
10 * Core class used for interacting with templates. |
|
11 * |
|
12 * @since 6.7.0 |
|
13 */ |
|
14 final class WP_Block_Templates_Registry { |
|
15 /** |
|
16 * Registered templates, as `$name => $instance` pairs. |
|
17 * |
|
18 * @since 6.7.0 |
|
19 * @var WP_Block_Template[] $registered_block_templates Registered templates. |
|
20 */ |
|
21 private $registered_templates = array(); |
|
22 |
|
23 /** |
|
24 * Container for the main instance of the class. |
|
25 * |
|
26 * @since 6.7.0 |
|
27 * @var WP_Block_Templates_Registry|null |
|
28 */ |
|
29 private static $instance = null; |
|
30 |
|
31 /** |
|
32 * Registers a template. |
|
33 * |
|
34 * @since 6.7.0 |
|
35 * |
|
36 * @param string $template_name Template name including namespace. |
|
37 * @param array $args Optional. Array of template arguments. |
|
38 * @return WP_Block_Template|WP_Error The registered template on success, or WP_Error on failure. |
|
39 */ |
|
40 public function register( $template_name, $args = array() ) { |
|
41 |
|
42 $template = null; |
|
43 |
|
44 $error_message = ''; |
|
45 $error_code = ''; |
|
46 |
|
47 if ( ! is_string( $template_name ) ) { |
|
48 $error_message = __( 'Template names must be strings.' ); |
|
49 $error_code = 'template_name_no_string'; |
|
50 } elseif ( preg_match( '/[A-Z]+/', $template_name ) ) { |
|
51 $error_message = __( 'Template names must not contain uppercase characters.' ); |
|
52 $error_code = 'template_name_no_uppercase'; |
|
53 } elseif ( ! preg_match( '/^[a-z0-9_\-]+\/\/[a-z0-9_\-]+$/', $template_name ) ) { |
|
54 $error_message = __( 'Template names must contain a namespace prefix. Example: my-plugin//my-custom-template' ); |
|
55 $error_code = 'template_no_prefix'; |
|
56 } elseif ( $this->is_registered( $template_name ) ) { |
|
57 /* translators: %s: Template name. */ |
|
58 $error_message = sprintf( __( 'Template "%s" is already registered.' ), $template_name ); |
|
59 $error_code = 'template_already_registered'; |
|
60 } |
|
61 |
|
62 if ( $error_message ) { |
|
63 _doing_it_wrong( |
|
64 __METHOD__, |
|
65 $error_message, |
|
66 '6.7.0' |
|
67 ); |
|
68 return new WP_Error( $error_code, $error_message ); |
|
69 } |
|
70 |
|
71 if ( ! $template ) { |
|
72 $theme_name = get_stylesheet(); |
|
73 list( $plugin, $slug ) = explode( '//', $template_name ); |
|
74 $default_template_types = get_default_block_template_types(); |
|
75 |
|
76 $template = new WP_Block_Template(); |
|
77 $template->id = $theme_name . '//' . $slug; |
|
78 $template->theme = $theme_name; |
|
79 $template->plugin = $plugin; |
|
80 $template->author = null; |
|
81 $template->content = isset( $args['content'] ) ? $args['content'] : ''; |
|
82 $template->source = 'plugin'; |
|
83 $template->slug = $slug; |
|
84 $template->type = 'wp_template'; |
|
85 $template->title = isset( $args['title'] ) ? $args['title'] : $template_name; |
|
86 $template->description = isset( $args['description'] ) ? $args['description'] : ''; |
|
87 $template->status = 'publish'; |
|
88 $template->origin = 'plugin'; |
|
89 $template->is_custom = ! isset( $default_template_types[ $template_name ] ); |
|
90 $template->post_types = isset( $args['post_types'] ) ? $args['post_types'] : array(); |
|
91 } |
|
92 |
|
93 $this->registered_templates[ $template_name ] = $template; |
|
94 |
|
95 return $template; |
|
96 } |
|
97 |
|
98 /** |
|
99 * Retrieves all registered templates. |
|
100 * |
|
101 * @since 6.7.0 |
|
102 * |
|
103 * @return WP_Block_Template[] Associative array of `$template_name => $template` pairs. |
|
104 */ |
|
105 public function get_all_registered() { |
|
106 return $this->registered_templates; |
|
107 } |
|
108 |
|
109 /** |
|
110 * Retrieves a registered template by its name. |
|
111 * |
|
112 * @since 6.7.0 |
|
113 * |
|
114 * @param string $template_name Template name including namespace. |
|
115 * @return WP_Block_Template|null The registered template, or null if it is not registered. |
|
116 */ |
|
117 public function get_registered( $template_name ) { |
|
118 if ( ! $this->is_registered( $template_name ) ) { |
|
119 return null; |
|
120 } |
|
121 |
|
122 return $this->registered_templates[ $template_name ]; |
|
123 } |
|
124 |
|
125 /** |
|
126 * Retrieves a registered template by its slug. |
|
127 * |
|
128 * @since 6.7.0 |
|
129 * |
|
130 * @param string $template_slug Slug of the template. |
|
131 * @return WP_Block_Template|null The registered template, or null if it is not registered. |
|
132 */ |
|
133 public function get_by_slug( $template_slug ) { |
|
134 $all_templates = $this->get_all_registered(); |
|
135 |
|
136 if ( ! $all_templates ) { |
|
137 return null; |
|
138 } |
|
139 |
|
140 foreach ( $all_templates as $template ) { |
|
141 if ( $template->slug === $template_slug ) { |
|
142 return $template; |
|
143 } |
|
144 } |
|
145 |
|
146 return null; |
|
147 } |
|
148 |
|
149 /** |
|
150 * Retrieves registered templates matching a query. |
|
151 * |
|
152 * @since 6.7.0 |
|
153 * |
|
154 * @param array $query { |
|
155 * Arguments to retrieve templates. Optional, empty by default. |
|
156 * |
|
157 * @type string[] $slug__in List of slugs to include. |
|
158 * @type string[] $slug__not_in List of slugs to skip. |
|
159 * @type string $post_type Post type to get the templates for. |
|
160 * } |
|
161 * @return WP_Block_Template[] Associative array of `$template_name => $template` pairs. |
|
162 */ |
|
163 public function get_by_query( $query = array() ) { |
|
164 $all_templates = $this->get_all_registered(); |
|
165 |
|
166 if ( ! $all_templates ) { |
|
167 return array(); |
|
168 } |
|
169 |
|
170 $query = wp_parse_args( |
|
171 $query, |
|
172 array( |
|
173 'slug__in' => array(), |
|
174 'slug__not_in' => array(), |
|
175 'post_type' => '', |
|
176 ) |
|
177 ); |
|
178 $slugs_to_include = $query['slug__in']; |
|
179 $slugs_to_skip = $query['slug__not_in']; |
|
180 $post_type = $query['post_type']; |
|
181 |
|
182 $matching_templates = array(); |
|
183 foreach ( $all_templates as $template_name => $template ) { |
|
184 if ( $slugs_to_include && ! in_array( $template->slug, $slugs_to_include, true ) ) { |
|
185 continue; |
|
186 } |
|
187 |
|
188 if ( $slugs_to_skip && in_array( $template->slug, $slugs_to_skip, true ) ) { |
|
189 continue; |
|
190 } |
|
191 |
|
192 if ( $post_type && ! in_array( $post_type, $template->post_types, true ) ) { |
|
193 continue; |
|
194 } |
|
195 |
|
196 $matching_templates[ $template_name ] = $template; |
|
197 } |
|
198 |
|
199 return $matching_templates; |
|
200 } |
|
201 |
|
202 /** |
|
203 * Checks if a template is registered. |
|
204 * |
|
205 * @since 6.7.0 |
|
206 * |
|
207 * @param string $template_name Template name. |
|
208 * @return bool True if the template is registered, false otherwise. |
|
209 */ |
|
210 public function is_registered( $template_name ) { |
|
211 return isset( $this->registered_templates[ $template_name ] ); |
|
212 } |
|
213 |
|
214 /** |
|
215 * Unregisters a template. |
|
216 * |
|
217 * @since 6.7.0 |
|
218 * |
|
219 * @param string $template_name Template name including namespace. |
|
220 * @return WP_Block_Template|WP_Error The unregistered template on success, or WP_Error on failure. |
|
221 */ |
|
222 public function unregister( $template_name ) { |
|
223 if ( ! $this->is_registered( $template_name ) ) { |
|
224 _doing_it_wrong( |
|
225 __METHOD__, |
|
226 /* translators: %s: Template name. */ |
|
227 sprintf( __( 'Template "%s" is not registered.' ), $template_name ), |
|
228 '6.7.0' |
|
229 ); |
|
230 /* translators: %s: Template name. */ |
|
231 return new WP_Error( 'template_not_registered', __( 'Template "%s" is not registered.' ) ); |
|
232 } |
|
233 |
|
234 $unregistered_template = $this->registered_templates[ $template_name ]; |
|
235 unset( $this->registered_templates[ $template_name ] ); |
|
236 |
|
237 return $unregistered_template; |
|
238 } |
|
239 |
|
240 /** |
|
241 * Utility method to retrieve the main instance of the class. |
|
242 * |
|
243 * The instance will be created if it does not exist yet. |
|
244 * |
|
245 * @since 6.7.0 |
|
246 * |
|
247 * @return WP_Block_Templates_Registry The main instance. |
|
248 */ |
|
249 public static function get_instance() { |
|
250 if ( null === self::$instance ) { |
|
251 self::$instance = new self(); |
|
252 } |
|
253 |
|
254 return self::$instance; |
|
255 } |
|
256 } |