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:
101
src/flextype/core/Serializers/PhpCode.php
Normal file
101
src/flextype/core/Serializers/PhpCode.php
Normal 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();
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
@@ -458,6 +458,9 @@ serializers:
|
||||
phparray:
|
||||
decode:
|
||||
cache: true
|
||||
phpcode:
|
||||
decode:
|
||||
cache: true
|
||||
|
||||
# Parsers
|
||||
#
|
||||
|
19
tests/src/flextype/core/Serializers/PhpCodeTest.php
Normal file
19
tests/src/flextype/core/Serializers/PhpCodeTest.php
Normal 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);
|
||||
});
|
Reference in New Issue
Block a user