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

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

201 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 Time and Duration setup editor.
4 *
5 * @package Booking Calendar
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 /**
13 * Expose Start Time and Duration through the common setup-module contract.
14 */
15 final class WPBC_Setup_Wizard_Start_Duration_Times_Module implements WPBC_Setup_Wizard_Step_Module, WPBC_Setup_Wizard_Contextual_Values_Validator {
16
17 /** @var WPBC_Setup_Wizard_Start_Duration_Times */
18 private $start_duration_times;
19
20 /**
21 * Build the module around its reusable proposal service.
22 *
23 * @param WPBC_Setup_Wizard_Start_Duration_Times|null $start_duration_times Optional service for tests or composition.
24 */
25 public function __construct( $start_duration_times = null ) {
26 $this->start_duration_times = $start_duration_times instanceof WPBC_Setup_Wizard_Start_Duration_Times
27 ? $start_duration_times
28 : new WPBC_Setup_Wizard_Start_Duration_Times();
29 }
30
31 /**
32 * Return the stable step identifier.
33 *
34 * @return string Stable step ID.
35 */
36 public function get_step_id() {
37 return 'start_duration_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 & duration times', 'booking' ),
49 'template' => 'step-start-duration-times',
50 'footer_note' => __( 'Save your start times and duration choices and continue to the next step.', 'booking' ),
51 );
52 }
53
54 /**
55 * Return the shared allow-listed choice-editor template.
56 *
57 * @return string Absolute template path.
58 */
59 public function get_template_path() {
60 return dirname( __DIR__ ) . '/step-start-end-times/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_duration_times' );
70 }
71
72 /**
73 * Require both choice lists 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_duration_times' => $this->start_duration_times->get_initial_start_duration_times(),
89 );
90 }
91
92 /**
93 * Return dependencies used for display formatting 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 shared editor 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_duration_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_duration_times' !== $field_id ) {
128 return new WP_Error( 'wpbc_setup_wizard_start_duration_times_field_unknown', __( 'The Start Time and Duration editor received an unsupported field.', 'booking' ) );
129 }
130
131 return $this->start_duration_times->validate_start_duration_times( $raw_value, $is_required );
132 }
133
134 /**
135 * Restrict this editor to the Start Time + Duration journey.
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_duration_configuration( $journey_id ) ) {
148 return $validated_values;
149 }
150
151 $message = __( 'Start Time and Duration choices are not available for the selected customer journey.', 'booking' );
152
153 return new WP_Error(
154 'wpbc_setup_wizard_start_duration_times_journey_invalid',
155 $message,
156 array( 'field_errors' => array( 'start_duration_times' => $message ) )
157 );
158 }
159
160 /**
161 * Enqueue the compiled shared editor assets and duration 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_duration_times',
182 'max_times_per_list' => WPBC_Setup_Wizard_Start_Duration_Times::MAX_TIMES_PER_LIST,
183 'time_increment' => WPBC_Setup_Wizard_Start_Duration_Times::TIME_INCREMENT,
184 'i18n' => array(
185 'start_times_required' => __( 'Add at least one start time.', 'booking' ),
186 'duration_times_required' => __( 'Add at least one duration.', 'booking' ),
187 'time_duplicate' => __( 'The same choice cannot appear twice in one list.', 'booking' ),
188 'generator_invalid' => __( 'The last generated choice must not be earlier than the first choice.', 'booking' ),
189 'time_limit' => __( 'No additional choice can be added to this list.', 'booking' ),
190 'start_times_cleared' => __( 'Start times cleared.', 'booking' ),
191 'duration_times_cleared' => __( 'Duration times cleared.', 'booking' ),
192 /* translators: 1: Displayed choice, 2: Choice-list label. */
193 'move_time_choice' => __( 'Move %1$s in the %2$s list', 'booking' ),
194 /* translators: 1: Displayed choice, 2: Choice-list label. */
195 'remove_time_choice' => __( 'Remove %1$s from the %2$s list', 'booking' ),
196 ),
197 )
198 );
199 }
200 }
201