PluginProbe
WANotifier for Forms and Actions / 2.5.3
WANotifier for Forms and Actions v2.5.3
3.1.0 3.0.4 2.7.10 2.7.11 2.7.12 2.7.13 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 3.0.0 3.0.1 3.0.2 3.0.3 trunk 0.1.0 0.1.1 1.0.0 1.0.1 1.0.2 1.0.3 All 66 releases
notifier / includes / classes / class-notifier-settings.php

class-notifier-settings.php in WANotifier for Forms and Actions 2.5.3, at includes/classes/class-notifier-settings.php

591 lines 19.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Settings page class
4 *
5 * @package Wa_Notifier
6 */
7 class Notifier_Settings {
8
9 /**
10 * Init
11 */
12 public static function init() {
13 add_action( 'admin_menu', array( __CLASS__ , 'setup_admin_page') );
14 add_action( 'admin_init', array( __CLASS__ , 'save_settings_fields' ) );
15 add_action( 'admin_init', array( __CLASS__ , 'disconnect_notifier' ) );
16 add_action( 'wp_ajax_notifier_preview_btn_style', array(__CLASS__, 'preview_btn_style'));
17 }
18
19 /**
20 * Add settings page to men
21 */
22 public static function setup_admin_page () {
23 if (!Notifier::is_api_active()){
24 return;
25 }
26
27 add_submenu_page( NOTIFIER_NAME, 'Settings', 'Settings', 'manage_options', NOTIFIER_NAME . '-settings', array( __CLASS__, 'output' ) );
28 }
29
30 /**
31 * Output
32 */
33 public static function output() {
34 include_once NOTIFIER_PATH . '/views/admin-settings.php';
35 }
36
37 /**
38 * Get settings tabs
39 */
40 private static function get_settings_tabs() {
41 $tabs = array(
42 'general' => 'General',
43 'click_to_chat' => 'Click to Chat',
44 'api' => 'API',
45 'advanced' => 'Advanced'
46 );
47 return $tabs;
48 }
49
50 /**
51 * Check if on settings page
52 */
53 public static function is_settings_page() {
54 $current_page = isset($_GET['page']) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
55 return strpos($current_page, NOTIFIER_NAME . '-settings') !== false;
56 }
57
58 /**
59 * Settings fields
60 */
61 private static function settings_fields($tab) {
62 $api_key = get_option(NOTIFIER_PREFIX . 'api_key');
63 if(Notifier::is_api_active() && '' != $api_key) {
64 $disabled = true;
65 $description = 'You are successfully connected to WANotifier.com. <a href="?notifier_disconnect=1">Disconnect</a>.';
66 }
67 else{
68 $disabled = false;
69 $description = 'You are not connected to WANotifier.com yet. Please enter valid API key and save the settings. You can get your WANotifier.com API Key from <a href="https://app.wanotifier.com/settings/api/" target="_blank">here</a>.';
70 }
71 $settings = array();
72 switch ($tab) {
73 case 'general':
74 $settings = array(
75 array(
76 'title' => 'General',
77 'type' => 'title',
78 'description' => ''
79 ),
80 array(
81 'id' => 'default_country_code',
82 'title' => 'Default Country Code (Optional)',
83 'type' => 'text',
84 'placeholder' => 'Eg. +91',
85 'description' => 'Enter default country code that will be added to all recipient phone number fields before sending to WANotifier that do not start with a + sign.',
86 'default' => ''
87 ),
88 );
89
90 if ( class_exists( 'WooCommerce' ) ) {
91 $settings = array_merge( $settings, array(
92 array(
93 'title' => 'WooCommerce',
94 'type' => 'title',
95 'description' => ''
96 ),
97 array(
98 'id' => 'enable_opt_in_checkbox_checkout',
99 'title' => 'Opt-in Consent on Checkout',
100 'type' => 'checkbox',
101 'default' => '',
102 'label' => 'Enable',
103 'name' => 'enable_opt_in_checkbox_checkout',
104 'description' => 'Add an opt-in checkbox to WooCommerce checkout form. Once enabled, WhatsApp notification will be sent only to customers who opt-in during checkout.'
105 ),
106 array(
107 'id' => 'checkout_opt_in_checkbox_text',
108 'title' => 'Opt-in Checkbox Text',
109 'type' => 'textarea',
110 'placeholder' => 'Enter text for the opt-in checkbox',
111 'default' => 'Receive updates on WhatsApp',
112 'name' => 'checkout_opt_in_checkbox_text',
113 )
114 ) );
115 }
116
117 break;
118 case 'click_to_chat':
119 $settings = array(
120 array(
121 'title' => 'Click to Chat',
122 'description' => 'Show click to chat button on your website to let your visitors start WhatsApp chat with you.',
123 'type' => 'title',
124 ),
125 array(
126 'id' => 'ctc_enable',
127 'title' => 'Enable',
128 'type' => 'checkbox',
129 'default' => '',
130 'name' => 'ctc_enable',
131 ),
132 array(
133 'id' => 'ctc_whatsapp_number',
134 'title' => 'Whatsapp Number',
135 'type' => 'text',
136 'placeholder' => 'Enter your WhatsApp number',
137 'name' => 'ctc_whatsapp_number',
138 'description' => 'Enter your WhatsApp number with country code. Eg. +919876543210',
139 ),
140 array(
141 'id' => 'ctc_greeting_text',
142 'title' => 'Greeting Message',
143 'type' => 'text',
144 'name' => 'ctc_greeting_text',
145 'placeholder' => 'Enter your greeting message here',
146 'description' => 'This text will be added to user\'s WhatsApp chat text field when they click on the button.' ,
147 ),
148 array(
149 'id' => 'ctc_button_style',
150 'title' => 'Button Style',
151 'name' => 'ctc_button_style',
152 'class' => 'chat-button-style',
153 'type' => 'select',
154 'default' => '',
155 'options' => array(
156 'default' => 'Select button style',
157 'btn-style-1' => 'Style 1' ,
158 'btn-style-2' => 'Style 2',
159 'btn-style-3' => 'Style 3',
160 'btn-style-4' => 'Style 4',
161 'btn-custom-image' => 'Add your own image'
162 ),
163 'description' => 'Select a button style. Preview will be shown on bottom right of this screen. You can update button style by writing custom CSS in your theme.',
164 ),
165 array(
166 'id' => 'ctc_custom_button_image_url',
167 'title' => 'Button image url',
168 'type' => 'text',
169 'placeholder' => 'https://',
170 'name' => 'ctc_custom_button_image_url',
171 'description' => 'Enter button image url here.',
172 'tr_class' => 'notifier-chat-btn-image-url',
173 ),
174 );
175 break;
176 case 'api':
177 $settings = array(
178 array(
179 'title' => 'API Configuration',
180 'description' => '',
181 'type' => 'title',
182 ),
183 array(
184 'id' => 'api_key',
185 'title' => 'WANotifier.com API key',
186 'type' => 'text',
187 'placeholder' => 'Enter your WANotifier.com API key here',
188 'default' => '',
189 'description' => $description,
190 'disabled' => $disabled
191 ),
192 );
193 break;
194 case 'advanced':
195 $settings = array(
196 array(
197 'title' => 'Advanced Settings',
198 'description' => '',
199 'type' => 'title',
200 ),
201 array(
202 'id' => 'hidden_custom_keys',
203 'title' => 'Hidden custom meta keys',
204 'type' => 'checkbox',
205 'label' => 'Enable',
206 'description' => 'Enable hidden custom meta keys that start with underscores (e.g. _field_name) to be avaialbe in Data and Recipient Fields. Note that enabling this might impact your website performance slightly.',
207 'default' => ''
208 ),
209 array(
210 'id' => 'enable_async_triggers',
211 'title' => 'Async triggers',
212 'type' => 'checkbox',
213 'default' => '',
214 'label' => 'Enable',
215 'name' => 'enable_async_triggers',
216 'description' => 'Plugin slowing down checkout or form submission? Enable this option to send triggers asynchronously using Action Scheduler. Note that if you have a site with strong caching, this might not work as expected.' ,
217 ),
218 array(
219 'id' => 'enable_activity_log',
220 'title' => 'Activity log',
221 'type' => 'checkbox',
222 'default' => '',
223 'label' => 'Enable',
224 'name' => 'enable_activity_log',
225 'description' => 'Enabling this option will activate the activity logging feature. You can view activity logs <a href="/wp-admin/admin.php?page=notifier-tools">here</a>.' ,
226 ),
227 );
228 break;
229 }
230 $settings = apply_filters( 'notifier_$tab_settings_fields', $settings );
231 return $settings;
232 }
233
234 /**
235 * Generate HTML for displaying individual fields
236 */
237 public static function display_field( $field ) {
238 $field = wp_parse_args($field, array(
239 'title' => '',
240 'description' => '',
241 'label' => ''
242 ));
243
244 $html = '';
245
246 if (isset($field['id'])) {
247 $option_name = NOTIFIER_PREFIX . $field['id'];
248 $option = get_option( $option_name );
249 }
250
251 $data = isset($option) ? $option : '';
252 if ( isset( $field['default'] ) && empty($option) ) {
253 $data = $field['default'];
254 }
255
256 $custom_attributes = array();
257 if ( ! empty( $field['custom_attributes'] ) && is_array( $field['custom_attributes'] ) ) {
258 foreach ( $field['custom_attributes'] as $attribute => $value ) {
259 $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $value ) . '"';
260 }
261 }
262
263 if ( isset($field['required']) && $field['required'] ) {
264 $custom_attributes[] = 'required="required"';
265 }
266
267 if ( isset($field['disabled']) && $field['disabled'] ) {
268 $custom_attributes[] = 'disabled="disabled"';
269 }
270
271 if(isset($field['tr_class'])){
272 $tr_class = $field['tr_class'];
273 }else{
274 $tr_class = '';
275 }
276
277 $custom_attributes_string = implode( ' ', $custom_attributes );
278
279 if ( 'title' === $field['type']) {
280 $html .= '<tr class="'.esc_attr($tr_class).'"><th class="section-title" colspan="2"><h3>' . $field['title'] . '</h3>';
281 $html .= '<p class="description">' . $field['description'] . '</p></th></tr>';
282 } else {
283 $html .= '<tr class="'.esc_attr($tr_class).'">';
284 $html .= '<th>' . $field['title'] . '</th>';
285 $html .= '<td>';
286
287 switch ( $field['type'] ) {
288
289 case 'text':
290 case 'password':
291 case 'number':
292 $html .= '<input id="' . esc_attr( $option_name ) . '" type="' . $field['type'] . '" name="' . esc_attr( $option_name ) . '" placeholder="' . esc_attr( $field['placeholder'] ) . '" value="' . esc_attr($data) . '" '.$custom_attributes_string.'/>';
293 break;
294
295 case 'textarea':
296 $html .= '<textarea id="' . esc_attr( $option_name ) . '" rows="5" name="' . esc_attr( $option_name ) . '" placeholder="' . esc_attr( $field['placeholder'] ) . '" '.$custom_attributes_string.'>' . esc_textarea($data) . '</textarea><br/>';
297 break;
298
299 case 'checkbox':
300 $checked = '';
301 if ( $option && 'yes' == $option ) {
302 $checked = 'checked="checked"';
303 }
304 $html .= '<label><input id="' . esc_attr( $option_name ) . '" type="' . $field['type'] . '" name="' . esc_attr( $option_name ) . '" ' . $checked . ' '.$custom_attributes_string.' value="yes"/>' . $field['label'] . '</label>';
305 break;
306
307 case 'checkbox_multi':
308 foreach ( $field['options'] as $k => $v ) {
309 $checked = false;
310 if ( in_array( $k, $data ) ) {
311 $checked = true;
312 }
313 $html .= '<p><label for="' . esc_attr( $field['id'] . '_' . $k ) . '"><input type="checkbox" ' . checked( $checked, true, false ) . ' name="' . esc_attr( $option_name ) . '[]" value="' . esc_attr( $k ) . '" id="' . esc_attr( $option_name . '_' . $k ) . '" '.$custom_attributes_string.'/> ' . $v . '</label></p>';
314 }
315 break;
316
317 case 'radio':
318 foreach ( $field['options'] as $k => $v ) {
319 $checked = false;
320 if ( $k == $data ) {
321 $checked = true;
322 }
323 $html .= '<p><label for="' . esc_attr( $field['id'] . '_' . $k ) . '"><input type="radio" ' . checked( $checked, true, false ) . ' name="' . esc_attr( $option_name ) . '" value="' . esc_attr( $k ) . '" id="' . esc_attr( $option_name . '_' . $k ) . '" '.$custom_attributes_string.'/> ' . $v . '</label></p>';
324 }
325 break;
326
327 case 'select':
328 $html .= '<select name="' . esc_attr( $option_name ) . '" id="' . esc_attr( $field['id'] ) . '" '.$custom_attributes_string.'>';
329 foreach ( $field['options'] as $k => $v ) {
330 $selected = false;
331 if ( $k == $data ) {
332 $selected = true;
333 }
334 $html .= '<option ' . selected( $selected, true, false ) . ' value="' . esc_attr( $k ) . '">' . $v . '</option>';
335 }
336 $html .= '</select> ';
337 break;
338
339 case 'select_multi':
340 $html .= '<select name="' . esc_attr( $option_name ) . '[]" id="' . esc_attr( $field['id'] ) . '" multiple="multiple" '.$custom_attributes_string.'>';
341 foreach ( $field['options'] as $k => $v ) {
342 $selected = false;
343 if ( in_array( $k, $data ) ) {
344 $selected = true;
345 }
346 $html .= '<option ' . selected( $selected, true, false ) . ' value="' . esc_attr( $k ) . '" />' . $v . '</label> ';
347 }
348 $html .= '</select> ';
349 break;
350
351 case 'file':
352 $uploader_title = isset($field['uploader_title']) ? $field['uploader_title'] : 'Upload media';
353 $uploader_button_text = isset($field['uploader_button_text']) ? $field['uploader_button_text'] : 'Select';
354 $file_types = isset($field['uploader_supported_file_types']) ? $field['uploader_supported_file_types'] : array();
355
356 $image_thumb = '';
357 $video_url = '';
358 $show_image = 'hide';
359 $show_video = 'hide';
360
361 $html .= '<span class="notifier-media-preview">';
362 if ( '' != $data ) {
363 $file_type = $field['uploader_supported_file_types'];
364 switch ($file_type) {
365 case 'image':
366 case 'image/jpeg':
367 case 'image/png':
368 case 'application/pdf':
369 $image_thumb = wp_get_attachment_thumb_url( $data );
370 $show_image = '';
371 $show_video = 'hide';
372 break;
373
374 case 'video/mp4':
375 $video_url = wp_get_attachment_url( $data );
376 $show_image = 'hide';
377 $show_video = '';
378 break;
379
380 default:
381 $show_image = 'hide';
382 $show_video = 'hide';
383 }
384 }
385 $html .= '<img id="' . esc_attr( $option_name ) . '_preview_image" class="notifier-media-preview-item '. esc_attr($show_image) .'" src="' . esc_url($image_thumb) . '" />';
386 $html .= '<video id="' . esc_attr( $option_name ) . '_preview_video" class="notifier-media-preview-item '. esc_attr($show_video) .'" width="300" height="169" controls muted><source src="' . esc_url($video_url) . '" type="video/mp4"></video><br/>';
387 $html .= '</span>';
388
389 $html .= '<input id="' . esc_attr( $option_name ) . '_button" type="button" data-uploader_title="' . esc_attr($uploader_title) . '" data-uploader_button_text="' . esc_attr($uploader_button_text) . '" data-uploader_supported_file_types="' . esc_attr($file_types) . '" class="notifier-media-upload-button button" value="' . 'Upload' . '" /> ';
390 $html .= '<input id="' . esc_attr( $option_name ) . '_delete" type="button" class="notifier-media-delete-button button" value="' . 'Remove' . '" />';
391 $html .= '<input id="' . esc_attr( $option_name ) . '" class="notifier-media-attachment-id" type="hidden" name="' . esc_attr( $option_name ) . '" value="' . esc_attr( $data ) . '"/><br/>';
392 break;
393
394 case 'color':
395 ?>
396 <div class="color-picker" style="position:relative;">
397 <input type="text" name="<?php echo esc_attr( $option_name ); ?>" class="color" value="<?php echo esc_attr( $data ); ?>" />
398 <div style="position:absolute;background:#FFF;z-index:99;border-radius:100%;" class="colorpicker"></div>
399 </div>
400 <?php
401 break;
402
403 }
404
405 if ( '' != $field['description'] ) {
406 $html .= '<p class="description">' . wp_kses_post($field['description']) . '</p>';
407 }
408 }
409
410 //phpcs:ignore
411 echo $html;
412 }
413
414 /**
415 * Show the setting fields
416 */
417 public static function show_settings_fields ($tab) {
418 $setting_fields = self::settings_fields($tab);
419 echo "<table class='notifier-fields-table'>";
420 foreach ($setting_fields as $field) {
421 self::display_field( $field );
422 }
423 echo '</table>';
424 }
425
426 /**
427 * Save the settings.
428 *
429 * TODO - check fields other than text and textarea
430 */
431 public static function save_settings_fields() {
432 if ( ! self::is_settings_page() ) {
433 return;
434 }
435
436 if ( ! isset( $_POST['save'] ) ) {
437 return;
438 }
439
440 //phpcs:ignore
441 if ( empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], NOTIFIER_NAME . '-settings' ) ) {
442 return;
443 }
444
445 $tab = isset($_GET['tab']) ? sanitize_text_field(wp_unslash($_GET['tab'])) : 'general';
446
447 $settings_fields = self::settings_fields($tab);
448 $data = $_POST;
449 $update_options = array();
450
451 // Loop options and get values to save.
452 foreach ( $settings_fields as $option ) {
453 if ( ! isset( $option['id'] ) || ! isset( $option['type'] ) ) {
454 continue;
455 }
456
457 if ( isset( $option['disabled'] ) && $option['disabled'] ) {
458 continue;
459 }
460
461 $option_name = NOTIFIER_PREFIX . $option['id'];
462 $setting_name = '';
463 $raw_value = isset( $data[ $option_name ] ) ? wp_unslash( $data[ $option_name ] ) : null;
464
465 // Format the value based on option type.
466 switch ( $option['type'] ) {
467 case 'checkbox':
468 $value = '1' === $raw_value || 'yes' === $raw_value ? 'yes' : 'no';
469 break;
470 case 'textarea':
471 $value = wp_kses_post( trim( $raw_value ) );
472 break;
473 case 'select':
474 $allowed_values = empty( $option['options'] ) ? array() : array_map( 'strval', array_keys( $option['options'] ) );
475 if ( empty( $option['default'] ) && empty( $allowed_values ) ) {
476 $value = null;
477 break;
478 }
479 $default = ( empty( $option['default'] ) ? $allowed_values[0] : $option['default'] );
480 $value = in_array( $raw_value, $allowed_values, true ) ? $raw_value : $default;
481 break;
482 default:
483 $value = sanitize_text_field( $raw_value );
484 break;
485 }
486
487 // Check if option is an array and handle that differently to single values.
488 if ( $option_name && $setting_name ) {
489 if ( ! isset( $update_options[ $option_name ] ) ) {
490 $update_options[ $option_name ] = get_option( $option_name, array() );
491 }
492 if ( ! is_array( $update_options[ $option_name ] ) ) {
493 $update_options[ $option_name ] = array();
494 }
495 $update_options[ $option_name ][ $setting_name ] = $value;
496 } else {
497 $update_options[ $option_name ] = $value;
498 }
499 }
500
501 // Save all options in our array.
502 foreach ( $update_options as $name => $value ) {
503 if('notifier_api_key' == $name){
504 $current_api_key = get_option($name);
505 if($current_api_key == $value){
506 continue;
507 }
508
509 update_option( NOTIFIER_PREFIX . 'api_key', $value);
510 delete_option( NOTIFIER_PREFIX . 'enabled_triggers' );
511 delete_option( NOTIFIER_PREFIX . 'api_activated' );
512
513 $params = array(
514 'site_url' => site_url(),
515 'source' => 'wp'
516 );
517
518 $response = Notifier::send_api_request( 'verify_api', $params, 'POST' );
519
520 if($response->error){
521 $notices[] = array(
522 'message' => 'There was an error validating API key. Error: ' . $response->message,
523 'type' => 'error'
524 );
525 }
526 else{
527 update_option('notifier_api_activated', 'yes');
528 $notices[] = array(
529 'message' => 'API key validated and saved successfully. Your triggers have been reset. Please enable and save your triggers again from the <a href="'.admin_url('admin.php?page=notifier').'">WANotifier</a> page.',
530 'type' => 'success'
531 );
532 }
533 }
534 elseif('notifier_ctc_whatsapp_number' == $name && !notifier_validate_phone_number($value)){
535 $notices[] = array(
536 'message' => 'Please enter a valid WhatsApp phone number with country code.',
537 'type' => 'error'
538 );
539 }
540 else{
541 update_option( $name, $value, 'yes' );
542 }
543 }
544
545 if('advanced' == $tab){
546 delete_transient( '_notifier_custom_meta_keys' );
547 }
548
549 if(empty($notices)){
550 $notices[] = array(
551 'message' => 'Settings updated successfully.',
552 'type' => 'success'
553 );
554 }
555
556 new Notifier_Admin_Notices($notices);
557 }
558
559 /**
560 * Disconnect WANotifier.com connection
561 */
562 public static function disconnect_notifier(){
563 if(isset($_GET['notifier_disconnect']) && '1' == $_GET['notifier_disconnect']){
564 delete_option( NOTIFIER_PREFIX . 'api_key' );
565 delete_option( NOTIFIER_PREFIX . 'enabled_triggers' );
566 delete_option( NOTIFIER_PREFIX . 'api_activated' );
567 $notices[] = array(
568 'message' => 'Disconnected successfully. To re-connect with WANotifier.com, enter API key below and click on <b>Save and validate</b>.',
569 'type' => 'success'
570 );
571 new Notifier_Admin_Notices($notices, true);
572 wp_redirect(admin_url('admin.php?page=notifier'));
573 }
574 }
575
576 /**
577 * Show Chat Button Preview
578 */
579 public static function preview_btn_style(){
580 $btn_style = isset($_POST['btn_style']) ? sanitize_text_field($_POST['btn_style']) : '';
581
582 ob_start();
583 include_once NOTIFIER_PATH.'templates/buttons/'.$btn_style.'.php';
584 $btn_output = ob_get_clean();
585
586 wp_send_json( array(
587 'preview' => $btn_output
588 ) );
589 }
590 }
591