# bookit/2.6.0.5/includes/classes/admin/CustomersController.php

Bookit — Booking &amp; Appointment Calendar, version 2.6.0.5. 327 lines.

- Page: https://pluginprobe.com/plugins/bookit/2.6.0.5/code/includes/classes/admin/CustomersController.php
- Raw: https://pluginprobe.com/plugins/bookit/2.6.0.5/raw/includes/classes/admin/CustomersController.php
- Modified: 2026-09-14T17:08:02+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/bookit/2.6.0.5/code/includes/classes/admin/CustomersController.php#L10-L20`.

```php
<?php

namespace Bookit\Classes\Admin;

use Bookit\Classes\Base\User;
use Bookit\Classes\Database\Appointments;
use Bookit\Classes\Database\Customers;
use Bookit\Classes\Template;
use Bookit\Helpers\CleanHelper;

class CustomersController extends DashboardController {

	private static $sortFields = array( 'id', 'full_name', 'email', 'phone' );

	private static function getCleanRules() {
		return array(
			'id'        => array( 'type' => 'intval' ),
			'limit'     => array( 'type' => 'intval' ),
			'offset'    => array( 'type' => 'intval' ),
			'sort'      => array( 'type' => 'strval' ),
			'order'     => array( 'type' => 'strval' ),
			'search'    => array( 'type' => 'strval' ),
			'full_name' => array( 'type' => 'strval' ),
			'phone'     => array(
				'function' => array(
					'custom' => true,
					'name'   => 'custom_sanitize_phone',
				),
			),
			'email'     => array(
				'type'     => 'strval',
				'function' => array(
					'custom' => false,
					'name'   => 'sanitize_email',
				),
			),
		);
	}

	/**
	 * Display Rendered Template
	 * @return bool|string
	 */
	public static function render() {
		self::enqueue_styles_scripts();

		$user_args = array(
			'fields' => array( 'ID', 'display_name' ),
		);
		$wp_users  = get_users( $user_args );

		return Template::load_template(
			'dashboard/bookit-customers',
			array(
				'wp_users' => $wp_users,
				'page' => __( 'Customers', 'bookit' ),
			),
			true
		);
	}

	/**
	 * Whether the account-lookup endpoint should respond. It supports the
	 * logged-out registered-booking flow, so limit availability to that case.
	 *
	 * @since 2.6.0
	 *
	 * @return bool
	 */
	private static function account_lookup_available() {
		return is_user_logged_in()
			|| 'registered' === get_option_by_path( 'bookit_settings.booking_type' );
	}

	/**
	 * Tell the registered-booking form whether an account already exists for
	 * an email. Limited to the registered-booking flow.
	 *
	 * @since 2.6.0
	 */
	public static function get_wp_user_by_email() {
		check_ajax_referer( 'bookit_get_wp_user_by_email', 'nonce' );

		if ( ! self::account_lookup_available() ) {
			wp_send_json_error( array( 'message' => __( 'Not available.', 'bookit' ) ) );
		}

		$email = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';
		if ( empty( $email ) ) {
			wp_send_json_success( array( 'exist' => false ) );
		}

		$exist = get_user_by( 'email', $email ) instanceof \WP_User;

		wp_send_json_success( array( 'exist' => $exist ) );
	}

	/**
	 * Get Customers with Pagination
	 */
	public static function get_customers() {
		check_ajax_referer( 'bookit_get_customers', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			return false;
		}

		global $wpdb;
		$data = CleanHelper::cleanData( $_GET, self::getCleanRules() );

		if ( ! empty( $data['limit'] ) ) {
			$search_where  = '';
			$search_values = array();
			if ( ! empty( $data['search'] ) ) {
				$like          = '%' . $wpdb->esc_like( $data['search'] ) . '%';
				$search_where  = 'WHERE full_name LIKE %s OR email LIKE %s OR phone LIKE %s';
				$search_values = array( $like, $like, $like );
			}
			$response['customers'] = Customers::get_paged(
				$data['limit'],
				$data['offset'],
				$search_where,
				( isset( $data['sort'] ) && in_array( $data['sort'], self::$sortFields ) ) ? $data['sort'] : '',
				( isset( $data['order'] ) && in_array( $data['order'], array( 'asc', 'desc' ) ) ) ? $data['order'] : '',
				$search_values
			);
			$response['total'] = ( ! empty( $search_where ) ) ? count( $response['customers'] ) : Customers::get_count();

			array_walk(
				$response['customers'],
				function ( &$value, $key ) {
					$value['full_name'] = stripslashes( $value['full_name'] );
				}
			);

			wp_send_json_success( $response );
		}

		wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
	}

	/**
	 * Validate post fields
	 */
	public static function validate( $data ) {
		$errors = array();

		if ( $data['phone'] || false === $data['phone'] ) {
			if ( ! preg_match( '/^((\+)?[0-9]{9,14})$/', $data['phone'] ) ) {
				$errors['phone'] = esc_html__( 'Please enter a valid phone number', 'bookit' );
			}
		}

		if ( ! $data['email'] ) {
			$errors['email'] = esc_html__( 'Email is required', 'bookit' );
		}

		if ( $data['email'] && ! is_email( $data['email'] ) ) {
			$errors['email'] = __( 'Not valid Email', 'bookit' );
		}

		$customer = Customers::get( 'email', $data['email'] );
		if ( null != $customer && ! isset( $data['id'] ) ) {
			$errors['email'] = __( 'Customer with such email already exist', 'bookit' );
		}

		if ( $data['full_name'] ) {
			if ( strlen( $data['full_name'] ) < 3 || strlen( $data['full_name'] ) > 25 ) {
				$errors['full_name'] = __( 'Full name must be between 3 and 25 characters long', 'bookit' );
			}
		} else {
			$errors['full_name'] = __( 'Full Name is required.', 'bookit' );
		}
		$settings_booking_type = get_option_by_path( 'bookit_settings.booking_type' );
		if ( isset( $data['from'] ) && 'calendar' == $data['from'] && 'registered' == $settings_booking_type ) {

			if ( empty( $data['password'] ) ) {
				$errors['password'] = __( 'Please enter a password', 'bookit' );
			}

			if ( false !== strpos( wp_unslash( $data['password'] ), '\\' ) ) {
				$errors['password'] = __( "Passwords may not contain the character '\\'", 'bookit' );
			}

			if ( ( ! empty( $data['password'] ) ) && $data['password'] != $data['password_confirmation'] ) {
				$errors['password_confirmation'] = __( 'Please enter the same password in both password fields', 'bookit' );
			}
		}

		if ( count( $errors ) > 0 ) {
			wp_send_json_error(
				array(
					'errors'  => $errors,
					'message' => __( 'Error occurred!', 'bookit' ),
				)
			);
		}
	}

	/**
	 * Create Customer from appointment
	 */
	public static function create() {
		check_ajax_referer( 'bookit_save_item', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			return false;
		}

		$data = CleanHelper::cleanData( $_POST, self::getCleanRules() );
		self::validate( $data );
		unset( $data['id'] );

		$exist = Customers::get( 'email', $data['email'] );
		if ( $exist ) {
			wp_send_json_error(
				array(
					'errors'  => array( 'email' => __( 'Customer with such email already exist.', 'bookit' ) ),
					'message' => __( 'Error occurred!', 'bookit' ),
				)
			);
		}

		/** save in WordPress users based on booking type value */
		$settings_booking_type = get_option_by_path( 'bookit_settings.booking_type' );
		if ( 'registered' == $settings_booking_type ) {
			$data['role']       = User::$customer_role;
			$data['wp_user_id'] = Customers::save_or_get_wp_user( $data );
		}

		unset( $data['role'] );
		unset( $data['password'] );
		unset( $data['password_confirmation'] );
		unset( $data['from'] );

		Customers::insert( $data );
		$customer = Customers::get( 'id', Customers::insert_id() );

		wp_send_json_success(
			array(
				'customer' => $customer,
				'message'  => __( 'Customer Saved!', 'bookit' ),
			)
		);
	}

	/**
	 * Save Customer
	 */
	public static function save() {
		check_ajax_referer( 'bookit_save_item', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			return false;
		}

		$data = CleanHelper::cleanData( $_POST, self::getCleanRules() );
		self::validate( $data );

		if ( ! empty( $data ) ) {
			if ( ! empty( $data['id'] ) ) {
				Customers::update( $data, array( 'id' => $data['id'] ) );
			} else {
				Customers::insert( $data );
				$data['id'] = Customers::insert_id();
			}

			do_action( 'bookit_customer_saved', $data['id'] );

			$customer = Customers::get( 'id', $data['id'] );

			wp_send_json_success(
				array(
					'id'       => $data['id'],
					'customer' => $customer,
					'message'  => __( 'Customer Saved!', 'bookit' ),
				)
			);
		}

		wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
	}

	/** Get Service Assosiated data by id **/
	public static function get_assosiated_total_data_by_id() {
		check_ajax_referer( 'bookit_get_customer_assosiated_total_data', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			return false;
		}

		$data = CleanHelper::cleanData( $_POST, self::getCleanRules() );

		if ( empty( $data['id'] ) ) {
			wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
		}

		$appointments = Appointments::get_total_active_assosiated_appointments( '', '', $data['id'] );

		$response = array( 'total' => array( 'appointments' => $appointments ) );
		wp_send_json_success( $response );
	}

	/**
	 * Delete the Customer
	 */
	public static function delete() {
		check_ajax_referer( 'bookit_delete_item', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			return false;
		}

		$data = CleanHelper::cleanData( $_GET, self::getCleanRules() );

		if ( isset( $data['id'] ) ) {

			$id = $data['id'];
			Customers::deleteCustomer( $id );
			do_action( 'bookit_customer_deleted', $id );
			wp_send_json_success( array( 'message' => __( 'Customer Deleted!', 'bookit' ) ) );
		}

		wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
	}
}

```
