PluginProbe
Booktics – Appointment Booking Calendar for Service Businesses / 1.0.0
Booktics – Appointment Booking Calendar for Service Businesses v1.0.0
1.0.29 1.0.28 1.0.27 1.0.26 1.0.25 1.0.24 1.0.23 1.0.22 1.0.21 1.0.20 1.0.19 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.2 1.0.3 All 31 releases
booktics / core / cart / controllers / cart-controller.php

cart-controller.php in Booktics – Appointment Booking Calendar for Service Businesses 1.0.0, at core/cart/controllers/cart-controller.php

345 lines 9.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Booktics\Cart\Controllers;
4
5 use Booktics\Abstracts\Base_Rest_Controller;
6 use Booktics\Cart\Cart_Manager;
7 use Booktics\Models\Service_Model;
8 use Booktics\Models\Team_Member_Model;
9 use WP_Error;
10 use WP_REST_Response;
11 use WP_REST_Server;
12
13 class Cart_Controller extends Base_Rest_Controller {
14
15 /**
16 * Endpoint namespace
17 *
18 * @var string
19 */
20 protected $namespace = 'booktics/v1';
21
22 /**
23 * Route name
24 *
25 * @var string
26 */
27 protected $base = 'carts';
28
29 /**
30 * @var Cart_Manager
31 */
32 private $cart_manager;
33
34 /**
35 * Initialize CartController with a new CartManager instance
36 */
37 public function __construct() {
38 $this->cart_manager = new Cart_Manager();
39 }
40
41 /**
42 * Register REST API routes for cart functionality
43 *
44 * @return void
45 */
46 public function register_routes(): void {
47 register_rest_route(
48 $this->namespace,
49 $this->base,
50 array(
51 'methods' => WP_REST_Server::CREATABLE,
52 'callback' => array( $this, 'add_to_cart' ),
53 'permission_callback' => '__return_true',
54 )
55 );
56
57 register_rest_route(
58 $this->namespace,
59 $this->base . '/(?P<uuid>[a-zA-Z0-9-]+)',
60 array(
61 'methods' => WP_REST_Server::DELETABLE,
62 'callback' => array( $this, 'delete_from_cart' ),
63 'permission_callback' => '__return_true',
64 )
65 );
66
67 register_rest_route(
68 $this->namespace,
69 $this->base,
70 array(
71 'methods' => WP_REST_Server::EDITABLE,
72 'callback' => array( $this, 'sync_cart' ),
73 'permission_callback' => array( $this, 'is_user_logged_in' ),
74 )
75 );
76
77 register_rest_route(
78 $this->namespace,
79 $this->base . '/(?P<uuid>[a-zA-Z0-9-]+)',
80 array(
81 'methods' => WP_REST_Server::EDITABLE,
82 'callback' => array( $this, 'edit_cart_item' ),
83 'permission_callback' => '__return_true',
84 )
85 );
86
87 register_rest_route(
88 $this->namespace,
89 $this->base,
90 array(
91 'methods' => WP_REST_Server::READABLE,
92 'callback' => array( $this, 'get_cart_items' ),
93 'permission_callback' => '__return_true',
94 )
95 );
96 }
97
98 /**
99 * Prepare and validate cart item data
100 *
101 * @param array $data
102 *
103 * @return []|array|bool|WP_Error
104 */
105 private function prepare_item_to_save( array $data ) {
106 $validated = booktics_validate(
107 $data, array(
108 'date' => array( 'required' ),
109 'start_time' => array( 'required' ),
110 'service_id' => array( 'required' ),
111 'team_member_id' => array( 'required' ),
112 )
113 );
114
115 if ( is_wp_error( $validated ) ) {
116 return $validated;
117 }
118
119 $item_validation = $this->validate_cart_item( $data );
120 if ( is_wp_error( $item_validation ) ) {
121 return $item_validation;
122 }
123
124 return $item_validation;
125 }
126
127 /**
128 * Add an item to the cart
129 *
130 * @param $request
131 *
132 * @return array|\WP_HTTP_Response
133 */
134 public function add_to_cart( $request ) {
135 $params = json_decode( $request->get_body(), true );
136 $validated = $this->prepare_item_to_save( $params );
137
138 if ( is_wp_error( $validated ) ) {
139 return $this->error(
140 __( 'Cart validation error', 'booktics' ),
141 422,
142 'Validation',
143 $validated->errors
144 );
145 }
146 $response = $this->cart_manager->add_to_cart( $validated );
147 $response['service'] = $this->get_service( $response['service_id'] );
148 $response['team'] = $this->get_team_member( $response['team_member_id'] );
149
150 return $this->response( $response, __( 'Item added to cart', 'booktics' ), 201 );
151 }
152
153 /**
154 * Delete an item from the user's cart
155 *
156 * @param $request
157 *
158 * @return array|\WP_HTTP_Response
159 */
160 public function delete_from_cart( $request ) {
161 $uuid = $request->get_param( 'uuid' );
162
163 if ( empty( $uuid ) ) {
164 return $this->error(
165 __( 'UUID is required', 'booktics' ),
166 422,
167 'Validation'
168 );
169 }
170
171 $this->cart_manager->remove_cart_item( $uuid );
172
173 return $this->response( array(), __( 'Successfully deleted item from cart.', 'booktics' ) );
174 }
175
176 /**
177 * Synchronize cart session data to database for logged-in user
178 *
179 * @param $request
180 *
181 * @return array|\WP_HTTP_Response
182 */
183 public function sync_cart( $request ) {
184 $user_id = get_current_user_id();
185 $this->cart_manager->sync_session_to_db( $user_id );
186
187 $response = $this->cart_manager->get_cart();
188
189 return $this->response( $response, __( 'Successfully synced cart.', 'booktics' ) );
190 }
191
192 /**
193 * Get all items from the cart
194 *
195 * @return array|\WP_HTTP_Response
196 */
197 public function get_cart_items() {
198 $response = $this->cart_manager->get_cart();
199 $response['items'] = isset( $response['items'] ) ? array_map(
200 function ( $item ) {
201 if ( ! is_array( $item ) ) {
202 $item = (array) $item;
203 }
204
205 $item['service'] = $this->get_service( $item['service_id'] );
206 $item['team'] = $this->get_team_member( $item['team_member_id'] );
207
208 return $item;
209 }, $response['items']
210 ) : array();
211
212 return $this->response( $response, __( 'Cart items fetched successfully', 'booktics' ) );
213 }
214
215 /**
216 * Check if the current user is logged in
217 *
218 * @return bool True if user is logged in, false otherwise
219 */
220 public function is_user_logged_in() {
221 return is_user_logged_in();
222 }
223
224 /**
225 * Validate service, team member and price
226 *
227 * @param array $data Cart item data
228 *
229 * @return array|WP_Error Returns true if valid, WP_Error otherwise
230 */
231 private function validate_cart_item( array $data ) {
232 $error = new WP_Error();
233
234 $service = ( new Service_Model() )->find( $data['service_id'] );
235 if ( ! $service ) {
236 $error->add( 'invalid_service', __( 'Invalid service selected', 'booktics' ) );
237 }
238
239 $team_member = ( new Team_Member_Model() )->find( $data['team_member_id'] );
240 if ( empty( $team_member ) ) {
241 $error->add( 'invalid_team_member', __( 'Invalid team member selected', 'booktics' ) );
242 }
243
244 $service_price = 0;
245 $addition_durations = $service->additional_durations;
246 if ( ! empty( $addition_durations ) && isset( $data['additional_duration_id'] ) ) {
247 $addition_durations = array_filter(
248 $addition_durations, function ( $duration ) use ( $data ) {
249 return $duration['id'] === $data['additional_duration_id'];
250 }
251 );
252 $addition_duration = reset( $addition_durations );
253 $service_price = $addition_duration['charge_amount'] ?? 0;
254 }
255 $data['price'] = $service_price;
256
257 return $error->has_errors() ? $error : $data;
258 }
259
260 /**
261 * Edit a cart item
262 *
263 * @param $request
264 *
265 * @return array|\WP_HTTP_Response
266 */
267 public function edit_cart_item( $request ) {
268 $uuid = $request->get_param( 'uuid' );
269 $params = json_decode( $request->get_body(), true );
270
271 if ( empty( $uuid ) ) {
272 return $this->error(
273 __( 'UUID is required', 'booktics' ),
274 422,
275 'Validation'
276 );
277 }
278
279 $validated = $this->prepare_item_to_save( $params );
280 if ( is_wp_error( $validated ) ) {
281 return $this->error(
282 __( 'Cart validation error', 'booktics' ),
283 422,
284 'Validation',
285 $validated->errors
286 );
287 }
288
289 // Add UUID to validated data
290 $validated['uuid'] = $uuid;
291
292 // Update the cart item
293 $updated_item = $this->cart_manager->edit_cart_item( $uuid, $validated );
294
295 if ( empty( $updated_item ) ) {
296 return $this->error(
297 __( 'Cart item not found', 'booktics' ),
298 404,
299 'NotFound'
300 );
301 }
302
303 return $this->response(
304 $updated_item,
305 __( 'Successfully updated cart item', 'booktics' )
306 );
307 }
308
309 /**
310 * @param $service_id
311 *
312 * @return array
313 */
314 public function get_service( $service_id ): array {
315 $service = Service_Model::find( $service_id );
316 if ( empty( $service ) ) {
317 return array();
318 }
319
320 return array(
321 'id' => $service->id,
322 'title' => $service->title,
323 );
324 }
325
326 /**
327 * @param $team_member_id
328 *
329 * @return array
330 */
331 public function get_team_member( $team_member_id ): array {
332 $team_member = ( new Team_Member_Model() )->find( $team_member_id );
333 if ( empty( $team_member ) ) {
334 return array();
335 }
336 $team_member = $team_member->to_array();
337
338 return array(
339 'id' => $team_member['id'],
340 'display_name' => $team_member['display_name'] ?? '',
341 'image' => $team_member['image'] ?? '',
342 );
343 }
344 }
345