Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,3 @@ phpunit.xml
psalm.xml
vendor
.php-cs-fixer.cache

16 changes: 10 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@
],
"require": {
"php": "^8.1",
"symfony/yaml": "^6.0 || ^7.0"
"ext-mbstring": "*"
},
"require-dev": {
"laravel/pint": "^1.2",
"pestphp/pest": "^2.6",
"pestphp/pest-plugin-arch": "^2.0",
"pestphp/pest": "^2.7",
"pestphp/pest-plugin-arch": "^2.2",
"phpbench/phpbench": "^1.2",
"phpstan/phpstan": "^1.10",
"phpstan/extension-installer": "^1.3",
"phpstan/phpstan": "^1.10.57",
"phpstan/phpstan-deprecation-rules": "^1.1",
"spatie/invade": "^2.0",
"spatie/ray": "^1.28",
"symfony/console": "^6.3 || ^7.0"
"symfony/console": "^6.3 || ^7.0",
"symfony/yaml": "^6.0 || ^7.0"
},
"suggest": {
"ext-yaml": "Used to parse YAML files with better performance than symfony/yaml"
Expand All @@ -47,7 +50,8 @@
"test-coverage": "vendor/bin/pest --coverage",
"format": "vendor/bin/pint",
"lint": "vendor/bin/phpstan analyse",
"benchmark": "vendor/bin/phpbench run --report=aggregate"
"benchmark": "vendor/bin/phpbench run --report=aggregate",
"profile": "vendor/bin/phpbench xdebug:profile"
},
"config": {
"sort-packages": true,
Expand Down
33 changes: 0 additions & 33 deletions locales/en.yml

This file was deleted.

4 changes: 2 additions & 2 deletions performance/CompiledThemeTestTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Keepsuit\Liquid\Performance;

use Keepsuit\Liquid\Render\Context;
use Keepsuit\Liquid\Render\RenderContext;
use Keepsuit\Liquid\Template;
use Keepsuit\Liquid\TemplateFactory;

Expand Down Expand Up @@ -33,7 +33,7 @@ public function render(array $assigns = []): void
}
}

protected function buildContext(array $assigns = []): Context
protected function buildContext(array $assigns = []): RenderContext
{
return $this->factory->newRenderContext(
staticEnvironment: $assigns,
Expand Down
38 changes: 21 additions & 17 deletions performance/Shopify/CommentFormTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,49 @@
namespace Keepsuit\Liquid\Performance\Shopify;

use Keepsuit\Liquid\Exceptions\SyntaxException;
use Keepsuit\Liquid\Parse\ParseContext;
use Keepsuit\Liquid\Parse\Regex;
use Keepsuit\Liquid\Parse\Tokenizer;
use Keepsuit\Liquid\Render\Context;
use Keepsuit\Liquid\Nodes\BodyNode;
use Keepsuit\Liquid\Nodes\TagParseContext;
use Keepsuit\Liquid\Nodes\VariableLookup;
use Keepsuit\Liquid\Render\RenderContext;
use Keepsuit\Liquid\TagBlock;

class CommentFormTag extends TagBlock
{
protected const Syntax = '/('.Regex::VariableSignature.'+)/';

protected string $variableName;

protected array $attributes;

protected BodyNode $body;

public static function tagName(): string
{
return 'form';
}

public function parse(ParseContext $parseContext, Tokenizer $tokenizer): static
public function parse(TagParseContext $context): static
{
parent::parse($parseContext, $tokenizer);
assert($context->body !== null);
$this->body = $context->body;

$variableName = $context->params->expression();
$this->variableName = match (true) {
$variableName instanceof VariableLookup, is_string($variableName) => (string) $variableName,
default => throw new SyntaxException('Invalid variable name'),
};

$this->attributes = [];

if (preg_match(self::Syntax, $this->markup, $matches)) {
$this->variableName = $matches[1];
$this->attributes = [];
} else {
throw new SyntaxException("Syntax Error in 'comment_form' - Valid syntax: comment_form [article]");
}
$context->params->assertEnd();

return $this;
}

public function render(Context $context): string
public function render(RenderContext $context): string
{
$article = $context->get($this->variableName);
assert(is_array($article));

$context->stack(function (Context $context) {
$context->stack(function (RenderContext $context) {
$context->set('form', [
'posted_successfully?' => $context->getRegister('posted_successfully'),
'errors' => $context->get('comment.errors'),
Expand All @@ -51,7 +55,7 @@ public function render(Context $context): string
]);
});

return $this->wrapInForm($article, parent::render($context));
return $this->wrapInForm($article, $this->body->render($context));
}

protected function wrapInForm(array $article, string $input): string
Expand Down
4 changes: 2 additions & 2 deletions performance/Shopify/CustomFilters.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public function urlForType(string $type): string

public function productImgUrl(string $url, string $style = 'small'): string
{
if (! preg_match('/\Aproducts\/([\w\-_]+)\.(\w{2,4})/', $url, $matches)) {
if (preg_match('/\Aproducts\/([\w\-_]+)\.(\w{2,4})/', $url, $matches) === 0) {
throw new InvalidArgumentException('filter "size" can only be called on product images');
}

Expand Down Expand Up @@ -215,7 +215,7 @@ protected function toHandle(string $input): string
$result = $input;
$result = strtolower($result);
$result = str_replace(['\'', '"', '()', '[]'], '', $result);
$result = preg_replace('/\W+/', '-', $result) ?? '';
$result = preg_replace('/\W+/', '-', $result) ?? $result;

return trim($result, '-');
}
Expand Down
4 changes: 2 additions & 2 deletions performance/Shopify/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Keepsuit\Liquid\Performance\Shopify;

use Keepsuit\Liquid\Support\Arr;
use Keepsuit\Liquid\Support\YamlParser;
use Symfony\Component\Yaml\Yaml;

class Database
{
Expand All @@ -17,7 +17,7 @@ public static function tables(): array
return static::$tables;
}

$database = YamlParser::parseFile(static::DATABASE_FILE_PATH);
$database = (array) Yaml::parseFile(static::DATABASE_FILE_PATH);

foreach ($database['products'] as $product) {
$collections = array_filter(
Expand Down
49 changes: 27 additions & 22 deletions performance/Shopify/PaginateTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,56 @@

use Keepsuit\Liquid\Exceptions\InvalidArgumentException;
use Keepsuit\Liquid\Exceptions\SyntaxException;
use Keepsuit\Liquid\Nodes\BodyNode;
use Keepsuit\Liquid\Nodes\Range;
use Keepsuit\Liquid\Parse\ParseContext;
use Keepsuit\Liquid\Parse\Regex;
use Keepsuit\Liquid\Parse\Tokenizer;
use Keepsuit\Liquid\Render\Context;
use Keepsuit\Liquid\Nodes\TagParseContext;
use Keepsuit\Liquid\Nodes\VariableLookup;
use Keepsuit\Liquid\Parse\TokenType;
use Keepsuit\Liquid\Render\RenderContext;
use Keepsuit\Liquid\TagBlock;

class PaginateTag extends TagBlock
{
protected const Syntax = '/('.Regex::QuotedFragment.')\s*(by\s*(\d+))?/';
protected VariableLookup|string $collectionName;

protected string $collectionName;

protected int $pageSize;
protected int $pageSize = 20;

protected array $attributes;

protected BodyNode $body;

public static function tagName(): string
{
return 'paginate';
}

public function parse(ParseContext $parseContext, Tokenizer $tokenizer): static
public function parse(TagParseContext $context): static
{
parent::parse($parseContext, $tokenizer);
assert($context->body !== null);
$this->body = $context->body;

if (preg_match(self::Syntax, $this->markup, $matches)) {
$this->collectionName = $matches[1];
$this->pageSize = isset($matches[2]) ? (int) $matches[3] : 20;
} else {
throw new SyntaxException("Syntax Error in tag 'paginate' - Valid syntax: paginate [collection] by number");
$collectionName = $context->params->expression();
$this->collectionName = match (true) {
$collectionName instanceof VariableLookup, is_string($collectionName) => (string) $collectionName,
default => throw new SyntaxException('Invalid collection name'),
};

if ($context->params->idOrFalse('by')) {
$this->pageSize = (int) $context->params->consume(TokenType::Number)->data;
}

$this->attributes = ['window_size' => 3];
preg_match_all(sprintf('/%s/', Regex::TagAttributes), $this->markup, $attributeMatches, PREG_SET_ORDER);
foreach ($attributeMatches as $matches) {
$this->attributes[$matches[1]] = $this->parseExpression($parseContext, $matches[2]);
if (! $context->params->isEnd()) {
dd('paginate', $context->params->current());
}

$context->params->assertEnd();

return $this;
}

public function render(Context $context): string
public function render(RenderContext $context): string
{
return $context->stack(function (Context $context) {
return $context->stack(function (RenderContext $context) {
$currentPage = $context->get('current_page');

$collection = $context->get($this->collectionName);
Expand Down Expand Up @@ -90,7 +95,7 @@ public function render(Context $context): string

$context->set('paginate', $pagination);

return parent::render($context);
return $this->body->render($context);
});
}

Expand Down
6 changes: 5 additions & 1 deletion performance/ThemeRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ class ThemeRunner
public function __construct(
protected TemplateFactory $templateFactory
) {
$files = glob(__DIR__.'/tests/**/*.liquid') ?: [];
$files = glob(__DIR__.'/tests/**/*.liquid');

if ($files === false) {
throw new \RuntimeException('Could not find any tests');
}

$this->tests = Arr::compact(Arr::map($files, function (string $path) {
if (basename($path) === 'theme.liquid') {
Expand Down
24 changes: 17 additions & 7 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,35 @@ parameters:
count: 3
path: performance/Shopify/CustomFilters.php

-
message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#"
count: 1
path: performance/Shopify/Database.php

-
message: "#^Cannot access offset 'articles' on mixed\\.$#"
count: 1
path: performance/Shopify/Database.php

-
message: "#^Strict comparison using \\!\\=\\= between null and null will always evaluate to false\\.$#"
message: "#^Cannot access offset 'collections' on mixed\\.$#"
count: 1
path: src/Profiler/Profiler.php
path: performance/Shopify/Database.php

-
message: "#^Access to protected property Spatie\\\\Invade\\\\Invader\\<Keepsuit\\\\Liquid\\\\Render\\\\Context\\>\\:\\:\\$scopes\\.$#"
count: 2
path: tests/Stubs/ContextDrop.php
message: "#^Cannot access offset 'id' on mixed\\.$#"
count: 1
path: performance/Shopify/Database.php

-
message: "#^Method Keepsuit\\\\Liquid\\\\Tests\\\\Stubs\\\\ContextDrop\\:\\:loopPos\\(\\) should return int\\|null but returns mixed\\.$#"
message: "#^Parameter \\#1 \\$array of static method Keepsuit\\\\Liquid\\\\Support\\\\Arr\\:\\:first\\(\\) expects array, mixed given\\.$#"
count: 1
path: tests/Stubs/ContextDrop.php
path: performance/Shopify/Database.php

-
message: "#^Strict comparison using \\!\\=\\= between null and null will always evaluate to false\\.$#"
count: 1
path: src/Profiler/Profiler.php

-
message: "#^Parameter \\#3 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, mixed given\\.$#"
Expand Down
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ parameters:
disableCheckMissingIterableValueType: false

ignoreErrors:
- '#Method .+ should return .+ but returns mixed#'
6 changes: 3 additions & 3 deletions src/Concerns/ContextAware.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

namespace Keepsuit\Liquid\Concerns;

use Keepsuit\Liquid\Render\Context;
use Keepsuit\Liquid\Render\RenderContext;

trait ContextAware
{
protected Context $context;
protected RenderContext $context;

public function setContext(Context $context): void
public function setContext(RenderContext $context): void
{
$this->context = $context;
}
Expand Down
Loading