BitsMask::deleteDeferredPath()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 16
c 0
b 0
f 0
ccs 11
cts 11
cp 1
rs 9.4285
cc 1
eloc 11
nc 1
nop 2
crap 1
1
<?php
2
3
/**
4
 * @author KonstantinKuklin <[email protected]>
5
 */
6
7
8
namespace KonstantinKuklin\DoctrineCompressedFields\DqlFunction;
9
10
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
11
use Doctrine\ORM\Query\Lexer;
12
use Doctrine\ORM\Query\Parser;
13
use Doctrine\ORM\Query\SqlWalker;
14
use KonstantinKuklin\DoctrineCompressedFields\Engine;
15
use KonstantinKuklin\DoctrineCompressedFields\MetadataLayer;
16
use ReflectionClass;
17
18
/**
19
 * CompressedSelectFunction ::= "BITS_MASK" ( "ArithmeticPrimary", "ArithmeticPrimary")
20
 */
21
class BitsMask extends FunctionNode
22
{
23
    /**
24
     * @var \Doctrine\ORM\Query\AST\PathExpression
25
     */
26
    private $maskField;
27
28
    /**
29
     * @var \Doctrine\ORM\Query\AST\Literal
30
     */
31
    private $findValue;
32
33
    /**
34
     * @var \Doctrine\ORM\Query\ParserResult
35
     */
36
    private $parserResult;
37
38
    /**
39
     * @var Engine
40
     */
41
    private $engine;
42
43
    /**
44
     * {@inheritdoc}
45
     */
46 1
    public function __construct($name)
47
    {
48 1
        parent::__construct($name);
49 1
        $this->engine = new Engine();
50 1
    }
51
52
    /**
53
     * @param Parser $parser
54
     *
55
     * @throws \Doctrine\ORM\Query\QueryException
56
     */
57 1
    public function parse(Parser $parser)
58
    {
59 1
        $parser->match(Lexer::T_IDENTIFIER);
60 1
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
61
62 1
        $this->maskField = $parser->ArithmeticPrimary();
63 1
        $this->deleteDeferredPath($parser, $this->maskField);
64
65 1
        $parser->match(Lexer::T_COMMA);
66 1
        $this->findValue = $parser->ArithmeticPrimary();
67
68 1
        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
69 1
        $this->parserResult = $parser->getParserResult();
70 1
    }
71
72
    /**
73
     * @param SqlWalker $sqlWalker
74
     *
75
     * @return string
76
     * @throws \Doctrine\ORM\Query\AST\ASTException
77
     */
78 1
    public function getSql(SqlWalker $sqlWalker)
79
    {
80 1
        $value = $this->findValue->dispatch($sqlWalker);
81 1
        $aliasTable = $this->maskField->identificationVariable;
82 1
        $field = $this->maskField->field;
83
84 1
        $queryComponent = $sqlWalker->getQueryComponent($aliasTable);
85
        /** @var \Doctrine\ORM\Mapping\ClassMetadata $classMetadata */
86 1
        $classMetadata = $queryComponent['metadata'];
87
88 1
        $maskAnnotation = MetadataLayer::getMaskAnnotation($classMetadata, $field);
89 1
        $columnAlias = $this->getColumnAlias($this->parserResult, $maskAnnotation);
90
91 1
        $maskReflection = MetadataLayer::getMaskReflection($classMetadata, $field);
92 1
        $valueCompressed = $this->engine->getPackedValue(
93 1
            0,
94
            [
0 ignored issues
show
Documentation introduced by
array(array(\KonstantinK...ON => $maskAnnotation)) is of type array<integer,array<stri...\\Annotation\\Mask>>"}>, but the function expects a array<integer,object<Kon...ields\Annotation\Mask>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
95
                [
96 1
                    MetadataLayer::REFLECTION => $maskReflection,
97 1
                    MetadataLayer::ANNOTATION => $maskAnnotation,
98
                ],
99
            ],
100 1
            [$value]
101
        );
102
103 1
        return "( {$columnAlias} & {$valueCompressed} = {$valueCompressed} )";
104
    }
105
106
    /**
107
     * @param \Doctrine\ORM\Query\ParserResult                           $parserResult
108
     * @param \KonstantinKuklin\DoctrineCompressedFields\Annotation\Mask $maskAnnotation
109
     *
110
     * @return string
111
     */
112 1
    private function getColumnAlias($parserResult, $maskAnnotation)
113
    {
114 1
        $resultSetMapping = $parserResult->getResultSetMapping();
115 1
        $fieldMappings = $resultSetMapping->fieldMappings;
116 1
        $fieldMappingsFlipped = array_flip($fieldMappings);
117
118 1
        return $fieldMappingsFlipped[$maskAnnotation->property];
119
    }
120
121
    /**
122
     * @param Parser $parser
123
     * @param mixed  $object
124
     *
125
     * @throws \ReflectionException
126
     */
127 1
    private function deleteDeferredPath($parser, $object)
128
    {
129 1
        $reflectionParser = new ReflectionClass($parser);
130 1
        $deferredPathExpressionsReflection = $reflectionParser->getProperty('deferredPathExpressions');
131 1
        $deferredPathExpressionsReflection->setAccessible(true);
132 1
        $deferredPathExpressions = $deferredPathExpressionsReflection->getValue($parser);
133 1
        $hash = spl_object_hash($object);
134
135 1
        $deferredPathExpressions = array_filter(
136 1
            $deferredPathExpressions,
137 1
            function ($item) use ($hash) {
138 1
                return $hash !== spl_object_hash($item['expression']);
139 1
            }
140
        );
141
        $deferredPathExpressionsReflection->setValue($parser, $deferredPathExpressions);
142
    }
143
}
144