Files
care-book-block-ultimate/BACKUP-ESSENTIALS/PRODUCTION-READY/care-booking-block-ultimate/includes/class-restriction-model.php
Emanuel Almeida 38bb926742 chore: add spec-kit and standardize signatures
- Added GitHub spec-kit for development workflow
- Standardized file signatures to Descomplicar® format
- Updated development configuration

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-12 01:27:34 +01:00

475 lines
13 KiB
PHP

/**
* Descomplicar® Crescimento Digital
* https://descomplicar.pt
*/
<?php
/**
* Restriction model for Care Booking Block plugin
*
* @package CareBookingBlock
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
/**
* Restriction model class
*/
class Care_Booking_Restriction_Model
{
/**
* Database handler instance
*
* @var Care_Booking_Database_Handler
*/
private $db_handler;
/**
* Cache manager instance
*
* @var Care_Booking_Cache_Manager
*/
private $cache_manager;
/**
* Constructor
*/
public function __construct()
{
$this->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())
];
}
}