PluginProbe
Booktics – Appointment Booking Calendar for Service Businesses / 1.0.27
Booktics – Appointment Booking Calendar for Service Businesses v1.0.27
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
← All changes | core/dummy-data/dummy-data-manager.php +601 -86 1.0.1 → 1.0.27 View file →
@@ -1,86 +1,601 @@
1 -<?php
2 -
3 -namespace Booktics\Dummy_Data;
4 -
5 -use Booktics\Models\Service_Model;
6 -use Exception;
7 -
8 -class Dummy_Data_Manager {
9 - private $generator;
10 -
11 - public function __construct() {
12 - $this->generator = new Generator();
13 - }
14 -
15 - /**
16 - * Generate dummy data for onboarding
17 - */
18 - public function generate_onboarding_data( $service_count = 3 ) {
19 - $result = $this->create_services( $service_count );
20 - if ( empty( $result['service_ids'] ) ) {
21 - return false;
22 - }
23 -
24 - return array(
25 - 'services' => $result['service_ids'],
26 - 'errors' => $result['errors'],
27 - );
28 - }
29 -
30 - /**
31 - * Create fake services
32 - *
33 - * @param int $count Number of services to create
34 - *
35 - * @return array Created service IDs
36 - */
37 - public function create_services( int $count = 3 ): array {
38 - $result = array(
39 - 'service_ids' => array(),
40 - 'errors' => array(),
41 - );
42 - $current_services = Service_Model::paginate();
43 - if ( $current_services['total'] > 0 ) {
44 - return $result;
45 - }
46 -
47 - $service_model = new \Booktics\Models\Service_Model();
48 - $service_ids = array();
49 - $service_types = array(
50 - 'Consultation' => 30,
51 - 'Check-up' => 60,
52 - 'Therapy' => 45,
53 - 'Examination' => 90,
54 - 'Follow-up' => 20,
55 - 'Massage' => 60,
56 - 'Treatment' => 45,
57 - 'Evaluation' => 30,
58 - );
59 -
60 - for ( $i = 0; $i < $count; $i++ ) {
61 - $service_name = $this->generator->random_element( array_keys( $service_types ) );
62 - $duration = $service_types[ $service_name ];
63 - $description = $this->generator->sentence( 7 );
64 - $service_data = array(
65 - 'title' => $service_name,
66 - 'description' => $description,
67 - 'content' => $description,
68 - 'duration_time' => $duration,
69 - 'duration_unit' => 'minutes',
70 - 'charge_amount' => $this->generator->number_between( 50, 300 ),
71 - 'status' => 'active',
72 - );
73 -
74 - try {
75 - $service_id = $service_model->create( $service_data );
76 - if ( $service_id ) {
77 - $result['service_ids'][] = $service_id;
78 - }
79 - } catch ( Exception $e ) {
80 - $result['errors'][] = 'Failed to create service: ' . $e->getMessage();
81 - }
82 - }
83 -
84 - return $result;
85 - }
86 -}
1 +<?php
2 +
3 +namespace Booktics\Dummy_Data;
4 +
5 +use Booktics\Models\Service_Model;
6 +use Ens\Flow\Flow;
7 +use Exception;
8 +use stdClass;
9 +
10 +class Dummy_Data_Manager {
11 + private $generator;
12 +
13 + /**
14 + * Constructor for dummy data manager
15 + *
16 + * @return void
17 + */
18 + public function __construct() {
19 + $this->generator = new Generator();
20 + }
21 +
22 + /**
23 + * Generate dummy data for onboarding
24 + */
25 + public function generate_onboarding_data( $service_count = 3 ) {
26 + $flow_result = $this->create_automation_flows();
27 + $result = $this->create_services( $service_count );
28 + if ( empty( $result['service_ids'] ) ) {
29 + return false;
30 + }
31 +
32 + return array(
33 + 'flows' => $flow_result['flow_ids'],
34 + 'services' => $result['service_ids'],
35 + 'errors' => array_merge( $result['errors'], $flow_result['errors'] ),
36 + );
37 + }
38 +
39 + /**
40 + * Create fake services
41 + *
42 + * @param int $count Number of services to create
43 + *
44 + * @return array Created service IDs
45 + */
46 + public function create_services( int $count = 3 ): array {
47 + $result = array(
48 + 'service_ids' => array(),
49 + 'errors' => array(),
50 + );
51 + $current_services = Service_Model::paginate();
52 + if ( $current_services['total'] > 0 ) {
53 + return $result;
54 + }
55 +
56 + $service_model = new \Booktics\Models\Service_Model();
57 + $service_ids = array();
58 + $service_types = array(
59 + 'Consultation' => 30,
60 + 'Check-up' => 60,
61 + 'Therapy' => 45,
62 + 'Examination' => 90,
63 + 'Follow-up' => 20,
64 + 'Massage' => 60,
65 + 'Treatment' => 45,
66 + 'Evaluation' => 30,
67 + );
68 +
69 + for ( $i = 0; $i < $count; $i++ ) {
70 + $service_name = $this->generator->random_element( array_keys( $service_types ) );
71 + $duration = $service_types[ $service_name ];
72 + $description = $this->generator->sentence( 7 );
73 + $service_data = array(
74 + 'title' => $service_name,
75 + 'description' => $description,
76 + 'content' => $description,
77 + 'duration_time' => $duration,
78 + 'duration_unit' => 'minutes',
79 + 'charge_amount' => $this->generator->number_between( 50, 300 ),
80 + 'status' => 'active',
81 + );
82 +
83 + try {
84 + $service_id = $service_model->create( $service_data );
85 + if ( $service_id ) {
86 + $result['service_ids'][] = $service_id;
87 + }
88 + } catch ( Exception $e ) {
89 + $result['errors'][] = 'Failed to create service: ' . $e->getMessage();
90 + }
91 + }
92 +
93 + return $result;
94 + }
95 +
96 + /**
97 + * Create automation flows
98 + *
99 + * @return array Created flow IDs
100 + */
101 + public function create_automation_flows() {
102 + $result = array(
103 + 'flow_ids' => array(),
104 + 'errors' => array(),
105 + );
106 +
107 + $automation_flows = array(
108 + array(
109 + 'name' => 'Order Created',
110 + 'trigger' => 'order_created',
111 + 'status' => 'publish',
112 + 'flow_config' => array(
113 + 'nodes' => array(
114 + array(
115 + 'id' => 'node_1',
116 + 'type' => 'trigger',
117 + 'name' => 'trigger',
118 + 'data' => array(
119 + 'label' => 'trigger: order_created',
120 + 'subtitle' => 'Order Created',
121 + 'triggerValue' => 'order_created',
122 + ),
123 + 'position' => array(
124 + 'x' => 200,
125 + 'y' => 50,
126 + ),
127 + ),
128 + array(
129 + 'id' => 'node_2',
130 + 'type' => 'end',
131 + 'name' => 'end',
132 + 'data' => array(
133 + 'label' => 'end_flow',
134 + 'subtitle' => 'End execution path',
135 + ),
136 + 'position' => array(
137 + 'x' => 200,
138 + 'y' => 410,
139 + ),
140 + ),
141 + array(
142 + 'id' => 'node_3',
143 + 'type' => 'action',
144 + 'name' => 'email',
145 + 'data' => array(
146 + 'actionType' => 'send_email',
147 + 'label' => 'send_email',
148 + 'subtitle' => 'Subject: You just placed and order!',
149 + 'receiverType' => 'user_email',
150 + 'from_address' => '',
151 + 'subject' => 'You just placed and order!',
152 + 'body' => '<p>Hi {{customer_name}}, </p><p>We are glad to let you know that your order placed successful.</p><p>Your order no: {{order_no}}</p>',
153 + ),
154 + 'position' => array(
155 + 'x' => 200,
156 + 'y' => 230,
157 + ),
158 + ),
159 + ),
160 + 'edges' => array(
161 + array(
162 + 'id' => 'edge_node_1-node_3',
163 + 'type' => 'smoothstep',
164 + 'markerEnd' => array(
165 + 'type' => 'arrowclosed',
166 + ),
167 + 'source' => 'node_1',
168 + 'target' => 'node_3',
169 + 'data' => new stdClass(),
170 + ),
171 + array(
172 + 'id' => 'edge_node_3-node_2',
173 + 'type' => 'smoothstep',
174 + 'markerEnd' => array(
175 + 'type' => 'arrowclosed',
176 + ),
177 + 'source' => 'node_3',
178 + 'target' => 'node_2',
179 + 'data' => new stdClass(),
180 + ),
181 + ),
182 + ),
183 + ),
184 + array(
185 + 'name' => 'Team Member Invitation',
186 + 'trigger' => 'team_member_created',
187 + 'status' => 'publish',
188 + 'flow_config' => array(
189 + 'nodes' => array(
190 + array(
191 + 'id' => 'node_1',
192 + 'type' => 'trigger',
193 + 'name' => 'trigger',
194 + 'data' => array(
195 + 'label' => 'trigger: team_member_created',
196 + 'subtitle' => 'Team Member Created',
197 + 'triggerValue' => 'team_member_created',
198 + ),
199 + 'position' => array(
200 + 'x' => 200,
201 + 'y' => 50,
202 + ),
203 + ),
204 + array(
205 + 'id' => 'node_2',
206 + 'type' => 'end',
207 + 'name' => 'end',
208 + 'data' => array(
209 + 'label' => 'end_flow',
210 + 'subtitle' => 'End execution path',
211 + ),
212 + 'position' => array(
213 + 'x' => 200,
214 + 'y' => 410,
215 + ),
216 + ),
217 + array(
218 + 'id' => 'node_3',
219 + 'type' => 'action',
220 + 'name' => 'email',
221 + 'data' => array(
222 + 'actionType' => 'send_email',
223 + 'label' => 'send_email',
224 + 'subtitle' => 'Subject: You are invited to join the team.',
225 + 'receiverType' => 'team_member_email',
226 + 'from_address' => '',
227 + 'subject' => 'You are invited to join the team',
228 + 'body' => '<p>Hi {{team_member_name}}, </p><p>We are glad to let you know that you are invited to join our team.</p><p>Please reset your password from the below link.</p><p><a href="{{password_reset_url}}" rel="noopener noreferrer" target="_blank">{{password_reset_url}}</a></p>',
229 + ),
230 + 'position' => array(
231 + 'x' => 200,
232 + 'y' => 230,
233 + ),
234 + ),
235 + ),
236 + 'edges' => array(
237 + array(
238 + 'id' => 'edge_node_1-node_3',
239 + 'type' => 'smoothstep',
240 + 'markerEnd' => array(
241 + 'type' => 'arrowclosed',
242 + ),
243 + 'source' => 'node_1',
244 + 'target' => 'node_3',
245 + 'data' => new stdClass(),
246 + ),
247 + array(
248 + 'id' => 'edge_node_3-node_2',
249 + 'type' => 'smoothstep',
250 + 'markerEnd' => array(
251 + 'type' => 'arrowclosed',
252 + ),
253 + 'source' => 'node_3',
254 + 'target' => 'node_2',
255 + 'data' => new stdClass(),
256 + ),
257 + ),
258 + ),
259 + ),
260 + array(
261 + 'name' => 'Appointment Scheduled',
262 + 'trigger' => 'appointment_scheduled',
263 + 'status' => 'draft',
264 + 'flow_config' => array(
265 + 'nodes' => array(
266 + array(
267 + 'id' => 'node_1',
268 + 'type' => 'trigger',
269 + 'name' => 'trigger',
270 + 'data' => array(
271 + 'label' => 'trigger: appointment_scheduled',
272 + 'subtitle' => 'Appointment Scheduled',
273 + 'triggerValue' => 'appointment_scheduled',
274 + ),
275 + 'position' => array(
276 + 'x' => 200,
277 + 'y' => 50,
278 + ),
279 + ),
280 + array(
281 + 'id' => 'node_2',
282 + 'type' => 'end',
283 + 'name' => 'end',
284 + 'data' => array(
285 + 'label' => 'end_flow',
286 + 'subtitle' => 'End execution path',
287 + ),
288 + 'position' => array(
289 + 'x' => 200,
290 + 'y' => 410,
291 + ),
292 + ),
293 + array(
294 + 'id' => 'node_3',
295 + 'type' => 'action',
296 + 'name' => 'email',
297 + 'data' => array(
298 + 'actionType' => 'send_email',
299 + 'label' => 'send_email',
300 + 'subtitle' => 'Subject: You have a new appointment.',
301 + 'receiverType' => 'user_email',
302 + 'from_address' => '',
303 + 'subject' => 'You have a new appointment',
304 + 'body' => '<p>Dear {{customer_name}}, </p><p>We are glad to let you know that you have a new appointment schedule for {{appointment_service}} with {{appointment_team_member}} on {{appointment_date}} at {{start_time}}.</p>',
305 + ),
306 + 'position' => array(
307 + 'x' => 200,
308 + 'y' => 230,
309 + ),
310 + ),
311 + ),
312 + 'edges' => array(
313 + array(
314 + 'id' => 'edge_node_1-node_3',
315 + 'type' => 'smoothstep',
316 + 'markerEnd' => array(
317 + 'type' => 'arrowclosed',
318 + ),
319 + 'source' => 'node_1',
320 + 'target' => 'node_3',
321 + 'data' => new stdClass(),
322 + ),
323 + array(
324 + 'id' => 'edge_node_3-node_2',
325 + 'type' => 'smoothstep',
326 + 'markerEnd' => array(
327 + 'type' => 'arrowclosed',
328 + ),
329 + 'source' => 'node_3',
330 + 'target' => 'node_2',
331 + 'data' => new stdClass(),
332 + ),
333 + ),
334 + ),
335 + ),
336 + array(
337 + 'name' => 'Appointment Rescheduled',
338 + 'trigger' => 'appointment_rescheduled',
339 + 'status' => 'draft',
340 + 'flow_config' => array(
341 + 'nodes' => array(
342 + array(
343 + 'id' => 'node_1',
344 + 'type' => 'trigger',
345 + 'name' => 'trigger',
346 + 'data' => array(
347 + 'label' => 'trigger: appointment_rescheduled',
348 + 'subtitle' => 'Appointment Rescheduled',
349 + 'triggerValue' => 'appointment_rescheduled',
350 + ),
351 + 'position' => array(
352 + 'x' => 200,
353 + 'y' => 50,
354 + ),
355 + ),
356 + array(
357 + 'id' => 'node_2',
358 + 'type' => 'end',
359 + 'name' => 'end',
360 + 'data' => array(
361 + 'label' => 'end_flow',
362 + 'subtitle' => 'End execution path',
363 + ),
364 + 'position' => array(
365 + 'x' => 200,
366 + 'y' => 410,
367 + ),
368 + ),
369 + array(
370 + 'id' => 'node_3',
371 + 'type' => 'action',
372 + 'name' => 'email',
373 + 'data' => array(
374 + 'actionType' => 'send_email',
375 + 'label' => 'send_email',
376 + 'subtitle' => 'Subject: Your appointment has been rescheduled.',
377 + 'receiverType' => 'user_email',
378 + 'from_address' => '',
379 + 'subject' => 'Your appointment has been rescheduled',
380 + 'body' => '<p>Dear {{customer_name}}, </p><p>We want to inform you that your appointment has been rescheduled for {{appointment_service}} with {{appointment_team_member}} on {{appointment_date}} at {{start_time}}.</p>',
381 + ),
382 + 'position' => array(
383 + 'x' => 200,
384 + 'y' => 230,
385 + ),
386 + ),
387 + ),
388 + 'edges' => array(
389 + array(
390 + 'id' => 'edge_node_1-node_3',
391 + 'type' => 'smoothstep',
392 + 'markerEnd' => array(
393 + 'type' => 'arrowclosed',
394 + ),
395 + 'source' => 'node_1',
396 + 'target' => 'node_3',
397 + 'data' => new stdClass(),
398 + ),
399 + array(
400 + 'id' => 'edge_node_3-node_2',
401 + 'type' => 'smoothstep',
402 + 'markerEnd' => array(
403 + 'type' => 'arrowclosed',
404 + ),
405 + 'source' => 'node_3',
406 + 'target' => 'node_2',
407 + 'data' => new stdClass(),
408 + ),
409 + ),
410 + ),
411 + ),
412 + array(
413 + 'name' => 'Appointment Cancelled',
414 + 'trigger' => 'appointment_cancelled',
415 + 'status' => 'draft',
416 + 'flow_config' => array(
417 + 'nodes' => array(
418 + array(
419 + 'id' => 'node_1',
420 + 'type' => 'trigger',
421 + 'name' => 'trigger',
422 + 'data' => array(
423 + 'label' => 'trigger: appointment_cancelled',
424 + 'subtitle' => 'Appointment Cancelled',
425 + 'triggerValue' => 'appointment_cancelled',
426 + ),
427 + 'position' => array(
428 + 'x' => 200,
429 + 'y' => 50,
430 + ),
431 + ),
432 + array(
433 + 'id' => 'node_2',
434 + 'type' => 'end',
435 + 'name' => 'end',
436 + 'data' => array(
437 + 'label' => 'end_flow',
438 + 'subtitle' => 'End execution path',
439 + ),
440 + 'position' => array(
441 + 'x' => 200,
442 + 'y' => 410,
443 + ),
444 + ),
445 + array(
446 + 'id' => 'node_3',
447 + 'type' => 'action',
448 + 'name' => 'email',
449 + 'data' => array(
450 + 'actionType' => 'send_email',
451 + 'label' => 'send_email',
452 + 'subtitle' => 'Subject: Your appointment has been cancelled.',
453 + 'receiverType' => 'user_email',
454 + 'from_address' => '',
455 + 'subject' => 'Your appointment has been cancelled',
456 + 'body' => '<p>Dear {{customer_name}}, </p><p>We want to inform you that your appointment has been cancelled for {{appointment_service}} with {{appointment_team_member}} on {{date}} at {{start_time}}.</p>',
457 + ),
458 + 'position' => array(
459 + 'x' => 200,
460 + 'y' => 230,
461 + ),
462 + ),
463 + ),
464 + 'edges' => array(
465 + array(
466 + 'id' => 'edge_node_1-node_3',
467 + 'type' => 'smoothstep',
468 + 'markerEnd' => array(
469 + 'type' => 'arrowclosed',
470 + ),
471 + 'source' => 'node_1',
472 + 'target' => 'node_3',
473 + 'data' => new stdClass(),
474 + ),
475 + array(
476 + 'id' => 'edge_node_3-node_2',
477 + 'type' => 'smoothstep',
478 + 'markerEnd' => array(
479 + 'type' => 'arrowclosed',
480 + ),
481 + 'source' => 'node_3',
482 + 'target' => 'node_2',
483 + 'data' => new stdClass(),
484 + ),
485 + ),
486 + ),
487 + ),
488 + array(
489 + 'name' => 'Customer Invitation',
490 + 'trigger' => 'customer_created',
491 + 'status' => 'publish',
492 + 'flow_config' => array(
493 + 'nodes' => array(
494 + array(
495 + 'id' => 'node_1',
496 + 'type' => 'trigger',
497 + 'name' => 'trigger',
498 + 'data' => array(
499 + 'label' => 'trigger: customer_created',
500 + 'subtitle' => 'Customer Created',
501 + 'triggerValue' => 'customer_created',
502 + ),
503 + 'position' => array(
504 + 'x' => 200,
505 + 'y' => 50,
506 + ),
507 + ),
508 + array(
509 + 'id' => 'node_2',
510 + 'type' => 'end',
511 + 'name' => 'end',
512 + 'data' => array(
513 + 'label' => 'end_flow',
514 + 'subtitle' => 'End execution path',
515 + ),
516 + 'position' => array(
517 + 'x' => 200,
518 + 'y' => 410,
519 + ),
520 + ),
521 + array(
522 + 'id' => 'node_3',
523 + 'type' => 'action',
524 + 'name' => 'email',
525 + 'data' => array(
526 + 'actionType' => 'send_email',
527 + 'label' => 'send_email',
528 + 'subtitle' => 'Subject: Your customer profile created.',
529 + 'receiverType' => 'customer_email',
530 + 'from_address' => '',
531 + 'subject' => 'Your customer profile created.',
532 + 'body' => '<p>Dear {{customer_full_name}}, </p><p>We are glad to let you know that you are invited as customer to our platform.</p><p>Please reset your password from the below link.</p><p><a href="{{password_reset_url}}" rel="noopener noreferrer" target="_blank">{{password_reset_url}}</a></p>',
533 + ),
534 + 'position' => array(
535 + 'x' => 200,
536 + 'y' => 230,
537 + ),
538 + ),
539 + ),
540 + 'edges' => array(
541 + array(
542 + 'id' => 'edge_node_1-node_3',
543 + 'type' => 'smoothstep',
544 + 'markerEnd' => array(
545 + 'type' => 'arrowclosed',
546 + ),
547 + 'source' => 'node_1',
548 + 'target' => 'node_3',
549 + 'data' => new stdClass(),
550 + ),
551 + array(
552 + 'id' => 'edge_node_3-node_2',
553 + 'type' => 'smoothstep',
554 + 'markerEnd' => array(
555 + 'type' => 'arrowclosed',
556 + ),
557 + 'source' => 'node_3',
558 + 'target' => 'node_2',
559 + 'data' => new stdClass(),
560 + ),
561 + ),
562 + ),
563 + ),
564 + );
565 + try {
566 + $prefix_for_cpt = 'bt';
567 + $post_type = $prefix_for_cpt . '-flow';
568 + foreach ( $automation_flows as $key => $automation_flow ) {
569 + $existing_flow = get_posts(
570 + array(
571 + 'post_type' => $post_type,
572 + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Meta query is necessary for filtering appointments by meta fields
573 + 'meta_query' => array(
574 + array(
575 + 'key' => '_bt_notification_flow_trigger',
576 + 'value' => $automation_flow['trigger'],
577 + 'compare' => '=',
578 + ),
579 + ),
580 + 'post_status' => 'any',
581 + 'numberposts' => 1,
582 + )
583 + );
584 + if ( ! empty( $existing_flow ) ) {
585 + continue;
586 + }
587 +
588 + $flow = new Flow( 'bt', 0 );
589 + $flow->set_props( $automation_flow );
590 + $flow_id = $flow->save();
591 + if ( $flow_id ) {
592 + $result['flow_ids'][] = $flow_id;
593 + }
594 + }
595 + } catch ( Exception $e ) {
596 + $result['errors'][] = 'Failed to create service: ' . $e->getMessage();
597 + }
598 +
599 + return $result;
600 + }
601 +}