Completed
Push — test-fieldrelation-location-se... ( 776906...448993 )
by
unknown
14:26 queued 01:34
created

SearchServiceTest::getContentInfoFixtureClosure()   A

Complexity

Conditions 4
Paths 1

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 1
nop 1
dl 0
loc 15
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing the SearchServiceTest class.
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\API\Repository\Tests;
10
11
use eZ\Publish\API\Repository\Tests\SetupFactory\LegacyElasticsearch;
12
use EzSystems\EzPlatformSolrSearchEngine\Tests\SetupFactory\LegacySetupFactory as LegacySolrSetupFactory;
13
use eZ\Publish\API\Repository\Values\Content\Content;
14
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
15
use eZ\Publish\API\Repository\Values\Content\Query;
16
use eZ\Publish\API\Repository\Values\Content\Location;
17
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
18
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
19
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;
20
use eZ\Publish\API\Repository\Values\Content\Query\FacetBuilder;
21
use eZ\Publish\API\Repository\Values\Content\Search\SearchResult;
22
use eZ\Publish\API\Repository\Values\Content\Search\SearchHit;
23
use eZ\Publish\API\Repository\Exceptions\NotImplementedException;
24
25
/**
26
 * Test case for operations in the SearchService using in memory storage.
27
 *
28
 * @see eZ\Publish\API\Repository\SearchService
29
 * @group integration
30
 * @group search
31
 */
32
class SearchServiceTest extends BaseTest
33
{
34
    public function getFilterContentSearches()
35
    {
36
        $fixtureDir = $this->getFixtureDir();
37
38
        return array(
39
            0 => array(
40
                array(
41
                    'filter' => new Criterion\ContentId(
42
                        array(1, 4, 10)
43
                    ),
44
                    'sortClauses' => array(new SortClause\ContentId()),
45
                ),
46
                $fixtureDir . 'ContentId.php',
47
            ),
48
            1 => array(
49
                array(
50
                    'filter' => new Criterion\LogicalAnd(
51
                        array(
52
                            new Criterion\ContentId(
53
                                array(1, 4, 10)
54
                            ),
55
                            new Criterion\ContentId(
56
                                array(4, 12)
57
                            ),
58
                        )
59
                    ),
60
                    'sortClauses' => array(new SortClause\ContentId()),
61
                ),
62
                $fixtureDir . 'LogicalAnd.php',
63
            ),
64
            2 => array(
65
                array(
66
                    'filter' => new Criterion\LogicalOr(
67
                        array(
68
                            new Criterion\ContentId(
69
                                array(1, 4, 10)
70
                            ),
71
                            new Criterion\ContentId(
72
                                array(4, 12)
73
                            ),
74
                        )
75
                    ),
76
                    'sortClauses' => array(new SortClause\ContentId()),
77
                ),
78
                $fixtureDir . 'LogicalOr.php',
79
            ),
80
            3 => array(
81
                array(
82
                    'filter' => new Criterion\LogicalAnd(
83
                        array(
84
                            new Criterion\ContentId(
85
                                array(1, 4, 10)
86
                            ),
87
                            new Criterion\LogicalNot(
88
                                new Criterion\ContentId(
89
                                    array(10, 12)
90
                                )
91
                            ),
92
                        )
93
                    ),
94
                    'sortClauses' => array(new SortClause\ContentId()),
95
                ),
96
                $fixtureDir . 'LogicalNot.php',
97
            ),
98
            4 => array(
99
                array(
100
                    'filter' => new Criterion\LogicalAnd(
101
                        array(
102
                            new Criterion\ContentId(
103
                                array(1, 4, 10)
104
                            ),
105
                            new Criterion\LogicalAnd(
106
                                array(
107
                                    new Criterion\LogicalNot(
108
                                        new Criterion\ContentId(
109
                                            array(10, 12)
110
                                        )
111
                                    ),
112
                                )
113
                            ),
114
                        )
115
                    ),
116
                    'sortClauses' => array(new SortClause\ContentId()),
117
                ),
118
                $fixtureDir . 'LogicalNot.php',
119
            ),
120
            5 => array(
121
                array(
122
                    'filter' => new Criterion\ContentTypeId(
123
                        4
124
                    ),
125
                    'sortClauses' => array(new SortClause\ContentId()),
126
                ),
127
                $fixtureDir . 'ContentTypeId.php',
128
            ),
129
            6 => array(
130
                array(
131
                    'filter' => new Criterion\ContentTypeIdentifier(
132
                        'user'
133
                    ),
134
                    'sortClauses' => array(new SortClause\ContentId()),
135
                ),
136
                $fixtureDir . 'ContentTypeId.php',
137
            ),
138
            7 => array(
139
                array(
140
                    'filter' => new Criterion\MatchNone(),
141
                    'sortClauses' => array(new SortClause\ContentId()),
142
                ),
143
                $fixtureDir . 'MatchNone.php',
144
            ),
145
            8 => array(
146
                array(
147
                    'filter' => new Criterion\ContentTypeGroupId(
148
                        2
149
                    ),
150
                    'sortClauses' => array(new SortClause\ContentId()),
151
                ),
152
                $fixtureDir . 'ContentTypeGroupId.php',
153
            ),
154
            9 => array(
155
                array(
156
                    'filter' => new Criterion\DateMetadata(
157
                        Criterion\DateMetadata::MODIFIED,
158
                        Criterion\Operator::GT,
159
                        1343140540
160
                    ),
161
                    'sortClauses' => array(new SortClause\ContentId()),
162
                ),
163
                $fixtureDir . 'DateMetadataGt.php',
164
            ),
165
            10 => array(
166
                array(
167
                    'filter' => new Criterion\DateMetadata(
168
                        Criterion\DateMetadata::MODIFIED,
169
                        Criterion\Operator::GTE,
170
                        1311154215
171
                    ),
172
                    'sortClauses' => array(new SortClause\ContentId()),
173
                ),
174
                $fixtureDir . 'DateMetadataGte.php',
175
            ),
176
            11 => array(
177
                array(
178
                    'filter' => new Criterion\DateMetadata(
179
                        Criterion\DateMetadata::MODIFIED,
180
                        Criterion\Operator::LTE,
181
                        1311154215
182
                    ),
183
                    'limit' => 10,
184
                    'sortClauses' => array(new SortClause\ContentId()),
185
                ),
186
                $fixtureDir . 'DateMetadataLte.php',
187
            ),
188
            12 => array(
189
                array(
190
                    'filter' => new Criterion\DateMetadata(
191
                        Criterion\DateMetadata::MODIFIED,
192
                        Criterion\Operator::IN,
193
                        array(1033920794, 1060695457, 1343140540)
194
                    ),
195
                    'sortClauses' => array(new SortClause\ContentId()),
196
                ),
197
                $fixtureDir . 'DateMetadataIn.php',
198
            ),
199
            13 => array(
200
                array(
201
                    'filter' => new Criterion\DateMetadata(
202
                        Criterion\DateMetadata::MODIFIED,
203
                        Criterion\Operator::BETWEEN,
204
                        array(1033920776, 1072180276)
205
                    ),
206
                    'sortClauses' => array(new SortClause\ContentId()),
207
                ),
208
                $fixtureDir . 'DateMetadataBetween.php',
209
            ),
210
            14 => array(
211
                array(
212
                    'filter' => new Criterion\DateMetadata(
213
                        Criterion\DateMetadata::CREATED,
214
                        Criterion\Operator::BETWEEN,
215
                        array(1033920776, 1072180278)
216
                    ),
217
                    'sortClauses' => array(new SortClause\ContentId()),
218
                ),
219
                $fixtureDir . 'DateMetadataCreated.php',
220
            ),
221
            15 => array(
222
                array(
223
                    'filter' => new Criterion\RemoteId(
224
                        array('f5c88a2209584891056f987fd965b0ba', 'faaeb9be3bd98ed09f606fc16d144eca')
225
                    ),
226
                    'sortClauses' => array(new SortClause\ContentId()),
227
                ),
228
                $fixtureDir . 'RemoteId.php',
229
            ),
230
            16 => array(
231
                array(
232
                    'filter' => new Criterion\SectionId(
233
                        array(2)
234
                    ),
235
                    'sortClauses' => array(new SortClause\ContentId()),
236
                ),
237
                $fixtureDir . 'SectionId.php',
238
            ),
239
            17 => array(
240
                array(
241
                    'filter' => new Criterion\Field(
242
                        'name',
243
                        Criterion\Operator::EQ,
244
                        'Members'
245
                    ),
246
                    'sortClauses' => array(new SortClause\ContentId()),
247
                ),
248
                $fixtureDir . 'Field.php',
249
            ),
250
            18 => array(
251
                array(
252
                    'filter' => new Criterion\Field(
253
                        'name',
254
                        Criterion\Operator::IN,
255
                        array('Members', 'Anonymous Users')
256
                    ),
257
                    'sortClauses' => array(new SortClause\ContentId()),
258
                ),
259
                $fixtureDir . 'FieldIn.php',
260
            ),
261
            19 => array(
262
                array(
263
                    'filter' => new Criterion\DateMetadata(
264
                        Criterion\DateMetadata::MODIFIED,
265
                        Criterion\Operator::BETWEEN,
266
                        array(1033920275, 1033920794)
267
                    ),
268
                    'sortClauses' => array(new SortClause\ContentId()),
269
                ),
270
                $fixtureDir . 'FieldBetween.php',
271
            ),
272
            20 => array(
273
                array(
274
                    'filter' => new Criterion\LogicalOr(
275
                        array(
276
                            new Criterion\Field(
277
                                'name',
278
                                Criterion\Operator::EQ,
279
                                'Members'
280
                            ),
281
                            new Criterion\DateMetadata(
282
                                Criterion\DateMetadata::MODIFIED,
283
                                Criterion\Operator::BETWEEN,
284
                                array(1033920275, 1033920794)
285
                            ),
286
                        )
287
                    ),
288
                    'sortClauses' => array(new SortClause\ContentId()),
289
                ),
290
                $fixtureDir . 'FieldOr.php',
291
            ),
292
            21 => array(
293
                array(
294
                    'filter' => new Criterion\Subtree(
295
                        '/1/5/'
296
                    ),
297
                    'sortClauses' => array(new SortClause\ContentId()),
298
                ),
299
                $fixtureDir . 'Subtree.php',
300
            ),
301
            22 => array(
302
                array(
303
                    'filter' => new Criterion\LocationId(
304
                        array(1, 2, 5)
305
                    ),
306
                    'sortClauses' => array(new SortClause\ContentId()),
307
                ),
308
                $fixtureDir . 'LocationId.php',
309
            ),
310
            23 => array(
311
                array(
312
                    'filter' => new Criterion\ParentLocationId(
313
                        array(1)
314
                    ),
315
                    'sortClauses' => array(new SortClause\ContentId()),
316
                ),
317
                $fixtureDir . 'ParentLocationId.php',
318
            ),
319
            24 => array(
320
                array(
321
                    'filter' => new Criterion\LocationRemoteId(
322
                        array('3f6d92f8044aed134f32153517850f5a', 'f3e90596361e31d496d4026eb624c983')
323
                    ),
324
                    'sortClauses' => array(new SortClause\ContentId()),
325
                ),
326
                $fixtureDir . 'LocationRemoteId.php',
327
            ),
328
            25 => array(
329
                array(
330
                    // There is no Status Criterion anymore, this should match all published as well
331
                    'filter' => new Criterion\Subtree(
332
                        '/1/'
333
                    ),
334
                    'sortClauses' => array(new SortClause\ContentId()),
335
                    'limit' => 50,
336
                ),
337
                $fixtureDir . 'Status.php',
338
                // Result having the same sort level should be sorted between them to be system independent
339
                function (&$data) {
340
                    usort(
341
                        $data->searchHits,
342
                        function ($a, $b) {
343
                            if ($a->score == $b->score) {
344
                                if ($a->valueObject['id'] == $b->valueObject['id']) {
345
                                    return 0;
346
                                }
347
348
                                // Order by ascending ID
349
                                return ($a->valueObject['id'] < $b->valueObject['id']) ? -1 : 1;
350
                            }
351
352
                            // Order by descending score
353
                            return ($a->score > $b->score) ? -1 : 1;
354
                        }
355
                    );
356
                },
357
            ),
358
            26 => array(
359
                array(
360
                    'filter' => new Criterion\UserMetadata(
361
                        Criterion\UserMetadata::MODIFIER,
362
                        Criterion\Operator::EQ,
363
                        14
364
                    ),
365
                    'sortClauses' => array(
366
                        new SortClause\ContentId(),
367
                    ),
368
                    'limit' => 50,
369
                ),
370
                $fixtureDir . 'UserMetadata.php',
371
            ),
372
            27 => array(
373
                array(
374
                    'filter' => new Criterion\UserMetadata(
375
                        Criterion\UserMetadata::MODIFIER,
376
                        Criterion\Operator::IN,
377
                        array(14)
378
                    ),
379
                    'sortClauses' => array(
380
                        new SortClause\ContentId(),
381
                    ),
382
                    'limit' => 50,
383
                ),
384
                $fixtureDir . 'UserMetadata.php',
385
            ),
386
            28 => array(
387
                array(
388
                    'filter' => new Criterion\UserMetadata(
389
                        Criterion\UserMetadata::OWNER,
390
                        Criterion\Operator::EQ,
391
                        14
392
                    ),
393
                    'sortClauses' => array(
394
                        new SortClause\ContentId(),
395
                    ),
396
                    'limit' => 50,
397
                ),
398
                $fixtureDir . 'UserMetadata.php',
399
            ),
400
            29 => array(
401
                array(
402
                    'filter' => new Criterion\UserMetadata(
403
                        Criterion\UserMetadata::OWNER,
404
                        Criterion\Operator::IN,
405
                        array(14)
406
                    ),
407
                    'sortClauses' => array(
408
                        new SortClause\ContentId(),
409
                    ),
410
                    'limit' => 50,
411
                ),
412
                $fixtureDir . 'UserMetadata.php',
413
            ),
414
            30 => array(
415
                array(
416
                    'filter' => new Criterion\UserMetadata(
417
                        Criterion\UserMetadata::GROUP,
418
                        Criterion\Operator::EQ,
419
                        12
420
                    ),
421
                    'sortClauses' => array(
422
                        new SortClause\ContentId(),
423
                    ),
424
                    'limit' => 50,
425
                ),
426
                $fixtureDir . 'UserMetadata.php',
427
            ),
428
            31 => array(
429
                array(
430
                    'filter' => new Criterion\UserMetadata(
431
                        Criterion\UserMetadata::GROUP,
432
                        Criterion\Operator::IN,
433
                        array(12)
434
                    ),
435
                    'sortClauses' => array(
436
                        new SortClause\ContentId(),
437
                    ),
438
                    'limit' => 50,
439
                ),
440
                $fixtureDir . 'UserMetadata.php',
441
            ),
442
            32 => array(
443
                array(
444
                    'filter' => new Criterion\UserMetadata(
445
                        Criterion\UserMetadata::GROUP,
446
                        Criterion\Operator::EQ,
447
                        4
448
                    ),
449
                    'sortClauses' => array(
450
                        new SortClause\ContentId(),
451
                    ),
452
                    'limit' => 50,
453
                ),
454
                $fixtureDir . 'UserMetadata.php',
455
            ),
456
            33 => array(
457
                array(
458
                    'filter' => new Criterion\UserMetadata(
459
                        Criterion\UserMetadata::GROUP,
460
                        Criterion\Operator::IN,
461
                        array(4)
462
                    ),
463
                    'sortClauses' => array(
464
                        new SortClause\ContentId(),
465
                    ),
466
                    'limit' => 50,
467
                ),
468
                $fixtureDir . 'UserMetadata.php',
469
            ),
470
            34 => array(
471
                array(
472
                    'filter' => new Criterion\Ancestor(
473
                        array(
0 ignored issues
show
Documentation introduced by
array('/1/5/44/', '/1/5/44/45/') is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
474
                            '/1/5/44/',
475
                            '/1/5/44/45/',
476
                        )
477
                    ),
478
                    'sortClauses' => array(
479
                        new SortClause\ContentId(),
480
                    ),
481
                    'limit' => 50,
482
                ),
483
                $fixtureDir . 'AncestorContent.php',
484
            ),
485
        );
486
    }
487
488
    public function getFilterContentSearchesCustomField()
489
    {
490
        $fixtureDir = $this->getFixtureDir();
491
492
        return [
493
            0 => [
494
                [
495
                    'filter' => new Criterion\CustomField(
496
                        'user_group_name_value_s',
497
                        Criterion\Operator::EQ,
498
                        'Members'
499
                    ),
500
                    'sortClauses' => array(new SortClause\ContentId()),
501
                ],
502
                $fixtureDir . 'Field.php',
503
            ],
504
            1 => [
505
                [
506
                    'filter' => new Criterion\CustomField(
507
                        'user_group_name_value_s',
508
                        Criterion\Operator::CONTAINS,
509
                        'Members'
510
                    ),
511
                    'sortClauses' => array(new SortClause\ContentId()),
512
                ],
513
                $fixtureDir . 'Field.php',
514
            ],
515
            2 => [
516
                [
517
                    'filter' => new Criterion\CustomField(
518
                        'user_group_name_value_s',
519
                        Criterion\Operator::LT,
520
                        'Members'
521
                    ),
522
                    'sortClauses' => array(new SortClause\ContentId()),
523
                ],
524
                $fixtureDir . 'CustomFieldLt.php',
525
            ],
526
            3 => [
527
                [
528
                    'filter' => new Criterion\CustomField(
529
                        'user_group_name_value_s',
530
                        Criterion\Operator::LTE,
531
                        'Members'
532
                    ),
533
                    'sortClauses' => array(new SortClause\ContentId()),
534
                ],
535
                $fixtureDir . 'CustomFieldLte.php',
536
            ],
537
            4 => [
538
                [
539
                    'filter' => new Criterion\CustomField(
540
                        'user_group_name_value_s',
541
                        Criterion\Operator::GT,
542
                        'Members'
543
                    ),
544
                    'sortClauses' => array(new SortClause\ContentId()),
545
                ],
546
                $fixtureDir . 'CustomFieldGt.php',
547
            ],
548
            5 => [
549
                [
550
                    'filter' => new Criterion\CustomField(
551
                        'user_group_name_value_s',
552
                        Criterion\Operator::GTE,
553
                        'Members'
554
                    ),
555
                    'sortClauses' => array(new SortClause\ContentId()),
556
                ],
557
                $fixtureDir . 'CustomFieldGte.php',
558
            ],
559
            6 => [
560
                [
561
                    'filter' => new Criterion\CustomField(
562
                        'user_group_name_value_s',
563
                        Criterion\Operator::BETWEEN,
564
                        array('Administrator users', 'Members')
565
                    ),
566
                    'sortClauses' => array(new SortClause\ContentId()),
567
                ],
568
                $fixtureDir . 'CustomFieldBetween.php',
569
            ],
570
        ];
571
    }
572
573
    public function getContentQuerySearches()
574
    {
575
        $fixtureDir = $this->getFixtureDir();
576
577
        return array(
578
            array(
579
                array(
580
                    'filter' => new Criterion\ContentId(
581
                        array(58, 10)
582
                    ),
583
                    'query' => new Criterion\FullText('contact'),
584
                    'sortClauses' => array(new SortClause\ContentId()),
585
                ),
586
                $fixtureDir . 'FullTextFiltered.php',
587
            ),
588
            array(
589
                array(
590
                    'query' => new Criterion\FullText(
591
                        'contact',
592
                        array(
593
                            'boost' => array(
594
                                'title' => 2,
595
                            ),
596
                            'fuzziness' => .5,
597
                        )
598
                    ),
599
                    'sortClauses' => array(new SortClause\ContentId()),
600
                ),
601
                $fixtureDir . 'FullText.php',
602
            ),
603
            array(
604
                array(
605
                    'query' => new Criterion\FullText(
606
                        'Contact*'
607
                    ),
608
                    'sortClauses' => array(new SortClause\ContentId()),
609
                ),
610
                $fixtureDir . 'FullTextWildcard.php',
611
            ),
612
            array(
613
                array(
614
                    'query' => new Criterion\LanguageCode('eng-GB', false),
615
                    'sortClauses' => array(new SortClause\ContentId()),
616
                ),
617
                $fixtureDir . 'LanguageCode.php',
618
            ),
619
            array(
620
                array(
621
                    'query' => new Criterion\LanguageCode(array('eng-US', 'eng-GB')),
622
                    'offset' => 10,
623
                    'sortClauses' => array(new SortClause\ContentId()),
624
                ),
625
                $fixtureDir . 'LanguageCodeIn.php',
626
            ),
627
            array(
628
                array(
629
                    'query' => new Criterion\LanguageCode('eng-GB'),
630
                    'offset' => 10,
631
                    'sortClauses' => array(new SortClause\ContentId()),
632
                ),
633
                $fixtureDir . 'LanguageCodeAlwaysAvailable.php',
634
            ),
635
            array(
636
                array(
637
                    'query' => new Criterion\Visibility(
638
                        Criterion\Visibility::VISIBLE
639
                    ),
640
                    'sortClauses' => array(new SortClause\ContentId()),
641
                    'limit' => 50,
642
                ),
643
                $fixtureDir . 'Visibility.php',
644
            ),
645
        );
646
    }
647
648
    public function getLocationQuerySearches()
649
    {
650
        $fixtureDir = $this->getFixtureDir();
651
652
        return array(
653
            array(
654
                array(
655
                    'query' => new Criterion\Location\Depth(Criterion\Operator::EQ, 1),
656
                    'sortClauses' => array(new SortClause\ContentId()),
657
                ),
658
                $fixtureDir . 'Depth.php',
659
            ),
660
            array(
661
                array(
662
                    'query' => new Criterion\Location\Depth(Criterion\Operator::IN, array(1, 3)),
663
                    'sortClauses' => array(new SortClause\ContentId()),
664
                ),
665
                $fixtureDir . 'DepthIn.php',
666
            ),
667
            array(
668
                array(
669
                    'query' => new Criterion\Location\Depth(Criterion\Operator::GT, 2),
670
                    'sortClauses' => array(new SortClause\ContentId()),
671
                ),
672
                $fixtureDir . 'DepthGt.php',
673
            ),
674
            array(
675
                array(
676
                    'query' => new Criterion\Location\Depth(Criterion\Operator::GTE, 2),
677
                    'sortClauses' => array(new SortClause\ContentId()),
678
                    'limit' => 50,
679
                ),
680
                $fixtureDir . 'DepthGte.php',
681
            ),
682
            array(
683
                array(
684
                    'query' => new Criterion\Location\Depth(Criterion\Operator::LT, 2),
685
                    'sortClauses' => array(new SortClause\ContentId()),
686
                ),
687
                $fixtureDir . 'Depth.php',
688
            ),
689
            array(
690
                array(
691
                    'query' => new Criterion\Location\Depth(Criterion\Operator::LTE, 2),
692
                    'sortClauses' => array(new SortClause\ContentId()),
693
                    'limit' => 50,
694
                ),
695
                $fixtureDir . 'DepthLte.php',
696
            ),
697
            array(
698
                array(
699
                    'query' => new Criterion\Location\Depth(Criterion\Operator::BETWEEN, array(1, 2)),
700
                    'sortClauses' => array(new SortClause\ContentId()),
701
                    'limit' => 50,
702
                ),
703
                $fixtureDir . 'DepthLte.php',
704
            ),
705
            array(
706
                array(
707
                    'filter' => new Criterion\Ancestor('/1/5/44/45/'),
708
                    'sortClauses' => array(
709
                        new SortClause\Location\Depth(),
710
                    ),
711
                    'limit' => 50,
712
                ),
713
                $fixtureDir . 'AncestorLocation.php',
714
            ),
715
        );
716
    }
717
718
    /**
719
     * Test for the findContent() method.
720
     *
721
     * @dataProvider getFilterContentSearches
722
     *
723
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
724
     */
725
    public function testFindContentFiltered($queryData, $fixture, $closure = null)
726
    {
727
        $query = new Query($queryData);
728
        $this->assertQueryFixture($query, $fixture, $closure);
729
    }
730
731
    /**
732
     * Test for the findContentInfo() method.
733
     *
734
     * @dataProvider getFilterContentSearches
735
     * @see \eZ\Publish\API\Repository\SearchService::findContentInfo()
736
     */
737
    public function testFindContentInfoFiltered($queryData, $fixture, $closure = null)
738
    {
739
        $query = new Query($queryData);
740
        $this->assertQueryFixture($query, $fixture, $closure, true);
741
    }
742
743
    /**
744
     * Test for the findLocations() method.
745
     *
746
     * @dataProvider getFilterContentSearches
747
     *
748
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
749
     */
750
    public function testFindLocationsContentFiltered($queryData, $fixture, $closure = null)
751
    {
752
        $query = new LocationQuery($queryData);
753
        $this->assertQueryFixture($query, $fixture, $closure);
754
    }
755
756
    /**
757
     * Test for the findContent() method.
758
     *
759
     * @dataProvider getFilterContentSearchesCustomField
760
     *
761
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
762
     */
763 View Code Duplication
    public function testFindContentFilteredCustomField($queryData, $fixture, $closure = null)
764
    {
765
        // Check using get_class since the others extend SetupFactory\Legacy
766
        if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') {
767
            $this->markTestSkipped(
768
                'Custom fields are not supported by the legacy search engine.'
769
            );
770
        }
771
772
        $query = new Query($queryData);
773
        $this->assertQueryFixture($query, $fixture, $closure);
774
    }
775
776
    /**
777
     * Test for the findContentInfo() method.
778
     *
779
     * @dataProvider getFilterContentSearchesCustomField
780
     * @see \eZ\Publish\API\Repository\SearchService::findContentInfo()
781
     */
782 View Code Duplication
    public function testFindContentInfoFilteredCustomField($queryData, $fixture, $closure = null)
783
    {
784
        // Check using get_class since the others extend SetupFactory\Legacy
785
        if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') {
786
            $this->markTestSkipped(
787
                'Custom fields are not supported by the legacy search engine.'
788
            );
789
        }
790
791
        $query = new Query($queryData);
792
        $this->assertQueryFixture($query, $fixture, $closure, true);
793
    }
794
795
    /**
796
     * Test for the findLocations() method.
797
     *
798
     * @dataProvider getFilterContentSearchesCustomField
799
     *
800
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
801
     */
802 View Code Duplication
    public function testFindLocationsContentFilteredCustomField($queryData, $fixture, $closure = null)
803
    {
804
        // Check using get_class since the others extend SetupFactory\Legacy
805
        if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') {
806
            $this->markTestSkipped(
807
                'Custom fields are not supported by the legacy search engine.'
808
            );
809
        }
810
811
        $query = new LocationQuery($queryData);
812
        $this->assertQueryFixture($query, $fixture, $closure);
813
    }
814
815
    /**
816
     * Test for deprecated $criterion property on query object.
817
     *
818
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
819
     * @deprecated
820
     */
821
    public function testDeprecatedCriteriaProperty()
822
    {
823
        $this->assertQueryFixture(
824
            new Query(
825
                array(
826
                    'query' => new Criterion\ContentId(
827
                        array(1, 4, 10)
828
                    ),
829
                    'sortClauses' => array(new SortClause\ContentId()),
830
                )
831
            ),
832
            $this->getFixtureDir() . 'DeprecatedContentIdQuery.php'
833
        );
834
    }
835
836
    /**
837
     * Test for the findContent() method.
838
     *
839
     * @dataProvider getContentQuerySearches
840
     *
841
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
842
     */
843
    public function testQueryContent($queryData, $fixture, $closure = null)
844
    {
845
        $query = new Query($queryData);
846
        $this->assertQueryFixture($query, $fixture, $closure);
847
    }
848
849
    /**
850
     * Test for the findContentInfo() method.
851
     *
852
     * @dataProvider getContentQuerySearches
853
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
854
     */
855
    public function testQueryContentInfo($queryData, $fixture, $closure = null)
856
    {
857
        $query = new Query($queryData);
858
        $this->assertQueryFixture($query, $fixture, $closure, true);
859
    }
860
861
    /**
862
     * Test for the findLocations() method.
863
     *
864
     * @dataProvider getContentQuerySearches
865
     *
866
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
867
     */
868
    public function testQueryContentLocations($queryData, $fixture, $closure = null)
869
    {
870
        $query = new LocationQuery($queryData);
871
        $this->assertQueryFixture($query, $fixture, $closure);
872
    }
873
874
    /**
875
     * Test for the findLocations() method.
876
     *
877
     * @dataProvider getLocationQuerySearches
878
     *
879
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
880
     */
881
    public function testQueryLocations($queryData, $fixture, $closure = null)
882
    {
883
        $query = new LocationQuery($queryData);
884
        $this->assertQueryFixture($query, $fixture, $closure);
885
    }
886
887
    public function getCaseInsensitiveSearches()
888
    {
889
        return array(
890
            array(
891
                array(
892
                    'filter' => new Criterion\Field(
893
                        'name',
894
                        Criterion\Operator::EQ,
895
                        'Members'
896
                    ),
897
                    'sortClauses' => array(new SortClause\ContentId()),
898
                ),
899
            ),
900
            array(
901
                array(
902
                    'filter' => new Criterion\Field(
903
                        'name',
904
                        Criterion\Operator::EQ,
905
                        'members'
906
                    ),
907
                    'sortClauses' => array(new SortClause\ContentId()),
908
                ),
909
            ),
910
            array(
911
                array(
912
                    'filter' => new Criterion\Field(
913
                        'name',
914
                        Criterion\Operator::EQ,
915
                        'MEMBERS'
916
                    ),
917
                    'sortClauses' => array(new SortClause\ContentId()),
918
                ),
919
            ),
920
        );
921
    }
922
923
    /**
924
     * Test for the findContent() method.
925
     *
926
     * @dataProvider getCaseInsensitiveSearches
927
     *
928
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
929
     */
930
    public function testFindContentFieldFiltersCaseSensitivity($queryData)
931
    {
932
        $query = new Query($queryData);
933
        $this->assertQueryFixture(
934
            $query,
935
            $this->getFixtureDir() . 'Field.php'
936
        );
937
    }
938
939
    /**
940
     * Test for the findLocations() method.
941
     *
942
     * @dataProvider getCaseInsensitiveSearches
943
     *
944
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
945
     */
946
    public function testFindLocationsFieldFiltersCaseSensitivity($queryData)
947
    {
948
        $query = new LocationQuery($queryData);
949
        $this->assertQueryFixture(
950
            $query,
951
            $this->getFixtureDir() . 'Field.php'
952
        );
953
    }
954
955
    public function getRelationFieldFilterSearches()
956
    {
957
        $fixtureDir = $this->getFixtureDir();
958
959
        return array(
960
            0 => array(
961
                array(
962
                    'filter' => new Criterion\FieldRelation(
963
                        'image',
964
                        Criterion\Operator::IN,
965
                        array(1, 4, 10)
966
                    ),
967
                    'sortClauses' => array(new SortClause\ContentId()),
968
                ),
969
                $fixtureDir . 'FieldRelation.php',
970
            ),
971
            1 => array(
972
                array(
973
                    'filter' => new Criterion\FieldRelation(
974
                        'image',
975
                        Criterion\Operator::IN,
976
                        array(4, 49)
977
                    ),
978
                    'sortClauses' => array(new SortClause\ContentId()),
979
                ),
980
                $fixtureDir . 'FieldRelationAll.php',
981
            ),
982
            2 => array(
983
                array(
984
                    'filter' => new Criterion\FieldRelation(
985
                        'image',
986
                        Criterion\Operator::IN,
987
                        array(4)
988
                    ),
989
                    'sortClauses' => array(new SortClause\ContentId()),
990
                ),
991
                $fixtureDir . 'FieldRelation.php',
992
            ),
993
            3 => array(
994
                array(
995
                    'filter' => new Criterion\FieldRelation(
996
                        'image',
997
                        Criterion\Operator::CONTAINS,
998
                        array(1, 4, 10)
999
                    ),
1000
                    'sortClauses' => array(new SortClause\ContentId()),
1001
                ),
1002
                $fixtureDir . 'MatchNone.php',
1003
            ),
1004
            4 => array(
1005
                array(
1006
                    'filter' => new Criterion\FieldRelation(
1007
                        'image',
1008
                        Criterion\Operator::CONTAINS,
1009
                        array(4, 49)
1010
                    ),
1011
                    'sortClauses' => array(new SortClause\ContentId()),
1012
                ),
1013
                $fixtureDir . 'MatchNone.php',
1014
            ),
1015
            5 => array(
1016
                array(
1017
                    'filter' => new Criterion\FieldRelation(
1018
                        'image',
1019
                        Criterion\Operator::CONTAINS,
1020
                        array(4)
1021
                    ),
1022
                    'sortClauses' => array(new SortClause\ContentId()),
1023
                ),
1024
                $fixtureDir . 'FieldRelation.php',
1025
            ),
1026
        );
1027
    }
1028
1029
    /**
1030
     * Purely for creating relation data needed for testFindRelationFieldContentInfoFiltered()
1031
     * and testFindRelationFieldLocationsFiltered().
1032
     */
1033
    public function testRelationContentCreation()
1034
    {
1035
        $repository = $this->getRepository();
1036
        $galleryType = $repository->getContentTypeService()->loadContentTypeByIdentifier('gallery');
1037
        $contentService = $repository->getContentService();
1038
        $locationService = $repository->getLocationService();
1039
1040
        $locationCreateStruct = $locationService->newLocationCreateStruct(2);// Home
1041
1042
        $createStruct = $contentService->newContentCreateStruct($galleryType, 'eng-GB');
1043
        $createStruct->setField('name', 'Image gallery');
1044
        $createStruct->setField('image', 49);// Images folder
1045
        $draft = $contentService->createContent($createStruct, [$locationCreateStruct]);
1046
        $contentService->publishVersion($draft->getVersionInfo());
1047
1048
        $createStruct = $contentService->newContentCreateStruct($galleryType, 'eng-GB');
1049
        $createStruct->setField('name', 'User gallery');
1050
        $createStruct->setField('image', 4);// User folder
1051
        $draft = $contentService->createContent($createStruct, [$locationCreateStruct]);
1052
        $contentService->publishVersion($draft->getVersionInfo());
1053
1054
        $this->refreshSearch($repository);
1055
    }
1056
1057
    /**
1058
     * Test for FieldRelation using findContentInfo() method.
1059
     *
1060
     * @dataProvider getRelationFieldFilterSearches
1061
     * @see \eZ\Publish\API\Repository\SearchService::findContentInfo()
1062
     * @depends eZ\Publish\API\Repository\Tests\SearchServiceTest::testRelationContentCreation
1063
     */
1064
    public function testFindRelationFieldContentInfoFiltered($queryData, $fixture)
1065
    {
1066
        $this->getRepository(false);// To make sure repo is setup w/o removing data from getRelationFieldFilterContentSearches
1067
        $query = new Query($queryData);
1068
        $this->assertQueryFixture($query, $fixture, null, true, true, false);
1069
    }
1070
1071
    /**
1072
     * Test for FieldRelation using findLocations() method.
1073
     *
1074
     * @dataProvider getRelationFieldFilterSearches
1075
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
1076
     * @depends eZ\Publish\API\Repository\Tests\SearchServiceTest::testRelationContentCreation
1077
     */
1078
    public function testFindRelationFieldLocationsFiltered($queryData, $fixture)
1079
    {
1080
        $this->getRepository(false);// To make sure repo is setup w/o removing data from getRelationFieldFilterContentSearches
1081
        $query = new LocationQuery($queryData);
1082
        $this->assertQueryFixture($query, $fixture, null, true, false, false);
1083
    }
1084
1085 View Code Duplication
    public function testFindSingle()
1086
    {
1087
        $repository = $this->getRepository();
1088
        $searchService = $repository->getSearchService();
1089
1090
        $content = $searchService->findSingle(
1091
            new Criterion\ContentId(
1092
                array(4)
1093
            )
1094
        );
1095
1096
        $this->assertEquals(
1097
            4,
1098
            $content->id
1099
        );
1100
    }
1101
1102 View Code Duplication
    public function testFindNoPerformCount()
1103
    {
1104
        $repository = $this->getRepository();
1105
        $searchService = $repository->getSearchService();
1106
1107
        $query = new Query();
1108
        $query->performCount = false;
1109
        $query->query = new Criterion\ContentTypeId(
1110
            array(4)
1111
        );
1112
1113
        $searchHit = $searchService->findContent($query);
1114
1115
        if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') {
1116
            $this->assertEquals(
1117
                null,
1118
                $searchHit->totalCount
1119
            );
1120
        } else {
1121
            $this->assertEquals(
1122
                2,
1123
                $searchHit->totalCount
1124
            );
1125
        }
1126
    }
1127
1128
    /**
1129
     * @expectedException \RuntimeException
1130
     */
1131 View Code Duplication
    public function testFindNoPerformCountException()
1132
    {
1133
        if (ltrim(get_class($this->getSetupFactory()), '\\') !== 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') {
1134
            $this->markTestSkipped('Only applicable to Legacy/DB based search');
1135
        }
1136
1137
        $repository = $this->getRepository();
1138
        $searchService = $repository->getSearchService();
1139
1140
        $query = new Query();
1141
        $query->performCount = false;
1142
        $query->limit = 0;
1143
        $query->query = new Criterion\ContentTypeId(
1144
            array(4)
1145
        );
1146
1147
        $searchService->findContent($query);
1148
    }
1149
1150 View Code Duplication
    public function testFindLocationsNoPerformCount()
1151
    {
1152
        $repository = $this->getRepository();
1153
        $searchService = $repository->getSearchService();
1154
1155
        $query = new LocationQuery();
1156
        $query->performCount = false;
1157
        $query->query = new Criterion\ContentTypeId(
1158
            array(4)
1159
        );
1160
1161
        $searchHit = $searchService->findLocations($query);
1162
1163
        if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') {
1164
            $this->assertEquals(
1165
                null,
1166
                $searchHit->totalCount
1167
            );
1168
        } else {
1169
            $this->assertEquals(
1170
                2,
1171
                $searchHit->totalCount
1172
            );
1173
        }
1174
    }
1175
1176
    /**
1177
     * @expectedException \RuntimeException
1178
     */
1179 View Code Duplication
    public function testFindLocationsNoPerformCountException()
1180
    {
1181
        if (ltrim(get_class($this->getSetupFactory()), '\\') !== 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') {
1182
            $this->markTestSkipped('Only applicable to Legacy/DB based search');
1183
        }
1184
1185
        $repository = $this->getRepository();
1186
        $searchService = $repository->getSearchService();
1187
1188
        $query = new LocationQuery();
1189
        $query->performCount = false;
1190
        $query->limit = 0;
1191
        $query->query = new Criterion\ContentTypeId(
1192
            array(4)
1193
        );
1194
1195
        $searchService->findLocations($query);
1196
    }
1197
1198
    /**
1199
     * Create test Content with ezcountry field having multiple countries selected.
1200
     *
1201
     * @return Content
1202
     */
1203
    protected function createMultipleCountriesContent()
1204
    {
1205
        $repository = $this->getRepository();
1206
        $contentTypeService = $repository->getContentTypeService();
1207
        $contentService = $repository->getContentService();
1208
1209
        $createStruct = $contentTypeService->newContentTypeCreateStruct('countries-multiple');
1210
        $createStruct->mainLanguageCode = 'eng-GB';
1211
        $createStruct->remoteId = 'countries-multiple-123';
1212
        $createStruct->names = array('eng-GB' => 'Multiple countries');
1213
        $createStruct->creatorId = 14;
1214
        $createStruct->creationDate = new \DateTime();
1215
1216
        $fieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('countries', 'ezcountry');
1217
        $fieldCreate->names = array('eng-GB' => 'Countries');
1218
        $fieldCreate->fieldGroup = 'main';
1219
        $fieldCreate->position = 1;
1220
        $fieldCreate->isTranslatable = false;
1221
        $fieldCreate->isSearchable = true;
1222
        $fieldCreate->fieldSettings = array('isMultiple' => true);
1223
1224
        $createStruct->addFieldDefinition($fieldCreate);
1225
1226
        $contentGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
1227
        $contentTypeDraft = $contentTypeService->createContentType($createStruct, array($contentGroup));
1228
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1229
        $contentType = $contentTypeService->loadContentType($contentTypeDraft->id);
0 ignored issues
show
Documentation introduced by
The property $id is declared protected in eZ\Publish\API\Repositor...ContentType\ContentType. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write 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.");
        }
    }

}

Since the property has write access only, you can use the @property-write 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...
1230
1231
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
1232
        $createStruct->remoteId = 'countries-multiple-456';
1233
        $createStruct->alwaysAvailable = false;
1234
        $createStruct->setField(
1235
            'countries',
1236
            array('BE', 'DE', 'FR', 'HR', 'NO', 'PT', 'RU')
1237
        );
1238
1239
        $draft = $contentService->createContent($createStruct);
1240
        $content = $contentService->publishVersion($draft->getVersionInfo());
1241
1242
        $this->refreshSearch($repository);
1243
1244
        return $content;
1245
    }
1246
1247
    /**
1248
     * Test for the findContent() method.
1249
     *
1250
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
1251
     */
1252 View Code Duplication
    public function testFieldCollectionContains()
1253
    {
1254
        $testContent = $this->createMultipleCountriesContent();
1255
1256
        $query = new Query(
1257
            array(
1258
                'query' => new Criterion\Field(
1259
                    'countries',
1260
                    Criterion\Operator::CONTAINS,
1261
                    'Belgium'
1262
                ),
1263
            )
1264
        );
1265
1266
        $repository = $this->getRepository();
1267
        $searchService = $repository->getSearchService();
1268
        $result = $searchService->findContent($query);
1269
1270
        $this->assertEquals(1, $result->totalCount);
1271
        $this->assertEquals(
1272
            $testContent->id,
1273
            $result->searchHits[0]->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...
1274
        );
1275
    }
1276
1277
    /**
1278
     * Test for the findContent() method.
1279
     *
1280
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
1281
     * @depends eZ\Publish\API\Repository\Tests\SearchServiceTest::testFieldCollectionContains
1282
     */
1283 View Code Duplication
    public function testFieldCollectionContainsNoMatch()
1284
    {
1285
        $this->createMultipleCountriesContent();
1286
        $query = new Query(
1287
            array(
1288
                'query' => new Criterion\Field(
1289
                    'countries',
1290
                    Criterion\Operator::CONTAINS,
1291
                    'Netherlands Antilles'
1292
                ),
1293
            )
1294
        );
1295
1296
        $repository = $this->getRepository();
1297
        $searchService = $repository->getSearchService();
1298
        $result = $searchService->findContent($query);
1299
1300
        $this->assertEquals(0, $result->totalCount);
1301
    }
1302
1303
    /**
1304
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1305
     * @expectedExceptionMessage Argument '$criterion->target' is invalid: No searchable fields found for the given criterion target 'some_hopefully_unknown_field'
1306
     */
1307 View Code Duplication
    public function testInvalidFieldIdentifierRange()
1308
    {
1309
        $repository = $this->getRepository();
1310
        $searchService = $repository->getSearchService();
1311
1312
        $searchService->findContent(
1313
            new Query(
1314
                array(
1315
                    'filter' => new Criterion\Field(
1316
                        'some_hopefully_unknown_field',
1317
                        Criterion\Operator::BETWEEN,
1318
                        array(10, 1000)
1319
                    ),
1320
                    'sortClauses' => array(new SortClause\ContentId()),
1321
                )
1322
            )
1323
        );
1324
    }
1325
1326
    /**
1327
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1328
     * @expectedExceptionMessage Argument '$criterion->target' is invalid: No searchable fields found for the given criterion target 'some_hopefully_unknown_field'
1329
     */
1330 View Code Duplication
    public function testInvalidFieldIdentifierIn()
1331
    {
1332
        $repository = $this->getRepository();
1333
        $searchService = $repository->getSearchService();
1334
1335
        $searchService->findContent(
1336
            new Query(
1337
                array(
1338
                    'filter' => new Criterion\Field(
1339
                        'some_hopefully_unknown_field',
1340
                        Criterion\Operator::EQ,
1341
                        1000
1342
                    ),
1343
                    'sortClauses' => array(new SortClause\ContentId()),
1344
                )
1345
            )
1346
        );
1347
    }
1348
1349
    /**
1350
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1351
     * @expectedExceptionMessage Argument '$criterion->target' is invalid: No searchable fields found for the given criterion target 'tag_cloud_url'
1352
     */
1353 View Code Duplication
    public function testFindContentWithNonSearchableField()
1354
    {
1355
        $repository = $this->getRepository();
1356
        $searchService = $repository->getSearchService();
1357
1358
        $searchService->findContent(
1359
            new Query(
1360
                array(
1361
                    'filter' => new Criterion\Field(
1362
                        'tag_cloud_url',
1363
                        Criterion\Operator::EQ,
1364
                        'http://nimbus.com'
1365
                    ),
1366
                    'sortClauses' => array(new SortClause\ContentId()),
1367
                )
1368
            )
1369
        );
1370
    }
1371
1372
    /**
1373
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1374
     * @expectedExceptionMessage Argument '$sortClause->targetData' is invalid: No searchable fields found for the given sort clause target 'title' on 'template_look'
1375
     */
1376 View Code Duplication
    public function testSortFieldWithNonSearchableField()
1377
    {
1378
        $repository = $this->getRepository();
1379
        $searchService = $repository->getSearchService();
1380
1381
        $searchService->findContent(
1382
            new Query(
1383
                array(
1384
                    'sortClauses' => array(new SortClause\Field('template_look', 'title')),
1385
                )
1386
            )
1387
        );
1388
    }
1389
1390
    /**
1391
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1392
     * @expectedExceptionMessage Argument '$sortClause->targetData' is invalid: No searchable fields found for the given sort clause target 'title' on 'template_look'
1393
     */
1394 View Code Duplication
    public function testSortMapLocationDistanceWithNonSearchableField()
1395
    {
1396
        $repository = $this->getRepository();
1397
        $searchService = $repository->getSearchService();
1398
1399
        $searchService->findContent(
1400
            new Query(
1401
                array(
1402
                    'sortClauses' => array(
1403
                        new SortClause\MapLocationDistance(
1404
                            'template_look',
1405
                            'title',
1406
                            1,
1407
                            2
1408
                        ),
1409
                    ),
1410
                )
1411
            )
1412
        );
1413
    }
1414
1415
    /**
1416
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1417
     */
1418 View Code Duplication
    public function testFindSingleFailMultiple()
1419
    {
1420
        $repository = $this->getRepository();
1421
        $searchService = $repository->getSearchService();
1422
1423
        $searchService->findSingle(
1424
            new Criterion\ContentId(
1425
                array(4, 10)
1426
            )
1427
        );
1428
    }
1429
1430
    /**
1431
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1432
     */
1433
    public function testFindSingleWithNonSearchableField()
1434
    {
1435
        $repository = $this->getRepository();
1436
        $searchService = $repository->getSearchService();
1437
1438
        $searchService->findSingle(
1439
            new Criterion\Field(
1440
                'tag_cloud_url',
1441
                Criterion\Operator::EQ,
1442
                'http://nimbus.com'
1443
            )
1444
        );
1445
    }
1446
1447
    public function getSortedContentSearches()
1448
    {
1449
        $fixtureDir = $this->getFixtureDir();
1450
1451
        return array(
1452
            0 => array(
1453
                array(
1454
                    'filter' => new Criterion\SectionId(array(2)),
1455
                    'offset' => 0,
1456
                    'limit' => 10,
1457
                    'sortClauses' => array(),
1458
                ),
1459
                $fixtureDir . 'SortNone.php',
1460
                // Result having the same sort level should be sorted between them to be system independent
1461
                function (&$data) {
1462
                    usort(
1463
                        $data->searchHits,
1464
                        function ($a, $b) {
1465
                            return ($a->valueObject['id'] < $b->valueObject['id']) ? -1 : 1;
1466
                        }
1467
                    );
1468
                },
1469
            ),
1470
            1 => array(
1471
                array(
1472
                    'filter' => new Criterion\SectionId(array(2)),
1473
                    'offset' => 0,
1474
                    'limit' => 10,
1475
                    'sortClauses' => array(
1476
                        new SortClause\DatePublished(),
1477
                        new SortClause\ContentId(),
1478
                    ),
1479
                ),
1480
                $fixtureDir . 'SortDatePublished.php',
1481
            ),
1482
            2 => array(
1483
                array(
1484
                    'filter' => new Criterion\SectionId(array(2)),
1485
                    'offset' => 0,
1486
                    'limit' => 50,
1487
                    'sortClauses' => array(
1488
                        new SortClause\DateModified(),
1489
                        new SortClause\ContentId(),
1490
                    ),
1491
                ),
1492
                $fixtureDir . 'SortDateModified.php',
1493
            ),
1494
            3 => array(
1495
                array(
1496
                    'filter' => new Criterion\SectionId(array(4, 2, 6, 3)),
1497
                    'offset' => 0,
1498
                    'limit' => 50,
1499
                    'sortClauses' => array(
1500
                        new SortClause\SectionIdentifier(),
1501
                        new SortClause\ContentId(),
1502
                    ),
1503
                ),
1504
                $fixtureDir . 'SortSectionIdentifier.php',
1505
            ),
1506
            4 => array(
1507
                array(
1508
                    'filter' => new Criterion\SectionId(array(4, 2, 6, 3)),
1509
                    'offset' => 0,
1510
                    'limit' => 50,
1511
                    'sortClauses' => array(
1512
                        new SortClause\SectionName(),
1513
                        new SortClause\ContentId(),
1514
                    ),
1515
                ),
1516
                $fixtureDir . 'SortSectionName.php',
1517
            ),
1518
            5 => array(
1519
                array(
1520
                    'filter' => new Criterion\SectionId(array(2, 3)),
1521
                    'offset' => 0,
1522
                    'limit' => 50,
1523
                    'sortClauses' => array(
1524
                        new SortClause\ContentName(),
1525
                        new SortClause\ContentId(),
1526
                    ),
1527
                ),
1528
                $fixtureDir . 'SortContentName.php',
1529
            ),
1530
            6 => array(
1531
                array(
1532
                    'filter' => new Criterion\ContentTypeId(1),
1533
                    'offset' => 0,
1534
                    'limit' => 50,
1535
                    'sortClauses' => array(
1536
                        new SortClause\Field('folder', 'name', Query::SORT_ASC),
1537
                        new SortClause\ContentId(),
1538
                    ),
1539
                ),
1540
                $fixtureDir . 'SortFolderName.php',
1541
            ),
1542
            7 => array(
1543
                array(
1544
                    'filter' => new Criterion\ContentTypeId(array(1, 3)),
1545
                    'offset' => 0,
1546
                    'limit' => 50,
1547
                    'sortClauses' => array(
1548
                        new SortClause\Field('folder', 'name', Query::SORT_ASC),
1549
                        new SortClause\ContentId(),
1550
                    ),
1551
                ),
1552
                $fixtureDir . 'SortFieldMultipleTypes.php',
1553
            ),
1554
            8 => array(
1555
                array(
1556
                    'filter' => new Criterion\ContentTypeId(array(1, 3)),
1557
                    'offset' => 0,
1558
                    'limit' => 50,
1559
                    'sortClauses' => array(
1560
                        new SortClause\Field('folder', 'name', Query::SORT_DESC),
1561
                        new SortClause\ContentId(),
1562
                    ),
1563
                ),
1564
                $fixtureDir . 'SortFieldMultipleTypesReverse.php',
1565
            ),
1566
            9 => array(
1567
                array(
1568
                    'filter' => new Criterion\ContentTypeId(array(1, 3)),
1569
                    'offset' => 3,
1570
                    'limit' => 5,
1571
                    'sortClauses' => array(
1572
                        new SortClause\Field('folder', 'name', Query::SORT_ASC),
1573
                        new SortClause\Field('user', 'first_name', Query::SORT_ASC),
1574
                        new SortClause\ContentId(),
1575
                    ),
1576
                ),
1577
                $fixtureDir . 'SortFieldMultipleTypesSlice.php',
1578
            ),
1579
            10 => array(
1580
                array(
1581
                    'filter' => new Criterion\ContentTypeId(array(1, 3)),
1582
                    'offset' => 3,
1583
                    'limit' => 5,
1584
                    'sortClauses' => array(
1585
                        new SortClause\Field('folder', 'name', Query::SORT_DESC),
1586
                        new SortClause\Field('user', 'first_name', Query::SORT_ASC),
1587
                        new SortClause\ContentId(),
1588
                    ),
1589
                ),
1590
                $fixtureDir . 'SortFieldMultipleTypesSliceReverse.php',
1591
            ),
1592
        );
1593
    }
1594
1595
    public function getSortedLocationSearches()
1596
    {
1597
        $fixtureDir = $this->getFixtureDir();
1598
1599
        return array(
1600
            array(
1601
                array(
1602
                    'filter' => new Criterion\SectionId(array(2)),
1603
                    'offset' => 0,
1604
                    'limit' => 10,
1605
                    'sortClauses' => array(new SortClause\Location\Path(Query::SORT_DESC)),
1606
                ),
1607
                $fixtureDir . 'SortPathString.php',
1608
            ),
1609
            array(
1610
                array(
1611
                    'filter' => new Criterion\SectionId(array(2)),
1612
                    'offset' => 0,
1613
                    'limit' => 10,
1614
                    'sortClauses' => array(new SortClause\Location\Depth(Query::SORT_ASC)),
1615
                ),
1616
                $fixtureDir . 'SortLocationDepth.php',
1617
                // Result having the same sort level should be sorted between them to be system independent
1618
                function (&$data) {
1619
                    // Result with ids:
1620
                    //     4 has depth = 1
1621
                    //     11, 12, 13, 42, 59 have depth = 2
1622
                    //     10, 14 have depth = 3
1623
                    $map = array(
1624
                        4 => 0,
1625
                        11 => 1,
1626
                        12 => 2,
1627
                        13 => 3,
1628
                        42 => 4,
1629
                        59 => 5,
1630
                        10 => 6,
1631
                        14 => 7,
1632
                    );
1633
                    usort(
1634
                        $data->searchHits,
1635
                        function ($a, $b) use ($map) {
1636
                            return ($map[$a->valueObject['id']] < $map[$b->valueObject['id']]) ? -1 : 1;
1637
                        }
1638
                    );
1639
                },
1640
            ),
1641
            array(
1642
                array(
1643
                    'filter' => new Criterion\SectionId(array(3)),
1644
                    'offset' => 0,
1645
                    'limit' => 10,
1646
                    'sortClauses' => array(
1647
                        new SortClause\Location\Path(Query::SORT_DESC),
1648
                        new SortClause\ContentName(Query::SORT_ASC),
1649
                    ),
1650
                ),
1651
                $fixtureDir . 'SortMultiple.php',
1652
            ),
1653
            array(
1654
                array(
1655
                    'filter' => new Criterion\SectionId(array(2)),
1656
                    'offset' => 0,
1657
                    'limit' => 10,
1658
                    'sortClauses' => array(
1659
                        new SortClause\Location\Priority(Query::SORT_DESC),
1660
                        new SortClause\ContentId(),
1661
                    ),
1662
                ),
1663
                $fixtureDir . 'SortDesc.php',
1664
            ),
1665
        );
1666
    }
1667
1668
    /**
1669
     * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType
1670
     */
1671 View Code Duplication
    protected function createTestContentType()
1672
    {
1673
        $repository = $this->getRepository();
1674
        $contentTypeService = $repository->getContentTypeService();
1675
1676
        $createStruct = $contentTypeService->newContentTypeCreateStruct('test-type');
1677
        $createStruct->mainLanguageCode = 'eng-GB';
1678
        $createStruct->names = array('eng-GB' => 'Test type');
1679
        $createStruct->creatorId = 14;
1680
        $createStruct->creationDate = new \DateTime();
1681
1682
        $translatableFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('integer', 'ezinteger');
1683
        $translatableFieldCreate->names = array('eng-GB' => 'Simple translatable integer field');
1684
        $translatableFieldCreate->fieldGroup = 'main';
1685
        $translatableFieldCreate->position = 1;
1686
        $translatableFieldCreate->isTranslatable = true;
1687
        $translatableFieldCreate->isSearchable = true;
1688
1689
        $createStruct->addFieldDefinition($translatableFieldCreate);
1690
1691
        $nonTranslatableFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('integer2', 'ezinteger');
1692
        $nonTranslatableFieldCreate->names = array('eng-GB' => 'Simple non-translatable integer field');
1693
        $nonTranslatableFieldCreate->fieldGroup = 'main';
1694
        $nonTranslatableFieldCreate->position = 2;
1695
        $nonTranslatableFieldCreate->isTranslatable = false;
1696
        $nonTranslatableFieldCreate->isSearchable = true;
1697
1698
        $createStruct->addFieldDefinition($nonTranslatableFieldCreate);
1699
1700
        $contentGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
1701
        $contentTypeDraft = $contentTypeService->createContentType($createStruct, array($contentGroup));
1702
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1703
        $contentType = $contentTypeService->loadContentType($contentTypeDraft->id);
0 ignored issues
show
Documentation introduced by
The property $id is declared protected in eZ\Publish\API\Repositor...ContentType\ContentType. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write 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.");
        }
    }

}

Since the property has write access only, you can use the @property-write 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...
1704
1705
        return $contentType;
1706
    }
1707
1708
    /**
1709
     * @param \eZ\Publish\API\Repository\Values\ContentType\ContentType $contentType
1710
     * @param int $fieldValue11 Value for translatable field in first language
1711
     * @param int $fieldValue12 Value for translatable field in second language
1712
     * @param int $fieldValue2 Value for non translatable field
1713
     * @param string $mainLanguageCode
1714
     * @param bool $alwaysAvailable
1715
     *
1716
     * @return Content
1717
     */
1718
    protected function createMultilingualContent(
1719
        $contentType,
1720
        $fieldValue11 = null,
1721
        $fieldValue12 = null,
1722
        $fieldValue2 = null,
1723
        $mainLanguageCode = 'eng-GB',
1724
        $alwaysAvailable = false
1725
    ) {
1726
        $repository = $this->getRepository();
1727
        $contentService = $repository->getContentService();
1728
1729
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
1730
        $createStruct->alwaysAvailable = $alwaysAvailable;
1731
        $createStruct->mainLanguageCode = $mainLanguageCode;
1732
        if ($fieldValue11) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $fieldValue11 of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1733
            $createStruct->setField('integer', $fieldValue11, 'eng-GB');
1734
        }
1735
        if ($fieldValue12) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $fieldValue12 of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1736
            $createStruct->setField('integer', $fieldValue12, 'ger-DE');
1737
        }
1738
        $createStruct->setField('integer2', $fieldValue2, $mainLanguageCode);
1739
1740
        $locationCreateStruct = $repository->getLocationService()->newLocationCreateStruct(2);
1741
        $draft = $contentService->createContent($createStruct, array($locationCreateStruct));
1742
        $content = $contentService->publishVersion($draft->getVersionInfo());
1743
1744
        $this->refreshSearch($repository);
1745
1746
        return $content;
1747
    }
1748
1749
    protected function checkPrioritizedLanguagesSupport()
1750
    {
1751
        $setupFactory = $this->getSetupFactory();
1752
        if ($setupFactory instanceof LegacyElasticsearch) {
1753
            $this->markTestIncomplete('Prioritized languages are not supported with Elasticsearch engine');
1754
        }
1755
    }
1756
1757
    public function providerForTestMultilingualFieldSort()
1758
    {
1759
        return array(
1760
            0 => array(
1761
                array(
1762
                    1 => array(1, 2, 1),
1763
                    2 => array(2, 1, 2),
1764
                    3 => array(2, 1, 3),
1765
                    4 => array(1, 2, 4),
1766
                ),
1767
                array(
1768
                    'languages' => array(
1769
                        'eng-GB',
1770
                        'ger-DE',
1771
                    ),
1772
                ),
1773
                array(
1774
                    new SortClause\Field('test-type', 'integer', Query::SORT_ASC),
1775
                    new SortClause\Field('test-type', 'integer2', Query::SORT_DESC),
1776
                ),
1777
                /**
1778
                 * Expected order, Value eng-GB, Value ger-DE.
1779
                 *
1780
                 * Content 4, 1, 2, 4
1781
                 * Content 1, 1, 2, 1
1782
                 * Content 3, 2, 1, 3
1783
                 * Content 2, 2, 1, 2
1784
                 */
1785
                array(4, 1, 3, 2),
1786
            ),
1787
            1 => array(
1788
                array(
1789
                    1 => array(1, 2, 1),
1790
                    2 => array(2, 1, 2),
1791
                    3 => array(2, 1, 3),
1792
                    4 => array(1, 2, 4),
1793
                ),
1794
                array(
1795
                    'languages' => array(
1796
                        'ger-DE',
1797
                        'eng-GB',
1798
                    ),
1799
                ),
1800
                array(
1801
                    new SortClause\Field('test-type', 'integer', Query::SORT_ASC),
1802
                    new SortClause\Field('test-type', 'integer2', Query::SORT_DESC),
1803
                ),
1804
                /**
1805
                 * Expected order, Value eng-GB, Value ger-DE.
1806
                 *
1807
                 * Content 3, 2, 1, 3
1808
                 * Content 2, 2, 1, 2
1809
                 * Content 4, 1, 2, 4
1810
                 * Content 1, 1, 2, 1
1811
                 */
1812
                array(3, 2, 4, 1),
1813
            ),
1814
            2 => array(
1815
                array(
1816
                    1 => array(null, 2, null, 'ger-DE'),
1817
                    2 => array(3, null, null, 'eng-GB'),
1818
                    3 => array(4, null, null, 'eng-GB'),
1819
                    4 => array(null, 1, null, 'ger-DE'),
1820
                ),
1821
                array(
1822
                    'languages' => array(
1823
                        'eng-GB',
1824
                    ),
1825
                ),
1826
                array(
1827
                    new SortClause\Field('test-type', 'integer', Query::SORT_DESC),
1828
                ),
1829
                /**
1830
                 * Expected order, Value eng-GB, Value ger-DE.
1831
                 *
1832
                 * Content 3, 4, -
1833
                 * Content 2, 3, -
1834
                 */
1835
                array(3, 2),
1836
            ),
1837
            3 => array(
1838
                array(
1839
                    1 => array(null, 2, null, 'ger-DE'),
1840
                    2 => array(3, null, null, 'eng-GB'),
1841
                    3 => array(4, null, null, 'eng-GB'),
1842
                    4 => array(null, 1, null, 'ger-DE'),
1843
                ),
1844
                array(
1845
                    'languages' => array(
1846
                        'ger-DE',
1847
                    ),
1848
                ),
1849
                array(
1850
                    new SortClause\Field('test-type', 'integer', Query::SORT_DESC),
1851
                ),
1852
                /**
1853
                 * Expected order, Value eng-GB, Value ger-DE.
1854
                 *
1855
                 * Content 1, -, 2
1856
                 * Content 4, -, 1
1857
                 */
1858
                array(1, 4),
1859
            ),
1860
            4 => array(
1861
                array(
1862
                    1 => array(null, 2, null, 'ger-DE'),
1863
                    2 => array(3, null, null, 'eng-GB'),
1864
                    3 => array(4, null, null, 'eng-GB'),
1865
                    4 => array(null, 1, null, 'ger-DE'),
1866
                ),
1867
                array(
1868
                    'languages' => array(
1869
                        'eng-GB',
1870
                        'ger-DE',
1871
                    ),
1872
                ),
1873
                array(
1874
                    new SortClause\Field('test-type', 'integer', Query::SORT_DESC),
1875
                ),
1876
                /**
1877
                 * Expected order, Value eng-GB, Value ger-DE.
1878
                 *
1879
                 * Content 3, 4, -
1880
                 * Content 2, 3, -
1881
                 * Content 1, -, 2
1882
                 * Content 4, -, 1
1883
                 */
1884
                array(3, 2, 1, 4),
1885
            ),
1886
            5 => array(
1887
                array(
1888
                    1 => array(null, 2, null, 'ger-DE'),
1889
                    2 => array(3, null, null, 'eng-GB'),
1890
                    3 => array(4, null, null, 'eng-GB'),
1891
                    4 => array(null, 1, null, 'ger-DE'),
1892
                ),
1893
                array(
1894
                    'languages' => array(
1895
                        'ger-DE',
1896
                        'eng-GB',
1897
                    ),
1898
                ),
1899
                array(
1900
                    new SortClause\Field('test-type', 'integer', Query::SORT_DESC),
1901
                ),
1902
                /**
1903
                 * Expected order, Value eng-GB, Value ger-DE.
1904
                 *
1905
                 * Content 3, 4, -
1906
                 * Content 2, 3, -
1907
                 * Content 1, -, 2
1908
                 * Content 4, -, 1
1909
                 */
1910
                array(3, 2, 1, 4),
1911
            ),
1912
            6 => array(
1913
                array(
1914
                    1 => array(null, 2, null, 'ger-DE'),
1915
                    2 => array(3, 4, null, 'eng-GB'),
1916
                    3 => array(4, 3, null, 'eng-GB'),
1917
                    4 => array(null, 1, null, 'ger-DE'),
1918
                ),
1919
                array(
1920
                    'languages' => array(
1921
                        'eng-GB',
1922
                        'ger-DE',
1923
                    ),
1924
                ),
1925
                array(
1926
                    new SortClause\Field('test-type', 'integer', Query::SORT_DESC),
1927
                ),
1928
                /**
1929
                 * Expected order, Value eng-GB, Value ger-DE.
1930
                 *
1931
                 * Content 3, 4, 3
1932
                 * Content 2, 3, 4
1933
                 * Content 1, -, 2
1934
                 * Content 4, -, 1
1935
                 */
1936
                array(3, 2, 1, 4),
1937
            ),
1938
            7 => array(
1939
                array(
1940
                    1 => array(null, 2, null, 'ger-DE'),
1941
                    2 => array(3, 4, null, 'eng-GB'),
1942
                    3 => array(4, 3, null, 'eng-GB'),
1943
                    4 => array(null, 1, null, 'ger-DE'),
1944
                ),
1945
                array(
1946
                    'languages' => array(
1947
                        'ger-DE',
1948
                        'eng-GB',
1949
                    ),
1950
                ),
1951
                array(
1952
                    new SortClause\Field('test-type', 'integer', Query::SORT_DESC),
1953
                ),
1954
                /**
1955
                 * Expected order, Value eng-GB, Value ger-DE.
1956
                 *
1957
                 * Content 2, 3, 4
1958
                 * Content 3, 4, 3
1959
                 * Content 1, -, 2
1960
                 * Content 4, -, 1
1961
                 */
1962
                array(2, 3, 1, 4),
1963
            ),
1964
            8 => array(
1965
                array(
1966
                    1 => array(null, 1, null, 'ger-DE', true),
1967
                    2 => array(4, null, null, 'eng-GB', true),
1968
                    3 => array(3, null, null, 'eng-GB', false),
1969
                    4 => array(null, 2, null, 'ger-DE', false),
1970
                ),
1971
                array(
1972
                    'languages' => array(
1973
                        'eng-GB',
1974
                    ),
1975
                ),
1976
                array(
1977
                    new SortClause\Field('test-type', 'integer', Query::SORT_ASC),
1978
                ),
1979
                /**
1980
                 * Expected order, Value eng-GB, Value ger-DE.
1981
                 *
1982
                 * Content 1, -, 1
1983
                 * Content 3, 3, -
1984
                 * Content 2, 4, -
1985
                 */
1986
                array(1, 3, 2),
1987
            ),
1988
            9 => array(
1989
                array(
1990
                    1 => array(null, 1, null, 'ger-DE', true),
1991
                    2 => array(4, null, null, 'eng-GB', true),
1992
                    3 => array(3, null, null, 'eng-GB', false),
1993
                    4 => array(null, 2, null, 'ger-DE', false),
1994
                ),
1995
                array(
1996
                    'languages' => array(
1997
                        'ger-DE',
1998
                    ),
1999
                ),
2000
                array(
2001
                    new SortClause\Field('test-type', 'integer', Query::SORT_DESC),
2002
                ),
2003
                /**
2004
                 * Expected order, Value eng-GB, Value ger-DE.
2005
                 *
2006
                 * Content 2, 4, -
2007
                 * Content 4, -, 2
2008
                 * Content 1, -, 1
2009
                 */
2010
                array(2, 4, 1),
2011
            ),
2012
            10 => array(
2013
                array(
2014
                    1 => array(null, 1, null, 'ger-DE', true),
2015
                    2 => array(4, null, null, 'eng-GB', true),
2016
                    3 => array(3, null, null, 'eng-GB', false),
2017
                    4 => array(null, 2, null, 'ger-DE', false),
2018
                ),
2019
                array(
2020
                    'languages' => array(
2021
                        'eng-GB',
2022
                    ),
2023
                    'useAlwaysAvailable' => false,
2024
                ),
2025
                array(
2026
                    new SortClause\Field('test-type', 'integer', Query::SORT_ASC),
2027
                ),
2028
                /**
2029
                 * Expected order, Value eng-GB, Value ger-DE.
2030
                 *
2031
                 * Content 3, 3, -
2032
                 * Content 2, 4, -
2033
                 */
2034
                array(3, 2),
2035
            ),
2036
            11 => array(
2037
                array(
2038
                    1 => array(null, 1, null, 'ger-DE', true),
2039
                    2 => array(4, null, null, 'eng-GB', true),
2040
                    3 => array(3, null, null, 'eng-GB', false),
2041
                    4 => array(null, 2, null, 'ger-DE', false),
2042
                ),
2043
                array(
2044
                    'languages' => array(
2045
                        'ger-DE',
2046
                    ),
2047
                    'useAlwaysAvailable' => false,
2048
                ),
2049
                array(
2050
                    new SortClause\Field('test-type', 'integer', Query::SORT_DESC),
2051
                ),
2052
                /**
2053
                 * Expected order, Value eng-GB, Value ger-DE.
2054
                 *
2055
                 * Content 4, -, 2
2056
                 * Content 1, -, 1
2057
                 */
2058
                array(4, 1),
2059
            ),
2060
        );
2061
    }
2062
2063
    /**
2064
     * Test for the findContent() method.
2065
     *
2066
     * @group rrr
2067
     * @dataProvider providerForTestMultilingualFieldSort
2068
     *
2069
     * @param array $contentDataList
2070
     * @param array $languageSettings
2071
     * @param \eZ\Publish\API\Repository\Values\Content\Query\SortClause[] $sortClauses
2072
     * @param array $expected
2073
     */
2074
    public function testMultilingualFieldSortContent(
2075
        array $contentDataList,
2076
        $languageSettings,
2077
        array $sortClauses,
2078
        $expected
2079
    ) {
2080
        $this->assertMultilingualFieldSort(
2081
            $contentDataList,
2082
            $languageSettings,
2083
            $sortClauses,
2084
            $expected
2085
        );
2086
    }
2087
2088
    /**
2089
     * Test for the findLocations() method.
2090
     *
2091
     * @group rrr
2092
     * @dataProvider providerForTestMultilingualFieldSort
2093
     *
2094
     * @param array $contentDataList
2095
     * @param array $languageSettings
2096
     * @param \eZ\Publish\API\Repository\Values\Content\Query\SortClause[] $sortClauses
2097
     * @param array $expected
2098
     */
2099
    public function testMultilingualFieldSortLocation(
2100
        array $contentDataList,
2101
        $languageSettings,
2102
        array $sortClauses,
2103
        $expected
2104
    ) {
2105
        $this->assertMultilingualFieldSort(
2106
            $contentDataList,
2107
            $languageSettings,
2108
            $sortClauses,
2109
            $expected,
2110
            false
2111
        );
2112
    }
2113
2114
    /**
2115
     * @param array $contentDataList
2116
     * @param array $languageSettings
2117
     * @param \eZ\Publish\API\Repository\Values\Content\Query\SortClause[] $sortClauses
2118
     * @param array $expected
2119
     * @param bool $contentSearch
2120
     */
2121
    protected function assertMultilingualFieldSort(
2122
        array $contentDataList,
2123
        $languageSettings,
2124
        array $sortClauses,
2125
        $expected,
2126
        $contentSearch = true
2127
    ) {
2128
        $this->checkPrioritizedLanguagesSupport();
2129
        $contentType = $this->createTestContentType();
2130
2131
        // Create a draft to account for behaviour with ContentType in different states
2132
        $repository = $this->getRepository();
2133
        $contentTypeService = $repository->getContentTypeService();
2134
        $contentTypeService->createContentTypeDraft($contentType);
2135
2136
        $defaults = array(null, null, null, 'eng-GB', false);
2137
        $contentIdList = array();
2138 View Code Duplication
        foreach ($contentDataList as $key => $contentData) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2139
            $contentData = $contentData + $defaults;
2140
            list(
2141
                $fieldValue11,
2142
                $fieldValue12,
2143
                $fieldValue2,
2144
                $mainLanguageCode,
2145
                $alwaysAvailable
2146
            ) = $contentData;
2147
2148
            $contentIdList[$key] = $this->createMultilingualContent(
2149
                $contentType,
2150
                $fieldValue11,
2151
                $fieldValue12,
2152
                $fieldValue2,
2153
                $mainLanguageCode,
2154
                $alwaysAvailable
2155
            )->id;
2156
        }
2157
2158
        // "article" type Content is not matched, this ensures that non-matched
2159
        // field does not affect sort
2160
        $dummySortClause = new SortClause\Field('article', 'title', Query::SORT_ASC);
2161
        array_unshift($sortClauses, $dummySortClause);
2162
        array_push($sortClauses, $dummySortClause);
2163
2164
        $searchService = $repository->getSearchService();
2165
        if ($contentSearch) {
2166
            $query = new Query(
2167
                array(
2168
                    'query' => new Criterion\ContentTypeId($contentType->id),
2169
                    'sortClauses' => $sortClauses,
2170
                )
2171
            );
2172
            $result = $searchService->findContent($query, $languageSettings);
2173
        } else {
2174
            $query = new LocationQuery(
2175
                array(
2176
                    'query' => new Criterion\ContentTypeId($contentType->id),
2177
                    'sortClauses' => $sortClauses,
2178
                )
2179
            );
2180
            $result = $searchService->findLocations($query, $languageSettings);
2181
        }
2182
2183
        $this->assertEquals(count($expected), $result->totalCount);
2184
2185
        $expectedIdList = array();
2186
        foreach ($expected as $contentNumber) {
2187
            $expectedIdList[] = $contentIdList[$contentNumber];
2188
        }
2189
2190
        $this->assertEquals($expectedIdList, $this->mapResultContentIds($result));
2191
    }
2192
2193
    public function providerForTestMultilingualFieldFilter()
2194
    {
2195
        return array(
2196
            0 => array(
2197
                $fixture = array(
2198
                    1 => array(null, 1, null, 'ger-DE', true),
2199
                    2 => array(4, null, null, 'eng-GB', true),
2200
                    3 => array(3, null, null, 'eng-GB', false),
2201
                    4 => array(null, 2, null, 'ger-DE', false),
2202
                    5 => array(5, null, null, 'eng-GB', true),
2203
                ),
2204
                $languageSettings = array(
2205
                    'languages' => array(
2206
                        'ger-DE',
2207
                    ),
2208
                ),
2209
                new Criterion\Field('integer', Criterion\Operator::LT, 5),
2210
                /**
2211
                 * Expected order, Value eng-GB, Value ger-DE.
2212
                 *
2213
                 * Content 2, 4, -
2214
                 * Content 4, -, 2
2215
                 * Content 1, -, 1
2216
                 */
2217
                array(2, 4, 1),
2218
            ),
2219
            1 => array(
2220
                $fixture,
2221
                array(
2222
                    'languages' => array(
2223
                        'ger-DE',
2224
                    ),
2225
                    'useAlwaysAvailable' => false,
2226
                ),
2227
                new Criterion\Field('integer', Criterion\Operator::LT, 2),
2228
                /**
2229
                 * Expected order, Value eng-GB, Value ger-DE.
2230
                 *
2231
                 * Content 1, -, 1
2232
                 */
2233
                array(1),
2234
            ),
2235
            2 => array(
2236
                $fixture,
2237
                array(
2238
                    'languages' => array(
2239
                        'eng-GB',
2240
                    ),
2241
                ),
2242
                new Criterion\Field('integer', Criterion\Operator::LTE, 4),
2243
                /**
2244
                 * Expected order, Value eng-GB, Value ger-DE.
2245
                 *
2246
                 * Content 5, 5, -
2247
                 * Content 2, 4, -
2248
                 * Content 3, 3, -
2249
                 * Content 1, -, 1
2250
                 */
2251
                array(2, 3, 1),
2252
            ),
2253
            3 => array(
2254
                $fixture,
2255
                array(
2256
                    'languages' => array(
2257
                        'eng-GB',
2258
                    ),
2259
                    'useAlwaysAvailable' => false,
2260
                ),
2261
                new Criterion\Field('integer', Criterion\Operator::LTE, 4),
2262
                /**
2263
                 * Expected order, Value eng-GB, Value ger-DE.
2264
                 *
2265
                 * Content 2, 4, -
2266
                 * Content 3, 3, -
2267
                 */
2268
                array(2, 3),
2269
            ),
2270
            4 => array(
2271
                $fixture,
2272
                $languageSettings,
2273
                new Criterion\Field('integer', Criterion\Operator::LTE, 4),
2274
                /**
2275
                 * Expected order, Value eng-GB, Value ger-DE.
2276
                 *
2277
                 * Content 2, 4, -
2278
                 * Content 4, -, 2
2279
                 * Content 1, -, 1
2280
                 */
2281
                array(2, 4, 1),
2282
            ),
2283
            5 => array(
2284
                $fixture,
2285
                $languageSettings,
2286
                new Criterion\Field('integer', Criterion\Operator::GT, 1),
2287
                /**
2288
                 * Expected order, Value eng-GB, Value ger-DE.
2289
                 *
2290
                 * Content 5, 5, -
2291
                 * Content 2, 4, -
2292
                 * Content 4, -, 2
2293
                 */
2294
                array(5, 2, 4),
2295
            ),
2296
            6 => array(
2297
                $fixture,
2298
                $languageSettings,
2299
                new Criterion\Field('integer', Criterion\Operator::GTE, 2),
2300
                /**
2301
                 * Expected order, Value eng-GB, Value ger-DE.
2302
                 *
2303
                 * Content 5, 5, -
2304
                 * Content 2, 4, -
2305
                 * Content 4, -, 2
2306
                 */
2307
                array(5, 2, 4),
2308
            ),
2309
            7 => array(
2310
                $fixture,
2311
                $languageSettings,
2312
                new Criterion\Field('integer', Criterion\Operator::BETWEEN, array(2, 4)),
2313
                /**
2314
                 * Expected order, Value eng-GB, Value ger-DE.
2315
                 *
2316
                 * Content 2, 4, -
2317
                 * Content 4, -, 2
2318
                 */
2319
                array(2, 4),
2320
            ),
2321
            8 => array(
2322
                $fixture,
2323
                $languageSettings,
2324
                new Criterion\Field('integer', Criterion\Operator::BETWEEN, array(4, 2)),
2325
                array(),
2326
            ),
2327
            9 => array(
2328
                $fixture,
2329
                $languageSettings,
2330
                new Criterion\Field('integer', Criterion\Operator::EQ, 4),
2331
                /**
2332
                 * Expected order, Value eng-GB, Value ger-DE.
2333
                 *
2334
                 * Content 4, -, 2
2335
                 */
2336
                array(2),
2337
            ),
2338
            10 => array(
2339
                $fixture,
2340
                $languageSettings,
2341
                new Criterion\Field('integer', Criterion\Operator::EQ, 2),
2342
                /**
2343
                 * Expected order, Value eng-GB, Value ger-DE.
2344
                 *
2345
                 * Content 2, 4, -
2346
                 */
2347
                array(4),
2348
            ),
2349
        );
2350
    }
2351
2352
    /**
2353
     * Test for the findContent() method.
2354
     *
2355
     * @group ttt
2356
     * @dataProvider providerForTestMultilingualFieldFilter
2357
     *
2358
     * @param array $contentDataList
2359
     * @param array $languageSettings
2360
     * @param \eZ\Publish\API\Repository\Values\Content\Query\Criterion $criterion
2361
     * @param array $expected
2362
     */
2363
    public function testMultilingualFieldFilterContent(
2364
        array $contentDataList,
2365
        $languageSettings,
2366
        Criterion $criterion,
2367
        $expected
2368
    ) {
2369
        $this->assertMultilingualFieldFilter(
2370
            $contentDataList,
2371
            $languageSettings,
2372
            $criterion,
2373
            $expected
2374
        );
2375
    }
2376
2377
    /**
2378
     * Test for the findLocations() method.
2379
     *
2380
     * @group ttt
2381
     * @dataProvider providerForTestMultilingualFieldFilter
2382
     *
2383
     * @param array $contentDataList
2384
     * @param array $languageSettings
2385
     * @param \eZ\Publish\API\Repository\Values\Content\Query\Criterion $criterion
2386
     * @param array $expected
2387
     */
2388
    public function testMultilingualFieldFilterLocation(
2389
        array $contentDataList,
2390
        $languageSettings,
2391
        Criterion $criterion,
2392
        $expected
2393
    ) {
2394
        $this->assertMultilingualFieldFilter(
2395
            $contentDataList,
2396
            $languageSettings,
2397
            $criterion,
2398
            $expected,
2399
            false
2400
        );
2401
    }
2402
2403
    /**
2404
     * @param array $contentDataList
2405
     * @param array $languageSettings
2406
     * @param \eZ\Publish\API\Repository\Values\Content\Query\Criterion $criterion
2407
     * @param array $expected
2408
     * @param bool $contentSearch
2409
     */
2410
    protected function assertMultilingualFieldFilter(
2411
        array $contentDataList,
2412
        $languageSettings,
2413
        Criterion $criterion,
2414
        $expected,
2415
        $contentSearch = true
2416
    ) {
2417
        $this->checkPrioritizedLanguagesSupport();
2418
        $contentType = $this->createTestContentType();
2419
2420
        // Create a draft to account for behaviour with ContentType in different states
2421
        $repository = $this->getRepository();
2422
        $contentTypeService = $repository->getContentTypeService();
2423
        $contentTypeService->createContentTypeDraft($contentType);
2424
2425
        $defaults = array(null, null, null, 'eng-GB', false);
2426
        $contentIdList = array();
2427 View Code Duplication
        foreach ($contentDataList as $key => $contentData) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2428
            $contentData = $contentData + $defaults;
2429
            list(
2430
                $fieldValue11,
2431
                $fieldValue12,
2432
                $fieldValue2,
2433
                $mainLanguageCode,
2434
                $alwaysAvailable
2435
            ) = $contentData;
2436
2437
            $contentIdList[$key] = $this->createMultilingualContent(
2438
                $contentType,
2439
                $fieldValue11,
2440
                $fieldValue12,
2441
                $fieldValue2,
2442
                $mainLanguageCode,
2443
                $alwaysAvailable
2444
            )->id;
2445
        }
2446
2447
        $sortClause = new SortClause\Field('test-type', 'integer', Query::SORT_DESC);
2448
        $searchService = $repository->getSearchService();
2449
        if ($contentSearch) {
2450
            $query = new Query(
2451
                array(
2452
                    'query' => new Criterion\LogicalAnd(
2453
                        array(
2454
                            new Criterion\ContentTypeId($contentType->id),
2455
                            $criterion,
2456
                        )
2457
                    ),
2458
                    'sortClauses' => array($sortClause),
2459
                )
2460
            );
2461
            $result = $searchService->findContent($query, $languageSettings);
2462
        } else {
2463
            $query = new LocationQuery(
2464
                array(
2465
                    'query' => new Criterion\LogicalAnd(
2466
                        array(
2467
                            new Criterion\ContentTypeId($contentType->id),
2468
                            $criterion,
2469
                        )
2470
                    ),
2471
                    'sortClauses' => array($sortClause),
2472
                )
2473
            );
2474
            $result = $searchService->findLocations($query, $languageSettings);
2475
        }
2476
2477
        $this->assertEquals(count($expected), $result->totalCount);
2478
2479
        $expectedIdList = array();
2480
        foreach ($expected as $contentNumber) {
2481
            $expectedIdList[] = $contentIdList[$contentNumber];
2482
        }
2483
2484
        $this->assertEquals($expectedIdList, $this->mapResultContentIds($result));
2485
    }
2486
2487
    /**
2488
     * @param \eZ\Publish\API\Repository\Values\Content\Search\SearchResult $result
2489
     *
2490
     * @return array
2491
     */
2492
    protected function mapResultContentIds(SearchResult $result)
2493
    {
2494
        return array_map(
2495
            function (SearchHit $searchHit) {
2496
                if ($searchHit->valueObject instanceof Location) {
2497
                    return $searchHit->valueObject->contentInfo->id;
2498
                }
2499
2500
                return $searchHit->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...
2501
            },
2502
            $result->searchHits
2503
        );
2504
    }
2505
2506
    /**
2507
     * Test for the findContent() method.
2508
     *
2509
     * @dataProvider getSortedContentSearches
2510
     *
2511
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
2512
     */
2513
    public function testFindAndSortContent($queryData, $fixture, $closure = null)
2514
    {
2515
        $query = new Query($queryData);
2516
        $this->assertQueryFixture($query, $fixture, $closure);
2517
    }
2518
2519
    /**
2520
     * Test for the findContentInfo() method.
2521
     *
2522
     * @dataProvider getSortedContentSearches
2523
     * @see \eZ\Publish\API\Repository\SearchService::findContentInfo()
2524
     */
2525
    public function testFindAndSortContentInfo($queryData, $fixture, $closure = null)
2526
    {
2527
        $query = new Query($queryData);
2528
        $this->assertQueryFixture($query, $fixture, $closure, true);
2529
    }
2530
2531
    /**
2532
     * Test for the findLocations() method.
2533
     *
2534
     * @dataProvider getSortedContentSearches
2535
     *
2536
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
2537
     */
2538
    public function testFindAndSortContentLocations($queryData, $fixture, $closure = null)
2539
    {
2540
        $query = new LocationQuery($queryData);
2541
        $this->assertQueryFixture($query, $fixture, $closure);
2542
    }
2543
2544
    /**
2545
     * Test for the findLocations() method.
2546
     *
2547
     * @dataProvider getSortedLocationSearches
2548
     *
2549
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
2550
     */
2551
    public function testFindAndSortLocations($queryData, $fixture, $closure = null)
2552
    {
2553
        $query = new LocationQuery($queryData);
2554
        $this->assertQueryFixture($query, $fixture, $closure);
2555
    }
2556
2557
    public function getFacettedSearches()
2558
    {
2559
        $fixtureDir = $this->getFixtureDir();
2560
2561
        return array(
2562
            array(
2563
                new Query(
2564
                    array(
2565
                        'filter' => new Criterion\SectionId(array(1)),
2566
                        'offset' => 0,
2567
                        'limit' => 10,
2568
                        'facetBuilders' => array(
2569
                            new FacetBuilder\ContentTypeFacetBuilder(
2570
                                array(
2571
                                    'name' => 'type',
2572
                                )
2573
                            ),
2574
                        ),
2575
                        'sortClauses' => array(new SortClause\ContentId()),
2576
                    )
2577
                ),
2578
                $fixtureDir . '/FacetContentType.php',
2579
                false,
2580
            ),
2581
            array(
2582
                new Query(
2583
                    array(
2584
                        'filter' => new Criterion\SectionId(array(1)),
2585
                        'offset' => 0,
2586
                        'limit' => 10,
2587
                        'facetBuilders' => array(
2588
                            new FacetBuilder\ContentTypeFacetBuilder(
2589
                                array(
2590
                                    'name' => 'type',
2591
                                    'minCount' => 3,
2592
                                )
2593
                            ),
2594
                        ),
2595
                        'sortClauses' => array(new SortClause\ContentId()),
2596
                    )
2597
                ),
2598
                $fixtureDir . '/FacetContentTypeMinCount.php',
2599
                false,
2600
            ),
2601
            array(
2602
                new Query(
2603
                    array(
2604
                        'filter' => new Criterion\SectionId(array(1)),
2605
                        'offset' => 0,
2606
                        'limit' => 10,
2607
                        'facetBuilders' => array(
2608
                            new FacetBuilder\ContentTypeFacetBuilder(
2609
                                array(
2610
                                    'name' => 'type',
2611
                                    'limit' => 5,
2612
                                )
2613
                            ),
2614
                        ),
2615
                        'sortClauses' => array(new SortClause\ContentId()),
2616
                    )
2617
                ),
2618
                $fixtureDir . '/FacetContentTypeMinLimit.php',
2619
                false,
2620
            ),
2621
            array(
2622
                new Query(
2623
                    array(
2624
                        'filter' => new Criterion\SectionId(array(1)),
2625
                        'offset' => 0,
2626
                        'limit' => 10,
2627
                        'facetBuilders' => array(
2628
                            new FacetBuilder\SectionFacetBuilder(
2629
                                array(
2630
                                    'name' => 'section',
2631
                                )
2632
                            ),
2633
                        ),
2634
                        'sortClauses' => array(new SortClause\ContentId()),
2635
                    )
2636
                ),
2637
                $fixtureDir . '/FacetSection.php',
2638
                false,
2639
            ),
2640
            array(
2641
                new Query(
2642
                    array(
2643
                        'filter' => new Criterion\SectionId(array(1)),
2644
                        'offset' => 0,
2645
                        'limit' => 10,
2646
                        'facetBuilders' => array(
2647
                            new FacetBuilder\UserFacetBuilder(
2648
                                array(
2649
                                    'name' => 'creator',
2650
                                )
2651
                            ),
2652
                        ),
2653
                        'sortClauses' => array(new SortClause\ContentId()),
2654
                    )
2655
                ),
2656
                $fixtureDir . '/FacetUser.php',
2657
                false,
2658
            ),
2659
            array(
2660
                new Query(
2661
                    array(
2662
                        'filter' => new Criterion\SectionId(array(1)),
2663
                        'offset' => 0,
2664
                        'limit' => 10,
2665
                        'facetBuilders' => array(
2666
                            new FacetBuilder\TermFacetBuilder(),
2667
                        ),
2668
                        'sortClauses' => array(new SortClause\ContentId()),
2669
                    )
2670
                ),
2671
                $fixtureDir . '/FacetTerm.php',
2672
                true,
2673
            ),
2674
            /* @todo: It needs to be defined how this one is supposed to work.
2675
            array(
2676
                new Query(
2677
                    array(
2678
                        'filter'      => new Criterion\SectionId( array( 1 ) ),
2679
                        'offset'      => 0,
2680
                        'limit'       => 10,
2681
                        'facetBuilders' => array(
2682
                            new FacetBuilder\CriterionFacetBuilder()
2683
                        ),
2684
                        'sortClauses' => array( new SortClause\ContentId() )
2685
                    )
2686
                ),
2687
                $fixtureDir . '/FacetCriterion.php',
2688
                true,
2689
            ), // */
2690
            /* @todo: Add sane ranges here:
2691
            array(
2692
                new Query(
2693
                    array(
2694
                        'filter'      => new Criterion\SectionId( array( 1 ) ),
2695
                        'offset'      => 0,
2696
                        'limit'       => 10,
2697
                        'facetBuilders' => array(
2698
                            new FacetBuilder\DateRangeFacetBuilder( array() )
2699
                        ),
2700
                        'sortClauses' => array( new SortClause\ContentId() )
2701
                    )
2702
                ),
2703
                $fixtureDir . '/FacetDateRange.php',
2704
                true,
2705
            ), // */
2706
            array(
2707
                new Query(
2708
                    array(
2709
                        'filter' => new Criterion\SectionId(array(1)),
2710
                        'offset' => 0,
2711
                        'limit' => 10,
2712
                        'facetBuilders' => array(
2713
                            new FacetBuilder\FieldFacetBuilder(
2714
                                array(
2715
                                    'fieldPaths' => array('article/title'),
2716
                                )
2717
                            ),
2718
                        ),
2719
                        'sortClauses' => array(new SortClause\ContentId()),
2720
                    )
2721
                ),
2722
                $fixtureDir . '/FacetFieldSimple.php',
2723
                true,
2724
            ),
2725
            array(
2726
                new Query(
2727
                    array(
2728
                        'filter' => new Criterion\SectionId(array(1)),
2729
                        'offset' => 0,
2730
                        'limit' => 10,
2731
                        'facetBuilders' => array(
2732
                            new FacetBuilder\FieldFacetBuilder(
2733
                                array(
2734
                                    'fieldPaths' => array('article/title'),
2735
                                    'regex' => '(a|b|c)',
2736
                                )
2737
                            ),
2738
                        ),
2739
                        'sortClauses' => array(new SortClause\ContentId()),
2740
                    )
2741
                ),
2742
                $fixtureDir . '/FacetFieldRegexp.php',
2743
                true,
2744
            ),
2745
            array(
2746
                new Query(
2747
                    array(
2748
                        'filter' => new Criterion\SectionId(array(1)),
2749
                        'offset' => 0,
2750
                        'limit' => 10,
2751
                        'facetBuilders' => array(
2752
                            new FacetBuilder\FieldFacetBuilder(
2753
                                array(
2754
                                    'fieldPaths' => array('article/title'),
2755
                                    'regex' => '(a|b|c)',
2756
                                    'sort' => FacetBuilder\FieldFacetBuilder::TERM_DESC,
2757
                                )
2758
                            ),
2759
                        ),
2760
                        'sortClauses' => array(new SortClause\ContentId()),
2761
                    )
2762
                ),
2763
                $fixtureDir . '/FacetFieldRegexpSortTerm.php',
2764
                true,
2765
            ),
2766
            array(
2767
                new Query(
2768
                    array(
2769
                        'filter' => new Criterion\SectionId(array(1)),
2770
                        'offset' => 0,
2771
                        'limit' => 10,
2772
                        'facetBuilders' => array(
2773
                            new FacetBuilder\FieldFacetBuilder(
2774
                                array(
2775
                                    'fieldPaths' => array('article/title'),
2776
                                    'regex' => '(a|b|c)',
2777
                                    'sort' => FacetBuilder\FieldFacetBuilder::COUNT_DESC,
2778
                                )
2779
                            ),
2780
                        ),
2781
                        'sortClauses' => array(new SortClause\ContentId()),
2782
                    )
2783
                ),
2784
                $fixtureDir . '/FacetFieldRegexpSortCount.php',
2785
                true,
2786
            ),
2787
            /* @todo: Add sane ranges here:
2788
            array(
2789
                new Query(
2790
                    array(
2791
                        'filter'      => new Criterion\SectionId( array( 1 ) ),
2792
                        'offset'      => 0,
2793
                        'limit'       => 10,
2794
                        'facetBuilders' => array(
2795
                            new FacetBuilder\FieldRangeFacetBuilder( array(
2796
                                'fieldPath' => 'product/price',
2797
                            ) )
2798
                        ),
2799
                        'sortClauses' => array( new SortClause\ContentId() )
2800
                    )
2801
                ),
2802
                $fixtureDir . '/FacetFieldRegexpSortCount.php',
2803
                true,
2804
            ), // */
2805
        );
2806
    }
2807
2808
    /**
2809
     * Test for the findContent() method.
2810
     *
2811
     * @dataProvider getFacettedSearches
2812
     *
2813
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
2814
     */
2815 View Code Duplication
    public function testFindFacettedContent(Query $query, $fixture, $skipNotImplemented)
2816
    {
2817
        // Check using get_class since the others extend SetupFactory\Legacy
2818
        if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') {
2819
            $this->markTestSkipped(
2820
                'Facets are not supported by the legacy search engine.'
2821
            );
2822
        }
2823
2824
        $this->assertQueryFixture(
2825
            $query,
2826
            $fixture,
2827
            null,
2828
            true,
2829
            false,
2830
            true,
2831
            $skipNotImplemented
2832
        );
2833
    }
2834
2835
    /**
2836
     * Test for the findContentInfo() method.
2837
     *
2838
     * @dataProvider getFacettedSearches
2839
     * @see \eZ\Publish\API\Repository\SearchService::findContentInfo()
2840
     */
2841 View Code Duplication
    public function testFindFacettedContentInfo(Query $query, $fixture, $skipNotImplemented)
2842
    {
2843
        // Check using get_class since the others extend SetupFactory\Legacy
2844
        if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') {
2845
            $this->markTestSkipped(
2846
                'Facets are not supported by the legacy search engine.'
2847
            );
2848
        }
2849
2850
        $this->assertQueryFixture(
2851
            $query,
2852
            $fixture,
2853
            null,
2854
            true,
2855
            false,
2856
            true,
2857
            $skipNotImplemented
2858
        );
2859
    }
2860
2861
    /**
2862
     * Test for the findContent() method.
2863
     *
2864
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
2865
     */
2866
    public function testQueryCustomField()
2867
    {
2868
        // Check using get_class since the others extend SetupFactory\Legacy
2869
        if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') {
2870
            $this->markTestSkipped(
2871
                'Custom fields are not supported by the legacy search engine.'
2872
            );
2873
        }
2874
2875
        $query = new Query(
2876
            array(
2877
                'query' => new Criterion\CustomField(
2878
                    'custom_field',
2879
                    Criterion\Operator::EQ,
2880
                    'AdMiNiStRaToR'
2881
                ),
2882
                'offset' => 0,
2883
                'limit' => 10,
2884
                'sortClauses' => array(new SortClause\ContentId()),
2885
            )
2886
        );
2887
        $this->assertQueryFixture(
2888
            $query,
2889
            $this->getFixtureDir() . '/QueryCustomField.php'
2890
        );
2891
    }
2892
2893
    /**
2894
     * Test for the findContent() method.
2895
     *
2896
     * This tests explicitely queries the first_name while user is contained in
2897
     * the last_name of admin and anonymous. This is done to show the custom
2898
     * copy field working.
2899
     *
2900
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
2901
     */
2902 View Code Duplication
    public function testQueryModifiedField()
2903
    {
2904
        // Check using get_class since the others extend SetupFactory\Legacy
2905
        if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') {
2906
            $this->markTestIncomplete(
2907
                'Custom fields not supported by LegacySE ' .
2908
                '(@todo: Legacy should fallback to just querying normal field so this should be tested here)'
2909
            );
2910
        }
2911
2912
        $query = new Query(
2913
            array(
2914
                'query' => new Criterion\Field(
2915
                    'first_name',
2916
                    Criterion\Operator::EQ,
2917
                    'User'
2918
                ),
2919
                'offset' => 0,
2920
                'limit' => 10,
2921
                'sortClauses' => array(new SortClause\ContentId()),
2922
            )
2923
        );
2924
        $query->query->setCustomField('user', 'first_name', 'custom_field');
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class eZ\Publish\API\Repositor...Content\Query\Criterion as the method setCustomField() does only exist in the following sub-classes of eZ\Publish\API\Repositor...Content\Query\Criterion: eZ\Publish\API\Repositor...t\Query\Criterion\Field, eZ\Publish\API\Repositor...uery\Criterion\FullText, eZ\Publish\API\Repositor...ion\MapLocationDistance. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
2925
2926
        $this->assertQueryFixture(
2927
            $query,
2928
            $this->getFixtureDir() . '/QueryModifiedField.php'
2929
        );
2930
    }
2931
2932
    /**
2933
     * Test for the findContent() method.
2934
     *
2935
     * This tests first explicitly creates sort clause on the 'short_name' which is empty
2936
     * for all Content instances of 'folder' ContentType. Custom sort field is then set
2937
     * to the index storage name of folder's 'name' field, in order to show the custom
2938
     * sort field working.
2939
     *
2940
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
2941
     */
2942
    public function testSortModifiedField()
2943
    {
2944
        // Check using get_class since the others extend SetupFactory\Legacy
2945
        if (ltrim(get_class($this->getSetupFactory()), '\\') === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') {
2946
            $this->markTestIncomplete(
2947
                'Custom field sort not supported by LegacySE ' .
2948
                '(@todo: Legacy should fallback to just querying normal field so this should be tested here)'
2949
            );
2950
        }
2951
2952
        $sortClause = new SortClause\Field('folder', 'short_name', Query::SORT_ASC);
2953
        $sortClause->setCustomField('folder', 'short_name', 'folder_name_value_s');
2954
2955
        $query = new Query(
2956
            array(
2957
                'filter' => new Criterion\ContentTypeId(1),
2958
                'offset' => 0,
2959
                'limit' => 10,
2960
                'sortClauses' => array(
2961
                    $sortClause,
2962
                    new SortClause\ContentId(),
2963
                ),
2964
            )
2965
        );
2966
2967
        $this->assertQueryFixture(
2968
            $query,
2969
            $this->getFixtureDir() . '/SortFolderName.php'
2970
        );
2971
    }
2972
2973
    /**
2974
     * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType
2975
     */
2976 View Code Duplication
    protected function createTestPlaceContentType()
2977
    {
2978
        $repository = $this->getRepository();
2979
        $contentTypeService = $repository->getContentTypeService();
2980
2981
        $createStruct = $contentTypeService->newContentTypeCreateStruct('testtype');
2982
        $createStruct->mainLanguageCode = 'eng-GB';
2983
        $createStruct->names = array('eng-GB' => 'Test type');
2984
        $createStruct->creatorId = 14;
2985
        $createStruct->creationDate = new \DateTime();
2986
2987
        $translatableFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct('maplocation', 'ezgmaplocation');
2988
        $translatableFieldCreate->names = array('eng-GB' => 'Map location field');
2989
        $translatableFieldCreate->fieldGroup = 'main';
2990
        $translatableFieldCreate->position = 1;
2991
        $translatableFieldCreate->isTranslatable = false;
2992
        $translatableFieldCreate->isSearchable = true;
2993
2994
        $createStruct->addFieldDefinition($translatableFieldCreate);
2995
2996
        $contentGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
2997
        $contentTypeDraft = $contentTypeService->createContentType($createStruct, array($contentGroup));
2998
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
2999
        $contentType = $contentTypeService->loadContentType($contentTypeDraft->id);
0 ignored issues
show
Documentation introduced by
The property $id is declared protected in eZ\Publish\API\Repositor...ContentType\ContentType. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write 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.");
        }
    }

}

Since the property has write access only, you can use the @property-write 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...
3000
3001
        return $contentType;
3002
    }
3003
3004
    /**
3005
     * Test for the findContent() method.
3006
     *
3007
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
3008
     * @group maplocation
3009
     */
3010 View Code Duplication
    public function testMapLocationDistanceLessThanOrEqual()
3011
    {
3012
        $contentType = $this->createTestPlaceContentType();
3013
3014
        // Create a draft to account for behaviour with ContentType in different states
3015
        $repository = $this->getRepository();
3016
        $contentTypeService = $repository->getContentTypeService();
3017
        $contentService = $repository->getContentService();
3018
        $contentTypeService->createContentTypeDraft($contentType);
3019
3020
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3021
        $createStruct->alwaysAvailable = false;
3022
        $createStruct->mainLanguageCode = 'eng-GB';
3023
        $createStruct->setField(
3024
            'maplocation',
3025
            array(
3026
                'latitude' => 45.894877,
3027
                'longitude' => 15.972699,
3028
                'address' => 'Here be wild boars',
3029
            ),
3030
            'eng-GB'
3031
        );
3032
3033
        $draft = $contentService->createContent($createStruct);
3034
        $wildBoars = $contentService->publishVersion($draft->getVersionInfo());
3035
3036
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3037
        $createStruct->alwaysAvailable = false;
3038
        $createStruct->mainLanguageCode = 'eng-GB';
3039
        $createStruct->setField(
3040
            'maplocation',
3041
            array(
3042
                'latitude' => 45.927334,
3043
                'longitude' => 15.934847,
3044
                'address' => 'A lone tree',
3045
            ),
3046
            'eng-GB'
3047
        );
3048
3049
        $draft = $contentService->createContent($createStruct);
3050
        $tree = $contentService->publishVersion($draft->getVersionInfo());
0 ignored issues
show
Unused Code introduced by
$tree is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
3051
3052
        $this->refreshSearch($repository);
3053
3054
        $query = new Query(
3055
            array(
3056
                'filter' => new Criterion\LogicalAnd(
3057
                    array(
3058
                        new Criterion\ContentTypeId($contentType->id),
3059
                        new Criterion\MapLocationDistance(
3060
                            'maplocation',
3061
                            Criterion\Operator::LTE,
3062
                            240,
3063
                            43.756825,
3064
                            15.775074
3065
                        ),
3066
                    )
3067
                ),
3068
                'offset' => 0,
3069
                'limit' => 10,
3070
                'sortClauses' => array(),
3071
            )
3072
        );
3073
3074
        $searchService = $repository->getSearchService();
3075
        $result = $searchService->findContent($query);
3076
3077
        $this->assertEquals(1, $result->totalCount);
3078
        $this->assertEquals(
3079
            $wildBoars->id,
3080
            $result->searchHits[0]->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...
3081
        );
3082
    }
3083
3084
    /**
3085
     * Test for the findContent() method.
3086
     *
3087
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
3088
     * @group maplocation
3089
     */
3090 View Code Duplication
    public function testMapLocationDistanceGreaterThanOrEqual()
3091
    {
3092
        $contentType = $this->createTestPlaceContentType();
3093
3094
        // Create a draft to account for behaviour with ContentType in different states
3095
        $repository = $this->getRepository();
3096
        $contentTypeService = $repository->getContentTypeService();
3097
        $contentService = $repository->getContentService();
3098
        $contentTypeService->createContentTypeDraft($contentType);
3099
3100
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3101
        $createStruct->alwaysAvailable = false;
3102
        $createStruct->mainLanguageCode = 'eng-GB';
3103
        $createStruct->setField(
3104
            'maplocation',
3105
            array(
3106
                'latitude' => 45.894877,
3107
                'longitude' => 15.972699,
3108
                'address' => 'Here be wild boars',
3109
            ),
3110
            'eng-GB'
3111
        );
3112
3113
        $draft = $contentService->createContent($createStruct);
3114
        $wildBoars = $contentService->publishVersion($draft->getVersionInfo());
0 ignored issues
show
Unused Code introduced by
$wildBoars is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
3115
3116
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3117
        $createStruct->alwaysAvailable = false;
3118
        $createStruct->mainLanguageCode = 'eng-GB';
3119
        $createStruct->setField(
3120
            'maplocation',
3121
            array(
3122
                'latitude' => 45.927334,
3123
                'longitude' => 15.934847,
3124
                'address' => 'A lone tree',
3125
            ),
3126
            'eng-GB'
3127
        );
3128
3129
        $draft = $contentService->createContent($createStruct);
3130
        $tree = $contentService->publishVersion($draft->getVersionInfo());
3131
3132
        $this->refreshSearch($repository);
3133
3134
        $query = new Query(
3135
            array(
3136
                'filter' => new Criterion\LogicalAnd(
3137
                    array(
3138
                        new Criterion\ContentTypeId($contentType->id),
3139
                        new Criterion\MapLocationDistance(
3140
                            'maplocation',
3141
                            Criterion\Operator::GTE,
3142
                            240,
3143
                            43.756825,
3144
                            15.775074
3145
                        ),
3146
                    )
3147
                ),
3148
                'offset' => 0,
3149
                'limit' => 10,
3150
                'sortClauses' => array(),
3151
            )
3152
        );
3153
3154
        $searchService = $repository->getSearchService();
3155
        $result = $searchService->findContent($query);
3156
3157
        $this->assertEquals(1, $result->totalCount);
3158
        $this->assertEquals(
3159
            $tree->id,
3160
            $result->searchHits[0]->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...
3161
        );
3162
    }
3163
3164
    /**
3165
     * Test for the findContent() method.
3166
     *
3167
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
3168
     * @group maplocation
3169
     */
3170
    public function testMapLocationDistanceBetween()
3171
    {
3172
        $contentType = $this->createTestPlaceContentType();
3173
3174
        // Create a draft to account for behaviour with ContentType in different states
3175
        $repository = $this->getRepository();
3176
        $contentTypeService = $repository->getContentTypeService();
3177
        $contentService = $repository->getContentService();
3178
        $contentTypeService->createContentTypeDraft($contentType);
3179
3180
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3181
        $createStruct->alwaysAvailable = false;
3182
        $createStruct->mainLanguageCode = 'eng-GB';
3183
        $createStruct->setField(
3184
            'maplocation',
3185
            array(
3186
                'latitude' => 45.894877,
3187
                'longitude' => 15.972699,
3188
                'address' => 'Here be wild boars',
3189
            ),
3190
            'eng-GB'
3191
        );
3192
3193
        $draft = $contentService->createContent($createStruct);
3194
        $wildBoars = $contentService->publishVersion($draft->getVersionInfo());
0 ignored issues
show
Unused Code introduced by
$wildBoars is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
3195
3196
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3197
        $createStruct->alwaysAvailable = false;
3198
        $createStruct->mainLanguageCode = 'eng-GB';
3199
        $createStruct->setField(
3200
            'maplocation',
3201
            array(
3202
                'latitude' => 45.927334,
3203
                'longitude' => 15.934847,
3204
                'address' => 'A lone tree',
3205
            ),
3206
            'eng-GB'
3207
        );
3208
3209
        $draft = $contentService->createContent($createStruct);
3210
        $tree = $contentService->publishVersion($draft->getVersionInfo());
0 ignored issues
show
Unused Code introduced by
$tree is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
3211
3212
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3213
        $createStruct->alwaysAvailable = false;
3214
        $createStruct->mainLanguageCode = 'eng-GB';
3215
        $createStruct->setField(
3216
            'maplocation',
3217
            array(
3218
                'latitude' => 45.903777,
3219
                'longitude' => 15.958788,
3220
                'address' => 'Meadow with mushrooms',
3221
            ),
3222
            'eng-GB'
3223
        );
3224
3225
        $draft = $contentService->createContent($createStruct);
3226
        $mushrooms = $contentService->publishVersion($draft->getVersionInfo());
3227
3228
        $this->refreshSearch($repository);
3229
3230
        $query = new Query(
3231
            array(
3232
                'filter' => new Criterion\LogicalAnd(
3233
                    array(
3234
                        new Criterion\ContentTypeId($contentType->id),
3235
                        new Criterion\MapLocationDistance(
3236
                            'maplocation',
3237
                            Criterion\Operator::BETWEEN,
3238
                            array(239, 241),
3239
                            43.756825,
3240
                            15.775074
3241
                        ),
3242
                    )
3243
                ),
3244
                'offset' => 0,
3245
                'limit' => 10,
3246
                'sortClauses' => array(),
3247
            )
3248
        );
3249
3250
        $searchService = $repository->getSearchService();
3251
        $result = $searchService->findContent($query);
3252
3253
        $this->assertEquals(1, $result->totalCount);
3254
        $this->assertEquals(
3255
            $mushrooms->id,
3256
            $result->searchHits[0]->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...
3257
        );
3258
    }
3259
3260
    /**
3261
     * Test for the findContent() method.
3262
     *
3263
     * This tests the distance over the pole. The tests intentionally uses large range,
3264
     * as the flat Earth model used in Legacy Storage Search is not precise for the use case.
3265
     * What is tested here is that outer bounding box is correctly calculated, so that
3266
     * location is not excluded.
3267
     *
3268
     * Range between 222km and 350km shows the magnitude of error between great-circle
3269
     * (always very precise) and flat Earth (very imprecise for this use case) models.
3270
     *
3271
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
3272
     * @group maplocation
3273
     */
3274
    public function testMapLocationDistanceBetweenPolar()
3275
    {
3276
        $contentType = $this->createTestPlaceContentType();
3277
3278
        // Create a draft to account for behaviour with ContentType in different states
3279
        $repository = $this->getRepository();
3280
        $contentTypeService = $repository->getContentTypeService();
3281
        $contentService = $repository->getContentService();
3282
        $contentTypeService->createContentTypeDraft($contentType);
3283
3284
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3285
        $createStruct->alwaysAvailable = false;
3286
        $createStruct->mainLanguageCode = 'eng-GB';
3287
        $createStruct->setField(
3288
            'maplocation',
3289
            array(
3290
                'latitude' => 89,
3291
                'longitude' => -164,
3292
                'address' => 'Polar bear media tower',
3293
            ),
3294
            'eng-GB'
3295
        );
3296
3297
        $draft = $contentService->createContent($createStruct);
3298
        $polarBear = $contentService->publishVersion($draft->getVersionInfo());
3299
3300
        $this->refreshSearch($repository);
3301
3302
        $query = new Query(
3303
            array(
3304
                'filter' => new Criterion\LogicalAnd(
3305
                    array(
3306
                        new Criterion\ContentTypeId($contentType->id),
3307
                        new Criterion\MapLocationDistance(
3308
                            'maplocation',
3309
                            Criterion\Operator::BETWEEN,
3310
                            array(221, 350),
3311
                            89,
3312
                            16
3313
                        ),
3314
                    )
3315
                ),
3316
                'offset' => 0,
3317
                'limit' => 10,
3318
                'sortClauses' => array(),
3319
            )
3320
        );
3321
3322
        $searchService = $repository->getSearchService();
3323
        $result = $searchService->findContent($query);
3324
3325
        $this->assertEquals(1, $result->totalCount);
3326
        $this->assertEquals(
3327
            $polarBear->id,
3328
            $result->searchHits[0]->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...
3329
        );
3330
    }
3331
3332
    /**
3333
     * Test for the findContent() method.
3334
     *
3335
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
3336
     * @group maplocation
3337
     */
3338 View Code Duplication
    public function testMapLocationDistanceSortAscending()
3339
    {
3340
        $contentType = $this->createTestPlaceContentType();
3341
3342
        // Create a draft to account for behaviour with ContentType in different states
3343
        $repository = $this->getRepository();
3344
        $contentTypeService = $repository->getContentTypeService();
3345
        $contentService = $repository->getContentService();
3346
        $contentTypeService->createContentTypeDraft($contentType);
3347
3348
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3349
        $createStruct->alwaysAvailable = false;
3350
        $createStruct->mainLanguageCode = 'eng-GB';
3351
        $createStruct->setField(
3352
            'maplocation',
3353
            array(
3354
                'latitude' => 45.894877,
3355
                'longitude' => 15.972699,
3356
                'address' => 'Here be wild boars',
3357
            ),
3358
            'eng-GB'
3359
        );
3360
3361
        $draft = $contentService->createContent($createStruct);
3362
        $wildBoars = $contentService->publishVersion($draft->getVersionInfo());
3363
3364
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3365
        $createStruct->alwaysAvailable = false;
3366
        $createStruct->mainLanguageCode = 'eng-GB';
3367
        $createStruct->setField(
3368
            'maplocation',
3369
            array(
3370
                'latitude' => 45.927334,
3371
                'longitude' => 15.934847,
3372
                'address' => 'A lone tree',
3373
            ),
3374
            'eng-GB'
3375
        );
3376
3377
        $draft = $contentService->createContent($createStruct);
3378
        $tree = $contentService->publishVersion($draft->getVersionInfo());
3379
3380
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3381
        $createStruct->alwaysAvailable = false;
3382
        $createStruct->mainLanguageCode = 'eng-GB';
3383
        $createStruct->setField(
3384
            'maplocation',
3385
            array(
3386
                'latitude' => 45.903777,
3387
                'longitude' => 15.958788,
3388
                'address' => 'Meadow with mushrooms',
3389
            ),
3390
            'eng-GB'
3391
        );
3392
3393
        $draft = $contentService->createContent($createStruct);
3394
        $mushrooms = $contentService->publishVersion($draft->getVersionInfo());
3395
3396
        $this->refreshSearch($repository);
3397
3398
        $wellInVodice = array(
3399
            'latitude' => 43.756825,
3400
            'longitude' => 15.775074,
3401
        );
3402
3403
        $query = new Query(
3404
            array(
3405
                'filter' => new Criterion\LogicalAnd(
3406
                    array(
3407
                        new Criterion\ContentTypeId($contentType->id),
3408
                        new Criterion\MapLocationDistance(
3409
                            'maplocation',
3410
                            Criterion\Operator::GTE,
3411
                            235,
3412
                            $wellInVodice['latitude'],
3413
                            $wellInVodice['longitude']
3414
                        ),
3415
                    )
3416
                ),
3417
                'offset' => 0,
3418
                'limit' => 10,
3419
                'sortClauses' => array(
3420
                    new SortClause\MapLocationDistance(
3421
                        'testtype',
3422
                        'maplocation',
3423
                        $wellInVodice['latitude'],
3424
                        $wellInVodice['longitude'],
3425
                        Query::SORT_ASC
3426
                    ),
3427
                ),
3428
            )
3429
        );
3430
3431
        $searchService = $repository->getSearchService();
3432
        $result = $searchService->findContent($query);
3433
3434
        $this->assertEquals(3, $result->totalCount);
3435
        $this->assertEquals(
3436
            $wildBoars->id,
3437
            $result->searchHits[0]->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...
3438
        );
3439
        $this->assertEquals(
3440
            $mushrooms->id,
3441
            $result->searchHits[1]->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...
3442
        );
3443
        $this->assertEquals(
3444
            $tree->id,
3445
            $result->searchHits[2]->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...
3446
        );
3447
    }
3448
3449
    /**
3450
     * Test for the findContent() method.
3451
     *
3452
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
3453
     * @group maplocation
3454
     */
3455 View Code Duplication
    public function testMapLocationDistanceSortDescending()
3456
    {
3457
        $contentType = $this->createTestPlaceContentType();
3458
3459
        // Create a draft to account for behaviour with ContentType in different states
3460
        $repository = $this->getRepository();
3461
        $contentTypeService = $repository->getContentTypeService();
3462
        $contentService = $repository->getContentService();
3463
        $contentTypeService->createContentTypeDraft($contentType);
3464
3465
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3466
        $createStruct->alwaysAvailable = false;
3467
        $createStruct->mainLanguageCode = 'eng-GB';
3468
        $createStruct->setField(
3469
            'maplocation',
3470
            array(
3471
                'latitude' => 45.894877,
3472
                'longitude' => 15.972699,
3473
                'address' => 'Here be wild boars',
3474
            ),
3475
            'eng-GB'
3476
        );
3477
3478
        $draft = $contentService->createContent($createStruct);
3479
        $wildBoars = $contentService->publishVersion($draft->getVersionInfo());
3480
3481
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3482
        $createStruct->alwaysAvailable = false;
3483
        $createStruct->mainLanguageCode = 'eng-GB';
3484
        $createStruct->setField(
3485
            'maplocation',
3486
            array(
3487
                'latitude' => 45.927334,
3488
                'longitude' => 15.934847,
3489
                'address' => 'A lone tree',
3490
            ),
3491
            'eng-GB'
3492
        );
3493
3494
        $draft = $contentService->createContent($createStruct);
3495
        $tree = $contentService->publishVersion($draft->getVersionInfo());
3496
3497
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3498
        $createStruct->alwaysAvailable = false;
3499
        $createStruct->mainLanguageCode = 'eng-GB';
3500
        $createStruct->setField(
3501
            'maplocation',
3502
            array(
3503
                'latitude' => 45.903777,
3504
                'longitude' => 15.958788,
3505
                'address' => 'Meadow with mushrooms',
3506
            ),
3507
            'eng-GB'
3508
        );
3509
3510
        $draft = $contentService->createContent($createStruct);
3511
        $mushrooms = $contentService->publishVersion($draft->getVersionInfo());
3512
3513
        $this->refreshSearch($repository);
3514
3515
        $well = array(
3516
            'latitude' => 43.756825,
3517
            'longitude' => 15.775074,
3518
        );
3519
3520
        $query = new Query(
3521
            array(
3522
                'filter' => new Criterion\LogicalAnd(
3523
                    array(
3524
                        new Criterion\ContentTypeId($contentType->id),
3525
                        new Criterion\MapLocationDistance(
3526
                            'maplocation',
3527
                            Criterion\Operator::GTE,
3528
                            235,
3529
                            $well['latitude'],
3530
                            $well['longitude']
3531
                        ),
3532
                    )
3533
                ),
3534
                'offset' => 0,
3535
                'limit' => 10,
3536
                'sortClauses' => array(
3537
                    new SortClause\MapLocationDistance(
3538
                        'testtype',
3539
                        'maplocation',
3540
                        $well['latitude'],
3541
                        $well['longitude'],
3542
                        Query::SORT_DESC
3543
                    ),
3544
                ),
3545
            )
3546
        );
3547
3548
        $searchService = $repository->getSearchService();
3549
        $result = $searchService->findContent($query);
3550
3551
        $this->assertEquals(3, $result->totalCount);
3552
        $this->assertEquals(
3553
            $wildBoars->id,
3554
            $result->searchHits[2]->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...
3555
        );
3556
        $this->assertEquals(
3557
            $mushrooms->id,
3558
            $result->searchHits[1]->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...
3559
        );
3560
        $this->assertEquals(
3561
            $tree->id,
3562
            $result->searchHits[0]->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...
3563
        );
3564
    }
3565
3566
    /**
3567
     * Test for the findContent() method.
3568
     *
3569
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
3570
     * @group maplocation
3571
     */
3572
    public function testMapLocationDistanceWithCustomField()
3573
    {
3574
        $setupFactory = $this->getSetupFactory();
3575
        if ($setupFactory instanceof LegacyElasticsearch) {
3576
            $this->markTestIncomplete("TODO: Some issues with 'copy_to' and 'geo_point'");
3577
        }
3578
3579
        $contentType = $this->createTestPlaceContentType();
3580
3581
        // Create a draft to account for behaviour with ContentType in different states
3582
        $repository = $this->getRepository();
3583
        $contentTypeService = $repository->getContentTypeService();
3584
        $contentService = $repository->getContentService();
3585
        $contentTypeService->createContentTypeDraft($contentType);
3586
3587
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3588
        $createStruct->alwaysAvailable = false;
3589
        $createStruct->mainLanguageCode = 'eng-GB';
3590
        $createStruct->setField(
3591
            'maplocation',
3592
            array(
3593
                'latitude' => 45.894877,
3594
                'longitude' => 15.972699,
3595
                'address' => 'Here be wild boars',
3596
            ),
3597
            'eng-GB'
3598
        );
3599
3600
        $draft = $contentService->createContent($createStruct);
3601
        $wildBoars = $contentService->publishVersion($draft->getVersionInfo());
3602
3603
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3604
        $createStruct->alwaysAvailable = false;
3605
        $createStruct->mainLanguageCode = 'eng-GB';
3606
        $createStruct->setField(
3607
            'maplocation',
3608
            array(
3609
                'latitude' => 45.927334,
3610
                'longitude' => 15.934847,
3611
                'address' => 'A lone tree',
3612
            ),
3613
            'eng-GB'
3614
        );
3615
3616
        $draft = $contentService->createContent($createStruct);
3617
        $tree = $contentService->publishVersion($draft->getVersionInfo());
0 ignored issues
show
Unused Code introduced by
$tree is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
3618
3619
        $this->refreshSearch($repository);
3620
3621
        $distanceCriterion = new Criterion\MapLocationDistance(
3622
            'maplocation',
3623
            Criterion\Operator::LTE,
3624
            240,
3625
            43.756825,
3626
            15.775074
3627
        );
3628
        $distanceCriterion->setCustomField('testtype', 'maplocation', 'custom_geolocation_field');
3629
3630
        $query = new Query(
3631
            array(
3632
                'filter' => new Criterion\LogicalAnd(
3633
                    array(
3634
                        new Criterion\ContentTypeId($contentType->id),
3635
                        $distanceCriterion,
3636
                    )
3637
                ),
3638
                'offset' => 0,
3639
                'limit' => 10,
3640
                'sortClauses' => array(),
3641
            )
3642
        );
3643
3644
        $searchService = $repository->getSearchService();
3645
        $result = $searchService->findContent($query);
3646
3647
        $this->assertEquals(1, $result->totalCount);
3648
        $this->assertEquals(
3649
            $wildBoars->id,
3650
            $result->searchHits[0]->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...
3651
        );
3652
    }
3653
3654
    /**
3655
     * Test for the findContent() method.
3656
     *
3657
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
3658
     * @group maplocation
3659
     */
3660
    public function testMapLocationDistanceWithCustomFieldSort()
3661
    {
3662
        $setupFactory = $this->getSetupFactory();
3663
        if ($setupFactory instanceof LegacyElasticsearch) {
3664
            $this->markTestIncomplete("TODO: Some issues with 'copy_to' and 'geo_point'");
3665
        }
3666
3667
        $contentType = $this->createTestPlaceContentType();
3668
3669
        // Create a draft to account for behaviour with ContentType in different states
3670
        $repository = $this->getRepository();
3671
        $contentTypeService = $repository->getContentTypeService();
3672
        $contentService = $repository->getContentService();
3673
        $contentTypeService->createContentTypeDraft($contentType);
3674
3675
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3676
        $createStruct->alwaysAvailable = false;
3677
        $createStruct->mainLanguageCode = 'eng-GB';
3678
        $createStruct->setField(
3679
            'maplocation',
3680
            array(
3681
                'latitude' => 45.894877,
3682
                'longitude' => 15.972699,
3683
                'address' => 'Here be wild boars',
3684
            ),
3685
            'eng-GB'
3686
        );
3687
3688
        $draft = $contentService->createContent($createStruct);
3689
        $wildBoars = $contentService->publishVersion($draft->getVersionInfo());
3690
3691
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3692
        $createStruct->alwaysAvailable = false;
3693
        $createStruct->mainLanguageCode = 'eng-GB';
3694
        $createStruct->setField(
3695
            'maplocation',
3696
            array(
3697
                'latitude' => 45.927334,
3698
                'longitude' => 15.934847,
3699
                'address' => 'A lone tree',
3700
            ),
3701
            'eng-GB'
3702
        );
3703
3704
        $draft = $contentService->createContent($createStruct);
3705
        $tree = $contentService->publishVersion($draft->getVersionInfo());
3706
3707
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
3708
        $createStruct->alwaysAvailable = false;
3709
        $createStruct->mainLanguageCode = 'eng-GB';
3710
        $createStruct->setField(
3711
            'maplocation',
3712
            array(
3713
                'latitude' => 45.903777,
3714
                'longitude' => 15.958788,
3715
                'address' => 'Meadow with mushrooms',
3716
            ),
3717
            'eng-GB'
3718
        );
3719
3720
        $draft = $contentService->createContent($createStruct);
3721
        $mushrooms = $contentService->publishVersion($draft->getVersionInfo());
3722
3723
        $this->refreshSearch($repository);
3724
3725
        $well = array(
3726
            'latitude' => 43.756825,
3727
            'longitude' => 15.775074,
3728
        );
3729
3730
        $sortClause = new SortClause\MapLocationDistance(
3731
            'testtype',
3732
            'maplocation',
3733
            $well['latitude'],
3734
            $well['longitude'],
3735
            Query::SORT_DESC
3736
        );
3737
        $sortClause->setCustomField('testtype', 'maplocation', 'custom_geolocation_field');
3738
3739
        $query = new Query(
3740
            array(
3741
                'filter' => new Criterion\LogicalAnd(
3742
                    array(
3743
                        new Criterion\ContentTypeId($contentType->id),
3744
                        new Criterion\MapLocationDistance(
3745
                            'maplocation',
3746
                            Criterion\Operator::GTE,
3747
                            235,
3748
                            $well['latitude'],
3749
                            $well['longitude']
3750
                        ),
3751
                    )
3752
                ),
3753
                'offset' => 0,
3754
                'limit' => 10,
3755
                'sortClauses' => array(
3756
                    $sortClause,
3757
                ),
3758
            )
3759
        );
3760
3761
        $searchService = $repository->getSearchService();
3762
        $result = $searchService->findContent($query);
3763
3764
        $this->assertEquals(3, $result->totalCount);
3765
        $this->assertEquals(
3766
            $wildBoars->id,
3767
            $result->searchHits[2]->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...
3768
        );
3769
        $this->assertEquals(
3770
            $mushrooms->id,
3771
            $result->searchHits[1]->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...
3772
        );
3773
        $this->assertEquals(
3774
            $tree->id,
3775
            $result->searchHits[0]->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...
3776
        );
3777
    }
3778
3779
    /**
3780
     * Test for the findLocations() method.
3781
     *
3782
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
3783
     */
3784 View Code Duplication
    public function testFindMainLocation()
3785
    {
3786
        $plainSiteLocationId = 56;
3787
        $designLocationId = 58;
3788
        $partnersContentId = 59;
3789
        $repository = $this->getRepository();
3790
        $locationService = $repository->getLocationService();
3791
        $contentService = $repository->getContentService();
3792
3793
        // Add secondary Location for "Partners" user group, under "Design" page
3794
        $locationService->createLocation(
3795
            $contentService->loadContentInfo($partnersContentId),
3796
            $locationService->newLocationCreateStruct($designLocationId)
3797
        );
3798
3799
        $this->refreshSearch($repository);
3800
3801
        $query = new LocationQuery(
3802
            array(
3803
                'filter' => new Criterion\LogicalAnd(
3804
                    array(
3805
                        new Criterion\ParentLocationId($designLocationId),
3806
                        new Criterion\Location\IsMainLocation(
3807
                            Criterion\Location\IsMainLocation::MAIN
3808
                        ),
3809
                    )
3810
                ),
3811
                'offset' => 0,
3812
                'limit' => 10,
3813
                'sortClauses' => array(),
3814
            )
3815
        );
3816
3817
        $searchService = $repository->getSearchService();
3818
        $result = $searchService->findLocations($query);
3819
3820
        $this->assertEquals(1, $result->totalCount);
3821
        $this->assertEquals($plainSiteLocationId, $result->searchHits[0]->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...
3822
    }
3823
3824
    /**
3825
     * Test for the findLocations() method.
3826
     *
3827
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
3828
     */
3829 View Code Duplication
    public function testFindNonMainLocation()
3830
    {
3831
        $designLocationId = 58;
3832
        $partnersContentId = 59;
3833
        $repository = $this->getRepository();
3834
        $locationService = $repository->getLocationService();
3835
        $contentService = $repository->getContentService();
3836
3837
        // Add secondary Location for "Partners" user group, under "Design" page
3838
        $newLocation = $locationService->createLocation(
3839
            $contentService->loadContentInfo($partnersContentId),
3840
            $locationService->newLocationCreateStruct($designLocationId)
3841
        );
3842
3843
        $this->refreshSearch($repository);
3844
3845
        $query = new LocationQuery(
3846
            array(
3847
                'filter' => new Criterion\LogicalAnd(
3848
                    array(
3849
                        new Criterion\ParentLocationId($designLocationId),
3850
                        new Criterion\Location\IsMainLocation(
3851
                            Criterion\Location\IsMainLocation::NOT_MAIN
3852
                        ),
3853
                    )
3854
                ),
3855
                'offset' => 0,
3856
                'limit' => 10,
3857
                'sortClauses' => array(),
3858
            )
3859
        );
3860
3861
        $searchService = $repository->getSearchService();
3862
        $result = $searchService->findLocations($query);
3863
3864
        $this->assertEquals(1, $result->totalCount);
3865
        $this->assertEquals($newLocation->id, $result->searchHits[0]->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...
3866
    }
3867
3868
    /**
3869
     * Test for the findLocations() method.
3870
     *
3871
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
3872
     */
3873 View Code Duplication
    public function testSortMainLocationAscending()
3874
    {
3875
        $plainSiteLocationId = 56;
3876
        $designLocationId = 58;
3877
        $partnersContentId = 59;
3878
        $repository = $this->getRepository();
3879
        $locationService = $repository->getLocationService();
3880
        $contentService = $repository->getContentService();
3881
3882
        // Add secondary Location for "Partners" user group, under "Design" page
3883
        $newLocation = $locationService->createLocation(
3884
            $contentService->loadContentInfo($partnersContentId),
3885
            $locationService->newLocationCreateStruct($designLocationId)
3886
        );
3887
3888
        $this->refreshSearch($repository);
3889
3890
        $query = new LocationQuery(
3891
            array(
3892
                'filter' => new Criterion\ParentLocationId($designLocationId),
3893
                'offset' => 0,
3894
                'limit' => 10,
3895
                'sortClauses' => array(
3896
                    new SortClause\Location\IsMainLocation(
3897
                        LocationQuery::SORT_ASC
3898
                    ),
3899
                ),
3900
            )
3901
        );
3902
3903
        $searchService = $repository->getSearchService();
3904
        $result = $searchService->findLocations($query);
3905
3906
        $this->assertEquals(2, $result->totalCount);
3907
        $this->assertEquals($newLocation->id, $result->searchHits[0]->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...
3908
        $this->assertEquals($plainSiteLocationId, $result->searchHits[1]->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...
3909
    }
3910
3911
    /**
3912
     * Test for the findLocations() method.
3913
     *
3914
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
3915
     */
3916 View Code Duplication
    public function testSortMainLocationDescending()
3917
    {
3918
        $plainSiteLocationId = 56;
3919
        $designLocationId = 58;
3920
        $partnersContentId = 59;
3921
        $repository = $this->getRepository();
3922
        $locationService = $repository->getLocationService();
3923
        $contentService = $repository->getContentService();
3924
3925
        // Add secondary Location for "Partners" user group, under "Design" page
3926
        $newLocation = $locationService->createLocation(
3927
            $contentService->loadContentInfo($partnersContentId),
3928
            $locationService->newLocationCreateStruct($designLocationId)
3929
        );
3930
3931
        $this->refreshSearch($repository);
3932
3933
        $query = new LocationQuery(
3934
            array(
3935
                'filter' => new Criterion\ParentLocationId($designLocationId),
3936
                'offset' => 0,
3937
                'limit' => 10,
3938
                'sortClauses' => array(
3939
                    new SortClause\Location\IsMainLocation(
3940
                        LocationQuery::SORT_DESC
3941
                    ),
3942
                ),
3943
            )
3944
        );
3945
3946
        $searchService = $repository->getSearchService();
3947
        $result = $searchService->findLocations($query);
3948
3949
        $this->assertEquals(2, $result->totalCount);
3950
        $this->assertEquals($plainSiteLocationId, $result->searchHits[0]->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...
3951
        $this->assertEquals($newLocation->id, $result->searchHits[1]->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...
3952
    }
3953
3954
    /**
3955
     * Test for the findLocations() method.
3956
     *
3957
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
3958
     */
3959
    public function testContentWithMultipleLocations()
3960
    {
3961
        $repository = $this->getRepository();
3962
        $contentService = $repository->getContentService();
3963
        $contentTypeService = $repository->getContentTypeService();
3964
        $locationService = $repository->getLocationService();
3965
3966
        $forumType = $contentTypeService->loadContentTypeByIdentifier('forum');
3967
3968
        $createStruct = $contentService->newContentCreateStruct($forumType, 'eng-GB');
3969
        $createStruct->alwaysAvailable = false;
3970
        $createStruct->setField('name', 'An awesome duplicate forum');
3971
3972
        $draft = $contentService->createContent($createStruct);
3973
        $content = $contentService->publishVersion($draft->getVersionInfo());
3974
3975
        $locationCreateStruct = $repository->getLocationService()->newLocationCreateStruct(2);
3976
        $location1 = $locationService->createLocation($content->contentInfo, $locationCreateStruct);
3977
        $locationCreateStruct = $repository->getLocationService()->newLocationCreateStruct(5);
3978
        $location2 = $locationService->createLocation($content->contentInfo, $locationCreateStruct);
3979
3980
        $this->refreshSearch($repository);
3981
3982
        $query = new LocationQuery(
3983
            array(
3984
                'filter' => new Criterion\ContentId($content->id),
3985
                'sortClauses' => array(
3986
                    new SortClause\Location\Id(LocationQuery::SORT_ASC),
3987
                ),
3988
            )
3989
        );
3990
3991
        $searchService = $repository->getSearchService();
3992
        $result = $searchService->findLocations($query);
3993
3994
        $this->assertEquals(2, $result->totalCount);
3995
        $this->assertEquals(
3996
            $location1->id,
3997
            $result->searchHits[0]->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...
3998
        );
3999
        $this->assertEquals(
4000
            $location2->id,
4001
            $result->searchHits[1]->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...
4002
        );
4003
    }
4004
4005
    protected function createContentForTestUserMetadataGroupHorizontal()
4006
    {
4007
        $repository = $this->getRepository();
4008
        $contentService = $repository->getContentService();
4009
        $contentTypeService = $repository->getContentTypeService();
4010
        $locationService = $repository->getLocationService();
4011
        $userService = $repository->getUserService();
4012
        $administratorUser = $repository->getCurrentUser();
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
4013
        // ID of the "Administrators" user group in an eZ Publish demo installation
4014
        $administratorsUserGroupId = 12;
4015
        // ID of the "Editors" user group in an eZ Publish demo installation
4016
        $editorsUserGroupId = 13;
4017
4018
        $administratorsUserGroup = $userService->loadUserGroup($administratorsUserGroupId);
4019
        $editorsUserGroup = $userService->loadUserGroup($editorsUserGroupId);
4020
4021
        // Add additional Location for Administrators UserGroup under Editors UserGroup Location
4022
        $locationCreateStruct = $locationService->newLocationCreateStruct(
4023
            $editorsUserGroup->contentInfo->mainLocationId
4024
        );
4025
        $newAdministratorsUserGroupLocation = $locationService->createLocation(
4026
            $administratorsUserGroup->contentInfo,
4027
            $locationCreateStruct
4028
        );
4029
4030
        // Add additional Location for administrator user under newly created UserGroup Location
4031
        $locationCreateStruct = $locationService->newLocationCreateStruct(
4032
            $newAdministratorsUserGroupLocation->id
4033
        );
4034
        $locationService->createLocation(
4035
            $administratorUser->contentInfo,
4036
            $locationCreateStruct
4037
        );
4038
4039
        // Create a Content to be found through Editors UserGroup id.
4040
        // This ensures data is indexed, it could also be done by updating metadata of
4041
        // an existing Content, but slot would need to reindex Content and that should
4042
        // be tested elsewhere (dedicated indexing integration tests, missing ATM).
4043
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
4044
4045
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
4046
        $createStruct->setField('name', 'test');
4047
4048
        $locationCreateStruct = $locationService->newLocationCreateStruct(2);
4049
        $draft = $contentService->createContent($createStruct, array($locationCreateStruct));
4050
        $content = $contentService->publishVersion($draft->getVersionInfo());
4051
        $contentTypeService->createContentTypeDraft($contentType);
4052
4053
        $this->refreshSearch($repository);
4054
4055
        return $content;
4056
    }
4057
4058
    /**
4059
     * Test for the findContent() method.
4060
     *
4061
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
4062
     */
4063
    public function testUserMetadataGroupHorizontalFilterContent($queryType = null)
4064
    {
4065
        if ($queryType === null) {
4066
            $queryType = 'filter';
4067
        }
4068
4069
        $repository = $this->getRepository();
4070
        $searchService = $repository->getSearchService();
4071
        $editorsUserGroupId = 13;
4072
4073
        $content = $this->createContentForTestUserMetadataGroupHorizontal();
4074
4075
        $criteria = array();
4076
        $setupFactory = $this->getSetupFactory();
4077
4078
        // Do not limit for LSE, as it does not not require reindexing.
4079
        // See explanation below.
4080
        if ($setupFactory instanceof LegacySolrSetupFactory || $setupFactory instanceof LegacyElasticsearch) {
0 ignored issues
show
Bug introduced by
The class EzSystems\EzPlatformSolr...tory\LegacySetupFactory does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
4081
            $criteria[] = new Criterion\ContentTypeIdentifier('folder');
4082
        }
4083
4084
        $criteria[] = new Criterion\UserMetadata(
4085
            Criterion\UserMetadata::GROUP,
4086
            Criterion\Operator::EQ,
4087
            $editorsUserGroupId
4088
        );
4089
4090
        $query = new Query(
4091
            array(
4092
                $queryType => new Criterion\LogicalAnd($criteria),
4093
                'sortClauses' => array(
4094
                    new SortClause\ContentId(),
4095
                ),
4096
                'limit' => 50,
4097
            )
4098
        );
4099
4100
        if ($setupFactory instanceof LegacySolrSetupFactory || $setupFactory instanceof LegacyElasticsearch) {
0 ignored issues
show
Bug introduced by
The class EzSystems\EzPlatformSolr...tory\LegacySetupFactory does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
4101
            $result = $searchService->findContent($query);
4102
4103
            // Administrator User is owned by itself, when additional Locations are added
4104
            // it should be reindexed and its UserGroups will updated, which means it should
4105
            // also be found as a Content of Editors UserGroup. However we do not handle this
4106
            // in slots yet, and also miss SPI methods to do it without using Search (also
4107
            // needed to decouple services), because as indexing is asynchronous Search
4108
            // should not eat its own dog food for reindexing.
4109
            $this->assertEquals(1, $result->totalCount);
4110
4111
            $this->assertEquals(
4112
                $content->id,
4113
                $result->searchHits[0]->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...
4114
            );
4115
        } else {
4116
            // This is how it should eventually work for all search engines,
4117
            // with required reindexing slots properly implemented.
4118
4119
            $result = $searchService->findContent($query);
4120
4121
            // Assert last hit manually, as id will change because it is created in test
4122
            // and not present it base fixture.
4123
            $foundContent1 = array_pop($result->searchHits);
4124
            $result->totalCount = $result->totalCount - 1;
0 ignored issues
show
Documentation Bug introduced by
It seems like $result->totalCount - 1 can also be of type double. However, the property $totalCount is declared as type integer|null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
4125
            $this->assertEquals($content->id, $foundContent1->valueObject->id);
4126
4127
            $this->simplifySearchResult($result);
4128
            $this->assertEquals(
4129
                include $this->getFixtureDir() . '/UserMetadata.php',
4130
                $result,
4131
                'Search results do not match.',
4132
                .1 // Be quite generous regarding delay -- most important for scores
4133
            );
4134
        }
4135
    }
4136
4137
    /**
4138
     * Test for the findContent() method.
4139
     *
4140
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
4141
     */
4142
    public function testUserMetadataGroupHorizontalQueryContent()
4143
    {
4144
        $this->testUserMetadataGroupHorizontalFilterContent('query');
4145
    }
4146
4147
    /**
4148
     * Test for the findLocations() method.
4149
     *
4150
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
4151
     */
4152
    public function testUserMetadataGroupHorizontalFilterLocation($queryType = null)
4153
    {
4154
        if ($queryType === null) {
4155
            $queryType = 'filter';
4156
        }
4157
4158
        $repository = $this->getRepository();
4159
        $searchService = $repository->getSearchService();
4160
        $editorsUserGroupId = 13;
4161
4162
        $content = $this->createContentForTestUserMetadataGroupHorizontal();
4163
4164
        $criteria = array();
4165
        $setupFactory = $this->getSetupFactory();
4166
4167
        // Do not limit for LSE, as it does not not require reindexing.
4168
        // See explanation below.
4169
        if ($setupFactory instanceof LegacySolrSetupFactory || $setupFactory instanceof LegacyElasticsearch) {
0 ignored issues
show
Bug introduced by
The class EzSystems\EzPlatformSolr...tory\LegacySetupFactory does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
4170
            $criteria[] = new Criterion\ContentTypeIdentifier('folder');
4171
        }
4172
4173
        $criteria[] = new Criterion\UserMetadata(
4174
            Criterion\UserMetadata::GROUP,
4175
            Criterion\Operator::EQ,
4176
            $editorsUserGroupId
4177
        );
4178
4179
        $query = new LocationQuery(
4180
            array(
4181
                $queryType => new Criterion\LogicalAnd($criteria),
4182
                'sortClauses' => array(
4183
                    new SortClause\Location\Id(),
4184
                ),
4185
                'limit' => 50,
4186
            )
4187
        );
4188
4189
        if ($setupFactory instanceof LegacySolrSetupFactory || $setupFactory instanceof LegacyElasticsearch) {
0 ignored issues
show
Bug introduced by
The class EzSystems\EzPlatformSolr...tory\LegacySetupFactory does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
4190
            $result = $searchService->findLocations($query);
4191
4192
            // Administrator User is owned by itself, when additional Locations are added
4193
            // it should be reindexed and its UserGroups will updated, which means it should
4194
            // also be found as a Content of Editors UserGroup. However we do not handle this
4195
            // in slots yet, and also miss SPI methods to do it without using Search (also
4196
            // needed to decouple services), because as indexing is asynchronous Search
4197
            // should not eat its own dog food for reindexing.
4198
            $this->assertEquals(1, $result->totalCount);
4199
4200
            $this->assertEquals(
4201
                $content->contentInfo->mainLocationId,
4202
                $result->searchHits[0]->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...
4203
            );
4204
        } else {
4205
            // This is how it should eventually work for all search engines,
4206
            // with required reindexing slots properly implemented.
4207
4208
            $result = $searchService->findLocations($query);
4209
4210
            // Assert last two hits manually, as ids will change because they are created
4211
            // in test and not present in base fixture.
4212
            $foundLocation1 = array_pop($result->searchHits);
4213
            $foundLocation2 = array_pop($result->searchHits);
4214
            // Remove additional Administrators UserGroup Location
4215
            array_pop($result->searchHits);
4216
            $result->totalCount = $result->totalCount - 2;
0 ignored issues
show
Documentation Bug introduced by
It seems like $result->totalCount - 2 can also be of type double. However, the property $totalCount is declared as type integer|null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
4217
            $this->assertEquals(
4218
                $content->versionInfo->contentInfo->mainLocationId,
4219
                $foundLocation1->valueObject->id
4220
            );
4221
            $this->assertEquals(
4222
                $repository->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
4223
                $foundLocation2->valueObject->contentId
4224
            );
4225
4226
            $this->simplifySearchResult($result);
4227
            $this->assertEquals(
4228
                include $this->getFixtureDir() . '/UserMetadataLocation.php',
4229
                $result,
4230
                'Search results do not match.',
4231
                .1 // Be quite generous regarding delay -- most important for scores
4232
            );
4233
        }
4234
    }
4235
4236
    /**
4237
     * Test for the findLocations() method.
4238
     *
4239
     * @see \eZ\Publish\API\Repository\SearchService::findLocations()
4240
     */
4241
    public function testUserMetadataGroupHorizontalQueryLocation()
4242
    {
4243
        $this->testUserMetadataGroupHorizontalFilterLocation('query');
4244
    }
4245
4246
    /**
4247
     * Test for FullText on the findContent() method.
4248
     *
4249
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
4250
     */
4251
    public function testFullTextOnNewContent()
4252
    {
4253
        $repository = $this->getRepository();
4254
        $contentService = $repository->getContentService();
4255
        $contentTypeService = $repository->getContentTypeService();
4256
        $locationService = $repository->getLocationService();
4257
        $searchService = $repository->getSearchService();
4258
4259
        $contentCreateStruct = $contentService->newContentCreateStruct(
4260
            $contentTypeService->loadContentTypeByIdentifier('folder'),
4261
            'eng-GB'
4262
        );
4263
4264
        $contentCreateStruct->setField('name', 'foxes');
4265
4266
        $englishContent = $contentService->publishVersion(
4267
            $contentService->createContent(
4268
                $contentCreateStruct,
4269
                array($locationService->newLocationCreateStruct(2))
4270
            )->versionInfo
4271
        );
4272
4273
        $this->refreshSearch($repository);
4274
4275
        $query = new Query(
4276
            array(
4277
                'query' => new Criterion\FullText('foxes'),
4278
            )
4279
        );
4280
4281
        $searchResult = $searchService->findContentInfo($query);
4282
4283
        $this->assertEquals(1, $searchResult->totalCount);
4284
        $this->assertEquals($englishContent->id, $searchResult->searchHits[0]->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...
4285
    }
4286
4287
    /**
4288
     * Test for the findContent() method.
4289
     *
4290
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
4291
     */
4292
    public function testLanguageAnalysisSeparateContent()
4293
    {
4294
        $setupFactory = $this->getSetupFactory();
4295
        if (!$setupFactory instanceof LegacyElasticsearch) {
4296
            $this->markTestSkipped('Language analysis is implemented only for Elasticsearch storage');
4297
        }
4298
4299
        $repository = $this->getRepository();
4300
        $contentService = $repository->getContentService();
4301
        $contentTypeService = $repository->getContentTypeService();
4302
        $locationService = $repository->getLocationService();
4303
        $searchService = $repository->getSearchService();
4304
        $languageService = $repository->getContentLanguageService();
4305
4306
        $languageCreateStruct = $languageService->newLanguageCreateStruct();
4307
        $languageCreateStruct->languageCode = 'rus-RU';
4308
        $languageCreateStruct->name = 'Russian';
4309
4310
        $languageService->createLanguage($languageCreateStruct);
4311
4312
        $contentCreateStruct = $contentService->newContentCreateStruct(
4313
            $contentTypeService->loadContentTypeByIdentifier('folder'),
4314
            'eng-GB'
4315
        );
4316
4317
        $contentCreateStruct->setField('name', 'foxes');
4318
4319
        $englishContent = $contentService->publishVersion(
4320
            $contentService->createContent(
4321
                $contentCreateStruct,
4322
                array($locationService->newLocationCreateStruct(2))
4323
            )->versionInfo
4324
        );
4325
4326
        $contentCreateStruct = $contentService->newContentCreateStruct(
4327
            $contentTypeService->loadContentTypeByIdentifier('folder'),
4328
            'rus-RU'
4329
        );
4330
4331
        $contentCreateStruct->setField('name', 'foxes');
4332
4333
        $russianContent = $contentService->publishVersion(
0 ignored issues
show
Unused Code introduced by
$russianContent is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
4334
            $contentService->createContent(
4335
                $contentCreateStruct,
4336
                array($locationService->newLocationCreateStruct(2))
4337
            )->versionInfo
4338
        );
4339
4340
        // Only Content in English should be found, because Content in Russian
4341
        // will not be correctly stemmed
4342
        $query = new Query(
4343
            array(
4344
                'query' => new Criterion\FullText('foxing'),
4345
            )
4346
        );
4347
4348
        $searchResult = $searchService->findContent($query);
4349
4350
        $this->assertEquals(1, $searchResult->totalCount);
4351
        $this->assertEquals($englishContent->id, $searchResult->searchHits[0]->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...
4352
    }
4353
4354
    /**
4355
     * Test for the findContent() method.
4356
     *
4357
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
4358
     */
4359
    public function testLanguageAnalysisSameContent()
4360
    {
4361
        $setupFactory = $this->getSetupFactory();
4362
        if (!$setupFactory instanceof LegacyElasticsearch) {
4363
            $this->markTestSkipped('Language analysis is implemented only for Elasticsearch storage');
4364
        }
4365
4366
        $repository = $this->getRepository();
4367
        $contentService = $repository->getContentService();
4368
        $contentTypeService = $repository->getContentTypeService();
4369
        $locationService = $repository->getLocationService();
4370
        $searchService = $repository->getSearchService();
4371
        $languageService = $repository->getContentLanguageService();
4372
4373
        $languageCreateStruct = $languageService->newLanguageCreateStruct();
4374
        $languageCreateStruct->languageCode = 'rus-RU';
4375
        $languageCreateStruct->name = 'Russian';
4376
4377
        $languageService->createLanguage($languageCreateStruct);
4378
4379
        $contentCreateStruct = $contentService->newContentCreateStruct(
4380
            $contentTypeService->loadContentTypeByIdentifier('folder'),
4381
            'eng-GB'
4382
        );
4383
4384
        $contentCreateStruct->setField('name', 'foxes важнейшими', 'eng-GB');
4385
        $contentCreateStruct->setField('name', 'foxes важнейшими', 'rus-RU');
4386
4387
        $mixedContent = $contentService->publishVersion(
4388
            $contentService->createContent(
4389
                $contentCreateStruct,
4390
                array($locationService->newLocationCreateStruct(2))
4391
            )->versionInfo
4392
        );
4393
4394
        // Content will be found because translation in Russian will be correctly stemmed
4395
        $query = new Query(
4396
            array(
4397
                'query' => new Criterion\FullText('важнее'),
4398
            )
4399
        );
4400
4401
        $searchResult = $searchService->findContent($query);
4402
4403
        $this->assertEquals(1, $searchResult->totalCount);
4404
        $this->assertEquals($mixedContent->id, $searchResult->searchHits[0]->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...
4405
    }
4406
4407
    /**
4408
     * Test for the findContent() method.
4409
     *
4410
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
4411
     */
4412
    public function testLanguageAnalysisSameContentNotFound()
4413
    {
4414
        $setupFactory = $this->getSetupFactory();
4415
        if (!$setupFactory instanceof LegacyElasticsearch) {
4416
            $this->markTestSkipped('Language analysis is implemented only for Elasticsearch storage');
4417
        }
4418
4419
        $repository = $this->getRepository();
4420
        $contentService = $repository->getContentService();
4421
        $contentTypeService = $repository->getContentTypeService();
4422
        $locationService = $repository->getLocationService();
4423
        $searchService = $repository->getSearchService();
4424
        $languageService = $repository->getContentLanguageService();
4425
4426
        $languageCreateStruct = $languageService->newLanguageCreateStruct();
4427
        $languageCreateStruct->languageCode = 'rus-RU';
4428
        $languageCreateStruct->name = 'Russian';
4429
4430
        $languageService->createLanguage($languageCreateStruct);
4431
4432
        $contentCreateStruct = $contentService->newContentCreateStruct(
4433
            $contentTypeService->loadContentTypeByIdentifier('folder'),
4434
            'eng-GB'
4435
        );
4436
4437
        $contentCreateStruct->setField('name', 'foxes важнейшими', 'eng-GB');
4438
        $contentCreateStruct->setField('name', 'foxes важнейшими', 'rus-RU');
4439
4440
        $mixedContent = $contentService->publishVersion(
0 ignored issues
show
Unused Code introduced by
$mixedContent is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
4441
            $contentService->createContent(
4442
                $contentCreateStruct,
4443
                array($locationService->newLocationCreateStruct(2))
4444
            )->versionInfo
4445
        );
4446
4447
        // Content should be found because translation in Russian will be correctly stemmed
4448
        $query = new Query(
4449
            array(
4450
                'query' => new Criterion\FullText('важнее'),
4451
            )
4452
        );
4453
4454
        // Filtering fields for only English will cause no match because the term will
4455
        // not be correctly stemmed
4456
        $searchResult = $searchService->findContent($query, array('languages' => array('eng-GB')));
4457
4458
        $this->assertEquals(0, $searchResult->totalCount);
4459
    }
4460
4461
    /**
4462
     * Test for the findContent() method.
4463
     *
4464
     * @see \eZ\Publish\API\Repository\SearchService::findContent()
4465
     */
4466
    public function testFulltextComplex()
4467
    {
4468
        $repository = $this->getRepository();
4469
        $contentService = $repository->getContentService();
4470
        $contentTypeService = $repository->getContentTypeService();
4471
        $locationService = $repository->getLocationService();
4472
        $searchService = $repository->getSearchService();
4473
4474
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
4475
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
4476
4477
        $contentCreateStruct->setField('name', 'red');
4478
        $contentCreateStruct->setField('short_name', 'red apple');
4479
        $content1 = $contentService->publishVersion(
4480
            $contentService->createContent(
4481
                $contentCreateStruct,
4482
                [$locationService->newLocationCreateStruct(2)]
4483
            )->versionInfo
4484
        );
4485
4486
        $contentCreateStruct->setField('name', 'apple');
4487
        $contentCreateStruct->setField('short_name', 'two');
4488
        $content2 = $contentService->publishVersion(
4489
            $contentService->createContent(
4490
                $contentCreateStruct,
4491
                [$locationService->newLocationCreateStruct(2)]
4492
            )->versionInfo
4493
        );
4494
4495
        $contentCreateStruct->setField('name', 'red apple');
4496
        $contentCreateStruct->setField('short_name', 'three');
4497
        $content3 = $contentService->publishVersion(
4498
            $contentService->createContent(
4499
                $contentCreateStruct,
4500
                [$locationService->newLocationCreateStruct(2)]
4501
            )->versionInfo
4502
        );
4503
4504
        $this->refreshSearch($repository);
4505
4506
        $query = new Query(
4507
            [
4508
                'query' => new Criterion\FullText(
4509
                    'red apple',
4510
                    [
4511
                        'boost' => [
4512
                            'short_name' => 2,
4513
                        ],
4514
                        'fuzziness' => .1,
4515
                    ]
4516
                ),
4517
            ]
4518
        );
4519
4520
        $searchResult = $searchService->findContent($query, ['languages' => ['eng-GB']]);
4521
4522
        $this->assertEquals(3, $searchResult->totalCount);
4523
4524
        // Legacy search engine does have scoring, sorting the results by ID in that case
4525
        $setupFactory = $this->getSetupFactory();
4526
        if (get_class($setupFactory) === 'eZ\Publish\API\Repository\Tests\SetupFactory\Legacy') {
4527
            usort(
4528
                $searchResult->searchHits,
4529
                function ($a, $b) {
4530
                    return ($a->valueObject->id < $b->valueObject->id) ? -1 : 1;
4531
                }
4532
            );
4533
4534
            $this->assertEquals($content1->id, $searchResult->searchHits[0]->valueObject->id);
4535
            $this->assertEquals($content2->id, $searchResult->searchHits[1]->valueObject->id);
4536
            $this->assertEquals($content3->id, $searchResult->searchHits[2]->valueObject->id);
4537
4538
            return;
4539
        }
4540
4541
        $this->assertEquals($content1->id, $searchResult->searchHits[0]->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...
4542
        $this->assertEquals($content3->id, $searchResult->searchHits[1]->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...
4543
        $this->assertEquals($content2->id, $searchResult->searchHits[2]->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...
4544
    }
4545
4546
    /**
4547
     * Assert that query result matches the given fixture.
4548
     *
4549
     * @param Query $query
4550
     * @param string $fixture
4551
     * @param null|callable $closure
4552
     * @param bool $info
4553
     * @param bool $id
4554
     */
4555
    protected function assertQueryFixture(
4556
        Query $query,
4557
        $fixture,
4558
        $closure = null,
4559
        $ignoreScore = true,
4560
        $info = false,
4561
        $id = true,
4562
        $skipNotImplemented = false
4563
    ) {
4564
        $repository = $this->getRepository();
4565
        $searchService = $repository->getSearchService();
4566
4567
        try {
4568
            if ($query instanceof LocationQuery) {
4569
                $setupFactory = $this->getSetupFactory();
4570
                if ($setupFactory instanceof LegacySolrSetupFactory) {
0 ignored issues
show
Bug introduced by
The class EzSystems\EzPlatformSolr...tory\LegacySetupFactory does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
4571
                    // @todo When we want to test score again by default we will need fixtures for Solr
4572
                }
4573
4574
                if ($setupFactory instanceof LegacyElasticsearch) {
4575
                    $position = strrpos($fixture, '/');
4576
                    $fixture = substr_replace($fixture, '/Location', $position, 0);
4577
                }
4578
4579
                $result = $searchService->findLocations($query);
4580
            } elseif ($query instanceof Query) {
4581
                if ($info) {
4582
                    $result = $searchService->findContentInfo($query);
4583
                } else {
4584
                    $result = $searchService->findContent($query);
4585
                }
4586
            } else {
4587
                $this->fail('Expected instance of LocationQuery or Query, got: ' . gettype($query));
4588
            }
4589
            $this->simplifySearchResult($result);
0 ignored issues
show
Bug introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
4590
        } catch (NotImplementedException $e) {
4591
            if (isset($_ENV['skipForNotImplementedException']) || $skipNotImplemented) {
4592
                $this->markTestSkipped(
4593
                    'This feature is not supported by the current search backend: ' . $e->getMessage()
4594
                );
4595
            }
4596
4597
            throw $e;
4598
        }
4599
4600 View Code Duplication
        if (!is_file($fixture)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
4601
            if (isset($_ENV['ez_tests_record'])) {
4602
                file_put_contents(
4603
                    $record = $fixture . '.recording',
4604
                    "<?php\n\nreturn " . var_export($result, true) . ";\n\n"
4605
                );
4606
                $this->markTestIncomplete("No fixture available. Result recorded at $record. Result: \n" . $this->printResult($result));
4607
            } else {
4608
                $this->markTestIncomplete("No fixture available. Set \$_ENV['ez_tests_record'] to generate it.");
4609
            }
4610
        }
4611
4612
        $fixture = include $fixture;
4613
4614
        if ($closure !== null) {
4615
            $closure($fixture);
4616
            $closure($result);
4617
        }
4618
4619 View Code Duplication
        if ($ignoreScore) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
4620
            foreach (array($fixture, $result) as $set) {
4621
                $property = new \ReflectionProperty(get_class($set), 'maxScore');
4622
                $property->setAccessible(true);
4623
                $property->setValue($set, 0.0);
4624
4625
                foreach ($set->searchHits as $hit) {
4626
                    $property = new \ReflectionProperty(get_class($hit), 'score');
4627
                    $property->setAccessible(true);
4628
                    $property->setValue($hit, 0.0);
4629
                }
4630
            }
4631
        }
4632
4633
        foreach (array($fixture, $result) as $set) {
4634
            foreach ($set->searchHits as $hit) {
4635
                $property = new \ReflectionProperty(get_class($hit), 'index');
4636
                $property->setAccessible(true);
4637
                $property->setValue($hit, null);
4638
4639
                $property = new \ReflectionProperty(get_class($hit), 'matchedTranslation');
4640
                $property->setAccessible(true);
4641
                $property->setValue($hit, null);
4642
4643
                if (!$id) {
4644
                    $hit->valueObject['id'] = null;
4645
                }
4646
            }
4647
        }
4648
4649
        $this->assertEquals(
4650
            $fixture,
4651
            $result,
4652
            'Search results do not match.',
4653
            .99 // Be quite generous regarding delay -- most important for scores
4654
        );
4655
    }
4656
4657
    /**
4658
     * Show a simplified view of the search result for manual introspection.
4659
     *
4660
     * @param SearchResult $result
4661
     *
4662
     * @return string
4663
     */
4664 View Code Duplication
    protected function printResult(SearchResult $result)
4665
    {
4666
        $printed = '';
4667
        foreach ($result->searchHits as $hit) {
4668
            $printed .= sprintf(" - %s (%s)\n", $hit->valueObject['title'], $hit->valueObject['id']);
4669
        }
4670
4671
        return $printed;
4672
    }
4673
4674
    /**
4675
     * Simplify search result.
4676
     *
4677
     * This leads to saner comparisons of results, since we do not get the full
4678
     * content objects every time.
4679
     *
4680
     * @param SearchResult $result
4681
     */
4682
    protected function simplifySearchResult(SearchResult $result)
4683
    {
4684
        $result->time = 1;
4685
4686
        foreach ($result->searchHits as $hit) {
4687
            switch (true) {
4688
                case $hit->valueObject instanceof Content:
4689 View Code Duplication
                case $hit->valueObject instanceof Location:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
4690
                    $hit->valueObject = array(
0 ignored issues
show
Documentation Bug introduced by
It seems like array('id' => $hit->valu...ect->contentInfo->name) of type array<string,?,{"id":"?","title":"?"}> is incompatible with the declared type object<eZ\Publish\API\Re...ory\Values\ValueObject> of property $valueObject.

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...
4691
                        'id' => $hit->valueObject->contentInfo->id,
4692
                        'title' => $hit->valueObject->contentInfo->name,
4693
                    );
4694
                    break;
4695
4696
                case $hit->valueObject instanceof ContentInfo:
4697
                    $hit->valueObject = array(
0 ignored issues
show
Documentation Bug introduced by
It seems like array('id' => $hit->valu...hit->valueObject->name) of type array<string,*,{"id":"*","title":"string"}> is incompatible with the declared type object<eZ\Publish\API\Re...ory\Values\ValueObject> of property $valueObject.

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...
4698
                        'id' => $hit->valueObject->id,
4699
                        'title' => $hit->valueObject->name,
4700
                    );
4701
                    break;
4702
4703
                default:
4704
                    throw new \RuntimeException('Unknown search result hit type: ' . get_class($hit->valueObject));
4705
            }
4706
        }
4707
    }
4708
4709
    /**
4710
     * Get fixture directory.
4711
     *
4712
     * @return string
4713
     */
4714
    protected function getFixtureDir()
4715
    {
4716
        return __DIR__ . '/_fixtures/' . getenv('fixtureDir') . '/';
4717
    }
4718
}
4719