diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b515fd..dacd6ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Changed + +- **Statamic's own fast YAML parser is used where it has one.** Flatpack's copy is only used on Statamic versions without it. + ## 1.1.0 (2026-11-10) ### Changed diff --git a/src/Flatpack.php b/src/Flatpack.php index a3fad10..92abd2d 100644 --- a/src/Flatpack.php +++ b/src/Flatpack.php @@ -21,6 +21,8 @@ public static function configure(string $path, int $lazyLimit = 2048): void self::$bodies = null; } + private static ?bool $statamicHasFastParser = null; + public static function bodies(): BodyStore { return self::$bodies ??= new BodyStore(self::$path.'/bodies'); @@ -32,9 +34,22 @@ public static function parseFrontMatter(string $contents): array $fm = str_starts_with($contents, '---') ? preg_split("/\n---/", $contents, 2, PREG_SPLIT_NO_EMPTY)[0] : $contents; $fm = preg_replace('/^---\n?/', '', $fm); + if (self::statamicHasFastParser()) { + return (new \Statamic\Yaml\FastParser)->parse($fm) ?? []; + } + return Yaml\FastParser::parse($fm) ?? SymfonyYaml::parse($fm) ?? []; } + /** + * Whether this Statamic version has its own fast YAML parser, which Flatpack then uses + * instead of the copy it ships for older versions. + */ + public static function statamicHasFastParser(): bool + { + return self::$statamicHasFastParser ??= method_exists(\Statamic\Yaml\FastParser::class, 'parse'); + } + /** True when $v holds only scalars, nulls and arrays of them (safe for var_export + OPcache). */ public static function isPlain($v): bool { diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index c178d6c..9ffb5c3 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -71,7 +71,10 @@ public function register(): void $this->app->booting(function ($app) { $app->bind(\Statamic\Contracts\Entries\Entry::class, FlatpackEntry::class); $app->bind(\Statamic\Stache\Traverser::class, Stache\FastTraverser::class); - $app->singleton(\Statamic\Yaml\Yaml::class, fn () => new LeanYaml(new Yaml\SymfonyFast)); + // Statamic parses with its own fast parser where it has one; older versions get Flatpack's. + $app->singleton(\Statamic\Yaml\Yaml::class, fn () => new LeanYaml( + Flatpack::statamicHasFastParser() ? new \Symfony\Component\Yaml\Yaml : new Yaml\SymfonyFast + )); Facade::clearResolvedInstance(\Statamic\Yaml\Yaml::class); }); } diff --git a/src/Yaml/FastParser.php b/src/Yaml/FastParser.php index 4439923..bed92ab 100644 --- a/src/Yaml/FastParser.php +++ b/src/Yaml/FastParser.php @@ -17,6 +17,10 @@ * collections or plain scalars, invalid YAML) makes it return null, and the caller parses the * whole document with Symfony. Errors are therefore always Symfony's. * + * Statamic has the same parser of its own from the release after 6.40 (statamic/cms#15838). + * Flatpack uses Statamic's where it exists and this one on older versions, Statamic 5 included + * (see Flatpack::statamicHasFastParser()). + * * tests/yaml/fuzz.php checks it against Symfony's parser. */ final class FastParser