Completed
Push — 2.0 ( d6b5ff...33bb83 )
by Peter
08:35 queued 11s
created

In::resolveContext()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
cc 4
nc 3
nop 1
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of the Happyr Doctrine Specification package.
6
 *
7
 * (c) Tobias Nyholm <[email protected]>
8
 *     Kacper Gunia <[email protected]>
9
 *     Peter Gribanov <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Happyr\DoctrineSpecification\Filter;
16
17
use Doctrine\ORM\QueryBuilder;
18
use Happyr\DoctrineSpecification\Operand\ArgumentToOperandConverter;
19
use Happyr\DoctrineSpecification\Operand\Operand;
20
21
final class In implements Filter, Satisfiable
22
{
23
    /**
24
     * @var Operand|string
25
     */
26
    private $field;
27
28
    /**
29
     * @var Operand|mixed
30
     */
31
    private $value;
32
33
    /**
34
     * @var string|null
35
     */
36
    private $context;
37
38
    /**
39
     * Make sure the $field has a value equals to $value.
40
     *
41
     * @param Operand|string $field
42
     * @param Operand|mixed  $value
43
     * @param string|null    $context
44
     */
45
    public function __construct($field, $value, ?string $context = null)
46
    {
47
        $this->field = $field;
48
        $this->value = $value;
49
        $this->context = $context;
50
    }
51
52
    /**
53
     * @param QueryBuilder $qb
54
     * @param string       $context
55
     *
56
     * @return string
57
     */
58
    public function getFilter(QueryBuilder $qb, string $context): string
59
    {
60
        if (null !== $this->context) {
61
            $context = sprintf('%s.%s', $context, $this->context);
62
        }
63
64
        $field = ArgumentToOperandConverter::toField($this->field);
65
        $value = ArgumentToOperandConverter::toValue($this->value);
66
67
        return (string) $qb->expr()->in(
68
            $field->transform($qb, $context),
69
            $value->transform($qb, $context)
70
        );
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76
    public function filterCollection(iterable $collection, ?string $context = null): iterable
77
    {
78
        $context = $this->resolveContext($context);
79
        $field = ArgumentToOperandConverter::toField($this->field);
80
        $value = ArgumentToOperandConverter::toValue($this->value);
81
82
        foreach ($collection as $candidate) {
83
            if ($this->contains($field->execute($candidate, $context), $value->execute($candidate, $context))) {
84
                yield $candidate;
85
            }
86
        }
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92
    public function isSatisfiedBy($candidate, ?string $context = null): bool
93
    {
94
        $context = $this->resolveContext($context);
95
        $field = ArgumentToOperandConverter::toField($this->field);
96
        $value = ArgumentToOperandConverter::toValue($this->value);
97
98
        return $this->contains($field->execute($candidate, $context), $value->execute($candidate, $context));
0 ignored issues
show
Bug introduced by
It seems like $candidate defined by parameter $candidate on line 92 can also be of type array; however, Happyr\DoctrineSpecifica...rand\Operand::execute() does only seem to accept array<integer,*>|object, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
99
    }
100
101
    /**
102
     * @param string|null $context
103
     *
104
     * @return string|null
105
     */
106
    private function resolveContext(?string $context): ?string
107
    {
108
        if (null !== $this->context && null !== $context) {
109
            return sprintf('%s.%s', $context, $this->context);
110
        }
111
112
        if (null !== $this->context) {
113
            return $this->context;
114
        }
115
116
        return $context;
117
    }
118
119
    /**
120
     * @param mixed $field
121
     * @param mixed $value
122
     *
123
     * @return bool
124
     */
125
    private function contains($field, $value): bool
126
    {
127
        if ($value instanceof \Traversable) {
128
            $value = iterator_to_array($value);
129
        }
130
131
        return in_array($field, $value, true);
132
    }
133
}
134