Completed
Push — master ( 9b05ea...0438db )
by Fabien
51:55
created
Classes/Persistence/Query.php 1 patch
Indentation   +637 added lines, -637 removed lines patch added patch discarded remove patch
@@ -24,642 +24,642 @@
 block discarded – undo
24 24
 class Query implements QueryInterface
25 25
 {
26 26
 
27
-    /**
28
-     * An inner join.
29
-     */
30
-    const JCR_JOIN_TYPE_INNER = '{http://www.jcp.org/jcr/1.0}joinTypeInner';
31
-
32
-    /**
33
-     * A left-outer join.
34
-     */
35
-    const JCR_JOIN_TYPE_LEFT_OUTER = '{http://www.jcp.org/jcr/1.0}joinTypeLeftOuter';
36
-
37
-    /**
38
-     * A right-outer join.
39
-     */
40
-    const JCR_JOIN_TYPE_RIGHT_OUTER = '{http://www.jcp.org/jcr/1.0}joinTypeRightOuter';
41
-
42
-    /**
43
-     * Charset of strings in QOM
44
-     */
45
-    const CHARSET = 'utf-8';
46
-
47
-    /**
48
-     * @var string
49
-     */
50
-    protected $sourceFieldName;
51
-
52
-    /**
53
-     * @var string
54
-     */
55
-    protected $type;
56
-
57
-    /**
58
-     * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
59
-     */
60
-    protected $persistenceManager;
61
-
62
-    /**
63
-     * @var \TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory
64
-     */
65
-    protected $qomFactory;
66
-
67
-    /**
68
-     * @var \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface
69
-     */
70
-    protected $source;
71
-
72
-    /**
73
-     * @var ConstraintInterface
74
-     */
75
-    protected $constraint;
76
-
77
-    /**
78
-     * @var \TYPO3\CMS\Extbase\Persistence\Generic\Qom\Statement
79
-     */
80
-    protected $statement;
81
-
82
-    /**
83
-     * @var array
84
-     */
85
-    protected $orderings = [];
86
-
87
-    /**
88
-     * @var int
89
-     */
90
-    protected $limit;
91
-
92
-    /**
93
-     * @var int
94
-     */
95
-    protected $offset;
96
-
97
-    /**
98
-     * Apply DISTINCT upon property.
99
-     *
100
-     * @var string
101
-     */
102
-    protected $distinct;
103
-
104
-    /**
105
-     * The query settings.
106
-     *
107
-     * @var \Fab\Vidi\Persistence\QuerySettings
108
-     * @inject
109
-     */
110
-    protected $querySettings;
111
-
112
-    /**
113
-     * Constructs a query object working on the given class name
114
-     *
115
-     * @param string $type
116
-     */
117
-    public function __construct($type)
118
-    {
119
-        $this->type = $type;
120
-    }
121
-
122
-    /**
123
-     * Injects the persistence manager, used to fetch the CR session
124
-     *
125
-     * @param \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager
126
-     * @return void
127
-     */
128
-    public function injectPersistenceManager(\TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager)
129
-    {
130
-        $this->persistenceManager = $persistenceManager;
131
-    }
132
-
133
-    /**
134
-     * Injects the Query Object Model Factory
135
-     *
136
-     * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory $qomFactory
137
-     * @return void
138
-     */
139
-    public function injectQomFactory(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory $qomFactory)
140
-    {
141
-        $this->qomFactory = $qomFactory;
142
-    }
143
-
144
-    /**
145
-     * Sets the Query Settings. These Query settings must match the settings expected by
146
-     * the specific Storage Backend.
147
-     *
148
-     * @param \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings The Query Settings
149
-     * @return void
150
-     * @api This method is not part of FLOW3 API
151
-     */
152
-    public function setQuerySettings(\TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings)
153
-    {
154
-        $this->querySettings = $querySettings;
155
-    }
156
-
157
-    /**
158
-     * Returns the Query Settings.
159
-     *
160
-     * @throws \Exception
161
-     * @return \Fab\Vidi\Persistence\QuerySettings $querySettings The Query Settings
162
-     * @api This method is not part of FLOW3 API
163
-     */
164
-    public function getQuerySettings()
165
-    {
166
-        if (!$this->querySettings instanceof \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface) {
167
-            throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception('Tried to get the query settings without setting them before.', 1248689115);
168
-        }
169
-
170
-        // Apply possible settings to the query.
171
-        if ($this->isBackendMode()) {
172
-            /** @var \TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager $backendConfigurationManager */
173
-            $backendConfigurationManager = $this->getObjectManager()->get('TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager');
174
-            $configuration = $backendConfigurationManager->getTypoScriptSetup();
175
-            $querySettings = array('respectSysLanguage');
176
-            foreach ($querySettings as $setting) {
177
-                if (isset($configuration['config.']['tx_vidi.']['persistence.']['backend.'][$this->type . '.'][$setting])) {
178
-                    $value = (bool)$configuration['config.']['tx_vidi.']['persistence.']['backend.'][$this->type . '.'][$setting];
179
-                    ObjectAccess::setProperty($this->querySettings, $setting, $value);
180
-                }
181
-            }
182
-        }
183
-
184
-        return $this->querySettings;
185
-    }
186
-
187
-    /**
188
-     * Returns the type this query cares for.
189
-     *
190
-     * @return string
191
-     * @api
192
-     */
193
-    public function getType()
194
-    {
195
-        return $this->type;
196
-    }
197
-
198
-    /**
199
-     * Sets the source to fetch the result from
200
-     *
201
-     * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source
202
-     */
203
-    public function setSource(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source)
204
-    {
205
-        $this->source = $source;
206
-    }
207
-
208
-    /**
209
-     * Returns the selectorn name or an empty string, if the source is not a selector
210
-     * TODO This has to be checked at another place
211
-     *
212
-     * @return string The selector name
213
-     */
214
-    protected function getSelectorName()
215
-    {
216
-        if ($this->getSource() instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SelectorInterface) {
217
-            return $this->source->getSelectorName();
218
-        } else {
219
-            return '';
220
-        }
221
-    }
222
-
223
-    /**
224
-     * Gets the node-tuple source for this query.
225
-     *
226
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface the node-tuple source; non-null
227
-     */
228
-    public function getSource()
229
-    {
230
-        if ($this->source === null) {
231
-            $this->source = $this->qomFactory->selector($this->getType());
232
-        }
233
-        return $this->source;
234
-    }
235
-
236
-    /**
237
-     * Executes the query against the database and returns the result
238
-     *
239
-     * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface|array The query result object or an array if $this->getQuerySettings()->getReturnRawQueryResult() is true
240
-     * @api
241
-     */
242
-    public function execute($returnRawQueryResult = false)
243
-    {
244
-        /** @var VidiDbBackend $backend */
245
-        $backend = $this->getObjectManager()->get(VidiDbBackend::class, $this);
246
-        return $backend->fetchResult();
247
-    }
248
-
249
-    /**
250
-     * Sets the property names to order the result by. Expected like this:
251
-     * array(
252
-     * 'foo' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
253
-     * 'bar' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
254
-     * )
255
-     * where 'foo' and 'bar' are property names.
256
-     *
257
-     * @param array $orderings The property names to order by
258
-     * @return QueryInterface
259
-     * @api
260
-     */
261
-    public function setOrderings(array $orderings)
262
-    {
263
-        $this->orderings = $orderings;
264
-        return $this;
265
-    }
266
-
267
-    /**
268
-     * Returns the property names to order the result by. Like this:
269
-     * array(
270
-     * 'foo' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
271
-     * 'bar' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
272
-     * )
273
-     *
274
-     * @return array
275
-     */
276
-    public function getOrderings()
277
-    {
278
-        return $this->orderings;
279
-    }
280
-
281
-    /**
282
-     * Sets the maximum size of the result set to limit. Returns $this to allow
283
-     * for chaining (fluid interface)
284
-     *
285
-     * @param integer $limit
286
-     * @throws \InvalidArgumentException
287
-     * @return QueryInterface
288
-     * @api
289
-     */
290
-    public function setLimit($limit)
291
-    {
292
-        if (!is_int($limit) || $limit < 1) {
293
-            throw new \InvalidArgumentException('The limit must be an integer >= 1', 1245071870);
294
-        }
295
-        $this->limit = $limit;
296
-        return $this;
297
-    }
298
-
299
-    /**
300
-     * Resets a previously set maximum size of the result set. Returns $this to allow
301
-     * for chaining (fluid interface)
302
-     *
303
-     * @return QueryInterface
304
-     * @api
305
-     */
306
-    public function unsetLimit()
307
-    {
308
-        unset($this->limit);
309
-        return $this;
310
-    }
311
-
312
-    /**
313
-     * Returns the maximum size of the result set to limit.
314
-     *
315
-     * @return integer
316
-     * @api
317
-     */
318
-    public function getLimit()
319
-    {
320
-        return $this->limit;
321
-    }
322
-
323
-    /**
324
-     * Sets the start offset of the result set to offset. Returns $this to
325
-     * allow for chaining (fluid interface)
326
-     *
327
-     * @param integer $offset
328
-     * @throws \InvalidArgumentException
329
-     * @return QueryInterface
330
-     * @api
331
-     */
332
-    public function setOffset($offset)
333
-    {
334
-        if (!is_int($offset) || $offset < 0) {
335
-            throw new \InvalidArgumentException('The offset must be a positive integer', 1245071872);
336
-        }
337
-        $this->offset = $offset;
338
-        return $this;
339
-    }
340
-
341
-    /**
342
-     * Returns the start offset of the result set.
343
-     *
344
-     * @return integer
345
-     * @api
346
-     */
347
-    public function getOffset()
348
-    {
349
-        return $this->offset;
350
-    }
351
-
352
-    /**
353
-     * The constraint used to limit the result set. Returns $this to allow
354
-     * for chaining (fluid interface)
355
-     *
356
-     * @param ConstraintInterface $constraint
357
-     * @return QueryInterface
358
-     * @api
359
-     */
360
-    public function matching($constraint)
361
-    {
362
-        $this->constraint = $constraint;
363
-        return $this;
364
-    }
365
-
366
-    /**
367
-     * Gets the constraint for this query.
368
-     *
369
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface the constraint, or null if none
370
-     * @api
371
-     */
372
-    public function getConstraint()
373
-    {
374
-        return $this->constraint;
375
-    }
376
-
377
-    /**
378
-     * Performs a logical conjunction of the given constraints. The method takes one or more contraints and concatenates them with a boolean AND.
379
-     * It also scepts a single array of constraints to be concatenated.
380
-     *
381
-     * @param mixed $constraint1 The first of multiple constraints or an array of constraints.
382
-     * @throws InvalidNumberOfConstraintsException
383
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\AndInterface
384
-     * @api
385
-     */
386
-    public function logicalAnd($constraint1)
387
-    {
388
-        if (is_array($constraint1)) {
389
-            $resultingConstraint = array_shift($constraint1);
390
-            $constraints = $constraint1;
391
-        } else {
392
-            $constraints = func_get_args();
393
-            $resultingConstraint = array_shift($constraints);
394
-        }
395
-        if ($resultingConstraint === null) {
396
-            throw new InvalidNumberOfConstraintsException('There must be at least one constraint or a non-empty array of constraints given.', 1401289500);
397
-        }
398
-        foreach ($constraints as $constraint) {
399
-            $resultingConstraint = $this->qomFactory->_and($resultingConstraint, $constraint);
400
-        }
401
-        return $resultingConstraint;
402
-    }
403
-
404
-    /**
405
-     * Performs a logical disjunction of the two given constraints
406
-     *
407
-     * @param mixed $constraint1 The first of multiple constraints or an array of constraints.
408
-     * @throws InvalidNumberOfConstraintsException
409
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\OrInterface
410
-     * @api
411
-     */
412
-    public function logicalOr($constraint1)
413
-    {
414
-        if (is_array($constraint1)) {
415
-            $resultingConstraint = array_shift($constraint1);
416
-            $constraints = $constraint1;
417
-        } else {
418
-            $constraints = func_get_args();
419
-            $resultingConstraint = array_shift($constraints);
420
-        }
421
-        if ($resultingConstraint === null) {
422
-            throw new InvalidNumberOfConstraintsException('There must be at least one constraint or a non-empty array of constraints given.', 1401289501);
423
-        }
424
-        foreach ($constraints as $constraint) {
425
-            $resultingConstraint = $this->qomFactory->_or($resultingConstraint, $constraint);
426
-        }
427
-        return $resultingConstraint;
428
-    }
429
-
430
-    /**
431
-     * Performs a logical negation of the given constraint
432
-     *
433
-     * @param ConstraintInterface $constraint Constraint to negate
434
-     * @throws \RuntimeException
435
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\NotInterface
436
-     * @api
437
-     */
438
-    public function logicalNot(ConstraintInterface $constraint)
439
-    {
440
-        return $this->qomFactory->not($constraint);
441
-    }
442
-
443
-    /**
444
-     * Returns an equals criterion used for matching objects against a query
445
-     *
446
-     * @param string $propertyName The name of the property to compare against
447
-     * @param mixed $operand The value to compare with
448
-     * @param boolean $caseSensitive Whether the equality test should be done case-sensitive
449
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
450
-     * @api
451
-     */
452
-    public function equals($propertyName, $operand, $caseSensitive = true)
453
-    {
454
-        if (is_object($operand) || $caseSensitive) {
455
-            $comparison = $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_EQUAL_TO, $operand);
456
-        } else {
457
-            $comparison = $this->qomFactory->comparison($this->qomFactory->lowerCase($this->qomFactory->propertyValue($propertyName, $this->getSelectorName())), QueryInterface::OPERATOR_EQUAL_TO, \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Charset\CharsetConverter::class)->conv_case(\TYPO3\CMS\Extbase\Persistence\Generic\Query::CHARSET, $operand, 'toLower'));
458
-        }
459
-        return $comparison;
460
-    }
461
-
462
-    /**
463
-     * Returns a like criterion used for matching objects against a query
464
-     *
465
-     * @param string $propertyName The name of the property to compare against
466
-     * @param mixed $operand The value to compare with
467
-     * @param boolean $caseSensitive Whether the matching should be done case-sensitive
468
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
469
-     * @api
470
-     */
471
-    public function like($propertyName, $operand, $caseSensitive = true)
472
-    {
473
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_LIKE, $operand);
474
-    }
475
-
476
-    /**
477
-     * Returns a "contains" criterion used for matching objects against a query.
478
-     * It matches if the multivalued property contains the given operand.
479
-     *
480
-     * @param string $propertyName The name of the (multivalued) property to compare against
481
-     * @param mixed $operand The value to compare with
482
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
483
-     * @api
484
-     */
485
-    public function contains($propertyName, $operand)
486
-    {
487
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_CONTAINS, $operand);
488
-    }
489
-
490
-    /**
491
-     * Returns an "in" criterion used for matching objects against a query. It
492
-     * matches if the property's value is contained in the multivalued operand.
493
-     *
494
-     * @param string $propertyName The name of the property to compare against
495
-     * @param mixed $operand The value to compare with, multivalued
496
-     * @throws UnexpectedTypeException
497
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
498
-     * @api
499
-     */
500
-    public function in($propertyName, $operand)
501
-    {
502
-        if (!is_array($operand) && !$operand instanceof \ArrayAccess && !$operand instanceof \Traversable) {
503
-            throw new UnexpectedTypeException('The "in" operator must be given a mutlivalued operand (array, ArrayAccess, Traversable).', 1264678095);
504
-        }
505
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_IN, $operand);
506
-    }
507
-
508
-    /**
509
-     * Returns a less than criterion used for matching objects against a query
510
-     *
511
-     * @param string $propertyName The name of the property to compare against
512
-     * @param mixed $operand The value to compare with
513
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
514
-     * @api
515
-     */
516
-    public function lessThan($propertyName, $operand)
517
-    {
518
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_LESS_THAN, $operand);
519
-    }
520
-
521
-    /**
522
-     * Returns a less or equal than criterion used for matching objects against a query
523
-     *
524
-     * @param string $propertyName The name of the property to compare against
525
-     * @param mixed $operand The value to compare with
526
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
527
-     * @api
528
-     */
529
-    public function lessThanOrEqual($propertyName, $operand)
530
-    {
531
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_LESS_THAN_OR_EQUAL_TO, $operand);
532
-    }
533
-
534
-    /**
535
-     * Returns a greater than criterion used for matching objects against a query
536
-     *
537
-     * @param string $propertyName The name of the property to compare against
538
-     * @param mixed $operand The value to compare with
539
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
540
-     * @api
541
-     */
542
-    public function greaterThan($propertyName, $operand)
543
-    {
544
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_GREATER_THAN, $operand);
545
-    }
546
-
547
-    /**
548
-     * Returns a greater than or equal criterion used for matching objects against a query
549
-     *
550
-     * @param string $propertyName The name of the property to compare against
551
-     * @param mixed $operand The value to compare with
552
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
553
-     * @api
554
-     */
555
-    public function greaterThanOrEqual($propertyName, $operand)
556
-    {
557
-        return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_GREATER_THAN_OR_EQUAL_TO, $operand);
558
-    }
559
-
560
-    /**
561
-     * Returns the query result count.
562
-     *
563
-     * @return integer The query result count
564
-     * @api
565
-     */
566
-    public function count()
567
-    {
568
-        /** @var VidiDbBackend $backend */
569
-        $backend = $this->getObjectManager()->get(VidiDbBackend::class, $this);
570
-        return $backend->countResult();
571
-    }
572
-
573
-    /**
574
-     * Returns an "isEmpty" criterion used for matching objects against a query.
575
-     * It matches if the multivalued property contains no values or is null.
576
-     *
577
-     * @param string $propertyName The name of the multivalued property to compare against
578
-     * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
579
-     * @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException if used on a single-valued property
580
-     * @api
581
-     */
582
-    public function isEmpty($propertyName)
583
-    {
584
-        throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException(__METHOD__);
585
-    }
586
-
587
-    /**
588
-     * @return string
589
-     */
590
-    public function getDistinct()
591
-    {
592
-        return $this->distinct;
593
-    }
594
-
595
-    /**
596
-     * @param string $distinct
597
-     * @return $this
598
-     */
599
-    public function setDistinct($distinct)
600
-    {
601
-        $this->distinct = $distinct;
602
-        return $this;
603
-    }
604
-
605
-    /**
606
-     * Sets the statement of this query. If you use this, you will lose the abstraction from a concrete storage
607
-     * backend (database).
608
-     *
609
-     * @param string|\TYPO3\CMS\Core\Database\PreparedStatement $statement The statement
610
-     * @param array $parameters An array of parameters. These will be bound to placeholders '?' in the $statement.
611
-     * @return QueryInterface
612
-     */
613
-    public function statement($statement, array $parameters = array())
614
-    {
615
-        $this->statement = $this->qomFactory->statement($statement, $parameters);
616
-        return $this;
617
-    }
618
-
619
-    /**
620
-     * Returns the statement of this query.
621
-     *
622
-     * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\Statement
623
-     */
624
-    public function getStatement()
625
-    {
626
-        return $this->statement;
627
-    }
628
-
629
-    /**
630
-     * Returns whether the current mode is Backend.
631
-     *
632
-     * @return bool
633
-     */
634
-    protected function isBackendMode()
635
-    {
636
-        return TYPO3_MODE == 'BE';
637
-    }
638
-
639
-    /**
640
-     * @return string
641
-     */
642
-    public function getSourceFieldName()
643
-    {
644
-        return $this->sourceFieldName;
645
-    }
646
-
647
-    /**
648
-     * @param string $sourceFieldName
649
-     * @return $this
650
-     */
651
-    public function setSourceFieldName($sourceFieldName)
652
-    {
653
-        $this->sourceFieldName = $sourceFieldName;
654
-        return $this;
655
-    }
656
-
657
-    /**
658
-     * @return object|\TYPO3\CMS\Extbase\Object\ObjectManager
659
-     */
660
-    protected function getObjectManager()
661
-    {
662
-        return GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
663
-    }
27
+	/**
28
+	 * An inner join.
29
+	 */
30
+	const JCR_JOIN_TYPE_INNER = '{http://www.jcp.org/jcr/1.0}joinTypeInner';
31
+
32
+	/**
33
+	 * A left-outer join.
34
+	 */
35
+	const JCR_JOIN_TYPE_LEFT_OUTER = '{http://www.jcp.org/jcr/1.0}joinTypeLeftOuter';
36
+
37
+	/**
38
+	 * A right-outer join.
39
+	 */
40
+	const JCR_JOIN_TYPE_RIGHT_OUTER = '{http://www.jcp.org/jcr/1.0}joinTypeRightOuter';
41
+
42
+	/**
43
+	 * Charset of strings in QOM
44
+	 */
45
+	const CHARSET = 'utf-8';
46
+
47
+	/**
48
+	 * @var string
49
+	 */
50
+	protected $sourceFieldName;
51
+
52
+	/**
53
+	 * @var string
54
+	 */
55
+	protected $type;
56
+
57
+	/**
58
+	 * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
59
+	 */
60
+	protected $persistenceManager;
61
+
62
+	/**
63
+	 * @var \TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory
64
+	 */
65
+	protected $qomFactory;
66
+
67
+	/**
68
+	 * @var \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface
69
+	 */
70
+	protected $source;
71
+
72
+	/**
73
+	 * @var ConstraintInterface
74
+	 */
75
+	protected $constraint;
76
+
77
+	/**
78
+	 * @var \TYPO3\CMS\Extbase\Persistence\Generic\Qom\Statement
79
+	 */
80
+	protected $statement;
81
+
82
+	/**
83
+	 * @var array
84
+	 */
85
+	protected $orderings = [];
86
+
87
+	/**
88
+	 * @var int
89
+	 */
90
+	protected $limit;
91
+
92
+	/**
93
+	 * @var int
94
+	 */
95
+	protected $offset;
96
+
97
+	/**
98
+	 * Apply DISTINCT upon property.
99
+	 *
100
+	 * @var string
101
+	 */
102
+	protected $distinct;
103
+
104
+	/**
105
+	 * The query settings.
106
+	 *
107
+	 * @var \Fab\Vidi\Persistence\QuerySettings
108
+	 * @inject
109
+	 */
110
+	protected $querySettings;
111
+
112
+	/**
113
+	 * Constructs a query object working on the given class name
114
+	 *
115
+	 * @param string $type
116
+	 */
117
+	public function __construct($type)
118
+	{
119
+		$this->type = $type;
120
+	}
121
+
122
+	/**
123
+	 * Injects the persistence manager, used to fetch the CR session
124
+	 *
125
+	 * @param \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager
126
+	 * @return void
127
+	 */
128
+	public function injectPersistenceManager(\TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager)
129
+	{
130
+		$this->persistenceManager = $persistenceManager;
131
+	}
132
+
133
+	/**
134
+	 * Injects the Query Object Model Factory
135
+	 *
136
+	 * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory $qomFactory
137
+	 * @return void
138
+	 */
139
+	public function injectQomFactory(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory $qomFactory)
140
+	{
141
+		$this->qomFactory = $qomFactory;
142
+	}
143
+
144
+	/**
145
+	 * Sets the Query Settings. These Query settings must match the settings expected by
146
+	 * the specific Storage Backend.
147
+	 *
148
+	 * @param \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings The Query Settings
149
+	 * @return void
150
+	 * @api This method is not part of FLOW3 API
151
+	 */
152
+	public function setQuerySettings(\TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface $querySettings)
153
+	{
154
+		$this->querySettings = $querySettings;
155
+	}
156
+
157
+	/**
158
+	 * Returns the Query Settings.
159
+	 *
160
+	 * @throws \Exception
161
+	 * @return \Fab\Vidi\Persistence\QuerySettings $querySettings The Query Settings
162
+	 * @api This method is not part of FLOW3 API
163
+	 */
164
+	public function getQuerySettings()
165
+	{
166
+		if (!$this->querySettings instanceof \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface) {
167
+			throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception('Tried to get the query settings without setting them before.', 1248689115);
168
+		}
169
+
170
+		// Apply possible settings to the query.
171
+		if ($this->isBackendMode()) {
172
+			/** @var \TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager $backendConfigurationManager */
173
+			$backendConfigurationManager = $this->getObjectManager()->get('TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager');
174
+			$configuration = $backendConfigurationManager->getTypoScriptSetup();
175
+			$querySettings = array('respectSysLanguage');
176
+			foreach ($querySettings as $setting) {
177
+				if (isset($configuration['config.']['tx_vidi.']['persistence.']['backend.'][$this->type . '.'][$setting])) {
178
+					$value = (bool)$configuration['config.']['tx_vidi.']['persistence.']['backend.'][$this->type . '.'][$setting];
179
+					ObjectAccess::setProperty($this->querySettings, $setting, $value);
180
+				}
181
+			}
182
+		}
183
+
184
+		return $this->querySettings;
185
+	}
186
+
187
+	/**
188
+	 * Returns the type this query cares for.
189
+	 *
190
+	 * @return string
191
+	 * @api
192
+	 */
193
+	public function getType()
194
+	{
195
+		return $this->type;
196
+	}
197
+
198
+	/**
199
+	 * Sets the source to fetch the result from
200
+	 *
201
+	 * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source
202
+	 */
203
+	public function setSource(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface $source)
204
+	{
205
+		$this->source = $source;
206
+	}
207
+
208
+	/**
209
+	 * Returns the selectorn name or an empty string, if the source is not a selector
210
+	 * TODO This has to be checked at another place
211
+	 *
212
+	 * @return string The selector name
213
+	 */
214
+	protected function getSelectorName()
215
+	{
216
+		if ($this->getSource() instanceof \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SelectorInterface) {
217
+			return $this->source->getSelectorName();
218
+		} else {
219
+			return '';
220
+		}
221
+	}
222
+
223
+	/**
224
+	 * Gets the node-tuple source for this query.
225
+	 *
226
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\SourceInterface the node-tuple source; non-null
227
+	 */
228
+	public function getSource()
229
+	{
230
+		if ($this->source === null) {
231
+			$this->source = $this->qomFactory->selector($this->getType());
232
+		}
233
+		return $this->source;
234
+	}
235
+
236
+	/**
237
+	 * Executes the query against the database and returns the result
238
+	 *
239
+	 * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface|array The query result object or an array if $this->getQuerySettings()->getReturnRawQueryResult() is true
240
+	 * @api
241
+	 */
242
+	public function execute($returnRawQueryResult = false)
243
+	{
244
+		/** @var VidiDbBackend $backend */
245
+		$backend = $this->getObjectManager()->get(VidiDbBackend::class, $this);
246
+		return $backend->fetchResult();
247
+	}
248
+
249
+	/**
250
+	 * Sets the property names to order the result by. Expected like this:
251
+	 * array(
252
+	 * 'foo' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
253
+	 * 'bar' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
254
+	 * )
255
+	 * where 'foo' and 'bar' are property names.
256
+	 *
257
+	 * @param array $orderings The property names to order by
258
+	 * @return QueryInterface
259
+	 * @api
260
+	 */
261
+	public function setOrderings(array $orderings)
262
+	{
263
+		$this->orderings = $orderings;
264
+		return $this;
265
+	}
266
+
267
+	/**
268
+	 * Returns the property names to order the result by. Like this:
269
+	 * array(
270
+	 * 'foo' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
271
+	 * 'bar' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
272
+	 * )
273
+	 *
274
+	 * @return array
275
+	 */
276
+	public function getOrderings()
277
+	{
278
+		return $this->orderings;
279
+	}
280
+
281
+	/**
282
+	 * Sets the maximum size of the result set to limit. Returns $this to allow
283
+	 * for chaining (fluid interface)
284
+	 *
285
+	 * @param integer $limit
286
+	 * @throws \InvalidArgumentException
287
+	 * @return QueryInterface
288
+	 * @api
289
+	 */
290
+	public function setLimit($limit)
291
+	{
292
+		if (!is_int($limit) || $limit < 1) {
293
+			throw new \InvalidArgumentException('The limit must be an integer >= 1', 1245071870);
294
+		}
295
+		$this->limit = $limit;
296
+		return $this;
297
+	}
298
+
299
+	/**
300
+	 * Resets a previously set maximum size of the result set. Returns $this to allow
301
+	 * for chaining (fluid interface)
302
+	 *
303
+	 * @return QueryInterface
304
+	 * @api
305
+	 */
306
+	public function unsetLimit()
307
+	{
308
+		unset($this->limit);
309
+		return $this;
310
+	}
311
+
312
+	/**
313
+	 * Returns the maximum size of the result set to limit.
314
+	 *
315
+	 * @return integer
316
+	 * @api
317
+	 */
318
+	public function getLimit()
319
+	{
320
+		return $this->limit;
321
+	}
322
+
323
+	/**
324
+	 * Sets the start offset of the result set to offset. Returns $this to
325
+	 * allow for chaining (fluid interface)
326
+	 *
327
+	 * @param integer $offset
328
+	 * @throws \InvalidArgumentException
329
+	 * @return QueryInterface
330
+	 * @api
331
+	 */
332
+	public function setOffset($offset)
333
+	{
334
+		if (!is_int($offset) || $offset < 0) {
335
+			throw new \InvalidArgumentException('The offset must be a positive integer', 1245071872);
336
+		}
337
+		$this->offset = $offset;
338
+		return $this;
339
+	}
340
+
341
+	/**
342
+	 * Returns the start offset of the result set.
343
+	 *
344
+	 * @return integer
345
+	 * @api
346
+	 */
347
+	public function getOffset()
348
+	{
349
+		return $this->offset;
350
+	}
351
+
352
+	/**
353
+	 * The constraint used to limit the result set. Returns $this to allow
354
+	 * for chaining (fluid interface)
355
+	 *
356
+	 * @param ConstraintInterface $constraint
357
+	 * @return QueryInterface
358
+	 * @api
359
+	 */
360
+	public function matching($constraint)
361
+	{
362
+		$this->constraint = $constraint;
363
+		return $this;
364
+	}
365
+
366
+	/**
367
+	 * Gets the constraint for this query.
368
+	 *
369
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface the constraint, or null if none
370
+	 * @api
371
+	 */
372
+	public function getConstraint()
373
+	{
374
+		return $this->constraint;
375
+	}
376
+
377
+	/**
378
+	 * Performs a logical conjunction of the given constraints. The method takes one or more contraints and concatenates them with a boolean AND.
379
+	 * It also scepts a single array of constraints to be concatenated.
380
+	 *
381
+	 * @param mixed $constraint1 The first of multiple constraints or an array of constraints.
382
+	 * @throws InvalidNumberOfConstraintsException
383
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\AndInterface
384
+	 * @api
385
+	 */
386
+	public function logicalAnd($constraint1)
387
+	{
388
+		if (is_array($constraint1)) {
389
+			$resultingConstraint = array_shift($constraint1);
390
+			$constraints = $constraint1;
391
+		} else {
392
+			$constraints = func_get_args();
393
+			$resultingConstraint = array_shift($constraints);
394
+		}
395
+		if ($resultingConstraint === null) {
396
+			throw new InvalidNumberOfConstraintsException('There must be at least one constraint or a non-empty array of constraints given.', 1401289500);
397
+		}
398
+		foreach ($constraints as $constraint) {
399
+			$resultingConstraint = $this->qomFactory->_and($resultingConstraint, $constraint);
400
+		}
401
+		return $resultingConstraint;
402
+	}
403
+
404
+	/**
405
+	 * Performs a logical disjunction of the two given constraints
406
+	 *
407
+	 * @param mixed $constraint1 The first of multiple constraints or an array of constraints.
408
+	 * @throws InvalidNumberOfConstraintsException
409
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\OrInterface
410
+	 * @api
411
+	 */
412
+	public function logicalOr($constraint1)
413
+	{
414
+		if (is_array($constraint1)) {
415
+			$resultingConstraint = array_shift($constraint1);
416
+			$constraints = $constraint1;
417
+		} else {
418
+			$constraints = func_get_args();
419
+			$resultingConstraint = array_shift($constraints);
420
+		}
421
+		if ($resultingConstraint === null) {
422
+			throw new InvalidNumberOfConstraintsException('There must be at least one constraint or a non-empty array of constraints given.', 1401289501);
423
+		}
424
+		foreach ($constraints as $constraint) {
425
+			$resultingConstraint = $this->qomFactory->_or($resultingConstraint, $constraint);
426
+		}
427
+		return $resultingConstraint;
428
+	}
429
+
430
+	/**
431
+	 * Performs a logical negation of the given constraint
432
+	 *
433
+	 * @param ConstraintInterface $constraint Constraint to negate
434
+	 * @throws \RuntimeException
435
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\NotInterface
436
+	 * @api
437
+	 */
438
+	public function logicalNot(ConstraintInterface $constraint)
439
+	{
440
+		return $this->qomFactory->not($constraint);
441
+	}
442
+
443
+	/**
444
+	 * Returns an equals criterion used for matching objects against a query
445
+	 *
446
+	 * @param string $propertyName The name of the property to compare against
447
+	 * @param mixed $operand The value to compare with
448
+	 * @param boolean $caseSensitive Whether the equality test should be done case-sensitive
449
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
450
+	 * @api
451
+	 */
452
+	public function equals($propertyName, $operand, $caseSensitive = true)
453
+	{
454
+		if (is_object($operand) || $caseSensitive) {
455
+			$comparison = $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_EQUAL_TO, $operand);
456
+		} else {
457
+			$comparison = $this->qomFactory->comparison($this->qomFactory->lowerCase($this->qomFactory->propertyValue($propertyName, $this->getSelectorName())), QueryInterface::OPERATOR_EQUAL_TO, \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Charset\CharsetConverter::class)->conv_case(\TYPO3\CMS\Extbase\Persistence\Generic\Query::CHARSET, $operand, 'toLower'));
458
+		}
459
+		return $comparison;
460
+	}
461
+
462
+	/**
463
+	 * Returns a like criterion used for matching objects against a query
464
+	 *
465
+	 * @param string $propertyName The name of the property to compare against
466
+	 * @param mixed $operand The value to compare with
467
+	 * @param boolean $caseSensitive Whether the matching should be done case-sensitive
468
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
469
+	 * @api
470
+	 */
471
+	public function like($propertyName, $operand, $caseSensitive = true)
472
+	{
473
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_LIKE, $operand);
474
+	}
475
+
476
+	/**
477
+	 * Returns a "contains" criterion used for matching objects against a query.
478
+	 * It matches if the multivalued property contains the given operand.
479
+	 *
480
+	 * @param string $propertyName The name of the (multivalued) property to compare against
481
+	 * @param mixed $operand The value to compare with
482
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
483
+	 * @api
484
+	 */
485
+	public function contains($propertyName, $operand)
486
+	{
487
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_CONTAINS, $operand);
488
+	}
489
+
490
+	/**
491
+	 * Returns an "in" criterion used for matching objects against a query. It
492
+	 * matches if the property's value is contained in the multivalued operand.
493
+	 *
494
+	 * @param string $propertyName The name of the property to compare against
495
+	 * @param mixed $operand The value to compare with, multivalued
496
+	 * @throws UnexpectedTypeException
497
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
498
+	 * @api
499
+	 */
500
+	public function in($propertyName, $operand)
501
+	{
502
+		if (!is_array($operand) && !$operand instanceof \ArrayAccess && !$operand instanceof \Traversable) {
503
+			throw new UnexpectedTypeException('The "in" operator must be given a mutlivalued operand (array, ArrayAccess, Traversable).', 1264678095);
504
+		}
505
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_IN, $operand);
506
+	}
507
+
508
+	/**
509
+	 * Returns a less than criterion used for matching objects against a query
510
+	 *
511
+	 * @param string $propertyName The name of the property to compare against
512
+	 * @param mixed $operand The value to compare with
513
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
514
+	 * @api
515
+	 */
516
+	public function lessThan($propertyName, $operand)
517
+	{
518
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_LESS_THAN, $operand);
519
+	}
520
+
521
+	/**
522
+	 * Returns a less or equal than criterion used for matching objects against a query
523
+	 *
524
+	 * @param string $propertyName The name of the property to compare against
525
+	 * @param mixed $operand The value to compare with
526
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
527
+	 * @api
528
+	 */
529
+	public function lessThanOrEqual($propertyName, $operand)
530
+	{
531
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_LESS_THAN_OR_EQUAL_TO, $operand);
532
+	}
533
+
534
+	/**
535
+	 * Returns a greater than criterion used for matching objects against a query
536
+	 *
537
+	 * @param string $propertyName The name of the property to compare against
538
+	 * @param mixed $operand The value to compare with
539
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
540
+	 * @api
541
+	 */
542
+	public function greaterThan($propertyName, $operand)
543
+	{
544
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_GREATER_THAN, $operand);
545
+	}
546
+
547
+	/**
548
+	 * Returns a greater than or equal criterion used for matching objects against a query
549
+	 *
550
+	 * @param string $propertyName The name of the property to compare against
551
+	 * @param mixed $operand The value to compare with
552
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface
553
+	 * @api
554
+	 */
555
+	public function greaterThanOrEqual($propertyName, $operand)
556
+	{
557
+		return $this->qomFactory->comparison($this->qomFactory->propertyValue($propertyName, $this->getSelectorName()), QueryInterface::OPERATOR_GREATER_THAN_OR_EQUAL_TO, $operand);
558
+	}
559
+
560
+	/**
561
+	 * Returns the query result count.
562
+	 *
563
+	 * @return integer The query result count
564
+	 * @api
565
+	 */
566
+	public function count()
567
+	{
568
+		/** @var VidiDbBackend $backend */
569
+		$backend = $this->getObjectManager()->get(VidiDbBackend::class, $this);
570
+		return $backend->countResult();
571
+	}
572
+
573
+	/**
574
+	 * Returns an "isEmpty" criterion used for matching objects against a query.
575
+	 * It matches if the multivalued property contains no values or is null.
576
+	 *
577
+	 * @param string $propertyName The name of the multivalued property to compare against
578
+	 * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
579
+	 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException if used on a single-valued property
580
+	 * @api
581
+	 */
582
+	public function isEmpty($propertyName)
583
+	{
584
+		throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException(__METHOD__);
585
+	}
586
+
587
+	/**
588
+	 * @return string
589
+	 */
590
+	public function getDistinct()
591
+	{
592
+		return $this->distinct;
593
+	}
594
+
595
+	/**
596
+	 * @param string $distinct
597
+	 * @return $this
598
+	 */
599
+	public function setDistinct($distinct)
600
+	{
601
+		$this->distinct = $distinct;
602
+		return $this;
603
+	}
604
+
605
+	/**
606
+	 * Sets the statement of this query. If you use this, you will lose the abstraction from a concrete storage
607
+	 * backend (database).
608
+	 *
609
+	 * @param string|\TYPO3\CMS\Core\Database\PreparedStatement $statement The statement
610
+	 * @param array $parameters An array of parameters. These will be bound to placeholders '?' in the $statement.
611
+	 * @return QueryInterface
612
+	 */
613
+	public function statement($statement, array $parameters = array())
614
+	{
615
+		$this->statement = $this->qomFactory->statement($statement, $parameters);
616
+		return $this;
617
+	}
618
+
619
+	/**
620
+	 * Returns the statement of this query.
621
+	 *
622
+	 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\Statement
623
+	 */
624
+	public function getStatement()
625
+	{
626
+		return $this->statement;
627
+	}
628
+
629
+	/**
630
+	 * Returns whether the current mode is Backend.
631
+	 *
632
+	 * @return bool
633
+	 */
634
+	protected function isBackendMode()
635
+	{
636
+		return TYPO3_MODE == 'BE';
637
+	}
638
+
639
+	/**
640
+	 * @return string
641
+	 */
642
+	public function getSourceFieldName()
643
+	{
644
+		return $this->sourceFieldName;
645
+	}
646
+
647
+	/**
648
+	 * @param string $sourceFieldName
649
+	 * @return $this
650
+	 */
651
+	public function setSourceFieldName($sourceFieldName)
652
+	{
653
+		$this->sourceFieldName = $sourceFieldName;
654
+		return $this;
655
+	}
656
+
657
+	/**
658
+	 * @return object|\TYPO3\CMS\Extbase\Object\ObjectManager
659
+	 */
660
+	protected function getObjectManager()
661
+	{
662
+		return GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
663
+	}
664 664
 
665 665
 }
Please login to merge, or discard this patch.