mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-14 07:27:47 +00:00
feat: add Liquid filter 'find_by'
This commit is contained in:
parent
61ff44b9ce
commit
e6bc225cfb
4 changed files with 158 additions and 0 deletions
|
|
@ -19,4 +19,24 @@ class Data extends FiltersProvider
|
||||||
{
|
{
|
||||||
return json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
return json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find an object in a collection by a specific key-value pair
|
||||||
|
*
|
||||||
|
* @param array $collection The collection to search in
|
||||||
|
* @param string $key The key to search for
|
||||||
|
* @param mixed $value The value to match
|
||||||
|
* @param mixed $fallback Optional fallback value if no match is found
|
||||||
|
* @return mixed The matching object or fallback value
|
||||||
|
*/
|
||||||
|
public function find_by(array $collection, string $key, mixed $value, mixed $fallback = null): mixed
|
||||||
|
{
|
||||||
|
foreach ($collection as $item) {
|
||||||
|
if (is_array($item) && isset($item[$key]) && $item[$key] === $value) {
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fallback;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -172,4 +172,60 @@ LIQUID
|
||||||
$this->assertStringContainsString('This is a test', $result);
|
$this->assertStringContainsString('This is a test', $result);
|
||||||
$this->assertStringContainsString('class="simple"', $result);
|
$this->assertStringContainsString('class="simple"', $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_plugin_with_find_by_filter(): void
|
||||||
|
{
|
||||||
|
$plugin = Plugin::factory()->create([
|
||||||
|
'markup_language' => 'liquid',
|
||||||
|
'render_markup' => <<<'LIQUID'
|
||||||
|
{% template user_info %}
|
||||||
|
<div class="user">
|
||||||
|
<h2>{{ user.name }}</h2>
|
||||||
|
<p>Age: {{ user.age }}</p>
|
||||||
|
</div>
|
||||||
|
{% endtemplate %}
|
||||||
|
|
||||||
|
{% assign found_user = collection | find_by: 'name', 'Ryan' %}
|
||||||
|
{% render "user_info", user: found_user %}
|
||||||
|
LIQUID
|
||||||
|
,
|
||||||
|
'data_payload' => [
|
||||||
|
'collection' => [
|
||||||
|
['name' => 'Ryan', 'age' => 35],
|
||||||
|
['name' => 'Sara', 'age' => 29],
|
||||||
|
['name' => 'Jimbob', 'age' => 29],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$result = $plugin->render('full');
|
||||||
|
|
||||||
|
// Should render the user info for Ryan
|
||||||
|
$this->assertStringContainsString('Ryan', $result);
|
||||||
|
$this->assertStringContainsString('Age: 35', $result);
|
||||||
|
$this->assertStringContainsString('class="user"', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_plugin_with_find_by_filter_and_fallback(): void
|
||||||
|
{
|
||||||
|
$plugin = Plugin::factory()->create([
|
||||||
|
'markup_language' => 'liquid',
|
||||||
|
'render_markup' => <<<'LIQUID'
|
||||||
|
{{ collection | find_by: 'name', 'ronak', 'Not Found' }}
|
||||||
|
LIQUID
|
||||||
|
,
|
||||||
|
'data_payload' => [
|
||||||
|
'collection' => [
|
||||||
|
['name' => 'Ryan', 'age' => 35],
|
||||||
|
['name' => 'Sara', 'age' => 29],
|
||||||
|
['name' => 'Jimbob', 'age' => 29],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$result = $plugin->render('full');
|
||||||
|
|
||||||
|
// Should return the fallback value
|
||||||
|
$this->assertStringContainsString('Not Found', $result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,3 +53,83 @@ test('json filter does not escape slashes', function () {
|
||||||
|
|
||||||
expect($filter->json($data))->toBe('{"url":"https://example.com/path"}');
|
expect($filter->json($data))->toBe('{"url":"https://example.com/path"}');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('find_by filter finds object by key-value pair', function () {
|
||||||
|
$filter = new Data();
|
||||||
|
$collection = [
|
||||||
|
['name' => 'Ryan', 'age' => 35],
|
||||||
|
['name' => 'Sara', 'age' => 29],
|
||||||
|
['name' => 'Jimbob', 'age' => 29],
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = $filter->find_by($collection, 'name', 'Ryan');
|
||||||
|
expect($result)->toBe(['name' => 'Ryan', 'age' => 35]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('find_by filter returns null when no match found', function () {
|
||||||
|
$filter = new Data();
|
||||||
|
$collection = [
|
||||||
|
['name' => 'Ryan', 'age' => 35],
|
||||||
|
['name' => 'Sara', 'age' => 29],
|
||||||
|
['name' => 'Jimbob', 'age' => 29],
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = $filter->find_by($collection, 'name', 'ronak');
|
||||||
|
expect($result)->toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('find_by filter returns fallback when no match found', function () {
|
||||||
|
$filter = new Data();
|
||||||
|
$collection = [
|
||||||
|
['name' => 'Ryan', 'age' => 35],
|
||||||
|
['name' => 'Sara', 'age' => 29],
|
||||||
|
['name' => 'Jimbob', 'age' => 29],
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = $filter->find_by($collection, 'name', 'ronak', 'Not Found');
|
||||||
|
expect($result)->toBe('Not Found');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('find_by filter finds by age', function () {
|
||||||
|
$filter = new Data();
|
||||||
|
$collection = [
|
||||||
|
['name' => 'Ryan', 'age' => 35],
|
||||||
|
['name' => 'Sara', 'age' => 29],
|
||||||
|
['name' => 'Jimbob', 'age' => 29],
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = $filter->find_by($collection, 'age', 29);
|
||||||
|
expect($result)->toBe(['name' => 'Sara', 'age' => 29]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('find_by filter handles empty collection', function () {
|
||||||
|
$filter = new Data();
|
||||||
|
$collection = [];
|
||||||
|
|
||||||
|
$result = $filter->find_by($collection, 'name', 'Ryan');
|
||||||
|
expect($result)->toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('find_by filter handles collection with non-array items', function () {
|
||||||
|
$filter = new Data();
|
||||||
|
$collection = [
|
||||||
|
'not an array',
|
||||||
|
['name' => 'Ryan', 'age' => 35],
|
||||||
|
null,
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = $filter->find_by($collection, 'name', 'Ryan');
|
||||||
|
expect($result)->toBe(['name' => 'Ryan', 'age' => 35]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('find_by filter handles items without the specified key', function () {
|
||||||
|
$filter = new Data();
|
||||||
|
$collection = [
|
||||||
|
['age' => 35],
|
||||||
|
['name' => 'Ryan', 'age' => 35],
|
||||||
|
['title' => 'Developer'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = $filter->find_by($collection, 'name', 'Ryan');
|
||||||
|
expect($result)->toBe(['name' => 'Ryan', 'age' => 35]);
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||||
namespace Tests\Unit\Liquid;
|
namespace Tests\Unit\Liquid;
|
||||||
|
|
||||||
use App\Liquid\FileSystems\InlineTemplatesFileSystem;
|
use App\Liquid\FileSystems\InlineTemplatesFileSystem;
|
||||||
|
use App\Liquid\Filters\Data;
|
||||||
use App\Liquid\Tags\TemplateTag;
|
use App\Liquid\Tags\TemplateTag;
|
||||||
use Keepsuit\Liquid\Environment;
|
use Keepsuit\Liquid\Environment;
|
||||||
use Keepsuit\Liquid\Exceptions\LiquidException;
|
use Keepsuit\Liquid\Exceptions\LiquidException;
|
||||||
|
|
@ -27,6 +28,7 @@ class InlineTemplatesTest extends TestCase
|
||||||
);
|
);
|
||||||
$this->environment->tagRegistry->register(TemplateTag::class);
|
$this->environment->tagRegistry->register(TemplateTag::class);
|
||||||
$this->environment->tagRegistry->register(RenderTag::class);
|
$this->environment->tagRegistry->register(RenderTag::class);
|
||||||
|
$this->environment->filterRegistry->register(Data::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_template_tag_registers_template(): void
|
public function test_template_tag_registers_template(): void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue