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
6 changes: 5 additions & 1 deletion src/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ abstract class Builder implements Contract
'>=' => 'GreaterThanOrEqualTo',
'<=' => 'LessThanOrEqualTo',
];
protected $likePatterns = [];

public function __call($method, $args)
{
Expand Down Expand Up @@ -816,7 +817,10 @@ protected function filterTestLike($item, $like)
$item = json_encode($item);
}

$pattern = Pattern::sqlLikeToRegex($like);
// What's being looked for is the same for every item, so its pattern is only worked out for the first.
$pattern = is_string($like)
? $this->likePatterns[$like] ??= Pattern::sqlLikeToRegex($like)
: Pattern::sqlLikeToRegex($like);

return preg_match('/'.$pattern.'/imu', (string) $item);
}
Expand Down
24 changes: 24 additions & 0 deletions tests/Data/Entries/EntryQueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1755,6 +1755,30 @@ public function a_query_builder_with_its_own_idea_of_equal_gets_to_use_it()

$this->assertEquals(['b'], $query->where('thing', 'red')->get()->map->id()->all());
}

#[Test]
public function the_pattern_for_a_like_is_worked_out_once_for_all_the_entries_it_is_tested_against()
{
$this->createDummyCollectionAndEntries();

\Statamic\Facades\Pattern::partialMock()->shouldReceive('sqlLikeToRegex')->with('%post 1%')->once()->passthru();

$this->assertEquals(['Post 1'], Entry::query()->where('title', 'like', '%post 1%')->get()->map->title->all());
}

#[Test]
public function each_like_in_a_query_looks_for_its_own_thing()
{
$this->createDummyCollectionAndEntries();

$entries = Entry::query()
->where('title', 'like', 'post%')
->where('title', 'not like', '%2')
->where(fn ($query) => $query->where('title', 'like', '%1')->orWhere('title', 'like', '%3'))
->get();

$this->assertEquals(['Post 1', 'Post 3'], $entries->map->title->all());
}
}

class CaseSensitiveEntryQueryBuilder extends \Statamic\Stache\Query\EntryQueryBuilder
Expand Down
Loading