PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / 2.3.2
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant v2.3.2
2.3.2 2.3.1 2.3.0 2.2.8 2.2.7 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.11.1 1.11.2 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.9.10 1.9.11 All 60 releases
merchant / admin / classes / admin-options / class-merchant-field-registry.php

class-merchant-field-registry.php in Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant 2.3.2, at admin/classes/admin-options/class-merchant-field-registry.php

374 lines 11.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Merchant Field Registry.
4 *
5 * Singleton registry that maps field type strings to their corresponding
6 * field classes. Uses an explicit array for field registration.
7 *
8 * @package Merchant
9 * @since 2.2.5
10 */
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit; // Exit if accessed directly
14 }
15
16 /**
17 * Merchant_Field_Registry
18 *
19 * @since 2.2.5
20 */
21 class Merchant_Field_Registry {
22
23 /**
24 * The single class instance.
25 *
26 * @since 2.2.5
27 * @var Merchant_Field_Registry|null
28 */
29 private static $instance = null;
30
31 /**
32 * Registered field types.
33 * Maps type string => class name.
34 *
35 * @since 2.2.5
36 * @var array<string, string>
37 */
38 private $types = array();
39
40 /**
41 * Get the singleton instance.
42 *
43 * @since 2.2.5
44 *
45 * @return Merchant_Field_Registry
46 */
47 public static function instance() {
48 if ( is_null( self::$instance ) ) {
49 self::$instance = new self();
50 }
51
52 return self::$instance;
53 }
54
55 /**
56 * Reset the singleton instance.
57 *
58 * Clears the cached instance so a fresh one is created
59 * on the next {@see instance()} call. Intended for unit tests.
60 *
61 * @since 2.2.5
62 *
63 * @return void
64 */
65 public static function reset(): void {
66 self::$instance = null;
67 }
68
69 /**
70 * Constructor.
71 *
72 * Loads field classes from an explicit registry array and builds the type map.
73 *
74 * @since 2.2.5
75 */
76 private function __construct() {
77 $base_path = MERCHANT_DIR . 'admin/classes/admin-options/fields';
78
79 /**
80 * Core field type definitions.
81 *
82 * Each entry maps a type key to its class name and file path.
83 * Format: type_key => [ 'class' => ClassName, 'file' => absolute_path ]
84 *
85 * @since 2.2.5
86 */
87 $field_types = array(
88 'text' => array(
89 'class' => 'Merchant_Field_Text',
90 'file' => $base_path . '/text/class-merchant-field-text.php',
91 ),
92 'number' => array(
93 'class' => 'Merchant_Field_Number',
94 'file' => $base_path . '/number/class-merchant-field-number.php',
95 ),
96 'url' => array(
97 'class' => 'Merchant_Field_Url',
98 'file' => $base_path . '/url/class-merchant-field-url.php',
99 ),
100 'textarea' => array(
101 'class' => 'Merchant_Field_Textarea',
102 'file' => $base_path . '/textarea/class-merchant-field-textarea.php',
103 ),
104 'textarea_multiline' => array(
105 'class' => 'Merchant_Field_Textarea_Multiline',
106 'file' => $base_path . '/textarea-multiline/class-merchant-field-textarea-multiline.php',
107 ),
108 'textarea_code' => array(
109 'class' => 'Merchant_Field_Textarea_Code',
110 'file' => $base_path . '/textarea-code/class-merchant-field-textarea-code.php',
111 ),
112 'text_readonly' => array(
113 'class' => 'Merchant_Field_Text_Readonly',
114 'file' => $base_path . '/text-readonly/class-merchant-field-text-readonly.php',
115 ),
116 'color' => array(
117 'class' => 'Merchant_Field_Color',
118 'file' => $base_path . '/color/class-merchant-field-color.php',
119 ),
120 'range' => array(
121 'class' => 'Merchant_Field_Range',
122 'file' => $base_path . '/range/class-merchant-field-range.php',
123 ),
124 'date_time' => array(
125 'class' => 'Merchant_Field_Date_Time',
126 'file' => $base_path . '/date-time/class-merchant-field-date-time.php',
127 ),
128 'select' => array(
129 'class' => 'Merchant_Field_Select',
130 'file' => $base_path . '/select/class-merchant-field-select.php',
131 ),
132 'select_ajax' => array(
133 'class' => 'Merchant_Field_Select_Ajax',
134 'file' => $base_path . '/select-ajax/class-merchant-field-select-ajax.php',
135 ),
136 'select_size_chart' => array(
137 'class' => 'Merchant_Field_Select_Size_Chart',
138 'file' => $base_path . '/select-size-chart/class-merchant-field-select-size-chart.php',
139 ),
140 'radio' => array(
141 'class' => 'Merchant_Field_Radio',
142 'file' => $base_path . '/radio/class-merchant-field-radio.php',
143 ),
144 'radio_alt' => array(
145 'class' => 'Merchant_Field_Radio_Alt',
146 'file' => $base_path . '/radio-alt/class-merchant-field-radio-alt.php',
147 ),
148 'buttons' => array(
149 'class' => 'Merchant_Field_Buttons',
150 'file' => $base_path . '/buttons/class-merchant-field-buttons.php',
151 ),
152 'buttons_alt' => array(
153 'class' => 'Merchant_Field_Buttons_Alt',
154 'file' => $base_path . '/buttons-alt/class-merchant-field-buttons-alt.php',
155 ),
156 'buttons_content' => array(
157 'class' => 'Merchant_Field_Buttons_Content',
158 'file' => $base_path . '/buttons-content/class-merchant-field-buttons-content.php',
159 ),
160 'image_picker' => array(
161 'class' => 'Merchant_Field_Image_Picker',
162 'file' => $base_path . '/image-picker/class-merchant-field-image-picker.php',
163 ),
164 'choices' => array(
165 'class' => 'Merchant_Field_Choices',
166 'file' => $base_path . '/choices/class-merchant-field-choices.php',
167 ),
168 'switcher' => array(
169 'class' => 'Merchant_Field_Switcher',
170 'file' => $base_path . '/switcher/class-merchant-field-switcher.php',
171 ),
172 'checkbox' => array(
173 'class' => 'Merchant_Field_Checkbox',
174 'file' => $base_path . '/checkbox/class-merchant-field-checkbox.php',
175 ),
176 'checkbox_multiple' => array(
177 'class' => 'Merchant_Field_Checkbox_Multiple',
178 'file' => $base_path . '/checkbox-multiple/class-merchant-field-checkbox-multiple.php',
179 ),
180 'dimensions' => array(
181 'class' => 'Merchant_Field_Dimensions',
182 'file' => $base_path . '/dimensions/class-merchant-field-dimensions.php',
183 ),
184 'responsive_dimensions' => array(
185 'class' => 'Merchant_Field_Responsive_Dimensions',
186 'file' => $base_path . '/responsive-dimensions/class-merchant-field-responsive-dimensions.php',
187 ),
188 'sortable' => array(
189 'class' => 'Merchant_Field_Sortable',
190 'file' => $base_path . '/sortable/class-merchant-field-sortable.php',
191 ),
192 'sortable_repeater' => array(
193 'class' => 'Merchant_Field_Sortable_Repeater',
194 'file' => $base_path . '/sortable-repeater/class-merchant-field-sortable-repeater.php',
195 ),
196 'sortable_repeater_icons' => array(
197 'class' => 'Merchant_Field_Sortable_Repeater_Icons',
198 'file' => $base_path . '/sortable-repeater-icons/class-merchant-field-sortable-repeater-icons.php',
199 ),
200 'upload' => array(
201 'class' => 'Merchant_Field_Upload',
202 'file' => $base_path . '/upload/class-merchant-field-upload.php',
203 ),
204 'gallery' => array(
205 'class' => 'Merchant_Field_Gallery',
206 'file' => $base_path . '/gallery/class-merchant-field-gallery.php',
207 ),
208 'hook_select' => array(
209 'class' => 'Merchant_Field_Hook_Select',
210 'file' => $base_path . '/hook-select/class-merchant-field-hook-select.php',
211 ),
212 'create_page' => array(
213 'class' => 'Merchant_Field_Create_Page',
214 'file' => $base_path . '/create-page/class-merchant-field-create-page.php',
215 ),
216 'products_selector' => array(
217 'class' => 'Merchant_Field_Products_Selector',
218 'file' => $base_path . '/products-selector/class-merchant-field-products-selector.php',
219 ),
220 'reviews_selector' => array(
221 'class' => 'Merchant_Field_Reviews_Selector',
222 'file' => $base_path . '/reviews-selector/class-merchant-field-reviews-selector.php',
223 ),
224 'wc_coupons' => array(
225 'class' => 'Merchant_Field_Wc_Coupons',
226 'file' => $base_path . '/wc-coupons/class-merchant-field-wc-coupons.php',
227 ),
228 'flexible_content' => array(
229 'class' => 'Merchant_Field_Flexible_Content',
230 'file' => $base_path . '/flexible-content/class-merchant-field-flexible-content.php',
231 ),
232 'fields_group' => array(
233 'class' => 'Merchant_Field_Fields_Group',
234 'file' => $base_path . '/fields-group/class-merchant-field-fields-group.php',
235 ),
236 'content' => array(
237 'class' => 'Merchant_Field_Content',
238 'file' => $base_path . '/content/class-merchant-field-content.php',
239 ),
240 'divider' => array(
241 'class' => 'Merchant_Field_Divider',
242 'file' => $base_path . '/divider/class-merchant-field-divider.php',
243 ),
244 'info' => array(
245 'class' => 'Merchant_Field_Info',
246 'file' => $base_path . '/info/class-merchant-field-info.php',
247 ),
248 'info_block' => array(
249 'class' => 'Merchant_Field_Info_Block',
250 'file' => $base_path . '/info-block/class-merchant-field-info-block.php',
251 ),
252 'warning' => array(
253 'class' => 'Merchant_Field_Warning',
254 'file' => $base_path . '/warning/class-merchant-field-warning.php',
255 ),
256 'custom_callback' => array(
257 'class' => 'Merchant_Field_Custom_Callback',
258 'file' => $base_path . '/custom-callback/class-merchant-field-custom-callback.php',
259 ),
260 );
261
262 /**
263 * Filter: register, override, or remove field types.
264 *
265 * Allows 3rd-party plugins and Merchant Pro to register custom field types
266 * or override existing ones.
267 *
268 * Expected format: array( 'type_key' => array( 'class' => 'ClassName', 'file' => '/path/to/file.php' ) )
269 *
270 * @since 2.2.5
271 *
272 * @param array<string, array<string, string>> $field_types Map of type key => config array.
273 */
274 $field_types = apply_filters( 'merchant_field_types', $field_types );
275
276 // Load and register each field type.
277 foreach ( $field_types as $type_key => $config ) {
278 if ( ! empty( $config['file'] ) && file_exists( $config['file'] ) ) {
279 require_once $config['file'];
280 }
281
282 if ( ! empty( $config['class'] ) && class_exists( $config['class'] ) ) {
283 $this->register( $type_key, $config['class'] );
284 }
285 }
286 }
287
288 /**
289 * Check if a field type is registered.
290 *
291 * @since 2.2.5
292 *
293 * @param string $type The field type string.
294 *
295 * @return bool
296 */
297 public function has( $type ) {
298 return isset( $this->types[ $type ] );
299 }
300
301 /**
302 * Create a field instance for the given type.
303 *
304 * @since 2.2.5
305 *
306 * @param string $type The field type string.
307 * @param array<string, mixed> $field The field configuration array.
308 * @param mixed $value The current saved value.
309 * @param string $module_id The module ID.
310 *
311 * @return Merchant_Field_Interface|null The field instance, or null if type is unknown and text fallback unavailable.
312 */
313 public function create( $type, $field, $value = null, $module_id = '' ) {
314 if ( ! $this->has( $type ) ) {
315 _doing_it_wrong(
316 __METHOD__,
317 sprintf(
318 /* translators: %s: field type */
319 'Unknown field type "%s". Falling back to text field.',
320 esc_html( $type )
321 ),
322 '2.2.5'
323 );
324
325 // Fallback to text field if available, otherwise return a basic instance.
326 if ( $this->has( 'text' ) ) {
327 $class = $this->types['text'];
328
329 /** @var Merchant_Field_Interface $instance */
330 $instance = new $class( $field, $value, $module_id );
331
332 return $instance;
333 }
334
335 // If even text is not registered, this is an early bootstrap call.
336 return null;
337 }
338
339 $class = $this->types[ $type ];
340
341 /** @var Merchant_Field_Interface $instance */
342 $instance = new $class( $field, $value, $module_id );
343
344 return $instance;
345 }
346
347 /**
348 * Get all registered types.
349 *
350 * @since 2.2.5
351 *
352 * @return array<string, string> Map of type => class name.
353 */
354 public function get_types() {
355 return $this->types;
356 }
357
358 /**
359 * Register a field type manually.
360 *
361 * Used internally and by the merchant_field_types filter.
362 *
363 * @since 2.2.5
364 *
365 * @param string $type The field type string.
366 * @param string $class_name The fully qualified class name.
367 *
368 * @return void
369 */
370 public function register( $type, $class_name ) {
371 $this->types[ $type ] = $class_name;
372 }
373 }
374