PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.2.1
LatePoint – Calendar Booking Plugin for Appointments and Events v5.2.1
5.6.7 5.6.6 5.6.5 5.6.4 5.6.3 5.6.2 5.6.1 5.6.0 5.5.2 5.5.1 5.5.0 5.4.2 trunk 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.1.91 5.1.92 5.1.93 5.1.94 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1
latepoint / lib / misc / process_action.php
latepoint / lib / misc Last commit date
blocked_period.php 1 year ago booked_period.php 1 year ago booking_request.php 1 year ago booking_resource.php 1 year ago booking_slot.php 1 year ago filter.php 1 year ago process_action.php 9 months ago process_event.php 1 year ago role.php 1 year ago router.php 1 year ago step.php 1 year ago stripe_connect_customer.php 1 year ago time_period.php 1 year ago user.php 1 year ago work_period.php 1 year ago
process_action.php
570 lines
1 <?php
2 /*
3 * Copyright (c) 2022 LatePoint LLC. All rights reserved.
4 */
5
6 namespace LatePoint\Misc;
7
8 class ProcessAction{
9 public string $id;
10 public string $type = 'send_email';
11 public string $status = 'active';
12 public ?array $settings = [];
13 public array $prepared_data_for_run = [];
14 public array $replacement_vars = [];
15 public array $selected_data_objects = []; // example ['model' => 'booking', 'id' => INT]
16 public ProcessEvent $event;
17
18 function __construct($args = []){
19 $allowed_props = self::allowed_props();
20 foreach($args as $key => $arg){
21 if(in_array($key, $allowed_props)) $this->$key = $arg;
22 }
23 if(empty($this->id)) $this->id = self::generate_id();
24 switch($this->type){
25 case 'send_email':
26 $this->settings['to_email'] = $this->settings['to_email'] ?? '';
27 $this->settings['subject'] = $this->settings['subject'] ?? '';
28 $this->settings['content'] = $this->settings['content'] ?? '';
29 break;
30 case 'send_sms':
31 $this->settings['to_phone'] = $this->settings['to_phone'] ?? '';
32 $this->settings['content'] = $this->settings['content'] ?? '';
33 break;
34 case 'send_whatsapp':
35 $this->settings['to_phone'] = $this->settings['to_phone'] ?? '';
36 $this->settings['content'] = $this->settings['content'] ?? '';
37 break;
38 }
39 }
40
41 public function is_attach_calendar( ) {
42 return !empty($this->settings['attach_calendar']) && \OsUtilHelper::is_on($this->settings['attach_calendar']);
43 }
44
45 public function get_nice_type_name(){
46 return self::get_action_name_for_type($this->type);
47 }
48
49 public function get_descriptive_setting(){
50 switch($this->type) {
51 case 'send_email':
52 return $this->settings['to_email'] ?? '';
53 case 'send_sms':
54 return $this->settings['to_phone'] ?? '';
55 case 'send_whatsapp':
56 return $this->settings['to_phone'] ?? '';
57 }
58 }
59
60 public function generate_replacement_vars(){
61 $this->replacement_vars = \OsReplacerHelper::generate_replacement_vars_from_data_objects($this->selected_data_objects);
62 }
63
64 public function set_from_params($params){
65 if(!empty($params['id'])) $this->id = $params['id'];
66 if(!empty($params['type'])) $this->type = $params['type'];
67 if(!empty($params['settings'])) $this->settings = $params['settings'];
68 if(!empty($params['event'])) $this->event = new ProcessEvent(['type' => $params['event']['type']]);
69 }
70
71 public function load_settings_from_template($template_id){
72 $templates = \OsNotificationsHelper::load_templates_for_action_type($this->type);
73 foreach($templates as $template){
74 if($template['id'] == $template_id){
75 switch($this->type){
76 case 'send_email':
77 $this->settings['to_email'] = $template['to_email'];
78 $this->settings['subject'] = $template['subject'];
79 $this->settings['content'] = $template['content'];
80 break;
81 case 'send_sms':
82 $this->settings['to_phone'] = $template['to_phone'];
83 $this->settings['content'] = $template['content'];
84 break;
85 case 'send_whatsapp':
86 $this->settings['to_phone'] = $template['to_phone'];
87 $this->settings['content'] = $template['content'];
88 break;
89 }
90
91 /**
92 * Returns an array of process action settings, based on a selected template
93 *
94 * @since 4.7.0
95 * @hook latepoint_process_action_settings
96 *
97 * @param {array} $settings Array of settings to filter
98 * @param {array} $template Array of data representing selected template
99 * @param {ProcessAction} $action Instance of <code>ProcessAction</code> for which settings are being generated
100 *
101 * @returns {array} Filtered array of process action settings
102 */
103 $this->settings = apply_filters('latepoint_process_action_settings', $this->settings, $template, $this);
104 break;
105 }
106 }
107 }
108
109 public static function generate_form(ProcessAction $action, string $process_id = ''): string{
110 $descriptive_setting = $action->get_descriptive_setting() ? '<div class="process-action-descriptive-setting">'.$action->get_descriptive_setting().'</div>' : '';
111 $html = '<div class="process-action-form pa-type-'.$action->type.' pa-status-'.$action->status.'" data-id="'.$action->id.'">';
112 $html.= '<div class="process-action-heading">
113 <div class="process-action-status"></div>
114 <div class="process-action-icon"></div>
115 <div class="process-action-name">'.self::get_action_name_for_type($action->type).'</div>
116 '.$descriptive_setting.'
117 <div class="process-action-chevron"><i class="latepoint-icon latepoint-icon-chevron-down"></i></div>
118 <a href="#" class="process-action-remove os-remove-process-action"
119 data-os-prompt="'.__('Are you sure you want to delete this action?', 'latepoint').'"><i class="latepoint-icon latepoint-icon-cross"></i></a>
120 </div>';
121 $html.= '<div class="process-action-content">';
122 $html.= '<div class="os-row">';
123 $html.= \OsFormHelper::select_field('process[actions]['.$action->id.'][type]', __('Action Type', 'latepoint'), \LatePoint\Misc\ProcessAction::get_action_types_for_select(), $action->type, ['class' => 'process-action-type', 'data-action-id' => $action->id, 'data-process-id' => $process_id, 'data-route' => \OsRouterHelper::build_route_name('processes', 'load_action_settings')], ['class' => 'os-col-10']);
124 $html.= \OsFormHelper::select_field('process[actions]['.$action->id.'][status]', __('Status', 'latepoint'), [LATEPOINT_STATUS_ACTIVE => __('Active', 'latepoint'), LATEPOINT_STATUS_DISABLED => __('Disabled', 'latepoint')], $action->status, false, ['class' => 'os-col-2']);
125 $html.= '</div>';
126 $html.= '<div class="process-action-settings">';
127 $html.= self::generate_settings_fields($action, $process_id);
128 $html.= '</div>';
129 $html.= '<div class="process-buttons">
130 <a href="#" class="latepoint-btn latepoint-btn-danger pull-left os-remove-process-action"
131 data-os-prompt="'.__('Are you sure you want to delete this action?', 'latepoint').'" >'.__('Delete', 'latepoint').'</a>
132 <a href="#" data-route="'.\OsRouterHelper::build_route_name('processes', 'action_test_preview').'" class="latepoint-btn latepoint-btn-secondary os-run-process-action" ><i class="latepoint-icon latepoint-icon-play-circle"></i><span>'.__('Test this action', 'latepoint').'</span></a>
133 </div>';
134 $html.= '</div>';
135 $html.= '</div>';
136 return $html;
137 }
138
139
140 public static function generate_settings_fields(ProcessAction $action, string $process_id = ''){
141 $html = '';
142
143 if(in_array($action->type, ['send_email', 'send_sms'])){
144 $html.= '<div class="process-action-controls-wrapper">';
145 $html.= '<a href="#" data-os-after-call="latepoint_init_template_library" data-os-params="'.\OsUtilHelper::build_os_params(['action_id'=>$action->id, 'action_type'=>$action->type, 'process_id' => $process_id]).'" data-os-lightbox-classes="width-1000" data-os-action="'.\OsRouterHelper::build_route_name('notifications', 'templates_index').'" href="#" data-os-output-target="side-panel" class="latepoint-btn latepoint-btn-outline latepoint-btn-sm"><i class="latepoint-icon latepoint-icon-book"></i><span>'.__('Load from template', 'latepoint').'</span></a>';
146 $html.= '<a href="#" class="latepoint-btn latepoint-btn-outline latepoint-btn-sm open-template-variables-panel"><i class="latepoint-icon latepoint-icon-zap"></i><span>'.__('Show smart variables', 'latepoint').'</span></a>';
147 $html.= '</div>';
148 }
149
150 switch($action->type){
151 case 'send_email':
152 $html.= '<div class="os-row">';
153 $html.= \OsFormHelper::text_field('process[actions]['.$action->id.'][settings][to_email]', __('To Email', 'latepoint'), $action->settings['to_email'], ['theme' => 'simple', 'placeholder' => __('To email address', 'latepoint')], ['class' => 'os-col-6']);
154 $html.= \OsFormHelper::text_field('process[actions]['.$action->id.'][settings][subject]', __('Email Subject', 'latepoint'), $action->settings['subject'], ['theme' => 'simple', 'placeholder' => __('Email Subject', 'latepoint')], ['class' => 'os-col-6']);
155 $html.= '</div>';
156 $html.= \OsFormHelper::textarea_field('process[actions]['.$action->id.'][settings][content]', false, $action->settings['content'], ['id' => 'process_actions_'.$action->id.'_settings_content', 'class' => 'os-wp-editor-textarea']);
157 $html.= \OsFormHelper::toggler_field('process[actions]['.$action->id.'][settings][attach_calendar]', __('Attach Booking Calendar', 'latepoint'), $action->is_attach_calendar());
158 $html.= \OsFormHelper::multiple_files_uploader_field('process[actions]['.$action->id.'][settings][attachments]', esc_html__( '+ Attach File', 'latepoint' ), esc_html__( 'Remove File', 'latepoint' ), $action->get_attachments() );
159 break;
160 case 'send_sms':
161 if(\OsSmsHelper::get_sms_processors()){
162 $html.= \OsFormHelper::text_field('process[actions]['.$action->id.'][settings][to_phone]', __('To Phone Number', 'latepoint'), $action->settings['to_phone'], ['theme' => 'simple', 'placeholder' => __('Phone Number', 'latepoint')]);
163 $html.= \OsFormHelper::textarea_field('process[actions]['.$action->id.'][settings][content]', __('Message Content', 'latepoint'), $action->settings['content'], ['theme' => 'simple', 'placeholder' => __('Message', 'latepoint'), 'rows' => 4]);
164 }else{
165 $html = \OsUtilHelper::generate_missing_addon_link(__('You have to enable an SMS processor to send text messages. Available in a premium version.', 'latepoint'));
166 }
167 break;
168 case 'send_whatsapp':
169 if(\OsWhatsappHelper::get_whatsapp_processors()){
170 $html.= '<div class="latepoint-whatsapp-templates-loader" data-route="'.esc_attr(\OsRouterHelper::build_route_name('whatsapp', 'load_templates_for_action')).'" data-selected-template-id="'.esc_attr($action->settings['template_id'] ?? '').'" data-process-id="'.esc_attr($process_id).'" data-process-action-id="'.esc_attr($action->id).'"></div>';
171 $html.= '<div class="latepoint-whatsapp-templates-holder">'.\OsFormHelper::get_hidden_fields_for_array($action->settings, 'process[actions]['.$action->id.']').'</div>';
172
173 }else{
174 $html = \OsUtilHelper::generate_missing_addon_link(__('You have to enable a WhatsApp processor to send messages. Available in a premium version.', 'latepoint'));
175 }
176 break;
177 case 'trigger_webhook':
178 $html = \OsUtilHelper::generate_missing_addon_link(__('Requires upgrade to a premium version', 'latepoint'));
179 break;
180 }
181
182 /**
183 * Filters HTML code (after) for Process Action settings form
184 *
185 * @since 4.7.0
186 * @hook latepoint_process_action_settings_fields_html_after
187 *
188 * @param {string} $html HTML content of the settings form
189 * @param {ProcessAction} $action ProcessAction object for which this settings form is being generated
190 *
191 * @returns {string} HTML content of the settings form
192 */
193 return apply_filters('latepoint_process_action_settings_fields_html_after', $html, $action);
194 }
195
196 public static function generate_id(): string{
197 return 'pa_'.\OsUtilHelper::random_text('alnum', 6);
198 }
199
200 public function settings_form(){
201 $html = '';
202 switch($this->type){
203 case 'send_email':
204 $html.= \OsFormHelper::text_field('action[actions]['.$this->id.'][to]', '', $this->settings['to'], ['theme' => 'simple', 'placeholder' => __('Email To', 'latepoint')]);
205 break;
206 case 'send_sms':
207 $html.= \OsFormHelper::text_field('action[actions]['.$this->id.'][to]', '', $this->settings['to'], ['theme' => 'simple', 'placeholder' => __('SMS To', 'latepoint')]);
208 break;
209 case 'send_whatsapp':
210 $html.= \OsFormHelper::text_field('action[actions]['.$this->id.'][to]', '', $this->settings['to'], ['theme' => 'simple', 'placeholder' => __('WhatsApp Message To', 'latepoint')]);
211 break;
212 case 'trigger_webhook':
213 $html.= \OsFormHelper::text_field('action[actions]['.$this->id.'][url]', '', $this->settings['url'], ['theme' => 'simple', 'placeholder' => __('Webhook URL', 'latepoint')]);
214 break;
215 }
216
217 return apply_filters('latepoint_process_action_settings_form_html', $html, $this);
218 }
219
220
221 public static function get_action_types(){
222 $action_types = ['send_email', 'send_sms', 'trigger_webhook', 'send_whatsapp'];
223
224 /**
225 * Returns an array of process action types that can be executed when an event is triggered
226 *
227 * @since 4.7.0
228 * @hook latepoint_process_action_types
229 *
230 * @param {array} $action_types Array of action types to filter
231 *
232 * @returns {array} Filtered array of action types
233 */
234 return apply_filters('latepoint_process_action_types', $action_types);
235 }
236
237 public static function get_action_name_for_type($type){
238 $names = [
239 'send_email' => __('Send Email', 'latepoint'),
240 'send_sms' => __('Send SMS', 'latepoint'),
241 'trigger_webhook' => __('HTTP Request (Webhook)', 'latepoint'),
242 'send_whatsapp' => __('Send WhatsApp Message', 'latepoint')
243 ];
244
245 /**
246 * Returns an array of process action types mapped to their displayable names
247 *
248 * @since 4.7.0
249 * @hook latepoint_process_action_names
250 *
251 * @param {array} $names Array of action types/names to filter
252 *
253 * @returns {array} Filtered array of action types/names
254 */
255 $names = apply_filters('latepoint_process_action_names', $names);
256
257 return $names[$type] ?? __('n/a', 'latepoint');
258 }
259
260 public static function get_action_types_for_select(){
261 $types = self::get_action_types();
262 $types_for_select = [];
263 foreach($types as $type){
264 $types_for_select[$type] = self::get_action_name_for_type($type);
265 }
266 return $types_for_select;
267 }
268
269 public function prepare_data_for_run(){
270 $this->generate_replacement_vars();
271 foreach($this->selected_data_objects as $data_object){
272 switch($data_object['model']) {
273 case 'order':
274 $this->prepared_data_for_run['activity_data']['order_id'] = $data_object['id'];
275 if(!empty($data_object['model_ready'])){
276 $this->prepared_data_for_run['activity_data']['customer_id'] = $data_object['model_ready']->customer_id;
277 }
278 break;
279 case 'booking':
280 $this->prepared_data_for_run['activity_data']['booking_id'] = $data_object['id'];
281 if(!empty($data_object['model_ready'])){
282 $this->prepared_data_for_run['activity_data']['agent_id'] = $data_object['model_ready']->agent_id;
283 $this->prepared_data_for_run['activity_data']['service_id'] = $data_object['model_ready']->service_id;
284 $this->prepared_data_for_run['activity_data']['customer_id'] = $data_object['model_ready']->customer_id;
285 }
286 break;
287 case 'customer':
288 $this->prepared_data_for_run['activity_data']['customer_id'] = $data_object['id'];
289 break;
290 case 'transaction':
291 $this->prepared_data_for_run['activity_data']['transaction_id'] = $data_object['id'];
292 break;
293 case 'payment_request':
294 $this->prepared_data_for_run['activity_data']['payment_request_id'] = $data_object['id'];
295 break;
296 }
297 }
298
299 $this->replacement_vars['sender_type'] = $this->type;
300
301 switch($this->type) {
302 case 'send_email':
303 $this->prepared_data_for_run['to'] = \OsReplacerHelper::replace_all_vars($this->settings['to_email'], $this->replacement_vars);
304 $this->prepared_data_for_run['subject'] = \OsReplacerHelper::replace_all_vars($this->settings['subject'], $this->replacement_vars);
305 $this->prepared_data_for_run['content'] = \OsReplacerHelper::replace_all_vars($this->settings['content'], $this->replacement_vars);
306 $this->prepared_data_for_run['attachments'] = [];
307
308 if ($this->is_attach_calendar()) {
309 $booking = $this->find_booking_from_selected_data();
310
311 if ($booking) {
312 $ical_temp_file = $this->create_ical_temp_file($booking);
313
314 if ($ical_temp_file) {
315 $this->prepared_data_for_run['attachments'][] = $ical_temp_file;
316 $this->prepared_data_for_run['_attachments_temp_files'] = [$ical_temp_file];
317 }
318 }
319 }
320 $attachments = $this->get_attachments();
321 if (!empty($attachments)) {
322 foreach ( $attachments as $attachment_id ) {
323 $file_path = get_attached_file($attachment_id);
324 if ($file_path && file_exists($file_path)) {
325 $this->prepared_data_for_run['attachments'][] = $file_path;
326 } else {
327 \OsDebugHelper::log('Attachment file not found: ' . $file_path, 'error');
328 }
329 }
330 }
331
332 break;
333 case 'send_sms':
334 $this->prepared_data_for_run['to'] = \OsReplacerHelper::replace_all_vars($this->settings['to_phone'], $this->replacement_vars);
335 $this->prepared_data_for_run['content'] = \OsReplacerHelper::replace_all_vars($this->settings['content'], $this->replacement_vars);
336 break;
337 case 'send_whatsapp':
338 $this->prepared_data_for_run['to'] = \OsReplacerHelper::replace_all_vars($this->settings['to_phone'], $this->replacement_vars);
339 $this->prepared_data_for_run['data']['type'] = 'template';
340 $this->prepared_data_for_run['data']['template_id'] = $this->settings['template_id'];
341 $this->prepared_data_for_run['data']['template_language'] = $this->settings['template_language'];
342 $this->prepared_data_for_run['data']['template_parameter_format'] = $this->settings['template_parameter_format'];
343 $this->prepared_data_for_run['data']['template_category'] = $this->settings['template_category'];
344 $this->prepared_data_for_run['data']['template_name'] = $this->settings['template_name'];
345
346 $selected_template = \OsWhatsappHelper::get_template($this->settings['template_id']);
347
348 $this->prepared_data_for_run['data']['variables'] = $this->settings['variables'] ?? [];
349 if(!empty($this->settings['variables'])){
350 foreach($this->settings['variables'] as $type => $variables){
351 $parameters = [];
352 foreach($variables as $key => $value){
353 $clean_key = str_replace(['{{', '}}'], '', $key);
354 $replaced_value = \OsReplacerHelper::replace_all_vars($value, $this->replacement_vars);
355 if(is_numeric($clean_key)){
356 $parameters[] = ['type' => 'text', 'text' => $replaced_value];
357 }else{
358 $parameters[] = ['type' => 'text', 'text' => $replaced_value, 'parameter_name' => $clean_key];
359 }
360 }
361 if(strtolower($type) == 'buttons'){
362 // each button has to have a separate component element, only URL typed buttons have variables in them
363 foreach($parameters as $index => $parameter){
364 $this->prepared_data_for_run['data']['components'][] = [
365 'type' => 'button',
366 'index' => $index,
367 'sub_type' => 'url',
368 'parameters' => $parameters
369 ];
370 }
371 }else{
372 $this->prepared_data_for_run['data']['components'][] = ['type' => $type, 'parameters' => $parameters];
373 }
374 }
375 }
376
377 $content_by_type['header'] = \OsWhatsappHelper::get_template_component_value_by_key($selected_template, 'HEADER', 'text');
378 $content_by_type['body'] = \OsWhatsappHelper::get_template_component_value_by_key($selected_template, 'BODY', 'text');
379 $content_by_type['buttons'] = \OsWhatsappHelper::get_template_component_value_by_key($selected_template, 'BUTTONS', 'buttons');
380
381
382 foreach($content_by_type as $content_type => $content){
383 if($content_type == 'buttons'){
384 if(!empty($content)){
385 foreach($content as $button){
386 // only URL can have variables
387 if($button['type'] == 'URL') $button['url'] = empty($this->settings['variables'][$content_type]) ? $button['url'] : \OsReplacerHelper::replace_all_vars(str_replace(array_keys($this->settings['variables'][$content_type]), array_values($this->settings['variables'][$content_type]), $button['url']), $this->replacement_vars);
388 $this->prepared_data_for_run['content_for_'.$content_type][] = $button;
389 }
390 }else{
391 $this->prepared_data_for_run['content_for_'.$content_type] = [];
392 }
393 }else{
394 $this->prepared_data_for_run['content_for_'.$content_type] = empty($this->settings['variables'][$content_type]) ? $content : \OsReplacerHelper::replace_all_vars(str_replace(array_keys($this->settings['variables'][$content_type]), array_values($this->settings['variables'][$content_type]), $content), $this->replacement_vars);
395 }
396 }
397 break;
398 }
399
400 /**
401 * Prepare data for action run
402 *
403 * @since 4.7.0
404 * @hook latepoint_process_prepare_data_for_run
405 *
406 * @param {ProcessAction} $action ProcessAction that was executed
407 *
408 * @returns {ProcessAction} $action ProcessAction with prepared data for action run
409 */
410 return apply_filters('latepoint_process_prepare_data_for_run', $this);
411 }
412
413
414 /**
415 * @param $prepare_data
416 * @return array [status => '', 'message' => '']
417 */
418 public function run($prepare_data = true){
419 $result = [
420 'status' => LATEPOINT_STATUS_SUCCESS,
421 'message' => __('Nothing to run', 'latepoint')
422 ];
423 if($prepare_data) $this->prepare_data_for_run();
424
425 switch($this->type) {
426 case 'send_email':
427 $notification_type = 'email';
428 $result = \OsNotificationsHelper::send($notification_type, $this->prepared_data_for_run);
429 break;
430 case 'send_sms':
431 $notification_type = 'sms';
432 $result = \OsNotificationsHelper::send($notification_type, $this->prepared_data_for_run);
433 break;
434 case 'send_whatsapp':
435 $notification_type = 'whatsapp';
436 $result = \OsNotificationsHelper::send($notification_type, $this->prepared_data_for_run);
437 break;
438 }
439
440 $tmp_files = $this->prepared_data_for_run['_attachments_temp_files'] ?? [];
441 foreach ( $tmp_files as $tmp_file ) {
442 if ( file_exists( $tmp_file ) ) {
443 @unlink( $tmp_file );
444 };
445 }
446
447 /**
448 * ProcessAction run result
449 *
450 * @since 4.7.0
451 * @hook latepoint_process_action_run
452 *
453 * @param {array} $result The array of data describing the status of the action run
454 * @param {ProcessAction} $action ProcessAction that was executed
455 *
456 * @returns {array} The array of descriptive data, possibly transformed by additional hooked ProcessAction handlers
457 */
458 return apply_filters('latepoint_process_action_run', $result, $this);
459 }
460
461
462 /**
463 * @return string
464 */
465 public function generate_preview(){
466 if(empty($this->prepared_data_for_run)){
467 $this->prepare_data_for_run();
468 // nothing was generated, probably because there is no object attached
469 if(empty($this->prepared_data_for_run)) return '<div class="action-preview-error">'.__('You have to create a booking to be able to test this action.', 'latepoint').'</div>';
470 }
471 $html = '<div class="action-preview-content-wrapper">';
472 $preview_content_html = '';
473 switch($this->type){
474 case 'send_email':
475 $preview_content_html.= '<div class="action-preview-subject"><span class="os-label">'.__('Subject:', 'latepoint').'</span> '.$this->prepared_data_for_run['subject'].'</div>';
476 $preview_content_html.= '<div class="action-preview-to"><span class="os-label">'.__('To:', 'latepoint').'</span><span class="os-value">'.esc_html($this->prepared_data_for_run['to']).'</div>';
477 $preview_content_html.= '<div class="action-preview-content">'.$this->prepared_data_for_run['content'].'</div>';
478 break;
479 case 'send_sms':
480 $preview_content_html.= '<div class="action-preview-to"><span class="os-label">'.__('To:', 'latepoint').'</span><span class="os-value">'.esc_html($this->prepared_data_for_run['to']).'</span></div>';
481 $preview_content_html.= '<div class="action-preview-content">'.$this->prepared_data_for_run['content'].'</div>';
482 break;
483 case 'send_whatsapp':
484 $preview_content_html.= '<div class="action-preview-to"><span class="os-label">'.__('To:', 'latepoint').'</span><span class="os-value">'.esc_html($this->prepared_data_for_run['to']).'</span></div>';
485 $preview_content_html.= '<div class="action-preview-content">';
486 $preview_content_html.= '<div class="latepoint-whatsapp-template-preview-messages">';
487 $preview_content_html.= '<div class="latepoint-whatsapp-template-preview-message">';
488 $preview_content_html.= '<div class="latepoint-whatsapp-template-preview-message-header">'.$this->prepared_data_for_run['content_for_header'].'</div>';
489 $preview_content_html.= '<div class="latepoint-whatsapp-template-preview-message-body">'.$this->prepared_data_for_run['content_for_body'].'</div>';
490 if($this->prepared_data_for_run['content_for_buttons']){
491 $preview_content_html.= '<div class="latepoint-whatsapp-template-preview-message-buttons">';
492 foreach($this->prepared_data_for_run['content_for_buttons'] as $button){
493 switch($button['type']){
494 case 'PHONE_NUMBER':
495 $preview_content_html.= '<a href="tel:'.esc_url($button['phone_number']).'" class="latepoint-whatsapp-template-preview-message-button"><i class="latepoint-icon latepoint-icon-phone"></i>'.esc_html($button['text']).'</a>';
496 break;
497 case 'URL':
498 $preview_content_html.= '<a href="'.esc_url($button['url']).'" class="latepoint-whatsapp-template-preview-message-button"><i class="latepoint-icon latepoint-icon-external-link"></i>'.esc_html($button['text']).'</a>';
499 break;
500 }
501 }
502 $preview_content_html.= '</div>';
503 }
504 $preview_content_html.= '</div>';
505 $preview_content_html.= '</div>';
506 $preview_content_html.= '</div>';
507 break;
508 }
509
510 /**
511 * Generates a preview html for ProcessAction testing
512 *
513 * @since 4.7.0
514 * @hook latepoint_process_action_generate_preview
515 *
516 * @param {string} $preview_content_html HTML that goes inside of a preview
517 * @param {ProcessAction} $action ProcessAction that is being tested
518 *
519 * @returns {string} HTML that goes inside of a preview
520 */
521 $preview_content_html = apply_filters('latepoint_process_action_generate_preview', $preview_content_html, $this);
522 $html.= $preview_content_html;
523 $html.= '</div>';
524 return $html;
525 }
526
527 private function find_booking_from_selected_data() {
528 foreach ($this->selected_data_objects as $data_object) {
529 if ($data_object['model'] === 'booking' && !empty($data_object['model_ready'])) {
530 return $data_object['model_ready'];
531 }
532 }
533 return null;
534 }
535
536 private function create_ical_temp_file( $booking ) {
537 try {
538 $ical_content = \OsBookingHelper::generate_ical_event_string( $booking );
539 if ( empty( $ical_content ) ) {
540 throw new \Exception( 'iCal content is empty' );
541 }
542
543 $temp_file = tempnam(sys_get_temp_dir(), 'latepoint_ical_');
544 $ical_temp_file = $temp_file . '.ics';
545 rename($temp_file, $ical_temp_file);
546
547 if ( file_put_contents( $ical_temp_file, $ical_content ) !== false ) {
548 return $ical_temp_file;
549 } else {
550 throw new \Exception( 'Failed to write iCal content to file' );
551 }
552 } catch ( \Exception $e ) {
553 \OsDebugHelper::log( 'Failed to create iCal file: ' . $e->getMessage(), 'error' );
554 }
555
556 return null;
557 }
558
559 public static function replace_variables($test){
560
561 }
562
563 public static function allowed_props(): array{
564 return ['id', 'type', 'settings', 'status'];
565 }
566
567 public function get_attachments() {
568 return !empty($this->settings['attachments']) ? explode(',', $this->settings['attachments']) : [];
569 }
570 }