From 84566cf5b00cfac85ab9d9abbcbbf3eb3dbd20e3 Mon Sep 17 00:00:00 2001 From: Awilum Date: Sat, 14 Aug 2021 11:00:16 +0300 Subject: [PATCH] feat(serializers): add PhpCode Serialization #569 --- src/flextype/core/Serializers/PhpCode.php | 101 ++++++++++++++++++ src/flextype/core/Serializers/Serializers.php | 9 ++ src/flextype/settings.yaml | 3 + .../flextype/core/Serializers/PhpCodeTest.php | 19 ++++ 4 files changed, 132 insertions(+) create mode 100644 src/flextype/core/Serializers/PhpCode.php create mode 100644 tests/src/flextype/core/Serializers/PhpCodeTest.php diff --git a/src/flextype/core/Serializers/PhpCode.php b/src/flextype/core/Serializers/PhpCode.php new file mode 100644 index 00000000..a1ce5019 --- /dev/null +++ b/src/flextype/core/Serializers/PhpCode.php @@ -0,0 +1,101 @@ +get('flextype.settings.serializers.phpcode.decode.cache'); + + $decode = static function (string $input) { + + $currentErrorLevel = error_reporting(); + error_reporting(E_ALL); + $return = null; + $eval = @eval('$return=' . $input . ';'); + $error = error_get_last(); + error_reporting($currentErrorLevel); + + if ($eval === false || $error) { + $msg = 'Decoding PhpCode failed'; + + if ($eval === false) { + $lastError = error_get_last(); + $msg .= ': ' . $lastError['message']; + } + + throw new RuntimeException($msg, 0, $error); + } + + return $return; + }; + + if ($cache === true && registry()->get('flextype.settings.cache.enabled') === true) { + $key = $this->getCacheID($input); + + if ($dataFromCache = cache()->get($key)) { + return $dataFromCache; + } + + $data = $decode($input); + cache()->set($key, $data); + + return $data; + } + + return $decode($input); + } + + /** + * Get Cache ID for phpcode. + * + * @param string $input Input. + * + * @return string Cache ID. + * + * @access public + */ + public function getCacheID(string $input): string + { + return strings('phpcode' . $input)->hash()->toString(); + } +} diff --git a/src/flextype/core/Serializers/Serializers.php b/src/flextype/core/Serializers/Serializers.php index ac0f6b47..ee433a7c 100644 --- a/src/flextype/core/Serializers/Serializers.php +++ b/src/flextype/core/Serializers/Serializers.php @@ -15,6 +15,7 @@ use Flextype\Serializers\Yaml; use Flextype\Serializers\Frontmatter; use Flextype\Serializers\Neon; use Flextype\Serializers\PhpArray; +use Flextype\Serializers\PhpCode; class Serializers { @@ -59,4 +60,12 @@ class Serializers { return new PhpArray(); } + + /** + * Create a PhpCode instance. + */ + public function phpcode(): PhpCode + { + return new PhpCode(); + } } diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index 3b8d05fb..ec7f98af 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -458,6 +458,9 @@ serializers: phparray: decode: cache: true + phpcode: + decode: + cache: true # Parsers # diff --git a/tests/src/flextype/core/Serializers/PhpCodeTest.php b/tests/src/flextype/core/Serializers/PhpCodeTest.php new file mode 100644 index 00000000..6b346c59 --- /dev/null +++ b/tests/src/flextype/core/Serializers/PhpCodeTest.php @@ -0,0 +1,19 @@ +assertEquals(35, strings(serializers()->phpcode()->encode(['flextype' => registry()->get("flextype.manifest.version")]))->length()); +}); + +test('test decode() method', function () { + $this->assertEquals('Flextype', serializers()->phpcode()->decode('registry()->get("flextype.manifest.name")')); +}); + +test('test getCacheID() method', function () { + $string = strings(serializers()->phpcode()->encode(['flextype' => registry()->get("flextype.manifest.version")]))->toString(); + $cache_id = serializers()->phparray() + ->getCacheID($string); + $this->assertEquals(32, strlen($cache_id)); + $this->assertNotEquals($string, $cache_id); +}); \ No newline at end of file