1<?php
2/**
3 * Blocks API: WP_Block_Pattern_Categories_Registry class
4 *
5 * @package WordPress
6 * @subpackage Blocks
7 * @since 5.5.0
8 */
9
10/**
11 * Class used for interacting with block pattern categories.
12 */
13#[AllowDynamicProperties]
14final class WP_Block_Pattern_Categories_Registry {
15 /**
16 * Registered block pattern categories array.
17 *
18 * @since 5.5.0
19 * @var array[]
20 */
21 private $registered_categories = array();
22
23 /**
24 * Pattern categories registered outside the `init` action.
25 *
26 * @since 6.0.0
27 * @var array[]
28 */
29 private $registered_categories_outside_init = array();
30
31 /**
32 * Container for the main instance of the class.
33 *
34 * @since 5.5.0
35 * @var WP_Block_Pattern_Categories_Registry|null
36 */
37 private static $instance = null;
38
39 /**
40 * Registers a pattern category.
41 *
42 * @since 5.5.0
43 *
44 * @param string $category_name Pattern category name including namespace.
45 * @param array $category_properties {
46 * List of properties for the block pattern category.
47 *
48 * @type string $label Required. A human-readable label for the pattern category.
49 * }
50 * @return bool True if the pattern was registered with success and false otherwise.
51 */
52 public function register( $category_name, $category_properties ) {
53 if ( ! isset( $category_name ) || ! is_string( $category_name ) ) {
54 _doing_it_wrong(
55 __METHOD__,
56 __( 'Block pattern category name must be a string.' ),
57 '5.5.0'
58 );
59 return false;
60 }
61
62 $category = array_merge(
63 array( 'name' => $category_name ),
64 $category_properties
65 );
66
67 $this->registered_categories[ $category_name ] = $category;
68
69 // If the category is registered inside an action other than `init`, store it
70 // also to a dedicated array. Used to detect deprecated registrations inside
71 // `admin_init` or `current_screen`.
72 if ( current_action() && 'init' !== current_action() ) {
73 $this->registered_categories_outside_init[ $category_name ] = $category;
74 }
75
76 return true;
77 }
78
79 /**
80 * Unregisters a pattern category.
81 *
82 * @since 5.5.0
83 *
84 * @param string $category_name Pattern category name including namespace.
85 * @return bool True if the pattern was unregistered with success and false otherwise.
86 */
87 public function unregister( $category_name ) {
88 if ( ! $this->is_registered( $category_name ) ) {
89 _doing_it_wrong(
90 __METHOD__,
91 /* translators: %s: Block pattern name. */
92 sprintf( __( 'Block pattern category "%s" not found.' ), $category_name ),
93 '5.5.0'
94 );
95 return false;
96 }
97
98 unset( $this->registered_categories[ $category_name ] );
99 unset( $this->registered_categories_outside_init[ $category_name ] );
100
101 return true;
102 }
103
104 /**
105 * Retrieves an array containing the properties of a registered pattern category.
106 *
107 * @since 5.5.0
108 *
109 * @param string $category_name Pattern category name including namespace.
110 * @return array|null Registered pattern properties, or `null` if the pattern category is not registered.
111 */
112 public function get_registered( $category_name ) {
113 if ( ! $this->is_registered( $category_name ) ) {
114 return null;
115 }
116
117 return $this->registered_categories[ $category_name ];
118 }
119
120 /**
121 * Retrieves all registered pattern categories.
122 *
123 * @since 5.5.0
124 *
125 * @param bool $outside_init_only Return only categories registered outside the `init` action.
126 * @return array[] Array of arrays containing the registered pattern categories properties.
127 */
128 public function get_all_registered( $outside_init_only = false ) {
129 return array_values(
130 $outside_init_only
131 ? $this->registered_categories_outside_init
132 : $this->registered_categories
133 );
134 }
135
136 /**
137 * Checks if a pattern category is registered.
138 *
139 * @since 5.5.0
140 *
141 * @param string|null $category_name Pattern category name including namespace.
142 * @return bool True if the pattern category is registered, false otherwise.
143 */
144 public function is_registered( $category_name ) {
145 return isset( $category_name, $this->registered_categories[ $category_name ] );
146 }
147
148 /**
149 * Utility method to retrieve the main instance of the class.
150 *
151 * The instance will be created if it does not exist yet.
152 *
153 * @since 5.5.0
154 *
155 * @return WP_Block_Pattern_Categories_Registry The main instance.
156 */
157 public static function get_instance() {
158 if ( null === self::$instance ) {
159 self::$instance = new self();
160 }
161
162 return self::$instance;
163 }
164}
165
166/**
167 * Registers a new pattern category.
168 *
169 * @since 5.5.0
170 *
171 * @param string $category_name Pattern category name including namespace.
172 * @param array $category_properties List of properties for the block pattern.
173 * See WP_Block_Pattern_Categories_Registry::register() for
174 * accepted arguments.
175 * @return bool True if the pattern category was registered with success and false otherwise.
176 */
177function register_block_pattern_category( $category_name, $category_properties ) {
178 return WP_Block_Pattern_Categories_Registry::get_instance()->register( $category_name, $category_properties );
179}
180
181/**
182 * Unregisters a pattern category.
183 *
184 * @since 5.5.0
185 *
186 * @param string $category_name Pattern category name including namespace.
187 * @return bool True if the pattern category was unregistered with success and false otherwise.
188 */
189function unregister_block_pattern_category( $category_name ) {
190 return WP_Block_Pattern_Categories_Registry::get_instance()->unregister( $category_name );
191}
192