Completed
Push — 2.0 ( 0357a9...3fe951 )
by Peter
08:22 queued 10s
created

Field::execute()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.7
c 0
b 0
f 0
cc 3
nc 4
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\Operand;
16
17
use Doctrine\ORM\QueryBuilder;
18
use Happyr\DoctrineSpecification\DQLContextResolver;
19
use Happyr\DoctrineSpecification\Query\Selection\Selection;
20
use Symfony\Component\PropertyAccess\PropertyAccess;
21
22
final class Field implements Operand, Selection
23
{
24
    /**
25
     * @var string
26
     */
27
    private $fieldName;
28
29
    /**
30
     * @var string|null
31
     */
32
    private $context;
33
34
    /**
35
     * @param string      $fieldName
36
     * @param string|null $context
37
     */
38
    public function __construct(string $fieldName, ?string $context = null)
39
    {
40
        $this->fieldName = $fieldName;
41
        $this->context = $context;
42
    }
43
44
    /**
45
     * @param QueryBuilder $qb
46
     * @param string       $context
47
     *
48
     * @return string
49
     */
50
    public function transform(QueryBuilder $qb, string $context): string
51
    {
52
        if (null !== $this->context) {
53
            $context = $this->context;
54
        }
55
56
        $dqlAlias = DQLContextResolver::resolveAlias($qb, $context);
57
58
        return sprintf('%s.%s', $dqlAlias, $this->fieldName);
59
    }
60
61
    /**
62
     * @param mixed[]|object $candidate
63
     *
64
     * @return mixed
65
     */
66
    public function execute($candidate)
67
    {
68
        if (null !== $this->context) {
69
            $propertyPath = sprintf('%s.%s', $this->context, $this->fieldName);
70
        } else {
71
            $propertyPath = $this->fieldName;
72
        }
73
74
        // If the candidate is a array, then we assume that all nested elements are also arrays.
75
        // The candidate cannot combine arrays and objects since Property Accessor expects different syntax for
76
        // accessing array and object elements.
77
        if (is_array($candidate)) {
78
            $propertyPath = sprintf('[%s]', str_replace('.', '][', $propertyPath));
79
        }
80
81
        return PropertyAccess::createPropertyAccessor()->getValue($candidate, $propertyPath);
82
    }
83
}
84