PluginProbe
Booking Calendar / 11.9
Booking Calendar v11.9
11.9 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 All 205 releases
booking / includes / page-setup-wizard / class-wpbc-setup-wizard-step-module-registry.php

class-wpbc-setup-wizard-step-module-registry.php in Booking Calendar 11.9, at includes/page-setup-wizard/class-wpbc-setup-wizard-step-module-registry.php

199 lines 6.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Reusable step-module registry for the Setup Wizard module.
4 *
5 * @package Booking Calendar
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 /**
13 * Register reusable domain editors without teaching consumer shells their rules.
14 */
15 final class WPBC_Setup_Wizard_Step_Module_Registry {
16
17 /** @var array<string,WPBC_Setup_Wizard_Step_Module> */
18 private $modules = array();
19
20 /**
21 * Build the registry from explicit modules or the bundled module set.
22 *
23 * @param WPBC_Setup_Wizard_Step_Module[]|null $modules Optional ordered modules.
24 */
25 public function __construct( $modules = null ) {
26 if ( null === $modules ) {
27 $modules = array(
28 new WPBC_Setup_Wizard_Date_Time_Formats_Module(),
29 new WPBC_Setup_Wizard_Date_Selection_Module(),
30 new WPBC_Setup_Wizard_Days_Off_Module(),
31 new WPBC_Setup_Wizard_Services_Module(),
32 new WPBC_Setup_Wizard_Booking_Resources_Module(),
33 new WPBC_Setup_Wizard_Start_End_Times_Module(),
34 new WPBC_Setup_Wizard_Start_Duration_Times_Module(),
35 new WPBC_Setup_Wizard_Fixed_Time_Slots_Module(),
36 new WPBC_Setup_Wizard_Working_Hours_Module(),
37 new WPBC_Setup_Wizard_Booking_Form_Template_Module(),
38 new WPBC_Setup_Wizard_Appearance_Module(),
39 new WPBC_Setup_Wizard_Publish_Integration_Module(),
40 new WPBC_Setup_Wizard_Review_Setup_Module(),
41 );
42 }
43
44 foreach ( (array) $modules as $module ) {
45 if ( ! $module instanceof WPBC_Setup_Wizard_Step_Module ) {
46 continue;
47 }
48
49 $step_id = sanitize_key( $module->get_step_id() );
50 $definition = $this->normalize_step_definition( $step_id, $module->get_step_definition() );
51 if ( '' !== $step_id && ! is_wp_error( $definition ) && ! isset( $this->modules[ $step_id ] ) ) {
52 $this->modules[ $step_id ] = $module;
53 }
54 }
55 }
56
57 /**
58 * Return all modules in their registered order.
59 *
60 * @return array<string,WPBC_Setup_Wizard_Step_Module> Modules keyed by step ID.
61 */
62 public function get_modules() {
63 return $this->modules;
64 }
65
66 /**
67 * Return one registered module.
68 *
69 * @param string $step_id Proposed step identifier.
70 *
71 * @return WPBC_Setup_Wizard_Step_Module|null Registered module or null.
72 */
73 public function get_module( $step_id ) {
74 $step_id = sanitize_key( is_scalar( $step_id ) ? (string) $step_id : '' );
75
76 return isset( $this->modules[ $step_id ] ) ? $this->modules[ $step_id ] : null;
77 }
78
79 /**
80 * Determine whether one registered module is available in this site context.
81 *
82 * Modules without a conditional contract are always available. Conditional
83 * modules own their restriction logic so the shared registry remains
84 * domain-neutral.
85 *
86 * @param string $step_id Proposed module step ID.
87 * @param array<string,mixed> $consumer_context Optional read-only route context.
88 *
89 * @return bool True when the registered module may appear in the route.
90 */
91 public function is_module_available( $step_id, array $consumer_context = array() ) {
92 $module = $this->get_module( $step_id );
93 if ( null === $module ) {
94 return false;
95 }
96
97 if ( $module instanceof WPBC_Setup_Wizard_Conditional_Step_Module ) {
98 return (bool) $module->is_available( $consumer_context );
99 }
100
101 return true;
102 }
103
104 /**
105 * Return step definitions contributed by registered modules.
106 *
107 * @return array<string,array<string,string>> Definitions keyed by step ID.
108 */
109 public function get_step_definitions() {
110 $definitions = array();
111
112 foreach ( $this->modules as $step_id => $module ) {
113 $definition = $this->normalize_step_definition( $step_id, $module->get_step_definition() );
114 if ( ! is_wp_error( $definition ) ) {
115 $definitions[ $step_id ] = $definition;
116 }
117 }
118
119 return $definitions;
120 }
121
122 /**
123 * Return the server-owned template allow-list contributed by modules.
124 *
125 * @return array<string,string> Template paths keyed by stable template ID.
126 */
127 public function get_template_allow_list() {
128 $allow_list = array();
129
130 foreach ( $this->modules as $step_id => $module ) {
131 $definition = $this->normalize_step_definition( $step_id, $module->get_step_definition() );
132 if ( is_wp_error( $definition ) ) {
133 continue;
134 }
135
136 $allow_list[ $definition['template'] ] = $module->get_template_path();
137 }
138
139 return $allow_list;
140 }
141
142 /**
143 * Enqueue the compiled assets owned by one registered module.
144 *
145 * @param string $step_id Current step identifier.
146 * @param string $module_url Absolute URL to the Setup Wizard module root.
147 * @param string|false $asset_version Plugin version used for cache busting.
148 * @param string $shared_style_handle Consumer shell style handle.
149 * @param string $shared_script_handle Consumer shell script handle.
150 *
151 * @return bool True when a module was found and enqueued.
152 */
153 public function enqueue_assets( $step_id, $module_url, $asset_version, $shared_style_handle, $shared_script_handle ) {
154 $module = $this->get_module( $step_id );
155
156 if ( null === $module ) {
157 return false;
158 }
159
160 $module->enqueue_assets( $module_url, $asset_version, $shared_style_handle, $shared_script_handle );
161
162 return true;
163 }
164
165 /**
166 * Normalize trusted module metadata before exposing it to a consumer shell.
167 *
168 * @param string $registered_step_id Registry key assigned to the module.
169 * @param mixed $definition Module-provided step definition.
170 *
171 * @return array<string,string>|WP_Error Normalized definition or an error.
172 */
173 private function normalize_step_definition( $registered_step_id, $definition ) {
174 if ( ! is_array( $definition ) ) {
175 return new WP_Error( 'wpbc_setup_wizard_module_definition_invalid', __( 'A setup editor has an invalid definition.', 'booking' ) );
176 }
177
178 $definition_step_id = isset( $definition['id'] ) && is_scalar( $definition['id'] ) ? sanitize_key( (string) $definition['id'] ) : '';
179 $template_id = isset( $definition['template'] ) && is_scalar( $definition['template'] ) ? sanitize_key( (string) $definition['template'] ) : '';
180 $label = isset( $definition['label'] ) && is_scalar( $definition['label'] ) ? sanitize_text_field( (string) $definition['label'] ) : '';
181
182 if ( $registered_step_id !== $definition_step_id || '' === $template_id || '' === $label ) {
183 return new WP_Error( 'wpbc_setup_wizard_module_definition_invalid', __( 'A setup editor has an invalid definition.', 'booking' ) );
184 }
185
186 $normalized_definition = array(
187 'id' => $definition_step_id,
188 'label' => $label,
189 'template' => $template_id,
190 );
191
192 if ( isset( $definition['footer_note'] ) && is_scalar( $definition['footer_note'] ) ) {
193 $normalized_definition['footer_note'] = sanitize_text_field( (string) $definition['footer_note'] );
194 }
195
196 return $normalized_definition;
197 }
198 }
199