- 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>
475 lines
13 KiB
PHP
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())
|
|
];
|
|
}
|
|
} |