mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-13 15:07:49 +00:00
feat: add Liquid filter 'group_by'
This commit is contained in:
parent
e6bc225cfb
commit
5378c39fde
3 changed files with 152 additions and 0 deletions
|
|
@ -39,4 +39,28 @@ class Data extends FiltersProvider
|
|||
|
||||
return $fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Group a collection by a specific key
|
||||
*
|
||||
* @param array $collection The collection to group
|
||||
* @param string $key The key to group by
|
||||
* @return array The grouped collection
|
||||
*/
|
||||
public function group_by(array $collection, string $key): array
|
||||
{
|
||||
$grouped = [];
|
||||
|
||||
foreach ($collection as $item) {
|
||||
if (is_array($item) && array_key_exists($key, $item)) {
|
||||
$groupKey = $item[$key];
|
||||
if (! isset($grouped[$groupKey])) {
|
||||
$grouped[$groupKey] = [];
|
||||
}
|
||||
$grouped[$groupKey][] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,4 +228,28 @@ LIQUID
|
|||
// Should return the fallback value
|
||||
$this->assertStringContainsString('Not Found', $result);
|
||||
}
|
||||
|
||||
public function test_plugin_with_group_by_filter(): void
|
||||
{
|
||||
$plugin = Plugin::factory()->create([
|
||||
'markup_language' => 'liquid',
|
||||
'render_markup' => <<<'LIQUID'
|
||||
{{ collection | group_by: 'age' | json }}
|
||||
LIQUID
|
||||
,
|
||||
'data_payload' => [
|
||||
'collection' => [
|
||||
['name' => 'Ryan', 'age' => 35],
|
||||
['name' => 'Sara', 'age' => 29],
|
||||
['name' => 'Jimbob', 'age' => 29],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$result = $plugin->render('full');
|
||||
|
||||
// Should output JSON representation of grouped data
|
||||
$this->assertStringContainsString('"35":[{"name":"Ryan","age":35}]', $result);
|
||||
$this->assertStringContainsString('"29":[{"name":"Sara","age":29},{"name":"Jimbob","age":29}]', $result);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,3 +133,107 @@ test('find_by filter handles items without the specified key', function () {
|
|||
$result = $filter->find_by($collection, 'name', 'Ryan');
|
||||
expect($result)->toBe(['name' => 'Ryan', 'age' => 35]);
|
||||
});
|
||||
|
||||
test('group_by filter groups collection by age', function () {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
['name' => 'Ryan', 'age' => 35],
|
||||
['name' => 'Sara', 'age' => 29],
|
||||
['name' => 'Jimbob', 'age' => 29],
|
||||
];
|
||||
|
||||
$result = $filter->group_by($collection, 'age');
|
||||
|
||||
expect($result)->toBe([
|
||||
35 => [['name' => 'Ryan', 'age' => 35]],
|
||||
29 => [
|
||||
['name' => 'Sara', 'age' => 29],
|
||||
['name' => 'Jimbob', 'age' => 29],
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test('group_by filter groups collection by name', function () {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
['name' => 'Ryan', 'age' => 35],
|
||||
['name' => 'Sara', 'age' => 29],
|
||||
['name' => 'Ryan', 'age' => 30],
|
||||
];
|
||||
|
||||
$result = $filter->group_by($collection, 'name');
|
||||
|
||||
expect($result)->toBe([
|
||||
'Ryan' => [
|
||||
['name' => 'Ryan', 'age' => 35],
|
||||
['name' => 'Ryan', 'age' => 30],
|
||||
],
|
||||
'Sara' => [['name' => 'Sara', 'age' => 29]],
|
||||
]);
|
||||
});
|
||||
|
||||
test('group_by filter handles empty collection', function () {
|
||||
$filter = new Data();
|
||||
$collection = [];
|
||||
|
||||
$result = $filter->group_by($collection, 'age');
|
||||
expect($result)->toBe([]);
|
||||
});
|
||||
|
||||
test('group_by filter handles collection with non-array items', function () {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
'not an array',
|
||||
['name' => 'Ryan', 'age' => 35],
|
||||
null,
|
||||
['name' => 'Sara', 'age' => 29],
|
||||
];
|
||||
|
||||
$result = $filter->group_by($collection, 'age');
|
||||
|
||||
expect($result)->toBe([
|
||||
35 => [['name' => 'Ryan', 'age' => 35]],
|
||||
29 => [['name' => 'Sara', 'age' => 29]],
|
||||
]);
|
||||
});
|
||||
|
||||
test('group_by filter handles items without the specified key', function () {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
['age' => 35],
|
||||
['name' => 'Ryan', 'age' => 35],
|
||||
['title' => 'Developer'],
|
||||
['name' => 'Sara', 'age' => 29],
|
||||
];
|
||||
|
||||
$result = $filter->group_by($collection, 'age');
|
||||
|
||||
expect($result)->toBe([
|
||||
35 => [
|
||||
['age' => 35],
|
||||
['name' => 'Ryan', 'age' => 35],
|
||||
],
|
||||
29 => [['name' => 'Sara', 'age' => 29]],
|
||||
]);
|
||||
});
|
||||
|
||||
test('group_by filter handles mixed data types as keys', function () {
|
||||
$filter = new Data();
|
||||
$collection = [
|
||||
['name' => 'Ryan', 'active' => true],
|
||||
['name' => 'Sara', 'active' => false],
|
||||
['name' => 'Jimbob', 'active' => true],
|
||||
['name' => 'Alice', 'active' => null],
|
||||
];
|
||||
|
||||
$result = $filter->group_by($collection, 'active');
|
||||
|
||||
expect($result)->toBe([
|
||||
1 => [ // PHP converts true to 1
|
||||
['name' => 'Ryan', 'active' => true],
|
||||
['name' => 'Jimbob', 'active' => true],
|
||||
],
|
||||
0 => [['name' => 'Sara', 'active' => false]], // PHP converts false to 0
|
||||
'' => [['name' => 'Alice', 'active' => null]], // PHP converts null keys to empty string
|
||||
]);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue