├── .env.example
├── .gitignore
├── .scrutinizer.yml
├── Examples
├── example01.php
├── example02.php
├── example03.php
├── example04.php
├── example05.php
├── example06.php
├── example07.php
└── example08.php
├── README.md
├── composer.json
├── docs
├── API-Reference
│ ├── FuncoesCache
│ │ └── README.md
│ ├── OptionBuilder
│ │ └── TimeBuilder.md
│ ├── compression_encryption.md
│ ├── optionBuilder.md
│ ├── setConfig.md
│ └── setDriver.md
├── api-reference.md
├── cacheer_php_logo.png
├── cacheer_php_logo__.png
├── example01.md
├── example02.md
├── example03.md
├── example04.md
├── example05.md
├── example06.md
├── example07.md
├── example08.md
├── example09.md
└── guia2.0.0.md
├── phpunit.xml
├── src
├── Boot
│ └── Configs.php
├── CacheStore
│ ├── ArrayCacheStore.php
│ ├── CacheManager
│ │ ├── FileCacheManager.php
│ │ ├── OptionBuilders
│ │ │ └── FileOptionBuilder.php
│ │ └── RedisCacheManager.php
│ ├── DatabaseCacheStore.php
│ ├── FileCacheStore.php
│ └── RedisCacheStore.php
├── Cacheer.php
├── Config
│ ├── .gitignore
│ └── Option
│ │ ├── .gitignore
│ │ └── Builder
│ │ └── OptionBuilder.php
├── Core
│ ├── Connect.php
│ ├── ConnectionFactory.php
│ └── MigrationManager.php
├── Exceptions
│ ├── BaseException.php
│ ├── CacheDatabaseException.php
│ ├── CacheFileException.php
│ ├── CacheRedisException.php
│ └── ConnectionException.php
├── Helpers
│ ├── CacheConfig.php
│ ├── CacheDatabaseHelper.php
│ ├── CacheFileHelper.php
│ ├── CacheRedisHelper.php
│ ├── CacheerHelper.php
│ ├── EnvHelper.php
│ └── SqliteHelper.php
├── Interface
│ └── CacheerInterface.php
├── Repositories
│ └── CacheDatabaseRepository.php
├── Support
│ └── TimeBuilder.php
└── Utils
│ ├── CacheDataFormatter.php
│ ├── CacheDriver.php
│ └── CacheLogger.php
└── tests
├── Feature
└── OptionBuildTest.php
└── Unit
├── ArrayCacheStoreTest.php
├── DatabaseCacheStoreTest.php
├── FileCacheStoreTest.php
├── RedisCacheStoreTest.php
└── SecurityFeatureTest.php
/.env.example:
--------------------------------------------------------------------------------
1 | DB_CONNECTION=sqlite
2 | # DB_HOST=localhost
3 | # DB_PORT=3306
4 | # DB_DATABASE=cacheer_db
5 | # DB_USERNAME=root
6 | # DB_PASSWORD=
7 |
8 | REDIS_CLIENT=
9 | REDIS_HOST=localhost
10 | REDIS_PASSWORD=
11 | REDIS_PORT=6379
12 | REDIS_NAMESPACE=
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 |
3 | .phpunit.result.cache
4 | .env
5 | /composer.lock
6 | /database
7 | /CacheerPHP
8 | cacheer.log
9 | /tests/Unit/cache
10 | /Examples/InternalTests/
--------------------------------------------------------------------------------
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | build:
2 | environment:
3 | php:
4 | version: 8.2
5 | dependencies:
6 | before:
7 | - sudo apt-get update
8 | - sudo apt-get install -y software-properties-common
9 | - sudo add-apt-repository ppa:ondrej/php -y
10 | - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y openssl libssl-dev
11 | - openssl version
12 | - export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
13 | - export OPENSSL_CFLAGS="-I/usr/local/include"
14 | - export OPENSSL_LIBS="-L/usr/local/lib -lssl -lcrypto"
15 | tests:
16 | override:
17 | - echo "Skipping tests"
18 | tools:
19 | php_analyzer:
20 | enabled: true
21 | php_cs_fixer:
22 | enabled: true
23 |
--------------------------------------------------------------------------------
/Examples/example01.php:
--------------------------------------------------------------------------------
1 | __DIR__ . "/cache",
9 | ];
10 |
11 | $Cacheer = new Cacheer($options);
12 |
13 | // Dados a serem armazenados no cache
14 | $cacheKey = 'user_profile_1234';
15 | $userProfile = [
16 | 'id' => 123,
17 | 'name' => 'John Doe',
18 | 'email' => 'john.doe@example.com',
19 | ];
20 |
21 | // Armazenando dados no cache
22 | $Cacheer->putCache($cacheKey, $userProfile);
23 |
24 | // Recuperando dados do cache
25 | $cachedProfile = $Cacheer->getCache($cacheKey);
26 |
27 | if ($Cacheer->isSuccess()) {
28 | echo "Cache Found: ";
29 | print_r($cachedProfile);
30 | } else {
31 | echo $Cacheer->getMessage();
32 | }
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Examples/example02.php:
--------------------------------------------------------------------------------
1 | __DIR__ . "/cache",
8 | "expirationTime" => "2 hour"
9 | ];
10 |
11 | $Cacheer = new Cacheer($options);
12 |
13 | // Dados a serem armazenados no cache
14 | $cacheKey = 'daily_stats';
15 | $dailyStats = [
16 | 'visits' => 1500,
17 | 'signups' => 35,
18 | 'revenue' => 500.75,
19 | ];
20 |
21 | // Armazenando dados no cache
22 | $Cacheer->putCache($cacheKey, $dailyStats);
23 |
24 | // Recuperando dados do cache por 2 horas
25 | $cachedStats = $Cacheer->getCache($cacheKey);
26 |
27 | if ($Cacheer->isSuccess()) {
28 | echo "Cache Found: ";
29 | print_r($cachedStats);
30 | } else {
31 | echo $Cacheer->getMessage();
32 | }
33 |
--------------------------------------------------------------------------------
/Examples/example03.php:
--------------------------------------------------------------------------------
1 | __DIR__ . "/cache",
9 | ];
10 |
11 | $Cacheer = new Cacheer($options);
12 |
13 | // Chave do cache a ser limpo
14 | $cacheKey = 'user_profile_123';
15 |
16 | // Limpando um item específico do cache
17 |
18 | $Cacheer->clearCache($cacheKey);
19 |
20 | if ($Cacheer->isSuccess()) {
21 | echo $Cacheer->getMessage();
22 | } else {
23 | echo $Cacheer->getMessage();
24 | }
25 |
26 | $Cacheer->flushCache();
27 |
28 | if ($Cacheer->isSuccess()) {
29 | echo $Cacheer->getMessage();
30 | } else {
31 | echo $Cacheer->getMessage();
32 | }
33 |
--------------------------------------------------------------------------------
/Examples/example04.php:
--------------------------------------------------------------------------------
1 | __DIR__ . "/cache",
8 | ];
9 |
10 | $Cacheer = new Cacheer($options);
11 |
12 | // Dados a serem armazenados no cache com namespace
13 | $namespace = 'session_data_01';
14 | $cacheKey = 'session_456';
15 | $sessionData = [
16 | 'user_id' => 456,
17 | 'login_time' => time(),
18 | ];
19 |
20 | // Armazenando dados no cache com namespace
21 | $Cacheer->putCache($cacheKey, $sessionData, $namespace);
22 |
23 | // Recuperando dados do cache
24 | $cachedSessionData = $Cacheer->getCache($cacheKey, $namespace);
25 |
26 | if ($Cacheer->isSuccess()) {
27 | echo "Cache Found: ";
28 | print_r($cachedSessionData);
29 | } else {
30 | echo $Cacheer->getMessage();
31 | }
32 |
--------------------------------------------------------------------------------
/Examples/example05.php:
--------------------------------------------------------------------------------
1 | __DIR__ . "/cache",
9 | ];
10 |
11 | $Cacheer = new Cacheer($options);
12 |
13 | // URL da API e chave de cache
14 | $apiUrl = 'https://jsonplaceholder.typicode.com/posts';
15 | $cacheKey = 'api_response_' . md5($apiUrl);
16 |
17 | // Verificando se a resposta da API já está no cache
18 | $cachedResponse = $Cacheer->getCache($cacheKey);
19 |
20 | if ($Cacheer->isSuccess()) {
21 | // Use a resposta do cache
22 | $response = $cachedResponse;
23 | } else {
24 | // Faça a chamada à API e armazene a resposta no cache
25 | $response = file_get_contents($apiUrl);
26 | $Cacheer->putCache($cacheKey, $response);
27 | }
28 |
29 | // Usando a resposta da API (do cache ou da chamada)
30 | $data = json_decode($response, true);
31 | print_r($data);
32 |
--------------------------------------------------------------------------------
/Examples/example06.php:
--------------------------------------------------------------------------------
1 | setDriver()->useRedisDriver();
9 |
10 | // Dados a serem armazenados no cache
11 | $cacheKey = 'user_profile_1234';
12 | $userProfile = [
13 | 'id' => 1,
14 | 'name' => 'Sílvio Silva',
15 | 'email' => 'gasparsilvio7@gmail.com',
16 | 'role' => 'Developer'
17 | ];
18 | $cacheNamespace = 'userData';
19 |
20 | // Armazenando dados no cache
21 | //$Cacheer->putCache($cacheKey, $userProfile, $cacheNamespace);
22 |
23 | $Cacheer->has($cacheKey, $cacheNamespace);
24 |
25 | // Verificando se o cache existe e recuperando os dados
26 | if ($Cacheer->isSuccess()) {
27 | $cachedProfile = $Cacheer->getCache($cacheKey, $cacheNamespace);
28 | echo "Perfil de Usuário Encontrado:\n";
29 | print_r($cachedProfile);
30 | } else {
31 | echo "Cache não encontrado: " . $Cacheer->getMessage();
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/Examples/example07.php:
--------------------------------------------------------------------------------
1 | setDriver()->useRedisDriver();
9 |
10 | // Dados a serem armazenados no cache
11 | $cacheKey = 'user_profile_1';
12 | $userProfile = [
13 | 'id' => 1,
14 | 'name' => 'Sílvio Silva',
15 | 'email' => 'gasparsilvio7@gmail.com',
16 | ];
17 |
18 | $userProfile02 = [
19 | 'casaNº' => 2130,
20 | 'telefone' => "(999)999-9999"
21 | ];
22 |
23 |
24 | // Armazenando dados no cache
25 | $Cacheer->putCache($cacheKey, $userProfile);
26 |
27 | // Recuperando dados do cache
28 | if($Cacheer->isSuccess()){
29 | echo "Cache Found: ";
30 | print_r($Cacheer->getCache($cacheKey));
31 | } else {
32 | echo $Cacheer->getMessage();
33 | }
34 |
35 |
36 | // Mesclando os dados
37 | $Cacheer->appendCache($cacheKey, $userProfile02);
38 |
39 | if($Cacheer->isSuccess()){
40 | echo $Cacheer->getMessage() . PHP_EOL;
41 | print_r($Cacheer->getCache($cacheKey));
42 | } else {
43 | echo $Cacheer->getMessage();
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/Examples/example08.php:
--------------------------------------------------------------------------------
1 | setDriver()->useRedisDriver();
9 |
10 | // Dados a serem armazenados no cache
11 | $cacheKey = 'user_profile_01';
12 | $userProfile = [
13 | 'id' => 1,
14 | 'name' => 'Sílvio Silva',
15 | 'email' => 'gasparsilvio7@gmail.com',
16 | ];
17 |
18 | // Armazenando dados no cache
19 | $Cacheer->putCache($cacheKey, $userProfile, ttl: 300);
20 |
21 | // Recuperando dados do cache
22 | if($Cacheer->isSuccess()){
23 | echo "Cache Found: ";
24 | print_r($Cacheer->getCache($cacheKey));
25 | } else {
26 | echo $Cacheer->getMessage();
27 | }
28 |
29 | // Renovando os dados do cache
30 | $Cacheer->renewCache($cacheKey, 3600);
31 |
32 | if($Cacheer->isSuccess()){
33 | echo $Cacheer->getMessage() . PHP_EOL;
34 | } else {
35 | echo $Cacheer->getMessage() . PHP_EOL;
36 |
37 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CacheerPHP
2 |
3 |

4 |
5 | [](https://github.com/silviooosilva)
6 | 
7 | [](https://github.com/silviooosilva/CacheerPHP/releases)
8 | [](https://scrutinizer-ci.com/g/silviooosilva/CacheerPHP)
9 | 
10 |
11 | CacheerPHP is a minimalist package for PHP caching. Now, in version 3.0.0, you get even more flexibility, support for multiple backends (files, database and Redis), as well as new features for monitoring, compression and encryption and a more robust API design.
12 |
13 | ---
14 |
15 | ## Features
16 |
17 | - **Cache Storage and Retrieval:** Support for file storage, databases (MySQL, PostgreSQL, SQLite) and Redis.
18 | - **Customizable expiration:** Set the TTL (Time To Live) of the cache precisely.
19 | - **Cache cleaning and flushing:** Support for manual and automatic cleaning (via `flushAfter`).
20 | - **Namespace support:** Organize your cache entries by category.
21 | - **Customized Data Output:** Options to return data in `JSON`, `Array`, `String` or `Object`.
22 | - **Compression and Encryption:** Reduce storage space and increase the security of cached data.
23 | - **Cache Statistics and Monitoring:** Track hit and miss statistics and average read/write times (Coming Soon).
24 | - **Advanced Logging:** Detailed monitoring of the operation of the caching system.
25 |
26 | ---
27 |
28 | ## Installation
29 |
30 | CacheerPHP 3.0.0 is available via Composer. Add the following line to your **composer.json** file:
31 |
32 | ```sh
33 | "silviooosilva/cacheer-php": "^3.0"
34 | ```
35 |
36 | Or run the command:
37 |
38 | ```sh
39 | composer require silviooosilva/cacheer-php
40 | ```
41 |
42 | ## IMPORTANT WARNING!!!
43 |
44 | Don't forget to set your environment variables in the .env.example file.
45 |
46 | Remember that they must be set in the .env file, not in .env.example.
47 | To do this, do the following on your command line:
48 |
49 | ```sh
50 | cp .env.example .env
51 | ```
52 |
53 | ## Documentation
54 |
55 | 1. [Storing and retrieving cached data](docs/example01.md)
56 | 2. [Customizable cache expiration](docs/example02.md)
57 | 3. [Cache flushing and cleaning](docs/example03.md)
58 | 4. [Namespace support for cache organization](docs/example04.md)
59 | 5. [Automatic cleaning of the `flushAfter` cache directory](docs/example09.md)
60 | 6. [API Response Cache](docs/example05.md)
61 | 7. [Custom Data Output (`JSON`)](docs/example06.md)
62 | 8. [Custom Data Output (`Array`)](docs/example07.md)
63 | 9. [Custom Data Output (`String`)](docs/example08.md)
64 | 10. [Upgrade Guide for Version 2.0.0](docs/guide2.0.0.md)
65 | 11. [API Reference](docs/api-reference.md)
66 | 12. [API Reference - Cache Functions](docs/API-Reference/FuncoesCache/README.md)
67 |
68 | Several practical examples are also available in the **Examples** folder in the root of the project.
69 |
70 | ## Compatibility
71 |
72 | - PHP: 8.0 or higher.
73 | - Database Drivers: MySQL, PostgreSQL, SQLite.
74 | - Redis
75 |
76 | ### Tests
77 |
78 | To run the tests, go to the root of the project and type the command:
79 |
80 | ```sh
81 | vendor/bin/phpunit
82 | ```
83 |
84 | Support:
85 | 
86 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "silviooosilva/cacheer-php",
3 | "description": "CacheerPHP is a minimalist package for caching in PHP, offering a simple interface for storing and retrieving cached data using multiple backends.",
4 | "keywords": [
5 | "cache",
6 | "optimizer",
7 | "performance",
8 | "PHP",
9 | "caching",
10 | "cache-manager",
11 | "Silviooosilva",
12 | "speed",
13 | "optimization",
14 | "file-cache",
15 | "database",
16 | "database-cache",
17 | "mysql",
18 | "sqlite",
19 | "pgsql",
20 | "redis",
21 | "predis",
22 | "nosql"
23 | ],
24 | "homepage": "https://github.com/silviooosilva",
25 | "type": "library",
26 | "license": "MIT",
27 | "version": "v3.6.1",
28 | "autoload": {
29 | "files": [
30 | "src/Boot/Configs.php"
31 | ],
32 | "psr-4": {
33 | "Silviooosilva\\CacheerPhp\\": "src/"
34 | }
35 | },
36 | "scripts": {
37 | "post-install-cmd": [
38 | "@php -r \"require 'src/Helpers/EnvHelper.php'; \\Silviooosilva\\CacheerPhp\\Helpers\\EnvHelper::copyEnv();\""
39 | ],
40 | "post-update-cmd": [
41 | "@php -r \"require 'src/Helpers/EnvHelper.php'; \\Silviooosilva\\CacheerPhp\\Helpers\\EnvHelper::copyEnv();\""
42 | ]
43 | },
44 | "authors": [
45 | {
46 | "name": "Sílvio Silva",
47 | "email": "gasparsilvio7@gmail.com",
48 | "role": "Developer"
49 | }
50 | ],
51 | "require": {
52 | "php": ">=8.0",
53 | "vlucas/phpdotenv": "^5.6",
54 | "predis/predis": "^2.3"
55 | },
56 | "require-dev": {
57 | "phpunit/phpunit": "^11.2"
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/docs/API-Reference/FuncoesCache/README.md:
--------------------------------------------------------------------------------
1 | ## Cache functions - CacheerPHP
2 |
3 | CacheerPHP offers a robust set of functions for managing caching in your PHP application. Below is the detailed documentation for each method available:
4 |
5 | ---
6 |
7 | ## Basic Cache Operations
8 |
9 | ### `getCache()` - Retrieves data from the cache
10 |
11 | ```php
12 |
13 | /**
14 | * Gets an item from the cache. If the item doesn't exist or is expired, returns null.
15 | * @param string $cacheKey Unique item key
16 | * @param string $namespace Namespace for organization
17 | * @param string|int $ttl Lifetime in seconds (default: 3600)
18 | * @return CacheDataFormatter|mixed Returns data in special format or raw value
19 | */
20 | $Cacheer->getCache(string $cacheKey, string $namespace, string|int $ttl = 3600);
21 | ```
22 |
23 | ### `putCache()` - Stores data in the cache
24 |
25 | ```php
26 |
27 | /**
28 | * Stores an item in the cache with a specific TTL.
29 | * @param string $cacheKey Unique item key
30 | * @param mixed $cacheData Data to be stored (serializable)
31 | * @param string|int $ttl Lifetime in seconds (default: 3600)
32 | * @return void
33 | */
34 | $Cacheer->putCache(string $cacheKey, mixed $cacheData, string|int $ttl = 3600);
35 | ```
36 |
37 | ### `putMany()` - Mass operations
38 |
39 | ```php
40 |
41 | /**
42 | * Stores multiple cache items at once with shared TTL.
43 | * @param array $items Associative array [key => value]
44 | * @param string $namespace Common namespace for all items
45 | * @param int $batchSize Number of operations per time
46 | * @return void
47 | */
48 | $Cacheer->putMany(array $items, string $namespace, int $batchSize = 100);
49 | ```
50 |
51 | ### `appendCache()` - Adding to existing cache
52 |
53 | ```php
54 | /**
55 | * Adds data to an existing cache item (useful for arrays or strings).
56 | * @param string $cacheKey Existing item key
57 | * @param mixed $cacheData Data to be added
58 | * @param string $namespace Item namespace
59 | * @return void
60 | */
61 | $Cacheer->appendCache(string $cacheKey, mixed $cacheData, string $namespace);
62 | ```
63 |
64 | ### `has()` - Checks if a key exists in the cache and is still valid (has not expired).
65 |
66 | ```php
67 | /**
68 | * Checks whether a particular cache key exists, and whether it is still valid.
69 | * @param string $cacheKey
70 | * @param string $namespace
71 | * @return void
72 | */
73 | $Cacheer->has(string $cacheKey, string $namespace);
74 | ```
75 |
76 | ### `renewCache()` - Renew cache TTL
77 |
78 |
79 | ```php
80 | /**
81 | * Updates the lifetime of an existing item without modifying its data.
82 | * @param string $cacheKey Item key
83 | * @param string|int $ttl New TTL in seconds (default: 3600)
84 | * @param string $namespace Item namespace
85 | * @return mixed Returns the item data or false if it fails
86 | */
87 | $Cacheer->renewCache(string $cacheKey, string|int $ttl = 3600, string $namespace);
88 | ```
89 |
90 | ### `increment()` - Numeric increment
91 |
92 | ```php
93 | /**
94 | * Increments a numeric value in the cache.
95 | * @param string $cacheKey Item key
96 | * @param int $amount Value to increment (default: 1)
97 | * @param string $namespace Item namespace
98 | * @return bool True if successful
99 | */
100 | $Cacheer->increment(string $cacheKey, int $amount, string $namespace);
101 | ```
102 |
103 | ### `decrement()` - Numerical decrement
104 |
105 | ```php
106 | /**
107 | * Decrements a numeric value in the cache.
108 | * @param string $cacheKey Item key
109 | * @param int $amount Value to decrement (default: 1)
110 | * @param string $namespace Item namespace
111 | * @return bool True if successful
112 | */
113 | $Cacheer->decrement(string $cacheKey, int $amount, string $namespace);
114 | ```
115 |
116 | ### `forever()` - Permanent storage
117 |
118 | ```php
119 | /**
120 | * Stores an item in the cache with no expiration time.
121 | * @param string $cacheKey Unique key
122 | * @param mixed $cacheData Data to be stored
123 | * @return void
124 | */
125 | $Cacheer->forever(string $cacheKey, mixed $cacheData);
126 | ```
127 |
128 | ### `remember()` - Standard “Get or Calculate”
129 |
130 | ```php
131 | /**
132 | * Gets the item from the cache or executes the closure and stores the result.
133 | * @param string $cacheKey Item key
134 | * @param int|string $ttl Lifetime in seconds
135 | * @param Closure $callback Function that returns the data if the cache does not exist
136 | * @return mixed
137 | */
138 | $Cacheer->remember(string $cacheKey, int|string $ttl, Closure $callback);
139 | ```
140 |
141 | ### `rememberForever()` - Standard “Get or Calculate” forever
142 |
143 | ```php
144 | /**
145 | * Similar to remember, but stores the result without expiration.
146 | * @param string $cacheKey Item key
147 | * @param int|string $ttl Lifetime in seconds
148 | * @param Closure $callback Function that returns the data if the cache does not exist
149 | * @return mixed
150 | */
151 | $Cacheer->rememberForever(string $cacheKey, int|string $ttl, Closure $callback);
152 | ```
153 |
154 | ### `getAndForget()` - Retrieve and remove
155 |
156 |
157 | ```php
158 | /**
159 | * Gets an item from the cache and immediately removes it.
160 | * @param string $cacheKey Item key
161 | * @param string $namespace Item namespace
162 | * @return mixed Item data or null if it doesn't exist
163 | */
164 | $Cacheer->getAndForget(string $cacheKey, string $namespace);
165 | ```
166 |
167 | ### `add()` - Conditional addition
168 |
169 | ```php
170 | /**
171 | * Adds an item to the cache only if the key does not exist.
172 | * @param string $cacheKey Item key
173 | * @param mixed $cacheData Data to be stored
174 | * @param string $namespace Item namespace
175 | * @param int|string $ttl Lifetime in seconds
176 | * @return bool True if the item was added, false if it already existed
177 | */
178 | $Cacheer->add(string $cacheKey, mixed $cacheData, string $namespace, int|string $ttl);
179 | ```
180 |
181 | ### `clearCache()` - Selective cleaning
182 |
183 |
184 | ```php
185 | /**
186 | * Removes a specific item from the cache.
187 | * @param string $cacheKey Item key
188 | * @param string $namespace Item namespace
189 | * @return void
190 | */
191 | $Cacheer->clearCache(string $cacheKey, string $namespace);
192 | ```
193 |
194 | ### `flushCache()` - Total cleaning
195 |
196 | ```php
197 | /**
198 | * Removes all items from the cache (complete cleaning).
199 | * @return void
200 | */
201 | $Cacheer->flushCache();
202 | ```
203 | ### `useCompression()` - Enable or disable compression
204 |
205 | ```php
206 | $Cacheer->useCompression();
207 | $Cacheer->useCompression(false);
208 | ```
209 |
210 | ### `useEncryption()` - Enable AES encryption
211 |
212 | ```php
213 | $Cacheer->useEncryption('secret-key');
214 | ```
215 | ---
216 |
217 | Each of the functions below allows you to interact with the cache in different ways. Functions that “return void” actually set the status of the operation internally, which can be checked via:
218 |
219 | ```php
220 | $Cacheer->isSuccess(); // Returns true ou false
221 | $Cacheer->getMessage(); // Returns a message
222 | ```
--------------------------------------------------------------------------------
/docs/API-Reference/OptionBuilder/TimeBuilder.md:
--------------------------------------------------------------------------------
1 | ## API Reference
2 |
3 | TimeBuilder provides a fluid and chainable way of defining time periods in a more intuitive way and without typing errors.
4 |
5 | It allows expirationTime and flushAfter values to be passed directly as integers or defined using chained methods such as day(1), week(2), etc.
6 |
7 | #### Simple use
8 |
9 | ```php
10 | OptionBuilder::forFile()
11 | ->expirationTime('1 day')
12 | ->build();
13 | ```
14 | Or use TimeBuilder's chained approach:
15 |
16 | ```php
17 | OptionBuilder::forFile()
18 | ->expirationTime()->day(1)
19 | ->build();
20 | ```
21 |
22 | #### Available methods
23 |
24 | Each method allows you to set a specific time interval.
25 |
26 | | Method | Description | Example |
27 | |--------------|--------------------------------|--------------|
28 | | `second($value)` | Define o tempo em segundos | `->second(30)` |
29 | | `minute($value)` | Define o tempo em minutos | `->minute(15)` |
30 | | `hour($value)` | Define o tempo em horas | `->hour(3)` |
31 | | `day($value)` | Define o tempo em dias | `->day(7)` |
32 | | `week($value)` | Define o tempo em semanas | `->week(2)` |
33 | | `month($value)` | Define o tempo em meses | `->month(1)` |
34 | | `year($value)` | Define o tempo em anos | `->year(1)` |
35 |
36 | #### Full Example
37 |
38 | ```php
39 | $Options = OptionBuilder::forFile()
40 | ->dir(__DIR__ . '/cache')
41 | ->expirationTime()->week(1)
42 | ->flushAfter()->minute(30)
43 | ->build();
44 |
45 | var_dump($Options);
46 | ```
47 |
48 | **Expected Output**
49 |
50 | ```php
51 | [
52 | "cacheDir" => "/path/to/cache",
53 | "expirationTime" => "1 week",
54 | "flushAfter" => "30 minutes"
55 | ]
56 | ```
57 |
58 | Now you can set expiration and flush times without having to remember exact strings. 🚀
--------------------------------------------------------------------------------
/docs/API-Reference/compression_encryption.md:
--------------------------------------------------------------------------------
1 | ## API Reference - Compression & Encryption
2 |
3 | #### `useCompression()`
4 | Enables or disables data compression before storage. When enabled, data is serialized and compressed using `gzcompress`.
5 |
6 | ```php
7 | $Cacheer->useCompression(); // enable
8 | $Cacheer->useCompression(false); // disable
9 | ```
10 |
11 | #### `useEncryption()`
12 | Activates encryption using AES-256-CBC. Provide a secret key to encrypt and decrypt cached data.
13 |
14 | ```php
15 | $Cacheer->useEncryption('your-secret-key');
16 | ```
17 |
18 | You can combine both features for smaller and secure payloads:
19 |
20 | ```php
21 | $Cacheer->useCompression()->useEncryption('your-secret-key');
22 | ```
23 |
--------------------------------------------------------------------------------
/docs/API-Reference/optionBuilder.md:
--------------------------------------------------------------------------------
1 | ## API Reference
2 |
3 | The **OptionBuilder** allows you to define different parameters for configuring CacheerPHP, giving it more security, robustness and speed of execution, as well as excluding possible errors, such as typos, for example.
4 |
5 | Also check out the **TimeBuilder**: [TimeBuilder - Introduction](./OptionBuilder/TimeBuilder.md)
6 |
7 | Currently, it is only compatible with **FileCacheStore**, as this is the driver that requires a set of configurations in advance for it to work.
8 |
9 | Here are some examples:
10 |
11 | [FileCacheStore - Example01](../example01.md)
12 |
13 | [FileCacheStore - Example02](../example02.md)
14 |
15 | You've seen that parameters are very susceptible to typing errors, right?
16 | The **OptionBuilder** arises from the need to eliminate these possible errors.
17 |
18 | #### `OptionBuilder()`
19 |
20 | The **OptionBuilder** has specific methods for configuring each type of cache driver supported.
21 | Each one initializes the configuration for a given driver and returns an instance of the corresponding builder.
22 |
23 | `forFile()`
24 |
25 | ```php
26 | dir(__DIR__ . "/cache")
48 | ->expirationTime("2 hours")
49 | ->flushAfter("1 day")
50 | ->build();
51 |
52 | $Cacheer = new Cacheer($Options);
53 | $Cacheer->setDriver()->useFileDriver(); //File Driver
54 | ```
55 |
56 | #### Coming soon
57 |
58 | ```php
59 | OptionBuilder::forRedis();
60 | OptionBuilder::forDatabase();
61 | ```
62 |
63 | The **OptionBuilder** simplifies the configuration of the **CacheerPHP** by eliminating typing errors and making the process more intuitive.
64 | Now all you have to do is choose the method corresponding to the desired driver and set the necessary parameters to ensure efficient and optimized caching. 🚀
--------------------------------------------------------------------------------
/docs/API-Reference/setConfig.md:
--------------------------------------------------------------------------------
1 | ## API Reference
2 |
3 | Always define the driver to be used in the first instance, and only then define the settings using **setConfig()**.
4 |
5 | Check it out below:
6 | [API Reference - setDriver()](setDriver.md)
7 |
8 | #### `setConfig()`
9 |
10 | ```php
11 | setConfig();
17 | ```
18 |
19 | Configures the database for storing the cache.
20 | ```php
21 | setConfig()->setDatabaseConnection(string $driver)
27 | ```
28 |
29 | - Parameters:
30 |
31 | ```php
32 | $driver: Database driver. Possible values: 'mysql', 'pgsql', 'sqlite'.
33 | ```
34 |
35 | **Example:**
36 |
37 | ```php
38 | setConfig()->setDatabaseConnection('mysql');
44 | ```
45 |
46 | There is also an alternative, which is to define the driver in the .env file, through the DB_CONNECTION variable, passing the same values.
47 |
48 | Timezone
49 | ---
50 |
51 | ```php
52 | setConfig()->setTimeZone(string $timezone);
58 | ```
59 |
60 | Sets the time zone for cache operations.
61 | - Parameters
62 |
63 | ```php
64 | $timezone: Time zone in PHP format (example: 'UTC', 'Africa/Luanda').
65 | ```
66 |
67 | **Example:**
68 |
69 | ```php
70 | $Cacheer->setConfig()->setTimeZone('UTC');
71 | ```
72 |
73 | Check out the timezones supported by PHP here:
74 | https://www.php.net/manual/en/timezones.php
75 |
76 | Logger
77 | ---
78 |
79 | ```php
80 | $Cacheer->setConfig()->setLoggerPath(string $path);
81 | ```
82 | Defines the path where the logs will be stored.
83 |
84 | - Parameters
85 |
86 | ```php
87 | $path: Caminho completo para o arquivo de logs.
88 | ```
89 |
90 | **Example:**
91 |
92 | ```php
93 | $Cacheer->setConfig()->setLoggerPath('/path/to/logs/CacheerPHP.log');
94 | ```
--------------------------------------------------------------------------------
/docs/API-Reference/setDriver.md:
--------------------------------------------------------------------------------
1 | ## API Reference
2 |
3 | #### 2. **Drivers**
4 |
5 | ```php
6 | setDriver();
12 | ```
13 |
14 | Defines the cache driver as file-based:
15 | ```php
16 | setDriver()->useFileDriver();
22 | ```
23 |
24 | Defines the cache driver as database-based:
25 | ```php
26 | setDriver()->useDatabaseDriver();
32 | ```
33 |
34 | Sets the cache driver to be based on Redis:
35 | ```php
36 | setDriver()->useRedisDriver();
42 | ```
43 |
44 | Sets the cache driver to be based on Arrays (Memory):
45 | ```php
46 | setDriver()->useArrayDriver();
52 | ```
--------------------------------------------------------------------------------
/docs/api-reference.md:
--------------------------------------------------------------------------------
1 | ## API Reference
2 |
3 | ## **Classes Principais**
4 |
5 | ```bash
6 | Silviooosilva\CacheerPhp\Cacheer
7 | ```
8 |
9 | The package's main class, used for all caching operations.
10 |
11 |
12 | ## **Methods**
13 |
14 | ### 1. **Configuration**
15 |
16 | #### `setConfig()`
17 | Starts a customized configuration for CacheerPHP.
18 |
19 | [API Reference - setConfig()](API-Reference/setConfig.md)
20 |
21 | ### 2. **Drivers**
22 | It allows you to define the different backends available for use.
23 |
24 | [API Reference - setDriver()](API-Reference/setDriver.md)
25 |
26 | ### 3. **OptionBuilder**
27 | The **OptionBuilder** simplifies the configuration of CacheerPHP by eliminating typing errors and making the process more intuitive.
28 |
29 | [API Reference - OptionBuilder](API-Reference/optionBuilder.md)
30 | ### 4. **Compression & Encryption**
31 | Built-in methods to reduce storage space and secure cached data.
32 |
33 | [API Reference - Compression & Encryption](API-Reference/compression_encryption.md)
34 |
--------------------------------------------------------------------------------
/docs/cacheer_php_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/silviooosilva/CacheerPHP/29b1f60e2032cabd5048ef0b40c389f2be3d4384/docs/cacheer_php_logo.png
--------------------------------------------------------------------------------
/docs/cacheer_php_logo__.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/silviooosilva/CacheerPHP/29b1f60e2032cabd5048ef0b40c389f2be3d4384/docs/cacheer_php_logo__.png
--------------------------------------------------------------------------------
/docs/example01.md:
--------------------------------------------------------------------------------
1 | ## Exemplo 01
2 | Simple Data Cache
3 |
4 | ```php
5 | __DIR__ . "/cache",
13 | ];
14 |
15 | $Cacheer = new Cacheer($options);
16 |
17 | // Data to be stored in the cache
18 | $cacheKey = 'user_profile_1234';
19 | $userProfile = [
20 | 'id' => 123,
21 | 'name' => 'John Doe',
22 | 'email' => 'john.doe@example.com',
23 | ];
24 |
25 | // Storing data in the cache
26 | $Cacheer->putCache($cacheKey, $userProfile);
27 |
28 | // Retrieving data from the cache
29 | $cachedProfile = $Cacheer->getCache($cacheKey);
30 |
31 | if ($Cacheer->isSuccess()) {
32 | echo "Cache Found: ";
33 | print_r($cachedProfile);
34 | } else {
35 | echo $Cacheer->getMessage();
36 | }
37 |
38 | ```
39 |
--------------------------------------------------------------------------------
/docs/example02.md:
--------------------------------------------------------------------------------
1 | w## Exemplo 02
2 |
3 | Cache com tempo de expiração Personalizado
4 |
5 | ```php
6 | __DIR__ . "/cache",
13 | "expirationTime" => "2 hour" //Primeira opção (definição global)
14 | ];
15 |
16 | $Cacheer = new Cacheer($options);
17 |
18 | // Dados a serem armazenados no cache
19 | $cacheKey = 'daily_stats';
20 | $dailyStats = [
21 | 'visits' => 1500,
22 | 'signups' => 35,
23 | 'revenue' => 500.75,
24 | ];
25 |
26 | // Armazenando dados no cache
27 | $Cacheer->putCache($cacheKey, $dailyStats);
28 |
29 | // Recuperando dados do cache por 2 horas
30 | $cachedStats = $Cacheer->getCache($cacheKey, 'namespace', '2 hours'); //Segunda opção (definição no método)
31 |
32 | if ($Cacheer->isSuccess()) {
33 | echo "Cache Found: ";
34 | print_r($cachedStats);
35 | } else {
36 | echo $Cacheer->getMessage();
37 | }
38 |
39 | ```
40 |
41 | Pode configurar o tempo de expiração do cache em:
42 |
43 | ```php
44 | Minutos: minute(s)
45 | Horas: hour(s)
46 | Segundos: second(s)
47 | ```
48 |
--------------------------------------------------------------------------------
/docs/example03.md:
--------------------------------------------------------------------------------
1 | ## Exemplo 03
2 | Cache cleaning and flushing
3 |
4 | ```php
5 | __DIR__ . "/cache",
13 | ];
14 |
15 | $Cacheer = new Cacheer($options);
16 |
17 | // Key of the cache to be cleared
18 | $cacheKey = 'user_profile_123';
19 |
20 | // Clearing a specific item from the cache
21 |
22 | $Cacheer->clearCache($cacheKey);
23 |
24 | if ($Cacheer->isSuccess()) {
25 | echo $Cacheer->getMessage();
26 | } else {
27 | echo $Cacheer->getMessage();
28 | }
29 |
30 | $Cacheer->flushCache();
31 |
32 | if ($Cacheer->isSuccess()) {
33 | echo $Cacheer->getMessage();
34 | } else {
35 | echo $Cacheer->getMessage();
36 | }
37 |
38 |
39 | ```
40 |
--------------------------------------------------------------------------------
/docs/example04.md:
--------------------------------------------------------------------------------
1 | ## Exemplo 04
2 | Use of Namespaces
3 |
4 | ```php
5 | __DIR__ . "/cache",
12 | ];
13 |
14 | $Cacheer = new Cacheer($options);
15 |
16 | // Data to be stored in the namespace cache
17 | $namespace = 'session_data_01';
18 | $cacheKey = 'session_456';
19 | $sessionData = [
20 | 'user_id' => 456,
21 | 'login_time' => time(),
22 | ];
23 |
24 | // Caching data with namespace
25 | $Cacheer->putCache($cacheKey, $sessionData, $namespace);
26 |
27 | // Retrieving data from the cache
28 | $cachedSessionData = $Cacheer->getCache($cacheKey, $namespace);
29 |
30 | if ($Cacheer->isSuccess()) {
31 | echo "Cache Found: ";
32 | print_r($cachedSessionData);
33 | } else {
34 | echo $Cacheer->getMessage();
35 | }
36 | ```
--------------------------------------------------------------------------------
/docs/example05.md:
--------------------------------------------------------------------------------
1 | ## Exemplo 05
2 | API Response Cache
3 |
4 | ```php
5 | __DIR__ . "/cache",
13 | ];
14 |
15 | $Cacheer = new Cacheer($options);
16 |
17 | // API URL and cache key
18 | $apiUrl = 'https://jsonplaceholder.typicode.com/posts';
19 | $cacheKey = 'api_response_' . md5($apiUrl);
20 |
21 | // Checking if the API response is already in the cache
22 | $cachedResponse = $Cacheer->getCache($cacheKey);
23 |
24 | if ($Cacheer->isSuccess()) {
25 | // Use the cache response
26 | $response = $cachedResponse;
27 | } else {
28 | // Call the API and store the response in the cache
29 | $response = file_get_contents($apiUrl);
30 | $Cacheer->putCache($cacheKey, $response);
31 | }
32 |
33 | // Using the API response (from cache or call)
34 | $data = json_decode($response, true);
35 | print_r($data);
36 |
37 | ```
38 |
--------------------------------------------------------------------------------
/docs/example06.md:
--------------------------------------------------------------------------------
1 | ## Exemplo 06
2 |
3 | JSON type data output
4 | To configure the output type you want, you have to enable it when you instantiate the class, passing the last parameter as true.:
5 |
6 | ```php
7 |
8 | __DIR__ . "/cache",
15 | ];
16 |
17 | $Cacheer = new Cacheer($options, $formatted = true); // True last parameter
18 |
19 | // Data to be stored in the cache
20 | $cacheKey = 'user_profile_1234';
21 |
22 | $userProfile = [
23 | 'id' => 123,
24 | 'name' => 'John Doe',
25 | 'email' => 'john.doe@example.com',
26 | ];
27 |
28 | // Storing data in the cache
29 |
30 | $Cacheer->putCache($cacheKey, $userProfile);
31 |
32 | // Retrieving data from the cache in JSON format
33 |
34 | $cachedProfile = $Cacheer->getCache(
35 | $cacheKey,
36 | $namespace,
37 | $ttl)->toJson();
38 |
39 | if ($Cacheer->isSuccess()) {
40 | echo "Cache Found: ";
41 | print_r($cachedProfile);
42 | } else {
43 | echo $Cacheer->getMessage();
44 | }
45 |
46 | ```
--------------------------------------------------------------------------------
/docs/example07.md:
--------------------------------------------------------------------------------
1 | ## Exemplo 07
2 |
3 | Array Data Output
4 | To configure the output type you want, you have to enable it when you instantiate the class, passing the last parameter as true.:
5 |
6 | ```php
7 |
8 | __DIR__ . "/cache",
15 | ];
16 |
17 | $Cacheer = new Cacheer($options, $formatted = true); // True last parameter
18 |
19 | // Data to be stored in the cache
20 |
21 | $cacheKey = 'user_profile_1234';
22 |
23 | $userProfile = [
24 | 'id' => 123,
25 | 'name' => 'John Doe',
26 | 'email' => 'john.doe@example.com',
27 | ];
28 |
29 | // Storing data in the cache
30 |
31 | $Cacheer->putCache($cacheKey, $userProfile);
32 |
33 | // Retrieving data from the cache in JSON format
34 |
35 | $cachedProfile = $Cacheer->getCache(
36 | $cacheKey,
37 | $namespace,
38 | $ttl)->toArray();
39 |
40 | if ($Cacheer->isSuccess()) {
41 | echo "Cache Found: ";
42 | print_r($cachedProfile);
43 | } else {
44 | echo $Cacheer->getMessage();
45 | }
46 |
47 | ```
--------------------------------------------------------------------------------
/docs/example08.md:
--------------------------------------------------------------------------------
1 | ## Exemplo 08
2 |
3 | String Data Output
4 | To configure the output type you want, you have to enable it when you instantiate the class, passing the last parameter as true.:
5 |
6 | ```php
7 |
8 | __DIR__ . "/cache",
15 | ];
16 |
17 | $Cacheer = new Cacheer($options, $formatted = true); // True last parameter
18 |
19 | // Data to be stored in the cache
20 |
21 | $cacheKey = 'user_profile_1234';
22 |
23 | $userProfile = [
24 | 'id' => 123,
25 | 'name' => 'John Doe',
26 | 'email' => 'john.doe@example.com',
27 | ];
28 |
29 | // Storing data in the cache
30 |
31 | $Cacheer->putCache($cacheKey, $userProfile);
32 |
33 | // Retrieving data from the cache in JSON format
34 |
35 | $cachedProfile = $Cacheer->getCache(
36 | $cacheKey,
37 | $namespace,
38 | $ttl)->toString();
39 |
40 | if ($Cacheer->isSuccess()) {
41 | echo "Cache Found: ";
42 | print_r($cachedProfile);
43 | } else {
44 | echo $Cacheer->getMessage();
45 | }
46 |
47 | ```
--------------------------------------------------------------------------------
/docs/example09.md:
--------------------------------------------------------------------------------
1 | ## Exemplo 09
2 |
3 | Automatic cleaning of the cache directory (flushAfter)
4 |
5 | To use automatic cleaning of the cache directory, you will need to configure the options:
6 |
7 | ```php
8 |
9 | __DIR__ . "/cache",
16 | "flushAfter" => "1 week" //string
17 | ];
18 |
19 | $Cacheer = new Cacheer($options);
20 |
21 | // Data to be stored in the cache
22 |
23 | $cacheKey = 'user_profile_1234';
24 |
25 | $userProfile = [
26 | 'id' => 123,
27 | 'name' => 'John Doe',
28 | 'email' => 'john.doe@example.com',
29 | ];
30 |
31 | // Storing data in the cache
32 |
33 | $Cacheer->putCache($cacheKey, $userProfile);
34 |
35 | // Retrieving data from the cache
36 |
37 | $cachedProfile = $Cacheer->getCache($cacheKey);
38 |
39 | if ($Cacheer->isSuccess()) {
40 | echo "Cache Found: ";
41 | print_r($cachedProfile);
42 | } else {
43 | echo $Cacheer->getMessage();
44 | }
45 |
46 |
47 | ```
48 | The accepted time formats for `flushAfter` are:
49 |
50 | ```php
51 | Segundos: second(s)
52 | Minutos: minute(s)
53 | Horas: hour(s)
54 | Dias: day(s)
55 | Semanas: week(s)
56 | Meses: month(s)
57 | Anos: year(s)
58 |
59 | ```
60 |
--------------------------------------------------------------------------------
/docs/guia2.0.0.md:
--------------------------------------------------------------------------------
1 | # Release of Version 2.0.0 of CacheerPHP
2 |
3 | We are excited to announce the release of **version 2.0.0** of **CacheerPHP**! This release brings a number of new features and improvements that increase flexibility and choice for developers looking to manage caching efficiently.
4 |
5 | ## Main New Features of Version 2.0.0
6 |
7 | - **Database Support**: CacheerPHP now supports cache storage in **databases** with options for `MySQL`, `SQLite`, and `PostgreSQL`. This allows for greater flexibility, scalability, and performance in various usage scenarios.
8 | - **Performance Improvements**: Additional optimizations for cache retrieval and insertion, ensuring greater efficiency, especially in systems with high data volume.
9 | - **New Features**: It is now possible to monitor the operation of the cache system with the new logging feature. Errors, warnings, information, and debug messages are recorded and stored, providing a clear view of system performance and making it easier to identify and solve potential issues.
10 |
11 | ## Benefits of the Update
12 |
13 | With **version 2.0.0**, you get:
14 |
15 | - **Flexibility** to choose the best cache storage solution for your application.
16 | - **Better performance**, with improvements in the process of retrieving and storing cached data.
17 |
18 | ---
19 |
20 | # Upgrade Guide for CacheerPHP 2.0.0
21 |
22 | To ensure a smooth transition to version 2.0.0, follow this detailed upgrade manual.
23 |
24 | ## System Requirements
25 |
26 | - **PHP** version 8.0 or higher.
27 | - **Database (optional)**: MySQL, PostgreSQL, or SQLite (for using the database-based cache driver).
28 |
29 | ## Step-by-Step Upgrade
30 |
31 | ### 1. Backup Current Cache Data
32 |
33 | Before starting the upgrade, it is recommended to back up any relevant cache data. If you are using file-based cache, save the cache directory.
34 |
35 | ### 2. Update the Package via Composer
36 |
37 | Run the command below to update to the latest version of CacheerPHP:
38 |
39 | ```bash
40 | composer require silviooosilva/cacheer-php:^2.0.0
41 | ```
42 |
43 | ### 3. Configuration
44 |
45 | After the update, follow the instructions below to configure the new version.
46 |
47 | **Keep File-Based Cache**
48 |
49 | If you already use file-based cache and want to keep this configuration, no further action is needed.
50 |
51 | **Migrate to Database-Based Cache**
52 |
53 | #### 1) Configure Connection Data
54 |
55 | - Edit the CacheerPHP configuration file, located in the ```Boot/config.php``` folder, and enter your database details.
56 |
57 | #### 2) Enable the Database Driver
58 |
59 | - Example usage in code:
60 |
61 | ```php
62 | setConfig()->setDatabaseConnection('mysql');
69 | $Cacheer->setDriver()->useDatabaseDriver();
70 |
71 | ```
72 |
73 | #### 3) Configure Timezone
74 |
75 | - To avoid issues with cache expiration, set the timezone:
76 |
77 | ```php
78 | $Cacheer->setConfig()->setTimeZone('Africa/Luanda');
79 | ```
80 | **NB: Make sure the provided timezone is valid**
81 | - https://www.php.net/manual/en/timezones.php
82 |
83 | #### 4) Logging System
84 |
85 | - Set the path to save the logs:
86 |
87 | ```php
88 | $Cacheer->setConfig()->setLoggerPath('/path/CacheerPHP.log');
89 | ```
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | tests
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/Boot/Configs.php:
--------------------------------------------------------------------------------
1 | load();
12 |
13 |
14 | $Connection = $_ENV['DB_CONNECTION'] ?? 'mysql';
15 | $Host = $_ENV['DB_HOST'] ?? 'localhost';
16 | $Port = $_ENV['DB_PORT'] ?? '3306';
17 | $DBName = $_ENV['DB_DATABASE'] ?? 'cacheer_db';
18 | $User = $_ENV['DB_USERNAME'] ?? 'root';
19 | $Password = $_ENV['DB_PASSWORD'] ?? '';
20 |
21 | // Retrieve Redis environment variables
22 | $redisClient = $_ENV['REDIS_CLIENT'] ?? '';
23 | $redisHost = $_ENV['REDIS_HOST'] ?? 'localhost';
24 | $redisPassword = $_ENV['REDIS_PASSWORD'] ?? '';
25 | $redisPort = $_ENV['REDIS_PORT'] ?? '6379';
26 | $redisNamespace = $_ENV['REDIS_NAMESPACE'] ?? '';
27 |
28 | Connect::setConnection($Connection);
29 |
30 | // Database configuration array
31 | define('CACHEER_DATABASE_CONFIG', [
32 | "mysql" => [
33 | "driver" => $Connection,
34 | "host" => $Host,
35 | "port" => $Port,
36 | "dbname" => $DBName,
37 | "username"=> $User,
38 | "passwd" => $Password,
39 | "options" => [
40 | PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
41 | PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
42 | PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
43 | PDO::ATTR_CASE => PDO::CASE_NATURAL
44 | ]
45 | ],
46 | "sqlite" => [
47 | "driver" => $Connection,
48 | "dbname" => SqliteHelper::database(),
49 | "options" => [
50 | PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
51 | PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
52 | PDO::ATTR_CASE => PDO::CASE_NATURAL
53 | ]
54 | ],
55 | "pgsql" => [
56 | "driver" => $Connection,
57 | "host" => $Host,
58 | "port" => $Port,
59 | "dbname" => $DBName,
60 | "username"=> $User,
61 | "passwd" => $Password,
62 | "options" => [
63 | PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
64 | PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
65 | PDO::ATTR_CASE => PDO::CASE_NATURAL
66 | ]
67 | ],
68 | ]);
69 |
70 | // Redis configuration array
71 | define('REDIS_CONNECTION_CONFIG', [
72 | 'REDIS_CLIENT' => $redisClient,
73 | 'REDIS_HOST' => $redisHost,
74 | 'REDIS_PASSWORD' => $redisPassword,
75 | 'REDIS_PORT' => $redisPort,
76 | 'REDIS_NAMESPACE'=> $redisNamespace
77 | ]);
78 |
79 |
--------------------------------------------------------------------------------
/src/CacheStore/ArrayCacheStore.php:
--------------------------------------------------------------------------------
1 |
11 | * @package Silviooosilva\CacheerPhp
12 | */
13 | class ArrayCacheStore implements CacheerInterface
14 | {
15 |
16 | /**
17 | * @param array $arrayStore
18 | */
19 | private array $arrayStore = [];
20 |
21 | /**
22 | * @param boolean
23 | */
24 | private bool $success = false;
25 |
26 | /**
27 | * @param string
28 | */
29 | private string $message = '';
30 |
31 | /**
32 | * @var CacheLogger
33 | */
34 | private $logger = null;
35 |
36 | public function __construct(string $logPath)
37 | {
38 | $this->logger = new CacheLogger($logPath);
39 | }
40 |
41 | /**
42 | * @param string $cacheKey
43 | * @param mixed $cacheData
44 | * @param string $namespace
45 | * @return bool
46 | */
47 | public function appendCache(string $cacheKey, mixed $cacheData, string $namespace = '')
48 | {
49 | $arrayStoreKey = $this->buildArrayKey($cacheKey, $namespace);
50 |
51 | if (!$this->has($cacheKey, $namespace)) {
52 | $this->setMessage("cacheData can't be appended, because doesn't exist or expired", false);
53 | $this->logger->debug("{$this->getMessage()} from array driver.");
54 | return false;
55 | }
56 |
57 | $this->arrayStore[$arrayStoreKey]['cacheData'] = serialize($cacheData);
58 | $this->setMessage("Cache appended successfully", true);
59 | return true;
60 | }
61 |
62 | /**
63 | * @param string $cacheKey
64 | * @param string $namespace
65 | * @return string
66 | */
67 | private function buildArrayKey(string $cacheKey, string $namespace = '')
68 | {
69 | return !empty($namespace) ? ($namespace . ':' . $cacheKey) : $cacheKey;
70 | }
71 |
72 | /**
73 | * @param string $cacheKey
74 | * @param string $namespace
75 | * @return void
76 | */
77 | public function clearCache(string $cacheKey, string $namespace = '')
78 | {
79 | $arrayStoreKey = $this->buildArrayKey($cacheKey, $namespace);
80 | unset($this->arrayStore[$arrayStoreKey]);
81 | $this->setMessage("Cache cleared successfully", true);
82 | $this->logger->debug("{$this->getMessage()} from array driver.");
83 | }
84 |
85 | /**
86 | * @param string $cacheKey
87 | * @param int $amount
88 | * @param string $namespace
89 | * @return bool
90 | */
91 | public function decrement(string $cacheKey, int $amount = 1, string $namespace = '')
92 | {
93 | return $this->increment($cacheKey, ($amount * -1), $namespace);
94 | }
95 |
96 | /**
97 | * @return void
98 | */
99 | public function flushCache()
100 | {
101 | unset($this->arrayStore);
102 | $this->arrayStore = [];
103 | $this->setMessage("Cache flushed successfully", true);
104 | $this->logger->debug("{$this->getMessage()} from array driver.");
105 | }
106 |
107 | /**
108 | * @param string $cacheKey
109 | * @param mixed $cacheData
110 | * @param string $namespace
111 | * @param int|string $ttl
112 | * @return void
113 | */
114 | public function forever(string $cacheKey, mixed $cacheData)
115 | {
116 | $this->putCache($cacheKey, $cacheData, ttl: 31536000 * 1000);
117 | $this->setMessage($this->getMessage(), $this->isSuccess());
118 | }
119 |
120 | /**
121 | * @param string $cacheKey
122 | * @param string $namespace
123 | * @param int|string $ttl
124 | * @return mixed
125 | */
126 | public function getCache(string $cacheKey, string $namespace = '', string|int $ttl = 3600)
127 | {
128 | $arrayStoreKey = $this->buildArrayKey($cacheKey, $namespace);
129 |
130 | if (!$this->has($cacheKey, $namespace)) {
131 | $this->setMessage("cacheData not found, does not exists or expired", false);
132 | $this->logger->debug("{$this->getMessage()} from array driver.");
133 | return false;
134 | }
135 |
136 | $cacheData = $this->arrayStore[$arrayStoreKey];
137 | $expirationTime = $cacheData['expirationTime'] ?? 0;
138 | $now = time();
139 |
140 | if($expirationTime !== 0 && $now >= $expirationTime) {
141 | list($np, $key) = explode(':', $arrayStoreKey);
142 | $this->clearCache($key, $np);
143 | $this->setMessage("cacheKey: {$key} has expired.", false);
144 | $this->logger->debug("{$this->getMessage()} from array driver.");
145 | return false;
146 | }
147 |
148 | $this->setMessage("Cache retrieved successfully", true);
149 | $this->logger->debug("{$this->getMessage()} from array driver.");
150 | return $this->serialize($cacheData['cacheData'], false);
151 | }
152 |
153 | /**
154 | * @param string $cacheKey
155 | * @param string $namespace
156 | * @return bool
157 | */
158 | public function has(string $cacheKey, string $namespace = '')
159 | {
160 | $arrayStoreKey = $this->buildArrayKey($cacheKey, $namespace);
161 | return isset($this->arrayStore[$arrayStoreKey]) && time() < $this->arrayStore[$arrayStoreKey]['expirationTime'];
162 | }
163 |
164 | /**
165 | * @param string $cacheKey
166 | * @param int $amount
167 | * @param string $namespace
168 | * @return bool
169 | */
170 | public function increment(string $cacheKey, int $amount = 1, string $namespace = '')
171 | {
172 | $cacheData = $this->getCache($cacheKey, $namespace);
173 |
174 | if(!empty($cacheData) && is_numeric($cacheData)) {
175 | $this->putCache($cacheKey, (int)($cacheData + $amount), $namespace);
176 | $this->setMessage($this->getMessage(), $this->isSuccess());
177 | return true;
178 | }
179 |
180 | return false;
181 | }
182 |
183 | /**
184 | * @return boolean
185 | */
186 | public function isSuccess()
187 | {
188 | return $this->success;
189 | }
190 |
191 | /**
192 | * @return string
193 | */
194 | public function getMessage()
195 | {
196 | return $this->message;
197 | }
198 |
199 | /**
200 | * @param string $cacheKey
201 | * @param mixed $cacheData
202 | * @param string $namespace
203 | * @param int|string $ttl
204 | * @return bool
205 | */
206 | public function putCache(string $cacheKey, mixed $cacheData, string $namespace = '', int|string $ttl = 3600)
207 | {
208 | $arrayStoreKey = $this->buildArrayKey($cacheKey, $namespace);
209 |
210 | $this->arrayStore[$arrayStoreKey] = [
211 | 'cacheData' => serialize($cacheData),
212 | 'expirationTime' => time() + $ttl
213 | ];
214 |
215 | $this->setMessage("Cache stored successfully", true);
216 | $this->logger->debug("{$this->getMessage()} from Array driver.");
217 | return true;
218 | }
219 |
220 | /**
221 | * @param array $items
222 | * @param string $namespace
223 | * @param int $batchSize
224 | * @return void
225 | */
226 | public function putMany(array $items, string $namespace = '', int $batchSize = 100)
227 | {
228 | $chunks = array_chunk($items, $batchSize, true);
229 |
230 | foreach ($chunks as $chunk) {
231 | foreach ($chunk as $key => $data) {
232 | $this->putCache($data['cacheKey'], $data['cacheData'], $namespace);
233 | }
234 | }
235 | $this->setMessage("{$this->getMessage()}", $this->isSuccess());
236 | $this->logger->debug("{$this->getMessage()} from Array driver.");
237 | }
238 |
239 | /**
240 | * @param string $cacheKey
241 | * @param string|int $ttl
242 | * @param string $namespace
243 | * @return void
244 | */
245 | public function renewCache(string $cacheKey, int|string $ttl = 3600, string $namespace = '')
246 | {
247 | $arrayStoreKey = $this->buildArrayKey($cacheKey, $namespace);
248 |
249 | if (isset($this->arrayStore[$arrayStoreKey])) {
250 | $ttlSeconds = is_numeric($ttl) ? (int) $ttl : strtotime($ttl) - time();
251 | $this->arrayStore[$arrayStoreKey]['expirationTime'] = time() + $ttlSeconds;
252 | $this->setMessage("cacheKey: {$cacheKey} renewed successfully", true);
253 | $this->logger->debug("{$this->getMessage()} from array driver.");
254 | }
255 | }
256 |
257 | /**
258 | * @param string $message
259 | * @param boolean $success
260 | * @return void
261 | */
262 | private function setMessage(string $message, bool $success)
263 | {
264 | $this->message = $message;
265 | $this->success = $success;
266 | }
267 |
268 | /**
269 | * @param mixed $data
270 | * @param bool $serialize
271 | * @return mixed
272 | */
273 | private function serialize(mixed $data, bool $serialize = true)
274 | {
275 | return $serialize ? serialize($data) : unserialize($data);
276 | }
277 | }
278 |
--------------------------------------------------------------------------------
/src/CacheStore/CacheManager/FileCacheManager.php:
--------------------------------------------------------------------------------
1 |
12 | * @package Silviooosilva\CacheerPhp
13 | */
14 | class FileCacheManager
15 | {
16 |
17 | /**
18 | * @param string $dir
19 | * @return void
20 | */
21 | public function createDirectory(string $dir)
22 | {
23 | if ((!file_exists($dir) || !is_dir($dir)) && !mkdir($dir, 0755, true)) {
24 | throw CacheFileException::create("Could not create directory: {$dir}");
25 | }
26 | }
27 |
28 | /**
29 | * @param string $filename
30 | * @param string $data
31 | * @return void
32 | */
33 | public function writeFile(string $filename, string $data)
34 | {
35 | if (!@file_put_contents($filename, $data, LOCK_EX)) {
36 | throw CacheFileException::create("Could not write file: {$filename}");
37 | }
38 | }
39 |
40 | /**
41 | * @param string $filename
42 | * @return string
43 | */
44 | public function readFile(string $filename)
45 | {
46 | if (!$this->fileExists($filename)) {
47 | throw CacheFileException::create("File not found: {$filename}");
48 | }
49 | return file_get_contents($filename);
50 | }
51 |
52 | /**
53 | * @param string $filename
54 | * @return bool
55 | */
56 | public function fileExists(string $filename)
57 | {
58 | return file_exists($filename);
59 | }
60 |
61 | /**
62 | * @param string $filename
63 | * @return void
64 | */
65 | public function removeFile(string $filename)
66 | {
67 | if (file_exists($filename)) {
68 | unlink($filename);
69 | }
70 | }
71 |
72 | /**
73 | * @param string $dir
74 | * @return void
75 | */
76 | public function clearDirectory(string $dir)
77 | {
78 | $iterator = new RecursiveIteratorIterator(
79 | new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
80 | RecursiveIteratorIterator::CHILD_FIRST
81 | );
82 | foreach ($iterator as $file) {
83 | $path = $file->getPathname();
84 | $file->isDir() ? rmdir($path) : unlink($path);
85 | }
86 | }
87 |
88 | /**
89 | * @param mixed $data
90 | * @param bool $serialize
91 | */
92 | public function serialize(mixed $data, bool $serialize = true)
93 | {
94 | if($serialize) {
95 | return serialize($data);
96 | }
97 | return unserialize($data);
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/CacheStore/CacheManager/OptionBuilders/FileOptionBuilder.php:
--------------------------------------------------------------------------------
1 |
12 | * @package Silviooosilva\CacheerPhp
13 | */
14 | class FileOptionBuilder
15 | {
16 | /** @param null|string $cacheDir */
17 | private ?string $cacheDir = null;
18 |
19 | /** @param null|string $expirationTime */
20 | private ?string $expirationTime = null;
21 |
22 | /** @param null|string $flushAfter */
23 | private ?string $flushAfter = null;
24 |
25 | /** @param array $options */
26 | private array $options = [];
27 |
28 | /**
29 | * @param string $cacheDir
30 | * @return $this
31 | */
32 | public function dir(string $cacheDir)
33 | {
34 | $this->cacheDir = $cacheDir;
35 | return $this;
36 | }
37 |
38 | /**
39 | * @param ?string $expirationTime
40 | * @return $this|TimeBuilder
41 | */
42 | public function expirationTime(?string $expirationTime = null)
43 | {
44 |
45 | if (!is_null($expirationTime)) {
46 | $this->expirationTime = $expirationTime;
47 | return $this;
48 | }
49 |
50 | return new TimeBuilder(function ($formattedTime){
51 | $this->expirationTime = $formattedTime;
52 | }, $this);
53 | }
54 |
55 | /**
56 | * @param ?string $flushAfter
57 | * @return $this|TimeBuilder
58 | */
59 | public function flushAfter(?string $flushAfter = null)
60 | {
61 |
62 | if (!is_null($flushAfter)) {
63 | $this->flushAfter = mb_strtolower($flushAfter, 'UTF-8');
64 | return $this;
65 | }
66 |
67 | return new TimeBuilder(function ($formattedTime){
68 | $this->flushAfter = $formattedTime;
69 | }, $this);
70 | }
71 |
72 | /**
73 | * @return array
74 | */
75 | public function build()
76 | {
77 | return $this->validated();
78 | }
79 |
80 | /**
81 | * @return array
82 | */
83 | private function validated()
84 | {
85 | foreach ($this->properties() as $key => $value) {
86 | if ($this->isValidAndNotNull($value)) {
87 | $this->options[$key] = $value;
88 | }
89 | }
90 | return $this->options;
91 | }
92 |
93 | /**
94 | * @param mixed $data
95 | * @return bool
96 | */
97 | private function isValidAndNotNull(mixed $data)
98 | {
99 | return !empty($data) ? true : false;
100 | }
101 |
102 | /**
103 | * @return array
104 | */
105 | private function properties()
106 | {
107 | $properties = [
108 | 'cacheDir' => $this->cacheDir,
109 | 'expirationTime' => $this->expirationTime,
110 | 'flushAfter' => $this->flushAfter
111 | ];
112 |
113 | return $properties;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/CacheStore/CacheManager/RedisCacheManager.php:
--------------------------------------------------------------------------------
1 |
12 | * @package Silviooosilva\CacheerPhp
13 | */
14 | class RedisCacheManager
15 | {
16 |
17 | /** @var Predis\Client */
18 | private static $redis;
19 |
20 | /** @param string $namespace */
21 | private static $namespace;
22 |
23 | /**
24 | * @return Client
25 | */
26 | public static function connect()
27 | {
28 | Autoloader::register();
29 | self::$redis = new Client([
30 | 'scheme' => 'tcp',
31 | 'host' => REDIS_CONNECTION_CONFIG['REDIS_HOST'],
32 | 'port' => REDIS_CONNECTION_CONFIG['REDIS_PORT'],
33 | 'password' => REDIS_CONNECTION_CONFIG['REDIS_PASSWORD'],
34 | 'database' => 0
35 | ]);
36 | self::auth();
37 | self::$namespace = REDIS_CONNECTION_CONFIG['REDIS_NAMESPACE'] ?? 'Cache';
38 | return self::$redis;
39 | }
40 |
41 | /**
42 | * @return void
43 | */
44 | private static function auth()
45 | {
46 | if(is_string(REDIS_CONNECTION_CONFIG['REDIS_PASSWORD']) && REDIS_CONNECTION_CONFIG['REDIS_PASSWORD'] !== '') {
47 | self::$redis->auth(REDIS_CONNECTION_CONFIG['REDIS_PASSWORD']);
48 | }
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/CacheStore/DatabaseCacheStore.php:
--------------------------------------------------------------------------------
1 |
13 | * @package Silviooosilva\CacheerPhp
14 | */
15 | class DatabaseCacheStore implements CacheerInterface
16 | {
17 | /**
18 | * @param boolean
19 | */
20 | private bool $success = false;
21 |
22 | /**
23 | * @param string
24 | */
25 | private string $message = '';
26 |
27 | /**
28 | * @var CacheLogger
29 | */
30 | private $logger = null;
31 |
32 | /**
33 | * @var CacheDatabaseRepository
34 | */
35 | private $cacheRepository;
36 |
37 | public function __construct(string $logPath)
38 | {
39 | $this->logger = new CacheLogger($logPath);
40 | $this->cacheRepository = new CacheDatabaseRepository();
41 | }
42 |
43 | /**
44 | * @param string $cacheKey
45 | * @param mixed $cacheData
46 | * @param string $namespace
47 | * @return bool
48 | */
49 | public function appendCache(string $cacheKey, mixed $cacheData, string $namespace = '')
50 | {
51 | $currentCacheData = $this->getCache($cacheKey, $namespace);
52 | $mergedCacheData = CacheDatabaseHelper::arrayIdentifier($currentCacheData, $cacheData);
53 |
54 | if ($this->updateCache($cacheKey, $mergedCacheData, $namespace)) {
55 | $this->logger->debug("{$this->getMessage()} from database driver.");
56 | return true;
57 | }
58 |
59 | $this->logger->error("{$this->getMessage()} from database driver.");
60 | return false;
61 | }
62 |
63 | /**
64 | * @param string $cacheKey
65 | * @param string $namespace
66 | * @return void
67 | */
68 | public function clearCache(string $cacheKey, string $namespace = '')
69 | {
70 | $data = $this->cacheRepository->clear($cacheKey, $namespace);
71 | if($data) {
72 | $this->setMessage("Cache deleted successfully!", true);
73 | } else {
74 | $this->setMessage("Cache does not exists!", false);
75 | }
76 |
77 | $this->logger->debug("{$this->getMessage()} from database driver.");
78 | }
79 |
80 | /**
81 | * @return void
82 | */
83 | public function flushCache()
84 | {
85 | if($this->cacheRepository->flush()){
86 | $this->setMessage("Flush finished successfully", true);
87 | } else {
88 | $this->setMessage("Something went wrong. Please, try again.", false);
89 | }
90 |
91 | $this->logger->info("{$this->getMessage()} from database driver.");
92 |
93 | }
94 |
95 | /**
96 | * @param string $cacheKey
97 | * @param string $namespace
98 | * @param string|int $ttl
99 | * @return mixed
100 | */
101 | public function getCache(string $cacheKey, string $namespace = '', string|int $ttl = 3600)
102 | {
103 | $cacheData = $this->retrieveCache($cacheKey, $namespace);
104 | if ($cacheData) {
105 | $this->setMessage("Cache retrieved successfully", true);
106 | $this->logger->debug("{$this->getMessage()} from database driver.");
107 | return $cacheData;
108 | }
109 | $this->setMessage("CacheData not found, does not exists or expired", false);
110 | $this->logger->info("{$this->getMessage()} from database driver.");
111 | return null;
112 | }
113 |
114 | /**
115 | * @return string
116 | */
117 | public function getMessage()
118 | {
119 | return $this->message;
120 | }
121 |
122 | /**
123 | * @param string $cacheKey
124 | * @param string $namespace
125 | * @return void
126 | */
127 | public function has(string $cacheKey, string $namespace = '')
128 | {
129 | $cacheData = $this->getCache($cacheKey, $namespace);
130 | if ($cacheData) {
131 | $this->logger->debug("Cache key: {$cacheKey} exists and it's available from database driver.");
132 | }
133 | $this->logger->warning("{$this->getMessage()} from database driver.");
134 | }
135 |
136 | /**
137 | * @return boolean
138 | */
139 | public function isSuccess()
140 | {
141 | return $this->success;
142 | }
143 |
144 | /**
145 | * @param array $items
146 | * @param string $namespace
147 | * @param integer $batchSize
148 | * @return void
149 | */
150 | public function putMany(array $items, string $namespace = '', int $batchSize = 100)
151 | {
152 | $processedCount = 0;
153 | $itemCount = count($items);
154 | while ($processedCount < $itemCount) {
155 | $batchItems = array_slice($items, $processedCount, $batchSize);
156 | $this->processBatchItems($batchItems, $namespace);
157 | $processedCount += count($batchItems);
158 | }
159 | }
160 |
161 | /**
162 | * @param string $cacheKey
163 | * @param mixed $cacheData
164 | * @param string $namespace
165 | * @param string|int $ttl
166 | * @return bool
167 | */
168 | public function putCache(string $cacheKey, mixed $cacheData, string $namespace = '', string|int $ttl = 3600)
169 | {
170 | if($this->storeCache($cacheKey, $cacheData, $namespace, $ttl)){
171 | $this->logger->debug("{$this->getMessage()} from database driver.");
172 | return true;
173 | }
174 | $this->logger->error("{$this->getMessage()} from database driver.");
175 | return false;
176 | }
177 |
178 | /**
179 | * @param string $cacheKey
180 | * @param string|int $ttl
181 | * @param string $namespace
182 | * @return void
183 | */
184 | public function renewCache(string $cacheKey, int | string $ttl, string $namespace = '')
185 | {
186 | $cacheData = $this->getCache($cacheKey, $namespace);
187 | if ($cacheData) {
188 | $this->renew($cacheKey, $ttl, $namespace);
189 | $this->setMessage("Cache with key {$cacheKey} renewed successfully", true);
190 | $this->logger->debug("{$this->getMessage()} from database driver.");
191 | }
192 | }
193 |
194 | /**
195 | * @param array $batchItems
196 | * @param string $namespace
197 | * @return void
198 | */
199 | private function processBatchItems(array $batchItems, string $namespace)
200 | {
201 | foreach($batchItems as $item) {
202 | CacheDatabaseHelper::validateCacheItem($item);
203 | $cacheKey = $item['cacheKey'];
204 | $cacheData = $item['cacheData'];
205 | $mergedData = CacheDatabaseHelper::mergeCacheData($cacheData);
206 | $this->putCache($cacheKey, $mergedData, $namespace);
207 | }
208 | }
209 |
210 | /**
211 | * @param string $cacheKey
212 | * @param string|int $ttl
213 | * @param string $namespace
214 | * @return bool
215 | */
216 | private function renew(string $cacheKey, string|int $ttl = 3600, string $namespace = '')
217 | {
218 | $cacheData = $this->getCache($cacheKey, $namespace);
219 | if ($cacheData) {
220 | $renewedCache = $this->cacheRepository->renew($cacheKey, $ttl, $namespace);
221 | if ($renewedCache) {
222 | $this->setMessage("Cache with key {$cacheKey} renewed successfully", true);
223 | $this->logger->debug("{$this->getMessage()} from database driver.");
224 | return true;
225 | }
226 | return false;
227 | }
228 | return false;
229 | }
230 |
231 | /**
232 | * @param string $message
233 | * @param boolean $success
234 | * @return void
235 | */
236 | private function setMessage(string $message, bool $success)
237 | {
238 | $this->message = $message;
239 | $this->success = $success;
240 | }
241 |
242 | /**
243 | * @param string $cacheKey
244 | * @param string $namespace
245 | * @return mixed
246 | */
247 | private function retrieveCache(string $cacheKey, string $namespace = '')
248 | {
249 | return $this->cacheRepository->retrieve($cacheKey, $namespace);
250 | }
251 |
252 | /**
253 | * @param string $cacheKey
254 | * @param mixed $cacheData
255 | * @param string $namespace
256 | * @param integer $ttl
257 | * @return bool
258 | */
259 | private function storeCache(string $cacheKey, mixed $cacheData, string $namespace = '', string|int $ttl = 3600)
260 | {
261 | $data = $this->cacheRepository->store($cacheKey, $cacheData, $namespace, $ttl);
262 | if($data) {
263 | $this->setMessage("Cache Stored Successfully", true);
264 | return true;
265 | }
266 | $this->setMessage("Already exists a cache with this key...", false);
267 | return false;
268 | }
269 |
270 | /**
271 | * @param string $cacheKey
272 | * @param mixed $cacheData
273 | * @param string $namespace
274 | * @return bool
275 | */
276 | private function updateCache(string $cacheKey, mixed $cacheData, string $namespace = '')
277 | {
278 | $data = $this->cacheRepository->update($cacheKey, $cacheData, $namespace);
279 | if($data) {
280 | $this->setMessage("Cache updated successfully.", true);
281 | return true;
282 | }
283 | $this->setMessage("Cache does not exist or update failed!", false);
284 | return false;
285 | }
286 | }
287 |
--------------------------------------------------------------------------------
/src/CacheStore/FileCacheStore.php:
--------------------------------------------------------------------------------
1 |
14 | * @package Silviooosilva\CacheerPhp
15 | */
16 | class FileCacheStore implements CacheerInterface
17 | {
18 | /**
19 | * @param string $cacheDir
20 | */
21 | private string $cacheDir;
22 |
23 | /**
24 | * @param array $options
25 | */
26 | private array $options = [];
27 |
28 | /**
29 | * @param string $message
30 | */
31 | private string $message = '';
32 |
33 | /**
34 | * @param integer $defaultTTL
35 | */
36 | private int $defaultTTL = 3600; // 1 hora por padrão
37 |
38 | /**
39 | * @param boolean $success
40 | */
41 | private bool $success = false;
42 |
43 | /**
44 | * @param string $lastFlushTimeFile
45 | */
46 | private string $lastFlushTimeFile;
47 |
48 | /**
49 | * @var CacheLogger
50 | */
51 | private $logger = null;
52 |
53 | /**
54 | * @var FileCacheManager
55 | */
56 | private FileCacheManager $fileManager;
57 |
58 | public function __construct(array $options = [])
59 | {
60 | $this->validateOptions($options);
61 | $this->fileManager = new FileCacheManager();
62 | $this->initializeCacheDir($options['cacheDir']);
63 | $this->defaultTTL = $this->getExpirationTime($options);
64 | $this->lastFlushTimeFile = "{$this->cacheDir}/last_flush_time";
65 | $this->handleAutoFlush($options);
66 | $this->logger = new CacheLogger($options['loggerPath']);
67 | }
68 |
69 | /**
70 | * @param string $cacheKey
71 | * @param mixed $cacheData
72 | * @param string $namespace
73 | * @return void
74 | */
75 | public function appendCache(string $cacheKey, mixed $cacheData, string $namespace = '')
76 | {
77 | $currentCacheFileData = $this->getCache($cacheKey, $namespace);
78 |
79 | if (!$this->isSuccess()) {
80 | return $this->getMessage();
81 | }
82 |
83 | $mergedCacheData = CacheFileHelper::arrayIdentifier($currentCacheFileData, $cacheData);
84 |
85 |
86 | $this->putCache($cacheKey, $mergedCacheData, $namespace);
87 | if ($this->isSuccess()) {
88 | $this->setMessage("Cache updated successfully", true);
89 | $this->logger->debug("{$this->getMessage()} from file driver.");
90 | }
91 | }
92 |
93 | /**
94 | * @param string $cacheKey
95 | * @param string $namespace
96 | * @return string
97 | */
98 | private function buildCacheFilePath(string $cacheKey, string $namespace)
99 | {
100 | $namespace = $namespace ? md5($namespace) . '/' : '';
101 | $cacheDir = "{$this->cacheDir}/";
102 |
103 | if (!empty($namespace)) {
104 | $cacheDir = "{$this->cacheDir}/{$namespace}";
105 | $this->fileManager->createDirectory($cacheDir);
106 | }
107 | return $cacheDir . md5($cacheKey) . ".cache";
108 | }
109 |
110 | /**
111 | * @param string $cacheKey
112 | * @param string $namespace
113 | * @return void
114 | */
115 | public function clearCache(string $cacheKey, string $namespace = '')
116 | {
117 | $cacheFile = $this->buildCacheFilePath($cacheKey, $namespace);
118 | if ($this->fileManager->readFile($cacheFile)) {
119 | $this->fileManager->removeFile($cacheFile);
120 | $this->setMessage("Cache file deleted successfully!", true);
121 | } else {
122 | $this->setMessage("Cache file does not exist!", false);
123 | }
124 | $this->logger->debug("{$this->getMessage()} from file driver.");
125 | }
126 |
127 | /**
128 | * @return void
129 | */
130 | public function flushCache()
131 | {
132 | $this->fileManager->clearDirectory($this->cacheDir);
133 | file_put_contents($this->lastFlushTimeFile, time());
134 | }
135 |
136 | /**
137 | * @param array $options
138 | * @return integer
139 | */
140 | private function getExpirationTime(array $options)
141 | {
142 | return isset($options['expirationTime'])
143 | ? CacheFileHelper::convertExpirationToSeconds($options['expirationTime'])
144 | : $this->defaultTTL;
145 | }
146 |
147 | /**
148 | * @return string
149 | */
150 | public function getMessage()
151 | {
152 | return $this->message;
153 | }
154 |
155 | /**
156 | * @param string $cacheKey
157 | * @param string $namespace
158 | * @param string|int $ttl
159 | * @return string
160 | */
161 | public function getCache(string $cacheKey, string $namespace = '', string|int $ttl = 3600)
162 | {
163 |
164 | $ttl = CacheFileHelper::ttl($ttl, $this->defaultTTL);
165 | $cacheFile = $this->buildCacheFilePath($cacheKey, $namespace);
166 | if ($this->isCacheValid($cacheFile, $ttl)) {
167 | $cacheData = $this->fileManager->serialize($this->fileManager->readFile($cacheFile), false);
168 |
169 | $this->setMessage("Cache retrieved successfully", true);
170 | $this->logger->debug("{$this->getMessage()} from file driver.");
171 | return $cacheData;
172 | }
173 |
174 | $this->setMessage("cacheFile not found, does not exists or expired", false);
175 | $this->logger->info("{$this->getMessage()} from file driver.");
176 | }
177 |
178 | /**
179 | * @param array $items
180 | * @param string $namespace
181 | * @param integer $batchSize
182 | * @return void
183 | */
184 | public function putMany(array $items, string $namespace = '', int $batchSize = 100)
185 | {
186 | $processedCount = 0;
187 | $itemCount = count($items);
188 |
189 | while ($processedCount < $itemCount) {
190 | $batchItems = array_slice($items, $processedCount, $batchSize);
191 | $this->processBatchItems($batchItems, $namespace);
192 | $processedCount += count($batchItems);
193 | }
194 | }
195 |
196 | /**
197 | * @param string $cacheKey
198 | * @param mixed $cacheData
199 | * @param string $namespace
200 | * @param string|int $ttl
201 | * @return void
202 | */
203 | public function putCache(string $cacheKey, mixed $cacheData, string $namespace = '', string|int $ttl = 3600)
204 | {
205 | $cacheFile = $this->buildCacheFilePath($cacheKey, $namespace);
206 | $data = $this->fileManager->serialize($cacheData);
207 |
208 | $this->fileManager->writeFile($cacheFile, $data);
209 | $this->setMessage("Cache file created successfully", true);
210 |
211 | $this->logger->debug("{$this->getMessage()} from file driver.");
212 | }
213 |
214 | /**
215 | * @param string $cacheKey
216 | * @param string $namespace
217 | * @return void
218 | */
219 | public function has(string $cacheKey, string $namespace = '')
220 | {
221 | $this->getCache($cacheKey, $namespace);
222 |
223 | if ($this->isSuccess()) {
224 | $this->setMessage("Cache key: {$cacheKey} exists and it's available! from file driver", true);
225 | } else {
226 | $this->setMessage("Cache key: {$cacheKey} does not exists or it's expired! from file driver", false);
227 | }
228 | }
229 |
230 | /**
231 | * @param string $cacheKey
232 | * @param string|int $ttl
233 | * @param string $namespace
234 | * @return void
235 | */
236 | public function renewCache(string $cacheKey, string|int $ttl, string $namespace = '')
237 | {
238 | $cacheData = $this->getCache($cacheKey, $namespace);
239 | if ($cacheData) {
240 | $this->putCache($cacheKey, $cacheData, $namespace, $ttl);
241 | $this->setMessage("Cache with key {$cacheKey} renewed successfully", true);
242 | $this->logger->debug("{$this->getMessage()} from file driver.");
243 | return;
244 | }
245 | $this->setMessage("Failed to renew Cache with key {$cacheKey}", false);
246 | $this->logger->debug("{$this->getMessage()} from file driver.");
247 | }
248 |
249 | /**
250 | * @param array $batchItems
251 | * @param string $namespace
252 | * @return void
253 | */
254 | private function processBatchItems(array $batchItems, string $namespace)
255 | {
256 | foreach ($batchItems as $item) {
257 | CacheFileHelper::validateCacheItem($item);
258 | $cacheKey = $item['cacheKey'];
259 | $cacheData = $item['cacheData'];
260 | $mergedData = CacheFileHelper::mergeCacheData($cacheData);
261 | $this->putCache($cacheKey, $mergedData, $namespace);
262 | }
263 | }
264 |
265 | /**
266 | * @return boolean
267 | */
268 | public function isSuccess()
269 | {
270 | return $this->success;
271 | }
272 |
273 | /**
274 | * @param string $message
275 | * @param boolean $success
276 | * @return void
277 | */
278 | private function setMessage(string $message, bool $success)
279 | {
280 | $this->message = $message;
281 | $this->success = $success;
282 | }
283 |
284 | /**
285 | * @param array $options
286 | * @return void
287 | */
288 | private function validateOptions(array $options)
289 | {
290 | if (!isset($options['cacheDir']) && $options['drive'] === 'file') {
291 | $this->logger->debug("The 'cacheDir' option is required from file driver.");
292 | throw CacheFileException::create("The 'cacheDir' option is required.");
293 | }
294 | $this->options = $options;
295 | }
296 |
297 | /**
298 | * @param string $cacheDir
299 | * @return void
300 | */
301 | private function initializeCacheDir(string $cacheDir)
302 | {
303 | $this->cacheDir = realpath($cacheDir) ?: "";
304 | $this->fileManager->createDirectory($cacheDir);
305 | }
306 |
307 | /**
308 | * @param array $options
309 | * @return void
310 | */
311 | private function handleAutoFlush(array $options)
312 | {
313 | if (isset($options['flushAfter'])) {
314 | $this->scheduleFlush($options['flushAfter']);
315 | }
316 | }
317 |
318 | /**
319 | * @param string $flushAfter
320 | * @return void
321 | */
322 | private function scheduleFlush(string $flushAfter)
323 | {
324 | $flushAfterSeconds = CacheFileHelper::convertExpirationToSeconds($flushAfter);
325 |
326 | if(!$this->fileManager->fileExists($this->lastFlushTimeFile)) {
327 | $this->fileManager->writeFile($this->lastFlushTimeFile, time());
328 | return;
329 | }
330 |
331 | $lastFlushTime = (int) $this->fileManager->readFile($this->lastFlushTimeFile);
332 |
333 | if ((time() - $lastFlushTime) >= $flushAfterSeconds) {
334 | $this->flushCache();
335 | $this->fileManager->writeFile($this->lastFlushTimeFile, time());
336 | }
337 | }
338 |
339 | /**
340 | * @param string $cacheFile
341 | * @param integer $ttl
342 | * @return boolean
343 | */
344 | private function isCacheValid(string $cacheFile, int $ttl)
345 | {
346 | return file_exists($cacheFile) && (filemtime($cacheFile) > (time() - $ttl));
347 | }
348 | }
--------------------------------------------------------------------------------
/src/CacheStore/RedisCacheStore.php:
--------------------------------------------------------------------------------
1 |
15 | * @package Silviooosilva\CacheerPhp
16 | */
17 | class RedisCacheStore implements CacheerInterface
18 | {
19 | /** @var */
20 | private $redis;
21 |
22 | /** @param string $namespace */
23 | private string $namespace = '';
24 |
25 | /**
26 | * @var CacheLogger
27 | */
28 | private $logger = null;
29 |
30 | /**
31 | * @var string
32 | */
33 | private string $message = '';
34 |
35 | /**
36 | * @var boolean
37 | */
38 | private bool $success = false;
39 |
40 | /**
41 | * @return void
42 | */
43 | public function __construct(string $logPath)
44 | {
45 | $this->redis = RedisCacheManager::connect();
46 | $this->logger = new CacheLogger($logPath);
47 | }
48 |
49 | /**
50 | * @param string $cacheKey
51 | * @param mixed $cacheData
52 | * @param string $namespace
53 | * @return void
54 | */
55 | public function appendCache(string $cacheKey, mixed $cacheData, string $namespace = '')
56 | {
57 | $cacheFullKey = $this->buildKey($cacheKey, $namespace);
58 | $existingData = $this->getCache($cacheFullKey);
59 |
60 | $mergedCacheData = CacheRedisHelper::arrayIdentifier($existingData, $cacheData);
61 |
62 | $serializedData = CacheRedisHelper::serialize($mergedCacheData);
63 |
64 | if ($this->redis->set($cacheFullKey, $serializedData)) {
65 | $this->setMessage("Cache appended successfully", true);
66 | } else {
67 | $this->setMessage("Something went wrong. Please, try again.", false);
68 | }
69 |
70 | $this->logger->debug("{$this->getMessage()} from redis driver.");
71 | }
72 |
73 | /**
74 | * @param string $key
75 | * @param string $namespace
76 | * @return string
77 | */
78 | private function buildKey(string $key, string $namespace)
79 | {
80 | return $this->namespace . ($namespace ? $namespace . ':' : '') . $key;
81 | }
82 |
83 | /**
84 | * @param string $cacheKey
85 | * @param string $namespace
86 | * @return void
87 | */
88 | public function clearCache(string $cacheKey, string $namespace = '')
89 | {
90 | $cacheFullKey = $this->buildKey($cacheKey, $namespace);
91 |
92 | if ($this->redis->del($cacheFullKey) > 0) {
93 | $this->setMessage("Cache cleared successfully", true);
94 | } else {
95 | $this->setMessage("Something went wrong. Please, try again.", false);
96 | }
97 |
98 | $this->logger->debug("{$this->getMessage()} from redis driver.");
99 | }
100 |
101 | /**
102 | * @return void
103 | */
104 | public function flushCache()
105 | {
106 | if ($this->redis->flushall()) {
107 | $this->setMessage("Cache flushed successfully", true);
108 | } else {
109 | $this->setMessage("Something went wrong. Please, try again.", false);
110 | }
111 |
112 | $this->logger->debug("{$this->getMessage()} from redis driver.");
113 | }
114 |
115 | /**
116 | * @param string $cacheKey
117 | * @param string $namespace
118 | * @param string|int $ttl
119 | * @return mixed
120 | */
121 | public function getCache(string $cacheKey, string $namespace = '', string|int $ttl = 3600)
122 | {
123 | $fullCacheKey = $this->buildKey($cacheKey, $namespace);
124 | $cacheData = $this->redis->get($fullCacheKey);
125 |
126 | if ($cacheData) {
127 | $this->setMessage("Cache retrieved successfully", true);
128 | $this->logger->debug("{$this->getMessage()} from redis driver.");
129 | return CacheRedisHelper::serialize($cacheData, false);
130 | }
131 |
132 | $this->setMessage("CacheData not found, does not exists or expired", false);
133 | $this->logger->info("{$this->getMessage()} from redis driver.");
134 | }
135 |
136 | /**
137 | * @return string
138 | */
139 | public function getMessage()
140 | {
141 | return $this->message;
142 | }
143 |
144 | /**
145 | * @param string $fullKey
146 | * @return string|null
147 | */
148 | private function getDump(string $fullKey)
149 | {
150 | return $this->redis->dump($fullKey);
151 | }
152 |
153 | /**
154 | * @param string $cacheKey
155 | * @param string $namespace
156 | * @return void
157 | */
158 | public function has(string $cacheKey, string $namespace = '')
159 | {
160 | $cacheFullKey = $this->buildKey($cacheKey, $namespace);
161 |
162 | if ($this->redis->exists($cacheFullKey) > 0) {
163 | $this->setMessage("Cache Key: {$cacheKey} exists!", true);
164 | } else {
165 | $this->setMessage("Cache Key: {$cacheKey} does not exists!", false);
166 | }
167 |
168 | $this->logger->debug("{$this->getMessage()} from redis driver.");
169 | }
170 |
171 | /**
172 | * @return boolean
173 | */
174 | public function isSuccess()
175 | {
176 | return $this->success;
177 | }
178 |
179 | /**
180 | * @param array $batchItems
181 | * @param string $namespace
182 | * @return void
183 | */
184 | private function processBatchItems(array $batchItems, string $namespace)
185 | {
186 | foreach ($batchItems as $item) {
187 | CacheRedisHelper::validateCacheItem($item);
188 | $cacheKey = $item['cacheKey'];
189 | $cacheData = $item['cacheData'];
190 | $mergedData = CacheRedisHelper::mergeCacheData($cacheData);
191 | $this->putCache($cacheKey, $mergedData, $namespace);
192 | }
193 | }
194 |
195 | /**
196 | * Armazena um item no cache Redis, com suporte a namespace e TTL opcional.
197 | *
198 | * @param string $cacheKey
199 | * @param mixed $cacheData
200 | * @param string $namespace
201 | * @param string|int|null $ttl
202 | * @return mixed
203 | */
204 | public function putCache(string $cacheKey, mixed $cacheData, string $namespace = '', string|int|null $ttl = null)
205 | {
206 | $cacheFullKey = $this->buildKey($cacheKey, $namespace);
207 | $serializedData = CacheRedisHelper::serialize($cacheData);
208 |
209 | $result = $ttl ? $this->redis->setex($cacheFullKey, (int) $ttl, $serializedData)
210 | : $this->redis->set($cacheFullKey, $serializedData);
211 |
212 | if ($result) {
213 | $this->setMessage("Cache stored successfully", true);
214 | } else {
215 | $this->setMessage("Failed to store cache", false);
216 | }
217 |
218 | $this->logger->debug("{$this->getMessage()} from Redis driver.");
219 | return $result;
220 | }
221 |
222 | /**
223 | * @param array $items
224 | * @param string $namespace
225 | * @param int $batchSize
226 | * @return void
227 | */
228 | public function putMany(array $items, string $namespace = '', int $batchSize = 100)
229 | {
230 | $processedCount = 0;
231 | $itemCount = count($items);
232 |
233 | while ($processedCount < $itemCount) {
234 | $batchItems = array_slice($items, $processedCount, $batchSize);
235 | $this->processBatchItems($batchItems, $namespace);
236 | $processedCount += count($batchItems);
237 | }
238 | }
239 |
240 | /**
241 | * @param string $cacheKey
242 | * @param string|int $ttl
243 | * @param string $namespace
244 | * @return void
245 | */
246 | public function renewCache(string $cacheKey, string|int $ttl, string $namespace = '')
247 | {
248 | $cacheFullKey = $this->buildKey($cacheKey, $namespace);
249 | $dump = $this->getDump($cacheFullKey);
250 |
251 | if (!$dump) {
252 | $this->setMessage("Cache Key: {$cacheKey} not found.", false);
253 | $this->logger->warning("{$this->getMessage()} from Redis driver.");
254 | return;
255 | }
256 |
257 | $this->clearCache($cacheFullKey);
258 |
259 | if ($this->restoreKey($cacheFullKey, $ttl, $dump)) {
260 | $this->setMessage("Cache Key: {$cacheKey} renewed successfully.", true);
261 | $this->logger->debug("{$this->getMessage()} from Redis driver.");
262 | } else {
263 | $this->setMessage("Failed to renew cache key: {$cacheKey}.", false);
264 | $this->logger->error("{$this->getMessage()} from Redis driver.");
265 | }
266 | }
267 |
268 | /**
269 | * @param string $fullKey
270 | * @param string|int $ttl
271 | * @param mixed $dump
272 | * @return bool
273 | */
274 | private function restoreKey(string $fullKey, string|int $ttl, mixed $dump)
275 | {
276 | try {
277 | $this->redis->restore($fullKey, $ttl * 1000, $dump, 'REPLACE');
278 | return true;
279 | } catch (Exception $e) {
280 | throw CacheRedisException::create($e->getMessage());
281 | }
282 | }
283 |
284 | /**
285 | * @param string $message
286 | * @param boolean $success
287 | * @return void
288 | */
289 | private function setMessage(string $message, bool $success)
290 | {
291 | $this->message = $message;
292 | $this->success = $success;
293 | }
294 | }
--------------------------------------------------------------------------------
/src/Cacheer.php:
--------------------------------------------------------------------------------
1 |
20 | * @package Silviooosilva\CacheerPhp
21 | */
22 | final class Cacheer implements CacheerInterface
23 | {
24 | /**
25 | * @var string
26 | */
27 | private string $message;
28 |
29 | /**
30 | * @var boolean
31 | */
32 | private bool $success;
33 |
34 | /**
35 | * @var boolean
36 | */
37 | private bool $formatted = false;
38 |
39 | /**
40 | * @var bool
41 | */
42 | private bool $compression = false;
43 |
44 | /**
45 | * @var string|null
46 | */
47 | private ?string $encryptionKey = null;
48 |
49 | /**
50 | * @var FileCacheStore|DatabaseCacheStore|RedisCacheStore|ArrayCacheStore
51 | */
52 | public $cacheStore;
53 |
54 | /**
55 | * @var array
56 | */
57 | public array $options = [];
58 |
59 | public function __construct(array $options = [], $formatted = false)
60 | {
61 | $this->formatted = $formatted;
62 | $this->validateOptions($options);
63 | $this->setDriver()->useDefaultDriver();
64 | }
65 |
66 | /**
67 | * @param string $cacheKey
68 | * @param mixed $cacheData
69 | * @param string $namespace
70 | * @param int|string $ttl
71 | * @return bool
72 | */
73 | public function add(string $cacheKey, mixed $cacheData, string $namespace = '', int|string $ttl = 3600)
74 | {
75 | if (!empty($this->getCache($cacheKey, $namespace))) {
76 | return true;
77 | }
78 |
79 | $this->putCache($cacheKey, $cacheData, $namespace, $ttl);
80 | $this->setMessage($this->getMessage(), $this->isSuccess());
81 |
82 | return false;
83 | }
84 |
85 | /**
86 | * @param string $cacheKey
87 | * @param mixed $cacheData
88 | * @param string $namespace
89 | * @return void
90 | */
91 | public function appendCache(string $cacheKey, mixed $cacheData, string $namespace = '')
92 | {
93 | $this->cacheStore->appendCache($cacheKey, $cacheData, $namespace);
94 | $this->setMessage($this->cacheStore->getMessage(), $this->cacheStore->isSuccess());
95 | }
96 |
97 | /**
98 | * @param string $cacheKey
99 | * @param string $namespace
100 | * @return void
101 | */
102 | public function clearCache(string $cacheKey, string $namespace = '')
103 | {
104 | $this->cacheStore->clearCache($cacheKey, $namespace);
105 | $this->setMessage($this->cacheStore->getMessage(), $this->cacheStore->isSuccess());
106 | }
107 |
108 | /**
109 | * @param string $cacheKey
110 | * @param int $amount
111 | * @param string $namespace
112 | * @return bool
113 | */
114 | public function decrement(string $cacheKey, int $amount = 1, string $namespace = '')
115 | {
116 | return $this->increment($cacheKey, ($amount * -1), $namespace);
117 | }
118 |
119 | /**
120 | * @param string $cacheKey
121 | * @param mixed $cacheData
122 | * @return void
123 | */
124 | public function forever(string $cacheKey, mixed $cacheData)
125 | {
126 | $this->putCache($cacheKey, $cacheData, ttl: 31536000 * 1000);
127 | $this->setMessage($this->getMessage(), $this->isSuccess());
128 | }
129 |
130 | /**
131 | * @return void
132 | */
133 | public function flushCache()
134 | {
135 | $this->cacheStore->flushCache();
136 | $this->setMessage($this->cacheStore->getMessage(), $this->cacheStore->isSuccess());
137 | }
138 |
139 | /**
140 | * @param string $cacheKey
141 | * @param string $namespace
142 | * @return mixed
143 | */
144 | public function getAndForget(string $cacheKey, string $namespace = '')
145 | {
146 | $cachedData = $this->getCache($cacheKey, $namespace);
147 |
148 | if (!empty($cachedData)) {
149 | $this->setMessage("Cache retrieved and deleted successfully!", true);
150 | $this->clearCache($cacheKey, $namespace);
151 | return $cachedData;
152 | }
153 |
154 | return null;
155 | }
156 |
157 | /**
158 | * @param string $cacheKey
159 | * @param string $namespace
160 | * @param string|int $ttl
161 | * @return CacheDataFormatter|mixed
162 | */
163 | public function getCache(string $cacheKey, string $namespace = '', string|int $ttl = 3600)
164 | {
165 | $cacheData = $this->cacheStore->getCache($cacheKey, $namespace, $ttl);
166 | $this->setMessage($this->cacheStore->getMessage(), $this->cacheStore->isSuccess());
167 |
168 | if ($this->cacheStore->isSuccess() && ($this->compression || $this->encryptionKey !== null)) {
169 | $cacheData = CacheerHelper::recoverFromStorage($cacheData, $this->compression, $this->encryptionKey);
170 | }
171 |
172 | return $this->formatted ? new CacheDataFormatter($cacheData) : $cacheData;
173 | }
174 |
175 | /**
176 | * @param string $cacheKey
177 | * @param string $namespace
178 | * @return void
179 | */
180 | public function has(string $cacheKey, string $namespace = '')
181 | {
182 | $this->cacheStore->has($cacheKey, $namespace);
183 | $this->setMessage($this->cacheStore->getMessage(), $this->cacheStore->isSuccess());
184 | }
185 |
186 | /**
187 | * @param string $cacheKey
188 | * @param int $amount
189 | * @param string $namespace
190 | * @return bool
191 | */
192 | public function increment(string $cacheKey, int $amount = 1, string $namespace = '')
193 | {
194 | $cacheData = $this->getCache($cacheKey, $namespace);
195 |
196 | if(!empty($cacheData) && is_numeric($cacheData)) {
197 | $this->putCache($cacheKey, (int)($cacheData + $amount), $namespace);
198 | $this->setMessage($this->getMessage(), $this->isSuccess());
199 | return true;
200 | }
201 |
202 | return false;
203 | }
204 |
205 | /**
206 | * @return boolean
207 | */
208 | public function isSuccess()
209 | {
210 | return $this->success;
211 | }
212 |
213 | /**
214 | * @param string $cacheKey
215 | * @param mixed $cacheData
216 | * @param string $namespace
217 | * @param string|int $ttl
218 | * @return void
219 | */
220 | public function putCache(string $cacheKey, mixed $cacheData, string $namespace = '', string|int $ttl = 3600)
221 | {
222 | $data = CacheerHelper::prepareForStorage($cacheData, $this->compression, $this->encryptionKey);
223 | $this->cacheStore->putCache($cacheKey, $data, $namespace, $ttl);
224 | $this->setMessage($this->cacheStore->getMessage(), $this->cacheStore->isSuccess());
225 | }
226 |
227 | /**
228 | * @param array $items
229 | * @param string $namespace
230 | * @param integer $batchSize
231 | * @return void
232 | */
233 | public function putMany(array $items, string $namespace = '', int $batchSize = 100)
234 | {
235 | $this->cacheStore->putMany($items, $namespace, $batchSize);
236 | }
237 |
238 | /**
239 | * @param string $cacheKey
240 | * @param string|int $ttl
241 | * @param string $namespace
242 | * @return void
243 | */
244 | public function renewCache(string $cacheKey, string|int $ttl = 3600, string $namespace = '')
245 | {
246 | $this->cacheStore->renewCache($cacheKey, $ttl, $namespace);
247 |
248 | if ($this->cacheStore->isSuccess()) {
249 | $this->setMessage($this->cacheStore->getMessage(), $this->cacheStore->isSuccess());
250 | } else {
251 | $this->setMessage($this->cacheStore->getMessage(), $this->cacheStore->isSuccess());
252 | }
253 | }
254 |
255 | /**
256 | * @param string $cacheKey
257 | * @param int|string $ttl
258 | * @param Closure $callback
259 | * @return mixed
260 | */
261 | public function remember(string $cacheKey, int|string $ttl, Closure $callback)
262 | {
263 | $cachedData = $this->getCache($cacheKey, ttl: $ttl);
264 |
265 | if(!empty($cachedData)) {
266 | return $cachedData;
267 | }
268 |
269 | $cacheData = $callback();
270 | $this->putCache($cacheKey, $cacheData, ttl: $ttl);
271 | $this->setMessage($this->getMessage(), $this->isSuccess());
272 |
273 | return $cacheData;
274 | }
275 |
276 | /**
277 | * @param string $cacheKey
278 | * @param Closure $callback
279 | * @return mixed
280 | */
281 | public function rememberForever(string $cacheKey, Closure $callback)
282 | {
283 | return $this->remember($cacheKey, 31536000 * 1000, $callback);
284 | }
285 |
286 | /**
287 | * @return CacheConfig
288 | */
289 | public function setConfig()
290 | {
291 | return new CacheConfig($this);
292 | }
293 |
294 | /**
295 | * @return CacheDriver
296 | */
297 | public function setDriver()
298 | {
299 | return new CacheDriver($this);
300 | }
301 |
302 | /**
303 | * @param string $message
304 | * @param boolean $success
305 | * @return void
306 | */
307 | private function setMessage(string $message, bool $success)
308 | {
309 | $this->message = $message;
310 | $this->success = $success;
311 | }
312 |
313 | /**
314 | * @return string
315 | */
316 | public function getMessage()
317 | {
318 | return $this->message;
319 | }
320 |
321 | /**
322 | * @return void
323 | */
324 | public function useFormatter()
325 | {
326 | $this->formatted = !$this->formatted;
327 | }
328 |
329 | /**
330 | * @param array $options
331 | * @return void
332 | */
333 | private function validateOptions(array $options)
334 | {
335 | $this->options = $options;
336 | }
337 |
338 | /**
339 | * Enable or disable data compression
340 | *
341 | * @param bool $status
342 | * @return $this
343 | */
344 | public function useCompression(bool $status = true)
345 | {
346 | $this->compression = $status;
347 | return $this;
348 | }
349 |
350 | /**
351 | * Enable encryption for cached data
352 | *
353 | * @param string $key
354 | * @return $this
355 | */
356 | public function useEncryption(string $key)
357 | {
358 | $this->encryptionKey = $key;
359 | return $this;
360 | }
361 | }
362 |
--------------------------------------------------------------------------------
/src/Config/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/silviooosilva/CacheerPHP/29b1f60e2032cabd5048ef0b40c389f2be3d4384/src/Config/.gitignore
--------------------------------------------------------------------------------
/src/Config/Option/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/silviooosilva/CacheerPHP/29b1f60e2032cabd5048ef0b40c389f2be3d4384/src/Config/Option/.gitignore
--------------------------------------------------------------------------------
/src/Config/Option/Builder/OptionBuilder.php:
--------------------------------------------------------------------------------
1 |
10 | * @package Silviooosilva\CacheerPhp
11 | */
12 | class OptionBuilder
13 | {
14 | /**
15 | * @return FileOptionBuilder
16 | */
17 | public static function forFile()
18 | {
19 | return new FileOptionBuilder();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Core/Connect.php:
--------------------------------------------------------------------------------
1 |
12 | * @package Silviooosilva\CacheerPhp
13 | */
14 | class Connect
15 | {
16 | public static string $connection = 'sqlite';
17 | private static ?PDOException $error = null;
18 |
19 |
20 | /**
21 | * @param array|null $database
22 | * @return PDO|null
23 | */
24 | public static function getInstance(?array $database = null)
25 | {
26 | $pdo = ConnectionFactory::createConnection($database);
27 | if ($pdo) {
28 | MigrationManager::migrate($pdo);
29 | }
30 | return $pdo;
31 | }
32 |
33 | /**
34 | * @param string $connection
35 | * @return void
36 | */
37 | public static function setConnection(string $connection)
38 | {
39 | $drivers = ['mysql', 'sqlite', 'pgsql'];
40 | if (!in_array($connection, $drivers)) {
41 | throw ConnectionException::create("Only ['MySQL(mysql)', 'SQLite(sqlite)', 'PgSQL(pgsql)'] are available at the moment...");
42 | }
43 | self::$connection = $connection;
44 | }
45 |
46 | /**
47 | * @return string
48 | */
49 | public static function getConnection()
50 | {
51 | return self::$connection;
52 | }
53 |
54 | /**
55 | * @return PDOException|null
56 | */
57 | public static function getError()
58 | {
59 | return self::$error;
60 | }
61 |
62 | private function __construct() {}
63 | private function __clone() {}
64 | }
65 |
--------------------------------------------------------------------------------
/src/Core/ConnectionFactory.php:
--------------------------------------------------------------------------------
1 |
12 | * @package Silviooosilva\CacheerPhp
13 | */
14 | class ConnectionFactory
15 | {
16 |
17 | /**
18 | * @param array|null $database
19 | * @return PDO|null
20 | */
21 | public static function createConnection(?array $database = null)
22 | {
23 | $dbConf = $database ?? CACHEER_DATABASE_CONFIG[Connect::getConnection()];
24 |
25 | if ($dbConf['driver'] === 'sqlite') {
26 | $dbName = $dbConf['dbname'];
27 | $dbDsn = $dbConf['driver'] . ':' . $dbName;
28 | } else {
29 | $dbName = "{$dbConf['driver']}-{$dbConf['dbname']}@{$dbConf['host']}";
30 | $dbDsn = "{$dbConf['driver']}:host={$dbConf['host']};dbname={$dbConf['dbname']};port={$dbConf['port']}";
31 | }
32 |
33 | try {
34 | $options = $dbConf['options'] ?? [];
35 | foreach ($options as $key => $value) {
36 | if (is_string($value) && defined($value)) {
37 | $options[$key] = constant($value);
38 | }
39 | }
40 | return new PDO($dbDsn, $dbConf['username'] ?? null, $dbConf['passwd'] ?? null, $options);
41 | } catch (PDOException $exception) {
42 | throw ConnectionException::create($exception->getMessage(), $exception->getCode(), $exception->getPrevious());
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Core/MigrationManager.php:
--------------------------------------------------------------------------------
1 |
11 | * @package Silviooosilva\CacheerPhp
12 | */
13 | class MigrationManager
14 | {
15 | /**
16 | * @param PDO $connection
17 | * @return void
18 | */
19 | public static function migrate(PDO $connection)
20 | {
21 | try {
22 | self::prepareDatabase($connection);
23 | $queries = self::getMigrationQueries($connection);
24 | foreach ($queries as $query) {
25 | if (trim($query)) {
26 | $connection->exec($query);
27 | }
28 | }
29 | } catch (PDOException $exception) {
30 | throw new PDOException($exception->getMessage(), $exception->getCode());
31 | }
32 | }
33 |
34 | /**
35 | * @param PDO $connection
36 | * @return void
37 | */
38 | private static function prepareDatabase(PDO $connection): void
39 | {
40 | $driver = $connection->getAttribute(PDO::ATTR_DRIVER_NAME);
41 | if ($driver !== 'sqlite') {
42 | $dbname = CACHEER_DATABASE_CONFIG[Connect::getConnection()]['dbname'];
43 | $connection->exec("USE $dbname");
44 | }
45 | }
46 |
47 | /**
48 | * @param PDO $connection
49 | * @return array
50 | */
51 | private static function getMigrationQueries(PDO $connection): array
52 | {
53 | $driver = $connection->getAttribute(PDO::ATTR_DRIVER_NAME);
54 | $createdAtDefault = ($driver === 'pgsql') ? 'DEFAULT NOW()' : 'DEFAULT CURRENT_TIMESTAMP';
55 |
56 | if ($driver === 'sqlite') {
57 | $query = "
58 | CREATE TABLE IF NOT EXISTS cacheer_table (
59 | id INTEGER PRIMARY KEY AUTOINCREMENT,
60 | cacheKey VARCHAR(255) NOT NULL,
61 | cacheData TEXT NOT NULL,
62 | cacheNamespace VARCHAR(255),
63 | expirationTime DATETIME NOT NULL,
64 | created_at DATETIME $createdAtDefault,
65 | UNIQUE(cacheKey, cacheNamespace)
66 | );
67 | CREATE INDEX IF NOT EXISTS idx_cacheer_cacheKey ON cacheer_table (cacheKey);
68 | CREATE INDEX IF NOT EXISTS idx_cacheer_cacheNamespace ON cacheer_table (cacheNamespace);
69 | CREATE INDEX IF NOT EXISTS idx_cacheer_expirationTime ON cacheer_table (expirationTime);
70 | CREATE INDEX IF NOT EXISTS idx_cacheer_key_namespace ON cacheer_table (cacheKey, cacheNamespace);
71 | ";
72 | } elseif ($driver === 'pgsql') {
73 | $query = "
74 | CREATE TABLE IF NOT EXISTS cacheer_table (
75 | id SERIAL PRIMARY KEY,
76 | cacheKey VARCHAR(255) NOT NULL,
77 | cacheData TEXT NOT NULL,
78 | cacheNamespace VARCHAR(255),
79 | expirationTime TIMESTAMP NOT NULL,
80 | created_at TIMESTAMP $createdAtDefault,
81 | UNIQUE(cacheKey, cacheNamespace)
82 | );
83 | CREATE INDEX IF NOT EXISTS idx_cacheer_cacheKey ON cacheer_table (cacheKey);
84 | CREATE INDEX IF NOT EXISTS idx_cacheer_cacheNamespace ON cacheer_table (cacheNamespace);
85 | CREATE INDEX IF NOT EXISTS idx_cacheer_expirationTime ON cacheer_table (expirationTime);
86 | CREATE INDEX IF NOT EXISTS idx_cacheer_key_namespace ON cacheer_table (cacheKey, cacheNamespace);
87 | ";
88 | } else {
89 | $query = "
90 | CREATE TABLE IF NOT EXISTS cacheer_table (
91 | id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
92 | cacheKey VARCHAR(255) NOT NULL,
93 | cacheData LONGTEXT NOT NULL,
94 | cacheNamespace VARCHAR(255) NULL,
95 | expirationTime DATETIME NOT NULL,
96 | created_at TIMESTAMP $createdAtDefault,
97 | UNIQUE KEY unique_cache_key_namespace (cacheKey, cacheNamespace),
98 | KEY idx_cacheer_cacheKey (cacheKey),
99 | KEY idx_cacheer_cacheNamespace (cacheNamespace),
100 | KEY idx_cacheer_expirationTime (expirationTime),
101 | KEY idx_cacheer_key_namespace (cacheKey, cacheNamespace)
102 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
103 | ";
104 | }
105 | return array_filter(array_map('trim', explode(';', $query)));
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/Exceptions/BaseException.php:
--------------------------------------------------------------------------------
1 | details = $details;
21 | }
22 |
23 | /**
24 | * @return array
25 | * */
26 | public function getDetails()
27 | {
28 | return $this->details;
29 | }
30 |
31 | /**
32 | * @param array $details
33 | * */
34 | public function setDetails(array $details)
35 | {
36 | $this->details = $details;
37 | }
38 |
39 | /**
40 | * @return array
41 | * */
42 | public function toArray()
43 | {
44 | return [
45 | 'type' => static::class,
46 | 'message' => $this->getMessage(),
47 | 'code' => $this->getCode(),
48 | 'details' => $this->getDetails(),
49 | 'file' => $this->getFile(),
50 | 'line' => $this->getLine(),
51 | 'trace' => $this->getTrace()
52 | ];
53 | }
54 |
55 | /**
56 | * @return array
57 | * */
58 | public function jsonSerialize(): array
59 | {
60 | return $this->toArray();
61 | }
62 |
63 | /**
64 | * @return string
65 | * */
66 | public function toJson(int $options = 0)
67 | {
68 | return json_encode($this->toArray(), $options | JSON_THROW_ON_ERROR);
69 | }
70 |
71 | /**
72 | * @return string
73 | * */
74 | public function __toString()
75 | {
76 | return sprintf(
77 | "[%s] %s in %s on line %d\nDetails: %s",
78 | $this->getCode(),
79 | $this->getMessage(),
80 | $this->getFile(),
81 | $this->getLine(),
82 | json_encode($this->getDetails(), JSON_PRETTY_PRINT)
83 | );
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/Exceptions/CacheDatabaseException.php:
--------------------------------------------------------------------------------
1 | ";
12 |
13 | /**
14 | * @param string $message
15 | * @param int $code
16 | * @param Exception|null $previous
17 | * @param array $details
18 | * @return self
19 | */
20 | public static function create(string $message = "", int $code = 0, ?Exception $previous = null, array $details = [])
21 | {
22 | return new self(self::getBefore() . ": " .$message, $code, $previous, $details);
23 | }
24 |
25 |
26 | /**
27 | * @return string
28 | */
29 | public static function getBefore(): string
30 | {
31 | return self::$before;
32 | }
33 |
34 | /**
35 | * @return void
36 | */
37 | public static function setBefore(string $text): void
38 | {
39 | self::$before = $text;
40 | }
41 |
42 | /*
43 | * @return array
44 | */
45 | public function toArray()
46 | {
47 | return parent::toArray();
48 | }
49 |
50 | /**
51 | * @return string
52 | */
53 | public function jsonSerialize(): array
54 | {
55 | return parent::jsonSerialize();
56 | }
57 |
58 | /**
59 | * @param int $options
60 | * @return string
61 | */
62 | public function toJson(int $options = 0)
63 | {
64 | return parent::toJson($options);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Exceptions/CacheFileException.php:
--------------------------------------------------------------------------------
1 | ";
10 |
11 | /**
12 | * @param string $message
13 | * @param int $code
14 | * @param Exception|null $previous
15 | * @param array $details
16 | * @return self
17 | */
18 | public static function create(string $message = "", int $code = 0, ?Exception $previous = null, array $details = [])
19 | {
20 | return new self(self::getBefore() . ": " . $message, $code, $previous, $details);
21 | }
22 |
23 | /**
24 | * @return string
25 | */
26 | public static function getBefore()
27 | {
28 | return self::$before;
29 | }
30 |
31 | /**
32 | * @param string $text
33 | */
34 | public static function setBefore(string $text)
35 | {
36 | self::$before = $text;
37 | }
38 |
39 | /*
40 | * @return array
41 | */
42 | public function toArray()
43 | {
44 | return parent::toArray();
45 | }
46 |
47 | /**
48 | * @return string
49 | */
50 | public function jsonSerialize(): array
51 | {
52 | return parent::jsonSerialize();
53 | }
54 |
55 | /**
56 | * @param int $options
57 | * @return string
58 | */
59 | public function toJson(int $options = 0)
60 | {
61 | return parent::toJson($options);
62 | }
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/src/Exceptions/CacheRedisException.php:
--------------------------------------------------------------------------------
1 | ";
10 |
11 | /**
12 | * @param string $message
13 | * @param int $code
14 | * @param Exception|null $previous
15 | * @param array $details
16 | * @return self
17 | */
18 | public static function create(string $message = "", int $code = 0, ?Exception $previous = null, array $details = [])
19 | {
20 | return new self(self::getBefore() . ": " . $message, $code, $previous, $details);
21 | }
22 |
23 | /**
24 | * @return string
25 | */
26 | public static function getBefore(): string
27 | {
28 | return self::$before;
29 | }
30 |
31 | /**
32 | * @param string $text
33 | */
34 | public static function setBefore(string $text): void
35 | {
36 | self::$before = $text;
37 | }
38 |
39 | /*
40 | * @return array
41 | */
42 | public function toArray()
43 | {
44 | return parent::toArray();
45 | }
46 |
47 | /**
48 | * @return string
49 | */
50 | public function jsonSerialize(): array
51 | {
52 | return parent::jsonSerialize();
53 | }
54 |
55 | /**
56 | * @param int $options
57 | * @return string
58 | */
59 | public function toJson(int $options = 0)
60 | {
61 | return parent::toJson($options);
62 | }
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/src/Exceptions/ConnectionException.php:
--------------------------------------------------------------------------------
1 | ";
10 |
11 | /**
12 | * @param string $message
13 | * @param int $code
14 | * @param Exception|null $previous
15 | * @param array $details
16 | * @return self
17 | */
18 | public static function create(string $message = "", int $code = 0, ?Exception $previous = null, array $details = [])
19 | {
20 | return new self(self::getBefore() . ": " . $message, $code, $previous, $details);
21 | }
22 |
23 | /**
24 | * @return string
25 | */
26 | public static function getBefore(): string
27 | {
28 | return self::$before;
29 | }
30 |
31 | /**
32 | * @param string $text
33 | */
34 | public static function setBefore(string $text): void
35 | {
36 | self::$before = $text;
37 | }
38 |
39 | /*
40 | * @return array
41 | */
42 | public function toArray()
43 | {
44 | return parent::toArray();
45 | }
46 |
47 | /**
48 | * @return string
49 | */
50 | public function jsonSerialize(): array
51 | {
52 | return parent::jsonSerialize();
53 | }
54 |
55 | /**
56 | * @param int $options
57 | * @return string
58 | */
59 | public function toJson(int $options = 0)
60 | {
61 | return parent::toJson($options);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Helpers/CacheConfig.php:
--------------------------------------------------------------------------------
1 |
16 | * @package Silviooosilva\CacheerPhp
17 | */
18 | class CacheConfig
19 | {
20 |
21 | /**
22 | * @var Cacheer
23 | */
24 | protected $cacheer;
25 |
26 | public function __construct(Cacheer $cacheer)
27 | {
28 | $this->cacheer = $cacheer;
29 | $this->setTimeZone(date_default_timezone_get());
30 | }
31 |
32 | /**
33 | * @param string $timezone
34 | * @return $this
35 | */
36 | public function setTimeZone($timezone)
37 | {
38 | /**
39 | * Certifique-se de que o timezone fornecido é válido *
40 | * https://www.php.net/manual/en/timezones.php
41 | * */
42 |
43 | if (in_array($timezone, timezone_identifiers_list())) {
44 | date_default_timezone_set($timezone);
45 | }
46 | return $this;
47 | }
48 |
49 | /**
50 | * @return CacheDriver
51 | */
52 | public function setDriver()
53 | {
54 | return new CacheDriver($this->cacheer);
55 | }
56 |
57 | /**
58 | * @param string $path
59 | * @return mixed
60 | */
61 | public function setLoggerPath(string $path)
62 | {
63 |
64 | $cacheDriver = $this->setDriver();
65 | $cacheDriver->logPath = $path;
66 |
67 | $cacheDriverInstance = $this->cacheer->cacheStore;
68 |
69 | return match (get_class($cacheDriverInstance)) {
70 | FileCacheStore::class => $cacheDriver->useFileDriver(),
71 | RedisCacheStore::class => $cacheDriver->useRedisDriver(),
72 | ArrayCacheStore::class => $cacheDriver->useArrayDriver(),
73 | DatabaseCacheStore::class => $cacheDriver->useDatabaseDriver(),
74 | default => $cacheDriver->useDatabaseDriver(),
75 | };
76 | }
77 |
78 | /**
79 | * @param string $driver
80 | * @return void
81 | */
82 | public function setDatabaseConnection(string $driver)
83 | {
84 | Connect::setConnection($driver);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/Helpers/CacheDatabaseHelper.php:
--------------------------------------------------------------------------------
1 |
11 | * @package Silviooosilva\CacheerPhp
12 | */
13 | class CacheDatabaseHelper
14 | {
15 | /**
16 | * @param array $item
17 | * @return void
18 | */
19 | public static function validateCacheItem(array $item)
20 | {
21 | CacheerHelper::validateCacheItem(
22 | $item,
23 | fn($msg) => CacheDatabaseException::create($msg)
24 | );
25 | }
26 |
27 | /**
28 | * @param array $options
29 | * @return array
30 | */
31 | public static function mergeCacheData($cacheData)
32 | {
33 | return CacheerHelper::mergeCacheData($cacheData);
34 | }
35 |
36 | /**
37 | * @param mixed $currentCacheData
38 | * @param mixed $cacheData
39 | * @return array
40 | */
41 | public static function arrayIdentifier(mixed $currentCacheData, mixed $cacheData)
42 | {
43 | return CacheerHelper::arrayIdentifier($currentCacheData, $cacheData);
44 | }
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/src/Helpers/CacheFileHelper.php:
--------------------------------------------------------------------------------
1 |
11 | * @package Silviooosilva\CacheerPhp
12 | */
13 | class CacheFileHelper
14 | {
15 |
16 | /**
17 | * @param string $expiration
18 | * @return int
19 | */
20 | public static function convertExpirationToSeconds(string $expiration)
21 | {
22 | $units = [
23 | 'second' => 1,
24 | 'minute' => 60,
25 | 'hour' => 3600,
26 | 'day' => 86400,
27 | 'week' => 604800,
28 | 'month' => 2592000,
29 | 'year' => 31536000,
30 | ];
31 | foreach ($units as $unit => $value) {
32 | if (strpos($expiration, $unit) !== false) {
33 | return (int)$expiration * $value;
34 | }
35 | }
36 | throw CacheFileException::create("Invalid expiration format");
37 | }
38 |
39 | /**
40 | * @param array $options
41 | * @return array
42 | */
43 | public static function mergeCacheData($cacheData)
44 | {
45 | return CacheerHelper::mergeCacheData($cacheData);
46 | }
47 |
48 | /**
49 | * @param array $item
50 | * @return void
51 | */
52 | public static function validateCacheItem(array $item)
53 | {
54 | CacheerHelper::validateCacheItem(
55 | $item,
56 | fn($msg) => CacheFileException::create($msg)
57 | );
58 | }
59 |
60 | /**
61 | * @param string|int $ttl
62 | * @param int $defaultTTL
63 | * @return mixed
64 | */
65 | public static function ttl($ttl = null, ?int $defaultTTL = null) {
66 | if ($ttl) {
67 | $ttl = is_string($ttl) ? self::convertExpirationToSeconds($ttl) : $ttl;
68 | } else {
69 | $ttl = $defaultTTL;
70 | }
71 | return $ttl;
72 | }
73 |
74 | /**
75 | * @param mixed $currentCacheData
76 | * @param mixed $cacheData
77 | * @return array
78 | */
79 | public static function arrayIdentifier(mixed $currentCacheData, mixed $cacheData)
80 | {
81 | return CacheerHelper::arrayIdentifier($currentCacheData, $cacheData);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/Helpers/CacheRedisHelper.php:
--------------------------------------------------------------------------------
1 |
11 | * @package Silviooosilva\CacheerPhp
12 | */
13 | class CacheRedisHelper
14 | {
15 |
16 | /**
17 | * @param mixed $data
18 | * @param bool $serialize
19 | * @return mixed
20 | */
21 | public static function serialize(mixed $data, bool $serialize = true)
22 | {
23 | if($serialize) {
24 | return serialize($data);
25 | }
26 |
27 | return unserialize($data);
28 |
29 | }
30 |
31 | /**
32 | * @param array $item
33 | * @return void
34 | */
35 | public static function validateCacheItem(array $item)
36 | {
37 | CacheerHelper::validateCacheItem(
38 | $item,
39 | fn($msg) => CacheRedisException::create($msg)
40 | );
41 | }
42 |
43 | /**
44 | * @param array $options
45 | * @return array
46 | */
47 | public static function mergeCacheData($cacheData)
48 | {
49 | return CacheerHelper::mergeCacheData($cacheData);
50 | }
51 |
52 | /**
53 | * @param mixed $currentCacheData
54 | * @param mixed $cacheData
55 | * @return array
56 | */
57 | public static function arrayIdentifier(mixed $currentCacheData, mixed $cacheData)
58 | {
59 | return CacheerHelper::arrayIdentifier($currentCacheData, $cacheData);
60 | }
61 |
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/src/Helpers/CacheerHelper.php:
--------------------------------------------------------------------------------
1 |
10 | * @package Silviooosilva\CacheerPhp
11 | */
12 | class EnvHelper {
13 |
14 | /**
15 | * @return string
16 | */
17 | public static function getRootPath()
18 | {
19 | // Tenta obter a raiz do projeto via Composer, se disponível
20 | if (class_exists(InstalledVersions::class)) {
21 | $rootPackage = InstalledVersions::getRootPackage();
22 | if (!empty($rootPackage['install_path'])) {
23 | return rtrim($rootPackage['install_path'], DIRECTORY_SEPARATOR);
24 | }
25 | }
26 |
27 | // Fallback: sobe os diretórios a partir do __DIR__ procurando o .env.example
28 | $baseDir = __DIR__;
29 | while (!file_exists($baseDir . DIRECTORY_SEPARATOR . '.env.example') && $baseDir !== dirname($baseDir)) {
30 | $baseDir = dirname($baseDir);
31 | }
32 |
33 | return rtrim($baseDir, DIRECTORY_SEPARATOR);
34 | }
35 |
36 | /**
37 | * @return void
38 | */
39 | public static function copyEnv()
40 | {
41 | $rootDir = self::getRootPath();
42 | $envFile = $rootDir . '/.env';
43 | $envExampleFile = $rootDir . '/.env.example';
44 |
45 | if (!file_exists($envFile) && file_exists($envExampleFile)) {
46 | if (copy($envExampleFile, $envFile)) {
47 | echo ".env file created successfully from .env.example.\n";
48 | } else {
49 | echo "Failed to create .env file from .env.example.\n";
50 | }
51 | }
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/Helpers/SqliteHelper.php:
--------------------------------------------------------------------------------
1 |
9 | * @package Silviooosilva\CacheerPhp
10 | */
11 | class SqliteHelper
12 | {
13 |
14 | /**
15 | * @param string $database
16 | * @param ?string $path
17 | * @return string
18 | */
19 | public static function database(string $database = 'database.sqlite', ?string $path = null)
20 | {
21 | return self::getDynamicSqliteDbPath($database, $path);
22 | }
23 |
24 | /**
25 | * @param string $database
26 | * @param ?string $path
27 | * @return string
28 | */
29 | private static function getDynamicSqliteDbPath(string $database, ?string $path = null)
30 | {
31 | $rootPath = EnvHelper::getRootPath();
32 | $databaseDir = is_null($path) ? $rootPath . '/database' : $rootPath . '/' . $path;
33 | $dbFile = $databaseDir . '/' . self::checkExtension($database);
34 |
35 | if (!is_dir($databaseDir)) {
36 | self::createDatabaseDir($databaseDir);
37 | }
38 | if (!file_exists($dbFile)) {
39 | self::createDatabaseFile($dbFile);
40 | }
41 |
42 | return $dbFile;
43 | }
44 |
45 | /**
46 | * @param string $databaseDir
47 | * @return void
48 | */
49 | private static function createDatabaseDir(string $databaseDir)
50 | {
51 | if (!is_dir($databaseDir)) {
52 | mkdir($databaseDir, 0755, true);
53 | }
54 | }
55 |
56 | /**
57 | * @param string $dbFile
58 | * @return void
59 | */
60 | private static function createDatabaseFile(string $dbFile)
61 | {
62 | if (!file_exists($dbFile)) {
63 | file_put_contents($dbFile, '');
64 | }
65 | }
66 |
67 | /**
68 | * @param string $database
69 | * @return string
70 | */
71 | private static function checkExtension(string $database)
72 | {
73 | if (strpos($database, '.sqlite') === false) {
74 | return $database . '.sqlite';
75 | }
76 | return $database;
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/src/Interface/CacheerInterface.php:
--------------------------------------------------------------------------------
1 |
8 | * @package Silviooosilva\CacheerPhp
9 | */
10 | interface CacheerInterface
11 | {
12 | public function getCache(string $cacheKey, string $namespace = '', string|int $ttl = 3600);
13 | public function putCache(string $cacheKey, mixed $cacheData, string $namespace = '', int|string $ttl = 3600);
14 | public function flushCache();
15 | public function clearCache(string $cacheKey, string $namespace = '');
16 | public function has(string $cacheKey, string $namespace = '');
17 | public function renewCache(string $cacheKey, int | string $ttl, string $namespace = '');
18 | public function appendCache(string $cacheKey, mixed $cacheData, string $namespace = '');
19 | public function putMany(array $items, string $namespace = '', int $batchSize = 100);
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/src/Repositories/CacheDatabaseRepository.php:
--------------------------------------------------------------------------------
1 |
11 | * @package Silviooosilva\CacheerPhp
12 | */
13 | class CacheDatabaseRepository
14 | {
15 |
16 | /** @var PDO */
17 | private $connection = null;
18 |
19 | public function __construct()
20 | {
21 | $this->connection = Connect::getInstance();
22 | }
23 |
24 |
25 | /**
26 | * @param string $cacheKey
27 | * @param mixed $cacheData
28 | * @param string $namespace
29 | * @param string|int $ttl
30 | * @return bool
31 | */
32 | public function store(string $cacheKey, mixed $cacheData, string $namespace, string|int $ttl = 3600)
33 | {
34 | if (!empty($this->retrieve($cacheKey, $namespace))) {
35 | return $this->update($cacheKey, $cacheData, $namespace);
36 | }
37 |
38 | $expirationTime = date('Y-m-d H:i:s', time() + $ttl);
39 | $createdAt = date('Y-m-d H:i:s');
40 |
41 | $stmt = $this->connection->prepare(
42 | "INSERT INTO cacheer_table (cacheKey, cacheData, cacheNamespace, expirationTime, created_at)
43 | VALUES (:cacheKey, :cacheData, :namespace, :expirationTime, :createdAt)"
44 | );
45 | $stmt->bindValue(':cacheKey', $cacheKey);
46 | $stmt->bindValue(':cacheData', $this->serialize($cacheData));
47 | $stmt->bindValue(':namespace', $namespace);
48 | $stmt->bindValue(':expirationTime', $expirationTime);
49 | $stmt->bindValue(':createdAt', $createdAt);
50 |
51 | return $stmt->execute() && $stmt->rowCount() > 0;
52 | }
53 |
54 | /**
55 | * @param string $cacheKey
56 | * @param string $namespace
57 | * @return mixed
58 | */
59 | public function retrieve(string $cacheKey, string $namespace = '')
60 | {
61 | $driver = $this->connection->getAttribute(PDO::ATTR_DRIVER_NAME);
62 | $nowFunction = $this->getCurrentDateTime($driver);
63 |
64 | $stmt = $this->connection->prepare(
65 | "SELECT cacheData FROM cacheer_table
66 | WHERE cacheKey = :cacheKey AND cacheNamespace = :namespace AND expirationTime > $nowFunction
67 | LIMIT 1"
68 | );
69 | $stmt->bindValue(':cacheKey', $cacheKey);
70 | $stmt->bindValue(':namespace', $namespace);
71 | $stmt->execute();
72 |
73 | $data = $stmt->fetch(PDO::FETCH_ASSOC);
74 | return (!empty($data)) ? $this->serialize($data['cacheData'], false) : null;
75 | }
76 |
77 | /**
78 | * @return string
79 | */
80 | private function getUpdateQueryWithDriver()
81 | {
82 | $driver = $this->connection->getAttribute(PDO::ATTR_DRIVER_NAME);
83 | if ($driver === 'mysql' || $driver === 'mariadb') {
84 | return "UPDATE cacheer_table SET cacheData = :cacheData, cacheNamespace = :namespace WHERE cacheKey = :cacheKey LIMIT 1";
85 | }
86 | return "UPDATE cacheer_table SET cacheData = :cacheData, cacheNamespace = :namespace WHERE cacheKey = :cacheKey";
87 | }
88 |
89 | /**
90 | * @return string
91 | */
92 | private function getDeleteQueryWithDriver()
93 | {
94 | $driver = $this->connection->getAttribute(PDO::ATTR_DRIVER_NAME);
95 | if ($driver === 'mysql' || $driver === 'mariadb') {
96 | return "DELETE FROM cacheer_table WHERE cacheKey = :cacheKey AND cacheNamespace = :namespace LIMIT 1";
97 | }
98 | return "DELETE FROM cacheer_table WHERE cacheKey = :cacheKey AND cacheNamespace = :namespace";
99 | }
100 |
101 | /**
102 | * @param string $cacheKey
103 | * @param mixed $cacheData
104 | * @param string $namespace
105 | * @return bool
106 | */
107 | public function update(string $cacheKey, mixed $cacheData, string $namespace = '')
108 | {
109 | $query = $this->getUpdateQueryWithDriver();
110 | $stmt = $this->connection->prepare($query);
111 | $stmt->bindValue(':cacheData', $this->serialize($cacheData));
112 | $stmt->bindValue(':namespace', $namespace);
113 | $stmt->bindValue(':cacheKey', $cacheKey);
114 | $stmt->execute();
115 |
116 | return $stmt->rowCount() > 0;
117 | }
118 |
119 | /**
120 | * @param string $cacheKey
121 | * @param string $namespace
122 | * @return bool
123 | */
124 | public function clear(string $cacheKey, string $namespace = '')
125 | {
126 | $query = $this->getDeleteQueryWithDriver();
127 | $stmt = $this->connection->prepare($query);
128 | $stmt->bindValue(':cacheKey', $cacheKey);
129 | $stmt->bindValue(':namespace', $namespace);
130 | $stmt->execute();
131 |
132 | return $stmt->rowCount() > 0;
133 | }
134 |
135 | /**
136 | * @return string
137 | */
138 | private function getRenewExpirationQueryWithDriver(): string
139 | {
140 | $driver = $this->connection->getAttribute(PDO::ATTR_DRIVER_NAME);
141 | if ($driver === 'sqlite') {
142 | return "UPDATE cacheer_table
143 | SET expirationTime = DATETIME(expirationTime, '+' || :ttl || ' seconds')
144 | WHERE cacheKey = :cacheKey AND cacheNamespace = :namespace AND expirationTime > :currentTime";
145 | }
146 | return "UPDATE cacheer_table
147 | SET expirationTime = DATE_ADD(expirationTime, INTERVAL :ttl SECOND)
148 | WHERE cacheKey = :cacheKey AND cacheNamespace = :namespace AND expirationTime > :currentTime";
149 | }
150 |
151 | /**
152 | * @param string $cacheKey
153 | * @param string $namespace
154 | * @param string $currentTime
155 | * @return bool
156 | */
157 | private function hasValidCache(string $cacheKey, string $namespace, string $currentTime): bool
158 | {
159 | $stmt = $this->connection->prepare(
160 | "SELECT 1 FROM cacheer_table
161 | WHERE cacheKey = :cacheKey AND cacheNamespace = :namespace AND expirationTime > :currentTime
162 | LIMIT 1"
163 | );
164 | $stmt->bindValue(':cacheKey', $cacheKey);
165 | $stmt->bindValue(':namespace', $namespace);
166 | $stmt->bindValue(':currentTime', $currentTime);
167 | $stmt->execute();
168 | return $stmt->fetchColumn() !== false;
169 | }
170 |
171 | /**
172 | * @param string $cacheKey
173 | * @param string|int $ttl
174 | * @param string $namespace
175 | * @return bool
176 | */
177 | public function renew(string $cacheKey, string|int $ttl, string $namespace = '')
178 | {
179 | $currentTime = date('Y-m-d H:i:s');
180 | if (!$this->hasValidCache($cacheKey, $namespace, $currentTime)) {
181 | return false;
182 | }
183 |
184 | $query = $this->getRenewExpirationQueryWithDriver();
185 | $stmt = $this->connection->prepare($query);
186 | $stmt->bindValue(':ttl', (int) $ttl, PDO::PARAM_INT);
187 | $stmt->bindValue(':cacheKey', $cacheKey);
188 | $stmt->bindValue(':namespace', $namespace);
189 | $stmt->bindValue(':currentTime', $currentTime);
190 | $stmt->execute();
191 |
192 | return $stmt->rowCount() > 0;
193 | }
194 |
195 | /**
196 | * @return bool
197 | */
198 | public function flush()
199 | {
200 | return $this->connection->exec("DELETE FROM cacheer_table") !== false;
201 | }
202 |
203 | /**
204 | * @param mixed $data
205 | * @return string
206 | */
207 | private function serialize(mixed $data, bool $serialize = true)
208 | {
209 | return $serialize ? serialize($data) : unserialize($data);
210 | }
211 |
212 | /**
213 | * @param string $driver
214 | * @return string
215 | */
216 | private function getCurrentDateTime(string $driver)
217 | {
218 | return ($driver === 'sqlite') ? "DATETIME('now', 'localtime')" : "NOW()";
219 | }
220 | }
221 |
--------------------------------------------------------------------------------
/src/Support/TimeBuilder.php:
--------------------------------------------------------------------------------
1 |
11 | * @package Silviooosilva\CacheerPhp
12 | */
13 | class TimeBuilder
14 | {
15 |
16 | /** @param string $unit */
17 | private string $unit;
18 |
19 | /** @param int $value */
20 | private int $value;
21 |
22 | /** @param Closure $callback */
23 | private Closure $callback;
24 |
25 | /** @param FileOptionBuilder */
26 | private $builder = null;
27 |
28 | public function __construct(Closure $callback, $builder)
29 | {
30 | $this->callback = $callback;
31 | $this->builder = $builder;
32 | }
33 |
34 | /**
35 | * @param int $value
36 | * @return FileOptionBuilder|mixed
37 | */
38 | public function second(int $value)
39 | {
40 | return $this->setTime($value, "seconds");
41 | }
42 |
43 | /**
44 | * @param int $value
45 | * @return FileOptionBuilder|mixed
46 | */
47 | public function minute(int $value)
48 | {
49 | return $this->setTime($value, "minutes");
50 | }
51 |
52 | /**
53 | * @param int $value
54 | * @return FileOptionBuilder|mixed
55 | */
56 | public function hour(int $value)
57 | {
58 | return $this->setTime($value, "hours");
59 | }
60 |
61 | /**
62 | * @param int $value
63 | * @return FileOptionBuilder|mixed
64 | */
65 | public function day(int $value)
66 | {
67 | return $this->setTime($value, "days");
68 | }
69 |
70 | /**
71 | * @param int $value
72 | * @return FileOptionBuilder|mixed
73 | */
74 | public function week(int $value)
75 | {
76 | return $this->setTime($value, "weeks");
77 | }
78 |
79 | /**
80 | * @param int $value
81 | * @return FileOptionBuilder|mixed
82 | */
83 | public function month(int $value)
84 | {
85 | return $this->setTime($value, "months");
86 | }
87 |
88 |
89 | /**
90 | * @param int $value
91 | * @param string $unit
92 | * @return FileOptionBuilder
93 | */
94 | private function setTime(int $value, string $unit)
95 | {
96 |
97 | $this->value = $value;
98 | $this->unit = $unit;
99 | ($this->callback)("{$value} {$unit}");
100 | return $this->builder;
101 | }
102 |
103 | }
104 |
--------------------------------------------------------------------------------
/src/Utils/CacheDataFormatter.php:
--------------------------------------------------------------------------------
1 |
8 | * @package Silviooosilva\CacheerPhp
9 | */
10 | class CacheDataFormatter
11 | {
12 | /** @param mixed $data */
13 | private mixed $data;
14 |
15 | public function __construct(mixed $data)
16 | {
17 | $this->data = $data;
18 | }
19 |
20 | /**
21 | * @return string|false
22 | */
23 | public function toJson()
24 | {
25 | return json_encode(
26 | $this->data,
27 | JSON_PRETTY_PRINT |
28 | JSON_UNESCAPED_UNICODE |
29 | JSON_UNESCAPED_SLASHES
30 | );
31 | }
32 |
33 | /**
34 | * @return array
35 | */
36 | public function toArray()
37 | {
38 | return (array)$this->data;
39 | }
40 |
41 | /**
42 | * @return string
43 | */
44 | public function toString()
45 | {
46 | return (string)$this->data;
47 | }
48 |
49 | /**
50 | * @return object
51 | */
52 | public function toObject()
53 | {
54 | return (object)$this->data;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Utils/CacheDriver.php:
--------------------------------------------------------------------------------
1 |
17 | * @package Silviooosilva\CacheerPhp
18 | */
19 | class CacheDriver
20 | {
21 |
22 | /**
23 | * @var Cacheer
24 | */
25 | protected $cacheer;
26 |
27 | /** @param string $logPath */
28 | public string $logPath = 'cacheer.log';
29 |
30 | public function __construct(Cacheer $cacheer)
31 | {
32 | $this->cacheer = $cacheer;
33 | }
34 |
35 | /**
36 | * @return Cacheer
37 | */
38 | public function useDatabaseDriver()
39 | {
40 | $this->cacheer->cacheStore = new DatabaseCacheStore($this->logPath);
41 | return $this->cacheer;
42 | }
43 |
44 | /**
45 | * @throws \Exception
46 | * @return Cacheer
47 | */
48 | public function useFileDriver()
49 | {
50 | $this->cacheer->options['loggerPath'] = $this->logPath;
51 | $this->cacheer->cacheStore = new FileCacheStore($this->cacheer->options);
52 | return $this->cacheer;
53 | }
54 |
55 | /**
56 | * @return Cacheer
57 | */
58 | public function useRedisDriver()
59 | {
60 | $this->cacheer->cacheStore = new RedisCacheStore($this->logPath);
61 | return $this->cacheer;
62 | }
63 |
64 | /**
65 | * @return Cacheer
66 | */
67 | public function useArrayDriver()
68 | {
69 | $this->cacheer->cacheStore = new ArrayCacheStore($this->logPath);
70 | return $this->cacheer;
71 | }
72 |
73 | /**
74 | * @return Cacheer
75 | */
76 | public function useDefaultDriver()
77 | {
78 | if (!isset($this->cacheer->options['cacheDir'])) {
79 | $projectRoot = EnvHelper::getRootPath();
80 | $cacheDir = $projectRoot . DIRECTORY_SEPARATOR . "CacheerPHP" . DIRECTORY_SEPARATOR . "Cache";
81 | if ($this->isDir($cacheDir)) {
82 | $this->cacheer->options['cacheDir'] = $cacheDir;
83 | } else {
84 | throw CacheFileException::create("Failed to create cache directory: " . $cacheDir);
85 | }
86 | }
87 | $this->useFileDriver();
88 | return $this->cacheer;
89 | }
90 |
91 | /**
92 | * @param mixed $dirName
93 | * @return bool
94 | */
95 | private function isDir(mixed $dirName)
96 | {
97 | if (is_dir($dirName)) {
98 | return true;
99 | }
100 | return mkdir($dirName, 0755, true);
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/Utils/CacheLogger.php:
--------------------------------------------------------------------------------
1 |
9 | * @package Silviooosilva\CacheerPhp
10 | */
11 | class CacheLogger
12 | {
13 | private $logFile;
14 | private $maxFileSize; // Tamanho máximo do arquivo em bytes (5MB)
15 | private $logLevel;
16 | private $logLevels = ['DEBUG', 'INFO', 'WARNING', 'ERROR'];
17 |
18 | public function __construct($logFile = 'cacheer.log', $maxFileSize = 5 * 1024 * 1024, $logLevel = 'DEBUG')
19 | {
20 | $this->logFile = $logFile;
21 | $this->maxFileSize = $maxFileSize;
22 | $this->logLevel = strtoupper($logLevel);
23 | }
24 |
25 | /**
26 | * @return void
27 | */
28 | public function info($message)
29 | {
30 | $this->log('INFO', $message);
31 | }
32 |
33 | /**
34 | * @return void
35 | */
36 | public function warning($message)
37 | {
38 | $this->log('WARNING', $message);
39 | }
40 |
41 | /**
42 | * @return void
43 | */
44 | public function error($message)
45 | {
46 | $this->log('ERROR', $message);
47 | }
48 |
49 | /**
50 | * @return void
51 | */
52 | public function debug($message)
53 | {
54 | $this->log('DEBUG', $message);
55 | }
56 |
57 | /**
58 | * @param mixed $level
59 | * @return string|int|false
60 | */
61 | private function shouldLog(mixed $level)
62 | {
63 | return array_search($level, $this->logLevels) >= array_search($this->logLevel, $this->logLevels);
64 | }
65 |
66 | /**
67 | * @return void
68 | */
69 | private function rotateLog()
70 | {
71 | if (file_exists($this->logFile) && filesize($this->logFile) >= $this->maxFileSize) {
72 | $date = date('Y-m-d_H-i-s');
73 | rename($this->logFile, "cacheer_$date.log");
74 | }
75 | }
76 |
77 | /**
78 | * @param mixed $level
79 | * @param string $message
80 | * @return void
81 | */
82 | private function log($level, $message)
83 | {
84 | if (!$this->shouldLog($level)) {
85 | return;
86 | }
87 |
88 | $this->rotateLog();
89 |
90 | $date = date('Y-m-d H:i:s');
91 | $logMessage = "[$date] [$level] $message" . PHP_EOL;
92 | file_put_contents($this->logFile, $logMessage, FILE_APPEND);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/tests/Feature/OptionBuildTest.php:
--------------------------------------------------------------------------------
1 | cacheDir = __DIR__ . '/cache';
16 | if (!file_exists($this->cacheDir) || !is_dir($this->cacheDir)) {
17 | mkdir($this->cacheDir, 0755, true);
18 | }
19 |
20 | $this->cache = new Cacheer();
21 | }
22 |
23 | protected function tearDown(): void
24 | {
25 | $this->cache->flushCache();
26 | }
27 |
28 | public function test_it_can_set_cache_directory()
29 | {
30 | $cacheDir = __DIR__ . "/cache";
31 |
32 | $options = OptionBuilder::forFile()
33 | ->dir($cacheDir)
34 | ->build();
35 |
36 | $this->assertArrayHasKey('cacheDir', $options);
37 | $this->assertEquals($cacheDir, $options['cacheDir']);
38 | }
39 |
40 |
41 | public function test_it_can_set_expiration_time()
42 | {
43 |
44 | $options = OptionBuilder::forFile()
45 | ->expirationTime('2 hours')
46 | ->build();
47 |
48 | $this->assertArrayHasKey('expirationTime', $options);
49 | $this->assertEquals('2 hours', $options['expirationTime']);
50 | }
51 |
52 | public function test_it_can_set_flush_after()
53 | {
54 | $options = OptionBuilder::forFile()
55 | ->flushAfter('11 seconds')
56 | ->build();
57 |
58 | $this->assertArrayHasKey('flushAfter', $options);
59 | $this->assertEquals('11 seconds', $options['flushAfter']);
60 | }
61 |
62 | public function test_it_can_set_multiple_options_together()
63 | {
64 | $cacheDir = __DIR__ . "/cache";
65 |
66 | $options = OptionBuilder::forFile()
67 | ->dir($cacheDir)
68 | ->expirationTime('1 day')
69 | ->flushAfter('30 minutes')
70 | ->build();
71 |
72 | $this->assertEquals([
73 | 'cacheDir' => $cacheDir,
74 | 'expirationTime' => '1 day',
75 | 'flushAfter' => '30 minutes',
76 | ], $options);
77 | }
78 |
79 | public function test_it_allows_setting_expiration_time_with_timebuilder()
80 | {
81 | $options = OptionBuilder::forFile()->expirationTime()->week(1)->build();
82 | $this->assertArrayHasKey('expirationTime', $options);
83 | $this->assertEquals('1 weeks', $options['expirationTime']);
84 | }
85 |
86 | public function test_it_allows_setting_flush_after_with_timebuilder()
87 | {
88 | $options = OptionBuilder::forFile()->flushAfter()->second(10)->build();
89 | $this->assertArrayHasKey('flushAfter', $options);
90 | $this->assertEquals('10 seconds', $options['flushAfter']);
91 | }
92 |
93 | public function test_it_can_set_multiple_options_together_with_timebuilder()
94 | {
95 | $cacheDir = __DIR__ . "/cache";
96 | $options = OptionBuilder::forFile()
97 | ->dir($cacheDir)
98 | ->expirationTime()->week(1)
99 | ->flushAfter()->minute(10)
100 | ->build();
101 |
102 | $this->assertEquals([
103 | 'cacheDir' => $cacheDir,
104 | 'expirationTime' => '1 weeks',
105 | 'flushAfter' => '10 minutes',
106 | ], $options);
107 | }
108 |
109 | public function test_it_returns_empty_array_when_no_options_are_set()
110 | {
111 | $options = OptionBuilder::forFile()->build();
112 | $this->assertIsArray($options);
113 | $this->assertEmpty($options);
114 | }
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/tests/Unit/ArrayCacheStoreTest.php:
--------------------------------------------------------------------------------
1 | cache = new Cacheer();
15 | $this->cache->setDriver()->useArrayDriver();
16 | $this->cache->setConfig()->setTimeZone('America/Toronto');
17 | }
18 |
19 | protected function tearDown(): void
20 | {
21 | $this->cache->flushCache();
22 | }
23 |
24 | public function testUsingArrayDriverSetsProperInstance()
25 | {
26 | $this->assertInstanceOf(ArrayCacheStore::class, $this->cache->cacheStore);
27 | }
28 |
29 | public function testPutAndGetCacheInArray()
30 | {
31 | $cacheKey = 'test_key';
32 | $cacheData = ['name' => 'John Doe', 'email' => 'john@example.com'];
33 |
34 | $this->cache->putCache($cacheKey, $cacheData, '', 3600);
35 |
36 | $result = $this->cache->getCache($cacheKey);
37 |
38 | $this->assertNotEmpty($result);
39 | $this->assertEquals($cacheData, $result);
40 | }
41 |
42 | public function testExpiredCacheInArray()
43 | {
44 | $cacheKey = 'expired_key';
45 | $cacheData = ['name' => 'Expired User', 'email' => 'expired@example.com'];
46 |
47 | $this->cache->putCache($cacheKey, $cacheData, '', 1);
48 | sleep(3);
49 |
50 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
51 | $this->assertEmpty($this->cache->getCache($cacheKey));
52 | $this->assertFalse($this->cache->isSuccess());
53 | }
54 |
55 |
56 | public function testOverwriteExistingCacheInArray()
57 | {
58 | $cacheKey = 'overwrite_key';
59 | $initialCacheData = ['name' => 'Initial Data', 'email' => 'initial@example.com'];
60 | $newCacheData = ['name' => 'New Data', 'email' => 'new@example.com'];
61 |
62 | $this->cache->putCache($cacheKey, $initialCacheData);
63 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
64 |
65 | $this->cache->appendCache($cacheKey, $newCacheData);
66 | $this->assertEquals("Cache appended successfully", $this->cache->getMessage());
67 | $this->assertEquals($newCacheData, $this->cache->getCache($cacheKey));
68 | }
69 |
70 |
71 | public function testPutManyCacheItemsInArray()
72 | {
73 | $items = [
74 | [
75 | 'cacheKey' => 'user_1_profile',
76 | 'cacheData' => [
77 | ['name' => 'John Doe', 'email' => 'john@example.com'],
78 | ['name' => 'John Doe', 'email' => 'john@example.com'],
79 | ['name' => 'John Doe', 'email' => 'john@example.com'],
80 | ['name' => 'John Doe', 'email' => 'john@example.com']
81 | ]
82 | ],
83 | [
84 | 'cacheKey' => 'user_2_profile',
85 | 'cacheData' => [
86 | ['name' => 'Jane Doe', 'email' => 'jane@example.com'],
87 | ['name' => 'Jane Doe', 'email' => 'jane@example.com'],
88 | ['name' => 'Jane Doe', 'email' => 'jane@example.com'],
89 | ['name' => 'Jane Doe', 'email' => 'jane@example.com']
90 | ]
91 | ]
92 | ];
93 |
94 | $this->cache->putMany($items);
95 | foreach ($items as $item) {
96 |
97 | $this->assertEquals($item['cacheData'], $this->cache->getCache($item['cacheKey']));
98 | }
99 | }
100 |
101 | public function testHasCacheFromArray()
102 | {
103 | $cacheKey = 'test_key';
104 | $cacheData = ['name' => 'Sílvio Silva', 'role' => 'Developer'];
105 |
106 | $this->cache->putCache($cacheKey, $cacheData);
107 |
108 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
109 | $this->assertTrue($this->cache->isSuccess());
110 |
111 | $this->cache->has($cacheKey);
112 | $this->assertTrue($this->cache->isSuccess());
113 | }
114 |
115 | public function testRenewCacheFromArray()
116 | {
117 | $cacheKey = 'expired_key';
118 | $cacheData = ['name' => 'Expired User', 'email' => 'expired@example.com'];
119 |
120 | // Define TTL de 10 seg para que a chave ainda exista quando renovarmos
121 | $this->cache->putCache($cacheKey, $cacheData, '', 120);
122 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
123 | sleep(2);
124 |
125 | // Verifica que a chave existe antes de renovar
126 | $this->assertNotEmpty($this->cache->getCache($cacheKey));
127 |
128 | $this->cache->renewCache($cacheKey, 7200);
129 | $this->assertTrue($this->cache->isSuccess());
130 | $this->assertNotEmpty($this->cache->getCache($cacheKey));
131 | }
132 |
133 | public function testRenewCacheWithNamespaceFromArray()
134 | {
135 | $cacheKey = 'expired_key';
136 | $namespace = 'expired_namespace';
137 | $cacheData = ['name' => 'Expired User', 'email' => 'expired@example.com'];
138 |
139 | $this->cache->putCache($cacheKey, $cacheData, $namespace, 120);
140 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
141 | sleep(2);
142 |
143 | $this->assertNotEmpty($this->cache->getCache($cacheKey, $namespace));
144 |
145 | $this->cache->renewCache($cacheKey, 7200, $namespace);
146 | $this->assertTrue($this->cache->isSuccess());
147 | $this->assertNotEmpty($this->cache->getCache($cacheKey, $namespace));
148 | }
149 |
150 | public function testClearCacheDataFromArray()
151 | {
152 | $cacheKey = 'test_key';
153 | $data = 'test_data';
154 |
155 | $this->cache->putCache($cacheKey, $data);
156 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
157 |
158 | $this->cache->clearCache($cacheKey);
159 | $this->assertTrue($this->cache->isSuccess());
160 | $this->assertEquals("Cache cleared successfully", $this->cache->getMessage());
161 |
162 | $this->assertEmpty($this->cache->getCache($cacheKey));
163 | }
164 |
165 | public function testFlushCacheDataFromArray()
166 | {
167 | $key1 = 'test_key1';
168 | $data1 = 'test_data1';
169 |
170 | $key2 = 'test_key2';
171 | $data2 = 'test_data2';
172 |
173 | $this->cache->putCache($key1, $data1);
174 | $this->cache->putCache($key2, $data2);
175 | $this->assertTrue($this->cache->isSuccess());
176 | $this->assertTrue($this->cache->isSuccess());
177 |
178 | $this->cache->flushCache();
179 |
180 | $this->assertTrue($this->cache->isSuccess());
181 | $this->assertEquals("Cache flushed successfully", $this->cache->getMessage());
182 | }
183 |
184 | public function test_remember_saves_and_recover_values()
185 | {
186 | $this->cache->flushCache();
187 |
188 | $value = $this->cache->remember('remember_test_key', 60, function () {
189 | return 'valor_teste';
190 | });
191 |
192 | $this->assertEquals('valor_teste', $value);
193 |
194 | $cachedValue = $this->cache->remember('remember_test_key', 60, function (){
195 | return 'novo_valor';
196 | });
197 |
198 |
199 | $this->assertEquals('valor_teste', $cachedValue);
200 | }
201 |
202 | public function test_remember_forever_saves_value_indefinitely()
203 | {
204 | $this->cache->flushCache();
205 |
206 | $value = $this->cache->rememberForever('remember_forever_key', function () {
207 | return 'valor_eterno';
208 | });
209 | $this->assertEquals('valor_eterno', $value);
210 |
211 | $cachedValue = $this->cache->rememberForever('remember_forever_key', function () {
212 | return 'novo_valor';
213 | });
214 |
215 | $this->assertEquals('valor_eterno', $cachedValue);
216 | }
217 |
218 |
219 | public function test_get_and_forget()
220 | {
221 | $cacheKey = 'cache_key_test';
222 | $this->cache->putCache($cacheKey, 10);
223 |
224 | $this->assertTrue($this->cache->isSuccess());
225 |
226 | $cacheData = $this->cache->getAndForget($cacheKey);
227 |
228 | $this->assertTrue($this->cache->isSuccess());
229 | $this->assertEquals(10, $cacheData);
230 |
231 | $oldCacheData = $this->cache->getAndForget($cacheKey);
232 |
233 | $this->assertNull($oldCacheData);
234 | $this->assertFalse($this->cache->isSuccess());
235 |
236 | $noCacheData = $this->cache->getAndForget('non_existent_cache_key');
237 | $this->assertNull($noCacheData);
238 | }
239 |
240 | public function test_store_if_not_present_with_add_function()
241 | {
242 | $existentKey = 'cache_key_test';
243 |
244 | $nonExistentKey = 'non_existent_key';
245 |
246 | $this->cache->putCache($existentKey, 'existent_data');
247 |
248 | $this->assertTrue($this->cache->isSuccess());
249 | $this->assertEquals('existent_data', $this->cache->getCache($existentKey));
250 |
251 | $addCache = $this->cache->add($existentKey, 100);
252 |
253 | $this->assertTrue($addCache);
254 | $this->assertNotEquals(100, 'existent_data');
255 |
256 | $addNonExistentKey = $this->cache->add($nonExistentKey, 'non_existent_data');
257 |
258 | $this->assertFalse($addNonExistentKey);
259 | $this->assertEquals('non_existent_data', $this->cache->getCache($nonExistentKey));
260 | $this->assertTrue($this->cache->isSuccess());
261 |
262 | }
263 |
264 | public function test_increment_function() {
265 |
266 | $cacheKey = 'test_increment';
267 | $cacheData = 2025;
268 |
269 | $this->cache->putCache($cacheKey, $cacheData);
270 |
271 | $this->assertTrue($this->cache->isSuccess());
272 | $this->assertEquals($cacheData, $this->cache->getCache($cacheKey));
273 | $this->assertIsNumeric($this->cache->getCache($cacheKey));
274 |
275 | $increment = $this->cache->increment($cacheKey, 2);
276 | $this->assertTrue($increment);
277 |
278 | $this->assertEquals(2027, $this->cache->getCache($cacheKey));
279 |
280 | }
281 |
282 | public function test_decrement_function() {
283 |
284 | $cacheKey = 'test_decrement';
285 | $cacheData = 2027;
286 |
287 | $this->cache->putCache($cacheKey, $cacheData);
288 |
289 | $this->assertTrue($this->cache->isSuccess());
290 | $this->assertEquals($cacheData, $this->cache->getCache($cacheKey));
291 | $this->assertIsNumeric($this->cache->getCache($cacheKey));
292 |
293 | $increment = $this->cache->decrement($cacheKey, 2);
294 | $this->assertTrue($increment);
295 |
296 | $this->assertEquals(2025, $this->cache->getCache($cacheKey));
297 |
298 | }
299 |
300 | }
--------------------------------------------------------------------------------
/tests/Unit/DatabaseCacheStoreTest.php:
--------------------------------------------------------------------------------
1 | cache = new Cacheer();
14 | $this->cache->setConfig()->setDatabaseConnection(Connect::getInstance()->getAttribute(PDO::ATTR_DRIVER_NAME));
15 | $this->cache->setDriver()->useDatabaseDriver();
16 | $this->cache->setConfig()->setTimeZone('America/Toronto');
17 | }
18 |
19 | protected function tearDown(): void
20 | {
21 | $this->cache->flushCache();
22 | }
23 |
24 | public function testPutCacheInDatabase()
25 | {
26 | $cacheKey = 'test_key';
27 | $cacheData = ['name' => 'John Doe', 'email' => 'john@example.com'];
28 |
29 | $this->cache->putCache($cacheKey, $cacheData, '', 3600);
30 |
31 | $result = $this->cache->getCache($cacheKey);
32 |
33 | $this->assertNotEmpty($result);
34 | $this->assertEquals($cacheData, $result);
35 | }
36 |
37 | public function testGetCacheFromDatabase()
38 | {
39 | $cacheKey = 'test_key02';
40 | $cacheData = ['name' => 'Jane Doe', 'email' => 'jane@example.com'];
41 |
42 | $this->cache->putCache($cacheKey, $cacheData, '', 3600);
43 | $this->assertEquals("Cache Stored Successfully", $this->cache->getMessage());
44 |
45 | $result = $this->cache->getCache($cacheKey);
46 |
47 | $this->assertNotEmpty($result);
48 | $this->assertEquals($cacheData, $result);
49 | }
50 |
51 | public function testExpiredCacheInDatabase()
52 | {
53 | $cacheKey = 'expired_key';
54 | $cacheData = ['name' => 'Expired User', 'email' => 'expired@example.com'];
55 |
56 | $this->cache->putCache($cacheKey, $cacheData, '', -3600);
57 | $this->assertEquals("Cache Stored Successfully", $this->cache->getMessage());
58 |
59 | $this->assertEmpty($this->cache->getCache($cacheKey));
60 | $this->assertFalse($this->cache->isSuccess());
61 | }
62 | public function testOverwriteExistingCacheInDatabase()
63 | {
64 |
65 | $cacheKey = 'overwrite_key';
66 | $initialCacheData = ['name' => 'Initial Data', 'email' => 'initial@example.com'];
67 | $newCacheData = ['name' => 'New Data', 'email' => 'new@example.com'];
68 |
69 | $expirationTime = date('Y-m-d H:i:s', time() + 3600);
70 |
71 |
72 | $db = Connect::getInstance();
73 | $query = $db->prepare("INSERT INTO cacheer_table (cacheKey, cacheData, cacheNamespace, expirationTime) VALUES (?, ?, ?, ?)");
74 | $query->bindValue(1, $cacheKey);
75 | $query->bindValue(2, serialize($initialCacheData));
76 | $query->bindValue(3, '');
77 | $query->bindValue(4, $expirationTime);
78 |
79 | $this->assertTrue($query->execute());
80 |
81 | $this->cache->appendCache($cacheKey, $newCacheData);
82 | $this->assertEquals("Cache updated successfully.", $this->cache->getMessage());
83 |
84 | $driver = Connect::getInstance()->getAttribute(PDO::ATTR_DRIVER_NAME);
85 | $nowFunction = ($driver === 'sqlite') ? "DATETIME('now', 'localtime')" : "NOW()";
86 |
87 | $query = $db->prepare("SELECT cacheData FROM cacheer_table WHERE cacheKey = ? AND cacheNamespace = ? AND expirationTime > $nowFunction");
88 | $query->bindValue(1, $cacheKey);
89 | $query->bindValue(2, '');
90 |
91 | $this->assertTrue($query->execute());
92 |
93 | $result = $query->fetch(PDO::FETCH_ASSOC);
94 |
95 | $this->assertEquals($newCacheData, unserialize($result['cacheData']));
96 | }
97 |
98 | public function testPutManyCacheItemsInDatabase(): void
99 | {
100 |
101 | $items = [
102 | [
103 | 'cacheKey' => 'user_1_profile',
104 | 'cacheData' => [
105 | ['name' => 'John Doe', 'email' => 'john@example.com'],
106 | ['name' => 'John Doe', 'email' => 'john@example.com'],
107 | ['name' => 'John Doe', 'email' => 'john@example.com'],
108 | ['name' => 'John Doe', 'email' => 'john@example.com']
109 | ]
110 | ],
111 | [
112 | 'cacheKey' => 'user_2_profile',
113 | 'cacheData' => [
114 | ['name' => 'Jane Doe', 'email' => 'jane@example.com'],
115 | ['name' => 'Jane Doe', 'email' => 'jane@example.com'],
116 | ['name' => 'Jane Doe', 'email' => 'jane@example.com'],
117 | ['name' => 'Jane Doe', 'email' => 'jane@example.com']
118 | ]
119 | ]
120 | ];
121 |
122 | $this->cache->putMany($items);
123 |
124 | foreach ($items as $item) {
125 | $this->assertEquals($item['cacheData'], $this->cache->getCache($item['cacheKey']));
126 | }
127 | }
128 |
129 | public function testAppendCacheWithNamespaceInDatabase(): void
130 | {
131 | $cacheKey = 'test_append_key_ns';
132 | $namespace = 'test_namespace';
133 |
134 | $initialData = ['initial' => 'data'];
135 | $additionalData = ['new' => 'data'];
136 |
137 | $expectedData = array_merge($initialData, $additionalData);
138 |
139 | // Armazena os dados iniciais no cache com namespace
140 | $this->cache->putCache($cacheKey, $initialData, $namespace);
141 | $this->assertTrue($this->cache->isSuccess());
142 |
143 | // Adiciona novos dados ao cache existente com namespace
144 | $this->cache->appendCache($cacheKey, $additionalData, $namespace);
145 | $this->assertTrue($this->cache->isSuccess());
146 |
147 | // Verifica se os dados no cache são os esperados
148 | $cachedData = $this->cache->getCache($cacheKey, $namespace);
149 | $this->assertEquals($expectedData, $cachedData);
150 | }
151 |
152 | public function testDataOutputShouldBeOfTypeJson()
153 | {
154 | $this->cache->useFormatter();
155 |
156 | $cacheKey = "key_json";
157 | $cacheData = "data_json";
158 |
159 | $this->cache->putCache($cacheKey, $cacheData);
160 | $this->assertTrue($this->cache->isSuccess());
161 |
162 | $cacheOutput = $this->cache->getCache($cacheKey)->toJson();
163 | $this->assertTrue($this->cache->isSuccess());
164 | $this->assertJson($cacheOutput);
165 | }
166 |
167 | public function testDataOutputShouldBeOfTypeArray()
168 | {
169 |
170 | $this->cache->useFormatter();
171 |
172 | $cacheKey = "key_array";
173 | $cacheData = "data_array";
174 |
175 | $this->cache->putCache($cacheKey, $cacheData);
176 | $this->assertTrue($this->cache->isSuccess());
177 |
178 | $cacheOutput = $this->cache->getCache($cacheKey)->toArray();
179 | $this->assertTrue($this->cache->isSuccess());
180 | $this->assertIsArray($cacheOutput);
181 | }
182 |
183 | public function testDataOutputShouldBeOfTypeObject()
184 | {
185 | $this->cache->useFormatter();
186 |
187 | $cacheKey = "key_object";
188 | $cacheData = ["id" => 123];
189 |
190 | $this->cache->putCache($cacheKey, $cacheData);
191 | $this->assertTrue($this->cache->isSuccess());
192 |
193 | $cacheOutput = $this->cache->getCache($cacheKey)->toObject();
194 | $this->assertTrue($this->cache->isSuccess());
195 | $this->assertIsObject($cacheOutput);
196 | }
197 |
198 |
199 | public function testClearCacheDataFromDatabase(): void
200 | {
201 | $cacheKey = 'test_key';
202 | $data = 'test_data';
203 |
204 | $this->cache->putCache($cacheKey, $data);
205 | $this->assertEquals("Cache Stored Successfully", $this->cache->getMessage());
206 |
207 | $this->cache->clearCache($cacheKey);
208 | $this->assertTrue($this->cache->isSuccess());
209 | $this->assertEquals("Cache deleted successfully!", $this->cache->getMessage());
210 |
211 | $this->assertEmpty($this->cache->getCache($cacheKey));
212 | }
213 |
214 |
215 | public function testFlushCacheDataFromDatabase(): void
216 | {
217 | $key1 = 'test_key1';
218 | $data1 = 'test_data1';
219 |
220 | $key2 = 'test_key2';
221 | $data2 = 'test_data2';
222 |
223 | $this->cache->putCache($key1, $data1);
224 | $this->cache->putCache($key2, $data2);
225 | $this->assertTrue($this->cache->isSuccess());
226 | $this->assertTrue($this->cache->isSuccess());
227 |
228 | $this->cache->flushCache();
229 | $this->assertTrue($this->cache->isSuccess());
230 | $this->assertEquals("Flush finished successfully", $this->cache->getMessage());
231 | }
232 |
233 | public function test_remember_saves_and_recover_values()
234 | {
235 | $value = $this->cache->remember('remember_test_key', 60, function () {
236 | return 'valor_teste';
237 | });
238 |
239 | $this->assertEquals('valor_teste', $value);
240 |
241 | $cachedValue = $this->cache->remember('remember_test_key', 60, function (){
242 | return 'novo_valor';
243 | });
244 |
245 |
246 | $this->assertEquals('valor_teste', $cachedValue);
247 | }
248 |
249 | public function test_remember_forever_saves_value_indefinitely()
250 | {
251 |
252 | $value = $this->cache->rememberForever('remember_forever_key', function () {
253 | return 'valor_eterno';
254 | });
255 | $this->assertEquals('valor_eterno', $value);
256 |
257 | $cachedValue = $this->cache->rememberForever('remember_forever_key', function () {
258 | return 'novo_valor';
259 | });
260 |
261 | $this->assertEquals('valor_eterno', $cachedValue);
262 | }
263 |
264 | public function test_get_and_forget()
265 | {
266 | $cacheKey = 'cache_key_test';
267 | $this->cache->putCache($cacheKey, 10);
268 |
269 | $this->assertTrue($this->cache->isSuccess());
270 |
271 | $cacheData = $this->cache->getAndForget($cacheKey);
272 |
273 | $this->assertTrue($this->cache->isSuccess());
274 | $this->assertEquals(10, $cacheData);
275 |
276 | $oldCacheData = $this->cache->getAndForget($cacheKey);
277 |
278 | $this->assertNull($oldCacheData);
279 | $this->assertFalse($this->cache->isSuccess());
280 |
281 | $noCacheData = $this->cache->getAndForget('non_existent_cache_key');
282 | $this->assertNull($noCacheData);
283 | }
284 |
285 | public function test_store_if_not_present_with_add_function()
286 | {
287 | $existentKey = 'cache_key_test';
288 |
289 | $nonExistentKey = 'non_existent_key';
290 |
291 | $this->cache->putCache($existentKey, 'existent_data');
292 |
293 | $this->assertTrue($this->cache->isSuccess());
294 | $this->assertEquals('existent_data', $this->cache->getCache($existentKey));
295 |
296 | $addCache = $this->cache->add($existentKey, 100);
297 |
298 | $this->assertTrue($addCache);
299 | $this->assertNotEquals(100, 'existent_data');
300 |
301 | $addNonExistentKey = $this->cache->add($nonExistentKey, 'non_existent_data');
302 |
303 | $this->assertFalse($addNonExistentKey);
304 | $this->assertEquals('non_existent_data', $this->cache->getCache($nonExistentKey));
305 | $this->assertTrue($this->cache->isSuccess());
306 | }
307 |
308 |
309 | public function test_increment_function() {
310 |
311 | $cacheKey = 'test_increment';
312 | $cacheData = 2025;
313 |
314 | $this->cache->putCache($cacheKey, $cacheData);
315 |
316 | $this->assertTrue($this->cache->isSuccess());
317 | $this->assertEquals($cacheData, $this->cache->getCache($cacheKey));
318 | $this->assertIsNumeric($this->cache->getCache($cacheKey));
319 |
320 | $increment = $this->cache->increment($cacheKey, 2);
321 | $this->assertTrue($increment);
322 |
323 | $this->assertEquals(2027, $this->cache->getCache($cacheKey));
324 |
325 | }
326 |
327 | public function test_decrement_function() {
328 |
329 | $cacheKey = 'test_decrement';
330 | $cacheData = 2027;
331 |
332 | $this->cache->putCache($cacheKey, $cacheData);
333 |
334 | $this->assertTrue($this->cache->isSuccess());
335 | $this->assertEquals($cacheData, $this->cache->getCache($cacheKey));
336 | $this->assertIsNumeric($this->cache->getCache($cacheKey));
337 |
338 | $increment = $this->cache->decrement($cacheKey, 2);
339 | $this->assertTrue($increment);
340 |
341 | $this->assertEquals(2025, $this->cache->getCache($cacheKey));
342 |
343 | }
344 |
345 |
346 | }
347 |
--------------------------------------------------------------------------------
/tests/Unit/FileCacheStoreTest.php:
--------------------------------------------------------------------------------
1 | cacheDir = __DIR__ . '/cache';
16 | if (!file_exists($this->cacheDir) || !is_dir($this->cacheDir)) {
17 | mkdir($this->cacheDir, 0755, true);
18 | }
19 |
20 | $options = [
21 | 'cacheDir' => $this->cacheDir,
22 | ];
23 |
24 | $this->cache = new Cacheer($options);
25 | }
26 |
27 | protected function tearDown(): void
28 | {
29 | $this->cache->flushCache();
30 | }
31 |
32 | public function testPutCache()
33 | {
34 | $cacheKey = 'test_key';
35 | $data = 'test_data';
36 |
37 | $this->cache->putCache($cacheKey, $data);
38 | $this->assertTrue($this->cache->isSuccess());
39 | $this->assertEquals('Cache file created successfully', $this->cache->getMessage());
40 |
41 | $cacheFile = $this->cacheDir . '/' . md5($cacheKey) . '.cache';
42 | $this->assertFileExists($cacheFile);
43 | $this->assertEquals($data, $this->cache->getCache($cacheKey));
44 | }
45 |
46 | public function testGetCache()
47 | {
48 | $cacheKey = 'test_key';
49 | $data = 'test_data';
50 |
51 | $this->cache->putCache($cacheKey, $data);
52 |
53 | $cachedData = $this->cache->getCache($cacheKey);
54 | $this->assertTrue($this->cache->isSuccess());
55 | $this->assertEquals($data, $cachedData);
56 |
57 | // Recuperar cache fora do período de expiração
58 | sleep(2);
59 | $cachedData = $this->cache->getCache($cacheKey, '', '2 seconds');
60 | $this->assertFalse($this->cache->isSuccess());
61 | $this->assertEquals('cacheFile not found, does not exists or expired', $this->cache->getMessage());
62 | }
63 |
64 | public function testClearCache()
65 | {
66 | $cacheKey = 'test_key';
67 | $data = 'test_data';
68 |
69 | $this->cache->putCache($cacheKey, $data);
70 | $this->cache->clearCache($cacheKey);
71 |
72 | $this->assertTrue($this->cache->isSuccess());
73 | $this->assertEquals('Cache file deleted successfully!', $this->cache->getMessage());
74 |
75 | $cacheFile = $this->cacheDir . '/' . md5($cacheKey) . '.cache';
76 | $this->assertFileDoesNotExist($cacheFile);
77 | }
78 |
79 | public function testFlushCache()
80 | {
81 | $key1 = 'test_key1';
82 | $data1 = 'test_data1';
83 |
84 | $key2 = 'test_key2';
85 | $data2 = 'test_data2';
86 |
87 | $this->cache->putCache($key1, $data1);
88 | $this->cache->putCache($key2, $data2);
89 | $this->cache->flushCache();
90 |
91 | $cacheFile1 = $this->cacheDir . '/' . md5($key1) . '.cache';
92 | $cacheFile2 = $this->cacheDir . '/' . md5($key2) . '.cache';
93 |
94 | $this->assertFileDoesNotExist($cacheFile1);
95 | $this->assertFileDoesNotExist($cacheFile2);
96 | }
97 |
98 | public function testAutoFlush()
99 | {
100 | $options = [
101 | 'cacheDir' => $this->cacheDir,
102 | 'flushAfter' => '10 seconds'
103 | ];
104 |
105 | $this->cache = new Cacheer($options);
106 | $this->cache->putCache('test_key', 'test_data');
107 |
108 | // Verifica se o cache foi criado com sucesso
109 | $this->assertEquals('test_data', $this->cache->getCache('test_key'));
110 | $this->assertTrue($this->cache->isSuccess());
111 |
112 | // Espera 11 segundos para o cache ser limpo automaticamente
113 | sleep(11);
114 |
115 | $this->cache = new Cacheer($options);
116 |
117 | // Verifica se o cache foi limpo automaticamente
118 | $cachedData = $this->cache->getCache('test_key');
119 | $this->assertFalse($this->cache->isSuccess());
120 | $this->assertEquals('cacheFile not found, does not exists or expired', $this->cache->getMessage());
121 | }
122 |
123 | public function testAppendCache()
124 | {
125 | $cacheKey = 'test_append_key';
126 | $initialData = ['initial' => 'data'];
127 | $additionalData = ['new' => 'data'];
128 | $expectedData = array_merge($initialData, $additionalData);
129 |
130 | // Armazena os dados iniciais no cache
131 | $this->cache->putCache($cacheKey, $initialData);
132 | $this->assertTrue($this->cache->isSuccess());
133 |
134 | // Adiciona novos dados ao cache existente
135 | $this->cache->appendCache($cacheKey, $additionalData);
136 | $this->assertTrue($this->cache->isSuccess());
137 |
138 | // Verifica se os dados no cache são os esperados
139 | $cachedData = $this->cache->getCache($cacheKey);
140 | $this->assertEquals($expectedData, $cachedData);
141 |
142 | // Testa adicionar dados como string
143 | $additionalData = ['string_data' => 'string data'];
144 | $expectedData = array_merge($expectedData, $additionalData);
145 | $this->cache->appendCache($cacheKey, $additionalData);
146 | $cachedData = $this->cache->getCache($cacheKey);
147 | $this->assertEquals($expectedData, $cachedData);
148 | }
149 |
150 | public function testAppendCacheFileNotExists()
151 | {
152 | $cacheKey = 'non_existing_key';
153 | $data = ['data'];
154 |
155 | // Tenta adicionar dados a um arquivo de cache que não existe
156 | $this->cache->appendCache($cacheKey, $data);
157 | $this->assertFalse($this->cache->isSuccess());
158 | $this->assertEquals('cacheFile not found, does not exists or expired', $this->cache->getMessage());
159 | }
160 |
161 | public function testAppendCacheWithNamespace()
162 | {
163 | $cacheKey = 'test_append_key_ns';
164 | $namespace = 'test_namespace';
165 |
166 | $initialData = ['initial' => 'data'];
167 | $additionalData = ['new' => 'data'];
168 |
169 | $expectedData = array_merge($initialData, $additionalData);
170 |
171 | // Armazena os dados iniciais no cache com namespace
172 | $this->cache->putCache($cacheKey, $initialData, $namespace);
173 | $this->assertTrue($this->cache->isSuccess());
174 |
175 | // Adiciona novos dados ao cache existente com namespace
176 | $this->cache->appendCache($cacheKey, $additionalData, $namespace);
177 | $this->assertTrue($this->cache->isSuccess());
178 |
179 | // Verifica se os dados no cache são os esperados
180 | $cachedData = $this->cache->getCache($cacheKey, $namespace);
181 | $this->assertEquals($expectedData, $cachedData);
182 | }
183 |
184 | public function testDataOutputShouldBeOfTypeJson()
185 | {
186 | $options = [
187 | 'cacheDir' => $this->cacheDir
188 | ];
189 | $this->cache = new Cacheer($options, true);
190 |
191 | $cacheKey = "key_json";
192 | $cacheData = "data_json";
193 |
194 | $this->cache->putCache($cacheKey, $cacheData);
195 | $this->assertTrue($this->cache->isSuccess());
196 |
197 | $cacheOutput = $this->cache->getCache($cacheKey)->toJson();
198 | $this->assertTrue($this->cache->isSuccess());
199 | $this->assertJson($cacheOutput);
200 | }
201 |
202 | public function testDataOutputShouldBeOfTypeArray()
203 | {
204 | $options = [
205 | 'cacheDir' => $this->cacheDir
206 | ];
207 | $this->cache = new Cacheer($options, true);
208 |
209 | $cacheKey = "key_array";
210 | $cacheData = "data_array";
211 |
212 | $this->cache->putCache($cacheKey, $cacheData);
213 | $this->assertTrue($this->cache->isSuccess());
214 |
215 | $cacheOutput = $this->cache->getCache($cacheKey)->toArray();
216 | $this->assertTrue($this->cache->isSuccess());
217 | $this->assertIsArray($cacheOutput);
218 | }
219 |
220 | public function testDataOutputShouldBeOfTypeObject()
221 | {
222 | $options = [
223 | 'cacheDir' => $this->cacheDir
224 | ];
225 | $this->cache = new Cacheer($options, true);
226 |
227 | $cacheKey = "key_object";
228 | $cacheData = ["id" => 123];
229 |
230 | $this->cache->putCache($cacheKey, $cacheData);
231 | $this->assertTrue($this->cache->isSuccess());
232 |
233 | $cacheOutput = $this->cache->getCache($cacheKey)->toObject();
234 | $this->assertTrue($this->cache->isSuccess());
235 | $this->assertIsObject($cacheOutput);
236 | }
237 |
238 | public function testPutMany()
239 | {
240 | $cacheer = new Cacheer(['cacheDir' => __DIR__ . '/cache']);
241 | $items = [
242 | [
243 | 'cacheKey' => 'user_1_profile',
244 | 'cacheData' => ['name' => 'John Doe', 'email' => 'john@example.com']
245 | ],
246 | [
247 | 'cacheKey' => 'user_2_profile',
248 | 'cacheData' => ['name' => 'Jane Doe', 'email' => 'jane@example.com']
249 | ],
250 | ];
251 |
252 | $cacheer->putMany($items);
253 |
254 | foreach ($items as $item) {
255 | $this->assertEquals($item['cacheData'], $cacheer->getCache($item['cacheKey']));
256 | }
257 | }
258 |
259 | public function test_remember_saves_and_recover_values()
260 | {
261 | $this->cache->flushCache();
262 |
263 | $value = $this->cache->remember('remember_test_key', 60, function () {
264 | return 'valor_teste';
265 | });
266 |
267 | $this->assertEquals('valor_teste', $value);
268 |
269 | $cachedValue = $this->cache->remember('remember_test_key', 60, function (){
270 | return 'novo_valor';
271 | });
272 |
273 |
274 | $this->assertEquals('valor_teste', $cachedValue);
275 | }
276 |
277 | public function test_remember_forever_saves_value_indefinitely()
278 | {
279 | $this->cache->flushCache();
280 |
281 | $value = $this->cache->rememberForever('remember_forever_key', function () {
282 | return 'valor_eterno';
283 | });
284 | $this->assertEquals('valor_eterno', $value);
285 |
286 | $cachedValue = $this->cache->rememberForever('remember_forever_key', function () {
287 | return 'novo_valor';
288 | });
289 |
290 | $this->assertEquals('valor_eterno', $cachedValue);
291 | }
292 |
293 | public function test_get_and_forget()
294 | {
295 | $cacheKey = 'cache_key_test';
296 | $this->cache->putCache($cacheKey, 10);
297 |
298 | $this->assertTrue($this->cache->isSuccess());
299 |
300 | $cacheData = $this->cache->getAndForget($cacheKey);
301 |
302 | $this->assertTrue($this->cache->isSuccess());
303 | $this->assertEquals(10, $cacheData);
304 |
305 | $oldCacheData = $this->cache->getAndForget($cacheKey);
306 |
307 | $this->assertNull($oldCacheData);
308 | $this->assertFalse($this->cache->isSuccess());
309 |
310 | $noCacheData = $this->cache->getAndForget('non_existent_cache_key');
311 | $this->assertNull($noCacheData);
312 | }
313 |
314 | public function test_store_if_not_present_with_add_function()
315 | {
316 | $existentKey = 'cache_key_test';
317 |
318 | $nonExistentKey = 'non_existent_key';
319 |
320 | $this->cache->putCache($existentKey, 'existent_data');
321 |
322 | $this->assertTrue($this->cache->isSuccess());
323 | $this->assertEquals('existent_data', $this->cache->getCache($existentKey));
324 |
325 | $addCache = $this->cache->add($existentKey, 100);
326 |
327 | $this->assertTrue($addCache);
328 | $this->assertNotEquals(100, 'existent_data');
329 |
330 | $addNonExistentKey = $this->cache->add($nonExistentKey, 'non_existent_data');
331 |
332 | $this->assertFalse($addNonExistentKey);
333 | $this->assertEquals('non_existent_data', $this->cache->getCache($nonExistentKey));
334 | $this->assertTrue($this->cache->isSuccess());
335 |
336 | }
337 |
338 | public function test_increment_function() {
339 |
340 | $cacheKey = 'test_increment';
341 | $cacheData = 2025;
342 |
343 | $this->cache->putCache($cacheKey, $cacheData);
344 |
345 | $this->assertTrue($this->cache->isSuccess());
346 | $this->assertEquals($cacheData, $this->cache->getCache($cacheKey));
347 | $this->assertIsNumeric($this->cache->getCache($cacheKey));
348 |
349 | $increment = $this->cache->increment($cacheKey, 2);
350 | $this->assertTrue($increment);
351 |
352 | $this->assertEquals(2027, $this->cache->getCache($cacheKey));
353 |
354 | }
355 |
356 | public function test_decrement_function() {
357 |
358 | $cacheKey = 'test_decrement';
359 | $cacheData = 2027;
360 |
361 | $this->cache->putCache($cacheKey, $cacheData);
362 |
363 | $this->assertTrue($this->cache->isSuccess());
364 | $this->assertEquals($cacheData, $this->cache->getCache($cacheKey));
365 | $this->assertIsNumeric($this->cache->getCache($cacheKey));
366 |
367 | $increment = $this->cache->decrement($cacheKey, 2);
368 | $this->assertTrue($increment);
369 |
370 | $this->assertEquals(2025, $this->cache->getCache($cacheKey));
371 |
372 | }
373 |
374 | private function removeDirectoryRecursively($dir)
375 | {
376 | if (!is_dir($dir)) {
377 | return;
378 | }
379 | $items = scandir($dir);
380 | foreach ($items as $item) {
381 | if ($item === '.' || $item === '..') {
382 | continue;
383 | }
384 | $path = $dir . DIRECTORY_SEPARATOR . $item;
385 | if (is_dir($path)) {
386 | $this->removeDirectoryRecursively($path);
387 | } else {
388 | unlink($path);
389 | }
390 | }
391 | rmdir($dir);
392 | }
393 |
394 | public function testUseDefaultDriverCreatesCacheDirInProjectRoot()
395 | {
396 | $cacheer = new Cacheer();
397 | $driver = new CacheDriver($cacheer);
398 |
399 | $projectRoot = EnvHelper::getRootPath();
400 | $expectedCacheDir = $projectRoot . DIRECTORY_SEPARATOR . "CacheerPHP" . DIRECTORY_SEPARATOR . "Cache";
401 |
402 | if (is_dir($expectedCacheDir)) {
403 | $this->removeDirectoryRecursively($expectedCacheDir);
404 | }
405 |
406 | $driver->useDefaultDriver();
407 |
408 | $this->assertDirectoryExists($expectedCacheDir);
409 |
410 | if (is_dir($expectedCacheDir)) {
411 | $this->removeDirectoryRecursively($expectedCacheDir);
412 | }
413 | }
414 |
415 | public function testPutCacheWithNamespace()
416 | {
417 | $cacheKey = 'namespace_key';
418 | $data = 'namespace_data';
419 | $namespace = 'my_namespace';
420 |
421 | $this->cache->putCache($cacheKey, $data, $namespace);
422 | $this->assertTrue($this->cache->isSuccess());
423 |
424 | $cachedData = $this->cache->getCache($cacheKey, $namespace);
425 | $this->assertEquals($data, $cachedData);
426 | }
427 |
428 | public function testClearCacheWithNamespace()
429 | {
430 | $cacheKey = 'namespace_key_clear';
431 | $data = 'namespace_data_clear';
432 | $namespace = 'clear_namespace';
433 |
434 | $this->cache->putCache($cacheKey, $data, $namespace);
435 | $this->assertTrue($this->cache->isSuccess());
436 |
437 | $this->cache->clearCache($cacheKey, $namespace);
438 | $this->assertTrue($this->cache->isSuccess());
439 |
440 | $cachedData = $this->cache->getCache($cacheKey, $namespace);
441 | $this->assertFalse($this->cache->isSuccess());
442 | $this->assertNull($cachedData);
443 | }
444 |
445 | public function testFlushCacheRemovesNamespacedFiles()
446 | {
447 | $cacheKey = 'ns_flush_key';
448 | $data = 'ns_flush_data';
449 | $namespace = 'flush_namespace';
450 |
451 | $this->cache->putCache($cacheKey, $data, $namespace);
452 | $this->assertTrue($this->cache->isSuccess());
453 |
454 | $this->cache->flushCache();
455 |
456 | $cachedData = $this->cache->getCache($cacheKey, $namespace);
457 | $this->assertFalse($this->cache->isSuccess());
458 | $this->assertNull($cachedData);
459 | }
460 |
461 | public function testAppendCacheWithDifferentTypes()
462 | {
463 | $cacheKey = 'append_type_key';
464 | $initialData = ['a' => 1];
465 | $additionalData = ['b' => 2];
466 | $expectedData = ['a' => 1, 'b' => 2];
467 |
468 | $this->cache->putCache($cacheKey, $initialData);
469 | $this->cache->appendCache($cacheKey, $additionalData);
470 | $this->assertEquals($expectedData, $this->cache->getCache($cacheKey));
471 |
472 | $this->cache->appendCache($cacheKey, ['c' => 'string']);
473 | $expectedData['c'] = 'string';
474 | $this->assertEquals($expectedData, $this->cache->getCache($cacheKey));
475 | }
476 |
477 | }
478 |
--------------------------------------------------------------------------------
/tests/Unit/RedisCacheStoreTest.php:
--------------------------------------------------------------------------------
1 | cache = new Cacheer();
16 | $this->cache->setDriver()->useRedisDriver();
17 | }
18 |
19 | protected function tearDown(): void
20 | {
21 | $this->cache->flushCache();
22 | }
23 |
24 | public function testUsingRedisDriverSetsProperInstance()
25 | {
26 | $this->assertInstanceOf(RedisCacheStore::class, $this->cache->cacheStore);
27 | }
28 |
29 | public function testPutCacheInRedis()
30 | {
31 | $cacheKey = 'test_key';
32 | $cacheData = ['name' => 'Sílvio Silva', 'role' => 'Developer'];
33 |
34 | $this->cache->putCache($cacheKey, $cacheData);
35 |
36 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
37 | $this->assertNotEmpty($this->cache->getCache($cacheKey));
38 | $this->assertEquals($cacheData, $this->cache->getCache($cacheKey));
39 |
40 | }
41 |
42 | public function testGetCacheFromRedis()
43 | {
44 | $cacheKey = 'test_key';
45 | $cacheData = ['name' => 'Sílvio Silva', 'role' => 'Developer'];
46 |
47 | $this->cache->putCache($cacheKey, $cacheData);
48 |
49 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
50 |
51 | $data = $this->cache->getCache($cacheKey);
52 | $this->assertNotEmpty($data);
53 | $this->assertEquals($cacheData, $data);
54 | }
55 |
56 | public function testExpiredCacheInRedis()
57 | {
58 | $cacheKey = 'expired_key';
59 | $cacheData = ['name' => 'Expired User', 'email' => 'expired@example.com'];
60 |
61 | $this->cache->putCache($cacheKey, $cacheData, '', 1);
62 | sleep(3);
63 |
64 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
65 | $this->assertEmpty($this->cache->getCache($cacheKey));
66 | $this->assertFalse($this->cache->isSuccess());
67 | }
68 |
69 | public function testOverwriteExistingCacheInRedis()
70 | {
71 | $cacheKey = 'overwrite_key';
72 | $initialCacheData = ['name' => 'Initial Data', 'email' => 'initial@example.com'];
73 | $newCacheData = ['name' => 'New Data', 'email' => 'new@example.com'];
74 |
75 | $this->cache->putCache($cacheKey, $initialCacheData);
76 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
77 |
78 | $this->cache->appendCache($cacheKey, $newCacheData);
79 | $this->assertEquals("Cache appended successfully", $this->cache->getMessage());
80 | $this->assertEquals($newCacheData, $this->cache->getCache($cacheKey));
81 | }
82 |
83 | public function testPutManyCacheItemsInRedis()
84 | {
85 | $items = [
86 | [
87 | 'cacheKey' => 'user_1_profile',
88 | 'cacheData' => [
89 | ['name' => 'John Doe', 'email' => 'john@example.com'],
90 | ['name' => 'John Doe', 'email' => 'john@example.com'],
91 | ['name' => 'John Doe', 'email' => 'john@example.com'],
92 | ['name' => 'John Doe', 'email' => 'john@example.com']
93 | ]
94 | ],
95 | [
96 | 'cacheKey' => 'user_2_profile',
97 | 'cacheData' => [
98 | ['name' => 'Jane Doe', 'email' => 'jane@example.com'],
99 | ['name' => 'Jane Doe', 'email' => 'jane@example.com'],
100 | ['name' => 'Jane Doe', 'email' => 'jane@example.com'],
101 | ['name' => 'Jane Doe', 'email' => 'jane@example.com']
102 | ]
103 | ]
104 | ];
105 |
106 | $this->cache->putMany($items);
107 | foreach ($items as $item) {
108 | $this->assertEquals($item['cacheData'], $this->cache->getCache($item['cacheKey']));
109 | }
110 | }
111 |
112 | public function testAppendCacheWithNamespaceInRedis()
113 | {
114 | $cacheKey = 'test_append_key_ns';
115 | $namespace = 'test_namespace';
116 |
117 | $initialData = ['initial' => 'data'];
118 | $additionalData = ['new' => 'data'];
119 |
120 | $expectedData = array_merge($initialData, $additionalData);
121 |
122 |
123 | $this->cache->putCache($cacheKey, $initialData, $namespace);
124 | $this->assertTrue($this->cache->isSuccess());
125 |
126 |
127 | $this->cache->appendCache($cacheKey, $additionalData, $namespace);
128 | $this->assertTrue($this->cache->isSuccess());
129 |
130 |
131 | $cachedData = $this->cache->getCache($cacheKey, $namespace);
132 | $this->assertEquals($expectedData, $cachedData);
133 | }
134 |
135 | public function testDataOutputShouldBeOfTypeArray()
136 | {
137 |
138 | $this->cache->useFormatter();
139 |
140 | $cacheKey = "key_array";
141 | $cacheData = "data_array";
142 |
143 | $this->cache->putCache($cacheKey, $cacheData);
144 | $this->assertTrue($this->cache->isSuccess());
145 |
146 | $cacheOutput = $this->cache->getCache($cacheKey)->toArray();
147 | $this->assertTrue($this->cache->isSuccess());
148 | $this->assertIsArray($cacheOutput);
149 | }
150 |
151 | public function testDataOutputShouldBeOfTypeObject()
152 | {
153 | $this->cache->useFormatter();
154 |
155 | $cacheKey = "key_object";
156 | $cacheData = ["id" => 123];
157 |
158 | $this->cache->putCache($cacheKey, $cacheData);
159 | $this->assertTrue($this->cache->isSuccess());
160 |
161 | $cacheOutput = $this->cache->getCache($cacheKey)->toObject();
162 | $this->assertTrue($this->cache->isSuccess());
163 | $this->assertIsObject($cacheOutput);
164 | }
165 |
166 | public function testDataOutputShouldBeOfTypeJson()
167 | {
168 | $this->cache->useFormatter();
169 |
170 | $cacheKey = "key_json";
171 | $cacheData = "data_json";
172 |
173 | $this->cache->putCache($cacheKey, $cacheData);
174 | $this->assertTrue($this->cache->isSuccess());
175 |
176 | $cacheOutput = $this->cache->getCache($cacheKey)->toJson();
177 | $this->assertTrue($this->cache->isSuccess());
178 | $this->assertJson($cacheOutput);
179 | }
180 |
181 | public function testClearCacheDataFromRedis()
182 | {
183 | $cacheKey = 'test_key';
184 | $data = 'test_data';
185 |
186 | $this->cache->putCache($cacheKey, $data);
187 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
188 |
189 | $this->cache->clearCache($cacheKey);
190 | $this->assertTrue($this->cache->isSuccess());
191 | $this->assertEquals("Cache cleared successfully", $this->cache->getMessage());
192 |
193 | $this->assertEmpty($this->cache->getCache($cacheKey));
194 | }
195 |
196 | public function testFlushCacheDataFromRedis()
197 | {
198 | $key1 = 'test_key1';
199 | $data1 = 'test_data1';
200 |
201 | $key2 = 'test_key2';
202 | $data2 = 'test_data2';
203 |
204 | $this->cache->putCache($key1, $data1);
205 | $this->cache->putCache($key2, $data2);
206 | $this->assertTrue($this->cache->isSuccess());
207 | $this->assertTrue($this->cache->isSuccess());
208 |
209 | $this->cache->flushCache();
210 |
211 | $this->assertTrue($this->cache->isSuccess());
212 | $this->assertEquals("Cache flushed successfully", $this->cache->getMessage());
213 | }
214 |
215 | public function testHasCacheFromRedis()
216 | {
217 | $cacheKey = 'test_key';
218 | $cacheData = ['name' => 'Sílvio Silva', 'role' => 'Developer'];
219 |
220 | $this->cache->putCache($cacheKey, $cacheData);
221 |
222 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
223 | $this->assertTrue($this->cache->isSuccess());
224 | }
225 |
226 | public function testRenewCacheFromRedis()
227 | {
228 | $cacheKey = 'expired_key';
229 | $cacheData = ['name' => 'Expired User', 'email' => 'expired@example.com'];
230 |
231 | // Define TTL de 10 seg para que a chave ainda exista quando renovarmos
232 | $this->cache->putCache($cacheKey, $cacheData, '', 120);
233 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
234 | sleep(2);
235 |
236 | // Verifica que a chave existe antes de renovar
237 | $this->assertNotEmpty($this->cache->getCache($cacheKey));
238 |
239 | $this->cache->renewCache($cacheKey, 7200);
240 | $this->assertTrue($this->cache->isSuccess());
241 | $this->assertNotEmpty($this->cache->getCache($cacheKey));
242 | }
243 |
244 | public function testRenewCacheWithNamespaceFromRedis()
245 | {
246 | $cacheKey = 'expired_key';
247 | $namespace = 'expired_namespace';
248 | $cacheData = ['name' => 'Expired User', 'email' => 'expired@example.com'];
249 |
250 | $this->cache->putCache($cacheKey, $cacheData, $namespace, 120);
251 | $this->assertEquals("Cache stored successfully", $this->cache->getMessage());
252 | sleep(2);
253 |
254 | $this->assertNotEmpty($this->cache->getCache($cacheKey, $namespace));
255 |
256 | $this->cache->renewCache($cacheKey, 7200, $namespace);
257 | $this->assertTrue($this->cache->isSuccess());
258 | $this->assertNotEmpty($this->cache->getCache($cacheKey, $namespace));
259 | }
260 |
261 | public function test_remember_saves_and_recover_values()
262 | {
263 | $this->cache->flushCache();
264 |
265 | $value = $this->cache->remember('remember_test_key', 60, function () {
266 | return 'valor_teste';
267 | });
268 |
269 | $this->assertEquals('valor_teste', $value);
270 |
271 | $cachedValue = $this->cache->remember('remember_test_key', 60, function (){
272 | return 'novo_valor';
273 | });
274 |
275 |
276 | $this->assertEquals('valor_teste', $cachedValue);
277 | }
278 |
279 | public function test_remember_forever_saves_value_indefinitely()
280 | {
281 | $this->cache->flushCache();
282 |
283 | $value = $this->cache->rememberForever('remember_forever_key', function () {
284 | return 'valor_eterno';
285 | });
286 | $this->assertEquals('valor_eterno', $value);
287 |
288 | $cachedValue = $this->cache->rememberForever('remember_forever_key', function () {
289 | return 'novo_valor';
290 | });
291 |
292 | $this->assertEquals('valor_eterno', $cachedValue);
293 | }
294 |
295 |
296 | public function test_get_and_forget()
297 | {
298 | $cacheKey = 'cache_key_test';
299 | $this->cache->putCache($cacheKey, 10);
300 |
301 | $this->assertTrue($this->cache->isSuccess());
302 |
303 | $cacheData = $this->cache->getAndForget($cacheKey);
304 |
305 | $this->assertTrue($this->cache->isSuccess());
306 | $this->assertEquals(10, $cacheData);
307 |
308 | $oldCacheData = $this->cache->getAndForget($cacheKey);
309 |
310 | $this->assertNull($oldCacheData);
311 | $this->assertFalse($this->cache->isSuccess());
312 |
313 | $noCacheData = $this->cache->getAndForget('non_existent_cache_key');
314 | $this->assertNull($noCacheData);
315 | }
316 |
317 | public function test_store_if_not_present_with_add_function()
318 | {
319 | $existentKey = 'cache_key_test';
320 |
321 | $nonExistentKey = 'non_existent_key';
322 |
323 | $this->cache->putCache($existentKey, 'existent_data');
324 |
325 | $this->assertTrue($this->cache->isSuccess());
326 | $this->assertEquals('existent_data', $this->cache->getCache($existentKey));
327 |
328 | $addCache = $this->cache->add($existentKey, 100);
329 |
330 | $this->assertTrue($addCache);
331 | $this->assertNotEquals(100, 'existent_data');
332 |
333 | $addNonExistentKey = $this->cache->add($nonExistentKey, 'non_existent_data');
334 |
335 | $this->assertFalse($addNonExistentKey);
336 | $this->assertEquals('non_existent_data', $this->cache->getCache($nonExistentKey));
337 | $this->assertTrue($this->cache->isSuccess());
338 |
339 | }
340 |
341 | public function test_increment_function() {
342 |
343 | $cacheKey = 'test_increment';
344 | $cacheData = 2025;
345 |
346 | $this->cache->putCache($cacheKey, $cacheData);
347 |
348 | $this->assertTrue($this->cache->isSuccess());
349 | $this->assertEquals($cacheData, $this->cache->getCache($cacheKey));
350 | $this->assertIsNumeric($this->cache->getCache($cacheKey));
351 |
352 | $increment = $this->cache->increment($cacheKey, 2);
353 | $this->assertTrue($increment);
354 |
355 | $this->assertEquals(2027, $this->cache->getCache($cacheKey));
356 |
357 | }
358 |
359 | public function test_decrement_function() {
360 |
361 | $cacheKey = 'test_decrement';
362 | $cacheData = 2027;
363 |
364 | $this->cache->putCache($cacheKey, $cacheData);
365 |
366 | $this->assertTrue($this->cache->isSuccess());
367 | $this->assertEquals($cacheData, $this->cache->getCache($cacheKey));
368 | $this->assertIsNumeric($this->cache->getCache($cacheKey));
369 |
370 | $increment = $this->cache->decrement($cacheKey, 2);
371 | $this->assertTrue($increment);
372 |
373 | $this->assertEquals(2025, $this->cache->getCache($cacheKey));
374 |
375 | }
376 |
377 | }
378 |
--------------------------------------------------------------------------------
/tests/Unit/SecurityFeatureTest.php:
--------------------------------------------------------------------------------
1 | cacheDir = __DIR__ . '/cache';
14 | if (!is_dir($this->cacheDir)) {
15 | mkdir($this->cacheDir, 0755, true);
16 | }
17 |
18 | $this->cache = new Cacheer(['cacheDir' => $this->cacheDir]);
19 | }
20 |
21 | protected function tearDown(): void
22 | {
23 | $this->cache->flushCache();
24 | }
25 |
26 | public function testCompressionFeature()
27 | {
28 | $this->cache->useCompression();
29 | $data = ['foo' => 'bar'];
30 |
31 | $this->cache->putCache('compression_key', $data);
32 | $this->assertTrue($this->cache->isSuccess());
33 |
34 | $cached = $this->cache->getCache('compression_key');
35 | $this->assertEquals($data, $cached);
36 | }
37 |
38 | public function testEncryptionFeature()
39 | {
40 | $this->cache->useEncryption('secret');
41 | $data = ['foo' => 'bar'];
42 |
43 | $this->cache->putCache('encryption_key', $data);
44 | $this->assertTrue($this->cache->isSuccess());
45 |
46 | $cached = $this->cache->getCache('encryption_key');
47 | $this->assertEquals($data, $cached);
48 | }
49 |
50 | public function testCompressionAndEncryptionTogether()
51 | {
52 | $this->cache->useCompression();
53 | $this->cache->useEncryption('secret');
54 | $data = ['foo' => 'bar'];
55 |
56 | $this->cache->putCache('secure_key', $data);
57 | $this->assertTrue($this->cache->isSuccess());
58 |
59 | $cached = $this->cache->getCache('secure_key');
60 | $this->assertEquals($data, $cached);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------