# booktics/1.0.0/core/cart/controllers/cart-controller.php

Booktics – Appointment Booking Calendar for Service Businesses, version 1.0.0. 345 lines.

- Page: https://pluginprobe.com/plugins/booktics/1.0.0/code/core/cart/controllers/cart-controller.php
- Raw: https://pluginprobe.com/plugins/booktics/1.0.0/raw/core/cart/controllers/cart-controller.php
- Modified: 2025-07-03T16:48:18+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/booktics/1.0.0/code/core/cart/controllers/cart-controller.php#L10-L20`.

```php
<?php

namespace Booktics\Cart\Controllers;

use Booktics\Abstracts\Base_Rest_Controller;
use Booktics\Cart\Cart_Manager;
use Booktics\Models\Service_Model;
use Booktics\Models\Team_Member_Model;
use WP_Error;
use WP_REST_Response;
use WP_REST_Server;

class Cart_Controller extends Base_Rest_Controller {

    /**
     * Endpoint namespace
     *
     * @var string
     */
    protected $namespace = 'booktics/v1';

    /**
     * Route name
     *
     * @var string
     */
    protected $base = 'carts';

    /**
     * @var Cart_Manager
     */
    private $cart_manager;

    /**
     * Initialize CartController with a new CartManager instance
     */
    public function __construct() {
        $this->cart_manager = new Cart_Manager();
    }

    /**
     * Register REST API routes for cart functionality
     *
     * @return void
     */
    public function register_routes(): void {
        register_rest_route(
            $this->namespace,
            $this->base,
            array(
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => array( $this, 'add_to_cart' ),
                'permission_callback' => '__return_true',
            )
        );

        register_rest_route(
            $this->namespace,
            $this->base . '/(?P<uuid>[a-zA-Z0-9-]+)',
            array(
                'methods'             => WP_REST_Server::DELETABLE,
                'callback'            => array( $this, 'delete_from_cart' ),
                'permission_callback' => '__return_true',
            )
        );

        register_rest_route(
            $this->namespace,
            $this->base,
            array(
                'methods'             => WP_REST_Server::EDITABLE,
                'callback'            => array( $this, 'sync_cart' ),
                'permission_callback' => array( $this, 'is_user_logged_in' ),
            )
        );

        register_rest_route(
            $this->namespace,
            $this->base . '/(?P<uuid>[a-zA-Z0-9-]+)',
            array(
                'methods'             => WP_REST_Server::EDITABLE,
                'callback'            => array( $this, 'edit_cart_item' ),
                'permission_callback' => '__return_true',
            )
        );

        register_rest_route(
            $this->namespace,
            $this->base,
            array(
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => array( $this, 'get_cart_items' ),
                'permission_callback' => '__return_true',
            )
        );
    }

    /**
     * Prepare and validate cart item data
     *
     * @param array $data
     *
     * @return []|array|bool|WP_Error
     */
    private function prepare_item_to_save( array $data ) {
        $validated = booktics_validate(
            $data, array(
				'date'           => array( 'required' ),
				'start_time'     => array( 'required' ),
				'service_id'     => array( 'required' ),
				'team_member_id' => array( 'required' ),
            )
        );

        if ( is_wp_error( $validated ) ) {
            return $validated;
        }

        $item_validation = $this->validate_cart_item( $data );
        if ( is_wp_error( $item_validation ) ) {
            return $item_validation;
        }

        return $item_validation;
    }

    /**
     * Add an item to the cart
     *
     * @param $request
     *
     * @return array|\WP_HTTP_Response
     */
    public function add_to_cart( $request ) {
        $params    = json_decode( $request->get_body(), true );
        $validated = $this->prepare_item_to_save( $params );

        if ( is_wp_error( $validated ) ) {
            return $this->error(
                __( 'Cart validation error', 'booktics' ),
                422,
                'Validation',
                $validated->errors
            );
        }
        $response            = $this->cart_manager->add_to_cart( $validated );
        $response['service'] = $this->get_service( $response['service_id'] );
        $response['team']    = $this->get_team_member( $response['team_member_id'] );

        return $this->response( $response, __( 'Item added to cart', 'booktics' ), 201 );
    }

    /**
     * Delete an item from the user's cart
     *
     * @param $request
     *
     * @return array|\WP_HTTP_Response
     */
    public function delete_from_cart( $request ) {
        $uuid = $request->get_param( 'uuid' );

        if ( empty( $uuid ) ) {
            return $this->error(
                __( 'UUID is required', 'booktics' ),
                422,
                'Validation'
            );
        }

        $this->cart_manager->remove_cart_item( $uuid );

        return $this->response( array(), __( 'Successfully deleted item from cart.', 'booktics' ) );
    }

    /**
     * Synchronize cart session data to database for logged-in user
     *
     * @param $request
     *
     * @return array|\WP_HTTP_Response
     */
    public function sync_cart( $request ) {
        $user_id = get_current_user_id();
        $this->cart_manager->sync_session_to_db( $user_id );

        $response = $this->cart_manager->get_cart();

        return $this->response( $response, __( 'Successfully synced cart.', 'booktics' ) );
    }

    /**
     * Get all items from the cart
     *
     * @return array|\WP_HTTP_Response
     */
    public function get_cart_items() {
        $response          = $this->cart_manager->get_cart();
        $response['items'] = isset( $response['items'] ) ? array_map(
            function ( $item ) {
                if ( ! is_array( $item ) ) {
                        $item = (array) $item;
                }

                $item['service'] = $this->get_service( $item['service_id'] );
                $item['team']    = $this->get_team_member( $item['team_member_id'] );

                return $item;
            }, $response['items']
        ) : array();

        return $this->response( $response, __( 'Cart items fetched successfully', 'booktics' ) );
    }

    /**
     * Check if the current user is logged in
     *
     * @return bool True if user is logged in, false otherwise
     */
    public function is_user_logged_in() {
        return is_user_logged_in();
    }

    /**
     * Validate service, team member and price
     *
     * @param array $data Cart item data
     *
     * @return array|WP_Error Returns true if valid, WP_Error otherwise
     */
    private function validate_cart_item( array $data ) {
        $error = new WP_Error();

        $service = ( new Service_Model() )->find( $data['service_id'] );
        if ( ! $service ) {
            $error->add( 'invalid_service', __( 'Invalid service selected', 'booktics' ) );
        }

        $team_member = ( new Team_Member_Model() )->find( $data['team_member_id'] );
        if ( empty( $team_member ) ) {
            $error->add( 'invalid_team_member', __( 'Invalid team member selected', 'booktics' ) );
        }

        $service_price      = 0;
        $addition_durations = $service->additional_durations;
        if ( ! empty( $addition_durations ) && isset( $data['additional_duration_id'] ) ) {
            $addition_durations = array_filter(
                $addition_durations, function ( $duration ) use ( $data ) {
					return $duration['id'] === $data['additional_duration_id'];
				}
            );
            $addition_duration  = reset( $addition_durations );
            $service_price      = $addition_duration['charge_amount'] ?? 0;
        }
        $data['price'] = $service_price;

        return $error->has_errors() ? $error : $data;
    }

    /**
     * Edit a cart item
     *
     * @param $request
     *
     * @return array|\WP_HTTP_Response
     */
    public function edit_cart_item( $request ) {
        $uuid   = $request->get_param( 'uuid' );
        $params = json_decode( $request->get_body(), true );

        if ( empty( $uuid ) ) {
            return $this->error(
                __( 'UUID is required', 'booktics' ),
                422,
                'Validation'
            );
        }

        $validated = $this->prepare_item_to_save( $params );
        if ( is_wp_error( $validated ) ) {
            return $this->error(
                __( 'Cart validation error', 'booktics' ),
                422,
                'Validation',
                $validated->errors
            );
        }

        // Add UUID to validated data
        $validated['uuid'] = $uuid;

        // Update the cart item
        $updated_item = $this->cart_manager->edit_cart_item( $uuid, $validated );

        if ( empty( $updated_item ) ) {
            return $this->error(
                __( 'Cart item not found', 'booktics' ),
                404,
                'NotFound'
            );
        }

        return $this->response(
            $updated_item,
            __( 'Successfully updated cart item', 'booktics' )
        );
    }

    /**
     * @param $service_id
     *
     * @return array
     */
    public function get_service( $service_id ): array {
        $service = Service_Model::find( $service_id );
        if ( empty( $service ) ) {
            return array();
        }

        return array(
            'id'    => $service->id,
            'title' => $service->title,
        );
    }

    /**
     * @param $team_member_id
     *
     * @return array
     */
    public function get_team_member( $team_member_id ): array {
        $team_member = ( new Team_Member_Model() )->find( $team_member_id );
        if ( empty( $team_member ) ) {
            return array();
        }
        $team_member = $team_member->to_array();

        return array(
            'id'           => $team_member['id'],
            'display_name' => $team_member['display_name'] ?? '',
            'image'        => $team_member['image'] ?? '',
        );
    }
}

```
