Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
BinaryAbstract
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
4 / 4
4
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toSql
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
 toInMemoryFilter
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getSqlTemplate
n/a
0 / 0
n/a
0 / 0
0
 evaluateBinary
n/a
0 / 0
n/a
0 / 0
0
 createBinaryFilter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3// ╔════════════════════════════════════════════════════════════╗
4// ║ MIT Licence (#Expat) - https://opensource.org/licenses/MIT ║
5// ║ Copyright 2026 Frederic Poeydomenge <dyno@phexium.com>     ║
6// ╚════════════════════════════════════════════════════════════╝
7
8declare(strict_types=1);
9
10namespace Phexium\Domain\Specification;
11
12use Override;
13
14abstract readonly class BinaryAbstract extends SpecificationAbstract implements SpecificationInterface
15{
16    public function __construct(
17        protected SpecificationInterface $left,
18        protected SpecificationInterface $right
19    ) {}
20
21    #[Override]
22    public function toSql(): array
23    {
24        $leftSql = $this->addSuffixToParams($this->left->toSql(), '0');
25        $rightSql = $this->addSuffixToParams($this->right->toSql(), '1');
26
27        $template = $this->getSqlTemplate();
28        $sql = str_replace(
29            ['LEFT', 'RIGHT'],
30            [$leftSql['sql'], $rightSql['sql']],
31            $template
32        );
33
34        return [
35            'sql' => $sql,
36            'params' => array_merge($leftSql['params'], $rightSql['params']),
37        ];
38    }
39
40    #[Override]
41    public function toInMemoryFilter(): callable
42    {
43        $leftFilter = $this->left->toInMemoryFilter();
44        $rightFilter = $this->right->toInMemoryFilter();
45
46        return $this->createBinaryFilter($leftFilter, $rightFilter);
47    }
48
49    abstract protected function getSqlTemplate(): string;
50
51    abstract protected function evaluateBinary(
52        callable $leftFilter,
53        callable $rightFilter,
54        array $row
55    ): bool;
56
57    private function createBinaryFilter(callable $leftFilter, callable $rightFilter): callable
58    {
59        return fn (array $row): bool => $this->evaluateBinary($leftFilter, $rightFilter, $row);
60    }
61}