PluginProbe
WANotifier for Forms and Actions / 2.6.1
WANotifier for Forms and Actions v2.6.1
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.6.1, at includes/classes/class-notifier-settings.php

607 lines 20.1 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' => self::get_button_styles(),
156 '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.',
157 ),
158 array(
159 'id' => 'ctc_custom_button_image_url',
160 'title' => 'Button image url',
161 'type' => 'text',
162 'placeholder' => 'https://',
163 'name' => 'ctc_custom_button_image_url',
164 'description' => 'Enter button image url here.',
165 'tr_class' => 'notifier-chat-btn-image-url',
166 ),
167 );
168 break;
169 case 'api':
170 $settings = array(
171 array(
172 'title' => 'API Configuration',
173 'description' => '',
174 'type' => 'title',
175 ),
176 array(
177 'id' => 'api_key',
178 'title' => 'WANotifier.com API key',
179 'type' => 'text',
180 'placeholder' => 'Enter your WANotifier.com API key here',
181 'default' => '',
182 'description' => $description,
183 'disabled' => $disabled
184 ),
185 );
186 break;
187 case 'advanced':
188 $settings = array(
189 array(
190 'title' => 'Advanced Settings',
191 'description' => '',
192 'type' => 'title',
193 ),
194 array(
195 'id' => 'hidden_custom_keys',
196 'title' => 'Hidden custom meta keys',
197 'type' => 'checkbox',
198 'label' => 'Enable',
199 '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.',
200 'default' => ''
201 ),
202 array(
203 'id' => 'enable_async_triggers',
204 'title' => 'Async triggers',
205 'type' => 'checkbox',
206 'default' => '',
207 'label' => 'Enable',
208 'name' => 'enable_async_triggers',
209 '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.' ,
210 ),
211 array(
212 'id' => 'enable_activity_log',
213 'title' => 'Activity log',
214 'type' => 'checkbox',
215 'default' => '',
216 'label' => 'Enable',
217 'name' => 'enable_activity_log',
218 '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>.' ,
219 ),
220 );
221 break;
222 }
223 $settings = apply_filters( 'notifier_$tab_settings_fields', $settings );
224 return $settings;
225 }
226
227 /**
228 * Generate HTML for displaying individual fields
229 */
230 public static function display_field( $field ) {
231 $field = wp_parse_args($field, array(
232 'title' => '',
233 'description' => '',
234 'label' => ''
235 ));
236
237 $html = '';
238
239 if (isset($field['id'])) {
240 $option_name = NOTIFIER_PREFIX . $field['id'];
241 $option = get_option( $option_name );
242 }
243
244 $data = isset($option) ? $option : '';
245 if ( isset( $field['default'] ) && empty($option) ) {
246 $data = $field['default'];
247 }
248
249 $custom_attributes = array();
250 if ( ! empty( $field['custom_attributes'] ) && is_array( $field['custom_attributes'] ) ) {
251 foreach ( $field['custom_attributes'] as $attribute => $value ) {
252 $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $value ) . '"';
253 }
254 }
255
256 if ( isset($field['required']) && $field['required'] ) {
257 $custom_attributes[] = 'required="required"';
258 }
259
260 if ( isset($field['disabled']) && $field['disabled'] ) {
261 $custom_attributes[] = 'disabled="disabled"';
262 }
263
264 if(isset($field['tr_class'])){
265 $tr_class = $field['tr_class'];
266 }else{
267 $tr_class = '';
268 }
269
270 $custom_attributes_string = implode( ' ', $custom_attributes );
271
272 if ( 'title' === $field['type']) {
273 $html .= '<tr class="'.esc_attr($tr_class).'"><th class="section-title" colspan="2"><h3>' . $field['title'] . '</h3>';
274 $html .= '<p class="description">' . $field['description'] . '</p></th></tr>';
275 } else {
276 $html .= '<tr class="'.esc_attr($tr_class).'">';
277 $html .= '<th>' . $field['title'] . '</th>';
278 $html .= '<td>';
279
280 switch ( $field['type'] ) {
281
282 case 'text':
283 case 'password':
284 case 'number':
285 $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.'/>';
286 break;
287
288 case 'textarea':
289 $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/>';
290 break;
291
292 case 'checkbox':
293 $checked = '';
294 if ( $option && 'yes' == $option ) {
295 $checked = 'checked="checked"';
296 }
297 $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>';
298 break;
299
300 case 'checkbox_multi':
301 foreach ( $field['options'] as $k => $v ) {
302 $checked = false;
303 if ( in_array( $k, $data ) ) {
304 $checked = true;
305 }
306 $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>';
307 }
308 break;
309
310 case 'radio':
311 foreach ( $field['options'] as $k => $v ) {
312 $checked = false;
313 if ( $k == $data ) {
314 $checked = true;
315 }
316 $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>';
317 }
318 break;
319
320 case 'select':
321 $html .= '<select name="' . esc_attr( $option_name ) . '" id="' . esc_attr( $field['id'] ) . '" '.$custom_attributes_string.'>';
322 foreach ( $field['options'] as $k => $v ) {
323 $selected = false;
324 if ( $k == $data ) {
325 $selected = true;
326 }
327 $html .= '<option ' . selected( $selected, true, false ) . ' value="' . esc_attr( $k ) . '">' . $v . '</option>';
328 }
329 $html .= '</select> ';
330 break;
331
332 case 'select_multi':
333 $html .= '<select name="' . esc_attr( $option_name ) . '[]" id="' . esc_attr( $field['id'] ) . '" multiple="multiple" '.$custom_attributes_string.'>';
334 foreach ( $field['options'] as $k => $v ) {
335 $selected = false;
336 if ( in_array( $k, $data ) ) {
337 $selected = true;
338 }
339 $html .= '<option ' . selected( $selected, true, false ) . ' value="' . esc_attr( $k ) . '" />' . $v . '</label> ';
340 }
341 $html .= '</select> ';
342 break;
343
344 case 'file':
345 $uploader_title = isset($field['uploader_title']) ? $field['uploader_title'] : 'Upload media';
346 $uploader_button_text = isset($field['uploader_button_text']) ? $field['uploader_button_text'] : 'Select';
347 $file_types = isset($field['uploader_supported_file_types']) ? $field['uploader_supported_file_types'] : array();
348
349 $image_thumb = '';
350 $video_url = '';
351 $show_image = 'hide';
352 $show_video = 'hide';
353
354 $html .= '<span class="notifier-media-preview">';
355 if ( '' != $data ) {
356 $file_type = $field['uploader_supported_file_types'];
357 switch ($file_type) {
358 case 'image':
359 case 'image/jpeg':
360 case 'image/png':
361 case 'application/pdf':
362 $image_thumb = wp_get_attachment_thumb_url( $data );
363 $show_image = '';
364 $show_video = 'hide';
365 break;
366
367 case 'video/mp4':
368 $video_url = wp_get_attachment_url( $data );
369 $show_image = 'hide';
370 $show_video = '';
371 break;
372
373 default:
374 $show_image = 'hide';
375 $show_video = 'hide';
376 }
377 }
378 $html .= '<img id="' . esc_attr( $option_name ) . '_preview_image" class="notifier-media-preview-item '. esc_attr($show_image) .'" src="' . esc_url($image_thumb) . '" />';
379 $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/>';
380 $html .= '</span>';
381
382 $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' . '" /> ';
383 $html .= '<input id="' . esc_attr( $option_name ) . '_delete" type="button" class="notifier-media-delete-button button" value="' . 'Remove' . '" />';
384 $html .= '<input id="' . esc_attr( $option_name ) . '" class="notifier-media-attachment-id" type="hidden" name="' . esc_attr( $option_name ) . '" value="' . esc_attr( $data ) . '"/><br/>';
385 break;
386
387 case 'color':
388 ?>
389 <div class="color-picker" style="position:relative;">
390 <input type="text" name="<?php echo esc_attr( $option_name ); ?>" class="color" value="<?php echo esc_attr( $data ); ?>" />
391 <div style="position:absolute;background:#FFF;z-index:99;border-radius:100%;" class="colorpicker"></div>
392 </div>
393 <?php
394 break;
395
396 }
397
398 if ( '' != $field['description'] ) {
399 $html .= '<p class="description">' . wp_kses_post($field['description']) . '</p>';
400 }
401 }
402
403 //phpcs:ignore
404 echo $html;
405 }
406
407 /**
408 * Show the setting fields
409 */
410 public static function show_settings_fields ($tab) {
411 $setting_fields = self::settings_fields($tab);
412 echo "<table class='notifier-fields-table'>";
413 foreach ($setting_fields as $field) {
414 self::display_field( $field );
415 }
416 echo '</table>';
417 }
418
419 /**
420 * Save the settings.
421 *
422 * TODO - check fields other than text and textarea
423 */
424 public static function save_settings_fields() {
425 if ( ! self::is_settings_page() ) {
426 return;
427 }
428
429 if ( ! isset( $_POST['save'] ) ) {
430 return;
431 }
432
433 //phpcs:ignore
434 if ( empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], NOTIFIER_NAME . '-settings' ) ) {
435 return;
436 }
437
438 $tab = isset($_GET['tab']) ? sanitize_text_field(wp_unslash($_GET['tab'])) : 'general';
439
440 $settings_fields = self::settings_fields($tab);
441 $data = $_POST;
442 $update_options = array();
443
444 // Loop options and get values to save.
445 foreach ( $settings_fields as $option ) {
446 if ( ! isset( $option['id'] ) || ! isset( $option['type'] ) ) {
447 continue;
448 }
449
450 if ( isset( $option['disabled'] ) && $option['disabled'] ) {
451 continue;
452 }
453
454 $option_name = NOTIFIER_PREFIX . $option['id'];
455 $setting_name = '';
456 $raw_value = isset( $data[ $option_name ] ) ? wp_unslash( $data[ $option_name ] ) : null;
457
458 // Format the value based on option type.
459 switch ( $option['type'] ) {
460 case 'checkbox':
461 $value = '1' === $raw_value || 'yes' === $raw_value ? 'yes' : 'no';
462 break;
463 case 'textarea':
464 $value = wp_kses_post( trim( $raw_value ) );
465 break;
466 case 'select':
467 $allowed_values = empty( $option['options'] ) ? array() : array_map( 'strval', array_keys( $option['options'] ) );
468 if ( empty( $option['default'] ) && empty( $allowed_values ) ) {
469 $value = null;
470 break;
471 }
472 $default = ( empty( $option['default'] ) ? $allowed_values[0] : $option['default'] );
473 $value = in_array( $raw_value, $allowed_values, true ) ? $raw_value : $default;
474 break;
475 default:
476 $value = sanitize_text_field( $raw_value );
477 break;
478 }
479
480 // Check if option is an array and handle that differently to single values.
481 if ( $option_name && $setting_name ) {
482 if ( ! isset( $update_options[ $option_name ] ) ) {
483 $update_options[ $option_name ] = get_option( $option_name, array() );
484 }
485 if ( ! is_array( $update_options[ $option_name ] ) ) {
486 $update_options[ $option_name ] = array();
487 }
488 $update_options[ $option_name ][ $setting_name ] = $value;
489 } else {
490 $update_options[ $option_name ] = $value;
491 }
492 }
493
494 // Save all options in our array.
495 foreach ( $update_options as $name => $value ) {
496 if('notifier_api_key' == $name){
497 $current_api_key = get_option($name);
498 if($current_api_key == $value){
499 continue;
500 }
501
502 update_option( NOTIFIER_PREFIX . 'api_key', $value);
503 delete_option( NOTIFIER_PREFIX . 'enabled_triggers' );
504 delete_option( NOTIFIER_PREFIX . 'api_activated' );
505
506 $params = array(
507 'site_url' => site_url(),
508 'source' => 'wp'
509 );
510
511 $response = Notifier::send_api_request( 'verify_api', $params, 'POST' );
512
513 if($response->error){
514 $notices[] = array(
515 'message' => 'There was an error validating API key. Error: ' . $response->message,
516 'type' => 'error'
517 );
518 }
519 else{
520 update_option('notifier_api_activated', 'yes');
521 $notices[] = array(
522 '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.',
523 'type' => 'success'
524 );
525 }
526 }
527 elseif('notifier_ctc_whatsapp_number' == $name && !notifier_validate_phone_number($value)){
528 $notices[] = array(
529 'message' => 'Please enter a valid WhatsApp phone number with country code.',
530 'type' => 'error'
531 );
532 }
533 else{
534 update_option( $name, $value, 'yes' );
535 }
536 }
537
538 if('advanced' == $tab){
539 delete_transient( '_notifier_custom_meta_keys' );
540 }
541
542 if(empty($notices)){
543 $notices[] = array(
544 'message' => 'Settings updated successfully.',
545 'type' => 'success'
546 );
547 }
548
549 new Notifier_Admin_Notices($notices);
550 }
551
552 /**
553 * Disconnect WANotifier.com connection
554 */
555 public static function disconnect_notifier(){
556 if(isset($_GET['notifier_disconnect']) && '1' == $_GET['notifier_disconnect']){
557 delete_option( NOTIFIER_PREFIX . 'api_key' );
558 delete_option( NOTIFIER_PREFIX . 'enabled_triggers' );
559 delete_option( NOTIFIER_PREFIX . 'api_activated' );
560 $notices[] = array(
561 'message' => 'Disconnected successfully. To re-connect with WANotifier.com, enter API key below and click on <b>Save and validate</b>.',
562 'type' => 'success'
563 );
564 new Notifier_Admin_Notices($notices, true);
565 wp_redirect(admin_url('admin.php?page=notifier'));
566 }
567 }
568
569 /**
570 * Get button styles
571 */
572 public static function get_button_styles(){
573 return array(
574 'default' => 'Select button style',
575 'btn-style-1' => 'Style 1' ,
576 'btn-style-2' => 'Style 2',
577 'btn-style-3' => 'Style 3',
578 'btn-style-4' => 'Style 4',
579 'btn-custom-image' => 'Add your own image'
580 );
581 }
582
583 /**
584 * Show Chat Button Preview
585 */
586 public static function preview_btn_style(){
587 $btn_style = isset($_POST['btn_style']) ? sanitize_text_field($_POST['btn_style']) : '';
588
589 $button_styles = self::get_button_styles();
590 $button_style_keys = array_keys($button_styles);
591
592 if(! in_array($btn_style, $button_style_keys)){
593 wp_send_json( array(
594 'preview' => 'Invalid request'
595 ) );
596 }
597
598 ob_start();
599 include_once NOTIFIER_PATH.'templates/buttons/'.$btn_style.'.php';
600 $btn_output = ob_get_clean();
601
602 wp_send_json( array(
603 'preview' => $btn_output
604 ) );
605 }
606 }
607