1
0
mirror of https://github.com/flextype/flextype.git synced 2025-08-07 21:56:33 +02:00

feat(serializers): add PhpCode Serialization #569

This commit is contained in:
Awilum
2021-08-14 11:00:16 +03:00
parent 83dc2781a1
commit 84566cf5b0
4 changed files with 132 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype\Serializers;
use RuntimeException;
use function cache;
use function registry;
use function strings;
class PhpCode
{
/**
* Returns the PhpCode representation of a value.
*
* @param mixed $input The PHP value.
*
* @return string A PhpCode string representing the original PHP value.
*/
public function encode($input): string
{
try {
$data = var_export($input, true);
} catch (Exception $e) {
throw new RuntimeException('Encoding PhpCode failed');
}
return $data;
}
/**
* Takes a PhpCode encoded string and converts it into a PHP variable.
*
* @param string $input A string containing PhpCode.
*
* @return mixed The PhpCode converted to a PHP value.
*/
public function decode(string $input)
{
$cache = registry()->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();
}
}

View File

@@ -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();
}
}

View File

@@ -458,6 +458,9 @@ serializers:
phparray:
decode:
cache: true
phpcode:
decode:
cache: true
# Parsers
#

View File

@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
test('test encode() method', function () {
$this->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);
});