Passed
Push — master ( c8b964...62d480 )
by Andrea
18:48 queued 12s
created

TabellaQueryTrait::biQueryBuilder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 12
ccs 10
cts 10
cp 1
crap 1
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
namespace Cdf\BiCoreBundle\Utils\Tabella;
4
5
use Doctrine\ORM\Tools\Pagination\Paginator;
6
use Doctrine\Common\Collections\Expr\Comparison;
7
use Cdf\BiCoreBundle\Utils\FieldType\FieldTypeUtils;
8
use function count;
9
10
trait TabellaQueryTrait
11
{
12 12
    protected function biQueryBuilder()
13
    {
14 12
        $nometabellaalias = $this->generaAlias($this->tablename);
0 ignored issues
show
Bug introduced by
It seems like generaAlias() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

14
        /** @scrutinizer ignore-call */ 
15
        $nometabellaalias = $this->generaAlias($this->tablename);
Loading history...
15 12
        $qb = $this->em->createQueryBuilder()
16 12
                ->select(array($nometabellaalias))
17 12
                ->from($this->entityname, $nometabellaalias);
18 12
        $campi = array_keys($this->em->getMetadataFactory()->getMetadataFor($this->entityname)->reflFields);
19 12
        $this->recursiveJoin($qb, $campi, $this->tablename, $nometabellaalias);
20 12
        $this->buildWhere($qb);
21 12
        $this->orderByBuilder($qb);
22
23 12
        return $qb;
24
    }
25
26 12
    protected function recursiveJoin(&$qb, $campi, $nometabella, $alias, $ancestors = array())
27
    {
28 12
        foreach ($campi as $campo) {
29 12
            if (false !== strpos(strtolower($campo), 'relatedby')) {
30
                continue;
31
            }
32 12
            if (!in_array($nometabella, $ancestors)) {
33 12
                $ancestors[] = $nometabella;
34
            }
35
36 12
            $configurazionecampo = isset($this->configurazionecolonnetabella[ucfirst(implode('.', $ancestors)).'.'.$campo]) ?
37 12
                    $this->configurazionecolonnetabella[ucfirst(implode('.', $ancestors)).'.'.$campo] : false;
38 12
            if ($configurazionecampo && true === $configurazionecampo['association']) {
39
                // crea la relazione con $padre = $nometabella in corso e figlio = $nomecampo con $alias generato
40 6
                if ((isset($configurazionecampo['sourceentityclass'])) && (null !== $configurazionecampo['sourceentityclass'])) {
41 6
                    $entitysrc = $configurazionecampo['sourceentityclass'];
42 6
                    $nometabellasrc = $this->em->getClassMetadata($entitysrc)->getTableName();
43
                } else {
44
                    $nometabellasrc = $nometabella;
45
                }
46
47 6
                $entitytarget = $configurazionecampo['associationtable']['targetEntity'];
48 6
                $nometabellatarget = $this->em->getClassMetadata($entitytarget)->getTableName();
49 6
                $aliastarget = $this->generaAlias($nometabellatarget, $nometabellasrc, $ancestors);
50
                //$qb->leftJoin($alias . "." . $configurazionecampo["nomecampo"], $aliastarget);
51
                //$camporelazionejoin = strtolower(substr($configurazionecampo["nomecampo"], strpos($configurazionecampo["nomecampo"], ".") + 1));
52 6
                $parti = explode('.', $configurazionecampo['nomecampo']);
53
54 6
                $camporelazionejoin = strtolower($parti[count($parti) - 1]);
55 6
                $qb->leftJoin($alias.'.'.$camporelazionejoin, $aliastarget);
56 6
                $campitarget = array_keys($this->em->getMetadataFactory()->getMetadataFor($entitytarget)->reflFields);
57 6
                $this->recursiveJoin($qb, $campitarget, $nometabellatarget, $aliastarget, $ancestors);
58
59
                // lancia rescursiveJoin su questo campo con padre = $aliasgenerato
60
                // --- figlio = $nomecampo
61
                // --- alias = alias generato nuovo
62
            }
63
        }
64 12
    }
65
66 12
    protected function buildWhere(&$qb)
67
    {
68
69 12
        $filtro = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $filtro is dead and can be removed.
Loading history...
70 12
        $prefiltro = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $prefiltro is dead and can be removed.
Loading history...
71 12
        foreach ($this->prefiltri as $key => $prefiltro) {
72 2
            $this->prefiltri[$key]['prefiltro'] = true;
0 ignored issues
show
Bug Best Practice introduced by
The property prefiltri does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
73
        }
74 12
        foreach ($this->filtri as $key => $filtro) {
75 2
            $this->filtri[$key]['prefiltro'] = false;
0 ignored issues
show
Bug Best Practice introduced by
The property filtri does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
76
        }
77 12
        $tuttifiltri = array_merge($this->filtri, $this->prefiltri);
78 12
        $parametribag = array();
79 12
        if (count($tuttifiltri)) {
80 3
            $descrizionefiltri = '';
81 3
            foreach ($tuttifiltri as $num => $filtrocorrente) {
82 3
                $tablename = substr($filtrocorrente['nomecampo'], 0, strripos($filtrocorrente['nomecampo'], '.'));
83 3
                $alias = $this->findAliasByTablename($tablename);
0 ignored issues
show
Bug introduced by
It seems like findAliasByTablename() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

83
                /** @scrutinizer ignore-call */ 
84
                $alias = $this->findAliasByTablename($tablename);
Loading history...
84 3
                $fieldname = $alias.'.'.(substr($filtrocorrente['nomecampo'], strripos($filtrocorrente['nomecampo'], '.') + 1));
85 3
                $fieldvalue = $this->getFieldValue($filtrocorrente['valore']);
0 ignored issues
show
Bug introduced by
It seems like getFieldValue() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

85
                /** @scrutinizer ignore-call */ 
86
                $fieldvalue = $this->getFieldValue($filtrocorrente['valore']);
Loading history...
86 3
                $fieldoperator = $this->getOperator($filtrocorrente['operatore']);
0 ignored issues
show
Bug introduced by
The method getOperator() does not exist on Cdf\BiCoreBundle\Utils\Tabella\TabellaQueryTrait. Did you maybe mean getApiOperator()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

86
                /** @scrutinizer ignore-call */ 
87
                $fieldoperator = $this->getOperator($filtrocorrente['operatore']);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
87 3
                $fitrocorrenteqp = 'fitrocorrente'.$num;
88 3
                $filtronomecampocorrente = $this->findFieldnameByAlias($filtrocorrente['nomecampo']);
0 ignored issues
show
Bug introduced by
It seems like findFieldnameByAlias() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

88
                /** @scrutinizer ignore-call */ 
89
                $filtronomecampocorrente = $this->findFieldnameByAlias($filtrocorrente['nomecampo']);
Loading history...
89 2
                $criteria = new ParametriQueryTabellaDecoder(
90 2
                    $fieldname,
91
                    $fieldoperator,
92
                    $fieldvalue,
93
                    $fitrocorrenteqp,
94
                    $filtronomecampocorrente
95
                );
96
97 2
                $querycriteria = $criteria->getQueryCriteria();
98 2
                $queryparameter = $criteria->getQueryParameters();
99
100 2
                if ($querycriteria) {
101 2
                    $qb->andWhere($querycriteria);
102 2
                    $parametribag = array_merge($queryparameter, $parametribag);
103
                } else {
104 2
                    $qb->andWhere($fieldname.' '.$fieldoperator.' '.":$fitrocorrenteqp");
105 2
                    $parametribag = array_merge(array($fitrocorrenteqp => $fieldvalue), $parametribag);
106
                }
107 2
                $this->getDescrizioneFiltro($descrizionefiltri, $filtrocorrente, $criteria);
0 ignored issues
show
Bug introduced by
It seems like getDescrizioneFiltro() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

107
                $this->/** @scrutinizer ignore-call */ 
108
                       getDescrizioneFiltro($descrizionefiltri, $filtrocorrente, $criteria);
Loading history...
108
            }
109 2
            $this->traduzionefiltri = substr($descrizionefiltri, 2);
0 ignored issues
show
Bug Best Practice introduced by
The property traduzionefiltri does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
110
        }
111 12
        $qb->setParameters($parametribag);
112
113 12
        if (isset($this->wheremanuale)) {
114
            $qb->andWhere($this->wheremanuale);
115
        }
116 12
    }
117
118 12
    protected function orderByBuilder(&$qb)
119
    {
120 12
        foreach ($this->colonneordinamento as $nomecampo => $tipoordinamento) {
121 10
            $tablename = substr($nomecampo, 0, strripos($nomecampo, '.'));
122 10
            $alias = $this->getAliasGenerato($tablename);
0 ignored issues
show
Bug introduced by
It seems like getAliasGenerato() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

122
            /** @scrutinizer ignore-call */ 
123
            $alias = $this->getAliasGenerato($tablename);
Loading history...
123 10
            $fieldname = $alias.'.'.(substr($nomecampo, strripos($nomecampo, '.') + 1));
124 10
            $qb->addOrderBy($fieldname, $tipoordinamento);
125
        }
126 12
    }
127
128
129
    /**
130
     * Attempt to translate the user given value into a boolean valid field
131
     */
132
    private function translateBoolValue($fieldvalue)
133
    {
134
        switch (strtoupper($fieldvalue)) {
135
            case 'SI':
136
                $fieldvalue = 'true';
137
                break;
138
            case '1':
139
                $fieldvalue = 'true';
140
                break;
141
            case 'NO':
142
                $fieldvalue = 'false';
143
                break;
144
            case '0':
145
                $fieldvalue = 'false';
146
                break;
147
            default:
148
                $fieldvalue = 'false';
149
                break;
150
        }
151
        return $fieldvalue;
152
    }
153
154
    /**
155
     * It appends the new filter string part to the given filter string ($filterString)
156
     */
157
    private function appendFilterString(String &$filterString, $swaggerType, $swaggerKind, $fieldvalue)
158
    {
159
        if ($swaggerKind == 'bool') {
160
            $filterString .= $this->translateBoolValue($fieldvalue);
161
        } elseif ($swaggerType == null /*|| $swaggerFormats[ $nomeCampo ] == 'datetime'*/) {
162
            //"%" chars will be applied by insurance back-end API
163
            $filterString .= '"'.$fieldvalue.'"';
164
        } elseif ($swaggerType == 'datetime' || $swaggerType == 'date') {
165
            $fieldvalue = \str_replace("/", "-", $fieldvalue);
166
            //does it contain an hour ?
167
            $hour = strpos($fieldvalue, ":");
168
            $time = strtotime($fieldvalue);
169
            $backend_format = FieldTypeUtils::getEnvVar("BE_DATETIME_FORMAT", "Y-m-d\TH:i:sP");
170
            if ($hour === false) {
171
                $backend_format = FieldTypeUtils::getEnvVar("BE_DATE_FORMAT", "Y-m-d");
172
            }
173
            $filter = date($backend_format, $time);
174
            $filterString .= $filter;
175
        } else {
176
            $filterString .= $fieldvalue;
177
        }
178
    }
179
180
    /**
181
     * It composes filtering string to be used with api rest services
182
     */
183
    protected function filterByApiBuilder(): ?String
184
    {
185
        $filterString = null;
186
        $filtro = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $filtro is dead and can be removed.
Loading history...
187
        $prefiltro = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $prefiltro is dead and can be removed.
Loading history...
188
        foreach ($this->prefiltri as $key => $prefiltro) {
189
            $this->prefiltri[$key]['prefiltro'] = true;
0 ignored issues
show
Bug Best Practice introduced by
The property prefiltri does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
190
        }
191
        foreach ($this->filtri as $key => $filtro) {
192
            $this->filtri[$key]['prefiltro'] = false;
0 ignored issues
show
Bug Best Practice introduced by
The property filtri does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
193
        }
194
        $tuttifiltri = array_merge($this->filtri, $this->prefiltri);
195
        //$parametribag = array();
196
        if (count($tuttifiltri)) {
197
            $attributeMap = $this->entityname::attributeMap();
198
            $swaggerFormats = $this->entityname::swaggerFormats();
199
            $swaggerTypes = $this->entityname::swaggerTypes();
200
            //compose the string
201
            $descrizionefiltri = '';
202
            foreach ($tuttifiltri as $num => $filtrocorrente) {
203
                $nomeCampo = substr($filtrocorrente['nomecampo'], strripos($filtrocorrente['nomecampo'], '.') + 1);
204
                $fieldname = ' '.$nomeCampo;
205
                $filteringValues = $this->getFieldValue($filtrocorrente['valore']);
206
                $fieldoperator = $this->getOperator($filtrocorrente['operatore']);
207
                $fitrocorrenteqp = 'fitrocorrente'.$num;
208
                $filtronomecampocorrente = $this->findFieldnameByAlias($filtrocorrente['nomecampo']);
209
210
                $criteria = new ParametriQueryTabellaDecoder(
211
                    $fieldname,
212
                    $fieldoperator,
213
                    $filteringValues,
214
                    $fitrocorrenteqp,
215
                    $filtronomecampocorrente
216
                );
217
218
                if (is_array($filteringValues)) {
219
                    $fieldstring =  '( ';
220
                    foreach ($filteringValues as $num => $filterValue) {
0 ignored issues
show
Comprehensibility Bug introduced by
$num is overwriting a variable from outer foreach loop.
Loading history...
221
                        $fieldstring .= $attributeMap[ $nomeCampo ];
222
                        $fieldstring .= ' '.$this->getApiOperator($filtrocorrente['operatore']).' ';
223
                        $fieldvalue = urldecode($filterValue);
224
                        $this->appendFilterString($fieldstring, $swaggerFormats[ $nomeCampo ], $swaggerTypes[ $nomeCampo ], $fieldvalue);
225
                        if ($num < count($filteringValues)-1) {
226
                            $fieldstring .= ' OR ';
227
                        }
228
                    }
229
                    $fieldstring .=  ' )';
230
                } else {
231
                    $fieldstring = $attributeMap[ $nomeCampo ];
232
                    $fieldstring .= ' '.$this->getApiOperator($filtrocorrente['operatore']).' ';
233
                    $fieldvalue = urldecode($filteringValues);
0 ignored issues
show
Unused Code introduced by
The assignment to $fieldvalue is dead and can be removed.
Loading history...
234
                    $this->appendFilterString($fieldstring, $swaggerFormats[ $nomeCampo ], $swaggerTypes[ $nomeCampo ], $filteringValues);
235
                }
236
237
                if ($filterString != null) {
238
                    $filterString .= ' AND ';
239
                }
240
                $filterString .= $fieldstring;
241
                $this->getDescrizioneFiltro($descrizionefiltri, $filtrocorrente, $criteria);
242
            }
243
            $this->traduzionefiltri = substr($descrizionefiltri, 2);
0 ignored issues
show
Bug Best Practice introduced by
The property traduzionefiltri does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
244
        }
245
        return $filterString;
246
    }
247
248
    /**
249
     * Return the operator to be used
250
     */
251
    private function getApiOperator($operator)
252
    {
253
        switch (strtoupper($operator)) {
254
            case Comparison::CONTAINS:
255
                $operator = '~';
256
                break;
257
            /*case 'IN':
258
                $operator = Comparison::IN;
259
                break;
260
            case 'NOT IN':
261
                $operator = Comparison::NIN;
262
                break;*/
263
            default:
264
                $operator = '=';
265
                break;
266
        }
267
268
        return $operator;
269
    }
270
271
    /**
272
     * Build the ordering string compliant with API REST services
273
     */
274
    protected function orderByApiBuilder(): ?String
275
    {
276
        $attributeMap = $this->entityname::attributeMap();
277
        $orderingString = null;
278
        foreach ($this->colonneordinamento as $nomecampo => $tipoordinamento) {
279
            $fieldname = $attributeMap[ substr($nomecampo, strripos($nomecampo, '.') + 1) ];
280
            $fieldname .= ':'.$tipoordinamento;
281
            if ($orderingString != null) {
282
                $orderingString .= ',';
283
            }
284
            $orderingString .= $fieldname;
285
        }
286
        return $orderingString;
287
    }
288
289 12
    public function getRecordstabella()
290
    {
291
        //Look for all tables
292 12
        $qb = $this->biQueryBuilder();
293
294 12
        if (false === $this->estraituttirecords) {
0 ignored issues
show
Bug introduced by
The property estraituttirecords does not exist on Cdf\BiCoreBundle\Utils\Tabella\TabellaQueryTrait. Did you mean records?
Loading history...
295 12
            $paginator = new Paginator($qb, true);
296 12
            $this->righetotali = count($paginator);
0 ignored issues
show
Bug Best Practice introduced by
The property righetotali does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
297 12
            $this->paginetotali = (int) $this->calcolaPagineTotali($this->getRigheperpagina());
0 ignored issues
show
Bug Best Practice introduced by
The property paginetotali does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
Bug introduced by
It seems like getRigheperpagina() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

297
            $this->paginetotali = (int) $this->calcolaPagineTotali($this->/** @scrutinizer ignore-call */ getRigheperpagina());
Loading history...
Bug introduced by
It seems like calcolaPagineTotali() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

297
            $this->paginetotali = (int) $this->/** @scrutinizer ignore-call */ calcolaPagineTotali($this->getRigheperpagina());
Loading history...
298
            /* imposta l'offset, ovvero il record dal quale iniziare a visualizzare i dati */
299 12
            $offsetrecords = ($this->getRigheperpagina() * ($this->getPaginacorrente() - 1));
0 ignored issues
show
Bug introduced by
It seems like getPaginacorrente() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

299
            $offsetrecords = ($this->getRigheperpagina() * ($this->/** @scrutinizer ignore-call */ getPaginacorrente() - 1));
Loading history...
300
301
            /* Imposta il limite ai record da estrarre */
302 12
            if ($this->getRigheperpagina()) {
303 12
                $qb = $qb->setMaxResults($this->getRigheperpagina());
304
            }
305
            /* E imposta il primo record da visualizzare (per la paginazione) */
306 12
            if ($offsetrecords) {
307
                $qb = $qb->setFirstResult($offsetrecords);
308
            }
309
            /* Dall'oggetto querybuilder si ottiene la query da eseguire */
310 12
            $recordsets = $qb->getQuery()->getResult();
311
        } else {
312
            /* Dall'oggetto querybuilder si ottiene la query da eseguire */
313 4
            $recordsets = $qb->getQuery()->getResult();
314 4
            $this->righetotali = count($recordsets);
315 4
            $this->paginetotali = 1;
316
        }
317
318 12
        $this->records = array();
0 ignored issues
show
Bug Best Practice introduced by
The property records does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
319 12
        $rigatabellahtml = array();
320 12
        foreach ($recordsets as $record) {
321 12
            $this->records[$record->getId()] = $record;
322 12
            unset($rigatabellahtml);
323
        }
324
325 12
        return $this->records;
326
    }
327
328
    /**
329
     * Read the API in order to obtains the pages features
330
     */
331
    public function getApiRecordstabella()
332
    {
333
        $newApi = $this->apiController;
334
        $apiController = new $newApi();
335
336
        if (false === $this->estraituttirecords) {
0 ignored issues
show
Bug introduced by
The property estraituttirecords does not exist on Cdf\BiCoreBundle\Utils\Tabella\TabellaQueryTrait. Did you mean records?
Loading history...
337
            $countMethod = $this->apiBook->getCount();
338
            
339
            $count = $apiController->$countMethod();
340
            $this->righetotali = $count;
0 ignored issues
show
Bug Best Practice introduced by
The property righetotali does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
341
            $this->paginetotali = (int) $this->calcolaPagineTotali($this->getRigheperpagina());
0 ignored issues
show
Bug Best Practice introduced by
The property paginetotali does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
342
            /* imposta l'offset, ovvero il record dal quale iniziare a visualizzare i dati */
343
            $offsetrecords = ($this->getRigheperpagina() * ($this->getPaginacorrente() - 1));
344
345
            /*$offset = null, $limit = null, $sort = null, $condition = null*/
346
            $paginationMethod = $this->apiBook->getAll();
347
            //dump($this->filterByApiBuilder());
348
349
            $recordsets = $apiController->$paginationMethod(
350
                $offsetrecords,
351
                $this->getRigheperpagina(),
352
                $this->orderByApiBuilder(),
353
                $this->filterByApiBuilder()
354
            );
355
        //dump($recordsets);
356
        } else {
357
            /* Dall'oggetto querybuilder si ottiene la query da eseguire */
358
            $paginationMethod = $this->apiBook->getAll();
359
            $recordsets = $apiController->$paginationMethod(0, null, $this->orderByApiBuilder(), $this->filterByApiBuilder());
360
            $this->paginetotali = 1;
361
            $this->righetotali = count($recordsets);
362
        }
363
        $this->records = array();
0 ignored issues
show
Bug Best Practice introduced by
The property records does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
364
        $rigatabellahtml = array();
365
        foreach ($recordsets as $record) {
366
            $this->records[$record->getId()] = $record;
367
            unset($rigatabellahtml);
368
        }
369
370
        return $this->records;
371
    }
372
}
373