From 1fc60f288c03853306073f67079858ec39fda764 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Fri, 23 Sep 2022 02:08:43 -0600 Subject: [PATCH] Make the SectionParser more extendable Allows for extending the SectionParser class to swap out how various sections are prepared for storage and parsed from storage (example, custom SectionParser that uses YAML in the settings section) --- src/Halcyon/Processors/SectionParser.php | 119 ++++++++++++++++------- 1 file changed, 84 insertions(+), 35 deletions(-) diff --git a/src/Halcyon/Processors/SectionParser.php b/src/Halcyon/Processors/SectionParser.php index 9b5cf53a7..e1ca58f35 100644 --- a/src/Halcyon/Processors/SectionParser.php +++ b/src/Halcyon/Processors/SectionParser.php @@ -60,22 +60,10 @@ protected static function parseIntoSections(string $content, int $limit = 3): ar } /** - * Renders a CMS object as file content. - * @throws InvalidArgumentException if section separators are found in the settings or code sections + * Renders the provided settings data into a string that can be stored in the Settings section */ - public static function render(array $data, array $options = []): string + public static function renderSettings(array $data): string { - $sectionOptions = array_merge([ - 'wrapCodeInPhpTags' => true, - 'isCompoundObject' => true, - ], $options); - extract($sectionOptions); - - if (!isset($isCompoundObject) || $isCompoundObject === false) { - return array_get($data, 'content', ''); - } - - // Prepare settings section for saving $iniParser = new Ini; $trim = function (&$values) use (&$trim) { foreach ($values as &$value) { @@ -89,10 +77,18 @@ public static function render(array $data, array $options = []): string }; $settings = array_get($data, 'settings', []); $trim($settings); - $settings = $iniParser->render($settings); - // Prepare code section for saving - $code = trim(array_get($data, 'code', '') ?? ''); + return $iniParser->render($settings); + } + + /** + * Renders the provided string into a string that can be stored in the Code section + */ + public static function renderCode(string $code, array $options = []): string + { + $wrapCodeInPhpTags = array_get($options, 'wrapCodeInPhpTags', true); + + $code = trim($code); if ($code) { if (isset($wrapCodeInPhpTags) && $wrapCodeInPhpTags === true) { $code = preg_replace('/^\<\?php/', '', $code); @@ -105,8 +101,37 @@ public static function render(array $data, array $options = []): string } } - // Prepare markup section for saving - $markup = trim(array_get($data, 'markup', '')); + return $code; + } + + /** + * Renders the provided string into a string that can be stored in the Markup section + */ + public static function renderMarkup(string $markup): string + { + return trim($markup); + } + + /** + * Renders a CMS object as file content. + * @throws InvalidArgumentException if section separators are found in the settings or code sections + */ + public static function render(array $data, array $options = []): string + { + $sectionOptions = array_merge([ + 'wrapCodeInPhpTags' => true, + 'isCompoundObject' => true, + ], $options); + extract($sectionOptions); + + if (!isset($isCompoundObject) || $isCompoundObject === false) { + return array_get($data, 'content', ''); + } + + // Prepare sections for saving + $settings = static::renderSettings($data); + $code = static::renderCode(array_get($data, 'code', '') ?? '', $sectionOptions); + $markup = static::renderMarkup(array_get($data, 'markup', '')); /* * Build content @@ -172,6 +197,40 @@ public static function render(array $data, array $options = []): string return $content; } + /** + * Parses the Settings section into an array + */ + public static function parseSettings(string $settings): array + { + $iniParser = new Ini; + return @$iniParser->parse($settings) + ?: [self::ERROR_INI => $settings]; + } + + /** + * Processes the Code section into a usable form + */ + public static function parseCode(string $code): string + { + $code = trim($code); + if ($code) { + $code = preg_replace('/^\s*\<\?php/', '', $code); + $code = preg_replace('/^\s*\<\?/', '', $code); + $code = preg_replace('/\?\>\s*$/', '', $code); + $code = trim($code, PHP_EOL); + } + + return $code; + } + + /** + * Processes the Markup section into a usable form + */ + public static function parseMarkup(string $markup): string + { + return $markup; + } + /** * Parses Halcyon section content. * The expected file format is following: @@ -205,7 +264,6 @@ public static function parse(string $content, array $options = []): array return $result; } - $iniParser = new Ini; $sections = static::parseIntoSections($content); $count = count($sections); foreach ($sections as &$section) { @@ -213,23 +271,14 @@ public static function parse(string $content, array $options = []): array } if ($count >= 3) { - $result['settings'] = @$iniParser->parse($sections[0]) - ?: [self::ERROR_INI => $sections[0]]; - - $result['code'] = $sections[1]; - $result['code'] = preg_replace('/^\s*\<\?php/', '', $result['code']); - $result['code'] = preg_replace('/^\s*\<\?/', '', $result['code']); - $result['code'] = preg_replace('/\?\>\s*$/', '', $result['code']); - $result['code'] = trim($result['code'], PHP_EOL); - - $result['markup'] = $sections[2]; + $result['settings'] = static::parseSettings($sections[0]); + $result['code'] = static::parseCode($sections[1]); + $result['markup'] = static::parseMarkup($sections[2]); } elseif ($count == 2) { - $result['settings'] = @$iniParser->parse($sections[0]) - ?: [self::ERROR_INI => $sections[0]]; - - $result['markup'] = $sections[1]; + $result['settings'] = static::parseSettings($sections[0]); + $result['markup'] = static::parseMarkup($sections[1]); } elseif ($count == 1) { - $result['markup'] = $sections[0]; + $result['markup'] = static::parseMarkup($sections[0]); } return $result;