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 / step-start-end-times / class-wpbc-setup-wizard-start-end-times-module.php

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

203 lines 7.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Reusable module adapter for the Start and End Times setup editor.
4 *
5 * @package Booking Calendar
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 /**
13 * Expose the Start and End Times editor through the setup-module contract.
14 */
15 final class WPBC_Setup_Wizard_Start_End_Times_Module implements WPBC_Setup_Wizard_Step_Module, WPBC_Setup_Wizard_Contextual_Values_Validator {
16
17 /** @var WPBC_Setup_Wizard_Start_End_Times */
18 private $start_end_times;
19
20 /**
21 * Build the module around its reusable domain service.
22 *
23 * @param WPBC_Setup_Wizard_Start_End_Times|null $start_end_times Optional service for tests or composition.
24 */
25 public function __construct( $start_end_times = null ) {
26 $this->start_end_times = $start_end_times instanceof WPBC_Setup_Wizard_Start_End_Times
27 ? $start_end_times
28 : new WPBC_Setup_Wizard_Start_End_Times();
29 }
30
31 /**
32 * Return the stable module identifier.
33 *
34 * @return string Stable step ID.
35 */
36 public function get_step_id() {
37 return 'start_end_times';
38 }
39
40 /**
41 * Return rail, template, and footer metadata.
42 *
43 * @return array{id:string,label:string,template:string,footer_note:string} Step definition.
44 */
45 public function get_step_definition() {
46 return array(
47 'id' => $this->get_step_id(),
48 'label' => __( 'Start & end times', 'booking' ),
49 'template' => 'step-start-end-times',
50 'footer_note' => __( 'Save your start and end times and continue to the next step.', 'booking' ),
51 );
52 }
53
54 /**
55 * Return the allow-listed module template.
56 *
57 * @return string Absolute template path.
58 */
59 public function get_template_path() {
60 return __DIR__ . '/template.php';
61 }
62
63 /**
64 * Return the owned draft field.
65 *
66 * @return string[] Field allow-list.
67 */
68 public function get_field_names() {
69 return array( 'start_end_times' );
70 }
71
72 /**
73 * Require the complete start/end choice DTO for forward navigation.
74 *
75 * @return string[] Required field list.
76 */
77 public function get_required_fields() {
78 return $this->get_field_names();
79 }
80
81 /**
82 * Return safe wizard-owned starter choices.
83 *
84 * @return array<string,mixed> Initial values.
85 */
86 public function get_initial_values() {
87 return array(
88 'start_end_times' => $this->start_end_times->get_initial_start_end_times(),
89 );
90 }
91
92 /**
93 * Return read-only dependencies needed for labels and route validation.
94 *
95 * @return string[] Dependency step IDs.
96 */
97 public function get_context_dependencies() {
98 return array( 'date_time_formats', 'customer_journey' );
99 }
100
101 /**
102 * Build the module template context.
103 *
104 * @param array<string,mixed> $field_values Validated module values.
105 * @param array<string,mixed> $consumer_context Read-only dependency values.
106 *
107 * @return array<string,mixed> Authorized presentation context.
108 */
109 public function get_context( array $field_values, array $consumer_context = array() ) {
110 $time_format = isset( $consumer_context['date_time_formats']['time_format'] ) && is_scalar( $consumer_context['date_time_formats']['time_format'] )
111 ? (string) $consumer_context['date_time_formats']['time_format']
112 : 'H:i';
113
114 return $this->start_end_times->get_context( $field_values, $time_format );
115 }
116
117 /**
118 * Validate the complete JSON transport field.
119 *
120 * @param string $field_id Stable field identifier.
121 * @param mixed $raw_value Untrusted JSON or array value.
122 * @param bool $is_required Whether complete lists are required.
123 *
124 * @return array<string,mixed>|WP_Error Normalized value or an error.
125 */
126 public function validate_field( $field_id, $raw_value, $is_required ) {
127 if ( 'start_end_times' !== $field_id ) {
128 return new WP_Error( 'wpbc_setup_wizard_start_end_times_field_unknown', __( 'The Start and End Times editor received an unsupported field.', 'booking' ) );
129 }
130
131 return $this->start_end_times->validate_start_end_times( $raw_value, $is_required );
132 }
133
134 /**
135 * Restrict this editor to journeys that configure explicit time choices.
136 *
137 * @param array<string,mixed> $validated_values Validated module values.
138 * @param array<string,mixed> $consumer_context Read-only dependency values.
139 *
140 * @return array<string,mixed>|WP_Error Validated values or a route error.
141 */
142 public function validate_values_with_context( array $validated_values, array $consumer_context ) {
143 $journey_id = isset( $consumer_context['customer_journey']['customer_journey'] )
144 ? sanitize_key( (string) $consumer_context['customer_journey']['customer_journey'] )
145 : '';
146
147 if ( '' === $journey_id || WPBC_Setup_Wizard_Customer_Journey_Policy::uses_start_end_configuration( $journey_id ) ) {
148 return $validated_values;
149 }
150
151 $message = __( 'Start and End Times are not available for the selected customer journey.', 'booking' );
152
153 return new WP_Error(
154 'wpbc_setup_wizard_start_end_times_journey_invalid',
155 $message,
156 array( 'field_errors' => array( 'start_end_times' => $message ) )
157 );
158 }
159
160 /**
161 * Enqueue compiled module assets and presentation translations.
162 *
163 * @param string $module_url Setup Wizard module URL.
164 * @param string|false $asset_version Plugin version for cache busting.
165 * @param string $shared_style_handle Shared shell style handle.
166 * @param string $shared_script_handle Shared shell script handle.
167 *
168 * @return void
169 */
170 public function enqueue_assets( $module_url, $asset_version, $shared_style_handle, $shared_script_handle ) {
171 $module_url = trailingslashit( $module_url );
172
173 wp_enqueue_style( 'wpbc-setup-wizard-start-end-times', $module_url . 'step-start-end-times/_out/step-start-end-times.css', array( $shared_style_handle ), $asset_version );
174 wp_enqueue_script( 'wpbc-sortable', wpbc_plugin_url( '/vendors/sortablejs/Sortable.min.js' ), array(), $asset_version, true );
175 wp_enqueue_script( 'wpbc-setup-wizard-start-end-times', $module_url . 'step-start-end-times/_out/step-start-end-times.js', array( $shared_script_handle, 'wpbc-sortable' ), $asset_version, true );
176 wp_localize_script(
177 'wpbc-setup-wizard-start-end-times',
178 'wpbc_setup_wizard_start_end_times',
179 array(
180 'module_id' => $this->get_step_id(),
181 'field_id' => 'start_end_times',
182 'max_times_per_list' => WPBC_Setup_Wizard_Start_End_Times::MAX_TIMES_PER_LIST,
183 'time_increment' => WPBC_Setup_Wizard_Start_End_Times::TIME_INCREMENT,
184 'i18n' => array(
185 'start_times_required' => __( 'Add at least one start time.', 'booking' ),
186 'end_times_required' => __( 'Add at least one end time.', 'booking' ),
187 'time_duplicate' => __( 'The same time cannot appear twice in one list.', 'booking' ),
188 'time_pair_invalid' => __( 'Add an end time that is later than at least one start time.', 'booking' ),
189 'generator_invalid' => __( 'The last generated time must not be earlier than the first time.', 'booking' ),
190 'time_limit' => __( 'No additional time choice can be added to this list.', 'booking' ),
191 'start_times_copied' => __( 'Start times copied to End times.', 'booking' ),
192 'start_times_cleared' => __( 'Start times cleared.', 'booking' ),
193 'end_times_cleared' => __( 'End times cleared.', 'booking' ),
194 /* translators: 1: Displayed time, 2: Start or End list label. */
195 'move_time_choice' => __( 'Move %1$s in the %2$s list', 'booking' ),
196 /* translators: 1: Displayed time, 2: Start or End list label. */
197 'remove_time_choice' => __( 'Remove %1$s from the %2$s list', 'booking' ),
198 ),
199 )
200 );
201 }
202 }
203