From e67de6f300b687721b3359cdb6b0e421b26f5bdc Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 20 Aug 2022 21:27:05 +0200 Subject: [PATCH] Support for SimpleCache Interface versions 1.0, 2.0 and 3.0; to stop people moaning; even though it requires a second implementation of the Memory cache for Cells --- CHANGELOG.md | 1 + composer.json | 2 +- phpstan-baseline.neon | 5 - src/PhpSpreadsheet/Collection/Cells.php | 4 +- .../{Memory.php => Memory/SimpleCache1.php} | 7 +- .../Collection/Memory/SimpleCache3.php | 109 ++++++++++++++++++ .../Reader/Security/XmlScanner.php | 2 +- src/PhpSpreadsheet/Settings.php | 10 +- .../Collection/CellsTest.php | 10 +- 9 files changed, 137 insertions(+), 13 deletions(-) rename src/PhpSpreadsheet/Collection/{Memory.php => Memory/SimpleCache1.php} (93%) create mode 100644 src/PhpSpreadsheet/Collection/Memory/SimpleCache3.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 62fdaf91..da29bc8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). ### Added +- Support for SimpleCache Interface versions 1.0, 2.0 and 3.0 - Add Chart Axis Option textRotation [Issue #2705](https://github.com/PHPOffice/PhpSpreadsheet/issues/2705) [PR #2940](https://github.com/PHPOffice/PhpSpreadsheet/pull/2940) ### Changed diff --git a/composer.json b/composer.json index cda2dc96..46ee56b9 100644 --- a/composer.json +++ b/composer.json @@ -75,7 +75,7 @@ "markbaker/matrix": "^3.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", - "psr/simple-cache": "^1.0 || ^2.0" + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "dev-master", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index c6d769d5..7c0070d7 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1100,11 +1100,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Cell/Coordinate.php - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Memory\\:\\:\\$cache has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Collection/Memory.php - - message: "#^Parameter \\#1 \\$namedRange of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:addNamedRange\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\NamedRange, \\$this\\(PhpOffice\\\\PhpSpreadsheet\\\\DefinedName\\) given\\.$#" count: 1 diff --git a/src/PhpSpreadsheet/Collection/Cells.php b/src/PhpSpreadsheet/Collection/Cells.php index 03ad1cd4..82c9ae1a 100644 --- a/src/PhpSpreadsheet/Collection/Cells.php +++ b/src/PhpSpreadsheet/Collection/Cells.php @@ -268,7 +268,9 @@ class Cells */ private function getUniqueID() { - return Settings::getCache() instanceof Memory + $cacheType = Settings::getCache(); + + return ($cacheType instanceof Memory\SimpleCache1 || $cacheType instanceof Memory\SimpleCache3) ? random_bytes(7) . ':' : uniqid('phpspreadsheet.', true) . '.'; } diff --git a/src/PhpSpreadsheet/Collection/Memory.php b/src/PhpSpreadsheet/Collection/Memory/SimpleCache1.php similarity index 93% rename from src/PhpSpreadsheet/Collection/Memory.php rename to src/PhpSpreadsheet/Collection/Memory/SimpleCache1.php index 2690ab7d..a0eb6ec2 100644 --- a/src/PhpSpreadsheet/Collection/Memory.php +++ b/src/PhpSpreadsheet/Collection/Memory/SimpleCache1.php @@ -1,6 +1,6 @@ cache = []; + + return true; + } + + /** + * @param string $key + */ + public function delete($key): bool + { + unset($this->cache[$key]); + + return true; + } + + /** + * @param iterable $keys + */ + public function deleteMultiple($keys): bool + { + foreach ($keys as $key) { + $this->delete($key); + } + + return true; + } + + /** + * @param string $key + * @param mixed $default + */ + public function get($key, $default = null): mixed + { + if ($this->has($key)) { + return $this->cache[$key]; + } + + return $default; + } + + /** + * @param iterable $keys + * @param mixed $default + */ + public function getMultiple($keys, $default = null): iterable + { + $results = []; + foreach ($keys as $key) { + $results[$key] = $this->get($key, $default); + } + + return $results; + } + + /** + * @param string $key + */ + public function has($key): bool + { + return array_key_exists($key, $this->cache); + } + + /** + * @param string $key + * @param mixed $value + * @param null|DateInterval|int $ttl + */ + public function set($key, $value, $ttl = null): bool + { + $this->cache[$key] = $value; + + return true; + } + + /** + * @param iterable $values + * @param null|DateInterval|int $ttl + */ + public function setMultiple($values, $ttl = null): bool + { + foreach ($values as $key => $value) { + $this->set($key, $value); + } + + return true; + } +} diff --git a/src/PhpSpreadsheet/Reader/Security/XmlScanner.php b/src/PhpSpreadsheet/Reader/Security/XmlScanner.php index 8155b838..40008d01 100644 --- a/src/PhpSpreadsheet/Reader/Security/XmlScanner.php +++ b/src/PhpSpreadsheet/Reader/Security/XmlScanner.php @@ -52,7 +52,7 @@ class XmlScanner public static function threadSafeLibxmlDisableEntityLoaderAvailability() { - if (PHP_MAJOR_VERSION == 7) { + if (PHP_MAJOR_VERSION === 7) { switch (PHP_MINOR_VERSION) { case 2: return PHP_RELEASE_VERSION >= 1; diff --git a/src/PhpSpreadsheet/Settings.php b/src/PhpSpreadsheet/Settings.php index 5fbbadb6..3282a596 100644 --- a/src/PhpSpreadsheet/Settings.php +++ b/src/PhpSpreadsheet/Settings.php @@ -8,6 +8,7 @@ use PhpOffice\PhpSpreadsheet\Collection\Memory; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; use Psr\SimpleCache\CacheInterface; +use ReflectionClass; class Settings { @@ -161,12 +162,19 @@ class Settings public static function getCache(): CacheInterface { if (!self::$cache) { - self::$cache = new Memory(); + self::$cache = self::useSimpleCacheVersion3() ? new Memory\SimpleCache3() : new Memory\SimpleCache1(); } return self::$cache; } + public static function useSimpleCacheVersion3(): bool + { + return + PHP_MAJOR_VERSION === 8 && + (new ReflectionClass(CacheInterface::class))->getMethod('get')->getReturnType() !== null; + } + /** * Set the HTTP client implementation to be used for network request. */ diff --git a/tests/PhpSpreadsheetTests/Collection/CellsTest.php b/tests/PhpSpreadsheetTests/Collection/CellsTest.php index 5731d581..9e662b92 100644 --- a/tests/PhpSpreadsheetTests/Collection/CellsTest.php +++ b/tests/PhpSpreadsheetTests/Collection/CellsTest.php @@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Collection; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Collection\Cells; use PhpOffice\PhpSpreadsheet\Collection\Memory; +use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use PHPUnit\Framework\TestCase; @@ -107,7 +108,10 @@ class CellsTest extends TestCase $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); $collection = $this->getMockBuilder(Cells::class) - ->setConstructorArgs([new Worksheet(), new Memory()]) + ->setConstructorArgs([ + new Worksheet(), + Settings::useSimpleCacheVersion3() ? new Memory\SimpleCache3() : new Memory\SimpleCache1(), + ]) ->onlyMethods(['has']) ->getMock(); @@ -121,7 +125,9 @@ class CellsTest extends TestCase { $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); - $cache = $this->createMock(Memory::class); + $cache = $this->createMock( + Settings::useSimpleCacheVersion3() ? Memory\SimpleCache3::class : Memory\SimpleCache1::class + ); $cell = $this->createMock(Cell::class); $cache->method('set') ->willReturn(false);