From ce8d8854edc0a7e02f7c14367c6751914e3a28fd Mon Sep 17 00:00:00 2001 From: Ibrahim Date: Sun, 15 Dec 2024 20:14:21 +0300 Subject: [PATCH 1/4] ci: Drop Support for PHP 7 --- .github/workflows/php70.yml | 42 --------------------------------- .github/workflows/php71.yml | 42 --------------------------------- .github/workflows/php72.yml | 44 ----------------------------------- .github/workflows/php73.yml | 46 ------------------------------------- .github/workflows/php74.yml | 44 ----------------------------------- 5 files changed, 218 deletions(-) delete mode 100644 .github/workflows/php70.yml delete mode 100644 .github/workflows/php71.yml delete mode 100644 .github/workflows/php72.yml delete mode 100644 .github/workflows/php73.yml delete mode 100644 .github/workflows/php74.yml diff --git a/.github/workflows/php70.yml b/.github/workflows/php70.yml deleted file mode 100644 index b9f8564..0000000 --- a/.github/workflows/php70.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Build PHP 7.0 - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: true - matrix: - os: [ ubuntu-latest ] - php: [7.0] - - name: PHP${{matrix.php}} - ${{matrix.os}} - - steps: - - name: Clone Repo - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: mbstring - tools: phpunit:5.7.27, composer - - - name: Install Dependencies - run: composer install --prefer-dist --no-interaction --no-dev - - - name: Execute Tests - run: phpunit --configuration tests/phpunit.xml - - - name: CodeCov - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - - \ No newline at end of file diff --git a/.github/workflows/php71.yml b/.github/workflows/php71.yml deleted file mode 100644 index 6add5f1..0000000 --- a/.github/workflows/php71.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Build PHP 7.1 - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - test: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: true - matrix: - os: [ ubuntu-latest ] - php: [7.1] - - name: PHP${{matrix.php}} - ${{matrix.os}} - - steps: - - name: Clone Repo - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: mysqli, mbstring, sqlsrv - tools: phpunit:5.7.27, composer - - - - name: Install Dependencies - run: composer install --prefer-dist --no-interaction --no-dev - - - name: Execute Tests - run: phpunit --configuration tests/phpunit.xml - - - name: CodeCov - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/php72.yml b/.github/workflows/php72.yml deleted file mode 100644 index 2e92f8f..0000000 --- a/.github/workflows/php72.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Build PHP 7.2 - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - test: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: true - matrix: - os: [ ubuntu-latest ] - php: [7.2] - - name: PHP${{matrix.php}} - ${{matrix.os}} - - steps: - - name: Clone Repo - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: mysqli, mbstring, sqlsrv - tools: phpunit:8.5.13 - - - - name: Install Dependencies - run: composer install --prefer-dist --no-interaction --no-dev - - - name: Execute Tests - run: phpunit --configuration tests/phpunit.xml - - - name: CodeCov - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - - diff --git a/.github/workflows/php73.yml b/.github/workflows/php73.yml deleted file mode 100644 index a8ff0c9..0000000 --- a/.github/workflows/php73.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Build PHP 7.3 - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - test: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: true - matrix: - os: [ ubuntu-latest ] - php: [7.3] - - name: PHP${{matrix.php}} - ${{matrix.os}} - - steps: - - name: Clone Repo - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: mysqli, mbstring, sqlsrv - tools: phpunit:8.5.13 - - - - name: Install Dependencies - run: composer install --prefer-dist --no-interaction --no-dev - - - name: Execute Tests - run: phpunit --configuration tests/phpunit.xml - - - name: CodeCov - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - - - - diff --git a/.github/workflows/php74.yml b/.github/workflows/php74.yml deleted file mode 100644 index 1db238a..0000000 --- a/.github/workflows/php74.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Build PHP 7.4 - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - test: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: true - matrix: - os: [ ubuntu-latest ] - php: [7.4] - - name: PHP${{matrix.php}} - ${{matrix.os}} - - steps: - - name: Clone Repo - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: mysqli, mbstring, sqlsrv - tools: phpunit:8.5.13 - - - name: Install Dependencies - run: composer install --prefer-dist --no-interaction --no-dev - - - name: Execute Tests - run: phpunit --configuration tests/phpunit.xml - - - name: CodeCov - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - - - From 770b1054a81cedbb095a2ae7e276b9f682a49439 Mon Sep 17 00:00:00 2001 From: Ibrahim Date: Mon, 6 Jan 2025 19:21:31 +0300 Subject: [PATCH 2/4] feat: Added Support for Prefixing Cache Items --- tests/webfiori/test/cache/CacheTest.php | 53 ++++++++++++++++++++++++- webfiori/cache/Cache.php | 28 +++++++++++-- webfiori/cache/FileStorage.php | 26 ++++++------ webfiori/cache/Item.php | 20 +++++++++- webfiori/cache/Storage.php | 11 +++-- 5 files changed, 116 insertions(+), 22 deletions(-) diff --git a/tests/webfiori/test/cache/CacheTest.php b/tests/webfiori/test/cache/CacheTest.php index 6be853e..00e7992 100644 --- a/tests/webfiori/test/cache/CacheTest.php +++ b/tests/webfiori/test/cache/CacheTest.php @@ -80,7 +80,7 @@ public function test05() { foreach ($keys as $key) { $this->assertTrue(Cache::has($key)); } - Cache::flush(); + Cache::flush(null); foreach ($keys as $key) { $this->assertFalse(Cache::has($key)); } @@ -143,4 +143,55 @@ public function testSetTTL01() { $key = 'not exist cool'; $this->assertFalse(Cache::setTTL($key, 700)); } + /** + * @test + */ + public function testWithPrefix00() { + $key = 'first'; + $this->assertTrue(Cache::isEnabled()); + $data =Cache::withPrefix('ok')->get($key, function () { + return 'This is a test.'; + }); + $this->assertEquals('This is a test.', $data); + $this->assertEquals('This is a test.', Cache::get($key)); + $this->assertNull(Cache::withPrefix('')->get($key)); + Cache::delete($key); + $this->assertEquals('This is a test.', Cache::withPrefix('ok')->get($key)); + } + /** + * @test + */ + public function testWithPrefix01() { + $key = 'test-'; + $key2 = 'ttest-2-'; + $prefix1 = 'good'; + $prefix2 = 'bad'; + + for ($x = 0 ; $x < 3 ; $x++) { + Cache::withPrefix($prefix1)->get($key.$x, function (int $x, $pfx) { + return 'This is a test. '.$x.$pfx; + }, 60, [$x, $prefix1]); + } + for ($x = 0 ; $x < 3 ; $x++) { + Cache::withPrefix($prefix2)->get($key2.$x, function (int $x, $pfx) { + return 'This is a test. '.$x.$pfx; + }, 60, [$x, $prefix2]); + } + Cache::withPrefix($prefix1); + for ($x = 0 ; $x < 3 ; $x++) { + $this->assertTrue(Cache::has($key.$x)); + } + Cache::withPrefix($prefix2); + for ($x = 0 ; $x < 3 ; $x++) { + $this->assertTrue(Cache::has($key2.$x)); + } + Cache::withPrefix($prefix1)->flush(); + for ($x = 0 ; $x < 3 ; $x++) { + $this->assertFalse(Cache::has($key.$x)); + } + Cache::withPrefix($prefix2); + for ($x = 0 ; $x < 3 ; $x++) { + $this->assertTrue(Cache::has($key2.$x)); + } + } } diff --git a/webfiori/cache/Cache.php b/webfiori/cache/Cache.php index 0e3f5c5..5b253d0 100644 --- a/webfiori/cache/Cache.php +++ b/webfiori/cache/Cache.php @@ -21,6 +21,11 @@ class Cache { private $driver; private static $inst; private $isEnabled; + private $prefix; + public static function withPrefix(string $prefix) : Cache { + self::getInst()->prefix = trim($prefix); + return self::getInst(); + } /** * Removes an item from the cache given its unique identifier. * @@ -31,9 +36,19 @@ public static function delete(string $key) { } /** * Removes all items from the cache. + * + * @param string|null $prefix An optional prefix. If provided, the method should + * only delete the items which has given prefix. */ public static function flush() { - self::getDriver()->flush(); + self::getDriver()->flush(self::getPrefix()); + } + /** + * + * @return string + */ + public static function getPrefix() : string { + return self::getInst()->prefix; } /** * Returns or creates a cache item given its key. @@ -52,7 +67,7 @@ public static function flush() { * @return null */ public static function get(string $key, callable $generator = null, int $ttl = 60, array $params = []) { - $data = self::getDriver()->read($key); + $data = self::getDriver()->read($key, self::getPrefix()); if ($data !== null && $data !== false) { return $data; @@ -65,6 +80,7 @@ public static function get(string $key, callable $generator = null, int $ttl = 6 if (self::isEnabled()) { $item = new Item($key, $newData, $ttl, defined('CACHE_SECRET') ? CACHE_SECRET : ''); + $item->setPrefix(self::getPrefix()); self::getDriver()->store($item); } @@ -89,7 +105,7 @@ public static function getDriver() : Storage { * than that, null is returned. */ public static function getItem(string $key) { - return self::getDriver()->readItem($key); + return self::getDriver()->readItem($key, self::getPrefix()); } /** * Checks if the cache has in item given its unique identifier. @@ -100,7 +116,7 @@ public static function getItem(string $key) { * Other than that, false is returned. */ public static function has(string $key) : bool { - return self::getDriver()->has($key); + return self::getDriver()->has($key, self::getPrefix()); } /** * Checks if caching is enabled or not. @@ -131,6 +147,8 @@ public static function isEnabled() : bool { * otherwise. */ public static function set(string $key, $data, int $ttl = 60, bool $override = false) : bool { + $key = self::getPrefix().$key; + if (!self::has($key) || $override === true) { $item = new Item($key, $data, $ttl, defined('CACHE_SECRET') ? CACHE_SECRET : ''); self::getDriver()->store($item); @@ -169,6 +187,7 @@ public static function setEnabled(bool $enable) { * is returned. */ public static function setTTL(string $key, int $ttl) { + $key = self::getPrefix().$key; $item = self::getItem($key); if ($item === null) { @@ -189,6 +208,7 @@ private static function getInst() : Cache { self::$inst = new Cache(); self::setDriver(new FileStorage(__DIR__.DIRECTORY_SEPARATOR.'cache')); self::setEnabled(true); + self::withPrefix(''); } return self::$inst; diff --git a/webfiori/cache/FileStorage.php b/webfiori/cache/FileStorage.php index 40f14c2..f191b9a 100644 --- a/webfiori/cache/FileStorage.php +++ b/webfiori/cache/FileStorage.php @@ -44,10 +44,12 @@ public function delete(string $key) { } /** * Removes all cached items. - * + * + * @param string|null $prefix An optional prefix. If provided, the method will + * only delete the items which has given prefix. */ - public function flush() { - $files = glob($this->cacheDir.DIRECTORY_SEPARATOR.'*.cache'); + public function flush(?string $prefix) { + $files = glob($this->cacheDir.DIRECTORY_SEPARATOR.$prefix.'*.cache'); foreach ($files as $file) { unlink($file); @@ -70,8 +72,8 @@ public function getPath() : string { * @return bool Returns true if given * key exist in the cache and not yet expired. */ - public function has(string $key): bool { - return $this->read($key) !== null; + public function has(string $key, ?string $prefix): bool { + return $this->read($key, $prefix) !== null; } /** * Reads and returns the data stored in cache item given its key. @@ -81,8 +83,8 @@ public function has(string $key): bool { * @return mixed|null If cache item is not expired, its data is returned. Other than * that, null is returned. */ - public function read(string $key) { - $item = $this->readItem($key); + public function read(string $key, ?string $prefix) { + $item = $this->readItem($key, $prefix); if ($item !== null) { return $item->getDataDecrypted(); @@ -99,8 +101,8 @@ public function read(string $key) { * an object of type 'Item' is returned. Other than * that, null is returned. */ - public function readItem(string $key) { - $this->initData($key); + public function readItem(string $key, ?string $prefix) { + $this->initData($key, $prefix); $now = time(); if ($now > $this->data['expires']) { @@ -130,7 +132,7 @@ public function setPath(string $path) { */ public function store(Item $item) { if ($item->getTTL() > 0) { - $filePath = $this->getPath().DIRECTORY_SEPARATOR.md5($item->getKey()).'.cache'; + $filePath = $this->getPath().DIRECTORY_SEPARATOR.$item->getPrefix().md5($item->getKey()).'.cache'; $encryptedData = $item->getDataEncrypted(); $storageFolder = $this->getPath(); @@ -148,8 +150,8 @@ public function store(Item $item) { ])); } } - private function initData(string $key) { - $filePath = $this->cacheDir.DIRECTORY_SEPARATOR.md5($key).'.cache'; + private function initData(string $key, string $prefix) { + $filePath = $this->cacheDir.DIRECTORY_SEPARATOR.$prefix.md5($key).'.cache'; if (!file_exists($filePath)) { $this->data = [ diff --git a/webfiori/cache/Item.php b/webfiori/cache/Item.php index b628b1e..54e1d15 100644 --- a/webfiori/cache/Item.php +++ b/webfiori/cache/Item.php @@ -19,6 +19,7 @@ class Item { private $key; private $secretKey; private $timeToLive; + private $prefix; /** * Creates new instance of the class. * @@ -38,6 +39,7 @@ public function __construct(string $key = 'item', $data = '', int $ttl = 60, str $this->setData($data); $this->setSecret($secretKey); $this->setCreatedAt(time()); + $this->setPrefix(''); } /** * Generates a cryptographic secure key. @@ -102,7 +104,7 @@ public function getExpiryTime() : int { * Gets the key of the item. * * The key acts as a unique identifier for cache items. - * + * * @return string A string that represents the key. */ public function getKey() : string { @@ -156,6 +158,22 @@ public function setData($data) { public function setKey(string $key) { $this->key = $key; } + /** + * Returns the prefix that will be appended to the key. + * + * @return string If no prefix is set, empty string is returned. + */ + public function getPrefix() : string { + return $this->prefix; + } + /** + * Sets the prefix that will be appended to the key. + * + * @param string $prefix + */ + public function setPrefix(string $prefix) { + $this->prefix = trim($prefix.''); + } /** * Sets the value of the key which is used in encrypting cache data. * diff --git a/webfiori/cache/Storage.php b/webfiori/cache/Storage.php index 6be15d7..d5e2f2a 100644 --- a/webfiori/cache/Storage.php +++ b/webfiori/cache/Storage.php @@ -25,8 +25,11 @@ public function delete(string $key); * * This method must be implemented in a way that it removes all cache items * regardless of expiry time. + * + * @param string|null $prefix An optional prefix. If provided, the method should + * only delete the items which has given prefix. */ - public function flush(); + public function flush(?string $prefix); /** * Checks if an item exist in the cache. * @@ -38,7 +41,7 @@ public function flush(); * @return bool Returns true if given * key exist in the cache and not yet expired. */ - public function has(string $key) : bool; + public function has(string $key, ?string $prefix) : bool; /** * Reads and returns the data stored in cache item given its key. * @@ -52,7 +55,7 @@ public function has(string $key) : bool; * @return mixed|null If cache item is not expired, its data is returned. Other than * that, null is returned. */ - public function read(string $key); + public function read(string $key, ?string $prefix); /** * Reads cache item as an object given its key. * @@ -62,7 +65,7 @@ public function read(string $key); * an object of type 'Item' should be returned. Other than * that, null is returned. */ - public function readItem(string $key); + public function readItem(string $key, ?string $prefix); /** * Store an item into the cache. * From 479ee29abfb8e1201ac003816564e3b2edded7f4 Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Mon, 6 Jan 2025 19:28:06 +0300 Subject: [PATCH 3/4] chore: Remove PHP7 Support --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 01a1bda..3d11352 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,6 @@ Another way to include the library is by going to releases and download the late ## Supported PHP Versions | Build Status | |:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| -| | -| | -| | -| | -| | | | | | | | From e03d1d9dc3aa89bcba14d32438ccb84d629890e5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:28:54 +0000 Subject: [PATCH 4/4] chore(main): release 1.1.0 --- CHANGELOG.md | 12 ++++++++++++ composer.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ce9e5d..1061c59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [1.1.0](https://github.com/WebFiori/cache/compare/v1.0.0...v1.1.0) (2025-01-06) + + +### Features + +* Added Support for Prefixing Cache Items ([770b105](https://github.com/WebFiori/cache/commit/770b1054a81cedbb095a2ae7e276b9f682a49439)) + + +### Miscellaneous Chores + +* Remove PHP7 Support ([479ee29](https://github.com/WebFiori/cache/commit/479ee29abfb8e1201ac003816564e3b2edded7f4)) + ## 1.0.0 (2024-12-08) diff --git a/composer.json b/composer.json index 19f457c..20f9f18 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "webfiori/cache", "description": "A simple caching engine which is highly customizable.", - "version": "1.0.0", + "version": "1.1.0", "keywords": [ "Cache", "File Cache", pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy