Skip to content

Commit

Permalink
Add where filter for array
Browse files Browse the repository at this point in the history
  • Loading branch information
PNixx committed Dec 27, 2023
1 parent c76f0b8 commit 4d2ab5f
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 2 deletions.
20 changes: 20 additions & 0 deletions src/Liquid/StandardFilters.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,26 @@ public static function json($input)
return json_encode($input);
}

/**
* Creates an array including only the objects with a given property value
* @link https://shopify.github.io/liquid/filters/where/
*
* @param array $input
* @param string ...$args
* @return array
* @throws LiquidException
*/
public static function where(array $input, string ...$args): array
{
switch (count($args)) {
case 1:
return array_filter($input, fn($v) => ($v[$args[0]] ?? null) !== null);
case 2:
return array_filter($input, fn($v) => ($v[$args[0]] ?? '') == $args[1]);
default:
throw new LiquidException('Wrong number of arguments to function `where`, given ' . count($args) . ', expected 1 or 2');
}
}

/**
* Escape a string
Expand Down
5 changes: 5 additions & 0 deletions src/Liquid/Tag/TagFor.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ class TagFor extends AbstractBlock
*/
private $name;

/**
* @var string
*/
private $start;

/**
* @var string The type of the loop (collection or digit)
*/
Expand Down
2 changes: 1 addition & 1 deletion src/Liquid/Tag/TagPaginate.php
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public function render(Context $context)
public function currentUrl($context, $queryPart = [])
{
// From here we have $url->path and $url->query
$url = (object) parse_url($context->get('REQUEST_URI'));
$url = (object) parse_url($context->get('REQUEST_URI') ?: '');

// Let's merge the query part
if (isset($url->query)) {
Expand Down
8 changes: 7 additions & 1 deletion tests/Liquid/ContextTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public function toLiquid()

class CountableObject implements \Countable
{
public function count()
public function count(): int
{
return 2;
}
Expand Down Expand Up @@ -135,6 +135,8 @@ public function __get($prop)

class HiFilter
{
public Context $context;

public function hi($value)
{
return $value . ' hi!';
Expand All @@ -143,6 +145,8 @@ public function hi($value)

class GlobalFilter
{
public Context $context;

public function notice($value)
{
return "Global $value";
Expand All @@ -151,6 +155,8 @@ public function notice($value)

class LocalFilter
{
public Context $context;

public function notice($value)
{
return "Local $value";
Expand Down
6 changes: 6 additions & 0 deletions tests/Liquid/FilterbankTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

namespace {

use Liquid\Context;

/**
* Global function acts as a filter.
*
Expand All @@ -28,6 +30,8 @@ function functionFilter($value)
*/
class ClassFilter
{
public Context $context;

private $variable = 'not set';

public function __construct()
Expand Down Expand Up @@ -59,6 +63,8 @@ public function instance_test_two()

class NamespacedClassFilter
{
public Context $context;

public static function static_test2($var)
{
return "good {$var}";
Expand Down
24 changes: 24 additions & 0 deletions tests/Liquid/OutputTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

class FunnyFilter
{
public Context $context;

public function make_funny($input)
{
return 'LOL';
Expand Down Expand Up @@ -191,4 +193,26 @@ public function testVariableWithANewLine()
$text = "{{ aaa\n }}";
$this->assertTemplateResult('', $text, $this->assigns);
}

public function testFilterArray()
{
$text = ' {{ cars | where: "model", "bmw" | json }} ';
$expected = ' [{"model":"bmw"}] ';

$this->assertTemplateResult($expected, $text, ['cars' => [
['model' => 'bmw'],
['model' => 'audi'],
]]);
}

public function testFilterArrayTruthy()
{
$text = ' {{ cars | where: "available" | json }} ';
$expected = ' [{"model":"bmw","available":1}] ';

$this->assertTemplateResult($expected, $text, ['cars' => [
['model' => 'bmw', 'available' => 1],
['model' => 'audi'],
]]);
}
}
22 changes: 22 additions & 0 deletions tests/Liquid/StandardFiltersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

class MoneyFilter
{
public Context $context;

public function money($value)
{
return sprintf(' %d$ ', $value);
Expand All @@ -26,6 +28,8 @@ public function money_with_underscore($value)

class CanadianMoneyFilter
{
public Context $context;

public function money($value)
{
return sprintf(' %d$ CAD ', $value);
Expand Down Expand Up @@ -204,6 +208,24 @@ public function testJson()
}
}

public function testWhere()
{
$data = [
[
'before' => [['model' => 'bmw'], ['model' => 'audi']],
'after' => [['model' => 'bmw']],
],
[
'before' => ['model' => 'bmw'],
'after' => [],
],
];

foreach ($data as $testCase) {
$this->assertEquals($testCase['after'], StandardFilters::where($testCase['before'], 'model', 'bmw'));
}
}

public function testEscape()
{
$data = array(
Expand Down

0 comments on commit 4d2ab5f

Please sign in to comment.