?
Current File : /home/cideo/www/wp-contentVIp/plugins/gAppointments/admin/page_ga_appointments.php
<?php 
if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

new ga_appointments_post_type();
class ga_appointments_post_type {

	public function __construct() {	
		// Post type		
		add_action( 'wp_loaded', array($this, 'ga_appointments_init') );			
		
		// New Statuses		
		add_action( 'wp_loaded', array($this,'ga_appointments_new_statuses') );		
		
		// Appointments Details Options
		add_action( 'cmb2_admin_init', array($this,'cmb2_ga_appointments_details_metaboxes') );			
		
		// Rename post statuses
		add_filter( "views_edit-ga_appointments", array($this, 'rename_ga_appointments_post_statuses') );		
				
		// Appointments post type new submit widget
		add_action( 'cmb2_admin_init', array($this, 'cmb2_ga_appointments_submitdiv_metabox' ) );	
				
		// Appointment row columns
		add_filter( "manage_edit-ga_appointments_columns", array($this,'manage_ga_appointments_columns') ); // column names
		add_action( "manage_ga_appointments_posts_custom_column", array($this,'manage_ga_appointments_posts_custom_column'), 10, 2 ); // html column	
	
		// Add post type filters
		add_action( 'restrict_manage_posts', array($this, 'add_service_provider_filter_to_posts_administration') );
		add_action( 'pre_get_posts', array($this, 'add_service_provider_filter_to_posts_query') );

		// Remove Date Drop Filter
		add_action('admin_head', array($this,'remove_date_drop'));
	}	

	
	

	/**
	 * Remove Date Drop Filter
	 */	
	public function remove_date_drop(){
		global $post_type, $pagenow; 

		if( $pagenow == 'edit.php' && $post_type == 'ga_appointments') {
			add_filter('months_dropdown_results', '__return_empty_array');
		}
	}

	
	
	/**
	 * Appointments Post Type
	 */
	public function ga_appointments_init() {
		$questions_labels = array(
			'name' => _x('Appointments', 'post type general name'),
			'singular_name' => _x('Appointment', 'post type singular name'),
			'all_items' => __('Appointments'),
			'add_new' => _x('Add new', 'ga_booking_appointments'),
			'add_new_item' => __('Add new appointment'),
			'edit_item' => __('Edit appointment'),
			'new_item' => __('New appointment'),
			'view_item' => __('View appointment'),
			'search_items' => __('Search appointments'),
			'not_found' =>  __('You do not have any appointments!'),
			'not_found_in_trash' => __('Nothing found in trash'), 
			'parent_item_colon' => ''
		);

		$args = array(
			'labels' => $questions_labels,
			'public' => false,
			'publicly_queryable' => false,
			'has_archive' => false,
			'show_ui' => true, 
			'show_in_menu' => 'ga_appointments_settings',
			'query_var' => true,
			'rewrite' => false,
			'rewrite' => array('slug' => 'contact'),
			'capability_type' => 'post',
			'hierarchical' => false,
			'menu_position' => 5,
			'supports' => array(''), // nothing supports
		); 
		
		register_post_type('ga_appointments', $args);
	}			
	
	/**
	 * Appointment Post Type New Statuses
	 */		
	public function ga_appointments_new_statuses() {
		register_post_status( 'completed', array(
			'label'                     => _x( 'Completed', 'post' ),
			'public'                    => true,
			'exclude_from_search'       => true,		
			'show_in_admin_all_list'    => true,
			'show_in_admin_status_list' => true,
			'label_count'               => _n_noop( 'Completed <span class="count">(%s)</span>', 'Completed <span class="count">(%s)</span>' ),
		) );
			

		register_post_status( 'payment', array(
			'label'                     => _x( 'Pending Payment', 'post' ),
			'public'                    => true,
			'exclude_from_search'       => true,		
			'show_in_admin_all_list'    => true,
			'show_in_admin_status_list' => true,
			'label_count'               => _n_noop( 'Pending Payment <span class="count">(%s)</span>', 'Pending Payment <span class="count">(%s)</span>' ),
		) );				
		
		register_post_status( 'cancelled', array(
			'label'                     => _x( 'Cancelled', 'post' ),
			'public'                    => true,
			'exclude_from_search'       => true,			
			'show_in_admin_all_list'    => true,
			'show_in_admin_status_list' => true,
			'label_count'               => _n_noop( 'Cancelled <span class="count">(%s)</span>', 'Cancelled <span class="count">(%s)</span>' ),
		) );		
	}

	
	/**
	 * 1. Add custom filters to appointments post type
	 */	
	public function add_service_provider_filter_to_posts_administration() {

		//execute only on the 'post' content type
		global $post_type, $pagenow; 

		//if we are currently on the edit screen of the post type listings
		if($pagenow == 'edit.php' && $post_type == 'ga_appointments') {

			$services_args = array(
				'show_option_all'   => 'Filter by service',
				'name'              => 'service_filter',
				'selected'          => '0',
			);

			$providers_args = array(
				'show_option_all'   => 'Filter by provider',
				'name'              => 'provider_filter',
				'selected'          => '-1',
			);		
			
			$date_filter_args = array(
				'name'              => 'ga_date_filter',
				'selected'          => '',
			);				
			
			// Filter by service
			if( isset($_GET['service_filter'])) {
				//set the selected value to the value of the author
				$services_args['selected'] = absint( $_GET['service_filter'] );
			} 

			echo '<select name="'.$services_args['name'].'" id="'.$services_args['name'].'">';
				echo '<option value="0">'.$services_args['show_option_all'].'</option>';
		
				if( get_ga_appointment_services() ) {
					foreach( get_ga_appointment_services() as $_id => $service_title ) {
						$selected = $services_args['selected'] == $_id ? ' selected' : '';
						echo '<option value="'.$_id.'"'.$selected.'>'.$service_title.'</option>';					
					}
				}	
			echo '</select>';		
			
			// Filter by provider			
			if( isset($_GET['provider_filter']) ) {
				// set the selected value to the value of the author
				$providers_args['selected'] = (int) $_GET['provider_filter'];
			}		
					
			echo '<select name="'.$providers_args['name'].'" id="'.$providers_args['name'].'">';
				echo '<option value="-1">'.$providers_args['show_option_all'].'</option>';
				
				if( get_ga_appointment_providers() ) {				
					foreach( get_ga_appointment_providers() as $_id => $service_title ) {
						$selected = $providers_args['selected'] == $_id ? ' selected' : '';
						echo '<option value="'.$_id.'"'.$selected.'>'.$service_title.'</option>';
					}
				}	

			echo '</select>';
			
			// Filter by input date		
			if( isset($_GET['ga_date_filter']) ) {
				// set the selected value to the value of the author
				$date_filter_args['selected'] = esc_html($_GET['ga_date_filter']);
			}			
			
			echo '<input type="text" class="ga-date-picker" name="'.$date_filter_args['name'].'" id="'.$date_filter_args['name'].'" value="'.$date_filter_args['selected'].'" placeholder="Filter by date">';
			
		}
	}
	
	/**
	 * 2. Add custom filters to appointments post type
	 */	
	public function add_service_provider_filter_to_posts_query($query){

		global $post_type, $pagenow; 

		//if we are currently on the edit screen of the post type listings
		if($pagenow == 'edit.php' && $post_type == 'ga_appointments' && $query->is_main_query()) {

			$filters = array();

			// Sort Appointment Order
			$filters[] = array(
				'relation' => 'AND',
				'date' => array( 'key' => 'ga_appointment_date', 'type' => 'DATE' ),
				'time' => array( 'key' => 'ga_appointment_time', 'compare' => 'BETWEEN', 'type' => 'TIME'  ),					
				array(
					// A nested set of conditions for when the above condition is false.
					array(
						'relation' => 'OR',	
						'date' => array( 'key' => 'ga_appointment_date', 'compare' => '=', 'value' => '',),
						'date' => array( 'key' => 'ga_appointment_date', 'compare' => 'NOT EXISTS', ),
						'date' => array( 'key' => 'ga_appointment_date', 'type' => 'DATE' ),																		
					)
				),
			);			
			
			
			$orderby =  array( 
				'date'   => 'ASC',
				'time'   => 'ASC',
			);
		
			// Sort Appointment Order
			
			if(isset($_GET['service_filter'])) {
				
				//set the query variable for 'author' to the desired value
				$service_id = sanitize_text_field($_GET['service_filter']);

				//if the author is not 0 (meaning all)
				if($service_id != 0) {
					$filters[] = array(
						'key'     => 'ga_appointment_service',
						'value'   => $service_id,	
						'type'    => 'numeric',
					);
				}

			}
			
			if(isset($_GET['provider_filter'])) {
				$provider_id = sanitize_text_field($_GET['provider_filter']);

				if($provider_id != '-1') {
					$filters[] = array(
						'key'     => 'ga_appointment_provider',
						'value'   => $provider_id,	
						'type'    => 'numeric',					
					);	
				}

			}

			// Filter by input date		
			if( isset($_GET['ga_date_filter']) && ga_valid_date_format($_GET['ga_date_filter']) ) {
				$date = $_GET['ga_date_filter'];
				$filters[] = array(
					'key'     => 'ga_appointment_date',
					'value'   => $date,
				);
			}			
			
			
			$query->set( 'meta_query', $filters);
			$query->set( 'orderby', $orderby);			
			
		}
	}
	
	/**
	 * Appointments Details Options
	 */
	public function cmb2_ga_appointments_details_metaboxes() {

		// Start with an underscore to hide fields from custom fields list
		$prefix = 'ga_appointment_';
		/**
		 * Initiate the metabox
		 */
		$cmb = new_cmb2_box( array(
			'id'            => 'ga_appointment_details',
			'title'         => __( 'Appointment Details', 'cmb2' ),
			'object_types'  => array( 'ga_appointments' ), // Post type
			'context'       => 'normal',
			'priority'      => 'high',
			'show_names'    => true, // Show field names on the left
		) );

		// Type
		$cmb->add_field( array(
			'name'            => 'Type',
			'desc'            => 'Interval or bookable date appointment',
			'id'              => $prefix . 'type',
			'type'            => 'select',		
			'default'         => 'time_slot',
			'options'         => array(
				'time_slot'   => __( 'Time slot', 'cmb2' ),
				'date'        => __( 'Bookable date', 'cmb2' ),
			),			
		) );		
		
		
		// Duration
		$cmb->add_field( array(
			'name' => 'Duration',
			'desc' => 'Duration is how long the appointment lasts',
			'id'   => $prefix . 'duration',
			'type' => 'select',
			'classes_cb'      => array($this, 'show_on_time_slot_type'),			
			'default' => '30', // 30 minutes
			'options_cb' => 'ga_service_duration_options',			
			'sanitization_cb' => 'ga_sanitize_service_duration_options', // function should return a sanitized value				
		) );			
		
		// Date
		$cmb->add_field( array(
			'name' => 'Date',
			'desc' => 'Format: year, month, day',
			'id'   => $prefix . 'date',
			'type' => 'text_date',
			'timezone_meta_key' => ga_time_zone(),
			'date_format' => 'Y-m-j',			
			'sanitization_cb' => 'sanitize_get_ga_services_date', // function should return a sanitized value				
		) );		
	
		// Time
		$cmb->add_field( array(
			'name' => 'Time',
			'desc' => 'Start time',
			'id'   => $prefix . 'time',			
			'type' => 'select',
			'classes_cb'      => array($this, 'show_on_time_slot_type'),			
			'default' => '09:00', // 30 minutes			
			'options_cb'      => 'get_ga_appointment_time',	
			'sanitization_cb' => 'sanitize_get_ga_appointment_time', // function should return a sanitized value
		) );		
				
		
		// Provider
		$cmb->add_field( array(
			'name' => 'Provider',
			'desc' => 'Select no provider if you don\'t want any provider',
			'id'   => $prefix . 'provider',
			'type' => 'select',	
			'options_cb' => 'get_ga_appointment_providers',
			'sanitization_cb' => 'sanitize_get_ga_appointment_providers', // function should return a sanitized value				
		) );	

		// Service
		$cmb->add_field( array(
			'name' => 'Service',
			'desc' => 'Select a service',
			'id'   => $prefix . 'service',
			'type'  => 'select',
			'options_cb' => 'get_ga_appointment_services',
			'sanitization_cb' => 'sanitize_ga_appointment_services', // function should return a sanitized value			
		) );	
		
		// Client
		$cmb->add_field( array(
			'name' => 'Client',
			'desc' => 'Select a registered user or add new client',
			'id'   => $prefix . 'client',
			'type'  => 'select',		
			'options_cb' => 'get_ga_appointment_users',
			'sanitization_cb' => 'sanitize_get_ga_appointment_users', // function should return a sanitized value
		) );	

		// Client
		$cmb->add_field( array(
			'name' => 'Client Information',
			'desc' => 'Name, Email & Phone',
			'id'   => $prefix . 'new_client',
			'type'  => 'text',
			'render_row_cb'   => 'get_ga_appointment_new_client_render_row',
			'sanitization_cb' => 'sanitize_get_ga_appointment_new_client', // function should return a sanitized value			
		) );			
		
		// GF Entry ID
		$cmb->add_field( array(
			'name' => 'Payment Order Details',
			'desc' => 'GravityForms Entry ID. This field is necessary to update appointment status after completed or failed payment. Modify this field only if you know what you\'re doing.',
			'id'   => $prefix . 'gf_entry_id',
			'type' => 'select',	
			'show_option_none' => 'Select entry',
			'options_cb'      => 'get_gravity_form_entries_ids',
			'sanitization_cb' => 'sanitize_get_gravity_form_entries_ids', // function should return a sanitized value
		) );	
		
		// Appointment IP
		$cmb->add_field( array(
			'name' => 'User IP',
			'desc' => 'Clients who want to book more than 1 time per time slot will be blocked if it\'s enabled service capacity',
			'id'   => $prefix . 'ip',
			'type' => 'text',	
			'sanitization_cb' => 'sanitize_ga_appointment_ip', // function should return a sanitized value			
		) );		
		
	}
	
	
	/**
	 * Show on time slot type
	 */	
	public function show_on_time_slot_type( $field_args, $field ) {
		// Appointment Type
		$type = (string) get_post_meta($field->object_id, 'ga_appointment_type', true);
		
		// Time Slots Mode
		if( $type == 'time_slot' || $type == '' ) {
			return '';
		} else {
			return 'cmb2-hidden';
		} 	
	}			
	
	
	/**
	 * Appointments New Submit Widget
	 */
	public function cmb2_ga_appointments_submitdiv_metabox() {

		// Start with an underscore to hide fields from custom fields list
		$prefix = 'ga_appointment_';
		/**
		 * Initiate the metabox
		 */
		$cmb = new_cmb2_box( array(
			'id'            => 'ga_appointment_submitdiv',
			'title'         => __( 'Save Appointment', 'cmb2' ),
			'object_types'  => array( 'ga_appointments' ), // Post type
			'context'       => 'side',
			'priority'      => 'high',
			'show_names'    => true, // Show field names on the left
		) );
		
		// New Submit Widget
		$cmb->add_field( array(
			'name'         => 'Save Appointment',
			'id'           => $prefix . 'submitdiv',
			'type'         => 'select',	
			'render_row_cb' => array($this, 'ga_appointment_submitdiv_render_row'),			
		) );	
	}
	
	/**
	 * Appointments New Submit Widget
	 */
	public function rename_ga_appointments_post_statuses( $views ) {
		if( isset( $views['publish'] ) )
			$views['publish'] = str_replace( 'Published ', 'Confirmed ', $views['publish'] );
		
		return $views;
	}

	/**
	 * Appointments Custom Columns
	 */	
	public function manage_ga_appointments_columns( $columns ) {

		$columns = array(
			'cb'            => '<input type="checkbox" />', // needed for checking/selecting multiple rows
			//'title'         => __( 'Title' ),
			//'date'          => __( 'Date' ),			
			'date_on'       => __( 'Appointment Date' ),
			'time'          => __( 'Time' ),
			'time_end'      => __( 'Ends' ),
			'duration'      => __( 'Duration' ),
			'provider'      => __( 'Provider' ),
			'service'       => __( 'Service' ),			
			'client'        => __( 'Client' ),
			'payment'       => __( 'Payment' ),
			'status'        => __( 'Status' ),			
		);

		return $columns;
	}

	/**
	 * Appointments Custom Columns HTML
	 */		
	public function manage_ga_appointments_posts_custom_column( $column, $post_id ) {
		//global $post;

		switch( $column ) {	
			case 'date_on' :
				$post                = get_post( $post_id );
				
				// DATE
				$app_date            = (string) get_post_meta( $post_id, 'ga_appointment_date', true );
				$date                = ga_valid_date_format($app_date) ? new DateTime($app_date) : false;
				$app_date_text       = $date ? $date->format('F j, Y') : 'Date not defined';
				
				// Date-Time Link
				echo '<a href="' . get_edit_post_link( $post->ID, true ) . '" title="' . esc_attr( __( 'Edit this appointment' ) ) . '">'. $app_date_text .'</a>';

				
				//***** ROW ACTIONS  *******//
				// First set up some variables
				$actions             = array();
				$post_type_object    = get_post_type_object( $post->post_type );
				$can_edit_post       = current_user_can( $post_type_object->cap->edit_post, $post->ID );


				// Actions to edit
				if ( $can_edit_post && 'trash' != $post->post_status ) {
					$actions['edit'] = '<a href="' . get_edit_post_link( $post->ID, true ) . '" title="' . esc_attr( __( 'Edit this appointment' ) ) . '">' . __( 'Edit' ) . '</a>';
				}

				// Actions to delete/trash
				if ( current_user_can( $post_type_object->cap->delete_post, $post->ID ) ) {
					if ( 'trash' == $post->post_status ) {
						$_wpnonce = wp_create_nonce( 'untrash-post_' . $post_id );
						$actions['untrash'] = "<a title='" . esc_attr( __( 'Restore this item from the Trash' ) ) . "' href='" . admin_url( 'post.php?post=' . $post->ID . '&action=untrash&_wpnonce=' . $_wpnonce ) . "'>" . __( 'Restore' ) . "</a>";					
					} elseif ( EMPTY_TRASH_DAYS ) {
						$actions['trash'] = "<a class='submitdelete' title='" . esc_attr( __( 'Move this item to the Trash' ) ) . "' href='" . get_delete_post_link( $post->ID ) . "'>" . __( 'Delete' ) . "</a>";
					}
					if ( 'trash' == $post->post_status || !EMPTY_TRASH_DAYS ) {
						$actions['delete'] = "<a class='submitdelete' title='" . esc_attr( __( 'Delete this item permanently' ) ) . "' href='" . get_delete_post_link( $post->ID, '', true ) . "'>" . __( 'Delete Permanently' ) . "</a>";						
					}
	
				}

				//***** END - ROW ACTIONS *******//		
				
				echo '<div class="row-actions">';		
				foreach( $actions as $key => $action ) {
					$sep = $key == 'edit' || $key == 'untrash' ? ' | ' : '';
					echo '<span class="'.$key.'">'. $action . $sep .'<span>';
				}
				echo '</div>';
					
				echo '<button type="button" class="toggle-row"><span class="screen-reader-text">Show more details</span></button>';	
			break;	
	
			case 'time' :
				// Time
				$app_time            = (string) get_post_meta( $post_id, 'ga_appointment_time', true );
				$time                = ga_valid_time_format($app_time) ? new DateTime($app_time) : false;
				$app_time_text       = $time ? $time->format('g:i a') : 'Time not defined';
				
				// Date Slots Mode
				$app_type = get_post_meta($post_id, 'ga_appointment_type', true);
				if( $app_type == 'date' ) {
					echo 'Full day';				
				} else {
					// Time Slots Mode
					echo $app_time_text;						
				}				
		
				break;		

			case 'time_end' :
				// Time
				$app_time            = (string) get_post_meta( $post_id, 'ga_appointment_time_end', true );
				$time                = ga_valid_time_format($app_time) ? new DateTime($app_time) : false;
				$app_time_text       = $time ? $time->format('g:i a') : 'Time not defined';
				
				// Date Slots Mode
				$app_type = get_post_meta($post_id, 'ga_appointment_type', true);
				if( $app_type == 'date' ) {
					echo 'Full day';				
				} else {
					// Time Slots Mode
					if( $time && $time->format('H:i') == '23:59' || $app_time == '24:00' ) {
						echo '12:00 am';
					} else {
						echo $app_time_text;
					}
				}						
				break;					
				
			case 'duration' :	
				// Date Slots Mode
				$app_type = get_post_meta($post_id, 'ga_appointment_type', true);
				if( $app_type == 'date' ) {
					echo 'Full day';			
				} else {
					// Time Slots Mode
					$duration = (int) get_post_meta( $post_id, 'ga_appointment_duration', true );
					echo convertToHoursMins($duration);					
				}	

				break;

			case 'client' :

				$client = (string) get_post_meta( $post_id, 'ga_appointment_client', true );
				
				if( $client == 'new_client' ) {
					$new_client = get_post_meta( $post_id, 'ga_appointment_new_client', true );
					
					$client = isset($new_client['name']) ? esc_html($new_client['name']) : '';
					
					if( isset($new_client['email']) && !empty($new_client['email']) ) {
						$client .= '<div class="ga_client_email">(' . esc_html($new_client['email']) . ')</div>';
					}
					
					if( isset($new_client['phone']) && !empty($new_client['phone']) ) {
						$client .= '<div class="ga_client_phone">(' . esc_html($new_client['phone']) . ')</div>';
					}
					
					echo $client;
					
				} else {
					
					$user_info = get_userdata($client);
					
					if( $user_info ) {
						echo '<a href="'.get_edit_user_link( $user_info->ID ).'" target="_blank">'.$user_info->user_login.'</a>';
					} else {
						echo 'Not defined';
					}	

				}

				break;		
				
			case 'service' :
				$service_id = get_post_meta( $post_id, 'ga_appointment_service', true );
				
				if( 'ga_services' == get_post_type($service_id) ) {
					echo esc_html( get_the_title( $service_id ) );				
				} else {	
					echo 'Not defined';
				}				
				break;	

			case 'provider' :
				$provider_id = (int) get_post_meta( $post_id, 'ga_appointment_provider', true );
				
				if( 'ga_providers' == get_post_type($provider_id) ) {
					echo esc_html( get_the_title( $provider_id ) );	
				} else {	
					echo 'No provider';
				}					

				break;					
				
			case 'payment' :
			
				$app_entry_id = (int) get_post_meta( $post_id, 'ga_appointment_gf_entry_id', true );
				if( RGFormsModel::get_lead($app_entry_id) ) {
					$entry_obj      = RGFormsModel::get_lead($app_entry_id);
					$form_id        = $entry_obj['form_id'];
					$entry_id       = $entry_obj['id'];
					$entry_url      = get_bloginfo( 'wpurl' ) . '/wp-admin/admin.php?page=gf_entries&view=entry&id=' . $form_id . '&lid=' . $entry_id;
					$text           = str_replace( '{entry_url}', urlencode( $entry_url ), $entry_url );			
				
					echo '<a href="'.esc_url($text).'" target="_blank">View Order Details</a>';					
				} else {
					echo '<span>Not Available</span>';
				}		
				break;

			case 'status' :
				$post_obj = get_post($post_id);
				if( isset($post_obj->post_status) ) {
					
					if( array_key_exists($post_obj->post_status, ga_appointment_statuses()) ) {
						$statuses = ga_appointment_statuses();
						echo $statuses[$post_obj->post_status];
					} elseif( $post_obj->post_status == 'trash' ) {
						echo 'In trash';
					} else {
						echo 'Unknown';
					}

				}
				break;	
				
			/* Just break out of the switch statement for everything else. */
			default :
				break;
		}
	}	
	
	/**
	 * Appointments Submit Widget HTML
	 */	
	public function ga_appointment_submitdiv_render_row() {
		global $post;
		$post_status = isset($post->post_status) ? $post->post_status : '';
		
		$appointment_statuses = ga_appointment_statuses();
		
		echo '<div class="cmb-submitdiv">';	
			echo '<select id="post-status" class="" name="post_status">';
			
			foreach($appointment_statuses as $key => $status) {
				$selected = $post_status == $key ? ' selected' : '';
				echo '<option value="'.$key.'"'.$selected.'>'.$status.'</option>';
			}
				
			echo '</select>';
			echo '<input type="submit" class="button button-ga right" value="Update">'; // button-primary
			echo '<div class="clear"></div>';

			echo '<textarea name="ga_cancel_message" class="ga_cancel_message cmb2-hidden" placeholder="Optional message"></textarea>';
			
		echo '</div>';
	}
	
} // end class