PluginProbe
Booking Calendar / 11.8.4
Booking Calendar v11.8.4
11.8.4 11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 All 204 releases
booking / includes / _shared-ui-catalog / class-wpbc-ui-catalog-inline-field-schema.php

class-wpbc-ui-catalog-inline-field-schema.php in Booking Calendar 11.8.4, at includes/_shared-ui-catalog/class-wpbc-ui-catalog-inline-field-schema.php

152 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Normalization for executable-free catalog editing field contracts.
4 *
5 * @package Booking Calendar
6 * @since 11.6.0
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Normalize the common field shape without deciding domain field availability.
15 *
16 * This class exists so every catalog can expose the same safe browser contract
17 * while keeping field selection, authorization, validation, and mutations in
18 * its domain module.
19 *
20 * @since 11.6.0
21 */
22 final class WPBC_UI_Catalog_Inline_Field_Schema {
23
24 /**
25 * Supported browser control types.
26 *
27 * @var array<int,string>
28 */
29 const CONTROL_TYPES = array( 'text', 'textarea', 'number', 'select' );
30
31 /**
32 * Normalize a list of domain-authorized field definitions.
33 *
34 * Unknown properties, callbacks, objects, and malformed options are removed.
35 * A domain must still validate the field and its value again at preview and
36 * apply time.
37 *
38 * @param mixed $raw_fields Domain field definitions.
39 * @return array<int,array<string,mixed>> Browser-safe field definitions.
40 */
41 public static function normalize_fields( $raw_fields ) {
42 $normalized_fields = array();
43
44 foreach ( is_array( $raw_fields ) ? $raw_fields : array() as $raw_field ) {
45 $normalized_field = self::normalize_field( $raw_field );
46 if ( ! empty( $normalized_field ) ) {
47 $normalized_fields[] = $normalized_field;
48 }
49 }
50
51 return $normalized_fields;
52 }
53
54 /**
55 * Index normalized fields by their stable key.
56 *
57 * @param mixed $raw_fields Domain field definitions.
58 * @return array<string,array<string,mixed>> Fields keyed by field key.
59 */
60 public static function index_fields( $raw_fields ) {
61 $indexed_fields = array();
62
63 foreach ( self::normalize_fields( $raw_fields ) as $field ) {
64 $indexed_fields[ $field['key'] ] = $field;
65 }
66
67 return $indexed_fields;
68 }
69
70 /**
71 * Normalize one common field definition.
72 *
73 * @param mixed $raw_field Raw field definition.
74 * @return array<string,mixed> Normalized definition or an empty array.
75 */
76 private static function normalize_field( $raw_field ) {
77 if ( ! is_array( $raw_field ) ) {
78 return array();
79 }
80
81 $field_key = isset( $raw_field['key'] ) && is_scalar( $raw_field['key'] ) ? sanitize_key( (string) $raw_field['key'] ) : '';
82 $control_type = isset( $raw_field['type'] ) && is_scalar( $raw_field['type'] ) ? sanitize_key( (string) $raw_field['type'] ) : '';
83 if ( '' === $field_key || ! in_array( $control_type, self::CONTROL_TYPES, true ) ) {
84 return array();
85 }
86
87 $normalized_field = array(
88 'key' => $field_key,
89 'column' => isset( $raw_field['column'] ) && is_scalar( $raw_field['column'] ) ? sanitize_key( (string) $raw_field['column'] ) : '',
90 'label' => isset( $raw_field['label'] ) && is_scalar( $raw_field['label'] ) ? wp_strip_all_tags( (string) $raw_field['label'] ) : $field_key,
91 'type' => $control_type,
92 'value' => isset( $raw_field['value'] ) && is_scalar( $raw_field['value'] ) ? (string) $raw_field['value'] : '',
93 'options' => self::normalize_choices( isset( $raw_field['options'] ) ? $raw_field['options'] : array() ),
94 );
95
96 foreach ( array( 'prefix', 'suffix', 'help', 'section' ) as $property_name ) {
97 if ( isset( $raw_field[ $property_name ] ) && is_scalar( $raw_field[ $property_name ] ) ) {
98 $normalized_field[ $property_name ] = wp_strip_all_tags( (string) $raw_field[ $property_name ] );
99 }
100 }
101 foreach ( array( 'min', 'max', 'maxlength', 'default_value', 'slider_min', 'slider_max', 'slider_step' ) as $property_name ) {
102 if ( isset( $raw_field[ $property_name ] ) && is_numeric( $raw_field[ $property_name ] ) ) {
103 $normalized_field[ $property_name ] = (float) $raw_field[ $property_name ];
104 }
105 }
106 if ( isset( $raw_field['step'] ) && is_scalar( $raw_field['step'] ) ) {
107 $raw_step = strtolower( trim( (string) $raw_field['step'] ) );
108 if ( 'any' === $raw_step ) {
109 $normalized_field['step'] = 'any';
110 } elseif ( is_numeric( $raw_step ) ) {
111 $normalized_field['step'] = (float) $raw_step;
112 }
113 }
114 if ( isset( $raw_field['operations'] ) ) {
115 $normalized_field['operations'] = self::normalize_choices( $raw_field['operations'], 'id' );
116 }
117
118 return $normalized_field;
119 }
120
121 /**
122 * Normalize select options or bulk operations into value-label records.
123 *
124 * @param mixed $raw_choices Raw choices.
125 * @param string $value_key Choice key containing the stable value.
126 * @return array<int,array<string,string>> Browser-safe choices.
127 */
128 private static function normalize_choices( $raw_choices, $value_key = 'value' ) {
129 $normalized_choices = array();
130
131 foreach ( is_array( $raw_choices ) ? $raw_choices : array() as $raw_key => $raw_choice ) {
132 if ( is_array( $raw_choice ) ) {
133 $choice_value = isset( $raw_choice[ $value_key ] ) && is_scalar( $raw_choice[ $value_key ] ) ? (string) $raw_choice[ $value_key ] : '';
134 $choice_label = isset( $raw_choice['label'] ) && is_scalar( $raw_choice['label'] ) ? (string) $raw_choice['label'] : $choice_value;
135 } else {
136 $is_list_choice = is_int( $raw_key );
137 $choice_value = $is_list_choice && is_scalar( $raw_choice ) ? (string) $raw_choice : ( is_scalar( $raw_key ) ? (string) $raw_key : '' );
138 $choice_label = is_scalar( $raw_choice ) ? (string) $raw_choice : $choice_value;
139 }
140 $choice_value = sanitize_key( $choice_value );
141 if ( '' !== $choice_value ) {
142 $normalized_choices[] = array(
143 $value_key => $choice_value,
144 'label' => wp_strip_all_tags( $choice_label ),
145 );
146 }
147 }
148
149 return $normalized_choices;
150 }
151 }
152