/** * Descomplicar® Crescimento Digital * https://descomplicar.pt */ db_handler = new Care_Booking_Database_Handler(); $this->cache_manager = new Care_Booking_Cache_Manager(); } /** * Create new restriction * * @param array $data Restriction data * @return int|false Restriction ID on success, false on failure */ public function create($data) { // Validate data if (!$this->validate_restriction_data($data)) { return false; } // Check if restriction already exists $existing = $this->find_existing( $data['restriction_type'], $data['target_id'], isset($data['doctor_id']) ? $data['doctor_id'] : null ); if ($existing) { // Update existing restriction return $this->update($existing->id, $data) ? (int) $existing->id : false; } // Create new restriction $result = $this->db_handler->insert($data); if ($result) { // Invalidate cache $this->invalidate_cache(); // Trigger action do_action( 'care_booking_restriction_created', $data['restriction_type'], $data['target_id'], isset($data['doctor_id']) ? $data['doctor_id'] : null ); } return $result; } /** * Get restriction by ID * * @param int $id Restriction ID * @return object|false Restriction object or false if not found */ public function get($id) { return $this->db_handler->get($id); } /** * Update restriction * * @param int $id Restriction ID * @param array $data Update data * @return bool True on success, false on failure */ public function update($id, $data) { // Validate update data if (!$this->validate_update_data($data)) { return false; } $result = $this->db_handler->update($id, $data); if ($result) { // Invalidate cache $this->invalidate_cache(); // Get updated restriction for action $restriction = $this->get($id); if ($restriction) { // Trigger action do_action( 'care_booking_restriction_updated', $restriction->restriction_type, $restriction->target_id, $restriction->doctor_id ); } } return $result; } /** * Delete restriction * * @param int $id Restriction ID * @return bool True on success, false on failure */ public function delete($id) { // Get restriction before deletion for action $restriction = $this->get($id); $result = $this->db_handler->delete($id); if ($result && $restriction) { // Invalidate cache $this->invalidate_cache(); // Trigger action do_action( 'care_booking_restriction_deleted', $restriction->restriction_type, $restriction->target_id, $restriction->doctor_id ); } return $result; } /** * Get restrictions by type * * @param string $type Restriction type ('doctor' or 'service') * @return array Array of restriction objects */ public function get_by_type($type) { return $this->db_handler->get_by_type($type); } /** * Get all restrictions * * @return array Array of restriction objects */ public function get_all() { return $this->db_handler->get_all(); } /** * Get blocked doctors (with caching) * * @return array Array of blocked doctor IDs */ public function get_blocked_doctors() { // Try to get from cache first $blocked_doctors = $this->cache_manager->get_blocked_doctors(); if ($blocked_doctors === false) { // Cache miss - get from database $blocked_doctors = $this->db_handler->get_blocked_doctors(); // Cache the result $this->cache_manager->set_blocked_doctors($blocked_doctors); } return $blocked_doctors; } /** * Get blocked services for specific doctor (with caching) * * @param int $doctor_id Doctor ID * @return array Array of blocked service IDs */ public function get_blocked_services($doctor_id) { // Try to get from cache first $blocked_services = $this->cache_manager->get_blocked_services($doctor_id); if ($blocked_services === false) { // Cache miss - get from database $blocked_services = $this->db_handler->get_blocked_services($doctor_id); // Cache the result $this->cache_manager->set_blocked_services($doctor_id, $blocked_services); } return $blocked_services; } /** * Find existing restriction * * @param string $type Restriction type * @param int $target_id Target ID * @param int $doctor_id Doctor ID (for service restrictions) * @return object|false Restriction object or false if not found */ public function find_existing($type, $target_id, $doctor_id = null) { return $this->db_handler->find_existing($type, $target_id, $doctor_id); } /** * Toggle restriction (create if not exists, update if exists) * * @param string $type Restriction type * @param int $target_id Target ID * @param int $doctor_id Doctor ID (for service restrictions) * @param bool $is_blocked Whether to block or unblock * @return int|bool Restriction ID if created, true if updated, false on failure */ public function toggle($type, $target_id, $doctor_id = null, $is_blocked = true) { // Validate parameters if (!in_array($type, ['doctor', 'service'])) { return false; } if ($type === 'service' && !$doctor_id) { return false; } // Check if restriction exists $existing = $this->find_existing($type, $target_id, $doctor_id); if ($existing) { // Update existing restriction return $this->update($existing->id, ['is_blocked' => $is_blocked]); } else { // Create new restriction $data = [ 'restriction_type' => $type, 'target_id' => $target_id, 'is_blocked' => $is_blocked ]; if ($doctor_id) { $data['doctor_id'] = $doctor_id; } return $this->create($data); } } /** * Bulk create restrictions * * @param array $restrictions Array of restriction data * @return array Array of results (IDs for successful, false for failed) */ public function bulk_create($restrictions) { if (!is_array($restrictions) || empty($restrictions)) { return []; } $results = []; foreach ($restrictions as $restriction_data) { $result = $this->create($restriction_data); $results[] = $result; } return $results; } /** * Bulk toggle restrictions * * @param array $restrictions Array of restriction toggle data * @return array Array of results with success/error information */ public function bulk_toggle($restrictions) { if (!is_array($restrictions) || empty($restrictions)) { return ['updated' => 0, 'errors' => []]; } $updated = 0; $errors = []; foreach ($restrictions as $restriction_data) { try { // Validate required fields if (!isset($restriction_data['restriction_type']) || !isset($restriction_data['target_id'])) { $errors[] = [ 'restriction' => $restriction_data, 'error' => 'Missing required fields' ]; continue; } $result = $this->toggle( $restriction_data['restriction_type'], $restriction_data['target_id'], isset($restriction_data['doctor_id']) ? $restriction_data['doctor_id'] : null, isset($restriction_data['is_blocked']) ? $restriction_data['is_blocked'] : true ); if ($result) { $updated++; } else { $errors[] = [ 'restriction' => $restriction_data, 'error' => 'Failed to update restriction' ]; } } catch (Exception $e) { $errors[] = [ 'restriction' => $restriction_data, 'error' => $e->getMessage() ]; } } return [ 'updated' => $updated, 'errors' => $errors ]; } /** * Check if doctor is blocked * * @param int $doctor_id Doctor ID * @return bool True if blocked, false otherwise */ public function is_doctor_blocked($doctor_id) { $blocked_doctors = $this->get_blocked_doctors(); return in_array((int) $doctor_id, $blocked_doctors); } /** * Check if service is blocked for specific doctor * * @param int $service_id Service ID * @param int $doctor_id Doctor ID * @return bool True if blocked, false otherwise */ public function is_service_blocked($service_id, $doctor_id) { $blocked_services = $this->get_blocked_services($doctor_id); return in_array((int) $service_id, $blocked_services); } /** * Validate restriction data * * @param array $data Restriction data to validate * @return bool True if valid, false otherwise */ private function validate_restriction_data($data) { // Check required fields if (!isset($data['restriction_type']) || !isset($data['target_id'])) { return false; } // Validate restriction type if (!in_array($data['restriction_type'], ['doctor', 'service'])) { return false; } // Validate target_id if (!is_numeric($data['target_id']) || (int) $data['target_id'] <= 0) { return false; } // Service restrictions require doctor_id if ($data['restriction_type'] === 'service') { if (!isset($data['doctor_id']) || !is_numeric($data['doctor_id']) || (int) $data['doctor_id'] <= 0) { return false; } } return true; } /** * Validate update data * * @param array $data Update data to validate * @return bool True if valid, false otherwise */ private function validate_update_data($data) { if (empty($data)) { return false; } // Validate restriction_type if provided if (isset($data['restriction_type']) && !in_array($data['restriction_type'], ['doctor', 'service'])) { return false; } // Validate target_id if provided if (isset($data['target_id']) && (!is_numeric($data['target_id']) || (int) $data['target_id'] <= 0)) { return false; } // Validate doctor_id if provided if (isset($data['doctor_id']) && (!is_numeric($data['doctor_id']) || (int) $data['doctor_id'] <= 0)) { return false; } return true; } /** * Invalidate all related caches */ private function invalidate_cache() { $this->cache_manager->invalidate_all(); // Trigger cache invalidation action do_action('care_booking_cache_invalidated'); } /** * Get statistics * * @return array Array of statistics */ public function get_statistics() { return [ 'total_restrictions' => count($this->get_all()), 'doctor_restrictions' => count($this->get_by_type('doctor')), 'service_restrictions' => count($this->get_by_type('service')), 'blocked_doctors' => count($this->get_blocked_doctors()) ]; } }