1
0
mirror of https://github.com/flextype/flextype.git synced 2025-08-13 00:24:15 +02:00

feat(support): Simplify parsers and serializers #438

This commit is contained in:
Awilum
2020-07-22 09:29:40 +03:00
parent 9bebc79984
commit a6510f7c79
8 changed files with 461 additions and 43 deletions

View File

@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype\Support\Parsers;
use function md5;
class Markdown
{
/**
* Flextype Dependency Container
*/
private $flextype;
/**
* Markdown
*/
private $markdown;
/**
* Constructor
*
* @access public
*/
public function __construct($flextype, $markdown)
{
$this->flextype = $flextype;
$this->markdown = $markdown;
}
/**
* Takes a MARKDOWN encoded string and converts it into a PHP variable.
*
* @param string $input A string containing MARKDOWN
* @param bool $cache Cache result data or no. Default is true
*
* @return mixed The MARKDOWN converted to a PHP value
*/
public function parse(string $input, bool $cache = true) : string
{
if ($cache === true && $this->flextype['registry']->get('flextype.settings.cache.enabled') === true) {
$key = md5($input);
if ($data_from_cache = $this->flextype['cache']->fetch($key)) {
return $data_from_cache;
}
$data = $this->_parse($input);
$this->flextype['cache']->save($key, $data);
return $data;
}
return $this->_parse($input);
}
/**
* @see parse()
*/
protected function _parse(string $input) : string
{
return $this->markdown->text($input);
}
}

View File

@@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype\Support\Parsers;
use function md5;
class Shortcode
{
/**
* Flextype Dependency Container
*/
private $flextype;
/**
* Shortcode Fasade
*/
private $shortcode;
/**
* Constructor
*
* @access public
*/
public function __construct($flextype, $shortcode)
{
$this->flextype = $flextype;
$this->shortcode = $shortcode;
}
/**
* Add shortcode handler
*
* @param string $name Shortcode name
* @param $handler Handler
*/
public function add(string $name, $handler)
{
return $this->shortcode->addHandler($name, $handler);
}
/**
* Takes a SHORTCODE encoded string and converts it into a PHP variable.
*
* @param string $input A string containing SHORTCODE
* @param bool $cache Cache result data or no. Default is true
*
* @return mixed The SHORTCODE converted to a PHP value
*/
public function parse(string $input, bool $cache = true) : string
{
if ($cache === true && $this->flextype['registry']->get('flextype.settings.cache.enabled') === true) {
$key = md5($input);
if ($data_from_cache = $this->flextype['cache']->fetch($key)) {
return $data_from_cache;
}
$data = $this->_parse($input);
$this->flextype['cache']->save($key, $data);
return $data;
}
return $this->_parse($input);
}
/**
* @see parse()
*/
protected function _parse(string $input) : string
{
return $this->shortcode->process($input);
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
// Shortcode: [entries_fetch id="entry-id" field="field-name" default="default-value"]
$flextype['shortcode']->add('entries_fetch', function (ShortcodeInterface $s) use ($flextype) {
return array_get($flextype['entries']->fetch($s->getParameter('id')), $s->getParameter('field'), $s->getParameter('default'));
});

View File

@@ -7,11 +7,9 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
// Shortcode: [registry_get name="item-name" default="default-value"]
$flextype['shortcodes']->addHandler('registry_get', static function (ShortcodeInterface $s) use ($flextype) {
$flextype['shortcode']->add('registry_get', function (ShortcodeInterface $s) use ($flextype) {
return $flextype['registry']->get($s->getParameter('name'), $s->getParameter('default'));
});

View File

@@ -7,13 +7,11 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype;
use Slim\Http\Environment;
use Slim\Http\Uri;
// Shortcode: [url]
$flextype['shortcodes']->addHandler('url', static function () use ($flextype) {
$flextype['shortcode']->add('url', function () use ($flextype) {
if ($flextype['registry']->has('flextype.settings.url') && $flextype['registry']->get('flextype.settings.url') !== '') {
return $flextype['registry']->get('flextype.settings.url');
}

View File

@@ -0,0 +1,111 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype\Support\Serializers;
use function array_delete;
use function array_slice;
use function count;
use function implode;
use function ltrim;
use function md5;
use function preg_split;
use function trim;
use const PHP_EOL;
class Frontmatter
{
/**
* Flextype Dependency Container
*/
private $flextype;
/**
* Constructor
*
* @access public
*/
public function __construct($flextype)
{
$this->flextype = $flextype;
}
/**
* Returns the FRONTMATTER representation of a value
*
* @param mixed $input The PHP value
*
* @return string A FRONTMATTER string representing the original PHP value
*/
public function encode($input) : string
{
return $this->_encode($input);
}
/**
* Takes a FRONTMATTER encoded string and converts it into a PHP variable.
*
* @param string $input A string containing FRONTMATTER
* @param bool $cache Cache result data or no. Default is true
*
* @return mixed The FRONTMATTER converted to a PHP value
*/
public function decode(string $input, bool $cache = true)
{
if ($cache === true && $this->flextype['registry']->get('flextype.settings.cache.enabled') === true) {
$key = md5($input);
if ($data_from_cache = $this->flextype['cache']->fetch($key)) {
return $data_from_cache;
}
$data = $this->_decode($input);
$this->flextype['cache']->save($key, $data);
return $data;
}
return $this->_decode($input);
}
/**
* @see encode()
*/
protected function _encode($input) : string
{
if (isset($input['content'])) {
$content = $input['content'];
array_delete($input, 'content');
$matter = Yaml::encode($input);
} else {
$content = '';
$matter = Yaml::encode($input);
}
$encoded = '---' . "\n" .
$matter .
'---' . "\n" .
$content;
return $encoded;
}
/**
* @see decode()
*/
protected function _decode(string $input)
{
$parts = preg_split('/^[\s\r\n]?---[\s\r\n]?$/sm', PHP_EOL . ltrim($input));
if (count($parts) < 3) {
return ['content' => trim($input)];
}
return Yaml::decode(trim($parts[1]), false) + ['content' => trim(implode(PHP_EOL . '---' . PHP_EOL, array_slice($parts, 2)))];
}
}

View File

@@ -0,0 +1,122 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype\Support\Serializers;
use RuntimeException;
use function defined;
use function json_decode;
use function json_encode;
use function json_last_error;
use function json_last_error_msg;
use function md5;
use const JSON_PRESERVE_ZERO_FRACTION;
use const JSON_PRETTY_PRINT;
use const JSON_UNESCAPED_SLASHES;
use const JSON_UNESCAPED_UNICODE;
class Json
{
public const FORCE_ARRAY = 0b0001;
public const PRETTY = 0b0010;
public const ESCAPE_UNICODE = 0b0100;
/**
* Flextype Dependency Container
*/
private $flextype;
/**
* Constructor
*
* @access public
*/
public function __construct($flextype)
{
$this->flextype = $flextype;
}
/**
* Returns the JSON representation of a value
*
* @param mixed $input The PHP value
* @param int $options Bitmask consisting of encode options
* @param int $depth Encode Depth. Set the maximum depth. Must be greater than zero.
*
* @return mixed A JSON string representing the original PHP value
*/
public function encode($input, int $options = 0, int $depth = 512) : string
{
return $this->_encode($input, $options, $depth);
}
/**
* Takes a JSON encoded string and converts it into a PHP variable.
*
* @param string $input A string containing JSON
* @param bool $cache Cache result data or no. Default is true
* @param bool $assoc Decode assoc. When TRUE, returned objects will be converted into associative arrays.
* @param int $depth Decode Depth. Set the maximum depth. Must be greater than zero.
* @param int $flags Bitmask consisting of decode options
*
* @return mixed The JSON converted to a PHP value
*
* @throws ParseException If the JSON is not valid
*/
public function decode(string $input, bool $cache = true, bool $assoc = true, int $depth = 512, int $flags = 0)
{
if ($cache === true && $this->flextype['registry']->get('flextype.settings.cache.enabled') === true) {
$key = md5($input);
if ($data_from_cache = $this->flextype['cache']->fetch($key)) {
return $data_from_cache;
}
$data = $this->_decode($input);
$this->flextype['cache']->save($key, $data);
return $data;
}
return $this->_decode($input);
}
/**
* @see Json::encode()
*/
public function _encode($input, $options = 0, int $depth = 512) : string
{
$options = ($options & $this->ESCAPE_UNICODE ? 0 : JSON_UNESCAPED_UNICODE)
| JSON_UNESCAPED_SLASHES
| ($options & $this->PRETTY ? JSON_PRETTY_PRINT : 0)
| (defined('JSON_PRESERVE_ZERO_FRACTION') ? JSON_PRESERVE_ZERO_FRACTION : 0);
$json = json_encode($value, $options, $depth);
if ($error = json_last_error()) {
throw new RuntimeException(json_last_error_msg(), $error);
}
return $json;
}
/**
* @see decode()
*/
protected function _decode(string $input, bool $assoc = true, int $depth = 512, int $flags = 0)
{
$value = json_decode($json, $assoc, $depth, $flags);
if ($error = json_last_error()) {
throw new RuntimeException(json_last_error_msg(), $error);
}
return $value;
}
}

View File

@@ -7,7 +7,7 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype;
namespace Flextype\Support\Serializers;
use RuntimeException;
use Symfony\Component\Yaml\Exception\DumpException as SymfonyYamlDumpException;
@@ -16,6 +16,7 @@ use Symfony\Component\Yaml\Yaml as SymfonyYaml;
use function function_exists;
use function ini_get;
use function ini_set;
use function md5;
class Yaml
{
@@ -32,23 +33,20 @@ class Yaml
public const DUMP_EMPTY_ARRAY_AS_SEQUENCE = 1024;
/**
* Inline
*
* The level where you switch to inline YAML
*
* @var int
* Flextype Dependency Container
*/
public static $inline = 5;
private $flextype;
/**
* Ident
* Constructor
*
* The amount of spaces to use for indentation of nested nodes
*
* @var int
* @access public
*/
public static $indent = 2;
public function __construct($flextype)
{
$this->flextype = $flextype;
}
/**
* Native
*
@@ -58,33 +56,64 @@ class Yaml
*/
public static $native = true;
/**
* Flags
*
* A bit field of PARSE_* constants to customize the YAML parser behavior
*
* @var int
*/
public static $flags = 16;
/**
* Dumps a PHP value to a YAML string.
*
* The dump method, when supplied with an array, will do its best
* to convert the array into friendly YAML.
*
* @param mixed $input The PHP value
* @param mixed $input The PHP value
* @param int $inline The level where you switch to inline YAML
* @param int $indent The amount of spaces to use for indentation of nested nodes
* @param int $flags A bit field of DUMP_* constants to customize the dumped YAML string
*
* @return string A YAML string representing the original PHP value
*/
public static function encode($input) : string
public function encode($input, int $inline = 2, int $indent = 4, int $flags = 0) : string
{
return $this->_encode($input, $inline, $indent, $flags);
}
/**
* Parses YAML into a PHP value.
*
* @param string $input A string containing YAML
* @param bool $cache Cache result data or no. Default is true
* @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
*
* @return mixed The YAML converted to a PHP value
*
* @throws ParseException If the YAML is not valid
*/
public function decode(string $input, bool $cache = true, int $flags = 0) : array
{
if ($cache === true && $this->flextype['registry']->get('flextype.settings.cache.enabled') === true) {
$key = md5($input);
if ($data_from_cache = $this->flextype['cache']->fetch($key)) {
return $data_from_cache;
}
$data = $this->_decode($input, $flags);
$this->flextype['cache']->save($key, $data);
return $data;
}
return $this->_decode($input, $flags);
}
/**
* @see encode()
*/
protected function _encode($input, int $inline = 2, int $indent = 4, int $flags = 0) : string
{
try {
return SymfonyYaml::dump(
$input,
self::$inline,
self::$indent,
self::$flags
$inline,
$indent,
$flags
);
} catch (SymfonyYamlDumpException $e) {
throw new RuntimeException('Encoding YAML failed: ' . $e->getMessage(), 0, $e);
@@ -92,18 +121,12 @@ class Yaml
}
/**
* Parses YAML into a PHP value.
*
* @param string $input A string containing YAML
*
* @return array The YAML converted to a PHP value
*
* @throws ParseException If the YAML is not valid
* @see decode()
*/
public static function decode(string $input) : array
protected function _decode(string $input, int $flags = 0) : array
{
// Try native PECL YAML PHP extension first if available.
if (function_exists('yaml_parse') && self::$native) {
if (function_exists('yaml_parse') && $this->$native) {
// Safely decode YAML.
$saved = @ini_get('yaml.decode_php');
@ini_set('yaml.decode_php', '0');
@@ -116,7 +139,7 @@ class Yaml
}
try {
return SymfonyYaml::parse($input, self::$flags);
return SymfonyYaml::parse($input, $flags);
} catch (SymfonyYamlParseException $e) {
throw new RuntimeException('Decoding YAML failed: ' . $e->getMessage(), 0, $e);
}