Completed
Push — ezp-29724 ( 1025e5...495423 )
by
unknown
30:13 queued 07:05
created

HandlerContentTest::getConverterRegistry()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19

Duplication

Lines 19
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 19
loc 19
rs 9.6333
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the eZ Publish Kernel package.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Publish\Core\Search\Legacy\Tests\Content;
10
11
use eZ\Publish\Core\Persistence\Legacy\Tests\Content\LanguageAwareTestCase;
12
use eZ\Publish\Core\Persistence;
13
use eZ\Publish\Core\Search\Legacy\Content;
14
use eZ\Publish\Core\Persistence\Legacy\Content\Type\Handler as ContentTypeHandler;
15
use eZ\Publish\Core\Persistence\Legacy\Content\Type\Mapper as ContentTypeMapper;
16
use eZ\Publish\API\Repository\Values\Content\Query;
17
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;
18
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
19
use eZ\Publish\SPI\Persistence\Content\ContentInfo;
20
use eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\Converter;
21
use eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry;
22
use eZ\Publish\Core\Persistence\Legacy\Content\Type\Gateway\DoctrineDatabase as ContentTypeGateway;
23
use eZ\Publish\Core\Search\Legacy\Content\Location\Gateway as LocationGateway;
24
use eZ\Publish\Core\Persistence\Legacy\Content\Location\Mapper as LocationMapper;
25
use eZ\Publish\Core\Persistence\Legacy\Content\Type\Update\Handler as ContentTypeUpdateHandler;
26
use eZ\Publish\Core\Persistence\Legacy\Content\Mapper as ContentMapper;
27
use eZ\Publish\Core\Persistence\Legacy\Content\FieldHandler;
28
29
/**
30
 * Content Search test case for ContentSearchHandler.
31
 */
32
class HandlerContentTest extends LanguageAwareTestCase
33
{
34
    protected static $setUp = false;
35
36
    /**
37
     * Field registry mock.
38
     *
39
     * @var \eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry
40
     */
41
    protected $fieldRegistry;
42
43
    /**
44
     * Only set up once for these read only tests on a large fixture.
45
     *
46
     * Skipping the reset-up, since setting up for these tests takes quite some
47
     * time, which is not required to spent, since we are only reading from the
48
     * database anyways.
49
     */
50 View Code Duplication
    public function setUp()
51
    {
52
        if (!self::$setUp) {
53
            parent::setUp();
54
            $this->insertDatabaseFixture(__DIR__ . '/../_fixtures/full_dump.php');
55
            self::$setUp = $this->handler;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->handler of type object<eZ\Publish\Core\P...tabase\DatabaseHandler> is incompatible with the declared type boolean of property $setUp.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
56
        } else {
57
            $this->handler = self::$setUp;
0 ignored issues
show
Documentation Bug introduced by
It seems like self::$setUp of type boolean is incompatible with the declared type object<eZ\Publish\Core\P...tabase\DatabaseHandler> of property $handler.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
58
        }
59
    }
60
61
    /**
62
     * Assert that the elements are.
63
     */
64 View Code Duplication
    protected function assertSearchResults($expectedIds, $searchResult)
65
    {
66
        $result = array_map(
67
            function ($hit) {
68
                return $hit->valueObject->id;
69
            },
70
            $searchResult->searchHits
71
        );
72
73
        sort($result);
74
75
        $this->assertEquals($expectedIds, $result);
76
    }
77
78
    /**
79
     * Returns the content search handler to test.
80
     *
81
     * This method returns a fully functional search handler to perform tests
82
     * on.
83
     *
84
     * @param array $fullTextSearchConfiguration
85
     *
86
     * @return \eZ\Publish\Core\Search\Legacy\Content\Handler
87
     */
88
    protected function getContentSearchHandler(array $fullTextSearchConfiguration = array())
89
    {
90
        $transformationProcessor = new Persistence\TransformationProcessor\DefinitionBased(
91
            new Persistence\TransformationProcessor\DefinitionBased\Parser(),
92
            new Persistence\TransformationProcessor\PcreCompiler(
93
                new Persistence\Utf8Converter()
94
            ),
95
            glob(__DIR__ . '/../../../../Persistence/Tests/TransformationProcessor/_fixtures/transformations/*.tr')
96
        );
97
        $commaSeparatedCollectionValueHandler = new Content\Common\Gateway\CriterionHandler\FieldValue\Handler\Collection(
98
            $this->getDatabaseHandler(),
99
            $transformationProcessor,
100
            ','
101
        );
102
        $hyphenSeparatedCollectionValueHandler = new Content\Common\Gateway\CriterionHandler\FieldValue\Handler\Collection(
103
            $this->getDatabaseHandler(),
104
            $transformationProcessor,
105
            '-'
106
        );
107
        $simpleValueHandler = new Content\Common\Gateway\CriterionHandler\FieldValue\Handler\Simple(
108
            $this->getDatabaseHandler(),
109
            $transformationProcessor
110
        );
111
        $compositeValueHandler = new Content\Common\Gateway\CriterionHandler\FieldValue\Handler\Composite(
112
            $this->getDatabaseHandler(),
113
            $transformationProcessor
114
        );
115
116
        return new Content\Handler(
117
            new Content\Gateway\DoctrineDatabase(
118
                $this->getDatabaseHandler(),
119
                new Content\Common\Gateway\CriteriaConverter(
120
                    array(
121
                        new Content\Common\Gateway\CriterionHandler\ContentId(
122
                            $this->getDatabaseHandler()
123
                        ),
124
                        new Content\Common\Gateway\CriterionHandler\LogicalNot(
125
                            $this->getDatabaseHandler()
126
                        ),
127
                        new Content\Common\Gateway\CriterionHandler\LogicalAnd(
128
                            $this->getDatabaseHandler()
129
                        ),
130
                        new Content\Common\Gateway\CriterionHandler\LogicalOr(
131
                            $this->getDatabaseHandler()
132
                        ),
133
                        new Content\Gateway\CriterionHandler\Subtree(
134
                            $this->getDatabaseHandler()
135
                        ),
136
                        new Content\Common\Gateway\CriterionHandler\ContentTypeId(
137
                            $this->getDatabaseHandler()
138
                        ),
139
                        new Content\Common\Gateway\CriterionHandler\ContentTypeIdentifier(
140
                            $this->getDatabaseHandler(),
141
                            $this->getContentTypeHandler()
142
                        ),
143
                        new Content\Common\Gateway\CriterionHandler\ContentTypeGroupId(
144
                            $this->getDatabaseHandler()
145
                        ),
146
                        new Content\Common\Gateway\CriterionHandler\DateMetadata(
147
                            $this->getDatabaseHandler()
148
                        ),
149
                        new Content\Gateway\CriterionHandler\LocationId(
150
                            $this->getDatabaseHandler()
151
                        ),
152
                        new Content\Gateway\CriterionHandler\ParentLocationId(
153
                            $this->getDatabaseHandler()
154
                        ),
155
                        new Content\Common\Gateway\CriterionHandler\RemoteId(
156
                            $this->getDatabaseHandler()
157
                        ),
158
                        new Content\Gateway\CriterionHandler\LocationRemoteId(
159
                            $this->getDatabaseHandler()
160
                        ),
161
                        new Content\Common\Gateway\CriterionHandler\SectionId(
162
                            $this->getDatabaseHandler()
163
                        ),
164
                        new Content\Common\Gateway\CriterionHandler\FullText(
165
                            $this->getDatabaseHandler(),
166
                            $transformationProcessor,
167
                            $fullTextSearchConfiguration
168
                        ),
169
                        new Content\Common\Gateway\CriterionHandler\Field(
170
                            $this->getDatabaseHandler(),
171
                            $this->getContentTypeHandler(),
172
                            $this->getLanguageHandler(),
173
                            $this->getConverterRegistry(),
174
                            new Content\Common\Gateway\CriterionHandler\FieldValue\Converter(
175
                                new Content\Common\Gateway\CriterionHandler\FieldValue\HandlerRegistry(
176
                                    array(
177
                                        'ezboolean' => $simpleValueHandler,
178
                                        'ezcountry' => $commaSeparatedCollectionValueHandler,
179
                                        'ezdate' => $simpleValueHandler,
180
                                        'ezdatetime' => $simpleValueHandler,
181
                                        'ezemail' => $simpleValueHandler,
182
                                        'ezinteger' => $simpleValueHandler,
183
                                        'ezobjectrelation' => $simpleValueHandler,
184
                                        'ezobjectrelationlist' => $commaSeparatedCollectionValueHandler,
185
                                        'ezselection' => $hyphenSeparatedCollectionValueHandler,
186
                                        'eztime' => $simpleValueHandler,
187
                                    )
188
                                ),
189
                                $compositeValueHandler
190
                            ),
191
                            $transformationProcessor
192
                        ),
193
                        new Content\Common\Gateway\CriterionHandler\ObjectStateId(
194
                            $this->getDatabaseHandler()
195
                        ),
196
                        new Content\Common\Gateway\CriterionHandler\LanguageCode(
197
                            $this->getDatabaseHandler(),
198
                            $this->getLanguageMaskGenerator()
199
                        ),
200
                        new Content\Gateway\CriterionHandler\Visibility(
201
                            $this->getDatabaseHandler()
202
                        ),
203
                        new Content\Common\Gateway\CriterionHandler\MatchAll(
204
                            $this->getDatabaseHandler()
205
                        ),
206
                        new Content\Common\Gateway\CriterionHandler\UserMetadata(
207
                            $this->getDatabaseHandler()
208
                        ),
209
                        new Content\Common\Gateway\CriterionHandler\FieldRelation(
210
                            $this->getDatabaseHandler(),
211
                            $this->getContentTypeHandler(),
212
                            $this->getLanguageHandler()
213
                        ),
214
                    )
215
                ),
216
                new Content\Common\Gateway\SortClauseConverter(
217
                    array(
218
                        new Content\Common\Gateway\SortClauseHandler\ContentId($this->getDatabaseHandler()),
219
                    )
220
                ),
221
                $this->getLanguageHandler()
222
            ),
223
            $this->createMock(LocationGateway::class),
224
            new Content\WordIndexer\Gateway\DoctrineDatabase(
225
                $this->getDatabaseHandler(),
226
                $this->getContentTypeHandler(),
227
                $this->getDefinitionBasedTransformationProcessor(),
228
                new Content\WordIndexer\Repository\SearchIndex($this->getDatabaseHandler()),
229
                $this->getFullTextSearchConfiguration()
230
            ),
231
            $this->getContentMapperMock(),
232
            $this->createMock(LocationMapper::class),
233
            $this->getLanguageHandler(),
234
            $this->getFullTextMapper($this->getContentTypeHandler())
235
        );
236
    }
237
238
    protected $contentTypeHandler;
239
240 View Code Duplication
    protected function getContentTypeHandler()
241
    {
242
        if (!isset($this->contentTypeHandler)) {
243
            $this->contentTypeHandler = new ContentTypeHandler(
244
                new ContentTypeGateway(
245
                    $this->getDatabaseHandler(),
246
                    $this->getDatabaseConnection(),
247
                    $this->getLanguageMaskGenerator()
248
                ),
249
                new ContentTypeMapper($this->getConverterRegistry()),
250
                $this->createMock(ContentTypeUpdateHandler::class)
251
            );
252
        }
253
254
        return $this->contentTypeHandler;
255
    }
256
257 View Code Duplication
    protected function getConverterRegistry()
258
    {
259
        if (!isset($this->fieldRegistry)) {
260
            $this->fieldRegistry = new ConverterRegistry(
261
                array(
262
                    'ezdatetime' => new Converter\DateAndTimeConverter(),
263
                    'ezinteger' => new Converter\IntegerConverter(),
264
                    'ezstring' => new Converter\TextLineConverter(),
265
                    'ezprice' => new Converter\IntegerConverter(),
266
                    'ezurl' => new Converter\UrlConverter(),
267
                    'ezrichtext' => new Converter\RichTextConverter(),
268
                    'ezboolean' => new Converter\CheckboxConverter(),
269
                    'ezkeyword' => new Converter\KeywordConverter(),
270
                )
271
            );
272
        }
273
274
        return $this->fieldRegistry;
275
    }
276
277
    /**
278
     * Returns a content mapper mock.
279
     *
280
     * @return \eZ\Publish\Core\Persistence\Legacy\Content\Mapper
281
     */
282 View Code Duplication
    protected function getContentMapperMock()
283
    {
284
        $mapperMock = $this->getMockBuilder(ContentMapper::class)
285
            ->setConstructorArgs(
286
                array(
287
                    $this->fieldRegistry,
288
                    $this->getLanguageHandler(),
289
                )
290
            )
291
            ->setMethods(array('extractContentInfoFromRows'))
292
            ->getMock();
293
        $mapperMock->expects($this->any())
294
            ->method('extractContentInfoFromRows')
295
            ->with($this->isType('array'))
296
            ->will(
297
                $this->returnCallback(
298
                    function ($rows) {
299
                        $contentInfoObjs = array();
300
                        foreach ($rows as $row) {
301
                            $contentId = (int)$row['id'];
302
                            if (!isset($contentInfoObjs[$contentId])) {
303
                                $contentInfoObjs[$contentId] = new ContentInfo();
304
                                $contentInfoObjs[$contentId]->id = $contentId;
305
                            }
306
                        }
307
308
                        return array_values($contentInfoObjs);
309
                    }
310
                )
311
            );
312
313
        return $mapperMock;
314
    }
315
316
    /**
317
     * Returns a content field handler mock.
318
     *
319
     * @return \eZ\Publish\Core\Persistence\Legacy\Content\FieldHandler
320
     */
321
    protected function getContentFieldHandlerMock()
322
    {
323
        return $this->getMockBuilder(FieldHandler::class)
324
            ->disableOriginalConstructor()
325
            ->setMethods(array('loadExternalFieldData'))
326
            ->getMock();
327
    }
328
329
    /**
330
     * Bug #80.
331
     */
332
    public function testFindWithoutOffsetLimit()
333
    {
334
        $locator = $this->getContentSearchHandler();
335
336
        $result = $locator->findContent(
337
            new Query(
338
                array(
339
                    'filter' => new Criterion\ContentId(10),
340
                )
341
            )
342
        );
343
344
        $this->assertEquals(
345
            1,
346
            $result->totalCount
347
        );
348
    }
349
350
    /**
351
     * Bug #81, bug #82.
352
     */
353
    public function testFindWithZeroLimit()
354
    {
355
        $locator = $this->getContentSearchHandler();
356
357
        $result = $locator->findContent(
358
            new Query(
359
                array(
360
                    'filter' => new Criterion\ContentId(10),
361
                    'offset' => 0,
362
                    'limit' => 0,
363
                )
364
            )
365
        );
366
367
        $this->assertEquals(
368
            1,
369
            $result->totalCount
370
        );
371
        $this->assertEquals(
372
            array(),
373
            $result->searchHits
374
        );
375
    }
376
377
    /**
378
     * Issue with PHP_MAX_INT limit overflow in databases.
379
     */
380 View Code Duplication
    public function testFindWithNullLimit()
381
    {
382
        $locator = $this->getContentSearchHandler();
383
384
        $result = $locator->findContent(
385
            new Query(
386
                array(
387
                    'filter' => new Criterion\ContentId(10),
388
                    'offset' => 0,
389
                    'limit' => null,
390
                )
391
            )
392
        );
393
394
        $this->assertEquals(
395
            1,
396
            $result->totalCount
397
        );
398
        $this->assertEquals(
399
            1,
400
            count($result->searchHits)
401
        );
402
    }
403
404
    /**
405
     * Issue with offsetting to the nonexistent results produces \ezcQueryInvalidParameterException exception.
406
     */
407 View Code Duplication
    public function testFindWithOffsetToNonexistent()
408
    {
409
        $locator = $this->getContentSearchHandler();
410
411
        $result = $locator->findContent(
412
            new Query(
413
                array(
414
                    'filter' => new Criterion\ContentId(10),
415
                    'offset' => 1000,
416
                    'limit' => null,
417
                )
418
            )
419
        );
420
421
        $this->assertEquals(
422
            1,
423
            $result->totalCount
424
        );
425
        $this->assertEquals(
426
            0,
427
            count($result->searchHits)
428
        );
429
    }
430
431
    public function testFindSingle()
432
    {
433
        $locator = $this->getContentSearchHandler();
434
435
        $contentInfo = $locator->findSingle(new Criterion\ContentId(10));
436
437
        $this->assertEquals(10, $contentInfo->id);
438
    }
439
440
    /**
441
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
442
     */
443
    public function testFindSingleWithNonSearchableField()
444
    {
445
        $locator = $this->getContentSearchHandler();
446
        $locator->findSingle(
447
            new Criterion\Field(
448
                'tag_cloud_url',
449
                Criterion\Operator::EQ,
450
                'http://nimbus.com'
451
            )
452
        );
453
    }
454
455
    /**
456
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
457
     */
458 View Code Duplication
    public function testFindContentWithNonSearchableField()
459
    {
460
        $locator = $this->getContentSearchHandler();
461
        $locator->findContent(
462
            new Query(
463
                array(
464
                    'filter' => new Criterion\Field(
465
                        'tag_cloud_url',
466
                        Criterion\Operator::EQ,
467
                        'http://nimbus.com'
468
                    ),
469
                    'sortClauses' => array(new SortClause\ContentId()),
470
                )
471
            )
472
        );
473
    }
474
475
    /**
476
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
477
     */
478
    public function testFindSingleTooMany()
479
    {
480
        $locator = $this->getContentSearchHandler();
481
        $locator->findSingle(new Criterion\ContentId(array(4, 10, 12, 23)));
482
    }
483
484
    /**
485
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
486
     */
487
    public function testFindSingleZero()
488
    {
489
        $locator = $this->getContentSearchHandler();
490
        $locator->findSingle(new Criterion\ContentId(0));
491
    }
492
493
    public function testContentIdFilter()
494
    {
495
        $this->assertSearchResults(
496
            array(4, 10),
497
            $this->getContentSearchHandler()->findContent(
498
                new Query(
499
                    array(
500
                        'filter' => new Criterion\ContentId(
501
                            array(1, 4, 10)
502
                        ),
503
                        'limit' => 10,
504
                    )
505
                )
506
            )
507
        );
508
    }
509
510
    public function testContentIdFilterCount()
511
    {
512
        $locator = $this->getContentSearchHandler();
513
514
        $result = $locator->findContent(
515
            new Query(
516
                array(
517
                    'filter' => new Criterion\ContentId(
518
                        array(1, 4, 10)
519
                    ),
520
                    'limit' => 10,
521
                )
522
            )
523
        );
524
525
        $this->assertSame(2, $result->totalCount);
526
    }
527
528
    public function testContentAndCombinatorFilter()
529
    {
530
        $this->assertSearchResults(
531
            array(4),
532
            $this->getContentSearchHandler()->findContent(
533
                new Query(
534
                    array(
535
                        'filter' => new Criterion\LogicalAnd(
536
                            array(
537
                                new Criterion\ContentId(
538
                                    array(1, 4, 10)
539
                                ),
540
                                new Criterion\ContentId(
541
                                    array(4, 12)
542
                                ),
543
                            )
544
                        ),
545
                        'limit' => 10,
546
                    )
547
                )
548
            )
549
        );
550
    }
551
552
    public function testContentOrCombinatorFilter()
553
    {
554
        $locator = $this->getContentSearchHandler();
555
556
        $result = $locator->findContent(
557
            new Query(
558
                array(
559
                    'filter' => new Criterion\LogicalOr(
560
                        array(
561
                            new Criterion\ContentId(
562
                                array(1, 4, 10)
563
                            ),
564
                            new Criterion\ContentId(
565
                                array(4, 12)
566
                            ),
567
                        )
568
                    ),
569
                    'limit' => 10,
570
                )
571
            )
572
        );
573
574
        $expectedContentIds = array(4, 10, 12);
575
576
        $this->assertEquals(
577
            count($expectedContentIds),
578
            count($result->searchHits)
579
        );
580
        foreach ($result->searchHits as $hit) {
581
            $this->assertContains(
582
                $hit->valueObject->id,
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
583
                $expectedContentIds
584
            );
585
        }
586
    }
587
588
    public function testContentNotCombinatorFilter()
589
    {
590
        $this->assertSearchResults(
591
            array(4),
592
            $this->getContentSearchHandler()->findContent(
593
                new Query(
594
                    array(
595
                        'filter' => new Criterion\LogicalAnd(
596
                            array(
597
                                new Criterion\ContentId(
598
                                    array(1, 4, 10)
599
                                ),
600
                                new Criterion\LogicalNot(
601
                                    new Criterion\ContentId(
602
                                        array(10, 12)
603
                                    )
604
                                ),
605
                            )
606
                        ),
607
                        'limit' => 10,
608
                    )
609
                )
610
            )
611
        );
612
    }
613
614 View Code Duplication
    public function testContentSubtreeFilterIn()
615
    {
616
        $this->assertSearchResults(
617
            array(67, 68, 69, 70, 71, 72, 73, 74),
618
            $this->getContentSearchHandler()->findContent(
619
                new Query(
620
                    array(
621
                        'filter' => new Criterion\Subtree(
622
                            array('/1/2/69/')
623
                        ),
624
                        'limit' => 10,
625
                    )
626
                )
627
            )
628
        );
629
    }
630
631 View Code Duplication
    public function testContentSubtreeFilterEq()
632
    {
633
        $this->assertSearchResults(
634
            array(67, 68, 69, 70, 71, 72, 73, 74),
635
            $this->getContentSearchHandler()->findContent(
636
                new Query(
637
                    array(
638
                        'filter' => new Criterion\Subtree('/1/2/69/'),
639
                        'limit' => 10,
640
                    )
641
                )
642
            )
643
        );
644
    }
645
646 View Code Duplication
    public function testContentTypeIdFilter()
647
    {
648
        $this->assertSearchResults(
649
            array(10, 14, 226),
650
            $this->getContentSearchHandler()->findContent(
651
                new Query(
652
                    array(
653
                        'filter' => new Criterion\ContentTypeId(4),
654
                        'limit' => 10,
655
                    )
656
                )
657
            )
658
        );
659
    }
660
661
    public function testContentTypeIdentifierFilter()
662
    {
663
        $this->assertSearchResults(
664
            array(41, 45, 49, 50, 51),
665
            $this->getContentSearchHandler()->findContent(
666
                new Query(
667
                    array(
668
                        'filter' => new Criterion\ContentTypeIdentifier('folder'),
669
                        'limit' => 5,
670
                        'sortClauses' => array(new SortClause\ContentId()),
671
                    )
672
                )
673
            )
674
        );
675
    }
676
677 View Code Duplication
    public function testContentTypeGroupFilter()
678
    {
679
        $this->assertSearchResults(
680
            array(4, 10, 11, 12, 13, 14, 42, 225, 226),
681
            $this->getContentSearchHandler()->findContent(
682
                new Query(
683
                    array(
684
                        'filter' => new Criterion\ContentTypeGroupId(2),
685
                        'limit' => 10,
686
                    )
687
                )
688
            )
689
        );
690
    }
691
692
    public function testDateMetadataFilterModifiedGreater()
693
    {
694
        $this->assertSearchResults(
695
            array(11, 225, 226),
696
            $this->getContentSearchHandler()->findContent(
697
                new Query(
698
                    array(
699
                        'filter' => new Criterion\DateMetadata(
700
                            Criterion\DateMetadata::MODIFIED,
701
                            Criterion\Operator::GT,
702
                            1311154214
703
                        ),
704
                        'limit' => 10,
705
                    )
706
                )
707
            )
708
        );
709
    }
710
711
    public function testDateMetadataFilterModifiedGreaterOrEqual()
712
    {
713
        $this->assertSearchResults(
714
            array(11, 14, 225, 226),
715
            $this->getContentSearchHandler()->findContent(
716
                new Query(
717
                    array(
718
                        'filter' => new Criterion\DateMetadata(
719
                            Criterion\DateMetadata::MODIFIED,
720
                            Criterion\Operator::GTE,
721
                            1311154214
722
                        ),
723
                        'limit' => 10,
724
                    )
725
                )
726
            )
727
        );
728
    }
729
730
    public function testDateMetadataFilterModifiedIn()
731
    {
732
        $this->assertSearchResults(
733
            array(11, 14, 225, 226),
734
            $this->getContentSearchHandler()->findContent(
735
                new Query(
736
                    array(
737
                        'filter' => new Criterion\DateMetadata(
738
                            Criterion\DateMetadata::MODIFIED,
739
                            Criterion\Operator::IN,
740
                            array(1311154214, 1311154215)
741
                        ),
742
                        'limit' => 10,
743
                    )
744
                )
745
            )
746
        );
747
    }
748
749
    public function testDateMetadataFilterModifiedBetween()
750
    {
751
        $this->assertSearchResults(
752
            array(11, 14, 225, 226),
753
            $this->getContentSearchHandler()->findContent(
754
                new Query(
755
                    array(
756
                        'filter' => new Criterion\DateMetadata(
757
                            Criterion\DateMetadata::MODIFIED,
758
                            Criterion\Operator::BETWEEN,
759
                            array(1311154213, 1311154215)
760
                        ),
761
                        'limit' => 10,
762
                    )
763
                )
764
            )
765
        );
766
    }
767
768
    public function testDateMetadataFilterCreatedBetween()
769
    {
770
        $this->assertSearchResults(
771
            array(66, 131, 225),
772
            $this->getContentSearchHandler()->findContent(
773
                new Query(
774
                    array(
775
                        'filter' => new Criterion\DateMetadata(
776
                            Criterion\DateMetadata::CREATED,
777
                            Criterion\Operator::BETWEEN,
778
                            array(1299780749, 1311154215)
779
                        ),
780
                        'limit' => 10,
781
                    )
782
                )
783
            )
784
        );
785
    }
786
787
    public function testLocationIdFilter()
788
    {
789
        $this->assertSearchResults(
790
            array(4, 65),
791
            $this->getContentSearchHandler()->findContent(
792
                new Query(
793
                    array(
794
                        'filter' => new Criterion\LocationId(array(1, 2, 5)),
795
                        'limit' => 10,
796
                    )
797
                )
798
            )
799
        );
800
    }
801
802
    public function testParentLocationIdFilter()
803
    {
804
        $this->assertSearchResults(
805
            array(4, 41, 45, 56, 65),
806
            $this->getContentSearchHandler()->findContent(
807
                new Query(
808
                    array(
809
                        'filter' => new Criterion\ParentLocationId(array(1)),
810
                        'limit' => 10,
811
                    )
812
                )
813
            )
814
        );
815
    }
816
817
    public function testRemoteIdFilter()
818
    {
819
        $this->assertSearchResults(
820
            array(4, 10),
821
            $this->getContentSearchHandler()->findContent(
822
                new Query(
823
                    array(
824
                        'filter' => new Criterion\RemoteId(
825
                            array('f5c88a2209584891056f987fd965b0ba', 'faaeb9be3bd98ed09f606fc16d144eca')
826
                        ),
827
                        'limit' => 10,
828
                    )
829
                )
830
            )
831
        );
832
    }
833
834
    public function testLocationRemoteIdFilter()
835
    {
836
        $this->assertSearchResults(
837
            array(4, 65),
838
            $this->getContentSearchHandler()->findContent(
839
                new Query(
840
                    array(
841
                        'filter' => new Criterion\LocationRemoteId(
842
                            array('3f6d92f8044aed134f32153517850f5a', 'f3e90596361e31d496d4026eb624c983')
843
                        ),
844
                        'limit' => 10,
845
                    )
846
                )
847
            )
848
        );
849
    }
850
851 View Code Duplication
    public function testSectionFilter()
852
    {
853
        $this->assertSearchResults(
854
            array(4, 10, 11, 12, 13, 14, 42, 226),
855
            $this->getContentSearchHandler()->findContent(
856
                new Query(
857
                    array(
858
                        'filter' => new Criterion\SectionId(array(2)),
859
                        'limit' => 10,
860
                    )
861
                )
862
            )
863
        );
864
    }
865
866
    public function testStatusFilter()
867
    {
868
        $this->assertSearchResults(
869
            array(4, 10, 11, 12, 13, 14, 41, 42, 45, 49),
870
            $searchResult = $this->getContentSearchHandler()->findContent(
871
                new Query(
872
                    array(
873
                        // Status criterion is gone, but this will also match all published
874
                        'filter' => new Criterion\LogicalNot(
875
                            new Criterion\ContentId(
876
                                array(0)
877
                            )
878
                        ),
879
                        'limit' => 10,
880
                        'sortClauses' => array(new SortClause\ContentId()),
881
                    )
882
                )
883
            )
884
        );
885
886
        $this->assertEquals(
887
            185,
888
            $searchResult->totalCount
889
        );
890
    }
891
892
    public function testFieldFilter()
893
    {
894
        $this->assertSearchResults(
895
            array(11),
896
            $this->getContentSearchHandler()->findContent(
897
                new Query(
898
                    array(
899
                        'filter' => new Criterion\Field(
900
                            'name',
901
                            Criterion\Operator::EQ,
902
                            'members'
903
                        ),
904
                        'limit' => 10,
905
                    )
906
                )
907
            )
908
        );
909
    }
910
911
    public function testFieldFilterIn()
912
    {
913
        $this->assertSearchResults(
914
            array(11, 42),
915
            $this->getContentSearchHandler()->findContent(
916
                new Query(
917
                    array(
918
                        'filter' => new Criterion\Field(
919
                            'name',
920
                            Criterion\Operator::IN,
921
                            array('members', 'anonymous users')
922
                        ),
923
                        'limit' => 10,
924
                    )
925
                )
926
            )
927
        );
928
    }
929
930
    public function testFieldFilterContainsPartial()
931
    {
932
        $this->assertSearchResults(
933
            array(42),
934
            $this->getContentSearchHandler()->findContent(
935
                new Query(
936
                    array(
937
                        'filter' => new Criterion\Field(
938
                            'name',
939
                            Criterion\Operator::CONTAINS,
940
                            'nonymous use'
941
                        ),
942
                        'limit' => 10,
943
                    )
944
                )
945
            )
946
        );
947
    }
948
949
    public function testFieldFilterContainsSimple()
950
    {
951
        $this->assertSearchResults(
952
            array(77),
953
            $this->getContentSearchHandler()->findContent(
954
                new Query(
955
                    array(
956
                        'filter' => new Criterion\Field(
957
                            'publish_date',
958
                            Criterion\Operator::CONTAINS,
959
                            1174643880
960
                        ),
961
                        'limit' => 10,
962
                    )
963
                )
964
            )
965
        );
966
    }
967
968
    public function testFieldFilterContainsSimpleNoMatch()
969
    {
970
        $this->assertSearchResults(
971
            array(),
972
            $this->getContentSearchHandler()->findContent(
973
                new Query(
974
                    array(
975
                        'filter' => new Criterion\Field(
976
                            'publish_date',
977
                            Criterion\Operator::CONTAINS,
978
                            1174643
979
                        ),
980
                        'limit' => 10,
981
                    )
982
                )
983
            )
984
        );
985
    }
986
987
    public function testFieldFilterBetween()
988
    {
989
        $this->assertSearchResults(
990
            array(69, 71, 72),
991
            $this->getContentSearchHandler()->findContent(
992
                new Query(
993
                    array(
994
                        'filter' => new Criterion\Field(
995
                            'price',
996
                            Criterion\Operator::BETWEEN,
997
                            array(10000, 1000000)
998
                        ),
999
                        'limit' => 10,
1000
                    )
1001
                )
1002
            )
1003
        );
1004
    }
1005
1006 View Code Duplication
    public function testFieldFilterOr()
1007
    {
1008
        $this->assertSearchResults(
1009
            array(11, 69, 71, 72),
1010
            $this->getContentSearchHandler()->findContent(
1011
                new Query(
1012
                    array(
1013
                        'filter' => new Criterion\LogicalOr(
1014
                            array(
1015
                                new Criterion\Field(
1016
                                    'name',
1017
                                    Criterion\Operator::EQ,
1018
                                    'members'
1019
                                ),
1020
                                new Criterion\Field(
1021
                                    'price',
1022
                                    Criterion\Operator::BETWEEN,
1023
                                    array(10000, 1000000)
1024
                                ),
1025
                            )
1026
                        ),
1027
                        'limit' => 10,
1028
                    )
1029
                )
1030
            )
1031
        );
1032
    }
1033
1034 View Code Duplication
    public function testFullTextFilter()
1035
    {
1036
        $this->assertSearchResults(
1037
            array(191),
1038
            $this->getContentSearchHandler()->findContent(
1039
                new Query(
1040
                    array(
1041
                        'filter' => new Criterion\FullText('applied webpage'),
1042
                        'limit' => 10,
1043
                    )
1044
                )
1045
            )
1046
        );
1047
    }
1048
1049 View Code Duplication
    public function testFullTextWildcardFilter()
1050
    {
1051
        $this->assertSearchResults(
1052
            array(191),
1053
            $this->getContentSearchHandler()->findContent(
1054
                new Query(
1055
                    array(
1056
                        'filter' => new Criterion\FullText('applie*'),
1057
                        'limit' => 10,
1058
                    )
1059
                )
1060
            )
1061
        );
1062
    }
1063
1064 View Code Duplication
    public function testFullTextDisabledWildcardFilter()
1065
    {
1066
        $this->assertSearchResults(
1067
            array(),
1068
            $this->getContentSearchHandler(
1069
                array('enableWildcards' => false)
1070
            )->findContent(
1071
                new Query(
1072
                    array(
1073
                        'filter' => new Criterion\FullText('applie*'),
1074
                        'limit' => 10,
1075
                    )
1076
                )
1077
            )
1078
        );
1079
    }
1080
1081 View Code Duplication
    public function testFullTextFilterStopwordRemoval()
1082
    {
1083
        $handler = $this->getContentSearchHandler(
1084
            array(
1085
                'stopWordThresholdFactor' => 0.1,
1086
            )
1087
        );
1088
1089
        $this->assertSearchResults(
1090
            array(),
1091
            $handler->findContent(
1092
                new Query(
1093
                    array(
1094
                        'filter' => new Criterion\FullText('the'),
1095
                        'limit' => 10,
1096
                    )
1097
                )
1098
            )
1099
        );
1100
    }
1101
1102 View Code Duplication
    public function testFullTextFilterNoStopwordRemoval()
1103
    {
1104
        $handler = $this->getContentSearchHandler(
1105
            array(
1106
                'stopWordThresholdFactor' => 1,
1107
            )
1108
        );
1109
1110
        $result = $handler->findContent(
1111
            new Query(
1112
                array(
1113
                    'filter' => new Criterion\FullText(
1114
                        'the'
1115
                    ),
1116
                    'limit' => 10,
1117
                )
1118
            )
1119
        );
1120
1121
        $this->assertEquals(
1122
            10,
1123
            count(
1124
                array_map(
1125
                    function ($hit) {
1126
                        return $hit->valueObject->id;
1127
                    },
1128
                    $result->searchHits
1129
                )
1130
            )
1131
        );
1132
    }
1133
1134
    /**
1135
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1136
     */
1137
    public function testFullTextFilterInvalidStopwordThreshold()
1138
    {
1139
        $this->getContentSearchHandler(
1140
            array(
1141
                'stopWordThresholdFactor' => 2,
1142
            )
1143
        );
1144
    }
1145
1146
    public function testObjectStateIdFilter()
1147
    {
1148
        $this->assertSearchResults(
1149
            array(4, 10, 11, 12, 13, 14, 41, 42, 45, 49),
1150
            $this->getContentSearchHandler()->findContent(
1151
                new Query(
1152
                    array(
1153
                        'filter' => new Criterion\ObjectStateId(1),
1154
                        'limit' => 10,
1155
                        'sortClauses' => array(new SortClause\ContentId()),
1156
                    )
1157
                )
1158
            )
1159
        );
1160
    }
1161
1162
    public function testObjectStateIdFilterIn()
1163
    {
1164
        $this->assertSearchResults(
1165
            array(4, 10, 11, 12, 13, 14, 41, 42, 45, 49),
1166
            $this->getContentSearchHandler()->findContent(
1167
                new Query(
1168
                    array(
1169
                        'filter' => new Criterion\ObjectStateId(array(1, 2)),
1170
                        'limit' => 10,
1171
                        'sortClauses' => array(new SortClause\ContentId()),
1172
                    )
1173
                )
1174
            )
1175
        );
1176
    }
1177
1178
    public function testLanguageCodeFilter()
1179
    {
1180
        $this->assertSearchResults(
1181
            array(4, 10, 11, 12, 13, 14, 41, 42, 45, 49),
1182
            $this->getContentSearchHandler()->findContent(
1183
                new Query(
1184
                    array(
1185
                        'filter' => new Criterion\LanguageCode('eng-US'),
1186
                        'limit' => 10,
1187
                        'sortClauses' => array(new SortClause\ContentId()),
1188
                    )
1189
                )
1190
            )
1191
        );
1192
    }
1193
1194
    public function testLanguageCodeFilterIn()
1195
    {
1196
        $this->assertSearchResults(
1197
            array(4, 10, 11, 12, 13, 14, 41, 42, 45, 49),
1198
            $this->getContentSearchHandler()->findContent(
1199
                new Query(
1200
                    array(
1201
                        'filter' => new Criterion\LanguageCode(array('eng-US', 'eng-GB')),
1202
                        'limit' => 10,
1203
                        'sortClauses' => array(new SortClause\ContentId()),
1204
                    )
1205
                )
1206
            )
1207
        );
1208
    }
1209
1210 View Code Duplication
    public function testLanguageCodeFilterWithAlwaysAvailable()
1211
    {
1212
        $this->assertSearchResults(
1213
            array(4, 10, 11, 12, 13, 14, 41, 42, 45, 49, 50, 51, 56, 57, 65, 68, 70, 74, 76, 80),
1214
            $this->getContentSearchHandler()->findContent(
1215
                new Query(
1216
                    array(
1217
                        'filter' => new Criterion\LanguageCode('eng-GB', true),
1218
                        'limit' => 20,
1219
                        'sortClauses' => array(new SortClause\ContentId()),
1220
                    )
1221
                )
1222
            )
1223
        );
1224
    }
1225
1226
    public function testVisibilityFilter()
1227
    {
1228
        $this->assertSearchResults(
1229
            array(4, 10, 11, 12, 13, 14, 41, 42, 45, 49),
1230
            $this->getContentSearchHandler()->findContent(
1231
                new Query(
1232
                    array(
1233
                        'filter' => new Criterion\Visibility(
1234
                            Criterion\Visibility::VISIBLE
1235
                        ),
1236
                        'limit' => 10,
1237
                        'sortClauses' => array(new SortClause\ContentId()),
1238
                    )
1239
                )
1240
            )
1241
        );
1242
    }
1243
1244 View Code Duplication
    public function testUserMetadataFilterOwnerWrongUserId()
1245
    {
1246
        $this->assertSearchResults(
1247
            array(),
1248
            $this->getContentSearchHandler()->findContent(
1249
                new Query(
1250
                    array(
1251
                        'filter' => new Criterion\UserMetadata(
1252
                            Criterion\UserMetadata::OWNER,
1253
                            Criterion\Operator::EQ,
1254
                            2
1255
                        ),
1256
                    )
1257
                )
1258
            )
1259
        );
1260
    }
1261
1262 View Code Duplication
    public function testUserMetadataFilterOwnerAdministrator()
1263
    {
1264
        $this->assertSearchResults(
1265
            array(4, 10, 11, 12, 13, 14, 41, 42, 45, 49),
1266
            $this->getContentSearchHandler()->findContent(
1267
                new Query(
1268
                    array(
1269
                        'filter' => new Criterion\UserMetadata(
1270
                            Criterion\UserMetadata::OWNER,
1271
                            Criterion\Operator::EQ,
1272
                            14
1273
                        ),
1274
                        'limit' => 10,
1275
                        'sortClauses' => array(new SortClause\ContentId()),
1276
                    )
1277
                )
1278
            )
1279
        );
1280
    }
1281
1282 View Code Duplication
    public function testUserMetadataFilterOwnerEqAMember()
1283
    {
1284
        $this->assertSearchResults(
1285
            array(223),
1286
            $this->getContentSearchHandler()->findContent(
1287
                new Query(
1288
                    array(
1289
                        'filter' => new Criterion\UserMetadata(
1290
                            Criterion\UserMetadata::OWNER,
1291
                            Criterion\Operator::EQ,
1292
                            226
1293
                        ),
1294
                    )
1295
                )
1296
            )
1297
        );
1298
    }
1299
1300 View Code Duplication
    public function testUserMetadataFilterOwnerInAMember()
1301
    {
1302
        $this->assertSearchResults(
1303
            array(223),
1304
            $this->getContentSearchHandler()->findContent(
1305
                new Query(
1306
                    array(
1307
                        'filter' => new Criterion\UserMetadata(
1308
                            Criterion\UserMetadata::OWNER,
1309
                            Criterion\Operator::IN,
1310
                            array(226)
1311
                        ),
1312
                    )
1313
                )
1314
            )
1315
        );
1316
    }
1317
1318 View Code Duplication
    public function testUserMetadataFilterCreatorEqAMember()
1319
    {
1320
        $this->assertSearchResults(
1321
            array(223),
1322
            $this->getContentSearchHandler()->findContent(
1323
                new Query(
1324
                    array(
1325
                        'filter' => new Criterion\UserMetadata(
1326
                            Criterion\UserMetadata::MODIFIER,
1327
                            Criterion\Operator::EQ,
1328
                            226
1329
                        ),
1330
                    )
1331
                )
1332
            )
1333
        );
1334
    }
1335
1336 View Code Duplication
    public function testUserMetadataFilterCreatorInAMember()
1337
    {
1338
        $this->assertSearchResults(
1339
            array(223),
1340
            $this->getContentSearchHandler()->findContent(
1341
                new Query(
1342
                    array(
1343
                        'filter' => new Criterion\UserMetadata(
1344
                            Criterion\UserMetadata::MODIFIER,
1345
                            Criterion\Operator::IN,
1346
                            array(226)
1347
                        ),
1348
                    )
1349
                )
1350
            )
1351
        );
1352
    }
1353
1354 View Code Duplication
    public function testUserMetadataFilterEqGroupMember()
1355
    {
1356
        $this->assertSearchResults(
1357
            array(223),
1358
            $this->getContentSearchHandler()->findContent(
1359
                new Query(
1360
                    array(
1361
                        'filter' => new Criterion\UserMetadata(
1362
                            Criterion\UserMetadata::GROUP,
1363
                            Criterion\Operator::EQ,
1364
                            11
1365
                        ),
1366
                    )
1367
                )
1368
            )
1369
        );
1370
    }
1371
1372 View Code Duplication
    public function testUserMetadataFilterInGroupMember()
1373
    {
1374
        $this->assertSearchResults(
1375
            array(223),
1376
            $this->getContentSearchHandler()->findContent(
1377
                new Query(
1378
                    array(
1379
                        'filter' => new Criterion\UserMetadata(
1380
                            Criterion\UserMetadata::GROUP,
1381
                            Criterion\Operator::IN,
1382
                            array(11)
1383
                        ),
1384
                    )
1385
                )
1386
            )
1387
        );
1388
    }
1389
1390 View Code Duplication
    public function testUserMetadataFilterEqGroupMemberNoMatch()
1391
    {
1392
        $this->assertSearchResults(
1393
            array(),
1394
            $this->getContentSearchHandler()->findContent(
1395
                new Query(
1396
                    array(
1397
                        'filter' => new Criterion\UserMetadata(
1398
                            Criterion\UserMetadata::GROUP,
1399
                            Criterion\Operator::EQ,
1400
                            13
1401
                        ),
1402
                    )
1403
                )
1404
            )
1405
        );
1406
    }
1407
1408 View Code Duplication
    public function testUserMetadataFilterInGroupMemberNoMatch()
1409
    {
1410
        $this->assertSearchResults(
1411
            array(),
1412
            $this->getContentSearchHandler()->findContent(
1413
                new Query(
1414
                    array(
1415
                        'filter' => new Criterion\UserMetadata(
1416
                            Criterion\UserMetadata::GROUP,
1417
                            Criterion\Operator::IN,
1418
                            array(13)
1419
                        ),
1420
                    )
1421
                )
1422
            )
1423
        );
1424
    }
1425
1426
    public function testFieldRelationFilterContainsSingle()
1427
    {
1428
        $this->assertSearchResults(
1429
            array(67),
1430
            $this->getContentSearchHandler()->findContent(
1431
                new Query(
1432
                    array(
1433
                        'filter' => new Criterion\FieldRelation(
1434
                            'billboard',
1435
                            Criterion\Operator::CONTAINS,
1436
                            array(60)
1437
                        ),
1438
                    )
1439
                )
1440
            )
1441
        );
1442
    }
1443
1444 View Code Duplication
    public function testFieldRelationFilterContainsSingleNoMatch()
1445
    {
1446
        $this->assertSearchResults(
1447
            array(),
1448
            $this->getContentSearchHandler()->findContent(
1449
                new Query(
1450
                    array(
1451
                        'filter' => new Criterion\FieldRelation(
1452
                            'billboard',
1453
                            Criterion\Operator::CONTAINS,
1454
                            array(4)
1455
                        ),
1456
                    )
1457
                )
1458
            )
1459
        );
1460
    }
1461
1462
    public function testFieldRelationFilterContainsArray()
1463
    {
1464
        $this->assertSearchResults(
1465
            array(67),
1466
            $this->getContentSearchHandler()->findContent(
1467
                new Query(
1468
                    array(
1469
                        'filter' => new Criterion\FieldRelation(
1470
                            'billboard',
1471
                            Criterion\Operator::CONTAINS,
1472
                            array(60, 75)
1473
                        ),
1474
                    )
1475
                )
1476
            )
1477
        );
1478
    }
1479
1480
    public function testFieldRelationFilterContainsArrayNotMatch()
1481
    {
1482
        $this->assertSearchResults(
1483
            array(),
1484
            $this->getContentSearchHandler()->findContent(
1485
                new Query(
1486
                    array(
1487
                        'filter' => new Criterion\FieldRelation(
1488
                            'billboard',
1489
                            Criterion\Operator::CONTAINS,
1490
                            array(60, 64)
1491
                        ),
1492
                    )
1493
                )
1494
            )
1495
        );
1496
    }
1497
1498
    public function testFieldRelationFilterInArray()
1499
    {
1500
        $this->assertSearchResults(
1501
            array(67, 75),
1502
            $this->getContentSearchHandler()->findContent(
1503
                new Query(
1504
                    array(
1505
                        'filter' => new Criterion\FieldRelation(
1506
                            'billboard',
1507
                            Criterion\Operator::IN,
1508
                            array(60, 64)
1509
                        ),
1510
                    )
1511
                )
1512
            )
1513
        );
1514
    }
1515
1516
    public function testFieldRelationFilterInArrayNotMatch()
1517
    {
1518
        $this->assertSearchResults(
1519
            array(),
1520
            $this->getContentSearchHandler()->findContent(
1521
                new Query(
1522
                    array(
1523
                        'filter' => new Criterion\FieldRelation(
1524
                            'billboard',
1525
                            Criterion\Operator::IN,
1526
                            array(4, 10)
1527
                        ),
1528
                    )
1529
                )
1530
            )
1531
        );
1532
    }
1533
}
1534