Changeset 3481786
- Timestamp:
- 03/13/2026 09:19:38 AM (2 weeks ago)
- Location:
- appointment-and-booking-for-gravity-forms/trunk
- Files:
-
- 1 added
- 19 edited
-
appointment-and-booking-for-gravity-forms.php (modified) (2 diffs)
-
assets/admin/css/apbgf-admin-style.css (modified) (1 diff)
-
assets/admin/css/apbgf-posttype-style.css (modified) (2 diffs)
-
assets/admin/js/apbgf-admin-script.js (modified) (5 diffs)
-
assets/images/ProPopup.svg (added)
-
gravity-form-booking-main.php (modified) (15 diffs)
-
includes/classes/class-apbgf-admin.php (modified) (4 diffs)
-
includes/classes/class-apbgf-calendar.php (modified) (3 diffs)
-
includes/classes/class-apbgf-email.php (modified) (5 diffs)
-
includes/classes/class-apbgf-location.php (modified) (4 diffs)
-
includes/classes/class-apbgf-service.php (modified) (1 diff)
-
includes/classes/class-apbgf-staff.php (modified) (3 diffs)
-
includes/classes/class-apbgf-wizard.php (modified) (1 diff)
-
includes/helper/apbgf-functions.php (modified) (2 diffs)
-
readme.txt (modified) (3 diffs)
-
views/admin/appointment-filters.php (modified) (1 diff)
-
views/admin/block_data_reports.php (modified) (2 diffs)
-
views/admin/email-templates.php (modified) (2 diffs)
-
views/admin/modal/staff-modal.php (modified) (1 diff)
-
views/admin/setting.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
appointment-and-booking-for-gravity-forms/trunk/appointment-and-booking-for-gravity-forms.php
r3421819 r3481786 4 4 * Plugin URI: https://gravitybooking.com/ 5 5 * Description: With this GravityForms addon you can implement complete booking and appointments system in your WordPress site. 6 * Version: 1. 26 * Version: 1.3 7 7 * Author: Gravity Booking 8 8 * Author URI: https://profiles.wordpress.org/saadiqbal/ … … 52 52 } 53 53 54 $existing = get_posts(array( 55 'post_type' => 'apbgf-location', 56 'meta_key' => '_apbgf_default_location', 57 'meta_value' => '1', 58 'numberposts' => 1 59 )); 60 61 if ( empty ( $existing ) ) { 62 $old_location = get_posts(array( 63 'post_type' => 'apbgf-location', 64 'meta_key' => '_apbgf_default_location', 65 'meta_value' => '1', 66 'numberposts' => 1 67 )); 68 69 if ( ! empty($old_location)) { 70 $old_post = $old_location[0]; 71 $post_id = wp_insert_post(array( 72 'post_title' => $old_post->post_title, 73 'post_content' => $old_post->post_content, 74 'post_status' => 'publish', 75 'post_type' => 'apbgf-location', 76 )); 77 78 if ($post_id && !is_wp_error($post_id)) { 79 $meta_data = get_post_meta($old_post->ID); 80 foreach ($meta_data as $key => $values) { 81 foreach ($values as $value) { 82 update_post_meta($post_id, $key, $value); 83 } 84 } 85 wp_delete_post($old_post->ID, true); 86 } 87 return; 88 } 89 90 $post_id = wp_insert_post(array( 91 'post_title' => 'Default Location', 92 'post_content' => '', 93 'post_status' => 'publish', 94 'post_type' => 'apbgf-location', 95 )); 96 97 if ($post_id && !is_wp_error($post_id)) { 98 update_post_meta($post_id, '_apbgf_default_location', '1'); 99 } 100 } 54 // Default location creation logic removed per user request. 101 55 102 56 $current_user_id = get_current_user_id(); -
appointment-and-booking-for-gravity-forms/trunk/assets/admin/css/apbgf-admin-style.css
r3421805 r3481786 702 702 703 703 .disabled-block { 704 pointer-events: none;704 pointer-events: auto; 705 705 opacity: 0.5; 706 706 position: relative; 707 707 } 708 709 .disabled-block input, 710 .disabled-block select, 711 .disabled-block button, 712 .disabled-block a { 713 pointer-events: none; 714 } 715 708 716 709 717 body.apbgf-wizard-fullscreen #wpadminbar, -
appointment-and-booking-for-gravity-forms/trunk/assets/admin/css/apbgf-posttype-style.css
r3409551 r3481786 34 34 outline: none!important; 35 35 box-shadow: none!important; 36 } 37 a.apbgf-pro-trigger { 38 float: right; 39 margin-left: 15px; 40 float: right; 41 color: #57B0EE; 42 line-height: 1; 43 font-size: 15px; 44 padding: 12px 24px; 45 text-align: center; 46 transition: all .3s; 47 background-color: #57B0EE; 48 border-style: solid; 49 border-width: 1px; 50 border-color: #57B0EE; 51 border-radius: 10px; 52 box-shadow: 0px 6px 18px 0px rgb(0 0 0 / 6%); 53 margin-bottom: 20px; 54 text-decoration: none; 55 color: #fff; 56 font-weight: 500; 57 padding-bottom: 13px; 58 } 59 i.fa.fa-plus-circle { 60 margin-right: 10px; 36 61 } 37 62 .errorBorder ~ label.error { … … 1270 1295 .form-time-slots-disabled { 1271 1296 opacity: 0.4!important; 1297 pointer-events: auto!important; 1298 } 1299 .form-time-slots-disabled input, 1300 .form-time-slots-disabled select, 1301 .form-time-slots-disabled textarea, 1302 .form-time-slots-disabled button, 1303 .form-time-slots-disabled a, 1304 .form-time-slots-disabled .select2-container { 1305 pointer-events: none!important; 1306 } 1307 .apbgf-lead-time-disabled { 1308 opacity: 0.4!important; 1272 1309 pointer-events: none!important; 1273 1310 } -
appointment-and-booking-for-gravity-forms/trunk/assets/admin/js/apbgf-admin-script.js
r3409551 r3481786 499 499 event.preventDefault(); 500 500 var id = $(this).data('id'); 501 var isStaffProPopup = ( id === 'apbgf-staff-pro-modal' ); 501 502 502 503 window.scrollTo({top: 0}); 503 504 $('body').addClass('apbgf-modal-open'); 504 505 505 $('.apbgf-response').html('').removeClass('success error'); 506 $('.modal--form')[0].reset(); 507 if ( $('#apbgf-location').length > 0 ) { 508 $('#apbgf-location').trigger('change'); 509 } 510 511 if ( $('#apbgf-staff-form-details').length > 0 ) { 512 506 if ( ! isStaffProPopup ) { 507 $('.apbgf-response').html('').removeClass('success error'); 508 $('.modal--form')[0].reset(); 513 509 if ( $('#apbgf-location').length > 0 ) { 514 510 $('#apbgf-location').trigger('change'); 515 511 } 516 512 517 $('#apbgf-staff-form-details')[0].reset(); 518 } 519 520 if ( $('#apbgf-staff-form-services').length > 0 ) { 521 $('#apbgf-staff-form-services')[0].reset(); 522 } 523 524 if ( $('#apbgf-staff-form-timings').length > 0 ) { 525 $('#apbgf-staff-form-timings')[0].reset(); 526 } 527 528 if ( $('#apbgf-staff-form-spl-day').length > 0 ) { 529 $('#apbgf-staff-form-spl-day')[0].reset(); 530 } 531 532 $('input[type=checkbox]').prop('checked', false); 533 534 535 if ( $('.post_id').length > 0 ) { 536 $('.post_id').val(''); 513 if ( $('#apbgf-staff-form-details').length > 0 ) { 514 515 if ( $('#apbgf-location').length > 0 ) { 516 $('#apbgf-location').trigger('change'); 517 } 518 519 $('#apbgf-staff-form-details')[0].reset(); 520 } 521 522 if ( $('#apbgf-staff-form-services').length > 0 ) { 523 $('#apbgf-staff-form-services')[0].reset(); 524 } 525 526 if ( $('#apbgf-staff-form-timings').length > 0 ) { 527 $('#apbgf-staff-form-timings')[0].reset(); 528 } 529 530 if ( $('#apbgf-staff-form-spl-day').length > 0 ) { 531 $('#apbgf-staff-form-spl-day')[0].reset(); 532 } 533 534 $('input[type=checkbox]').prop('checked', false); 535 536 537 if ( $('.post_id').length > 0 ) { 538 $('.post_id').val(''); 539 } 537 540 } 538 541 //modal to open … … 554 557 */ 555 558 556 if ( $(datePickerAddHolidayField).length > 0 ) {559 if ( ! isStaffProPopup && $(datePickerAddHolidayField).length > 0 ) { 557 560 //destroy the calendar 558 561 $(datePickerAddHolidayField).data('daterangepicker').remove(); … … 612 615 }); 613 616 617 // Staff modal: clicking any disabled element or disabled section opens SVG pro popup 618 // Note: some "disabled-looking" controls are implemented via CSS classes, and some areas (labels/containers) 619 // are not the disabled element itself — so we detect disabled state by proximity. 620 $(document).on('click pointerdown mousedown touchstart', '#apbgf-staff-modal', function(e) { 621 if ( $('#apbgf-staff-pro-modal').length === 0 ) { 622 return; 623 } 624 // Only trigger from inside the open staff modal (not when opening it). 625 if ( ! $('#apbgf-staff-modal').hasClass('apbgf-modal-show') ) { 626 return; 627 } 628 var $target = $(e.target); 629 // Don't hijack close clicks. 630 if ( $target.closest('.modal__close').length > 0 ) { 631 return; 632 } 633 634 var $closestFormCol = $target.closest('#apbgf-staff-modal .form-col-full'); 635 var isTimingDisabledContainer = 636 $closestFormCol.find('#apbgf-duration.form-time-slots-disabled, #apbgf-interval.form-time-slots-disabled').length > 0; 637 638 var isStartEndDisabled = 639 $target.closest('.form-start-time-slots.form-time-slots-disabled, .form-end-time-slots.form-time-slots-disabled').length > 0; 640 641 var isDisabledZone = 642 $target.closest('#apbgf-multiple_booking, #apbgf-lead-time-container, .form-time-slots-disabled, .disabled-block').length > 0 || 643 isTimingDisabledContainer || 644 isStartEndDisabled || 645 $target.is('[disabled]'); 646 647 if ( isDisabledZone ) { 648 e.preventDefault(); 649 e.stopPropagation(); 650 $('body').addClass('apbgf-modal-open'); 651 $('#apbgf-staff-pro-modal').addClass('apbgf-modal-show'); 652 } 653 }); 654 655 // Capture-phase handler: attached ONLY to the staff modal so it can't interfere with list-table edit icon clicks. 656 // Needed for <input type="time"> which can swallow bubbling events. 657 (function() { 658 var staffModal = document.getElementById('apbgf-staff-modal'); 659 if (!staffModal) { return; } 660 661 function openStaffProModal() { 662 jQuery('body').addClass('apbgf-modal-open'); 663 jQuery('#apbgf-staff-pro-modal').addClass('apbgf-modal-show'); 664 } 665 666 function isDisabledZoneTarget(target) { 667 var proModal = document.getElementById('apbgf-staff-pro-modal'); 668 if (!proModal) { return false; } 669 if (!staffModal.classList.contains('apbgf-modal-show')) { return false; } 670 if (!staffModal.contains(target)) { return false; } 671 if (target.closest && target.closest('.modal__close')) { return false; } 672 673 var inDisabledZone = 674 (target.closest && target.closest('#apbgf-multiple_booking, #apbgf-lead-time-container, .form-time-slots-disabled, .disabled-block')) || 675 (target.closest && target.closest('.form-start-time-slots.form-time-slots-disabled, .form-end-time-slots.form-time-slots-disabled')) || 676 (target.matches && target.matches('[disabled]')); 677 678 if (!inDisabledZone && target.closest) { 679 var col = target.closest('#apbgf-staff-modal .form-col-full'); 680 if (col && col.querySelector('#apbgf-duration.form-time-slots-disabled, #apbgf-interval.form-time-slots-disabled')) { 681 inDisabledZone = true; 682 } 683 } 684 685 return !!inDisabledZone; 686 } 687 688 function captureHandler(e) { 689 if (isDisabledZoneTarget(e.target)) { 690 e.preventDefault(); 691 e.stopPropagation(); 692 openStaffProModal(); 693 } 694 } 695 696 ['pointerdown', 'mousedown', 'touchstart', 'click'].forEach(function(evt) { 697 staffModal.addEventListener(evt, captureHandler, true); 698 }); 699 })(); 700 614 701 $('#apbgf-booking_type').on('change', function() { 615 702 if ( 'fullday' == $(this).val() ) { … … 621 708 } 622 709 }); 710 711 $(document).on('click pointerdown', '.apbgf-pro-trigger', function(e) { 712 var modalId = $(this).data('apbgf-pro-modal') || 'apbgf-pro-modal'; 713 var $modal = $(`#${modalId}`); 714 if ( $modal.length === 0 ) { 715 return; 716 } 717 e.preventDefault(); 718 e.stopPropagation(); 719 $('body').addClass('apbgf-modal-open'); 720 if ( $modal.hasClass('apbgf-pro-modal') ) { 721 $modal.show(); 722 } else { 723 $modal.addClass('apbgf-modal-show'); 724 } 725 }); 623 726 624 727 $('.form-time-slots-content-row .apbgf_staff_time_toggle').on('click', function() { … … 1519 1622 1520 1623 1624 //add Location ajax 1625 $('#apbgf-location-form').on( 'submit', function( event ) { 1626 1627 event.preventDefault(); 1628 var This = $(this); 1629 var post_id = ''; 1630 var action = ''; 1631 1632 if ( $(This).find('.post_id').length > 0 ) { 1633 post_id = $(This).find('.post_id').val(); 1634 } 1635 1636 if ( post_id != '' ) { 1637 action = 'apbgf_edit_location'; 1638 } else { 1639 action = 'apbgf_add_location'; 1640 } 1641 1642 var formData = $(This).serialize() + `&action=${action}&nonce=${apbgf_admin.nonce}`; 1643 $.ajax({ 1644 url: apbgf_admin.ajaxurl, 1645 type: 'POST', 1646 data: formData, 1647 beforeSend: function () { 1648 $('#apbgf-location-form').find('.errorBorder').removeClass('errorBorder'); 1649 $('#apbgf-location-form').append('<div class="apbgf-modal-overlay" />'); 1650 $('#apbgf-location-form').find('.apbgf-response').html(''); 1651 $('.apbgf-response').removeClass('error').removeClass('success'); 1652 }, 1653 success: function (response) { 1654 var response = $.parseJSON(response); 1655 $('#apbgf-location-form').find('.apbgf-response').addClass(response.status); 1656 $('#apbgf-location-form').find('.apbgf-response').html(response.message); 1657 if ( 'success' == response.status ) { 1658 $('#apbgf-location-form')[0].reset(); 1659 location.reload(); 1660 } 1661 }, 1662 complete: function () { 1663 $('.apbgf-modal-overlay').remove(); 1664 } 1665 }); 1666 }); 1667 1521 1668 //add Service ajax 1522 1669 $('#apbgf-service-form').validate({ -
appointment-and-booking-for-gravity-forms/trunk/gravity-form-booking-main.php
r3421819 r3481786 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) {3 exit; 4 } 5 6 if ( ! defined( 'APBGF_LIVE_MODE' )) {7 define( 'APBGF_LIVE_MODE', false); // TRUE OR FALSE8 } 9 10 if ( ! defined( 'APBGF_FILE' )) {11 define( 'APBGF_FILE', __FILE__);12 } 13 14 if ( ! defined( 'APBGF_VERSION' )) {15 define( 'APBGF_VERSION', '1.2');16 } 17 18 if ( ! defined( 'APBGF_SLUG' )) {19 define( 'APBGF_SLUG', 'appointment-and-booking-for-gravity-forms');20 } 21 22 if ( ! defined( 'APBGF_URL' )) {23 define( 'APBGF_URL', plugin_dir_url( __FILE__ ));24 } 25 26 if ( ! defined( 'APBGF_PATH' )) {27 define( 'APBGF_PATH', plugin_dir_path( __FILE__ ));28 } 29 30 if ( ! defined( 'APBGF_FONT_URL' )) {31 define( 'APBGF_FONT_URL', APBGF_URL . 'assets/fonts/');32 } 33 34 if ( ! defined( 'APBGF_IMAGE_URL' )) {35 define( 'APBGF_IMAGE_URL', APBGF_URL . 'assets/images/');36 } 37 38 if ( ! defined( 'APBGF_ADMIN_JS_URL' )) {39 define( 'APBGF_ADMIN_JS_URL', APBGF_URL . 'assets/admin/js/');40 } 41 42 if ( ! defined( 'APBGF_COMMON_URL' )) {43 define( 'APBGF_COMMON_URL', APBGF_URL . 'assets/common/');44 } 45 46 if ( ! defined( 'APBGF_ADMIN_CSS_URL' )) {47 define( 'APBGF_ADMIN_CSS_URL', APBGF_URL . 'assets/admin/css/');48 } 49 50 if ( ! defined( 'APBGF_JS_URL' )) {51 define( 'APBGF_JS_URL', APBGF_URL . 'assets/frontend/js/');52 } 53 54 if ( ! defined( 'APBGF_CSS_URL' )) {55 define( 'APBGF_CSS_URL', APBGF_URL . 'assets/frontend/css/');56 } 57 58 if ( ! defined( 'APBGF_ADMIN_VIEW_PATH' )) {59 define( 'APBGF_ADMIN_VIEW_PATH', APBGF_PATH . 'views/admin/');60 } 61 62 if ( ! defined( 'APBGF_VIEW_PATH' )) {63 define( 'APBGF_VIEW_PATH', APBGF_PATH . 'views/frontend/');2 if (!defined('ABSPATH')) { 3 exit; 4 } 5 6 if (!defined('APBGF_LIVE_MODE')) { 7 define('APBGF_LIVE_MODE', false); // TRUE OR FALSE 8 } 9 10 if (!defined('APBGF_FILE')) { 11 define('APBGF_FILE', __FILE__); 12 } 13 14 if (!defined('APBGF_VERSION')) { 15 define('APBGF_VERSION', '1.3'); 16 } 17 18 if (!defined('APBGF_SLUG')) { 19 define('APBGF_SLUG', 'appointment-and-booking-for-gravity-forms'); 20 } 21 22 if (!defined('APBGF_URL')) { 23 define('APBGF_URL', plugin_dir_url(__FILE__)); 24 } 25 26 if (!defined('APBGF_PATH')) { 27 define('APBGF_PATH', plugin_dir_path(__FILE__)); 28 } 29 30 if (!defined('APBGF_FONT_URL')) { 31 define('APBGF_FONT_URL', APBGF_URL . 'assets/fonts/'); 32 } 33 34 if (!defined('APBGF_IMAGE_URL')) { 35 define('APBGF_IMAGE_URL', APBGF_URL . 'assets/images/'); 36 } 37 38 if (!defined('APBGF_ADMIN_JS_URL')) { 39 define('APBGF_ADMIN_JS_URL', APBGF_URL . 'assets/admin/js/'); 40 } 41 42 if (!defined('APBGF_COMMON_URL')) { 43 define('APBGF_COMMON_URL', APBGF_URL . 'assets/common/'); 44 } 45 46 if (!defined('APBGF_ADMIN_CSS_URL')) { 47 define('APBGF_ADMIN_CSS_URL', APBGF_URL . 'assets/admin/css/'); 48 } 49 50 if (!defined('APBGF_JS_URL')) { 51 define('APBGF_JS_URL', APBGF_URL . 'assets/frontend/js/'); 52 } 53 54 if (!defined('APBGF_CSS_URL')) { 55 define('APBGF_CSS_URL', APBGF_URL . 'assets/frontend/css/'); 56 } 57 58 if (!defined('APBGF_ADMIN_VIEW_PATH')) { 59 define('APBGF_ADMIN_VIEW_PATH', APBGF_PATH . 'views/admin/'); 60 } 61 62 if (!defined('APBGF_VIEW_PATH')) { 63 define('APBGF_VIEW_PATH', APBGF_PATH . 'views/frontend/'); 64 64 } 65 65 … … 67 67 * Main class 68 68 */ 69 if ( ! class_exists( 'APBGF_Main' )) {69 if (!class_exists('APBGF_Main')) { 70 70 71 71 … … 73 73 * Restaurant main class 74 74 */ 75 class APBGF_Main { 75 class APBGF_Main 76 { 76 77 77 78 /** … … 89 90 * Class Constructor 90 91 */ 91 private function __construct() { 92 private function __construct() 93 { 92 94 93 95 /** … … 96 98 require_once APBGF_PATH . 'includes/classes/class-apbgf-dependencies.php'; 97 99 98 if ( APBGF_Dependencies::active_check( 'gravityforms/gravityforms.php' ) ) {99 100 self::$classes = array( 100 if (APBGF_Dependencies::active_check('gravityforms/gravityforms.php')) { 101 102 self::$classes = array( 101 103 'admin', 102 104 'setting', … … 106 108 'service', 107 109 'staff', 108 'customer', 110 'customer', 109 111 'calendar', 110 'report' 112 'report' 111 113 ); 112 114 113 add_action( 'gform_loaded', array( $this, 'apbgf_init' ));114 add_action( 'init', array( $this, 'load_textdomain' ));115 add_action( 'init', array( $this, 'apbgf_reminder_email_cron_schedule' ));116 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'add_action_links' ) );115 add_action('init', array($this, 'apbgf_init'), 2); 116 add_action('init', array($this, 'load_textdomain'), 1); 117 add_action('init', array($this, 'apbgf_reminder_email_cron_schedule')); 118 add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this, 'add_action_links')); 117 119 118 120 } else { 119 add_action( 'admin_notices', array( $this, 'inactive_plugin_notice' ) ); 120 } 121 } 122 123 public function apbgf_reminder_email_cron_schedule() { 124 if ( ! wp_next_scheduled( 'apbgf_plugin_cron_hook_for_email' ) ) { 125 $timezone = get_option( 'timezone_string' ); 126 if ( ! empty( $timezone ) ) { 121 add_action('admin_notices', array($this, 'inactive_plugin_notice')); 122 } 123 } 124 125 public function apbgf_reminder_email_cron_schedule() 126 { 127 if (!wp_next_scheduled('apbgf_plugin_cron_hook_for_email')) { 128 $timezone = get_option('timezone_string'); 129 if (!empty($timezone)) { 127 130 // Convert timezone for timestamp using WordPress functions 128 131 $datetime = new DateTime('today midnight', new DateTimeZone($timezone)); … … 130 133 } else { 131 134 // Fallback to default WordPress timezone offset 132 $timestamp = strtotime('today midnight') + ( get_option('gmt_offset') * HOUR_IN_SECONDS);135 $timestamp = strtotime('today midnight') + (get_option('gmt_offset') * HOUR_IN_SECONDS); 133 136 } 134 wp_schedule_event( $timestamp, 'daily', 'apbgf_plugin_cron_hook_for_email' ); 135 } 136 137 add_action( 'apbgf_plugin_cron_hook_for_email', array( $this, 'apbgf_cron_callback' ) ); 138 } 139 140 public function apbgf_cron_callback() { 141 APBGF_Email::send_reminder_notification( 'template_9', 'staff' ); # template_9 142 APBGF_Email::send_reminder_notification( 'template_10', 'customer' ); # template_10 143 } 144 145 public function apbgf_init() { 137 wp_schedule_event($timestamp, 'daily', 'apbgf_plugin_cron_hook_for_email'); 138 } 139 140 add_action('apbgf_plugin_cron_hook_for_email', array($this, 'apbgf_cron_callback')); 141 } 142 143 public function apbgf_cron_callback() 144 { 145 APBGF_Email::send_reminder_notification('template_9', 'staff'); # template_9 146 APBGF_Email::send_reminder_notification('template_10', 'customer'); # template_10 147 } 148 149 public function apbgf_init() 150 { 146 151 147 152 self::apbgf_includes(); 148 self::includes(); 149 } 150 151 public function add_action_links( $actions ) { 153 self::includes(); 154 } 155 156 public function add_action_links($actions) 157 { 152 158 $mylinks = array( 153 '<a href="' . admin_url( 'admin.php?page=gfb') . '">' . esc_html__('Dashboard', 'appointment-and-booking-for-gravity-forms') . '</a>'159 '<a href="' . admin_url('admin.php?page=gfb') . '">' . esc_html__('Dashboard', 'appointment-and-booking-for-gravity-forms') . '</a>' 154 160 ); 155 $actions = array_merge( $actions, $mylinks);161 $actions = array_merge($actions, $mylinks); 156 162 return $actions; 157 163 } … … 160 166 * Plugin Domain loaded 161 167 */ 162 public function load_textdomain() { 163 load_plugin_textdomain( 'appointment-and-booking-for-gravity-forms', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); 168 public function load_textdomain() 169 { 170 load_plugin_textdomain('appointment-and-booking-for-gravity-forms', false, dirname(plugin_basename(__FILE__)) . '/languages/'); 164 171 } 165 172 … … 167 174 * Inactive plugin notice. 168 175 */ 169 public function inactive_plugin_notice() { 170 $class = 'notice notice-error'; 171 $headline = esc_html__( 'Gravity Booking requires Gravity Form to be install & active.', 'appointment-and-booking-for-gravity-forms' ); 172 $message = esc_html__( 'Go to the plugins page to activate Gravity Form plugin', 'appointment-and-booking-for-gravity-forms' ); 173 printf( '<div class="%1$s"><h2>%2$s</h2><p>%3$s</p></div>', esc_attr( $class ), esc_html( $headline ), esc_html( $message ) ); 176 public function inactive_plugin_notice() 177 { 178 $class = 'notice notice-error'; 179 $headline = esc_html__('Gravity Booking requires Gravity Form to be install & active.', 'appointment-and-booking-for-gravity-forms'); 180 $message = esc_html__('Go to the plugins page to activate Gravity Form plugin', 'appointment-and-booking-for-gravity-forms'); 181 printf('<div class="%1$s"><h2>%2$s</h2><p>%3$s</p></div>', esc_attr($class), esc_html($headline), esc_html($message)); 174 182 } 175 183 … … 177 185 * Files to includes 178 186 */ 179 private static function includes() { 187 private static function includes() 188 { 180 189 181 190 require_once APBGF_PATH . 'includes/helper/apbgf-functions.php'; 182 191 183 if ( is_array( self::$classes ) && count( self::$classes ) > 0) {184 foreach ( self::$classes as $class) {192 if (is_array(self::$classes) && count(self::$classes) > 0) { 193 foreach (self::$classes as $class) { 185 194 require_once APBGF_PATH . '/includes/classes/class-apbgf-' . $class . '.php'; 186 195 } … … 195 204 196 205 /* update data on first load */ 197 if ( false == get_option('apbgf_update_staff_data', false) ) {198 199 $all_staffs = get_posts( array(206 if (false == get_option('apbgf_update_staff_data', false)) { 207 208 $all_staffs = get_posts(array( 200 209 'fields' => 'ids', 201 210 'post_type' => 'apbgf-staff', … … 204 213 )); 205 214 206 if ( is_array($all_staffs) && count( $all_staffs ) > 0) {215 if (is_array($all_staffs) && count($all_staffs) > 0) { 207 216 foreach ($all_staffs as $staff_id) { 208 217 APBGF_Staff::get_staff_data_by_id($staff_id); … … 211 220 212 221 update_option('apbgf_update_staff_data', true); 213 } 222 } 214 223 } 215 224 … … 217 226 * Files to includes GFB Related files 218 227 */ 219 private static function apbgf_includes() { 220 228 private static function apbgf_includes() 229 { 230 221 231 require_once APBGF_PATH . 'includes/gravity-form/class-apbgf-form-setting.php'; 222 232 require_once APBGF_PATH . 'includes/gravity-form/apbgf-fields/class-apbgf-appointment-calendar-field.php'; … … 226 236 * Singleton Class Instatnce. 227 237 */ 228 public static function get_instance() { 229 if ( null === self::$instance ) { 238 public static function get_instance() 239 { 240 if (null === self::$instance) { 230 241 self::$instance = new APBGF_Main(); 231 242 } -
appointment-and-booking-for-gravity-forms/trunk/includes/classes/class-apbgf-admin.php
r3421805 r3481786 28 28 'apbgf-customer', 29 29 'apbgf-calendar', 30 'apbgf-appointment' 30 'apbgf-appointment', 31 'apbgf-location' 31 32 ); 32 33 … … 39 40 'gravity-booking_page_apbgf-setting', 40 41 'edit-apbgf-service-category', 41 'gravity-booking_page_apbgf-calendar' 42 'gravity-booking_page_apbgf-calendar', 43 'edit-apbgf-location' 42 44 ); 43 45 … … 177 179 178 180 public function register_main_menu() { 181 if ( defined( 'GFB_VERSION' ) ) { 182 return; 183 } 184 179 185 $wizard_completed = get_option( 'apbgf_wizard_completed', false ); 180 186 … … 223 229 'apbgf-appointment', 224 230 'apbgf-calendar', 231 'apbgf-location', 225 232 ); 226 233 -
appointment-and-booking-for-gravity-forms/trunk/includes/classes/class-apbgf-calendar.php
r3421805 r3481786 226 226 $staff_id = isset($_POST['staff_id']) ? sanitize_text_field(wp_unslash($_POST['staff_id'])) : ''; 227 227 $lead_time_meta = get_post_meta($staff_id, 'gbf_lead_time', true); 228 $apbgf_settings = APBGF_Setting::get_settings(); 228 229 $lead_time = !empty($lead_time_meta) ? $lead_time_meta : $apbgf_settings['gbf_lead_time']; 229 230 $current_time = new DateTime(); … … 270 271 $multiple_slot = sprintf(esc_html__('%1$s slots left', 'appointment-and-booking-for-gravity-forms'), $remaining_capacity); 271 272 $tooltip = ( 1 >= $remaining_capacity ) ? $single_slot : $multiple_slot; 272 $apbgf_settings = APBGF_Setting::get_settings(); 273 273 274 274 if (( isset($apbgf_settings['hide_slot_capacity']) && 'enabled' == $apbgf_settings['hide_slot_capacity'] ) ) { 275 275 $slot_field_type = 'hidden'; … … 438 438 $service_hide = false ; 439 439 $staff_hide = false; 440 $service_category_hide = false; 440 441 $location_id = 0 ; 441 442 $service_id = 0 ; 442 $staff_id = 0; 443 $staff_id = 0; 444 $service_category_id = ''; 443 445 444 446 if ( isset($field[0]) ) { -
appointment-and-booking-for-gravity-forms/trunk/includes/classes/class-apbgf-email.php
r3409551 r3481786 351 351 '{staff_name}' => esc_html__( 'name of staff', 'appointment-and-booking-for-gravity-forms' ), 352 352 '{total_slot}' => esc_html__( 'total no. of slots', 'appointment-and-booking-for-gravity-forms' ), 353 '{total_price}' => esc_html__( 'total price of booking', 'appointment-and-booking-for-gravity-forms' ) 353 '{total_price}' => esc_html__( 'total price of booking', 'appointment-and-booking-for-gravity-forms' ), 354 '{sender_name}' => esc_html__( 'sender name', 'appointment-and-booking-for-gravity-forms' ), 355 '{sender_email}' => esc_html__( 'sender email', 'appointment-and-booking-for-gravity-forms' ) 354 356 ) ); 355 357 } … … 372 374 } else { 373 375 require_once APBGF_ADMIN_VIEW_PATH . 'email-templates.php'; 376 } 377 378 // Add global PRO popup modal on the Email Notifications page, reusing the shared SVG artwork. 379 if ( defined( 'APBGF_IMAGE_URL' ) ) { 380 $apbgf_pro_popup_img = APBGF_IMAGE_URL . 'ProPopup.svg'; 381 $apbgf_pricing_url = 'https://gravitybooking.com/pricing/?utm_source=plugin&utm_medium=email'; 382 if ( $apbgf_pro_popup_img ) { 383 ?> 384 <div id="apbgf-pro-modal" class="apbgf-pro-modal" style="display:none;"> 385 <div class="apbgf-pro-modal-backdrop" style="position:fixed;inset:0;background:rgba(0,0,0,0.5);z-index:100000;"></div> 386 <div class="apbgf-pro-modal-inner" style="position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:100001;max-width:640px;width:100%;overflow:hidden;border-radius:8px;"> 387 <div class="apbgf-pro-modal-content" style="position:relative;"> 388 <img src="<?php echo esc_url( $apbgf_pro_popup_img ); ?>" alt="<?php esc_attr_e( 'Upgrade to Pro', 'appointment-and-booking-for-gravity-forms' ); ?>" style="display:block;width:100%;height:auto;" /> 389 <a href="<?php echo esc_url( $apbgf_pricing_url ); ?>" target="_blank" rel="noopener noreferrer" 390 aria-label="<?php esc_attr_e( 'Buy Gravity Bookings', 'appointment-and-booking-for-gravity-forms' ); ?>" 391 style="position:absolute;left:31%;top:69%;width:38%;height:15%;background:transparent;border:none;outline:none;box-shadow:none;cursor:pointer;text-indent:-9999px;overflow:hidden;"> 392 <?php esc_html_e( 'Buy Gravity Bookings', 'appointment-and-booking-for-gravity-forms' ); ?> 393 </a> 394 <button type="button" class="apbgf-pro-modal-close-area" aria-label="<?php esc_attr_e( 'Close', 'appointment-and-booking-for-gravity-forms' ); ?>" style="position:absolute;top:0;right:0;width:15%;height:12%;background:transparent;border:none;outline:none;box-shadow:none;cursor:pointer;z-index:2;"></button> 395 </div> 396 </div> 397 </div> 398 <script type="text/javascript"> 399 (function() { 400 function apbgfReady(fn) { 401 if (document.readyState === 'loading') { 402 document.addEventListener('DOMContentLoaded', fn); 403 } else { 404 fn(); 405 } 406 } 407 apbgfReady(function() { 408 var modal = document.getElementById('apbgf-pro-modal'); 409 if (!modal) { return; } 410 var closeArea = modal.querySelector('.apbgf-pro-modal-close-area'); 411 var backdrop = modal.querySelector('.apbgf-pro-modal-backdrop'); 412 413 function closeModal(e) { 414 if (e) { 415 e.preventDefault(); 416 } 417 modal.style.display = 'none'; 418 } 419 420 if (closeArea) { 421 closeArea.addEventListener('click', closeModal); 422 } 423 if (backdrop) { 424 backdrop.addEventListener('click', closeModal); 425 } 426 }); 427 })(); 428 </script> 429 <?php 430 } 374 431 } 375 432 } … … 446 503 $data['company_phone'] = self::$apbgf_setting['apbgf_company_number']; 447 504 $data['company_website'] = self::$apbgf_setting['apbgf_company_website_url']; 505 $data['sender_name'] = self::$apbgf_setting['apbgf_sender_name']; 506 $data['sender_email'] = self::$apbgf_setting['apbgf_sender_email']; 448 507 $data['footer'] = apply_filters('apbgf_email_template_footer', ''); 449 508 … … 512 571 $template_message = str_replace('{total_slot}', $data['total_slot'], $template_message); 513 572 $template_message = str_replace('{total_price}', $data['total_price'], $template_message); 573 $template_message = str_replace('{sender_name}', $data['sender_name'], $template_message); 574 $template_message = str_replace('{sender_email}', $data['sender_email'], $template_message); 514 575 515 576 $template_message = apply_filters('apbgf_email_template_message', $template_message, $data); … … 570 631 $template_message = str_replace('{total_slot}', $data['total_slot'], $template_message); 571 632 $template_message = str_replace('{total_price}', $data['total_price'], $template_message); 633 $template_message = str_replace('{sender_name}', $data['sender_name'], $template_message); 634 $template_message = str_replace('{sender_email}', $data['sender_email'], $template_message); 572 635 573 636 $template_message = apply_filters('apbgf_email_template_message', $template_message, $data); -
appointment-and-booking-for-gravity-forms/trunk/includes/classes/class-apbgf-location.php
r3421805 r3481786 16 16 private function __construct() { 17 17 add_action( 'init', array( $this, 'register_location_posttype' ), 20 ); 18 19 add_filter( 'manage_apbgf-location_posts_columns', array( $this, 'apbgf_modify_column_names' ) ); 20 add_action( 'manage_apbgf-location_posts_custom_column', array( $this, 'apbgf_add_custom_column' ), 9, 2 ); 21 add_action( 'admin_footer', array( $this, 'highlight_menu' ) ); 22 add_action( 'manage_posts_extra_tablenav', array( $this, 'apbgf_manage_posts_extra_tablenav' ) ); 23 24 add_action( 'wp_ajax_apbgf_add_location', array( $this, 'apbgf_add_location' ) ); 25 add_action( 'wp_ajax_apbgf_edit_location', array( $this, 'apbgf_edit_location' ) ); 26 add_action( 'wp_ajax_apbgf_delete_location', array( $this, 'apbgf_delete_location' ) ); 27 add_action( 'wp_ajax_apbgf_show_location_data', array( $this, 'apbgf_show_location_data' ) ); 18 28 } 19 29 … … 22 32 */ 23 33 public function register_location_posttype() { 34 35 24 36 $labels = array( 25 37 'name' => esc_html__( 'Locations', 'appointment-and-booking-for-gravity-forms' ), … … 40 52 'public' => false, 41 53 'publicly_queryable' => false, 42 'show_ui' => false,43 'show_in_menu' => false,44 'show_in_rest' => false,54 'show_ui' => true, 55 'show_in_menu' => 'appointment-and-booking-for-gravity-forms', 56 'show_in_rest' => true, 45 57 'query_var' => true, 46 'rewrite' => false,58 'rewrite' => array( 'slug' => 'apbgf-location' ), 47 59 'capability_type' => 'post', 48 'has_archive' => false,60 'has_archive' => true, 49 61 'hierarchical' => false, 50 62 'supports' => array( 'title' ), … … 52 64 53 65 register_post_type( 'apbgf-location', $args ); 66 } 67 68 public function apbgf_modify_column_names( $columns ) { 69 unset($columns['date']); 70 unset($columns['title']); 71 72 $columns['id'] = __(' Location ID', 'appointment-and-booking-for-gravity-forms'); 73 $columns['name'] = __('Name', 'appointment-and-booking-for-gravity-forms'); 74 $columns['phone'] = __('Phone', 'appointment-and-booking-for-gravity-forms'); 75 $columns['address'] = __('Address', 'appointment-and-booking-for-gravity-forms'); 76 $columns['actions'] = __('Actions', 'appointment-and-booking-for-gravity-forms'); 77 78 return $columns; 79 } 80 81 public function apbgf_add_custom_column( $column, $post_id ) { 82 switch ($column) { 83 case 'id': 84 echo ' ' . esc_attr($post_id); 85 break; 86 case 'name': 87 echo esc_attr(get_the_title($post_id)); 88 break; 89 case 'phone': 90 echo esc_attr(get_post_meta($post_id, 'phone', true)); 91 break; 92 case 'address': 93 echo esc_attr(get_post_meta($post_id, 'address', true)); 94 break; 95 case 'actions': 96 echo '<a href="#" data-type="location" data-id="apbgf-location-modal" data-post_id="' . esc_attr( $post_id ) . '" class="wc-dashicons apbgf-edit"> <i class="fa fa-edit customer--icon"></i> </a>'; 97 if ( 'publish' == get_post_status($post_id) ) { 98 echo '<a href="#" data-type="location" data-post_id="' . esc_attr( $post_id ) . '" class="wc-dashicons apbgf-delete" title="Delete"> <i class="fa fa-trash customer--icon"></i></a>'; 99 } 100 break; 101 } 102 } 103 104 public function apbgf_manage_posts_extra_tablenav( $which ) { 105 if ( 'top' === $which ) { 106 $screen = get_current_screen(); 107 if ( isset($screen->post_type) && 'apbgf-location' === $screen->post_type ) { 108 printf('<a href="#" data-apbgf-pro-modal="apbgf-location-pro-modal" class="apbgf-pro-trigger"><i class="fa fa-plus-circle"></i>%1$s</a>', esc_html__('Add Location', 'appointment-and-booking-for-gravity-forms') ); 109 } 110 } 111 } 112 113 public function highlight_menu() { 114 $screen = get_current_screen(); 115 if ( isset($screen->post_type) && 'apbgf-location' === $screen->post_type ) { 116 require_once APBGF_ADMIN_VIEW_PATH . 'modal/location-modal.php'; 117 118 $popup_img = defined( 'APBGF_IMAGE_URL' ) ? APBGF_IMAGE_URL . 'ProPopup.svg' : ''; 119 $popup_url = 'https://gravitybooking.com/pricing/?utm_source=plugin&utm_medium=location'; 120 if ( $popup_img ) { 121 ?> 122 <div id="apbgf-location-pro-modal" class="modal" role="dialog" aria-modal="true" aria-label="<?php esc_attr_e( 'Upgrade to Pro', 'appointment-and-booking-for-gravity-forms' ); ?>"> 123 <div class="apbgf-location-pro-modal__inner" style="position:relative;max-width:640px;width:100%;margin:auto;"> 124 <div class="apbgf-location-pro-modal__content" style="position:relative;border-radius:8px;overflow:hidden;"> 125 <img src="<?php echo esc_url( $popup_img ); ?>" alt="<?php esc_attr_e( 'Upgrade to Pro', 'appointment-and-booking-for-gravity-forms' ); ?>" style="display:block;width:100%;height:auto;" /> 126 <a href="<?php echo esc_url( $popup_url ); ?>" target="_blank" rel="noopener noreferrer" 127 aria-label="<?php esc_attr_e( 'Buy Gravity Bookings', 'appointment-and-booking-for-gravity-forms' ); ?>" 128 style="position:absolute;left:31%;top:69%;width:38%;height:15%;background:transparent;border:none;outline:none;box-shadow:none;cursor:pointer;text-indent:-9999px;overflow:hidden;"> 129 <?php esc_html_e( 'Buy Gravity Bookings', 'appointment-and-booking-for-gravity-forms' ); ?> 130 </a> 131 <button type="button" class="modal__close" aria-label="<?php esc_attr_e( 'Close', 'appointment-and-booking-for-gravity-forms' ); ?>" style="position:absolute;top:0;right:0;width:15%;height:12%;background:transparent;border:none;outline:none;box-shadow:none;cursor:pointer;z-index:2;"></button> 132 </div> 133 </div> 134 </div> 135 <?php 136 } 137 138 // Register and enqueue the menu highlight script 139 wp_register_script('apbgf-location-menu-highlight', false, array( 'jquery' )); 140 wp_enqueue_script('apbgf-location-menu-highlight'); 141 142 wp_add_inline_script('apbgf-location-menu-highlight', ' 143 jQuery(document).ready(function($) { 144 $("#toplevel_page_gfb li, #toplevel_page_gfb li > a").removeClass("current"); 145 $("#toplevel_page_gfb a[href=\"edit.php?post_type=apbgf-location\"]").addClass("current"); 146 $("#toplevel_page_gfb a[href=\"edit.php?post_type=apbgf-location\"]").parent("li").addClass("current"); 147 }); 148 '); 149 } 150 } 151 152 public function apbgf_add_location() { 153 check_ajax_referer( 'appointment-and-booking-for-gravity-forms', 'nonce' ); 154 155 $response = array( 156 'message' => esc_html__( 'Please fill all required fields.', 'appointment-and-booking-for-gravity-forms' ), 157 'status' => 'error' 158 ); 159 160 $name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : ''; 161 $phone = isset( $_POST['phone'] ) ? sanitize_text_field( wp_unslash( $_POST['phone'] ) ) : ''; 162 $address = isset( $_POST['address'] ) ? sanitize_textarea_field( wp_unslash( $_POST['address'] ) ) : ''; 163 $description = isset( $_POST['description'] ) ? sanitize_textarea_field( wp_unslash( $_POST['description'] ) ) : ''; 164 165 if ( ! empty( $name ) ) { 166 $args = array( 167 'post_title' => $name, 168 'post_content' => $description, 169 'post_type' => 'apbgf-location', 170 'post_status' => 'publish', 171 'meta_input' => array( 172 'phone' => $phone, 173 'address' => $address, 174 ), 175 ); 176 177 $location_id = wp_insert_post( $args ); 178 179 if ( ! is_wp_error( $location_id ) ) { 180 $response['message'] = esc_html__( 'Location created successfully.', 'appointment-and-booking-for-gravity-forms' ); 181 $response['status'] = 'success'; 182 } else { 183 $response['message'] = $location_id->get_error_message(); 184 } 185 } 186 187 echo wp_json_encode( $response ); 188 wp_die(); 189 } 190 191 public function apbgf_edit_location() { 192 check_ajax_referer( 'appointment-and-booking-for-gravity-forms', 'nonce' ); 193 194 $response = array( 195 'message' => esc_html__( 'Please fill all required fields.', 'appointment-and-booking-for-gravity-forms' ), 196 'status' => 'error' 197 ); 198 199 $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; 200 $name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : ''; 201 $phone = isset( $_POST['phone'] ) ? sanitize_text_field( wp_unslash( $_POST['phone'] ) ) : ''; 202 $address = isset( $_POST['address'] ) ? sanitize_textarea_field( wp_unslash( $_POST['address'] ) ) : ''; 203 $description = isset( $_POST['description'] ) ? sanitize_textarea_field( wp_unslash( $_POST['description'] ) ) : ''; 204 205 if ( ! empty( $post_id ) && ! empty( $name ) ) { 206 $args = array( 207 'ID' => $post_id, 208 'post_title' => $name, 209 'post_content' => $description, 210 'post_status' => 'publish', 211 'meta_input' => array( 212 'phone' => $phone, 213 'address' => $address, 214 ), 215 ); 216 217 $update = wp_update_post( $args, true ); 218 219 if ( ! is_wp_error( $update ) ) { 220 $response['message'] = esc_html__( 'Location updated successfully.', 'appointment-and-booking-for-gravity-forms' ); 221 $response['status'] = 'success'; 222 } else { 223 $response['message'] = $update->get_error_message(); 224 } 225 } 226 227 echo wp_json_encode( $response ); 228 wp_die(); 229 } 230 231 public function apbgf_delete_location() { 232 check_ajax_referer( 'appointment-and-booking-for-gravity-forms', 'nonce' ); 233 234 $response = array( 235 'message' => esc_html__( 'Location not deleted.', 'appointment-and-booking-for-gravity-forms' ), 236 'status' => 'error' 237 ); 238 239 $post_id = isset( $_REQUEST['post_id'] ) ? absint( $_REQUEST['post_id'] ) : 0; 240 241 if ( $post_id ) { 242 $post = get_post( $post_id ); 243 if ( $post && 'apbgf-location' === $post->post_type ) { 244 wp_delete_post( $post_id, true ); 245 $response['message'] = esc_html__( 'Location deleted successfully.', 'appointment-and-booking-for-gravity-forms' ); 246 $response['status'] = 'success'; 247 } 248 } 249 250 echo wp_json_encode( $response ); 251 wp_die(); 252 } 253 254 public function apbgf_show_location_data() { 255 check_ajax_referer( 'appointment-and-booking-for-gravity-forms', 'nonce' ); 256 257 $response = array( 258 'status' => 'error' 259 ); 260 261 $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; 262 263 if ( $post_id ) { 264 $post = get_post( $post_id ); 265 if ( $post && 'apbgf-location' === $post->post_type ) { 266 $response['status'] = 'success'; 267 $response['name'] = $post->post_title; 268 $response['description'] = $post->post_content; 269 $response['phone'] = get_post_meta( $post_id, 'phone', true ); 270 $response['address'] = get_post_meta( $post_id, 'address', true ); 271 } 272 } 273 274 echo wp_json_encode( $response ); 275 wp_die(); 54 276 } 55 277 -
appointment-and-booking-for-gravity-forms/trunk/includes/classes/class-apbgf-service.php
r3409551 r3481786 681 681 682 682 //adding customer modal view file 683 require_once APBGF_ADMIN_VIEW_PATH . 'modal/service-modal.php'; 683 require_once APBGF_ADMIN_VIEW_PATH . 'modal/service-modal.php'; 684 685 $popup_img = defined( 'APBGF_IMAGE_URL' ) ? APBGF_IMAGE_URL . 'ProPopup.svg' : ''; 686 $popup_url = 'https://gravitybooking.com/pricing/?utm_source=plugin&utm_medium=service'; 687 if ( $popup_img ) { 688 ?> 689 <div id="apbgf-service-pro-modal" class="modal" role="dialog" aria-modal="true" aria-label="<?php esc_attr_e( 'Export', 'appointment-and-booking-for-gravity-forms' ); ?>"> 690 <div class="apbgf-service-pro-modal__inner" style="position:relative;max-width:640px;width:100%;margin:auto;"> 691 <div class="apbgf-service-pro-modal__content" style="position:relative;border-radius:8px;overflow:hidden;"> 692 <img src="<?php echo esc_url( $popup_img ); ?>" alt="<?php esc_attr_e( 'Upgrade to Pro', 'appointment-and-booking-for-gravity-forms' ); ?>" style="display:block;width:100%;height:auto;" /> 693 <a href="<?php echo esc_url( $popup_url ); ?>" target="_blank" rel="noopener noreferrer" 694 aria-label="<?php esc_attr_e( 'Buy Gravity Bookings', 'appointment-and-booking-for-gravity-forms' ); ?>" 695 style="position:absolute;left:31%;top:69%;width:38%;height:15%;background:transparent;border:none;outline:none;box-shadow:none;cursor:pointer;text-indent:-9999px;overflow:hidden;"> 696 <?php esc_html_e( 'Buy Gravity Bookings', 'appointment-and-booking-for-gravity-forms' ); ?> 697 </a> 698 <button type="button" class="modal__close" aria-label="<?php esc_attr_e( 'Close', 'appointment-and-booking-for-gravity-forms' ); ?>" style="position:absolute;top:0;right:0;width:15%;height:12%;background:transparent;border:none;outline:none;box-shadow:none;cursor:pointer;z-index:2;"></button> 699 </div> 700 </div> 701 </div> 702 <?php 703 } 684 704 685 705 // Register and enqueue the menu highlight script -
appointment-and-booking-for-gravity-forms/trunk/includes/classes/class-apbgf-staff.php
r3421805 r3481786 52 52 add_filter('post_row_actions', '__return_empty_array'); 53 53 54 //add_action('manage_posts_extra_tablenav', array( $this, 'apbgf_manage_posts_extra_tablenav' ));54 add_action( 'manage_posts_extra_tablenav', array( $this, 'apbgf_manage_posts_extra_tablenav' ) ); 55 55 56 56 add_filter('months_dropdown_results', '__return_empty_array'); … … 973 973 if ( current_user_can( 'manage_options' ) ) { 974 974 if ( 'top' === $which ) { 975 printf('<a href="#" data-id="apbgf-staff- modal" class="apbgf-add-button"><i class="fa fa-plus-circle"></i>%1$s</a>', esc_html__('Add Staff', 'appointment-and-booking-for-gravity-forms') );975 printf('<a href="#" data-id="apbgf-staff-pro-modal" class="apbgf-add-button"><i class="fa fa-plus-circle"></i>%1$s</a>', esc_html__('Add Staff', 'appointment-and-booking-for-gravity-forms') ); 976 976 } 977 977 } … … 982 982 //adding customer modal view file 983 983 require_once APBGF_ADMIN_VIEW_PATH . 'modal/staff-modal.php'; 984 985 // Add Staff: SVG popup modal (button opens URL in new tab) 986 $popup_img = defined( 'APBGF_IMAGE_URL' ) ? APBGF_IMAGE_URL . 'ProPopup.svg' : ''; 987 $popup_url = 'https://gravitybooking.com/pricing/?utm_source=plugin&utm_medium=staff'; 988 if ( $popup_img ) { 989 ?> 990 <div id="apbgf-staff-pro-modal" class="modal" role="dialog" aria-modal="true" aria-label="<?php esc_attr_e( 'Add Staff', 'appointment-and-booking-for-gravity-forms' ); ?>"> 991 <div class="apbgf-staff-pro-modal__inner" style="position:relative;max-width:640px;width:100%;margin:auto;"> 992 <div class="apbgf-staff-pro-modal__content" style="position:relative;border-radius:8px;overflow:hidden;"> 993 <img src="<?php echo esc_url( $popup_img ); ?>" alt="<?php esc_attr_e( 'Upgrade to Pro', 'appointment-and-booking-for-gravity-forms' ); ?>" style="display:block;width:100%;height:auto;" /> 994 <a href="<?php echo esc_url( $popup_url ); ?>" target="_blank" rel="noopener noreferrer" class="apbgf-staff-pro-modal__cta" aria-label="<?php esc_attr_e( 'Buy Gravity Bookings', 'appointment-and-booking-for-gravity-forms' ); ?>" style="position:absolute;left:31%;top:69%;width:38%;height:15%;background:transparent;border:none;outline:none;box-shadow:none;cursor:pointer;text-indent:-9999px;overflow:hidden;"><?php esc_html_e( 'Buy Gravity Bookings', 'appointment-and-booking-for-gravity-forms' ); ?></a> 995 <button type="button" class="modal__close apbgf-staff-pro-modal-close" aria-label="<?php esc_attr_e( 'Close', 'appointment-and-booking-for-gravity-forms' ); ?>" style="position:absolute;top:0;right:0;width:15%;height:12%;background:transparent;border:none;outline:none;box-shadow:none;cursor:pointer;z-index:2;"></button> 996 </div> 997 </div> 998 </div> 999 <script type="text/javascript"> 1000 (function() { 1001 function apbgfStaffPopupReady(fn) { 1002 if (document.readyState === 'loading') { 1003 document.addEventListener('DOMContentLoaded', fn); 1004 } else { 1005 fn(); 1006 } 1007 } 1008 apbgfStaffPopupReady(function() { 1009 var modal = document.getElementById('apbgf-staff-pro-modal'); 1010 if (!modal) { return; } 1011 // Close when clicking backdrop (the .modal element itself) 1012 modal.addEventListener('click', function(e) { 1013 if (e.target === modal) { 1014 modal.classList.remove('apbgf-modal-show'); 1015 document.body.classList.remove('apbgf-modal-open'); 1016 } 1017 }); 1018 // Close button (modal__close is already handled by main admin script; this ensures body class is removed) 1019 var closeBtn = modal.querySelector('.apbgf-staff-pro-modal-close'); 1020 if (closeBtn) { 1021 closeBtn.addEventListener('click', function() { 1022 modal.classList.remove('apbgf-modal-show'); 1023 document.body.classList.remove('apbgf-modal-open'); 1024 }); 1025 } 1026 }); 1027 })(); 1028 </script> 1029 <?php 1030 } 984 1031 } 985 1032 -
appointment-and-booking-for-gravity-forms/trunk/includes/classes/class-apbgf-wizard.php
r3421805 r3481786 187 187 $default_term_id = is_array( $default_term ) ? $default_term['term_id'] : (int) $default_term; 188 188 189 $default_location = false; 190 if ( class_exists( 'APBGF_Location' ) ) { 191 $default_location = \APBGF_Location::all_location(); 192 } 193 if ( ! $default_location ) { 194 $existing = get_posts( array( 195 'post_type' => 'apbgf-location', 196 'meta_key' => '_apbgf_default_location', 197 'meta_value' => '1', 198 'numberposts' => 1, 199 ) ); 200 if ( ! empty( $existing ) ) { 201 $default_location = $existing[0]; 202 } else { 203 $location_id = wp_insert_post( array( 204 'post_title' => 'Default Location', 205 'post_content' => '', 206 'post_status' => 'publish', 207 'post_type' => 'apbgf-location', 208 ) ); 209 if ( $location_id && ! is_wp_error( $location_id ) ) { 210 update_post_meta( $location_id, '_apbgf_default_location', '1' ); 211 $default_location = get_post( $location_id ); 212 } 213 } 214 } 215 $default_location_id = $default_location ? (int) $default_location->ID : 0; 189 // Default location creation logic removed per user request. 190 $default_location_id = 0; 216 191 217 192 $created_service_ids = array(); -
appointment-and-booking-for-gravity-forms/trunk/includes/helper/apbgf-functions.php
r3409551 r3481786 410 410 } 411 411 412 function parse_appointment_time( $date, $time_str, $staff_timezone ) {412 function apbgf_parse_appointment_time( $date, $time_str, $staff_timezone ) { 413 413 $start_time_str = isset( $time_str[0] ) ? trim( $time_str[0] ) : ''; 414 414 $end_time_str = isset( $time_str[1] ) ? trim( $time_str[1] ) : ''; … … 427 427 428 428 return $event_time; 429 } 430 431 // Back-compat alias, but avoid fatals if another plugin already defines it. 432 if ( ! function_exists( 'parse_appointment_time' ) ) { 433 function parse_appointment_time( $date, $time_str, $staff_timezone ) { 434 return apbgf_parse_appointment_time( $date, $time_str, $staff_timezone ); 435 } 429 436 } 430 437 -
appointment-and-booking-for-gravity-forms/trunk/readme.txt
r3474451 r3481786 1 === Gravity Booking – Appointment Booking & Scheduling Addon for Gravity Forms ===1 === Gravity Forms Booking – Appointment Booking & Scheduling Addon for Gravity Forms === 2 2 Contributors: saadiqbal, wpexpertsio 3 3 Tags: gravity, appointments, booking, gravity forms, scheduling … … 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.2 7 Stable tag: 1. 27 Stable tag: 1.3 8 8 License: GPLv2 or later 9 9 License URI: [http://www.gnu.org/licenses/gpl-2.0.html](http://www.gnu.org/licenses/gpl-2.0.html) 10 10 11 Gravity Booking transforms Gravity Forms into a complete appointment booking and scheduling system. 11 Gravity Forms Booking is a Gravity Forms-powered appointment booking & scheduling plugin. It turns Gravity Forms into a complete appointment booking system with a calendar. It lets customers pick services, staff, locations, dates, and time slots directly from your forms. Setup is quick, appointments and bookings are smooth, and everything updates instantly without manual admin work. 12 This appointment booking plugin is built for service businesses that want automation but prefer the flexibility of Gravity Forms. 13 Start with essential appointment bookings features for free, then move towards advanced booking calendar sync, staff/location management, and export tools with Gravity Forms Booking Pro. 12 14 13 15 == Description == 16 14 17 [🚀 Gravity Booking Pro](https://gravitybooking.com/?utm_source=wp_org&utm_medium=read_me) | [📝 Documentation](https://gravitybooking.com/docs/gravity-forms-booking/?utm_source=wp_org&utm_medium=read_me) | [📞 Support](https://objectsws.atlassian.net/servicedesk/customer/portal/20/group/37/create/173) | [🧩 Features](https://gravitybooking.com/features/?utm_source=wp_org&utm_medium=read_me) 15 18 16 Gravity Booking – Appointment Booking & Scheduling Addon for Gravity Forms 17 18 Gravity Booking is a Gravity Forms-powered appointment & scheduling plugin. It turns Gravity Forms into a complete appointment scheduling system. It lets customers pick services, staff, locations, dates, and time slots directly from your forms. Setup is quick, booking is smooth, and updates instantly, without manual admin work. 19 20 This appointment scheduling plugin is built for service businesses that want automation but prefer the flexibility of Gravity Forms. 21 22 Start with essential scheduling features for free, then unlock advanced calendar sync, staff/location management, and export tools with Gravity Booking Pro. 23 24 == Fast, Flexible Appointment Booking & Scheduling Inside Gravity Forms == 25 26 With Gravity Forms Booking, you can create a booking form in minutes. Define services, set working hours, configure holidays, and your booking calendar is ready to publish. 27 28 Customers only see available time slots. Every booking is logged and manageable from your WordPress dashboard. 29 30 The calendar scheduling plugin keeps your existing Gravity Forms workflow. Use conditional logic, payment add-ons, notification settings, and your existing forms without rebuilding anything. 19 Fast, Flexible Appointment Booking & Scheduling Inside Gravity Forms 20 With Gravity Forms appointment booking, you can create a booking form in minutes. Define services, set working hours, configure holidays, and your calendar for bookings and appointments is ready to publish. 21 Customers only see available time slots. Every appointment and booking is logged and manageable from your WordPress dashboard. 22 The calendar appointment booking plugin keeps your existing Gravity Forms workflow. Use conditional logic, payment add-ons, notification settings, and your existing forms without rebuilding anything. 31 23 32 24 == Key Features of Gravity Forms Booking == 33 25 34 26 = Appointment Scheduling & Availability = 35 36 * Create booking rules for any service 37 * Set working hours, breaks, and holidays 38 * Control seat availability and prevent double bookings 27 * Create booking rules for any service 28 * Set working hours, breaks, and holidays 29 * Control seat availability and prevent double bookings 39 30 * Add buffer time before and after appointments 40 31 41 32 = Gravity Forms Native Integration = 42 43 * Use Gravity Forms fields, conditional logic, and validations 44 * Add booking calendars to any form 33 * Use Gravity Forms fields, conditional logic, and validations 34 * Add calendar booking fields to any form 45 35 * Works with existing GF payment gateways (Stripe, PayPal, Square, Mollie, etc.) 46 36 47 37 = Customer-Friendly Booking Flow = 48 49 * Mobile-responsive booking widget 50 * Real-time slot availability 38 * Mobile-responsive calendar booking widget 39 * Real-time slot availability for appointments 51 40 * Automatic confirmation emails via Gravity Forms notifications 52 41 53 42 = Administration = 43 * View and manage appointments and bookings inside WordPress 44 * Edit availability and service settings from a single dashboard 45 This calendar appointment booking plugin gives you the essential scheduling workflow, then lets Pro handle the advanced operations when your business grows. 54 46 55 * View and manage appointments inside WordPress 56 * Edit availability and service settings from a single dashboard 47 == Gravity Forms Booking Pro Features == 57 48 58 This calendar booking plugin gives you the essential scheduling workflow, then lets Pro handle the advanced operations when your business grows. 59 60 == Gravity Booking Pro Features == 61 62 Gravity Booking Pro offers full scheduling control, multi-staff operations, and calendar synchronization. Schedule appointments seamlessly with no hassle! 49 Gravity Booking Pro offers full scheduling control, multi-staff operations, and calendar synchronization for appointments and bookings. Schedule appointments seamlessly with no hassle! 63 50 64 51 = Staff & Location Management = 65 66 * Multiple staff with individual working hours and calendars 67 * Multiple locations to support multi-branch businesses 68 * Special days management for custom working hours on specific dates 52 * Multiple staff with individual working hours and booking calendars 53 * Multiple locations to support multi-branch businesses 54 * Special days management for custom working hours on specific dates 69 55 * Holidays & days off management to automatically block non-working periods 70 56 71 57 = Advanced Scheduling = 72 73 * Multiple slot booking for customers who need more than one slot at once 74 * Custom labels for location, service, and staff for full form personalization 58 * Multiple slot booking for customers who need more than one slot at once 59 * Custom labels for location, service, and staff for full form personalization 75 60 * Calendar color customization to color-code services or staff 76 61 77 62 = Calendar Integrations = 78 79 * Google Calendar integration for real-time sync and conflict avoidance 63 * Google Calendar integration for real-time sync and conflict avoidance 80 64 * Outlook Calendar integration for teams using Microsoft 365 81 65 82 66 = Data Tools & Exports = 83 84 * Export customers data 85 * Export appointments data 67 * Export customers data 68 * Export appointments data 86 69 * Export services data 87 88 Perfect for reporting, backups, or moving data into analytics tools. 70 Perfect for reporting, backups, or moving bookings and appointment data into analytics tools. 89 71 90 72 = Admin Productivity = 91 92 * Book appointment from backend so admins can schedule manually without using the front-end form 93 94 These features unlock the full business use case: teams, branches, advanced schedules, analytics, and calendar automation. 73 * Book appointments from backend so admins can schedule manually without using the front-end form 74 These features unlock the full business use case: teams, branches, advanced schedules, analytics, and calendar automation for appointment booking. 95 75 96 76 == Who Should Use Gravity Booking Pro == 97 77 98 Every service-based business with Gravity Forms installed can use Gravity Forms Booking. This scheduling booking plugin is designed for businesses that rely on predictable client scheduling: 99 100 * Health & wellness clinics, therapists, physiotherapists, nutritionists, wellness centers 101 * Salons, spas, barbershops, tattoo studios, makeup artists 102 * Coaches, tutors, language teachers, fitness trainers, academies 103 * Agencies, legal advisors, accountants, mentors, real estate professionals 104 * Electricians, mechanics, plumbers, and cleaning services 78 Every service-based business with Gravity Forms installed can use Gravity Forms appointment booking. This calendar appointment booking plugin is designed for businesses that rely on predictable client appointments and bookings: 79 * Health & wellness clinics, therapists, physiotherapists, nutritionists, wellness centers 80 * Salons, spas, barbershops, tattoo studios, makeup artists 81 * Coaches, tutors, language teachers, fitness trainers, academies 82 * Agencies, legal advisors, accountants, mentors, real estate professionals 83 * Electricians, mechanics, plumbers, and cleaning services 105 84 * Photography studios, meeting rooms, equipment rentals 106 107 If your business requires structured time booking, Gravity Booking fits. 85 If your business requires structured appointment booking with a calendar for bookings and appointments, Gravity Booking fits. 108 86 109 87 == Why Users Choose Gravity Booking == 110 111 * Uses the Gravity Forms ecosystem you already rely on 112 * Lets you automate scheduling without changing your form builder 113 * Offers clear, no-nonsense availability control 114 * Scales from single-professional setups to multi-staff organizations 88 * Uses the Gravity Forms ecosystem you already rely on 89 * Lets you automate appointments and bookings without changing your form builder 90 * Offers clear, no-nonsense calendar availability control 91 * Scales from single-professional setups to multi-staff organizations 115 92 * Pro unlocks calendar sync, detailed exports, and multi-location support when you need it 116 93 117 == Gravity Booking Integrations ==94 == Gravity Forms Booking Integrations == 118 95 119 Gravity Booking works natively with Gravity Forms and inherits Gravity Forms product add-ons: 120 121 * Stripe, PayPal, Square, Mollie 122 * Twilio (via Gravity Forms) 123 * GravityView, GravityFlow, and other GF extensions 124 * Email notifications 125 * Conditional logic workflows 96 Gravity Booking works natively with Gravity Forms and inherits Gravity Forms product add-ons: 97 * Stripe, PayPal, Square, Mollie 98 * Twilio (via Gravity Forms) 99 * GravityView, GravityFlow, and other GF extensions 100 * Email notifications 101 * Conditional logic workflows 126 102 * Webhooks and CRM integrations (via GF add-ons) 127 103 128 Gravity Booking Pro adds: 129 130 * Google Calendar 104 Gravity Forms Booking Pro adds: 105 * Google Calendar 131 106 * Outlook Calendar 132 107 133 == How to Get Started == 134 135 1. Install Gravity Booking and activate it 136 2. Create or edit a Gravity Form 137 3. Add the booking field and configure services, slots, and availability 138 4. Publish the form using a block or shortcode 139 5. Manage appointments from the Booking dashboard 108 == How to Get Started With Gravity Forms Booking == 109 1. Install Gravity Booking and activate it 110 2. Create or edit a Gravity Forms form 111 3. Add the appointment booking calendar field and configure services, slots, and availability 112 4. Publish the form using a block or shortcode 113 5. Manage appointments and bookings from the Booking dashboard 140 114 141 115 == Installation == … … 167 141 * Gravity Forms installed and active 168 142 * PHP 7.2 or higher 169 * SSL certificate recommended forpayment processing143 * SSL certificate is recommended for bookings payment processing 170 144 171 145 == Changelog == 146 147 = 1.3 = 148 * Code improvement 172 149 173 150 = 1.2 = -
appointment-and-booking-for-gravity-forms/trunk/views/admin/appointment-filters.php
r3409551 r3481786 31 31 ?> 32 32 33 <select name="apbgf_export_type" id="apbgf-export-type" class="disabled-block" >33 <select name="apbgf_export_type" id="apbgf-export-type" class="disabled-block" disabled> 34 34 <option value=""><?php echo esc_html__('Select Export Format', 'appointment-and-booking-for-gravity-forms'); ?></option> 35 35 <option value="csv"><?php echo esc_html__('CSV', 'appointment-and-booking-for-gravity-forms'); ?></option> 36 36 </select> 37 37 38 <input type="submit" class="disabled-block" id="apbgf-export" name="apbgf-export-submit" value="<?php echo esc_html__('Export', 'appointment-and-booking-for-gravity-forms'); ?>" />38 <input type="submit" class="disabled-block" id="apbgf-export" name="apbgf-export-submit" disabled value="<?php echo esc_html__('Export', 'appointment-and-booking-for-gravity-forms'); ?>" /> 39 39 <?php 40 40 $nonce = wp_create_nonce('apbgf_export_nonce_action'); -
appointment-and-booking-for-gravity-forms/trunk/views/admin/block_data_reports.php
r3409551 r3481786 32 32 <span class="reports-tab-contents"> 33 33 <h6><?php echo esc_html__('Total Customers', 'appointment-and-booking-for-gravity-forms'); ?></h6> 34 <h3><?php echo esc_html( wp_count_posts('apbgf-customer')->publish ); ?></h3>34 <h3><?php echo esc_html( wp_count_posts('apbgf-customer')->publish ?? 0 ); ?></h3> 35 35 </span> 36 36 </li> … … 47 47 <span class="reports-tab-contents"> 48 48 <h6><?php echo esc_html__('Total Services', 'appointment-and-booking-for-gravity-forms'); ?></h6> 49 <h3><?php echo esc_html( wp_count_posts('apbgf-service')->publish ); ?></h3>49 <h3><?php echo esc_html( wp_count_posts('apbgf-service')->publish ?? 0 ); ?></h3> 50 50 </span> 51 51 </li> -
appointment-and-booking-for-gravity-forms/trunk/views/admin/email-templates.php
r3409551 r3481786 80 80 ?> 81 81 82 <?php if ( $email_template === 'pro' ) : ?> 83 <div class="apbgf-pro-trigger" data-apbgf-pro-modal="apbgf-pro-modal"> 84 <?php endif; ?> 85 82 86 <h4 class='apbgf_section-title <?php echo esc_attr($class); ?>' ><?php echo esc_html($template['title']); ?> <?php echo esc_html($template['title']); ?> <span class=" <?php echo !empty($pro_label) ? esc_attr('pro-email-template-label') :''; ?>"> <?php echo esc_attr($pro_label); ?> </span></h4> 83 87 <div> … … 146 150 </div> 147 151 </div> 152 153 <?php if ( $email_template === 'pro' ) : ?> 154 </div> 155 <?php endif; ?> 148 156 <?php 149 157 } -
appointment-and-booking-for-gravity-forms/trunk/views/admin/modal/staff-modal.php
r3409551 r3481786 138 138 <div class="form-col-full" id="apbgf-lead-time-container"> 139 139 <label for="apbgf-lead-time"><?php echo esc_html__('Lead Time', 'appointment-and-booking-for-gravity-forms'); ?></label> 140 <input type="number" id="apbgf-lead-time" name="apbgf-lead-time" data-general="<?php echo esc_attr($general_settings['gbf_lead_time']); ?>" placeholder="<?php echo esc_attr($general_settings['gbf_lead_time']); ?>" >140 <input type="number" id="apbgf-lead-time" name="apbgf-lead-time" data-general="<?php echo esc_attr($general_settings['gbf_lead_time']); ?>" placeholder="<?php echo esc_attr($general_settings['gbf_lead_time']); ?>" class="apbgf-lead-time-disabled" disabled > 141 141 <small><?php esc_html_e('Each Staff Lead Time. Ex: 180 = 3 hours. Default is set as general settings.', 'appointment-and-booking-for-gravity-forms'); ?></small> 142 142 </div> -
appointment-and-booking-for-gravity-forms/trunk/views/admin/setting.php
r3421805 r3481786 146 146 </div> 147 147 148 <?php 149 // Global Pro popup modal using the shared SVG artwork in this plugin. 150 $apbgf_pro_popup_img = APBGF_IMAGE_URL . 'ProPopup.svg'; 151 $apbgf_pricing_url = 'https://gravitybooking.com/pricing/?utm_source=plugin&utm_medium=settings'; 152 if ( $apbgf_pro_popup_img ) : 153 ?> 154 <div id="apbgf-pro-modal" class="apbgf-pro-modal" style="display:none;"> 155 <div class="apbgf-pro-modal-backdrop" style="position:fixed;inset:0;background:rgba(0,0,0,0.5);z-index:100000;"></div> 156 <div class="apbgf-pro-modal-inner" style="position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:100001;max-width:640px;width:100%;overflow:hidden;border-radius:8px;"> 157 <div class="apbgf-pro-modal-content" style="position:relative;"> 158 <img src="<?php echo esc_url( $apbgf_pro_popup_img ); ?>" alt="<?php esc_attr_e( 'Upgrade to Pro', 'appointment-and-booking-for-gravity-forms' ); ?>" style="display:block;width:100%;height:auto;" /> 159 <a href="<?php echo esc_url( $apbgf_pricing_url ); ?>" target="_blank" rel="noopener noreferrer" 160 aria-label="<?php esc_attr_e( 'Buy Gravity Bookings', 'appointment-and-booking-for-gravity-forms' ); ?>" 161 style="position:absolute;left:31%;top:69%;width:38%;height:15%;background:transparent;border:none;outline:none;box-shadow:none;cursor:pointer;text-indent:-9999px;overflow:hidden;"> 162 <?php esc_html_e( 'Buy Gravity Bookings', 'appointment-and-booking-for-gravity-forms' ); ?> 163 </a> 164 <button type="button" class="apbgf-pro-modal-close-area" aria-label="<?php esc_attr_e( 'Close', 'appointment-and-booking-for-gravity-forms' ); ?>" style="position:absolute;top:0;right:0;width:15%;height:12%;background:transparent;border:none;outline:none;box-shadow:none;cursor:pointer;z-index:2;"></button> 165 </div> 166 </div> 167 </div> 168 <script type="text/javascript"> 169 (function() { 170 function apbgfReady(fn) { 171 if (document.readyState === 'loading') { 172 document.addEventListener('DOMContentLoaded', fn); 173 } else { 174 fn(); 175 } 176 } 177 apbgfReady(function() { 178 var modal = document.getElementById('apbgf-pro-modal'); 179 if (!modal) { return; } 180 var closeArea = modal.querySelector('.apbgf-pro-modal-close-area'); 181 var backdrop = modal.querySelector('.apbgf-pro-modal-backdrop'); 182 183 function openModal(e) { 184 if (e) { 185 e.preventDefault(); 186 if (e.stopImmediatePropagation) { 187 e.stopImmediatePropagation(); 188 } 189 e.stopPropagation(); 190 } 191 modal.style.display = 'block'; 192 } 193 194 function closeModal(e) { 195 if (e) { 196 e.preventDefault(); 197 } 198 modal.style.display = 'none'; 199 } 200 201 // Attach popup to PRO cards on the main settings grid. 202 var proCardIds = [ 203 'gf_booking_cardtwo', // Display Settings (PRO) 204 'gf_bookings_appointments', // Labels (PRO) 205 'gf_booking_google_calender', // Google Calendar (PRO) 206 'gf_booking_outlook_calender' // Office 365 Calendar (PRO) 207 ]; 208 proCardIds.forEach(function(id) { 209 var el = document.getElementById(id); 210 if (!el) { return; } 211 // Use capture so we intercept before sidebar handlers. 212 el.addEventListener('click', openModal, true); 213 }); 214 215 // Attach popup to key PRO-only controls inside sidebars. 216 var triggerInputs = [ 217 document.getElementById('custom_slots_multiple_enabled'), 218 document.getElementById('apbgf_gcal_enabled'), 219 document.getElementById('apbgf_gcal_two_way_sync_enabled'), 220 document.getElementById('apbgf_ocal_enabled'), 221 document.getElementById('gbf_lead_time'), 222 document.getElementById('lead-time-pro-feature') 223 ]; 224 triggerInputs.forEach(function(input) { 225 if (!input) { return; } 226 input.addEventListener('click', openModal); 227 }); 228 229 if (closeArea) { 230 closeArea.addEventListener('click', closeModal); 231 } 232 if (backdrop) { 233 backdrop.addEventListener('click', closeModal); 234 } 235 }); 236 })(); 237 </script> 238 <?php 239 endif; 240 ?> 241 148 242 <div class="gf_booking_sidebar"> 149 243 <span class="close_icon"></span> … … 194 288 195 289 <div class="apbgf-field-wrapper"> 196 <label for="gbf_lead_time"><?php echo esc_html__('Lead Time (minutes)', 'appointment-and-booking-for-gravity-forms'); ?></label> 197 <input type="number" min="1" name="gbf_lead_time" id="gbf_lead_time" value="<?php echo esc_attr($gbf_lead_time); ?>" /> 290 <label class="apbgf-pro-feature-heading" for="gbf_lead_time"><?php echo esc_html__('Lead Time (minutes)', 'appointment-and-booking-for-gravity-forms'); ?></label> 291 <div id="lead-time-pro-feature"> 292 <input type="number" min="1" name="gbf_lead_time" id="gbf_lead_time" value="<?php echo esc_attr($gbf_lead_time); ?>" readonly style="cursor: pointer;" /> 293 </div> 198 294 <small><?php esc_html_e('Time slot lead time. Ex: 180 = 3 hours. Default is 30 mins', 'appointment-and-booking-for-gravity-forms'); ?></small> 199 295 </div>
Note: See TracChangeset
for help on using the changeset viewer.