PluginProbe
Awesome Support – WordPress HelpDesk & Support Plugin / trunk
Awesome Support – WordPress HelpDesk & Support Plugin vtrunk
6.4.0 trunk 3.0.0 3.0.1 3.1.0 3.1.1 3.1.10 3.1.11 3.1.12 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 All 95 releases
awesome-support / includes / admin / functions-tools.php

functions-tools.php in Awesome Support – WordPress HelpDesk & Support Plugin trunk, at includes/admin/functions-tools.php

798 lines 19.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 add_action( 'admin_init', 'wpas_system_tools', 10, 0 );
4 function wpas_system_tools() {
5
6 if ( ! isset( $_GET['tool'] ) || ! isset( $_GET['_nonce'] ) ) {
7 return false;
8 }
9
10 if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_nonce'] ) ), 'system_tool' ) ) {
11 return false;
12 }
13
14 switch ( sanitize_text_field( wp_unslash( $_GET['tool'] ) ) ) {
15
16 /* Clear all tickets metas */
17 case 'tickets_metas';
18 wpas_clear_tickets_metas();
19 break;
20
21 case 'agents_metas':
22 wpas_clear_agents_metas();
23 break;
24
25 case 'clear_taxonomies':
26 wpas_clear_taxonomies();
27 break;
28
29 case 'resync_products':
30 wpas_delete_synced_products( true );
31 break;
32
33 case 'delete_products':
34 wpas_delete_synced_products();
35 break;
36
37 case 'delete_unused_terms':
38 wpas_delete_unused_terms();
39 break;
40
41 case 'ticket_attachments':
42 wpas_delete_unclaimed_attachments();
43 break;
44
45 case 'update_last_reply':
46 wpas_update_last_reply();
47 break;
48
49 case 'reset_replies_count':
50 wpas_reset_replies_count();
51 break;
52
53 case 'reset_channels':
54 wpas_reset_channel_terms();
55 break;
56
57 case 'reset_ticket_types':
58 wpas_reset_ticket_types();
59 break;
60
61 case 'reset_time_fields':
62 wpas_reset_time_fields_to_zero();
63 break;
64
65 case 'rerun_334_to_400_conversion':
66 wpas_upgrade_406();
67 break ;
68
69 case 'rerun_400_to_440_conversion':
70 wpas_upgrade_440();
71 break;
72
73 case 'rerun_400_to_500_conversion':
74 wpas_upgrade_511();
75 wpas_upgrade_520();
76 break;
77
78 case 'rerun_580_to_590_conversion':
79 wpas_upgrade_590();
80 break;
81
82 case 'install_blue_blocks_email_template':
83 wpas_install_email_template( 'blue_blocks' );
84 break;
85
86 case 'install_blue_blocks_ss_email_template':
87 wpas_install_email_template( 'blue_blocks-ss' );
88 break;
89
90 case 'install_elegant_email_template':
91 wpas_install_email_template( 'elegant' );
92 break;
93
94 case 'install_elegant_ss_email_template':
95 wpas_install_email_template( 'elegant-ss' );
96 break;
97
98 case 'install_simple_email_template':
99 wpas_install_email_template( 'simple' );
100 break;
101
102 case 'install_default_email_template':
103 wpas_install_email_template( 'default' );
104 break;
105
106 case 'install_debug_email_template':
107 wpas_install_email_template( 'debug' );
108 break;
109
110 case 'mark_all_auto_del_attchmnts':
111 case 'remove_mark_all_auto_del_attchmnts':
112 case 'mark_open_auto_del_attchmnts':
113 case 'remove_mark_open_auto_del_attchmnts':
114 case 'mark_closed_auto_del_attchmnts':
115 case 'remove_mark_closed_auto_del_attchmnts':
116
117 $act = sanitize_text_field( wp_unslash( $_GET['tool'] ) );
118 $act_parts = explode( '_', $act );
119 $flag_added = 'remove' === substr( $act, 0, 6 ) ? false : true;
120 $flag_ticket_type = $flag_added ? $act_parts[1] : $act_parts[2];
121
122 WPAS_File_Upload::mark_tickets_auto_delete_attachments( $flag_ticket_type, $flag_added );
123
124 break;
125 }
126
127 do_action( 'execute_additional_tools', sanitize_text_field( wp_unslash( $_GET['tool'] ) ) );
128
129 /* Redirect in "read-only" mode */
130 $url = add_query_arg( array(
131 'post_type' => 'ticket',
132 'page' => 'wpas-status',
133 'tab' => 'tools',
134 'done' => sanitize_text_field( wp_unslash( $_GET['tool'] ) )
135 ), admin_url( 'edit.php' )
136 );
137
138 wp_redirect( wp_sanitize_redirect( $url ) );
139 exit;
140
141 }
142
143 /**
144 * Require this file here so that we don't duplicate the upgrade functions. Its used by one of the case statements above to
145 * run the 3.3.4 to 4.0.0 upgrade process on demand.
146 * We can remove it or find a better way to handle it later (after a couple of 4.x releases).
147 */
148 require_once( WPAS_PATH . 'includes/admin/upgrade/functions-upgrade.php' );
149
150 /**
151 * Add default channels.
152 *
153 * @return boolean
154 *
155 */
156 function wpas_reset_channel_terms() {
157 return wpas_add_default_channel_terms(true);
158 }
159
160 /**
161 * Add default ticket types.
162 *
163 * @return boolean
164 *
165 */
166 function wpas_reset_ticket_types() {
167 return wpas_add_default_ticket_types(true);
168 }
169
170 /**
171 * Reset replies count for all tickets.
172 *
173 * Gets all the existing tickets from the system
174 * and reset their replies count one by one.
175 *
176 * @return boolean
177 *
178 */
179 function wpas_reset_replies_count() {
180 $args = array(
181 'post_type' => 'ticket',
182 'post_status' => 'any',
183 'posts_per_page' => -1,
184 'no_found_rows' => true,
185 'cache_results' => false,
186 'update_post_term_cache' => false,
187 'update_post_meta_cache' => false,
188 );
189
190 $query = new WP_Query( $args );
191 $reset = false;
192
193 if ( 0 == $query->post_count ) {
194 return false;
195 }
196
197 foreach( $query->posts as $post ) {
198 if ( wpas_count_replies( $post->ID ) && false === $reset ) {
199 $reset = true;
200 }
201 }
202
203 return $reset;
204 }
205
206 /**
207 * Clear the activity meta for a given ticket.
208 *
209 * Deletes the activity meta transient from the database
210 * for one given ticket.
211 *
212 * @since 3.0.0
213 * @param integer $ticket_id ID of the ticket to clear the meta from
214 * @return boolean True if meta was cleared, false otherwise
215 *
216 */
217 function wpas_clear_ticket_activity_meta( $ticket_id ) {
218 return delete_transient( "wpas_activity_meta_post_$ticket_id" );
219 }
220
221 /**
222 * Clear all tickets metas.
223 *
224 * Gets all the existing tickets from the system
225 * and clear their metas one by one.
226 *
227 * @since 3.0.0
228 * @return True if some metas were cleared, false otherwise
229 *
230 */
231 function wpas_clear_tickets_metas() {
232
233 $args = array(
234 'post_type' => 'ticket',
235 'post_status' => 'any',
236 'posts_per_page' => -1,
237 'no_found_rows' => true,
238 'cache_results' => false,
239 'update_post_term_cache' => false,
240 'update_post_meta_cache' => false,
241 );
242
243 $query = new WP_Query( $args );
244 $cleared = false;
245
246 if ( 0 == $query->post_count ) {
247 return false;
248 }
249
250 foreach( $query->posts as $post ) {
251 if ( wpas_clear_ticket_activity_meta( $post->ID ) && false === $cleared ) {
252 $cleared = true;
253 }
254 }
255
256 return $cleared;
257
258 }
259
260 /**
261 * Clear all terms for a given taxonomy.
262 *
263 * @since 3.0.0
264 * @param string $taxonomy Taxonomy name
265 * @return boolean True if terms were deleted, false otherwise
266 */
267 function wpas_clear_taxonomy( $taxonomy ) {
268
269 $terms = get_terms( $taxonomy, array( 'hide_empty' => false ) );
270 $delete = false;
271
272 if ( is_wp_error( $terms ) || empty( $terms ) ) {
273 return false;
274 }
275
276 foreach ( $terms as $term ) {
277 if ( wp_delete_term( $term->term_id, $taxonomy ) && false === $delete ) {
278 $delete = true;
279 }
280 }
281
282 return $delete;
283
284 }
285
286 /**
287 * Clear all custom taxonomies terms.
288 *
289 * @since 3.0.0
290 * @return boolean True if terms were deleted, false otherwise
291 */
292 function wpas_clear_taxonomies() {
293
294 $taxonomies = (array) WPAS()->custom_fields->get_custom_fields();
295 $deleted = false;
296
297 if ( empty( $taxonomies ) ) {
298 return false;
299 }
300
301 foreach ( $taxonomies as $taxonomy ) {
302
303 if ( 'taxonomy' !== $taxonomy['args']['callback'] ) {
304 continue;
305 }
306
307 if ( wpas_clear_taxonomy( $taxonomy['name'] ) && false === $deleted ) {
308 $deleted = true;
309 }
310
311 }
312
313 return $deleted;
314
315 }
316
317 /**
318 * Delete the synchronized e-commerce products.
319 *
320 * The function goes through all the available products
321 * and deletes the associated synchronized terms along with
322 * the term taxonomy and term relationship. It also deleted
323 * the post metas where the taxonomy ID is stored.
324 *
325 * @param $resync boolean Whether or not to re-synchronize the products after deleting them
326 *
327 * @return boolean True if the operation completed, false otherwise
328 * @since 3.1.7
329 */
330 function wpas_delete_synced_products( $resync = false ) {
331
332 $post_type = isset($_GET['pt']) ? sanitize_text_field( wp_unslash( $_GET['pt'] ) ) : null;
333
334 if ( empty( $post_type ) ) {
335 return false;
336 }
337
338 $sync = new WPAS_Product_Sync( '', 'product' );
339 $posts = new WP_Query( array( 'post_type' => $post_type, 'posts_per_page' => -1, 'post_status' => 'any', 'no_found_rows' => true ) );
340 $sync->set_post_type( $post_type );
341
342 $product_terms = get_terms([
343 'taxonomy' => 'product',
344 'hide_empty' => false,
345 ]);
346
347 if ( ! empty( $posts->posts ) ) {
348
349 foreach((array)$product_terms as $product_term){
350
351 $unsync_term = false;
352
353 /* Does the product taxonmy exist as a product post? */
354 /* Note even sure this section is needed - it seems */
355 /* to be unnecessary given what comes in the next */
356 /* section. */
357 foreach ( $posts->posts as $post ) {
358 if($product_term->name == $post->ID){
359 $unsync_term = true;
360 }
361 }
362
363 /* Product taxonomy item exists in the product posts so process this section */
364 if($unsync_term == true){
365
366 /* Is the product term on a ticket? Only if its not used on a ticket should we remove it from the product taxonomy */
367 if( wpas_product_has_tickets($product_term->term_id) === false ){
368
369 wp_delete_term( (int) $product_term->term_id, 'product' );
370
371 }
372 }
373
374 }
375
376 }
377
378 /* Now let's make sure we don't have some orphan post metas left */
379 global $wpdb;
380 $sql = "SELECT * FROM {$wpdb->postmeta} WHERE meta_key = '%s'";
381 $metas = $wpdb->get_results( $wpdb->prepare( "$sql", '_wpas_product_term' ) );
382 if ( ! empty( $metas ) ) {
383 foreach ( $metas as $meta ) {
384 $raw_value = $meta->meta_value;
385 if ( is_serialized( $raw_value ) ) {
386 $value = @unserialize( $raw_value, ['allowed_classes' => false] );
387 if ( is_array( $value ) && isset( $value['term_id'] ) ) {
388 $term = get_term_by( 'id', (int) $value['term_id'], 'product' );
389 if ( empty( $term ) ) {
390 delete_post_meta( $meta->post_id, '_wpas_product_term' );
391 }
392 }
393 }
394 }
395 }
396 if ( true === $resync ) {
397 /* Delete the initial synchronization marker so that it's done again */
398 // delete_option( "wpas_sync_$post_type" );
399 update_option( "wpas_sync_$post_type", 0 );
400 /* Synchronize */
401 $sync->run_initial_sync();
402 }
403 return true;
404 }
405
406 /**
407 * Check product term has any ticket
408 *
409 * @since 4.0.0
410 * @return boolean */
411 function wpas_product_has_tickets($term_id) {
412 $args = array(
413 'post_type' => 'ticket',
414 'status' => 'publish',
415 'tax_query' => array(
416 array(
417 'taxonomy' => 'product',
418 'field' => 'id',
419 'terms' => $term_id
420 )
421 )
422 );
423 $term_query = new WP_Query( $args );
424 $term_posts_count = $term_query->found_posts;
425
426 if( $term_posts_count > 0 ){
427 return true;
428 }else{
429 return false;
430 }
431 }
432
433 /**
434 * @return array
435 */
436 function wpas_delete_unused_terms() {
437
438 $statistics = array(
439 'count' => 0,
440 'deleted' => 0,
441 'used' => 0,
442 );
443
444 $taxonomy = get_taxonomy('product');
445 $terms = get_terms( 'product', array( 'hide_empty' => false ) );
446
447 $statistics['count'] = count($terms);
448
449 foreach( $terms as $term ) {
450
451 $items = new WP_Query( array(
452 'post_type' => 'ticket',
453 'numberposts' => -1,
454 'no_found_rows' => true,
455 'tax_query' => array(
456 array(
457 'taxonomy' => 'product',
458 'terms' => array($term->term_id),
459 'field' => 'term_id',
460 'operator' => 'IN'
461 )
462 )
463 ) );
464
465 if( 0 === count( $items->posts ) ) {
466 wp_delete_term($term->term_id, $taxonomy->name);
467 $statistics['deleted'] += 1;
468 }
469
470 wp_update_term_count_now( array($term->term_id), $taxonomy->name );
471
472 }
473
474 $statistics['used'] = count(get_terms( 'product', array( 'hide_empty' => false ) ));
475
476 return $statistics;
477 }
478
479 /**
480 * Clear the agents metas that can be
481 *
482 * @since 3.2
483 * @return void
484 */
485 function wpas_clear_agents_metas() {
486
487 $agents = wpas_get_users( array( 'cap' => 'edit_ticket' ) );
488
489 foreach ( $agents as $user ) {
490 delete_user_option( $user->ID, 'wpas_open_tickets' ); // Delete the open tickets count
491 delete_user_option( $user->ID, 'wpas_open_tickets',true ); // Delete it as well at the global level just in case it exists there (which it shouldn't!)
492 }
493
494 }
495
496 /**
497 * Checks for templates overrides.
498 *
499 * Check if any of the plugin templates is being
500 * overwritten by the child theme or the theme.
501 *
502 * @since 3.0.0
503 * @param string $dir Directory to check
504 * @return array Array of overridden templates
505 */
506 function wpas_check_templates_override( $dir ) {
507
508 $templates = array(
509 'details.php',
510 'list.php',
511 'registration.php',
512 'submission.php'
513 );
514
515 $overrides = array();
516
517 if ( is_dir( $dir ) ) {
518
519 $files = scandir( $dir );
520
521 if ( empty( $files ) ) {
522 return array();
523 }
524
525 foreach ( $files as $key => $file ) {
526 if ( !in_array( $file, $templates ) ) {
527 continue;
528 }
529
530 array_push( $overrides, $file );
531 }
532
533 }
534
535 return $overrides;
536
537 }
538
539 /**
540 * Update the last reply date postmeta for all tickets.
541 *
542 * @return boolean
543 *
544 */
545 function wpas_update_last_reply() {
546
547 global $wpdb;
548
549 $sql = "SELECT "
550 . "wpas_ticket.ID AS ticket_id, "
551 . "wpas_reply.ID AS reply_id, "
552 . "wpas_replies.latest_reply, "
553 . "wpas_replies.latest_reply_gmt, "
554 . "wpas_replies.post_author, "
555 . "wpas_ticket.post_author = wpas_reply.post_author AS client_replied_last "
556 . "FROM "
557 . "{$wpdb->posts} AS wpas_ticket "
558 . "LEFT OUTER JOIN {$wpdb->posts} AS wpas_reply ON wpas_ticket.ID = wpas_reply.post_parent "
559 . "LEFT OUTER JOIN ( "
560 . "SELECT "
561 . "post_parent AS ticket_id, "
562 . "post_author AS post_author, "
563 . "post_date_gmt AS latest_reply_gmt, "
564 . "MAX(post_date) AS latest_reply "
565 . "FROM "
566 . "{$wpdb->posts} "
567 . "WHERE "
568 . "post_type = 'ticket_reply' "
569 . "GROUP BY "
570 . "post_parent "
571 . ") wpas_replies ON wpas_replies.ticket_id = wpas_reply.post_parent AND wpas_replies.latest_reply = wpas_reply.post_date "
572 . "WHERE "
573 . "wpas_replies.latest_reply IS NOT NULL "
574 . "AND wpas_reply.post_type = 'ticket_reply' "
575 . "ORDER BY "
576 . "wpas_replies.latest_reply ASC";
577
578 $test = wpas_get_tickets('any');
579
580 /* Set some defaults or all tickets */
581 foreach ( $test as $ticket) {
582 update_post_meta( $ticket->ID, '_wpas_last_reply_date', $ticket->post_date );
583 update_post_meta( $ticket->ID, '_wpas_last_reply_date_gmt', $ticket->post_date_gmt );
584 update_post_meta( $ticket->ID, '_wpas_is_waiting_client_reply', 0 );
585 }
586
587 $replies = $wpdb->get_results( "$sql" );
588
589 foreach ( $replies as $reply_post ) {
590
591 if( null !== get_post( $reply_post->ticket_id) ) {
592
593 /* . */
594 update_post_meta( $reply_post->ticket_id, '_wpas_last_reply_date', $reply_post->latest_reply );
595 update_post_meta( $reply_post->ticket_id, '_wpas_last_reply_date_gmt', $reply_post->latest_reply_gmt );
596 update_post_meta( $reply_post->ticket_id, '_wpas_is_waiting_client_reply', (int)$reply_post->client_replied_last );
597
598 }
599 }
600
601 }
602
603 /**
604 * Delete unclaimed attachments
605 *
606 * @since 3.3.4
607 * @return void
608 */
609 function wpas_delete_unclaimed_attachments() {
610
611 $upload = wp_get_upload_dir();
612 $attachments_root = trailingslashit( $upload['basedir'] ) . 'awesome-support/';
613 $ticket_folders = glob( $attachments_root . 'ticket_*' );
614
615 foreach ( $ticket_folders as $folder ) {
616
617 $basename = basename( $folder );
618
619 if ( ( $x_pos = strpos( $basename, '_' ) ) !== false ) {
620 $ticket_id = substr( $basename, $x_pos + 1 );
621 $post = get_post( absint( $ticket_id ) );
622
623 if ( empty( $post ) ) {
624
625 $it = new RecursiveDirectoryIterator( $attachments_root . $basename, RecursiveDirectoryIterator::SKIP_DOTS );
626 $files = new RecursiveIteratorIterator( $it, RecursiveIteratorIterator::CHILD_FIRST );
627
628 foreach ( $files as $file ) {
629 if ( $file->isDir() ) {
630 wp_rmdir( $file->getRealPath() );
631 } else {
632 unlink( $file->getRealPath() );
633 }
634 }
635 wp_rmdir( $attachments_root . $basename );
636 }
637 }
638 }
639
640 return;
641
642 }
643
644
645 /**
646 * wp_rmdir
647 *
648 * Delete directory using wp functions
649 * @param mixed $directory_path
650 * @return void
651 */
652 function wp_rmdir($directory_path){
653 // Ensure WP_Filesystem is available and initialized
654 if ( !function_exists('get_filesystem_method') ) {
655 require_once ABSPATH . 'wp-admin/includes/file.php';
656 }
657
658 // Initialize WP_Filesystem
659 global $wp_filesystem;
660 if ( empty($wp_filesystem) ) {
661 WP_Filesystem();
662 }
663
664 // Check if the directory exists
665 if ( $wp_filesystem->is_dir($directory_path) ) {
666 // Remove the directory
667 if ( $wp_filesystem->rmdir($directory_path, true) ) {
668 // Directory removed successfully
669 echo "Directory removed successfully.";
670 } else {
671 // Handle error if directory could not be removed
672 echo "Failed to remove directory.";
673 }
674 } else {
675 // Handle the case where the directory does not exist
676 echo "Directory does not exist.";
677 }
678 }
679
680
681 /**
682 * Reset all time tracking fields to zero
683 *
684 * @since 3.6.0
685 * @return void
686 */
687
688 function wpas_reset_time_fields_to_zero() {
689
690 $args = array(
691 'post_type' => 'ticket',
692 'post_status' => 'any',
693 'posts_per_page' => -1,
694 'no_found_rows' => true,
695 'cache_results' => false,
696 'update_post_term_cache' => false,
697 'update_post_meta_cache' => false,
698 );
699
700 $query = new WP_Query( $args );
701 $reset = true;
702
703 if ( 0 == $query->post_count ) {
704 return false;
705 }
706
707 foreach( $query->posts as $post ) {
708 update_post_meta( $post->ID, '_wpas_ttl_calculated_time_spent_on_ticket', 0 );
709 update_post_meta( $post->ID, '_wpas_ttl_adjustments_to_time_spent_on_ticket', 0 );
710 update_post_meta( $post->ID, '_wpas_final_time_spent_on_ticket', 0 );
711 }
712
713 return $reset;
714 }
715
716 function wpas_install_email_template( $template, $overwrite = true ) {
717
718 $template_root_path = ''; // the file path to the folder containing the template set
719
720 // Set the variable to the template set path based on which template we need
721 switch ( $template ) {
722
723 case 'blue_blocks' :
724 $template_root_path = WPAS_URL . 'assets/admin/email-templates/blue-block/';
725 break;
726
727 case 'blue_blocks-ss' :
728 $template_root_path = WPAS_URL . 'assets/admin/email-templates/blue-block-with-satisfaction-surveys/';
729 break;
730
731 case 'elegant' :
732 $template_root_path = WPAS_URL . 'assets/admin/email-templates/elegant/';
733 break;
734
735 case 'elegant-ss' :
736 $template_root_path = WPAS_URL . 'assets/admin/email-templates/elegant-with-with-satisfaction-surveys/';
737 break;
738
739 case 'simple' :
740 $template_root_path = WPAS_URL . 'assets/admin/email-templates/simple/';
741 break;
742
743 case 'default' :
744 $template_root_path = WPAS_URL . 'assets/admin/email-templates/default/';
745 break;
746
747 case 'debug' :
748 $template_root_path = WPAS_URL . 'assets/admin/email-templates/debug/';
749 break;
750 }
751
752 // Allow other add-ons to set this path
753 $template_root_path = apply_filters( 'wpas_email_template_root_path', $template_root_path ) ;
754
755 // Create array with option names and corresponding file names
756 $template_files['content_confirmation'] = $template_root_path . 'New-Ticket-Confirmation-Going-To-End-User.html';
757 $template_files['content_assignment'] = $template_root_path . 'New-Ticket-Assigned-To-Agent.html';
758 $template_files['content_reply_agent'] = $template_root_path . 'Agent-Reply-Going-To-End-User.html';
759
760 $template_files['content_reply_client'] = $template_root_path . 'New-Reply-From-Client-Going-To-Agent.html';
761 $template_files['content_closed'] = $template_root_path . 'Ticket-Closed-By-Agent.html';
762 $template_files['content_closed_client'] = $template_root_path . 'Ticket-Closed-By-Client.html';
763
764 // Allow other add-ons to update this array
765 $template_files = apply_filters( 'wpas_email_template_map_to_files', $template_files );
766
767 // Read the template files into the appropriate option based on the key-fiile mapping array above.
768 foreach ( $template_files as $key => $template_file ) {
769
770 // Validate the URL
771 if (wp_http_validate_url( esc_url_raw( $template_file ) ) ) {
772 // Ensure the HTTP API functions are available
773 if ( !function_exists('wp_remote_get') ) {
774 require_once ABSPATH . WPINC . '/http.php';
775 }
776
777 $template_contents = wp_remote_get( $template_file );
778
779 if ( !is_wp_error( $template_contents ) ) {
780
781 $body_template_contents = wp_remote_retrieve_body( $template_contents );
782
783 if ( ! empty( $body_template_contents ) ) {
784
785 // Is there any existing value in the option?
786 $existing_contents = wpas_get_option( $key );
787
788 if ( ! empty( $existing_contents ) && ! $overwrite ) {
789 // do not overwrite existing contents
790 continue ;
791 }
792 wpas_update_option( $key, $body_template_contents, true ) ;
793 }
794 }
795 }
796 }
797 }
798