first_name );
$last = trim( $user->last_name );
if ( $first || $last ) {
return trim( $first . ' ' . $last );
}
// Fallbacks if no first/last name
if ( $user->display_name ) {
return $user->display_name;
}
if ( $user->user_login ) {
return $user->user_login;
}
if ( $user->user_email ) {
return $user->user_email;
}
return $fallback;
}
function get_date_format() {
return apply_filters('pickuppt_get_date_format', 'Y-m-d');
}
function get_time_format() {
return apply_filters('pickuppt_get_time_format', 'h:i A');
}
function get_datetime_format() {
return apply_filters('pickuppt_get_datetime_format', 'Y-m-d h:i A');
}
# register settings
function pickuppt_register_options_cb() {
register_setting('pickuppt_general_settings', 'pickuppt_general_settings_group',
array(
'sanitize_callback' => array($this, 'pickuppt_sanitize_general_settings'),
)
);
do_action('pickuppt_register_options_cb');
}
# sanitize settings
function pickuppt_sanitize_general_settings( $input ) {
if ( ! is_array( $input ) ) {
return array();
}
$output = array();
/**
* Payment settings
*/
$output['payment_link'] = isset( $input['payment_link'] )? esc_url_raw( $input['payment_link'] ): '';
$output['qr_code_link'] = isset( $input['qr_code_link'] ) ? esc_url_raw( $input['qr_code_link'] ) : '';
/*
* General settings.
*/
$output['logo_url'] = isset( $input['logo_url'] ) ? esc_url_raw( $input['logo_url'] ) : '';
$output['auto_generate_title'] = ! empty( $input['auto_generate_title'] ) ? 'on' : '';
$output['is_alpha_numeric'] = ! empty( $input['is_alpha_numeric'] ) ? 'on' : '';
$output['title_length'] = isset( $input['title_length'] ) ? absint( $input['title_length'] ) : 0;
$output['title_prefix'] = isset( $input['title_prefix'] )? sanitize_text_field( $input['title_prefix'] ): '';
$output['title_suffix'] = isset( $input['title_suffix'] )? sanitize_text_field( $input['title_suffix'] ): '';
$output['items'] = isset( $input['items'] )? pickuppt_sanitize_csv( $input['items'] ): '';
$output['statuses'] = isset( $input['statuses'] )? pickuppt_sanitize_csv( $input['statuses'] ): '';
/*
* Colors.
*/
$output['theme_color'] = isset( $input['theme_color'] ) ? sanitize_hex_color( $input['theme_color'] ) : '';
foreach ( pickuppt_statuses() as $status ) {
$slugified_status = pickuppt_slugify($status) . '_color';
$output[ $slugified_status ] = isset( $input[ $slugified_status ] ) ? sanitize_hex_color( $input[ $slugified_status ] ) : '';
}
/*
* Status settings.
*/
$status_fields = array(
'default_status',
'rescheduled_status',
'driver_assigned_status',
'picked_up_status',
'completed_status',
'cancelled_status',
'flagged_status',
'awaiting_reassignment_status',
'pending_payment_status',
'payment_confirmed_status'
);
foreach ( $status_fields as $field ) {
$output[ $field ] = isset( $input[ $field ] ) ? sanitize_text_field( $input[ $field ] ) : '';
}
/*
* Other settings.
*/
$output['weight_unit'] = isset( $input['weight_unit'] )? sanitize_text_field( $input['weight_unit'] ): '';
$output['time_slot_interval'] = isset( $input['time_slot_interval'] )? absint( $input['time_slot_interval'] ): 0;
$output['max_time_slot_cap'] = isset( $input['max_time_slot_cap'] ) ? absint( $input['max_time_slot_cap'] ): 0;
$output['pickuppt_sender_email'] = isset( $input['pickuppt_sender_email'] )? sanitize_email( $input['pickuppt_sender_email'] ): '';
$output['gmaps_api_key'] = isset( $input['gmaps_api_key'] )? sanitize_text_field( $input['gmaps_api_key'] ): '';
/*
* Destination structure.
*/
$output['custom_destination'] = ! empty( $input['custom_destination'] ) ? 'on' : '';
$output['warehouses'] = array();
if ( isset( $input['warehouses'] ) && is_array( $input['warehouses'] ) ) {
foreach ( $input['warehouses'] as $holiday ) {
if ( ! is_array( $holiday ) ) {
continue;
}
$output['warehouses'][] = array(
'warehouse_name' => isset( $holiday['warehouse_name'] )? sanitize_text_field( $holiday['warehouse_name'] ): '',
'warehouse_address' => isset( $holiday['warehouse_address'] )? sanitize_text_field( $holiday['warehouse_address'] ): '',
);
}
}
/*
* Day offs.
*/
$output['day_offs'] = array();
if ( isset( $input['day_offs'] ) && is_array( $input['day_offs'] ) ) {
foreach ( $input['day_offs'] as $day ) {
$output['day_offs'][] = absint( $day );
}
$output['day_offs'] = array_values(
array_unique( $output['day_offs'] )
);
}
/*
* Holidays.
*/
$output['holidays'] = array();
if ( isset( $input['holidays'] ) && is_array( $input['holidays'] ) ) {
foreach ( $input['holidays'] as $holiday ) {
if ( ! is_array( $holiday ) ) {
continue;
}
$output['holidays'][] = array(
'holiday_name' => isset( $holiday['holiday_name'] )? sanitize_text_field( $holiday['holiday_name'] ): '',
'holiday_date' => isset( $holiday['holiday_date'] )? sanitize_text_field( $holiday['holiday_date'] ): '',
);
}
}
/*
* Customer email settings.
*/
$output['email_subject'] = isset( $input['email_subject'] ) ? sanitize_text_field( $input['email_subject'] ) : '';
$output['email_from'] = isset( $input['email_from'] ) ? sanitize_email( $input['email_from'] ) : '';
$output['email_to'] = isset( $input['email_to'] ) ? pickuppt_sanitize_email_placeholders( $input['email_to'] ) : '';
$output['email_bc'] = isset( $input['email_bc'] ) ? pickuppt_sanitize_email_placeholders( $input['email_bc'] ) : '';
$output['email_cc'] = isset( $input['email_cc'] ) ? pickuppt_sanitize_email_placeholders( $input['email_cc'] ) : '';
$output['email_body'] = isset( $input['email_body'] ) ? wp_kses_post( $input['email_body'] ) : '';
/*
* Admin email settings.
*/
$output['admin_email_subject'] = isset( $input['admin_email_subject'] ) ? sanitize_text_field( $input['admin_email_subject'] ) : '';
$output['admin_email_from'] = isset( $input['admin_email_from'] ) ? sanitize_email( $input['admin_email_from'] ) : '';
$output['admin_email_to'] = isset( $input['admin_email_to'] ) ? pickuppt_sanitize_email_placeholders( $input['admin_email_to'] ) : '';
$output['admin_email_bc'] = isset( $input['admin_email_bc'] ) ? pickuppt_sanitize_email_placeholders( $input['admin_email_bc'] ) : '';
$output['admin_email_cc'] = isset( $input['admin_email_cc'] ) ? pickuppt_sanitize_email_placeholders( $input['admin_email_cc'] ) : '';
$output['admin_email_body'] = isset( $input['admin_email_body'] ) ? wp_kses_post( $input['admin_email_body'] ) : '';
/*
* Appointment status email settings.
*/
$output['appt_email_subject'] = isset( $input['appt_email_subject'] ) ? sanitize_text_field( $input['appt_email_subject'] ) : '';
$output['appt_email_from'] = isset( $input['appt_email_from'] ) ? sanitize_email( $input['appt_email_from'] ) : '';
$output['appt_email_to'] = isset( $input['appt_email_to'] ) ? pickuppt_sanitize_email_placeholders( $input['appt_email_to'] ) : '';
$output['appt_email_bc'] = isset( $input['appt_email_bc'] ) ? pickuppt_sanitize_email_placeholders( $input['appt_email_bc'] ) : '';
$output['appt_email_cc'] = isset( $input['appt_email_cc'] ) ? pickuppt_sanitize_email_placeholders( $input['appt_email_cc'] ) : '';
$output['appt_email_body'] = isset( $input['appt_email_body'] ) ? wp_kses_post( $input['appt_email_body'] ) : '';
$hooked_output = apply_filters( 'pickuppt_settings_sanitized_output', $output, $input );
return $hooked_output;
}
/**
* Get and sanitize URL parameters safely for admin and front-end views.
*/
public function pickuppt_get_all_url_param_values() {
// Admin parameters: Ensure user is in admin and has proper permissions
if ( is_admin() ) {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$this->url_param_post_type = isset( $_GET['post_type'] ) ? sanitize_text_field( wp_unslash( $_GET['post_type'] ) ) : '';
$this->url_param_page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
$this->url_param_pu_assigned_driver_id = isset( $_GET['pu_assigned_driver_id'] ) ? absint( wp_unslash( $_GET['pu_assigned_driver_id'] ) ) : 0;
$this->url_param_action = isset( $_GET['action'] ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : '';
$this->url_param_post = isset( $_GET['post'] ) ? absint( wp_unslash( $_GET['post'] ) ) : 0;
}
// Front-end / public parameters (accessible to guests or users)
if ( isset( $_GET['pickuppt'] ) ) {
$this->url_param_pickuppt = sanitize_text_field( wp_unslash( $_GET['pickuppt'] ) );
} else {
$this->url_param_pickuppt = '';
}
}
# register custom post type
function pickuppt_register_cpt() {
$labels = array(
'name' => _x('All Appointments', 'Appointment', 'pickuppointment'),
'singular_name' => _x('Appointment', 'Appointment', 'pickuppointment'),
'menu_name' => esc_html__('PickUppointments', 'pickuppointment'),
'all_items' => esc_html__('All Appointments', 'pickuppointment'),
'view_item' => esc_html__('View Appointments', 'pickuppointment'),
'add_new_item' => esc_html__('Add New', 'pickuppointment'),
'add_new' => esc_html__('Add Appointment', 'pickuppointment'),
'edit_item' => esc_html__('Edit Appointment', 'pickuppointment'),
'update_item' => esc_html__('Update Appointment', 'pickuppointment'),
'search_items' => esc_html__('Search', 'pickuppointment'),
'not_found' => esc_html__('No appointments found.', 'pickuppointment'),
'not_found_in_trash' => esc_html__('No appointments found in trash.', 'pickuppointment')
);
$supports = array( 'title', 'author', 'thumbnail', 'revisions' );
$args = array(
'label' => esc_html__('Appointments', 'pickuppointment'),
'description' => esc_html__('Appointments', 'pickuppointment'),
'labels' => $labels,
'supports' => $supports,
'taxonomies' => array( PICKUPPOINTMENT_POST_TYPE, 'post_tag' ),
'menu_icon' => 'dashicons-text-page',
'hierarchical' => true,
'public' => false,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'can_export' => true,
'has_archive' => false,
'exclude_from_search' => true,
'publicly_queryable' => false,
'capability_type' => 'post'
);
register_post_type(PICKUPPOINTMENT_POST_TYPE, $args);
$cat_labels = array(
'name' => _x('Categories', 'Category', 'pickuppointment'),
'singular_name' => _x('Category', 'Category', 'pickuppointment'),
'search_items' => esc_html__('Search Category', 'pickuppointment'),
'all_items' => esc_html__('All Categories', 'pickuppointment'),
'parent_item' => esc_html__('Parent Category', 'pickuppointment'),
'parent_item_colon' => esc_html__('Parent Category:', 'pickuppointment'),
'edit_item' => esc_html__('Edit Category', 'pickuppointment'),
'update_item' => esc_html__('Update Category', 'pickuppointment'),
'add_new_item' => esc_html__('Add New', 'pickuppointment'),
'new_item_name' => esc_html__('New Category Name', 'pickuppointment'),
'menu_name' => esc_html__('Category', 'pickuppointment')
);
$cat_args = array(
'hierarchical' => true,
'labels' => $cat_labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true
);
register_taxonomy('pickuppointment_cat', array( PICKUPPOINTMENT_POST_TYPE ), $cat_args);
// add a new role
foreach(pickuppt_system_roles() as $role_slug => $role_name) {
if(!get_role($role_slug)) {
add_role($role_slug, $role_name, array());
}
}
}
function pickuppt_admin_menu_page_cb() {
$parent = 'edit.php?post_type=' . PICKUPPOINTMENT_POST_TYPE;
add_submenu_page(
$parent,
__( 'Calendar', 'pickuppointment' ),
__( 'Calendar', 'pickuppointment' ),
'manage_options',
'pickuppointments-page',
array( $this, 'pickuppt_admin_dashboard_page_cb' )
);
add_submenu_page(
$parent,
__( 'Settings', 'pickuppointment' ),
__( 'Settings', 'pickuppointment' ),
'manage_options',
'pickuppointment-settings-page',
array( $this, 'pickuppt_admin_settings_page_cb' )
);
}
function pickuppt_admin_dashboard_page_cb() {
?>
url_param_page;
$pickuppt = $this->url_param_pickuppt;
if($page === 'pickuppointments-page' || $pickuppt === 'calendar') {
require_once(pickuppt_include_template('calendar-script.tpl'));
}
}
function pickuppt_admin_wp_enqueue_scripts_cb() {
global $post;
if(!$post) {
return;
}
$is_pickuppointment_public_form_present = false;
if ( $post && has_shortcode( $post->post_content, 'pickuppointment_form_public' ) ) {
$is_pickuppointment_public_form_present = true;
}
$dynamic_version = PICKUPPOINTMENT_VERSION . time();
$page = $this->url_param_page;
$pickuppt = $this->url_param_pickuppt;
if(in_array($page, pickuppt_page_slugs_for_assets()) || $pickuppt === 'calendar') {
wp_enqueue_style('pickuppt-bootstrap-css', PICKUPPOINTMENT_URL . 'lib/bootstrap.min.css', array(), PICKUPPOINTMENT_VERSION);
if( $page === 'pickuppointments-page' || $pickuppt === 'calendar' ) {
wp_enqueue_script('pickuppt-popper-min-js', PICKUPPOINTMENT_URL . 'lib/popper.min.js', array('jquery'), PICKUPPOINTMENT_VERSION, true);
wp_enqueue_script('pickuppt-fullcalendar-scripts', PICKUPPOINTMENT_URL . 'lib/fullcalendar-6.1.17/dist/index.global.min.js', array('jquery'), PICKUPPOINTMENT_VERSION, true);
wp_enqueue_script('pickuppt-calendar-scripts', PICKUPPOINTMENT_URL . 'admin/assets/js/calendar-scripts.js', array('jquery'), $dynamic_version, true);
$calendar_scripts_localization = array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'puAllAppointments' => pickuppt_all_appointments(true),
'puCanUpdate' => pickuppt_can_update() ? true : false,
'pickupptGetTransInfoNonce' => wp_create_nonce('pickupptGetTransInfoNonce'),
'pickupptUpdateTransNonce' => wp_create_nonce('pickupptUpdateTransNonce'),
'pickupptGetCurrentMonthYearApptsNonce' => wp_create_nonce('pickupptGetCurrentMonthYearApptsNonce')
);
wp_localize_script('pickuppt-calendar-scripts', 'pickupptCalendarScripts', $calendar_scripts_localization);
}
}
$calendar_day_offs = pickuppt_get_general_setting('day_offs') ?: array();
$calendar_holidays = pickuppt_get_general_setting('holidays') ?: array();
$calendar_holiday_dates = array_column( $calendar_holidays, 'holiday_date' );
$calendar_day_offs_json = json_encode( $calendar_day_offs );
$calendar_holiday_dates_json = json_encode( $calendar_holiday_dates );
wp_enqueue_script('pickuppt-repeater-js', PICKUPPOINTMENT_URL . 'lib/repeater.min.js', array('jquery'), PICKUPPOINTMENT_VERSION, true);
if ($post && has_shortcode($post->post_content, 'pickuppointment_form_public')) {
wp_enqueue_style('pickuppt-timepicker-css', PICKUPPOINTMENT_URL . 'lib/timepicker/jquery.timepicker.min.css', array(), PICKUPPOINTMENT_VERSION);
wp_enqueue_style('pickuppt-public-form-css', PICKUPPOINTMENT_URL . 'admin/assets/css/public-form-styles.css', array(), $dynamic_version);
wp_enqueue_script('pickuppt-timepicker-js', PICKUPPOINTMENT_URL . 'lib/timepicker/jquery.timepicker.min.js', array('jquery'), PICKUPPOINTMENT_VERSION, true);
wp_enqueue_script('pickuppt-popper-min-js', PICKUPPOINTMENT_URL . 'lib/popper.min.js', array('jquery'), PICKUPPOINTMENT_VERSION, true);
wp_enqueue_script('pickuppt-fullcalendar-scripts', PICKUPPOINTMENT_URL . 'lib/fullcalendar-6.1.17/dist/index.global.min.js', array('jquery'), PICKUPPOINTMENT_VERSION, true);
wp_enqueue_script('pickuppt-public-form-js', PICKUPPOINTMENT_URL . 'admin/assets/js/public-form-scripts.js', array('jquery'), $dynamic_version, true);
$localization = array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'calendarDayoffsJson' => $calendar_day_offs_json,
'calendarHolidayDatesJson' => $calendar_holiday_dates_json,
'pickupptPublicFormNonce' => wp_create_nonce('pu_submit_public_appointment'),
'pickupptPublicFormTimeslotInterval' => pickuppt_time_slot_interval()
);
wp_localize_script('pickuppt-public-form-js', 'pickupptPublicForm', $localization);
}
/**
* global styles
*/
wp_enqueue_style('pickuppointment-global-styles', PICKUPPOINTMENT_URL . 'admin/assets/css/global-styles.css', array(), $dynamic_version);
/**
* calendar styles
*/
wp_register_style( 'pickuppointment-calendary-styles', false, array(), PICKUPPOINTMENT_VERSION );
wp_enqueue_style( 'pickuppointment-calendary-styles' );
$base_color = pickuppt_get_general_setting('theme_color') ?: '#0073aa';
$dynamic_css = '
/* ===============================
FullCalendar Custom Styling
Dynamic Theme Color
Scoped to #pickuppt-calendar
=============================== */
#pickuppt-calendar {
font-family: "Poppins", "Segoe UI", Arial, sans-serif;
background: ' . esc_html(pickuppt_color_shade_generator($base_color, 90)) . ';
border: 1px solid ' . esc_html(pickuppt_color_shade_generator($base_color, 55)) . ';
border-radius: 8px;
font-size: 0.9rem !important;
}
/* Header Toolbar */
#pickuppt-calendar .fc-toolbar {
background: ' . esc_html(pickuppt_color_shade_generator($base_color, 70)) . ';
border-bottom: 1px solid ' . esc_html(pickuppt_color_shade_generator($base_color, 55)) . ';
border-radius: 8px 8px 0 0;
padding: 0.5rem 1rem;
}
#pickuppt-calendar .fc-toolbar-title {
font-size: 1.25rem;
font-weight: 600;
color: ' . esc_html(pickuppt_color_shade_generator($base_color, -35)) . ';
}
/* Buttons */
#pickuppt-calendar .fc-button {
background: ' . esc_html(pickuppt_color_shade_generator($base_color, 0)) . ';
color: #fff;
border: none;
border-radius: 4px;
font-size: 0.9rem;
transition: background 0.2s ease, transform 0.1s ease;
}
#pickuppt-calendar .fc-button:hover {
background: ' . esc_html(pickuppt_color_shade_generator($base_color, -20)) . ';
transform: translateY(-1px);
}
#pickuppt-calendar .fc-button-primary:not(:disabled).fc-button-active,
#pickuppt-calendar .fc-button-primary:not(:disabled):active {
background-color: ' . esc_html(pickuppt_color_shade_generator($base_color, -35)) . ';
}
/* Calendar Grid */
#pickuppt-calendar .fc-daygrid-day {
border: 1px style ' . esc_html(pickuppt_color_shade_generator($base_color, 65)) . ';
background-color: ' . esc_html(pickuppt_color_shade_generator($base_color, 90)) . ';
transition: background 0.15s ease;
}
#pickuppt-calendar .fc-daygrid-day:hover {
background-color: ' . esc_html(pickuppt_color_shade_generator($base_color, 75)) . ';
}
#pickuppt-calendar .fc-daygrid-day.fc-day-today {
background: ' . esc_html(pickuppt_color_shade_generator($base_color, 45)) . ';
border-color: ' . esc_html(pickuppt_color_shade_generator($base_color, 0)) . ';
}
/* Day Numbers */
#pickuppt-calendar .fc-daygrid-day-number {
font-weight: 500;
color: ' . esc_html(pickuppt_color_shade_generator($base_color, -35)) . ';
}
/* Events */
#pickuppt-calendar .fc-event {
background-color: ' . esc_html(pickuppt_color_shade_generator($base_color, 0)) . ';
border: none;
color: #fff;
border-radius: 4px;
font-size: 0.85rem;
transition: background 0.2s ease;
}
#pickuppt-calendar .fc-event:hover {
background-color: ' . esc_html(pickuppt_color_shade_generator($base_color, -20)) . ';
}
/* Scrollbar & List View */
#pickuppt-calendar .fc-scroller {
scrollbar-width: thin;
scrollbar-color: ' . esc_html(pickuppt_color_shade_generator($base_color, 0)) . ' ' . esc_html(pickuppt_color_shade_generator($base_color, 70)) . ';
}
#pickuppt-calendar .fc-scroller::-webkit-scrollbar {
width: 6px;
}
#pickuppt-calendar .fc-scroller::-webkit-scrollbar-thumb {
background: ' . esc_html(pickuppt_color_shade_generator($base_color, 0)) . ';
border-radius: 3px;
}
#pickuppt-calendar .fc-list-event {
border-bottom: 1px solid ' . esc_html(pickuppt_color_shade_generator($base_color, 65)) . ';
}
#pickuppt-calendar .fc-list-event:hover {
background-color: ' . esc_html(pickuppt_color_shade_generator($base_color, 75)) . ';
}
.tooltip-inner {
text-align: left !important;
}
/* Responsive */
@media (max-width: 768px) {
#pickuppt-calendar .fc-toolbar {
flex-wrap: wrap;
text-align: center;
}
#pickuppt-calendar .fc-toolbar-title {
width: 100%;
margin-bottom: 0.5rem;
}
}';
wp_add_inline_style( 'pickuppointment-calendary-styles', $dynamic_css );
/**
* dynamic timeslot script
*/
wp_enqueue_script('pickuppointment-dynamic-timeslot-scripts', PICKUPPOINTMENT_URL . 'admin/assets/js/dynamic-timeslot.js', array('jquery'), $dynamic_version, true);
$pickuppointment_dynamic_timeslot_localization = array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'timeSlotInterval' => pickuppt_time_slot_interval(),
'pickupptDynamicTimeslotNonce' => wp_create_nonce( 'pickupptDynamicTimeslotNonce' )
);
wp_localize_script('pickuppointment-dynamic-timeslot-scripts', 'pickuppointmentDynamicTimeslotObj', $pickuppointment_dynamic_timeslot_localization);
/**
* charges script
*/
wp_enqueue_script('pickuppointment-charges-scripts', PICKUPPOINTMENT_URL . 'admin/assets/js/charges-scripts.js', array('jquery'), $dynamic_version, true);
$pickuppointment_charges_localization = array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'deleteItemWarning' => __( 'Are you sure you want to delete this item?', 'pickuppointment' ),
'pickupptSaveOrderChargesNonce' => wp_create_nonce( 'pickupptSaveOrderChargesNonce' ),
'pickupptGetOrderChargesNonce' => wp_create_nonce( 'pickupptGetOrderChargesNonce' )
);
wp_localize_script('pickuppointment-charges-scripts', 'pickuppointmentChargesObj', $pickuppointment_charges_localization);
/**
* google maps api script
*/
$gmaps_api_key = pickuppt_get_general_setting('gmaps_api_key');
if( !empty( $gmaps_api_key ) ) {
$pickuppt_can_load_gmaps_api = false;
if( $this->url_param_page === 'pickuppointment-settings-page' ) {
$pickuppt_can_load_gmaps_api = true;
}
if( 'pickuppointment' == $this->url_param_post_type ) {
$pickuppt_can_load_gmaps_api = true;
}
global $post;
if ( is_singular() && is_a( $post, 'WP_Post' ) ) {
if ( has_shortcode( $post->post_content, 'pickuppointment_form_public' ) ) {
$pickuppt_can_load_gmaps_api = true;
}
$page_template = get_post_meta($post->ID, '_wp_page_template', true);
if('pu-hub-template.php' === $page_template && is_user_logged_in()) {
$pickuppt_can_load_gmaps_api = true;
}
}
$pickuppt_can_load_gmaps_api = apply_filters( 'pickuppt_can_load_gmaps_api', $pickuppt_can_load_gmaps_api );
if( $pickuppt_can_load_gmaps_api ) {
$maps_url = add_query_arg(
array(
'key' => $gmaps_api_key,
'libraries' => 'places',
'callback' => 'pickuppointmentInitAutocomplete',
),
'https://maps.googleapis.com/maps/api/js'
);
wp_register_script( 'pickuppointment-google-maps', $maps_url, array('jquery'), PICKUPPOINTMENT_VERSION, array( 'strategy' => 'async', 'in_footer' => true ) );
$inline_script = '
function pickuppointmentInitAutocomplete() {
jQuery(function($) {
$(".pickuppointment-autocomplete").each(function() {
const autocomplete = new google.maps.places.Autocomplete(
this,
{
fields: ["address_components", "formatted_address"]
}
);
});
});
}';
wp_add_inline_script( 'pickuppointment-google-maps', $inline_script, 'before' );
wp_enqueue_script( 'pickuppointment-google-maps' );
}
}
}
# add meta boxes
function pickuppt_add_mtb() {
$action = $this->url_param_action;
add_meta_box(
'pickuppt_add_mtb_customer_info',
pickuppt_customer_information_label(),
array($this, 'pickuppt_add_mtb_customer_info'),
PICKUPPOINTMENT_POST_TYPE,
'normal'
);
add_meta_box(
'pickuppt_add_mtb_item_info',
pickuppt_item_information_label(),
array($this, 'pickuppt_add_mtb_item_info'),
PICKUPPOINTMENT_POST_TYPE,
'normal'
);
add_meta_box(
'pickuppt_add_mtb_pickup_info',
pickuppt_pickup_information_label(),
array($this, 'pickuppt_add_mtb_pickup_info'),
PICKUPPOINTMENT_POST_TYPE,
'normal'
);
if($action === 'edit') {
add_meta_box(
'pickuppt_history_info',
pickuppt_appt_history_label(),
array($this, 'pickuppt_history_info'),
PICKUPPOINTMENT_POST_TYPE,
'normal'
);
}
do_action('pickuppt_add_mtb', $this);
}
# customer info section callback
function pickuppt_add_mtb_customer_info($post) {
$post_id = $post->ID;
require_once(pickuppt_include_template('mtb-customer-info'));
}
# pickup info section callback
function pickuppt_add_mtb_pickup_info($post) {
$post_id = $post->ID;
require_once(pickuppt_include_template('mtb-pickup-info'));
}
# items info section callback
function pickuppt_add_mtb_item_info($post) {
$post_id = $post->ID;
require_once(pickuppt_include_template('mtb-item-info'));
}
# history information on edit page
function pickuppt_history_info($post) {
$post_id = $post->ID;
$pickuppt_get_appt_history = pickuppt_get_appt_history($post_id);
require_once(pickuppt_include_template('mtb-history-info'));
}
function pickuppt_save_custom_mtb($post_id) {
// Prevent recursion / auto-saves
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
// Check post type (run only for your CPT)
if (get_post_type($post_id) !== PICKUPPOINTMENT_POST_TYPE) {
return;
}
// Check user permissions
if (!current_user_can('edit_post', $post_id)) {
return;
}
// check nonce
if (!isset($_POST['pickuppt_meta_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['pickuppt_meta_nonce'])), 'pickuppt_save_meta')) {
return;
}
if($_POST && is_array($_POST)) {
$first_status = '';
$old_status = get_post_meta($post_id, 'pickuppt_status', true);
// get email
$pickuppt_email = sanitize_text_field(wp_unslash($_POST['pickuppt_email'] ?? ''));
# save customer info fields
foreach(pickuppt_customer_info_fields() as $k => $v) {
$customer_info_val = sanitize_text_field(wp_unslash(($_POST[$k] ?? '') ?: ''));
update_post_meta($post_id, $k, $customer_info_val);
}
# save pickup info fields
foreach(pickuppt_pickup_info_fields() as $k => $v) {
$pickup_info_val = sanitize_text_field(wp_unslash(($_POST[$k] ?? '') ?: ''));
if($k === 'pickuppt_status') {
$first_status = $pickup_info_val;
}
update_post_meta($post_id, $k, $pickup_info_val);
}
# save pickup info fields
foreach(pickuppt_items_info_fields() as $k => $v) {
$item_info_val = sanitize_text_field(wp_unslash(($_POST[$k] ?? '') ?: ''));
update_post_meta($post_id, $k, $item_info_val);
}
// assign the appointment if user email exists on the system
if($pickuppt_email) {
$user_data = get_user_by('email', $pickuppt_email);
if($user_data && is_object($user_data)) {
update_post_meta($post_id, 'pickuppt_appt_owner', $user_data->ID);
}
}
# save history
if($first_status) {
pickuppt_save_history($post_id, $old_status, $first_status);
$pickuppt_history = maybe_unserialize(get_post_meta($post_id, 'pickuppt_history', true));
if(is_array($pickuppt_history) && count($pickuppt_history) === 1) {
pickuppt_send_appt_emails($post_id);
} else {
pickuppt_send_appt_email($post_id);
}
$sanitized_form_data = pickuppt_sanitize_array( wp_unslash( $_POST ) );
do_action('pickuppt_after_save_admin_appt', $post_id, $sanitized_form_data, $first_status);
}
}
}
function pickuppt_enqueue_general_assets() {
$can_enqueue_admin_assets = false;
$can_enqueue_additional_assets = false;
$post_type = $this->url_param_post_type;
$post = $this->url_param_post;
$action = $this->url_param_action;
$page = $this->url_param_page;
$pickuppt = $this->url_param_pickuppt;
$is_auto_generate_title = pickuppt_get_general_setting('auto_generate_title') ?: false;
$generated_title = pickuppt_generate_title();
$dynamic_version = PICKUPPOINTMENT_VERSION . time();
if(in_array($page, pickuppt_page_slugs_for_assets()) || $pickuppt === 'calendar') {
wp_enqueue_style('pickuppt-bootstrap-css', PICKUPPOINTMENT_URL . 'lib/bootstrap.min.css', array(), PICKUPPOINTMENT_VERSION);
if( $page === 'pickuppointments-page' || $pickuppt === 'calendar' ) {
wp_enqueue_script('pickuppt-popper-min-js', PICKUPPOINTMENT_URL . 'lib/popper.min.js', array('jquery'), PICKUPPOINTMENT_VERSION, true);
wp_enqueue_script('pickuppt-fullcalendar-scripts', PICKUPPOINTMENT_URL . 'lib/fullcalendar-6.1.17/dist/index.global.min.js', array('jquery'), PICKUPPOINTMENT_VERSION, true);
wp_enqueue_script('pickuppt-calendar-scripts', PICKUPPOINTMENT_URL . 'admin/assets/js/calendar-scripts.js', array('jquery'), $dynamic_version, true);
$calendar_scripts_localization = array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'puAllAppointments' => pickuppt_all_appointments(true),
'puCanUpdate' => pickuppt_can_update() ? true : false,
'pickupptGetTransInfoNonce' => wp_create_nonce('pickupptGetTransInfoNonce'),
'pickupptUpdateTransNonce' => wp_create_nonce('pickupptUpdateTransNonce'),
'pickupptGetCurrentMonthYearApptsNonce' => wp_create_nonce('pickupptGetCurrentMonthYearApptsNonce')
);
wp_localize_script('pickuppt-calendar-scripts', 'pickupptCalendarScripts', $calendar_scripts_localization);
}
}
if($post_type === PICKUPPOINTMENT_POST_TYPE) {
$can_enqueue_admin_assets = true;
}
if(is_numeric($post) && $post > 0 && $action === 'edit') {
$post_type = get_post_type($post);
if($post_type === PICKUPPOINTMENT_POST_TYPE) {
$can_enqueue_admin_assets = true;
}
}
if($page === 'pickuppointments-page') {
$can_enqueue_admin_assets = true;
}
$_can_enqueue_admin_assets = apply_filters('pickuppt_can_enqueue_admin_assets', $can_enqueue_admin_assets);
$_can_enqueue_additional_assets = apply_filters('pickuppt_can_enqueue_additional_assets', $can_enqueue_additional_assets);
if($page === 'pickuppointment-settings-page' || $_can_enqueue_admin_assets) {
wp_enqueue_media();
wp_enqueue_style('pickuppt-jquery-ui-css', PICKUPPOINTMENT_URL . 'admin/assets/css/jquery-ui.css', array(), PICKUPPOINTMENT_VERSION);
wp_enqueue_script('jquery-ui-tabs');
}
wp_enqueue_script('jquery-ui-datepicker');
$calendar_day_offs = pickuppt_get_general_setting('day_offs') ?: array();
$calendar_holidays = pickuppt_get_general_setting('holidays') ?: array();
$calendar_holiday_dates = array_column( $calendar_holidays, 'holiday_date' );
$calendar_day_offs_json = json_encode( $calendar_day_offs );
$calendar_holiday_dates_json = json_encode( $calendar_holiday_dates );
$localization = array(
'datepickerDateFormat' => apply_filters('pickuppt_datepicker_date_format', 'yy-mm-dd'),
'calendarDayOffsJSON' => $calendar_day_offs_json,
'calendarHolidayDatesJSON' => $calendar_holiday_dates_json,
'ajaxUrl' => admin_url('admin-ajax.php'),
'emptyItemWarningMsg' => apply_filters('pickuppt_empty_item_warning_message', __('Please select at least one booking.', 'pickuppointment')),
'emptyDriverWarningMsg' => apply_filters('pickuppt_empty_driver_warning_message', __('Please select a driver.', 'pickuppointment')),
'driverAssignSuccessMsg' => apply_filters('pickuppt_driver_assign_success_message', __('Selected booking(s) have been assigned to driver.', 'pickuppointment')),
'deleteItemConfirmMsg' => apply_filters('pickuppt_delete_item_confirm_message', __('Are you sure you want to delete this item?', 'pickuppointment')),
'puDateFormat' => pickuppt_datepicker_format(),
'pickupptAssignAppointmentsToDriverNonce' => wp_create_nonce('pickupptAssignAppointmentsToDriverNonce'),
'pickupptSendPaymentLinkNonce' => wp_create_nonce('pickupptSendPaymentLinkNonce'),
'isAutoGenerateTitle' => $is_auto_generate_title,
'generatedTitle' => $generated_title,
'puTimeslotInterval' => pickuppt_time_slot_interval(),
'pickupptAction' => $action
);
$dynamic_version = PICKUPPOINTMENT_VERSION . time();
if($_can_enqueue_admin_assets) {
wp_enqueue_style('pickuppt-admin-styles', PICKUPPOINTMENT_URL . 'admin/assets/css/admin-styles.css', array(), $dynamic_version);
wp_enqueue_style('pickuppt-admin-timepicker-css', PICKUPPOINTMENT_URL . 'lib/timepicker/jquery.timepicker.min.css', array(), PICKUPPOINTMENT_VERSION);
wp_enqueue_script('pickuppt-admin-timepicker-js', PICKUPPOINTMENT_URL . 'lib/timepicker/jquery.timepicker.min.js', array('jquery'), PICKUPPOINTMENT_VERSION, true);
}
wp_enqueue_script('pickuppt-admin-scripts', PICKUPPOINTMENT_URL . 'admin/assets/js/admin-scripts.js', array('jquery', 'jquery-ui-datepicker', 'jquery-ui-tabs'), $dynamic_version, true);
wp_enqueue_script('pickuppt-repeater-js', PICKUPPOINTMENT_URL . 'lib/repeater.min.js', array('jquery'), PICKUPPOINTMENT_VERSION, true);
wp_localize_script('pickuppt-admin-scripts', 'pickupptAdminAssets', $localization);
/**
* global styles
*/
wp_enqueue_style('pickuppointment-global-styles', PICKUPPOINTMENT_URL . 'admin/assets/css/global-styles.css', array(), $dynamic_version);
/**
* calendar styles
*/
wp_register_style( 'pickuppointment-calendary-styles', false, array(), PICKUPPOINTMENT_VERSION );
wp_enqueue_style( 'pickuppointment-calendary-styles' );
$base_color = pickuppt_get_general_setting('theme_color') ?: '#0073aa';
$dynamic_css = '
/* ===============================
FullCalendar Custom Styling
Dynamic Theme Color
Scoped to #pickuppt-calendar
=============================== */
#pickuppt-calendar {
font-family: "Poppins", "Segoe UI", Arial, sans-serif;
background: ' . esc_html(pickuppt_color_shade_generator($base_color, 90)) . ';
border: 1px solid ' . esc_html(pickuppt_color_shade_generator($base_color, 55)) . ';
border-radius: 8px;
font-size: 0.9rem !important;
}
/* Header Toolbar */
#pickuppt-calendar .fc-toolbar {
background: ' . esc_html(pickuppt_color_shade_generator($base_color, 70)) . ';
border-bottom: 1px solid ' . esc_html(pickuppt_color_shade_generator($base_color, 55)) . ';
border-radius: 8px 8px 0 0;
padding: 0.5rem 1rem;
}
#pickuppt-calendar .fc-toolbar-title {
font-size: 1.25rem;
font-weight: 600;
color: ' . esc_html(pickuppt_color_shade_generator($base_color, -35)) . ';
}
/* Buttons */
#pickuppt-calendar .fc-button {
background: ' . esc_html(pickuppt_color_shade_generator($base_color, 0)) . ';
color: #fff;
border: none;
border-radius: 4px;
font-size: 0.9rem;
transition: background 0.2s ease, transform 0.1s ease;
}
#pickuppt-calendar .fc-button:hover {
background: ' . esc_html(pickuppt_color_shade_generator($base_color, -20)) . ';
transform: translateY(-1px);
}
#pickuppt-calendar .fc-button-primary:not(:disabled).fc-button-active,
#pickuppt-calendar .fc-button-primary:not(:disabled):active {
background-color: ' . esc_html(pickuppt_color_shade_generator($base_color, -35)) . ';
}
/* Calendar Grid */
#pickuppt-calendar .fc-daygrid-day {
border: 1px style ' . esc_html(pickuppt_color_shade_generator($base_color, 65)) . ';
background-color: ' . esc_html(pickuppt_color_shade_generator($base_color, 90)) . ';
transition: background 0.15s ease;
}
#pickuppt-calendar .fc-daygrid-day:hover {
background-color: ' . esc_html(pickuppt_color_shade_generator($base_color, 75)) . ';
}
#pickuppt-calendar .fc-daygrid-day.fc-day-today {
background: ' . esc_html(pickuppt_color_shade_generator($base_color, 45)) . ';
border-color: ' . esc_html(pickuppt_color_shade_generator($base_color, 0)) . ';
}
/* Day Numbers */
#pickuppt-calendar .fc-daygrid-day-number {
font-weight: 500;
color: ' . esc_html(pickuppt_color_shade_generator($base_color, -35)) . ';
}
/* Events */
#pickuppt-calendar .fc-event {
background-color: ' . esc_html(pickuppt_color_shade_generator($base_color, 0)) . ';
border: none;
color: #fff;
border-radius: 4px;
font-size: 0.85rem;
transition: background 0.2s ease;
}
#pickuppt-calendar .fc-event:hover {
background-color: ' . esc_html(pickuppt_color_shade_generator($base_color, -20)) . ';
}
/* Scrollbar & List View */
#pickuppt-calendar .fc-scroller {
scrollbar-width: thin;
scrollbar-color: ' . esc_html(pickuppt_color_shade_generator($base_color, 0)) . ' ' . esc_html(pickuppt_color_shade_generator($base_color, 70)) . ';
}
#pickuppt-calendar .fc-scroller::-webkit-scrollbar {
width: 6px;
}
#pickuppt-calendar .fc-scroller::-webkit-scrollbar-thumb {
background: ' . esc_html(pickuppt_color_shade_generator($base_color, 0)) . ';
border-radius: 3px;
}
#pickuppt-calendar .fc-list-event {
border-bottom: 1px solid ' . esc_html(pickuppt_color_shade_generator($base_color, 65)) . ';
}
#pickuppt-calendar .fc-list-event:hover {
background-color: ' . esc_html(pickuppt_color_shade_generator($base_color, 75)) . ';
}
.tooltip-inner {
text-align: left !important;
}
/* Responsive */
@media (max-width: 768px) {
#pickuppt-calendar .fc-toolbar {
flex-wrap: wrap;
text-align: center;
}
#pickuppt-calendar .fc-toolbar-title {
width: 100%;
margin-bottom: 0.5rem;
}
}';
wp_add_inline_style( 'pickuppointment-calendary-styles', $dynamic_css );
/**
* dynamic timeslot script
*/
wp_enqueue_script('pickuppointment-dynamic-timeslot-scripts', PICKUPPOINTMENT_URL . 'admin/assets/js/dynamic-timeslot.js', array('jquery'), $dynamic_version, true);
$pickuppointment_dynamic_timeslot_localization = array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'timeSlotInterval' => pickuppt_time_slot_interval(),
'pickupptDynamicTimeslotNonce' => wp_create_nonce( 'pickupptDynamicTimeslotNonce' )
);
wp_localize_script('pickuppointment-dynamic-timeslot-scripts', 'pickuppointmentDynamicTimeslotObj', $pickuppointment_dynamic_timeslot_localization);
/**
* charges script
*/
wp_enqueue_script('pickuppointment-charges-scripts', PICKUPPOINTMENT_URL . 'admin/assets/js/charges-scripts.js', array('jquery'), $dynamic_version, true);
$pickuppointment_charges_localization = array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'deleteItemWarning' => __( 'Are you sure you want to delete this item?', 'pickuppointment' ),
'pickupptSaveOrderChargesNonce' => wp_create_nonce( 'pickupptSaveOrderChargesNonce' ),
'pickupptGetOrderChargesNonce' => wp_create_nonce( 'pickupptGetOrderChargesNonce' )
);
wp_localize_script('pickuppointment-charges-scripts', 'pickuppointmentChargesObj', $pickuppointment_charges_localization);
/**
* google maps api script
*/
$gmaps_api_key = pickuppt_get_general_setting('gmaps_api_key');
if( !empty( $gmaps_api_key ) ) {
$pickuppt_can_load_gmaps_api = false;
if( $this->url_param_page === 'pickuppointment-settings-page' ) {
$pickuppt_can_load_gmaps_api = true;
}
if( 'pickuppointment' == $this->url_param_post_type ) {
$pickuppt_can_load_gmaps_api = true;
}
global $post;
if ( is_singular() && is_a( $post, 'WP_Post' ) ) {
if ( has_shortcode( $post->post_content, 'pickuppointment_form_public' ) ) {
$pickuppt_can_load_gmaps_api = true;
}
$page_template = get_post_meta($post->ID, '_wp_page_template', true);
if('pu-hub-template.php' === $page_template && is_user_logged_in()) {
$pickuppt_can_load_gmaps_api = true;
}
}
$pickuppt_can_load_gmaps_api = apply_filters( 'pickuppt_can_load_gmaps_api', $pickuppt_can_load_gmaps_api );
if( $pickuppt_can_load_gmaps_api ) {
$maps_url = add_query_arg(
array(
'key' => $gmaps_api_key,
'libraries' => 'places',
'callback' => 'pickuppointmentInitAutocomplete',
),
'https://maps.googleapis.com/maps/api/js'
);
wp_register_script( 'pickuppointment-google-maps', $maps_url, array('jquery'), PICKUPPOINTMENT_VERSION, array( 'strategy' => 'async', 'in_footer' => true ) );
$inline_script = '
function pickuppointmentInitAutocomplete() {
jQuery(function($) {
$(".pickuppointment-autocomplete").each(function() {
const autocomplete = new google.maps.places.Autocomplete(
this,
{
fields: ["address_components", "formatted_address"]
}
);
});
});
}';
wp_add_inline_script( 'pickuppointment-google-maps', $inline_script, 'before' );
wp_enqueue_script( 'pickuppointment-google-maps' );
}
}
}
}
$pickuppointment_class = new PickUppointment();
}