# timetics/1.0.0/core/bookings/api-booking.php

Timetics – Appointment Booking Calendar &amp; Scheduling, version 1.0.0. 692 lines.

- Page: https://pluginprobe.com/plugins/timetics/1.0.0/code/core/bookings/api-booking.php
- Raw: https://pluginprobe.com/plugins/timetics/1.0.0/raw/core/bookings/api-booking.php
- Modified: 2023-01-30T14:51:10+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/timetics/1.0.0/code/core/bookings/api-booking.php#L10-L20`.

```php
<?php
/**
 * Booking api
 *
 * @package Timetics
 */
namespace Timetics\Core\Bookings;

use Timetics\Base\Api;
use Timetics\Core\Appointments\Appointment;
use Timetics\Core\Customers\Customer;
use Timetics\Core\Emails\New_Event_Email;
use Timetics\Core\Staffs\Staff;
use Timetics\Utils\Singleton;
use WP_HTTP_Response;
use WP_Query;

class Api_Booking extends Api {
    use Singleton;

    /**
     * Store api namespace
     *
     * @var string
     */
    protected $namespace = 'timetics/v1';

    /**
     * Store rest base
     *
     * @var string
     */
    protected $rest_base = 'bookings';

    /**
     * Register rest routes
     *
     * @return  void
     */
    public function register_routes() {
        /**
         * Register route
         *
         * @var void
         */
        register_rest_route(
            $this->namespace, $this->rest_base, [
                [
                    'methods'             => \WP_REST_Server::READABLE,
                    'callback'            => [ $this, 'get_items' ],
                    'permission_callback' => function () {
                        return current_user_can( 'manage_timetics' );
                    },
                ],
                [
                    'methods'             => \WP_REST_Server::CREATABLE,
                    'callback'            => [ $this, 'create_item' ],
                    'permission_callback' => function () {
                        return true;
                    },
                ],
                [
                    'methods'             => \WP_REST_Server::DELETABLE,
                    'callback'            => [ $this, 'bulk_delete' ],
                    'permission_callback' => function () {
                        return current_user_can( 'edit_booking' );
                    },
                ],
            ]
        );

        /**
         * Register route
         *
         * @var void
         */
        register_rest_route(
            $this->namespace, '/' . $this->rest_base . '/(?P<booking_id>[\d]+)', [
                [
                    'methods'             => \WP_REST_Server::READABLE,
                    'callback'            => [ $this, 'get_item' ],
                    'permission_callback' => function () {
                        return current_user_can( 'manage_timetics' );
                    },
                ],
                [
                    'methods'             => \WP_REST_Server::EDITABLE,
                    'callback'            => [ $this, 'update_item' ],
                    'permission_callback' => function () {
                        return true;
                    },
                ],
                [
                    'methods'             => \WP_REST_Server::DELETABLE,
                    'callback'            => [ $this, 'delete_item' ],
                    'permission_callback' => function () {
                        return current_user_can( 'edit_booking' );
                    },
                ],
            ]
        );

        register_rest_route(
            $this->namespace, '/' . $this->rest_base . '/(?P<booking_id>[\d]+)/payment', [
                [
                    'methods'             => \WP_REST_Server::EDITABLE,
                    'callback'            => [ $this, 'make_payment' ],
                    'permission_callback' => function () {
                        return true;
                    },
                ],
            ]
        );

        register_rest_route(
            $this->namespace, $this->rest_base . '/search', [
                [
                    'methods'             => \WP_REST_Server::READABLE,
                    'callback'            => [ $this, 'search_items' ],
                    'permission_callback' => function () {
                        return current_user_can( 'edit_posts' );
                    },
                ],
            ]
        );

        register_rest_route(
            $this->namespace, $this->rest_base . '/entries', [
                [
                    'methods'             => \WP_REST_Server::READABLE,
                    'callback'            => [ $this, 'get_entries' ],
                    'permission_callback' => function () {
                        return true;
                    },
                ],
            ]
        );
    }

    /**
     * Get all bookings
     *
     * @param   WP_Rest_Request  $request
     *
     * @return JSON
     */
    public function get_items( $request ) {
        $per_page   = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
        $paged      = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
        $meeting_id = ! empty( $request['meeting_id'] ) ? intval( $request['meeting_id'] ) : 0;
        $staff_id   = ! current_user_can( 'edit_booking' ) ? get_current_user_id() : 0;

        $args = [
            'posts_per_page' => $per_page,
            'paged'          => $paged,
            'meeting'        => $meeting_id,
            'staff'          => $staff_id,
        ];
        $appoint = Booking::all( $args );

        $items = [];

        foreach ( $appoint['items'] as $item ) {
            $items[] = $this->prepare_item( $item->ID );
        }

        $data = [
            'success'     => 1,
            'status_code' => 200,
            'data'        => [
                'total' => $appoint['total'],
                'items' => $items,
            ],
        ];

        return rest_ensure_response( $data );
    }

    /**
     * Get single booking
     *
     * @param   WP_Rest_Request  $request
     *
     * @return  JSON
     */
    public function get_item( $request ) {
        $booking_id = (int) $request['booking_id'];
        $booking    = new Booking( $booking_id );

        if ( ! $booking->is_booking() ) {
            return [
                'success'     => 0,
                'status_code' => 404,
                'message'     => __( 'Invalid booking id.', 'timetics' ),
                'data'        => [],
            ];
        }

        $data = [
            'success'     => 1,
            'status_code' => 200,
            'data'        => $this->prepare_item( $booking ),
        ];

        return rest_ensure_response( $data );
    }

    /**
     * Create booking
     *
     * @param   WP_Rest_Request  $request
     *
     * @return JSON
     */
    public function create_item( $request ) {
        return $this->save_bookings( $request );
    }

    /**
     * Update booking
     *
     * @param   WP_Rest_Request  $request
     *
     * @return  JSON
     */
    public function update_item( $request ) {
        $booking_id = (int) $request['booking_id'];
        $booking    = new Booking( $booking_id );

        if ( ! $booking->is_booking() ) {
            return [
                'status_code' => 404,
                'message'     => __( 'Invalid booking id.', 'timetics' ),
                'data'        => [],
            ];
        }

        return $this->save_bookings( $request, $booking_id );
    }

    /**
     * Delete booking
     *
     * @param   WP_Rest_Request  $request
     *
     * @return  JSON
     */
    public function delete_item( $request ) {
        $booking_id = (int) $request['booking_id'];
        $booking    = new Booking( $booking_id );

        if ( ! $booking->is_booking() ) {
            return [
                'status_code' => 404,
                'message'     => __( 'Invalid booking id.', 'timetics' ),
                'data'        => [],
            ];
        }

        $booking->delete_event();
        $booking->delete();

        $data = [
            'success'     => 1,
            'status_code' => 200,
            'message'     => __( 'Successfully deleted booking', 'timetics' ),
            'data'        => [],
        ];

        return rest_ensure_response( $data );
    }

    /**
     * Delete multiples
     *
     * @param   WP_Rest_Request  $request
     *
     * @return JSON
     */
    public function bulk_delete( $request ) {
        $bookings = json_decode( $request->get_body(), true );

        foreach ( $bookings as $booking ) {
            $booking = new Booking( $booking );

            if ( ! $booking->is_booking() ) {
                return [
                    'success'     => 0,
                    'status_code' => 404,
                    'message'     => __( 'Invalid booking id.', 'timetics' ),
                    'data'        => [],
                ];
            }

            $booking->delete();
        }

        return [
            'success'     => 1,
            'status_code' => 200,
            'message'     => __( 'Successfully deleted booking', 'timetics' ),
        ];
    }

    /**
     * Search bookings
     *
     * @param   WP_Rest_Request  $request
     *
     * @return  JSON
     */
    public function search_items( $request ) {
        // Prepare search args.
        $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
        $paged    = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
        $search   = ! empty( $request['search'] ) ? sanitize_text_field( $request['search'] ) : '';

        // Get search.
        $booking = new WP_Query(
            array(
                'post_type'      => 'timetics-booking',
                'posts_per_page' => $per_page,
                'paged'          => $paged,
                'post_status'    => 'any',

                // @codingStandardsIgnoreStart
                'meta_query' => array(
                    'relation' => 'OR',
                    array(
                        'key'     => '_tt_booking_customer_fname',
                        'value'   => $search,
                        'compare' => 'LIKE',
                    ),
                    array(
                        'key'     => '_tt_booking_customer_lname',
                        'value'   => $search,
                        'compare' => 'LIKE',
                    ),
                    array(
                        'key'     => '_tt_booking_customer_email',
                        'value'   => $search,
                        'compare' => 'LIKE',
                    ),
                    array(
                        'key'     => '_tt_booking_customer_phone',
                        'value'   => $search,
                        'compare' => 'LIKE',
                    ),
                    array(
                        'key'     => '_tt_booking_staff_fname',
                        'value'   => $search,
                        'compare' => 'LIKE',
                    ),
                    array(
                        'key'     => '_tt_booking_staff_lname',
                        'value'   => $search,
                        'compare' => 'LIKE',
                    ),
                    array(
                        'key'     => '_tt_booking_staff_email',
                        'value'   => $search,
                        'compare' => 'LIKE',
                    ),
                    array(
                        'key'     => '_tt_booking_meeting_name',
                        'value'   => $search,
                        'compare' => 'LIKE',
                    ),
                    array(
                        'key'     => '_tt_booking_meeting_description',
                        'value'   => $search,
                        'compare' => 'LIKE',
                    ),
                    array(
                        'key'     => '_tt_booking_meeting_type',
                        'value'   => $search,
                        'compare' => 'LIKE',
                    ),
                ),
                // @codingStandardsIgnoreEnd
            )
        );

        // Prepare items for response.
        $items = [];

        foreach ( $booking->posts as $item ) {
            $items[] = $this->prepare_item( $item->ID );
        }

        $data = [
            'success' => 1,
            'status'  => 200,
            'data'    => [
                'total' => $booking->found_posts,
                'items' => $items,
            ],
        ];

        return rest_ensure_response( $data );
    }

    /**
     * Get all booking entries
     *
     * @param   WP_Rest_Request  $request
     *
     * @return JSON
     */
    public function get_entries( $request ) {
        $staff_id   = ! empty( $request['staff_id'] ) ? intval( $request['staff_id'] ) : 0;
        $meeting_id = ! empty( $request['meeting_id'] ) ? intval( $request['meeting_id'] ) : 0;
        $start_date = ! empty( $request['start_date'] ) ? sanitize_text_field( $request['start_date'] ) : 0;
        $end_date   = ! empty( $request['end_date'] ) ? sanitize_text_field( $request['end_date'] ) : 0;

        $meeting = new Appointment( $meeting_id );

        $days = $meeting->prepare_schedule( $start_date, $end_date, $staff_id );

        $data = [
            'today'                 => gmdate( 'Y-m-d' ),
            'availability_timezone' => $meeting->get_timezone(),
            'days'                  => $days,
        ];

        return [
            'success'     => true,
            'status_code' => 200,
            'message'     => __( 'Get all entries', 'timetics' ),
            'data'        => $data,
        ];
    }

    /**
     * Make payment transaction for the current booking
     *
     * @param   WP_Rest_Request  $request
     *
     * @return  JSON
     */
    public function make_payment( $request ) {
        $booking_id      = intval( $request['booking_id'] );
        $booking         = new Booking( $booking_id );
        $data            = json_decode( $request->get_body(), true );
        $status          = ! empty( $data['status'] ) ? sanitize_text_field( $data['status'] ) : '';
        $post_status     = 'succeeded' === $status ? 'completed' : 'pending';
        $payment_method  = ! empty( $data['payment_method'] ) ? sanitize_text_field( $data['payment_method'] ) : '';
        $payment_details = ! empty( $data['payment_details'] ) ? $data['payment_details'] : '';

        if ( ! $booking->is_booking() ) {
            return [
                'status_code' => 404,
                'message'     => __( 'Invalid booking id.', 'timetics' ),
                'data'        => [],
            ];
        }

        $update = $booking->update(
            [
				'post_status'     => $post_status,
				'payment_status'  => $status,
				'payment_details' => $payment_details,
				'payment_method'  => $payment_method,
			]
        );

        if ( is_wp_error( $update ) ) {
            $data = [
                'success'     => 0,
                'status_code' => 409,
                /* translators: Action */
                'message'     => $update->get_error_message(),
            ];

            return new WP_HTTP_Response( $data, 409 );
        }

        $data = [
            'success'     => 1,
            'status_code' => 200,
            /* translators: Action */
            'message'     => sprintf( __( 'Payment %s', 'timetics' ), $post_status ),
        ];

        return new WP_HTTP_Response( $data, 200 );
    }

    /**
     * Save booking
     *
     * @param   WP_Rest_Request  $request
     * @param   integer  $id       Booking id
     *
     * @return  JSON
     */
    public function save_bookings( $request, $id = 0 ) {
        $data = json_decode( $request->get_body(), true );

        $first_name     = ! empty( $data['first_name'] ) ? sanitize_text_field( $data['first_name'] ) : '';
        $last_name      = ! empty( $data['last_name'] ) ? sanitize_text_field( $data['last_name'] ) : '';
        $email          = ! empty( $data['email'] ) ? sanitize_text_field( $data['email'] ) : '';
        $phone          = ! empty( $data['phone'] ) ? sanitize_text_field( $data['phone'] ) : '';
        $city           = ! empty( $data['city'] ) ? sanitize_text_field( $data['city'] ) : '';
        $state          = ! empty( $data['state'] ) ? sanitize_text_field( $data['state'] ) : '';
        $post_code      = ! empty( $data['post_code'] ) ? sanitize_text_field( $data['post_code'] ) : '';
        $country        = ! empty( $data['country'] ) ? sanitize_text_field( $data['country'] ) : '';
        $payment_method = ! empty( $data['payment_method'] ) ? sanitize_text_field( $data['payment_method'] ) : '';
        $address_1      = ! empty( $data['address_1'] ) ? sanitize_text_field( $data['address_1'] ) : '';
        $address_2      = ! empty( $data['address_2'] ) ? sanitize_text_field( $data['address_2'] ) : '';
        $appointment    = ! empty( $data['appointment'] ) ? intval( $data['appointment'] ) : 0;
        $staff          = ! empty( $data['staff'] ) ? intval( $data['staff'] ) : 0;
        $start_date     = ! empty( $data['start_date'] ) ? sanitize_text_field( $data['start_date'] ) : '';
        $date           = ! empty( $data['date'] ) ? sanitize_text_field( $data['date'] ) : '';
        $end_date       = ! empty( $data['end_date'] ) ? sanitize_text_field( $data['end_date'] ) : $start_date;
        $start_time     = ! empty( $data['start_time'] ) ? sanitize_text_field( $data['start_time'] ) : '';
        $end_time       = ! empty( $data['end_time'] ) ? sanitize_text_field( $data['end_time'] ) : '';
        $order_total    = ! empty( $data['order_total'] ) ? intval( $data['order_total'] ) : 0;
        $status         = ! empty( $data['status'] ) ? sanitize_text_field( $data['status'] ) : 'publish';
        $location       = ! empty( $data['location'] ) ? sanitize_text_field( $data['location'] ) : '';
        $location_type  = ! empty( $data['location_type'] ) ? sanitize_text_field( $data['location_type'] ) : '';
        $action         = $id ? 'updated' : 'created';

        $validate = $this->validate(
            $data, [
                'first_name',
                'email',
                'payment_method',
                'appointment',
                'start_date',
                'start_time',
                'end_time',
            ]
        );

        if ( is_wp_error( $validate ) ) {
            $data = [
                'status_code' => 403,
                'success'     => 0,
                'message'     => $validate->get_error_messages(),
            ];
            return new WP_HTTP_Response( $data, 403 );
        }

        $customer = new Customer();
        $meeting  = new Appointment( $appointment );
        $staff    = new Staff( $staff );
        $customer->make(
            [
                'first_name' => $first_name,
                'last_name'  => $last_name,
                'email'      => $email,
                'phone'      => $phone,
            ]
        );

        $booking       = new Booking( $id );
        $booking_entry = new Booking_Entry();

        $booking->set_props(
            [
                'customer'            => $customer->get_id(),
                'appointment'         => $meeting->get_id(),
                'staff'               => $staff->get_id(),
                'customer_fname'      => $customer->get_first_name(),
                'customer_lname'      => $customer->get_last_name(),
                'customer_email'      => $customer->get_email(),
                'customer_phone'      => $customer->get_phone(),
                'staff_fname'         => $staff->get_first_name(),
                'staff_lname'         => $staff->get_last_name(),
                'staff_email'         => $staff->get_email(),
                'meeting_name'        => $meeting->get_name(),
                'meeting_description' => $meeting->get_description(),
                'meeting_type'        => $meeting->get_type(),
                'start_date'          => $start_date,
                'date'                => $date,
                'end_date'            => $end_date,
                'start_time'          => $start_time,
                'end_time'            => $end_time,
                'order_total'         => $order_total,
                'post_status'         => $status,
                'location'            => $location,
                'location_type'       => $location_type
            ]
        );

        $booking->save();

        // Create or update calendar event.
        if ( $id ) {
            $booking->update_event();
        } else {
            $booking->create_event();
            $new_event_email = new New_Event_Email( $booking );
            $new_event_email->send();
        }

        // Create booking schedule.
        $entries = $booking_entry->find(
            [
                'staff_id'   => $staff->get_id(),
                'meeting_id' => $meeting->get_id(),
                'date'       => $start_date,
                'start'      => $start_time,
            ]
        );

        if ( $entries ) {
            $entry  = $booking_entry->first();
            $booked = intval( $entry->get_booked() ) + 1;
            $entry->update( [ 'booked' => $booked ] );
        } else {
            $booking_entry->create(
                [
                    'meeting_id'  => $meeting->get_id(),
                    'staff_id'    => $staff->get_id(),
                    'customer_id' => $customer->get_id(),
                    'booking_id'  => $booking->get_id(),
                    'booked'      => 1,
                    'date'        => $start_date,
                    'start'       => $start_time,
                    'end'         => $end_time,
                ]
            );
        }

        $data = [
            'success'     => 1,
            'status_code' => 200,
            /* translators: Action */
            'message'     => sprintf( __( 'Successfully %s booking', 'timetics' ), $action ),
            'data'        => $this->prepare_item( $booking ),
        ];

        return new WP_HTTP_Response( $data, 200 );
    }

    /**
     * Prepare item for response
     *
     * @param   integer  $booking_id
     *
     * @return array
     */
    public function prepare_item( $booking_id ) {
        $booking     = new Booking( $booking_id );
        $appointment = new Appointment( $booking->get_appointment() );
        $staff       = new Staff( $booking->get_staff_id() );
        $customer    = new Customer( $booking->get_customer_id() );

        $start_date = gmdate( 'd F, Y', strtotime( $booking->get_start_date() ) );
        $end_date   = gmdate( 'd F, Y', strtotime( $booking->get_end_date() ) );
        $date       = gmdate( 'd F, Y', strtotime( $booking->get_date() ) );

        return [
            'id'          => $booking->get_id(),
            'random_id'   => $booking->get_random_id(),
            'status'      => $booking->get_status(),
            'order_total' => $booking->get_total(),
            'start_date'  => $start_date,
            'end_date'    => $end_date,
            'date'        => $date,
            'start_time'  => $booking->get_start_time(),
            'end_time'    => $booking->get_end_time(),
            'customer'    => [
                'id'           => $customer->get_id(),
                'full_name'    => $customer->get_display_name(),
                'first_name'   => $customer->get_first_name(),
                'last_name'    => $customer->get_last_name(),
                'email'        => $customer->get_email(),
            ],
            'appointment' => [
                'id'        => $appointment->get_id(),
                'name'      => $appointment->get_name(),
                'duration'  => $appointment->get_duration(),
                'type'      => $appointment->get_type(),
                'price'     => $appointment->get_price(),
                'locations' => $appointment->get_locations(),
                'timezone'  => $appointment->get_timezone(),
            ],
            'staff'       => [
                'id'           => $staff->get_id(),
                'full_name'    => $staff->get_display_name(),
                'first_name'   => $staff->get_first_name(),
                'last_name'    => $staff->get_last_name(),
                'email_name'   => $staff->get_email(),
                'phone'        => $staff->get_phone(),
                'image'        => $staff->get_image(),
            ],
        ];
    }
}

```
