redis_host = $REDIS_CONFIG['host']; $this->redis_user = $REDIS_CONFIG['user'] ?? ''; $this->redis_database = $REDIS_CONFIG['database']; $this->redis_password = $REDIS_CONFIG['password']; if (isset($REDIS_CONFIG['port']) && is_numeric($REDIS_CONFIG['port'])) { $this->redis_port = (int)$REDIS_CONFIG['port']; } } /** * @inheritDoc */ public function cache_department_booking_count(int $department_id, int $count): redis_i { // Cache the department booking count $this->set('department_booking_count_' . $department_id, $count); return $this; } /** * @inheritDoc */ public function get_department_booking_count(int $department_id): int|null { // Get the department booking count return $this->get('department_booking_count_' . $department_id); } /** * @inheritDoc */ public function clear_department_booking_count(int $department_id): redis_i { // Clear the department booking count $this->delete('department_booking_count_' . $department_id); return $this; } /** * @inheritDoc */ public function cache_department_webhook(int $department_id, string $webhook): self { // Cache the department webhook $this->set('department_webhook_' . $department_id, $webhook); $this->expire('department_webhook_' . $department_id, 300); // Expire in 5 minutes return $this; } /** * @inheritDoc */ public function get_department_webhook(int $department_id): string|null { // Get the department webhook return $this->get('department_webhook_' . $department_id); } /** * @inheritDoc */ public function clear_department_webhook(int $department_id): self { // Clear the department webhook $this->delete('department_webhook_' . $department_id); return $this; } /** * @inheritDoc */ public function cache_department_name(int $department_id, string $department_name): self { // Cache the department name (If it is not empty or null) if (empty($department_name)) { $department_name = 'IS_EMPTY_OR_NULL'; return $this; } // Set the department's name in the cache if ($this->get_department_name($department_id) === null) { $this->set('department_' . $department_id, json_encode(['name' => $department_name] )); }; return $this; } /** * @inheritDoc */ public function get_department_name(int $department_id): string|null { // Get the department name $tmp_department = $this->get('department_' . $department_id) ?? null; if ($tmp_department === 'IS_EMPTY_OR_NULL' || $tmp_department === null) { return null; } $tmp_department = json_decode($tmp_department); // Return the department name return $tmp_department->name ?: $tmp_department['name'] ?? null; } /** * @inheritDoc */ public function clear_department_name(int $department_id): self { // Clear the department name $this->delete('department_' . $department_id); return $this; } /** * @inheritDoc */ public function cache_economic_customer_discount_percentage(int $user_id, int $discount_percentage): self { // Cache the economic customer discount percentage $this->set('users_' . $user_id . '_economic_customer_discount_percentage', $discount_percentage); return $this; } /** * @inheritDoc */ public function get_economic_customer_discount_percentage(int $user_id): int|null { // Get the economic customer discount percentage return $this->get('users_' . $user_id . '_economic_customer_discount_percentage'); } /** * @inheritDoc */ public function clear_economic_customer_discount_percentage(int $user_id): self { // Clear the economic customer discount percentage $this->delete('users_' . $user_id . '_economic_customer_discount_percentage'); return $this; } /** * @inheritDoc */ public function cache_customer_notes(int $user_id, array $customer_notes): self { // Cache the customer notes $this->set_array('users_' . $user_id . '_customer_notes', $customer_notes); return $this; } /** * @inheritDoc */ public function get_customer_notes(int $user_id): array|null { // Get the customer notes return $this->get_array('users_' . $user_id . '_customer_notes'); } /** * @inheritDoc */ public function clear_customer_notes(int $user_id): self { // Clear the customer notes $this->delete('users_' . $user_id . '_customer_notes'); return $this; } /** * @inheritDoc */ public function add_log(string $module, string $department, int $type, int $user_id, string $action, string $message): redis_i { // Get the current timestamp $timestamp = strtotime('now'); // Get unique id for the log $log_id = uniqid(); // Add the log to the cache $this->set_array('log_' . $log_id, [ 'id' => $log_id, 'module' => $module, 'department' => $department, 'type' => $type, 'user_id' => $user_id, 'action' => $action, 'message' => $message, 'timestamp' => $timestamp ]); return $this; } /** * @inheritDoc */ public function get_logs(): array|null { // Get all logs from the cache return $this->get_arrays('log_*'); } /** * @inheritDoc */ public function clear_logs(): self { // Clear all logs from the cache $keys = $this->get_keys('log_*'); foreach ( $keys as $key ) { $this->delete($key); } return $this; } /** * @inheritDoc */ public function get_department(int $department_id): array|null { // Get the department return $this->get_array('department_' . $department_id); } /** * @inheritDoc */ public function clear_department(int $department_id): self { // Clear the departments $this->clear_departments(); return $this; } /** * @inheritDoc */ public function clear_departments(): self { // Clear all departments from the cache $this->delete('departments'); $keys = $this->get_keys('department_*'); foreach ( $keys as $key ) { $this->delete($key); } return $this; } /** * @inheritDoc */ public function get_departments(): array|null { // Get all departments from the cache return $this->get_array('departments'); } /** * @inheritDoc */ public function cache_departments(array $departments): self { // Cache the departments foreach ( $departments as $department ) { $this->cache_department($department['id'], $department); } redis->set_array('departments', $departments); return $this; } /** * @inheritDoc */ public function cache_department(int $department_id, array $department): self { // Cache the department $this->set_array('department_' . $department_id, $department); return $this; } /** * @inheritDoc */ public function get_log_count(): int { // Get the log count return $this->count_keys('log_*'); } /** * @inheritDoc */ public function cache_token(string $token, array $row): self { // Cache the token $this->set_array('token_' . $token, $row); return $this; } /** * @inheritDoc */ public function get_token(string $token): array|null { // Get the token return $this->get_array('token_' . $token); } /** * @inheritDoc */ public function clear_token(string $token): self { // Clear the token $this->delete('token_' . $token); return $this; } /** * Cache auth session payload for a token with TTL */ public function cache_auth_session(string $token, array $data, int $ttl = 60): self { $key = 'auth_session_' . $token; $this->set_array($key, $data); $this->expire($key, $ttl); return $this; } /** * Get cached auth session payload by token */ public function get_auth_session(string $token): array|null { return $this->get_array('auth_session_' . $token); } /** * Clear cached auth session payload by token */ public function clear_auth_session(string $token): self { $this->delete('auth_session_' . $token); return $this; } /** * @inheritDoc */ public function cache_invoice_period_manual_flags(array $flags): self { $this->set_array('invoice_period_manual_flags', $flags); return $this; } /** * @inheritDoc */ public function get_invoice_period_manual_flags(): array|null { return $this->get_array('invoice_period_manual_flags'); } /** * @inheritDoc */ public function clear_invoice_period_manual_flags(): self { $this->delete('invoice_period_manual_flags'); return $this; } private function invoicePeriodCacheKey(string $prefix, string $dateFrom, string $dateTo): string { return $prefix . ':' . $dateFrom . ':' . $dateTo; } private function workfeedEmployeeNameCacheKey(string $employeeId): string { return 'workfeed_employee_name:' . rawurlencode($employeeId); } /** * @inheritDoc */ public function cache_invoice_period_automatic_flags(string $dateFrom, string $dateTo, array $flags): self { $this->set_array($this->invoicePeriodCacheKey('invoice_period_automatic_flags', $dateFrom, $dateTo), $flags); return $this; } /** * @inheritDoc */ public function get_invoice_period_automatic_flags(string $dateFrom, string $dateTo): array|null { return $this->get_array($this->invoicePeriodCacheKey('invoice_period_automatic_flags', $dateFrom, $dateTo)); } /** * @inheritDoc */ public function clear_invoice_period_automatic_flags(string $dateFrom, string $dateTo): self { $this->delete($this->invoicePeriodCacheKey('invoice_period_automatic_flags', $dateFrom, $dateTo)); return $this; } /** * @inheritDoc */ public function cache_invoice_period_order_item_rows(string $dateFrom, string $dateTo, array $rows): self { $this->set_array($this->invoicePeriodCacheKey('invoice_period_order_item_rows', $dateFrom, $dateTo), $rows); return $this; } /** * @inheritDoc */ public function get_invoice_period_order_item_rows(string $dateFrom, string $dateTo): array|null { return $this->get_array($this->invoicePeriodCacheKey('invoice_period_order_item_rows', $dateFrom, $dateTo)); } /** * @inheritDoc */ public function clear_invoice_period_order_item_rows(string $dateFrom, string $dateTo): self { $this->delete($this->invoicePeriodCacheKey('invoice_period_order_item_rows', $dateFrom, $dateTo)); return $this; } /** * @inheritDoc */ public function cache_workfeed_employee_name(string $employeeId, string $employeeName, int $ttl = 86400): self { $normalizedEmployeeId = trim($employeeId); if ($normalizedEmployeeId === '') { return $this; } $normalizedEmployeeName = trim($employeeName); if ($normalizedEmployeeName === '') { return $this; } $key = $this->workfeedEmployeeNameCacheKey($normalizedEmployeeId); $this->set($key, $normalizedEmployeeName); $this->expire($key, $ttl); return $this; } /** * @inheritDoc */ public function get_workfeed_employee_name(string $employeeId): string|null { $normalizedEmployeeId = trim($employeeId); if ($normalizedEmployeeId === '') { return null; } $value = $this->get($this->workfeedEmployeeNameCacheKey($normalizedEmployeeId)); if ($value === null) { return null; } $normalized = trim((string)$value); return $normalized !== '' ? $normalized : null; } /** * @inheritDoc */ public function clear_workfeed_employee_name(string $employeeId): self { $normalizedEmployeeId = trim($employeeId); if ($normalizedEmployeeId === '') { return $this; } $this->delete($this->workfeedEmployeeNameCacheKey($normalizedEmployeeId)); return $this; } /** * @inheritDoc */ public function enqueue_invoice_period_warming(string $dateFrom, string $dateTo): self { $this->get_client()->sadd('invoice_period_warming_queue', [$dateFrom . '|' . $dateTo]); return $this; } /** * @inheritDoc */ public function consume_invoice_period_warming_queue(): array { $client = $this->get_client(); $members = $client->smembers('invoice_period_warming_queue'); if (!empty($members)) { $client->del('invoice_period_warming_queue'); } $periods = []; foreach ($members as $member) { $parts = explode('|', (string)$member, 2); if (count($parts) === 2 && $parts[0] !== '' && $parts[1] !== '') { $periods[] = ['dateFrom' => $parts[0], 'dateTo' => $parts[1]]; } } return $periods; } /** * @inheritDoc */ public function get_last_crond_run(string $task): int|null { // Get the last cron task return $this->get('last_cron_task_' . $task) ?? null; } /** * @inheritDoc */ public function set_last_crond_run(string $task, int $time): self { // Set the last cron task $this->set('last_cron_task_' . $task, $time); return $this; } /** * @inheritDoc */ public function cache_user_id_from_customer_number(int $customer_number, int $user_id): self { // Cache the user id from customer number $this->set('user_id_from_customer_number_' . $customer_number, $user_id); return $this; } /** * @inheritDoc */ public function get_user_id_from_customer_number(int $customer_number): int|null { // Get the user id from customer number return $this->get('user_id_from_customer_number_' . $customer_number); } /** * @inheritDoc */ public function clear_user_id_from_customer_number(int $customer_number): self { // Clear the user id from customer number $this->delete('user_id_from_customer_number_' . $customer_number); return $this; } /** * @inheritDoc */ public function cache_customer_number_from_user_id(int $user_id, int $customer_number): self { // Cache the customer number from user id $this->set('customer_number_from_user_id_' . $user_id, $customer_number); return $this; } /** * @inheritDoc */ public function get_customer_number_from_user_id(int $user_id): int|null { // Get the customer number from user id return $this->get('customer_number_from_user_id_' . $user_id); } /** * @inheritDoc */ public function clear_customer_number_from_user_id(int $user_id): self { // Clear the customer number from user id $this->delete('customer_number_from_user_id_' . $user_id); return $this; } public function expire(string $key, int $seconds): self { // Set the expiration time for a key $this->redis->expire($key, $seconds); return $this; } public function generateTemporaryCacheKey(): string { // Generate a temporary cache key return 'temporary_cache_' . uniqid(); } /** * Atomically set a key with TTL only when it does not already exist. */ public function set_if_absent_with_expiration(string $key, string $value, int $seconds): bool { if (!self::is_connected()) { self::connect(); } $seconds = max(1, $seconds); $result = $this->redis->set($key, $value, 'EX', $seconds, 'NX'); return $result === true || strtoupper((string)$result) === 'OK'; } public function mget(array $array_map): array { if (empty($array_map)) { return []; } // Get multiple keys from Redis return $this->redis->mget($array_map); } /** * @inheritDoc */ public function cache_permission(string $cache_key, bool $allowed, int $ttl = 300): self { $this->setEx('perm:' . $cache_key, $allowed ? '1' : '0', $ttl); return $this; } /** * @inheritDoc */ public function get_permission(string $cache_key): bool|null { $val = $this->get('perm:' . $cache_key); if ($val === null) { return null; } return $val === '1'; } /** * @inheritDoc */ public function clear_permission(string $cache_key): self { $this->delete('perm:' . $cache_key); return $this; } /** * @throws \Exception */ public function ping(): bool { if (!self::is_connected()) { self::connect(); } if (!self::is_connected()) { return false; } return true; } }