793 lines
24 KiB
PHP
793 lines
24 KiB
PHP
/**
|
|
* ResponseOptimizer.php
|
|
*
|
|
* @package care-book-block-ultimate.src.Performance
|
|
* @author Descomplicar® Crescimento Digital
|
|
* @link https://descomplicar.pt
|
|
* @copyright 2025 Descomplicar® - Todos os direitos reservados
|
|
*/
|
|
|
|
<?php
|
|
/**
|
|
* AJAX Response Optimizer
|
|
*
|
|
* High-performance AJAX optimization with response compression and caching
|
|
* Target: <75ms response time, JSON compression, concurrent request handling
|
|
*
|
|
* @package CareBook\Ultimate\Performance
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace CareBook\Ultimate\Performance;
|
|
|
|
use CareBook\Ultimate\Cache\CacheManager;
|
|
|
|
/**
|
|
* Advanced AJAX response optimization for WordPress
|
|
*
|
|
* Features:
|
|
* - Response payload minification and compression
|
|
* - HTTP/2 optimization and connection reuse
|
|
* - Concurrent request batching and deduplication
|
|
* - Response caching with intelligent invalidation
|
|
* - JSON optimization and binary data handling
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
final class ResponseOptimizer
|
|
{
|
|
private CacheManager $cacheManager;
|
|
private array $responseMetrics = [];
|
|
private array $batchQueue = [];
|
|
private array $compressionStats = [];
|
|
private bool $compressionEnabled = false;
|
|
|
|
private const TARGET_RESPONSE_TIME = 75; // 75ms target
|
|
private const COMPRESSION_THRESHOLD = 1024; // 1KB minimum for compression
|
|
private const BATCH_TIMEOUT = 50; // 50ms batch collection timeout
|
|
private const MAX_BATCH_SIZE = 10; // Maximum requests per batch
|
|
|
|
/**
|
|
* Constructor with dependency injection
|
|
*
|
|
* @param CacheManager $cacheManager Cache manager instance
|
|
* @since 1.0.0
|
|
*/
|
|
public function __construct(CacheManager $cacheManager)
|
|
{
|
|
$this->cacheManager = $cacheManager;
|
|
$this->initializeOptimizer();
|
|
}
|
|
|
|
/**
|
|
* Optimize AJAX response with compression and caching
|
|
*
|
|
* @param array $data Response data
|
|
* @param array $options Response options
|
|
* @return array Optimized response
|
|
* @since 1.0.0
|
|
*/
|
|
public function optimizeResponse(array $data, array $options = []): array
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
// Generate response cache key
|
|
$cacheKey = $this->generateResponseCacheKey($data, $options);
|
|
|
|
// Try cached response first
|
|
if ($options['use_cache'] ?? true) {
|
|
$cachedResponse = $this->cacheManager->get(
|
|
"ajax_response_{$cacheKey}",
|
|
null,
|
|
$options['cache_ttl'] ?? 300 // 5 minutes default
|
|
);
|
|
|
|
if ($cachedResponse !== null) {
|
|
$this->recordResponseMetric($startTime, true, strlen(json_encode($cachedResponse)));
|
|
return $this->finalizeResponse($cachedResponse, $options);
|
|
}
|
|
}
|
|
|
|
// Optimize response data
|
|
$optimizedData = $this->optimizeResponseData($data, $options);
|
|
|
|
// Apply compression if beneficial
|
|
if ($this->shouldCompressResponse($optimizedData, $options)) {
|
|
$optimizedData = $this->compressResponse($optimizedData, $options);
|
|
}
|
|
|
|
// Cache optimized response
|
|
if ($options['use_cache'] ?? true) {
|
|
$this->cacheManager->set(
|
|
"ajax_response_{$cacheKey}",
|
|
$optimizedData,
|
|
$options['cache_ttl'] ?? 300
|
|
);
|
|
}
|
|
|
|
$this->recordResponseMetric($startTime, false, strlen(json_encode($optimizedData)));
|
|
|
|
return $this->finalizeResponse($optimizedData, $options);
|
|
}
|
|
|
|
/**
|
|
* Batch multiple AJAX requests for efficiency
|
|
*
|
|
* @param array $requests Array of request configurations
|
|
* @param array $options Batch options
|
|
* @return array Batch response
|
|
* @since 1.0.0
|
|
*/
|
|
public function batchRequests(array $requests, array $options = []): array
|
|
{
|
|
$startTime = microtime(true);
|
|
$batchId = uniqid('batch_', true);
|
|
|
|
// Process requests in parallel simulation
|
|
$responses = [];
|
|
$errors = [];
|
|
|
|
foreach ($requests as $index => $request) {
|
|
try {
|
|
$response = $this->processIndividualRequest($request, $options);
|
|
$responses[$index] = $response;
|
|
} catch (\Exception $e) {
|
|
$errors[$index] = [
|
|
'error' => $e->getMessage(),
|
|
'code' => $e->getCode()
|
|
];
|
|
}
|
|
}
|
|
|
|
$executionTime = (microtime(true) - $startTime) * 1000;
|
|
|
|
$batchResponse = [
|
|
'batch_id' => $batchId,
|
|
'responses' => $responses,
|
|
'errors' => $errors,
|
|
'execution_time' => $executionTime,
|
|
'requests_count' => count($requests),
|
|
'success_count' => count($responses),
|
|
'error_count' => count($errors)
|
|
];
|
|
|
|
$this->recordBatchMetric($batchResponse);
|
|
|
|
return $batchResponse;
|
|
}
|
|
|
|
/**
|
|
* Stream large responses for memory efficiency
|
|
*
|
|
* @param callable $dataProvider Data provider callback
|
|
* @param array $options Streaming options
|
|
* @return void
|
|
* @since 1.0.0
|
|
*/
|
|
public function streamResponse(callable $dataProvider, array $options = []): void
|
|
{
|
|
// Set appropriate headers for streaming
|
|
$this->setStreamingHeaders($options);
|
|
|
|
// Start output buffering with compression
|
|
if ($this->compressionEnabled && ($options['compress'] ?? true)) {
|
|
ob_start('gzhandler');
|
|
} else {
|
|
ob_start();
|
|
}
|
|
|
|
echo '{"data":[';
|
|
|
|
$isFirst = true;
|
|
$totalItems = 0;
|
|
|
|
foreach ($dataProvider() as $item) {
|
|
if (!$isFirst) {
|
|
echo ',';
|
|
}
|
|
|
|
echo json_encode($item, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
|
|
|
// Flush every 100 items to prevent memory buildup
|
|
if (++$totalItems % 100 === 0) {
|
|
ob_flush();
|
|
flush();
|
|
}
|
|
|
|
$isFirst = false;
|
|
}
|
|
|
|
echo '],"total":' . $totalItems . '}';
|
|
|
|
ob_end_flush();
|
|
}
|
|
|
|
/**
|
|
* Handle WebSocket-like real-time updates
|
|
*
|
|
* @param array $data Update data
|
|
* @param array $options Update options
|
|
* @return array Real-time response
|
|
* @since 1.0.0
|
|
*/
|
|
public function handleRealtimeUpdate(array $data, array $options = []): array
|
|
{
|
|
// For AJAX-based real-time updates (since WebSocket isn't available in this context)
|
|
$updateKey = $options['update_key'] ?? 'default';
|
|
|
|
// Store update for polling clients
|
|
$this->cacheManager->set(
|
|
"realtime_update_{$updateKey}",
|
|
[
|
|
'data' => $data,
|
|
'timestamp' => time(),
|
|
'version' => $options['version'] ?? 1
|
|
],
|
|
60 // 1 minute TTL for real-time data
|
|
);
|
|
|
|
return [
|
|
'status' => 'update_stored',
|
|
'update_key' => $updateKey,
|
|
'timestamp' => time(),
|
|
'data_size' => strlen(json_encode($data))
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Get performance metrics for AJAX responses
|
|
*
|
|
* @return array Performance metrics
|
|
* @since 1.0.0
|
|
*/
|
|
public function getPerformanceMetrics(): array
|
|
{
|
|
$recentMetrics = array_slice($this->responseMetrics, -100);
|
|
|
|
if (empty($recentMetrics)) {
|
|
return [
|
|
'total_responses' => 0,
|
|
'average_response_time' => 0,
|
|
'cache_hit_rate' => 0,
|
|
'compression_ratio' => 0,
|
|
'target_achievement_rate' => 0
|
|
];
|
|
}
|
|
|
|
$responseTimes = array_column($recentMetrics, 'response_time');
|
|
$cachedResponses = array_filter($recentMetrics, fn($m) => $m['cached']);
|
|
$targetAchieved = array_filter($recentMetrics, fn($m) => $m['response_time'] <= self::TARGET_RESPONSE_TIME);
|
|
|
|
return [
|
|
'total_responses' => count($recentMetrics),
|
|
'average_response_time' => array_sum($responseTimes) / count($responseTimes),
|
|
'median_response_time' => $this->calculateMedian($responseTimes),
|
|
'cache_hit_rate' => (count($cachedResponses) / count($recentMetrics)) * 100,
|
|
'compression_ratio' => $this->calculateCompressionRatio(),
|
|
'target_achievement_rate' => (count($targetAchieved) / count($recentMetrics)) * 100,
|
|
'batch_efficiency' => $this->calculateBatchEfficiency(),
|
|
'data_transfer_savings' => $this->calculateDataTransferSavings()
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Optimize response data structure and content
|
|
*
|
|
* @param array $data Response data
|
|
* @param array $options Optimization options
|
|
* @return array Optimized data
|
|
* @since 1.0.0
|
|
*/
|
|
private function optimizeResponseData(array $data, array $options): array
|
|
{
|
|
$optimized = $data;
|
|
|
|
// Remove null values to reduce payload size
|
|
if ($options['remove_nulls'] ?? true) {
|
|
$optimized = $this->removeNullValues($optimized);
|
|
}
|
|
|
|
// Compress repeated strings
|
|
if ($options['compress_strings'] ?? true) {
|
|
$optimized = $this->compressRepeatedStrings($optimized);
|
|
}
|
|
|
|
// Optimize numeric data
|
|
if ($options['optimize_numbers'] ?? true) {
|
|
$optimized = $this->optimizeNumbers($optimized);
|
|
}
|
|
|
|
// Remove unnecessary fields
|
|
if (!empty($options['exclude_fields'])) {
|
|
$optimized = $this->excludeFields($optimized, $options['exclude_fields']);
|
|
}
|
|
|
|
// Apply data transformation
|
|
if (!empty($options['transform_callback'])) {
|
|
$optimized = call_user_func($options['transform_callback'], $optimized);
|
|
}
|
|
|
|
return $optimized;
|
|
}
|
|
|
|
/**
|
|
* Determine if response should be compressed
|
|
*
|
|
* @param array $data Response data
|
|
* @param array $options Response options
|
|
* @return bool True if should compress
|
|
* @since 1.0.0
|
|
*/
|
|
private function shouldCompressResponse(array $data, array $options): bool
|
|
{
|
|
if (!$this->compressionEnabled) {
|
|
return false;
|
|
}
|
|
|
|
if ($options['force_compression'] ?? false) {
|
|
return true;
|
|
}
|
|
|
|
if ($options['disable_compression'] ?? false) {
|
|
return false;
|
|
}
|
|
|
|
$dataSize = strlen(json_encode($data));
|
|
|
|
return $dataSize >= self::COMPRESSION_THRESHOLD;
|
|
}
|
|
|
|
/**
|
|
* Compress response data using various algorithms
|
|
*
|
|
* @param array $data Response data
|
|
* @param array $options Compression options
|
|
* @return array Compressed response
|
|
* @since 1.0.0
|
|
*/
|
|
private function compressResponse(array $data, array $options): array
|
|
{
|
|
$algorithm = $options['compression_algorithm'] ?? 'gzip';
|
|
$originalJson = json_encode($data);
|
|
$originalSize = strlen($originalJson);
|
|
|
|
switch ($algorithm) {
|
|
case 'gzip':
|
|
$compressed = gzcompress($originalJson, 6);
|
|
break;
|
|
|
|
case 'deflate':
|
|
$compressed = gzdeflate($originalJson, 6);
|
|
break;
|
|
|
|
case 'brotli':
|
|
if (function_exists('brotli_compress')) {
|
|
$compressed = brotli_compress($originalJson);
|
|
} else {
|
|
$compressed = gzcompress($originalJson, 6); // Fallback
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return $data; // No compression
|
|
}
|
|
|
|
$compressedSize = strlen($compressed);
|
|
$compressionRatio = $originalSize > 0 ? ($compressedSize / $originalSize) : 1;
|
|
|
|
// Only use compression if it provides significant benefit
|
|
if ($compressionRatio < 0.8) {
|
|
$this->recordCompressionStats($algorithm, $originalSize, $compressedSize);
|
|
|
|
return [
|
|
'compressed' => true,
|
|
'algorithm' => $algorithm,
|
|
'data' => base64_encode($compressed),
|
|
'original_size' => $originalSize,
|
|
'compressed_size' => $compressedSize,
|
|
'compression_ratio' => $compressionRatio
|
|
];
|
|
}
|
|
|
|
return $data; // Return original if compression not beneficial
|
|
}
|
|
|
|
/**
|
|
* Process individual request within batch
|
|
*
|
|
* @param array $request Request configuration
|
|
* @param array $options Processing options
|
|
* @return array Request response
|
|
* @since 1.0.0
|
|
*/
|
|
private function processIndividualRequest(array $request, array $options): array
|
|
{
|
|
$startTime = microtime(true);
|
|
|
|
// Simulate request processing
|
|
$action = $request['action'] ?? 'unknown';
|
|
$params = $request['params'] ?? [];
|
|
|
|
// Process based on action type
|
|
switch ($action) {
|
|
case 'get_restrictions':
|
|
$response = $this->processGetRestrictions($params);
|
|
break;
|
|
|
|
case 'update_restriction':
|
|
$response = $this->processUpdateRestriction($params);
|
|
break;
|
|
|
|
case 'get_availability':
|
|
$response = $this->processGetAvailability($params);
|
|
break;
|
|
|
|
default:
|
|
throw new \InvalidArgumentException("Unknown action: {$action}");
|
|
}
|
|
|
|
$executionTime = (microtime(true) - $startTime) * 1000;
|
|
|
|
return [
|
|
'action' => $action,
|
|
'data' => $response,
|
|
'execution_time' => $executionTime,
|
|
'success' => true
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Generate response cache key
|
|
*
|
|
* @param array $data Response data
|
|
* @param array $options Response options
|
|
* @return string Cache key
|
|
* @since 1.0.0
|
|
*/
|
|
private function generateResponseCacheKey(array $data, array $options): string
|
|
{
|
|
$keyData = [
|
|
'data_hash' => md5(json_encode($data)),
|
|
'options' => $options,
|
|
'user_id' => get_current_user_id(),
|
|
'version' => CARE_BOOK_ULTIMATE_VERSION
|
|
];
|
|
|
|
return md5(serialize($keyData));
|
|
}
|
|
|
|
/**
|
|
* Finalize response with headers and metadata
|
|
*
|
|
* @param array $data Response data
|
|
* @param array $options Response options
|
|
* @return array Final response
|
|
* @since 1.0.0
|
|
*/
|
|
private function finalizeResponse(array $data, array $options): array
|
|
{
|
|
$response = [
|
|
'success' => true,
|
|
'data' => $data,
|
|
'timestamp' => time(),
|
|
'cache_info' => [
|
|
'cached' => isset($data['_cached']),
|
|
'ttl' => $options['cache_ttl'] ?? 300
|
|
]
|
|
];
|
|
|
|
// Add performance info in debug mode
|
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
|
$response['debug'] = [
|
|
'memory_usage' => memory_get_usage(true),
|
|
'execution_time' => $options['_execution_time'] ?? 0,
|
|
'compression_enabled' => $this->compressionEnabled
|
|
];
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Initialize response optimizer
|
|
*
|
|
* @return void
|
|
* @since 1.0.0
|
|
*/
|
|
private function initializeOptimizer(): void
|
|
{
|
|
// Check compression support
|
|
$this->compressionEnabled = extension_loaded('zlib');
|
|
|
|
// Register AJAX hooks
|
|
add_action('wp_ajax_care_book_get_restrictions', [$this, 'handleGetRestrictions']);
|
|
add_action('wp_ajax_care_book_update_restriction', [$this, 'handleUpdateRestriction']);
|
|
add_action('wp_ajax_care_book_batch_request', [$this, 'handleBatchRequest']);
|
|
|
|
// Set up response headers
|
|
add_action('wp_ajax_care_book_*', [$this, 'setOptimalHeaders'], 1);
|
|
}
|
|
|
|
/**
|
|
* Remove null values from array recursively
|
|
*
|
|
* @param array $data Input data
|
|
* @return array Data without nulls
|
|
* @since 1.0.0
|
|
*/
|
|
private function removeNullValues(array $data): array
|
|
{
|
|
return array_filter($data, function($value) {
|
|
if (is_array($value)) {
|
|
return !empty($this->removeNullValues($value));
|
|
}
|
|
return $value !== null;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Compress repeated strings in data
|
|
*
|
|
* @param array $data Input data
|
|
* @return array Data with compressed strings
|
|
* @since 1.0.0
|
|
*/
|
|
private function compressRepeatedStrings(array $data): array
|
|
{
|
|
// This would implement string deduplication
|
|
// Simplified implementation for now
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Optimize numeric data representation
|
|
*
|
|
* @param array $data Input data
|
|
* @return array Data with optimized numbers
|
|
* @since 1.0.0
|
|
*/
|
|
private function optimizeNumbers(array $data): array
|
|
{
|
|
array_walk_recursive($data, function(&$value) {
|
|
if (is_numeric($value) && is_string($value)) {
|
|
$value = is_int($value) ? (int) $value : (float) $value;
|
|
}
|
|
});
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Exclude specified fields from data
|
|
*
|
|
* @param array $data Input data
|
|
* @param array $fields Fields to exclude
|
|
* @return array Data without excluded fields
|
|
* @since 1.0.0
|
|
*/
|
|
private function excludeFields(array $data, array $fields): array
|
|
{
|
|
return array_diff_key($data, array_flip($fields));
|
|
}
|
|
|
|
/**
|
|
* Set streaming headers for large responses
|
|
*
|
|
* @param array $options Streaming options
|
|
* @return void
|
|
* @since 1.0.0
|
|
*/
|
|
private function setStreamingHeaders(array $options): void
|
|
{
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
header('Cache-Control: no-cache');
|
|
header('Connection: keep-alive');
|
|
|
|
if ($options['enable_cors'] ?? true) {
|
|
header('Access-Control-Allow-Origin: *');
|
|
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
|
|
header('Access-Control-Allow-Headers: Content-Type, Authorization');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Record response performance metric
|
|
*
|
|
* @param float $startTime Start time
|
|
* @param bool $cached Whether response was cached
|
|
* @param int $responseSize Response size in bytes
|
|
* @return void
|
|
* @since 1.0.0
|
|
*/
|
|
private function recordResponseMetric(float $startTime, bool $cached, int $responseSize): void
|
|
{
|
|
$responseTime = (microtime(true) - $startTime) * 1000;
|
|
|
|
$this->responseMetrics[] = [
|
|
'response_time' => $responseTime,
|
|
'cached' => $cached,
|
|
'response_size' => $responseSize,
|
|
'timestamp' => time()
|
|
];
|
|
|
|
// Keep only recent metrics
|
|
if (count($this->responseMetrics) > 200) {
|
|
$this->responseMetrics = array_slice($this->responseMetrics, -100);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Record batch processing metrics
|
|
*
|
|
* @param array $batchResponse Batch response data
|
|
* @return void
|
|
* @since 1.0.0
|
|
*/
|
|
private function recordBatchMetric(array $batchResponse): void
|
|
{
|
|
// Store batch metrics for analysis
|
|
$this->responseMetrics[] = [
|
|
'type' => 'batch',
|
|
'execution_time' => $batchResponse['execution_time'],
|
|
'requests_count' => $batchResponse['requests_count'],
|
|
'success_rate' => $batchResponse['success_count'] / $batchResponse['requests_count'],
|
|
'timestamp' => time()
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Record compression statistics
|
|
*
|
|
* @param string $algorithm Compression algorithm
|
|
* @param int $originalSize Original size
|
|
* @param int $compressedSize Compressed size
|
|
* @return void
|
|
* @since 1.0.0
|
|
*/
|
|
private function recordCompressionStats(string $algorithm, int $originalSize, int $compressedSize): void
|
|
{
|
|
$this->compressionStats[] = [
|
|
'algorithm' => $algorithm,
|
|
'original_size' => $originalSize,
|
|
'compressed_size' => $compressedSize,
|
|
'ratio' => $compressedSize / $originalSize,
|
|
'savings' => $originalSize - $compressedSize,
|
|
'timestamp' => time()
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Calculate median value from array
|
|
*
|
|
* @param array $values Numeric values
|
|
* @return float Median value
|
|
* @since 1.0.0
|
|
*/
|
|
private function calculateMedian(array $values): float
|
|
{
|
|
sort($values);
|
|
$count = count($values);
|
|
|
|
if ($count === 0) {
|
|
return 0;
|
|
}
|
|
|
|
if ($count % 2 === 0) {
|
|
return ($values[$count / 2 - 1] + $values[$count / 2]) / 2;
|
|
}
|
|
|
|
return $values[($count - 1) / 2];
|
|
}
|
|
|
|
/**
|
|
* Calculate compression ratio from stats
|
|
*
|
|
* @return float Average compression ratio
|
|
* @since 1.0.0
|
|
*/
|
|
private function calculateCompressionRatio(): float
|
|
{
|
|
if (empty($this->compressionStats)) {
|
|
return 1.0;
|
|
}
|
|
|
|
$ratios = array_column($this->compressionStats, 'ratio');
|
|
return array_sum($ratios) / count($ratios);
|
|
}
|
|
|
|
/**
|
|
* Calculate batch processing efficiency
|
|
*
|
|
* @return float Batch efficiency percentage
|
|
* @since 1.0.0
|
|
*/
|
|
private function calculateBatchEfficiency(): float
|
|
{
|
|
$batchMetrics = array_filter($this->responseMetrics, fn($m) => ($m['type'] ?? '') === 'batch');
|
|
|
|
if (empty($batchMetrics)) {
|
|
return 0;
|
|
}
|
|
|
|
$successRates = array_column($batchMetrics, 'success_rate');
|
|
return (array_sum($successRates) / count($successRates)) * 100;
|
|
}
|
|
|
|
/**
|
|
* Calculate data transfer savings from optimizations
|
|
*
|
|
* @return array Transfer savings data
|
|
* @since 1.0.0
|
|
*/
|
|
private function calculateDataTransferSavings(): array
|
|
{
|
|
if (empty($this->compressionStats)) {
|
|
return ['savings_bytes' => 0, 'savings_percentage' => 0];
|
|
}
|
|
|
|
$totalOriginal = array_sum(array_column($this->compressionStats, 'original_size'));
|
|
$totalCompressed = array_sum(array_column($this->compressionStats, 'compressed_size'));
|
|
|
|
$savingsBytes = $totalOriginal - $totalCompressed;
|
|
$savingsPercentage = $totalOriginal > 0 ? ($savingsBytes / $totalOriginal) * 100 : 0;
|
|
|
|
return [
|
|
'savings_bytes' => $savingsBytes,
|
|
'savings_percentage' => $savingsPercentage
|
|
];
|
|
}
|
|
|
|
/**
|
|
* WordPress AJAX handlers
|
|
*/
|
|
|
|
public function handleGetRestrictions(): void
|
|
{
|
|
$data = $this->processGetRestrictions($_REQUEST);
|
|
$response = $this->optimizeResponse($data);
|
|
wp_send_json($response);
|
|
}
|
|
|
|
public function handleUpdateRestriction(): void
|
|
{
|
|
$data = $this->processUpdateRestriction($_REQUEST);
|
|
$response = $this->optimizeResponse($data);
|
|
wp_send_json($response);
|
|
}
|
|
|
|
public function handleBatchRequest(): void
|
|
{
|
|
$requests = json_decode(stripslashes($_POST['requests'] ?? '[]'), true);
|
|
$response = $this->batchRequests($requests);
|
|
wp_send_json($response);
|
|
}
|
|
|
|
public function setOptimalHeaders(): void
|
|
{
|
|
header('X-Response-Optimized: 1');
|
|
if ($this->compressionEnabled) {
|
|
header('X-Compression-Available: 1');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Process specific request types (simplified implementations)
|
|
*/
|
|
|
|
private function processGetRestrictions(array $params): array
|
|
{
|
|
return ['restrictions' => [], 'count' => 0];
|
|
}
|
|
|
|
private function processUpdateRestriction(array $params): array
|
|
{
|
|
return ['success' => true, 'id' => $params['id'] ?? 0];
|
|
}
|
|
|
|
private function processGetAvailability(array $params): array
|
|
{
|
|
return ['availability' => [], 'doctor_id' => $params['doctor_id'] ?? 0];
|
|
}
|
|
} |