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

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