Completed
Push — master ( a063ee...aff5fa )
by
unknown
22:17
created

assertSubtreeInvisibleProperty()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 3
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the eZ Publish Kernel package.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Publish\API\Repository\Tests;
10
11
use eZ\Publish\API\Repository\Tests\SetupFactory\LegacyElasticsearch as LegacyElasticsearchSetupFactory;
12
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
13
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
14
use eZ\Publish\API\Repository\SearchService;
15
use eZ\Publish\API\Repository\Tests\SetupFactory\LegacyElasticsearch;
16
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
17
use eZ\Publish\API\Repository\Values\Content\Query;
18
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
19
use DateTime;
20
21
/**
22
 * Test case for indexing operations with a search engine.
23
 *
24
 * @group integration
25
 * @group search
26
 * @group indexing
27
 */
28
class SearchEngineIndexingTest extends BaseTest
29
{
30
    /**
31
     * Test that indexing full text data depends on the isSearchable flag on the field definition.
32
     */
33
    public function testFindContentInfoFullTextIsSearchable()
34
    {
35
        $searchTerm = 'pamplemousse';
36
        $content = $this->createFullTextIsSearchableContent($searchTerm, true);
37
38
        $repository = $this->getRepository();
39
        $searchService = $repository->getSearchService();
40
41
        $query = new Query(
42
            [
43
                'query' => new Criterion\FullText($searchTerm),
44
            ]
45
        );
46
47
        $searchResult = $searchService->findContentInfo($query);
48
49
        $this->assertEquals(1, $searchResult->totalCount);
50
        $contentInfo = $searchResult->searchHits[0]->valueObject;
51
        $this->assertEquals($content->id, $contentInfo->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...
52
53
        return $contentInfo;
54
    }
55
56
    /**
57
     * Test that indexing full text data depends on the isSearchable flag on the field definition.
58
     *
59
     * @depends testFindContentInfoFullTextIsSearchable
60
     *
61
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
62
     */
63
    public function testFindLocationsFullTextIsSearchable(ContentInfo $contentInfo)
64
    {
65
        $setupFactory = $this->getSetupFactory();
66
        if ($setupFactory instanceof LegacyElasticsearchSetupFactory) {
67
            $this->markTestSkipped(
68
                'Elasticsearch Search Engine is missing full text Location search implementation'
69
            );
70
        }
71
72
        $searchTerm = 'pamplemousse';
73
74
        $repository = $this->getRepository(false);
75
        $searchService = $repository->getSearchService();
76
77
        $query = new LocationQuery(
78
            [
79
                'query' => new Criterion\FullText($searchTerm),
80
            ]
81
        );
82
83
        $searchResult = $searchService->findLocations($query);
84
85
        $this->assertEquals(1, $searchResult->totalCount);
86
        $this->assertEquals(
87
            $contentInfo->mainLocationId,
88
            $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...
89
        );
90
    }
91
92
    /**
93
     * Test that indexing full text data depends on the isSearchable flag on the field definition.
94
     *
95
     * @depends testFindContentInfoFullTextIsSearchable
96
     */
97 View Code Duplication
    public function testFindContentInfoFullTextIsNotSearchable()
98
    {
99
        $searchTerm = 'pamplemousse';
100
        $this->createFullTextIsSearchableContent($searchTerm, false);
101
102
        $repository = $this->getRepository();
103
        $searchService = $repository->getSearchService();
104
105
        $query = new Query(
106
            [
107
                'query' => new Criterion\FullText($searchTerm),
108
            ]
109
        );
110
111
        $searchResult = $searchService->findContentInfo($query);
112
113
        $this->assertEquals(0, $searchResult->totalCount);
114
    }
115
116
    /**
117
     * Test that indexing full text data depends on the isSearchable flag on the field definition.
118
     *
119
     * @depends testFindLocationsFullTextIsSearchable
120
     */
121 View Code Duplication
    public function testFindLocationsFullTextIsNotSearchable()
122
    {
123
        $searchTerm = 'pamplemousse';
124
125
        $repository = $this->getRepository(false);
126
        $searchService = $repository->getSearchService();
127
128
        $query = new LocationQuery(
129
            [
130
                'query' => new Criterion\FullText($searchTerm),
131
            ]
132
        );
133
134
        $searchResult = $searchService->findLocations($query);
135
136
        $this->assertEquals(0, $searchResult->totalCount);
137
    }
138
139
    /**
140
     * Creates Content for testing full text search depending on the isSearchable flag.
141
     *
142
     * @see testFindContentInfoFullTextIsearchable
143
     * @see testFindLocationsFullTextIsSearchable
144
     * @see testFindContentInfoFullTextIsNotSearchable
145
     * @see testFindLocationsFullTextIsNotSearchable
146
     *
147
     * @param string $searchText
148
     * @param bool $isSearchable
149
     *
150
     * @return \eZ\Publish\API\Repository\Values\Content\Content
151
     */
152
    protected function createFullTextIsSearchableContent($searchText, $isSearchable)
153
    {
154
        $repository = $this->getRepository();
155
        $contentService = $repository->getContentService();
156
        $contentTypeService = $repository->getContentTypeService();
157
        $locationService = $repository->getLocationService();
158
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
159
160
        if (!$isSearchable) {
161
            $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
162
            $fieldDefinitionUpdateStruct = $contentTypeService->newFieldDefinitionUpdateStruct();
163
            $fieldDefinitionUpdateStruct->isSearchable = false;
164
165
            $fieldDefinition = $contentType->getFieldDefinition('name');
166
167
            $contentTypeService->updateFieldDefinition(
168
                $contentTypeDraft,
169
                $fieldDefinition,
170
                $fieldDefinitionUpdateStruct
171
            );
172
173
            $contentTypeService->publishContentTypeDraft($contentTypeDraft);
174
            $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
175
        }
176
177
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
178
179
        $contentCreateStruct->setField('name', $searchText);
180
        $contentCreateStruct->setField('short_name', 'hello world');
181
        $content = $contentService->publishVersion(
182
            $contentService->createContent(
183
                $contentCreateStruct,
184
                [$locationService->newLocationCreateStruct(2)]
185
            )->versionInfo
186
        );
187
188
        $this->refreshSearch($repository);
189
190
        return $content;
191
    }
192
193
    /**
194
     * EZP-26186: Make sure index is NOT deleted on removal of version draft (affected Solr & content index on Elastic).
195
     */
196
    public function testDeleteVersion()
197
    {
198
        $repository = $this->getRepository();
199
        $contentService = $repository->getContentService();
200
        $searchService = $repository->getSearchService();
201
202
        $membersContentId = $this->generateId('content', 11);
203
        $contentInfo = $contentService->loadContentInfo($membersContentId);
204
205
        $draft = $contentService->createContentDraft($contentInfo);
206
        $contentService->deleteVersion($draft->getVersionInfo());
207
208
        $this->refreshSearch($repository);
209
210
        // Found
211
        $criterion = new Criterion\LocationId($contentInfo->mainLocationId);
212
        $query = new Query(array('filter' => $criterion));
213
        $result = $searchService->findContentInfo($query);
214
        $this->assertEquals(1, $result->totalCount);
215
        $this->assertEquals(
216
            $contentInfo->id,
217
            $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...
218
        );
219
    }
220
221
    /**
222
     * EZP-26186: Make sure affected child locations are deleted on content deletion (affected Solr & Elastic).
223
     */
224 View Code Duplication
    public function testDeleteContent()
225
    {
226
        $repository = $this->getRepository();
227
        $contentService = $repository->getContentService();
228
        $searchService = $repository->getSearchService();
229
230
        $anonymousUsersContentId = $this->generateId('content', 42);
231
        $contentInfo = $contentService->loadContentInfo($anonymousUsersContentId);
232
233
        $contentService->deleteContent($contentInfo);
234
235
        $this->refreshSearch($repository);
236
237
        // Should not be found
238
        $criterion = new Criterion\ParentLocationId($contentInfo->mainLocationId);
239
        $query = new LocationQuery(array('filter' => $criterion));
240
        $result = $searchService->findLocations($query);
241
        $this->assertEquals(0, $result->totalCount);
242
    }
243
244
    /**
245
     * EZP-26186: Make sure index is deleted on removal of Users  (affected Solr & Elastic).
246
     */
247 View Code Duplication
    public function testDeleteUser()
248
    {
249
        $repository = $this->getRepository();
250
        $userService = $repository->getUserService();
251
        $searchService = $repository->getSearchService();
252
253
        $anonymousContentId = $this->generateId('user', 10);
254
        $user = $userService->loadUser($anonymousContentId);
255
256
        $userService->deleteUser($user);
257
258
        $this->refreshSearch($repository);
259
260
        // Should not be found
261
        $criterion = new Criterion\ContentId($user->id);
262
        $query = new Query(array('filter' => $criterion));
263
        $result = $searchService->findContentInfo($query);
264
        $this->assertEquals(0, $result->totalCount);
265
    }
266
267
    /**
268
     * EZP-26186: Make sure index is deleted on removal of UserGroups  (affected Solr & Elastic).
269
     */
270 View Code Duplication
    public function testDeleteUserGroup()
271
    {
272
        $repository = $this->getRepository();
273
        $userService = $repository->getUserService();
274
        $searchService = $repository->getSearchService();
275
276
        $membersContentId = $this->generateId('user_group', 11);
277
        $userGroup = $userService->loadUserGroup($membersContentId);
278
279
        $userService->deleteUserGroup($userGroup);
280
281
        $this->refreshSearch($repository);
282
283
        // Should not be found
284
        $criterion = new Criterion\ContentId($userGroup->id);
285
        $query = new Query(array('filter' => $criterion));
286
        $result = $searchService->findContentInfo($query);
287
        $this->assertEquals(0, $result->totalCount);
288
    }
289
290
    /**
291
     * Test that a newly created user is available for search.
292
     */
293
    public function testCreateUser()
294
    {
295
        $repository = $this->getRepository();
296
        $userService = $repository->getUserService();
297
        $searchService = $repository->getSearchService();
298
299
        // ID of the "Editors" user group
300
        $editorsGroupId = 13;
301
        $userCreate = $userService->newUserCreateStruct(
302
            'user',
303
            '[email protected]',
304
            'secret',
305
            'eng-US'
306
        );
307
        $userCreate->enabled = true;
308
        $userCreate->setField('first_name', 'Example');
309
        $userCreate->setField('last_name', 'User');
310
311
        // Load parent group for the user
312
        $group = $userService->loadUserGroup($editorsGroupId);
313
314
        // Create a new user instance.
315
        $user = $userService->createUser($userCreate, array($group));
316
317
        $this->refreshSearch($repository);
318
319
        // Should be found
320
        $criterion = new Criterion\ContentId($user->id);
321
        $query = new Query(array('filter' => $criterion));
322
        $result = $searchService->findContentInfo($query);
323
        $this->assertEquals(1, $result->totalCount);
324
    }
325
326
    /**
327
     * Test that a newly updated user is available for search.
328
     */
329
    public function testUpdateUser()
330
    {
331
        $repository = $this->getRepository();
332
        $userService = $repository->getUserService();
333
        $contentService = $repository->getContentService();
334
        $searchService = $repository->getSearchService();
335
336
        $user = $this->createUserVersion1();
337
338
        $newName = 'Drizzt Do\'Urden';
339
        $userUpdate = $userService->newUserUpdateStruct();
340
        $userUpdate->contentUpdateStruct = $contentService->newContentUpdateStruct();
341
        $userUpdate->contentUpdateStruct->setField('first_name', $newName);
342
343
        $userService->updateUser($user, $userUpdate);
344
345
        $this->refreshSearch($repository);
346
347
        // Should be found
348
        $query = new Query(
349
            [
350
                'query' => new Criterion\FullText($newName),
351
            ]
352
        );
353
        $result = $searchService->findContentInfo($query);
354
355
        $this->assertEquals(1, $result->totalCount);
356
    }
357
358
    /**
359
     * Test that a newly created user group is available for search.
360
     */
361
    public function testCreateUserGroup()
362
    {
363
        $repository = $this->getRepository();
364
        $userService = $repository->getUserService();
365
        $searchService = $repository->getSearchService();
366
367
        $mainGroupId = $this->generateId('group', 4);
368
369
        $parentUserGroup = $userService->loadUserGroup($mainGroupId);
370
        $userGroupCreateStruct = $userService->newUserGroupCreateStruct('eng-GB');
371
        $userGroupCreateStruct->setField('name', 'Example Group');
372
373
        // Create a new user group
374
        $userGroup = $userService->createUserGroup(
375
            $userGroupCreateStruct,
376
            $parentUserGroup
377
        );
378
379
        $this->refreshSearch($repository);
380
381
        // Should be found
382
        $criterion = new Criterion\ContentId($userGroup->id);
383
        $query = new Query(array('filter' => $criterion));
384
        $result = $searchService->findContentInfo($query);
385
        $this->assertEquals(1, $result->totalCount);
386
    }
387
388
    /**
389
     * Test that a newly created Location is available for search.
390
     */
391
    public function testCreateLocation()
392
    {
393
        $repository = $this->getRepository();
394
        $searchService = $repository->getSearchService();
395
        $membersLocation = $this->createNewTestLocation();
396
397
        $this->refreshSearch($repository);
398
399
        // Found
400
        $criterion = new Criterion\LocationId($membersLocation->id);
401
        $query = new LocationQuery(array('filter' => $criterion));
402
        $result = $searchService->findLocations($query);
403
        $this->assertEquals(1, $result->totalCount);
404
        $this->assertEquals(
405
            $membersLocation->id,
406
            $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...
407
        );
408
    }
409
410
    /**
411
     * Test that hiding a Location makes it unavailable for search.
412
     */
413
    public function testHideSubtree()
414
    {
415
        $repository = $this->getRepository();
416
        $searchService = $repository->getSearchService();
417
418
        // 5 is the ID of an existing location
419
        $locationId = $this->generateId('location', 5);
420
        $locationService = $repository->getLocationService();
421
        $location = $locationService->loadLocation($locationId);
422
        $locationService->hideLocation($location);
423
        $this->refreshSearch($repository);
424
425
        // Check if parent location is hidden
426
        $criterion = new Criterion\LocationId($locationId);
427
        $query = new LocationQuery(array('filter' => $criterion));
428
        $result = $searchService->findLocations($query);
429
        $this->assertEquals(1, $result->totalCount);
430
        $this->assertTrue($result->searchHits[0]->valueObject->hidden);
0 ignored issues
show
Documentation introduced by
The property hidden 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...
431
432
        // Check if children locations are invisible
433
        $this->assertSubtreeInvisibleProperty($searchService, $locationId, true);
434
    }
435
436
    /**
437
     * Test that hiding and revealing a Location makes it available for search.
438
     */
439
    public function testRevealSubtree()
440
    {
441
        $repository = $this->getRepository();
442
        $searchService = $repository->getSearchService();
443
444
        // 5 is the ID of an existing location
445
        $locationId = $this->generateId('location', 5);
446
        $locationService = $repository->getLocationService();
447
        $location = $locationService->loadLocation($locationId);
448
        $locationService->hideLocation($location);
449
        $this->refreshSearch($repository);
450
        $locationService->unhideLocation($location);
451
        $this->refreshSearch($repository);
452
453
        // Check if parent location is not hidden
454
        $criterion = new Criterion\LocationId($locationId);
455
        $query = new LocationQuery(array('filter' => $criterion));
456
        $result = $searchService->findLocations($query);
457
        $this->assertEquals(1, $result->totalCount);
458
        $this->assertFalse($result->searchHits[0]->valueObject->hidden);
0 ignored issues
show
Documentation introduced by
The property hidden 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...
459
460
        // Check if children locations are not invisible
461
        $this->assertSubtreeInvisibleProperty($searchService, $locationId, false);
462
    }
463
464
    /**
465
     * Test that a copied subtree is available for search.
466
     */
467
    public function testCopySubtree()
468
    {
469
        $repository = $this->getRepository();
470
        $locationService = $repository->getLocationService();
471
        $contentService = $repository->getContentService();
472
        $searchService = $repository->getSearchService();
473
474
        $rootLocationId = 2;
475
        $membersContentId = 11;
476
        $adminsContentId = 12;
477
        $editorsContentId = 13;
478
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
479
        $adminsContentInfo = $contentService->loadContentInfo($adminsContentId);
480
        $editorsContentInfo = $contentService->loadContentInfo($editorsContentId);
481
482
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
483
        $membersLocation = $locationService->createLocation($membersContentInfo, $locationCreateStruct);
484
        $editorsLocation = $locationService->createLocation($editorsContentInfo, $locationCreateStruct);
485
        $adminsLocation = $locationService->createLocation(
486
            $adminsContentInfo,
487
            $locationService->newLocationCreateStruct($membersLocation->id)
488
        );
489
490
        $copiedLocation = $locationService->copySubtree($adminsLocation, $editorsLocation);
491
        $this->refreshSearch($repository);
492
493
        // Found under Members
494
        $criterion = new Criterion\ParentLocationId($membersLocation->id);
495
        $query = new LocationQuery(array('filter' => $criterion));
496
        $result = $searchService->findLocations($query);
497
        $this->assertEquals(1, $result->totalCount);
498
        $this->assertEquals(
499
            $adminsLocation->id,
500
            $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...
501
        );
502
503
        // Found under Editors
504
        $criterion = new Criterion\ParentLocationId($editorsLocation->id);
505
        $query = new LocationQuery(array('filter' => $criterion));
506
        $result = $searchService->findLocations($query);
507
        $this->assertEquals(1, $result->totalCount);
508
        $this->assertEquals(
509
            $copiedLocation->id,
510
            $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...
511
        );
512
    }
513
514
    /**
515
     * Test that moved subtree is available for search and found only under a specific parent Location.
516
     */
517
    public function testMoveSubtree()
518
    {
519
        $repository = $this->getRepository();
520
        $locationService = $repository->getLocationService();
521
        $contentService = $repository->getContentService();
522
        $searchService = $repository->getSearchService();
523
524
        $rootLocationId = 2;
525
        $membersContentId = 11;
526
        $adminsContentId = 12;
527
        $editorsContentId = 13;
528
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
529
        $adminsContentInfo = $contentService->loadContentInfo($adminsContentId);
530
        $editorsContentInfo = $contentService->loadContentInfo($editorsContentId);
531
532
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
533
        $membersLocation = $locationService->createLocation($membersContentInfo, $locationCreateStruct);
534
        $editorsLocation = $locationService->createLocation($editorsContentInfo, $locationCreateStruct);
535
        $adminsLocation = $locationService->createLocation(
536
            $adminsContentInfo,
537
            $locationService->newLocationCreateStruct($membersLocation->id)
538
        );
539
540
        $this->refreshSearch($repository);
541
542
        // Not found under Editors
543
        $criterion = new Criterion\ParentLocationId($editorsLocation->id);
544
        $query = new LocationQuery(array('filter' => $criterion));
545
        $result = $searchService->findLocations($query);
546
        $this->assertEquals(0, $result->totalCount);
547
548
        // Found under Members
549
        $criterion = new Criterion\ParentLocationId($membersLocation->id);
550
        $query = new LocationQuery(array('filter' => $criterion));
551
        $result = $searchService->findLocations($query);
552
        $this->assertEquals(1, $result->totalCount);
553
        $this->assertEquals(
554
            $adminsLocation->id,
555
            $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...
556
        );
557
558
        $locationService->moveSubtree($adminsLocation, $editorsLocation);
559
        $this->refreshSearch($repository);
560
561
        // Found under Editors
562
        $criterion = new Criterion\ParentLocationId($editorsLocation->id);
563
        $query = new LocationQuery(array('filter' => $criterion));
564
        $result = $searchService->findLocations($query);
565
        $this->assertEquals(1, $result->totalCount);
566
        $this->assertEquals(
567
            $adminsLocation->id,
568
            $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...
569
        );
570
571
        // Not found under Members
572
        $criterion = new Criterion\ParentLocationId($membersLocation->id);
573
        $query = new LocationQuery(array('filter' => $criterion));
574
        $result = $searchService->findLocations($query);
575
        $this->assertEquals(0, $result->totalCount);
576
    }
577
578
    /**
579
     * Testing that content is indexed even when containing only fields with values
580
     * considered to be empty by the search engine.
581
     */
582
    public function testIndexContentWithNullField()
583
    {
584
        $repository = $this->getRepository();
585
        $contentService = $repository->getContentService();
586
        $contentTypeService = $repository->getContentTypeService();
587
        $searchService = $repository->getSearchService();
588
589
        $createStruct = $contentTypeService->newContentTypeCreateStruct('test-type');
590
        $createStruct->mainLanguageCode = 'eng-GB';
591
        $createStruct->names = array('eng-GB' => 'Test type');
592
        $createStruct->creatorId = 14;
593
        $createStruct->creationDate = new DateTime();
594
595
        $translatableFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct(
596
            'integer',
597
            'ezinteger'
598
        );
599
        $translatableFieldCreate->names = array('eng-GB' => 'Simple translatable integer field');
600
        $translatableFieldCreate->fieldGroup = 'main';
601
        $translatableFieldCreate->position = 1;
602
        $translatableFieldCreate->isTranslatable = true;
603
        $translatableFieldCreate->isSearchable = true;
604
605
        $createStruct->addFieldDefinition($translatableFieldCreate);
606
607
        $contentGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
608
        $contentTypeDraft = $contentTypeService->createContentType(
609
            $createStruct,
610
            array($contentGroup)
611
        );
612
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
613
        $contentType = $contentTypeService->loadContentType($contentTypeDraft->id);
614
615
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
616
        $createStruct->alwaysAvailable = false;
617
        $createStruct->mainLanguageCode = 'eng-GB';
618
619
        $draft = $contentService->createContent($createStruct);
620
        $content = $contentService->publishVersion($draft->getVersionInfo());
621
622
        $this->refreshSearch($repository);
623
624
        // Found
625
        $criterion = new Criterion\ContentId($content->id);
626
        $query = new Query(array('filter' => $criterion));
627
        $result = $searchService->findContent($query);
628
        $this->assertEquals(1, $result->totalCount);
629
        $this->assertEquals(
630
            $content->id,
631
            $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...
632
        );
633
    }
634
635
    /**
636
     * Test that updated Location is available for search.
637
     */
638
    public function testUpdateLocation()
639
    {
640
        $repository = $this->getRepository();
641
        $locationService = $repository->getLocationService();
642
        $searchService = $repository->getSearchService();
643
644
        $rootLocationId = 2;
645
        $locationToUpdate = $locationService->loadLocation($rootLocationId);
646
647
        $criterion = new Criterion\LogicalAnd([
648
            new Criterion\LocationId($rootLocationId),
649
            new Criterion\Location\Priority(Criterion\Operator::GT, 0),
650
        ]);
651
652
        $query = new LocationQuery(array('filter' => $criterion));
653
        $result = $searchService->findLocations($query);
654
655
        $this->assertEquals(0, $result->totalCount);
656
657
        $locationUpdateStruct = $locationService->newLocationUpdateStruct();
658
        $locationUpdateStruct->priority = 4;
659
        $locationService->updateLocation($locationToUpdate, $locationUpdateStruct);
660
661
        $this->refreshSearch($repository);
662
663
        $result = $searchService->findLocations($query);
664
665
        $this->assertEquals(1, $result->totalCount);
666
        $this->assertEquals(
667
            $locationToUpdate->id,
668
            $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...
669
        );
670
    }
671
672
    /**
673
     * Testing that content will be deleted with all of its subitems but subitems with additional location will stay as
674
     * they are.
675
     */
676
    public function testDeleteLocation()
677
    {
678
        $repository = $this->getRepository();
679
        $locationService = $repository->getLocationService();
680
681
        $treeContainerContent = $this->createContentWithName('Tree Container', [2]);
682
        $supposeBeDeletedSubItem = $this->createContentWithName(
683
            'Suppose to be deleted sub-item',
684
            [$treeContainerContent->contentInfo->mainLocationId]
685
        );
686
        $supposeSurviveSubItem = $this->createContentWithName(
687
            'Suppose to Survive Item',
688
            [2, $treeContainerContent->contentInfo->mainLocationId]
689
        );
690
691
        $treeContainerLocation = $locationService->loadLocation($treeContainerContent->contentInfo->mainLocationId);
692
693
        $this->refreshSearch($repository);
694
695
        $this->assertContentIdSearch($treeContainerContent->id, 1);
696
        $this->assertContentIdSearch($supposeSurviveSubItem->id, 1);
697
        $this->assertContentIdSearch($supposeBeDeletedSubItem->id, 1);
698
699
        $locationService->deleteLocation($treeContainerLocation);
700
701
        $this->refreshSearch($repository);
702
703
        $this->assertContentIdSearch($supposeSurviveSubItem->id, 1);
704
        $this->assertContentIdSearch($treeContainerContent->id, 0);
705
        $this->assertContentIdSearch($supposeBeDeletedSubItem->id, 0);
706
    }
707
708
    /**
709
     * Test content is available for search after being published.
710
     */
711
    public function testPublishVersion()
712
    {
713
        $repository = $this->getRepository();
714
        $searchService = $repository->getSearchService();
715
716
        $publishedContent = $this->createContentWithName('publishedContent', [2]);
717
        $this->refreshSearch($repository);
718
719
        $criterion = new Criterion\FullText('publishedContent');
720
        $query = new Query(['filter' => $criterion]);
721
        $result = $searchService->findContent($query);
722
723
        $this->assertCount(1, $result->searchHits);
724
        $this->assertEquals($publishedContent->contentInfo->id, $result->searchHits[0]->valueObject->contentInfo->id);
0 ignored issues
show
Documentation introduced by
The property contentInfo 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...
725
726
        // Searching for children of locationId=2 should also hit this content
727
        $criterion = new Criterion\ParentLocationId(2);
728
        $query = new LocationQuery(array('filter' => $criterion));
729
        $result = $searchService->findLocations($query);
730
731
        foreach ($result->searchHits as $searchHit) {
732
            if ($searchHit->valueObject->contentInfo->id === $publishedContent->contentInfo->id) {
0 ignored issues
show
Documentation introduced by
The property contentInfo 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...
733
                return;
734
            }
735
        }
736
        $this->fail('Parent location sub-items do not contain published content');
737
    }
738
739
    /**
740
     * Test recovered content is available for search.
741
     */
742
    public function testRecoverLocation()
743
    {
744
        $repository = $this->getRepository();
745
        $locationService = $repository->getLocationService();
746
        $trashService = $repository->getTrashService();
747
        $searchService = $repository->getSearchService();
748
749
        $publishedContent = $this->createContentWithName('recovery-test', [2]);
750
        $location = $locationService->loadLocation($publishedContent->contentInfo->mainLocationId);
751
752
        $trashService->trash($location);
753
        $this->refreshSearch($repository);
754
755
        $criterion = new Criterion\LocationId($location->id);
756
        $query = new LocationQuery(['filter' => $criterion]);
757
        $locations = $searchService->findLocations($query);
758
        $this->assertEquals(0, $locations->totalCount);
759
760
        $trashItem = $trashService->loadTrashItem($location->id);
761
        $trashService->recover($trashItem);
762
        $this->refreshSearch($repository);
763
764
        $locations = $searchService->findLocations($query);
765
        $this->assertEquals(0, $locations->totalCount);
766
        $this->assertContentIdSearch($publishedContent->contentInfo->id, 1);
767
    }
768
769
    /**
770
     * Test copied content is available for search.
771
     */
772
    public function testCopyContent()
773
    {
774
        $repository = $this->getRepository();
775
        $searchService = $repository->getSearchService();
776
        $contentService = $repository->getContentService();
777
        $locationService = $repository->getLocationService();
778
779
        $publishedContent = $this->createContentWithName('copyTest', [2]);
780
        $this->refreshSearch($repository);
781
        $criterion = new Criterion\FullText('copyTest');
782
        $query = new Query(['filter' => $criterion]);
783
        $result = $searchService->findContent($query);
784
        $this->assertCount(1, $result->searchHits);
785
786
        $copiedContent = $contentService->copyContent($publishedContent->contentInfo, $locationService->newLocationCreateStruct(2));
787
        $this->refreshSearch($repository);
788
        $result = $searchService->findContent($query);
789
        $this->assertCount(2, $result->searchHits);
790
791
        $this->assertContentIdSearch($publishedContent->contentInfo->id, 1);
792
        $this->assertContentIdSearch($copiedContent->contentInfo->id, 1);
793
    }
794
795
    /**
796
     * Test that setting object content state to locked and then unlocked does not affect search index.
797
     */
798
    public function testSetContentState()
799
    {
800
        $repository = $this->getRepository();
801
        $objectStateService = $repository->getObjectStateService();
802
803
        // get Object States
804
        $stateNotLocked = $objectStateService->loadObjectState(1);
805
        $stateLocked = $objectStateService->loadObjectState(2);
806
807
        $publishedContent = $this->createContentWithName('setContentStateTest', [2]);
808
        $objectStateService->setContentState($publishedContent->contentInfo, $stateLocked->getObjectStateGroup(), $stateLocked);
809
        $this->refreshSearch($repository);
810
811
        // Setting Content State to "locked" should not affect search index
812
        $this->assertContentIdSearch($publishedContent->contentInfo->id, 1);
813
814
        $objectStateService->setContentState($publishedContent->contentInfo, $stateNotLocked->getObjectStateGroup(), $stateNotLocked);
815
        $this->refreshSearch($repository);
816
817
        // Setting Content State back to "not locked" should not affect search index
818
        $this->assertContentIdSearch($publishedContent->contentInfo->id, 1);
819
    }
820
821
    /**
822
     * Check if FullText indexing works for special cases of text.
823
     *
824
     * @param string $text Content Item field value text (to be indexed)
825
     * @param string $searchForText text based on which Content Item should be found
826
     * @param array $ignoreForSetupFactories list of SetupFactories to be ignored
827
     * @dataProvider getSpecialFullTextCases
828
     */
829
    public function testIndexingSpecialFullTextCases($text, $searchForText, array $ignoreForSetupFactories = [])
830
    {
831
        // check if provided data should be ignored for the current Search Engine (via SetupFactory)
832
        if (!empty($ignoreForSetupFactories) && in_array(get_class($this->getSetupFactory()), $ignoreForSetupFactories)) {
833
            $this->markTestIncomplete(sprintf(
834
                'Handling FullText Searching for the phrase {%s} is incomplete for %s',
835
                $searchForText,
836
                get_class($this->getSetupFactory())
837
            ));
838
        }
839
840
        $repository = $this->getRepository();
841
        $searchService = $repository->getSearchService();
842
843
        $content = $this->createContentWithName($text, [2]);
844
        $this->refreshSearch($repository);
845
846
        $criterion = new Criterion\FullText($searchForText);
847
        $query = new Query(['filter' => $criterion]);
848
        $result = $searchService->findContent($query);
849
850
        // for some cases there might be more than one hit, so check if proper one was found
851
        foreach ($result->searchHits as $searchHit) {
852
            if ($content->contentInfo->id === $searchHit->valueObject->versionInfo->contentInfo->id) {
0 ignored issues
show
Documentation introduced by
The property versionInfo 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...
853
                return;
854
            }
855
        }
856
        $this->fail('Failed to find required Content in search results');
857
    }
858
859
    /**
860
     * Data Provider for {@see testIndexingSpecialFullTextCases()} method.
861
     *
862
     * @return array
863
     */
864
    public function getSpecialFullTextCases()
865
    {
866
        return [
867
            ['UPPERCASE TEXT', 'uppercase text'],
868
            ['lowercase text', 'LOWERCASE TEXT'],
869
            ['text-with-hyphens', 'text-with-hyphens'],
870
            ['text containing spaces', 'text containing spaces'],
871
            ['"quoted text"', 'quoted text'],
872
            ['ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝ', 'àáâãäåçèéêëìíîïðñòóôõöøùúûüý'],
873
            ['with boundary.', 'with boundary'],
874
            ['Folder1.', 'Folder1.'],
875
            ['whitespaces', "     whitespaces  \n \t "],
876
            // @todo: Remove as soon as elastic is updated to later version not affected
877
            ["it's", "it's", [LegacyElasticsearch::class]],
878
            ['with_underscore', 'with_underscore'],
879
        ];
880
    }
881
882
    /**
883
     * Test FullText search on user first name and last name.
884
     *
885
     * @see https://jira.ez.no/browse/EZP-27250
886
     */
887
    public function testUserFullTextSearch()
888
    {
889
        $repository = $this->getRepository();
890
        $searchService = $repository->getSearchService();
891
        $user = $this->createUser('TestUser', 'Jon', 'Snow');
892
893
        $criterion = new Criterion\LogicalAnd(
894
            [
895
                new Criterion\FullText('Jon Snow'),
896
                new Criterion\ContentTypeIdentifier('user'),
897
            ]
898
        );
899
        $query = new Query(['filter' => $criterion]);
900
        $this->refreshSearch($repository);
901
        $results = $searchService->findContent($query);
902
        self::assertEquals(1, $results->totalCount);
903
        self::assertEquals($user->id, $results->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...
904
    }
905
906
    /**
907
     * Test updating Content field value with empty value removes it from search index.
908
     */
909
    public function testRemovedContentFieldValueIsNotFound()
910
    {
911
        $repository = $this->getRepository();
912
        $contentService = $repository->getContentService();
913
        $searchService = $repository->getSearchService();
914
        $publishedContent = $this->createContentWithNameAndDescription('testRemovedContentFieldValueIsNotFound', 'descriptionToBeRemoved', [2]);
915
        $this->refreshSearch($repository);
916
917
        $contentDraft = $contentService->createContentDraft($publishedContent->contentInfo);
918
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
919
        $contentUpdateStruct->setField('description', null);
920
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
921
        $contentService->publishVersion($contentDraft->versionInfo);
922
        $this->refreshSearch($repository);
923
924
        // Removed field value should not be found
925
        $criterion = new Criterion\FullText('descriptionToBeRemoved');
926
        $query = new Query(['filter' => $criterion]);
927
        $results = $searchService->findContent($query);
928
        $this->assertEquals(0, $results->totalCount);
929
930
        // Should be found
931
        $criterion = new Criterion\FullText('testRemovedContentFieldValueIsNotFound');
932
        $query = new Query(['filter' => $criterion]);
933
        $results = $searchService->findContent($query);
934
        $this->assertEquals(1, $results->totalCount);
935
    }
936
937
    /**
938
     * Check if children locations are/are not ivisible.
939
     *
940
     * @param \eZ\Publish\API\Repository\SearchService $searchService
941
     * @param int $parentLocationId parent location Id
942
     * @param bool $expected expected value of {invisible} property in subtree
943
     */
944
    private function assertSubtreeInvisibleProperty(SearchService $searchService, $parentLocationId, $expected)
945
    {
946
        $criterion = new Criterion\ParentLocationId($parentLocationId);
947
        $query = new LocationQuery(array('filter' => $criterion));
948
        $result = $searchService->findLocations($query);
949
        foreach ($result->searchHits as $searchHit) {
950
            $this->assertEquals($expected, $searchHit->valueObject->invisible, sprintf('Location %s is not hidden', $searchHit->valueObject->id));
0 ignored issues
show
Documentation introduced by
The property invisible 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...
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...
951
            // Perform recursive check for children locations
952
            $this->assertSubtreeInvisibleProperty($searchService, $searchHit->valueObject->id, $expected);
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...
953
        }
954
    }
955
956
    /**
957
     * Test that swapping locations affects properly Search Engine Index.
958
     */
959
    public function testSwapLocation()
960
    {
961
        $repository = $this->getRepository();
962
        $locationService = $repository->getLocationService();
963
        $searchService = $repository->getSearchService();
964
965
        $content01 = $this->createContentWithName('content01', [2]);
966
        $location01 = $locationService->loadLocation($content01->contentInfo->mainLocationId);
967
968
        $content02 = $this->createContentWithName('content02', [2]);
969
        $location02 = $locationService->loadLocation($content02->contentInfo->mainLocationId);
970
971
        $locationService->swapLocation($location01, $location02);
972
        $this->refreshSearch($repository);
973
974
        // content02 should be at location01
975
        $criterion = new Criterion\LocationId($location01->id);
976
        $query = new Query(['filter' => $criterion]);
977
        $results = $searchService->findContent($query);
978
        $this->assertEquals(1, $results->totalCount);
979
        $this->assertEquals($content02->id, $results->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...
980
981
        // content01 should be at location02
982
        $criterion = new Criterion\LocationId($location02->id);
983
        $query = new Query(['filter' => $criterion]);
984
        $results = $searchService->findContent($query);
985
        $this->assertEquals(1, $results->totalCount);
986
        $this->assertEquals($content01->id, $results->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...
987
    }
988
989
    /**
990
     * Test that updating Content metadata affects properly Search Engine Index.
991
     */
992
    public function testUpdateContentMetadata()
993
    {
994
        $repository = $this->getRepository();
995
        $contentService = $repository->getContentService();
996
        $locationService = $repository->getLocationService();
997
        $searchService = $repository->getSearchService();
998
999
        $publishedContent = $this->createContentWithName('updateMetadataTest', [2]);
1000
        $originalMainLocationId = $publishedContent->contentInfo->mainLocationId;
1001
        $newLocationCreateStruct = $locationService->newLocationCreateStruct(60);
1002
        $newLocation = $locationService->createLocation($publishedContent->contentInfo, $newLocationCreateStruct);
1003
1004
        $newContentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
1005
        $newContentMetadataUpdateStruct->remoteId = md5('Test');
1006
        $newContentMetadataUpdateStruct->publishedDate = new \DateTime();
1007
        $newContentMetadataUpdateStruct->publishedDate->add(new \DateInterval('P1D'));
1008
        $newContentMetadataUpdateStruct->mainLocationId = $newLocation->id;
1009
1010
        $contentService->updateContentMetadata($publishedContent->contentInfo, $newContentMetadataUpdateStruct);
1011
        $this->refreshSearch($repository);
1012
1013
        // find Content by Id, calling findContentInfo which is using the Search Index
1014
        $criterion = new Criterion\ContentId($publishedContent->id);
1015
        $query = new Query(['filter' => $criterion]);
1016
        $results = $searchService->findContentInfo($query);
1017
        $this->assertEquals(1, $results->totalCount);
1018
        $this->assertEquals($publishedContent->contentInfo->id, $results->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...
1019
1020
        // find Content using updated RemoteId
1021
        $criterion = new Criterion\RemoteId($newContentMetadataUpdateStruct->remoteId);
1022
        $query = new Query(['filter' => $criterion]);
1023
        $results = $searchService->findContent($query);
1024
        $this->assertEquals(1, $results->totalCount);
1025
        $foundContentInfo = $results->searchHits[0]->valueObject->contentInfo;
0 ignored issues
show
Documentation introduced by
The property contentInfo does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __set, maybe consider adding a @property annotation.

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...
1026
        /** @var \eZ\Publish\Core\Repository\Values\Content\Content $foundContentInfo */
1027
        $this->assertEquals($publishedContent->id, $foundContentInfo->id);
1028
        $this->assertEquals($newContentMetadataUpdateStruct->publishedDate->getTimestamp(), $foundContentInfo->publishedDate->getTimestamp());
0 ignored issues
show
Documentation introduced by
The property publishedDate does not exist on object<eZ\Publish\Core\R...Values\Content\Content>. 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...
1029
        $this->assertEquals($newLocation->id, $foundContentInfo->mainLocationId);
0 ignored issues
show
Documentation introduced by
The property mainLocationId does not exist on object<eZ\Publish\Core\R...Values\Content\Content>. 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...
1030
        $this->assertEquals($newContentMetadataUpdateStruct->remoteId, $foundContentInfo->remoteId);
0 ignored issues
show
Documentation introduced by
The property remoteId does not exist on object<eZ\Publish\Core\R...Values\Content\Content>. 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...
1031
1032
        // find Content using old main location
1033
        $criterion = new Criterion\LocationId($originalMainLocationId);
1034
        $query = new LocationQuery(['filter' => $criterion]);
1035
        $results = $searchService->findLocations($query);
1036
        $this->assertEquals(1, $results->totalCount);
1037
        $this->assertEquals($newContentMetadataUpdateStruct->remoteId, $results->searchHits[0]->valueObject->contentInfo->remoteId);
0 ignored issues
show
Documentation introduced by
The property contentInfo 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...
1038
    }
1039
1040
    /**
1041
     * Test that updating Content Draft metadata does not affect Search Engine Index.
1042
     */
1043
    public function testUpdateContentDraftMetadataIsNotIndexed()
1044
    {
1045
        $repository = $this->getRepository();
1046
        $contentService = $repository->getContentService();
1047
        $locationService = $repository->getLocationService();
1048
1049
        $testableContentType = $this->createTestContentType();
1050
        $rootContentStruct = $contentService->newContentCreateStruct($testableContentType, 'eng-GB');
1051
        $rootContentStruct->setField('name', 'TestUpdatingContentDraftMetadata');
1052
1053
        $contentDraft = $contentService->createContent($rootContentStruct, [$locationService->newLocationCreateStruct(2)]);
1054
1055
        $newContentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
1056
        $newContentMetadataUpdateStruct->ownerId = 10;
1057
        $newContentMetadataUpdateStruct->remoteId = md5('Test');
1058
1059
        $contentService->updateContentMetadata($contentDraft->contentInfo, $newContentMetadataUpdateStruct);
1060
1061
        $this->refreshSearch($repository);
1062
        $this->assertContentIdSearch($contentDraft->contentInfo->id, 0);
1063
    }
1064
1065
    /**
1066
     * Test that assigning section to content object properly affects Search Engine Index.
1067
     */
1068
    public function testAssignSection()
1069
    {
1070
        $repository = $this->getRepository();
1071
        $sectionService = $repository->getSectionService();
1072
        $searchService = $repository->getSearchService();
1073
1074
        $section = $sectionService->loadSection(2);
1075
        $content = $this->createContentWithName('testAssignSection', [2]);
1076
1077
        $sectionService->assignSection($content->contentInfo, $section);
1078
        $this->refreshSearch($repository);
1079
1080
        $criterion = new Criterion\ContentId($content->id);
1081
        $query = new Query(['filter' => $criterion]);
1082
        $results = $searchService->findContentInfo($query);
1083
        $this->assertEquals($section->id, $results->searchHits[0]->valueObject->sectionId);
0 ignored issues
show
Documentation introduced by
The property sectionId 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...
1084
    }
1085
1086
    /**
1087
     * Test search engine is updated after removal of the translation from all the Versions.
1088
     */
1089
    public function testDeleteTranslation()
1090
    {
1091
        $repository = $this->getRepository();
1092
        $searchService = $repository->getSearchService();
1093
        $contentService = $repository->getContentService();
1094
1095
        $content = $this->createMultiLanguageContent(
1096
            [
1097
                'eng-US' => 'AmE Name',
1098
                'eng-GB' => 'BrE Name',
1099
            ],
1100
            2,
1101
            false
1102
        );
1103
1104
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
1105
1106
        $this->refreshSearch($repository);
1107
1108
        // Test ContentId search returns Content without removed Translation
1109
        $query = new Query([
1110
            'query' => new Criterion\ContentId($content->contentInfo->id),
1111
            'filter' => new Criterion\LanguageCode('eng-GB', false),
1112
        ]);
1113
        $result = $searchService->findContent($query);
1114
        self::assertEquals(0, $result->totalCount);
1115
1116
        // Test FullText search for removed unique name part returns no results
1117
        $query = new Query([
1118
            'query' => new Criterion\FullText('BrE'),
1119
        ]);
1120
        $result = $searchService->findContent($query);
1121
        self::assertEquals(0, $result->totalCount);
1122
1123
        if (!$this->getSetupFactory() instanceof LegacyElasticsearchSetupFactory) {
1124
            // Test Location Search returns Content without removed Translation
1125
            $query = new LocationQuery(
1126
                [
1127
                    'query' => new Criterion\FullText('BrE'),
1128
                ]
1129
            );
1130
            $result = $searchService->findLocations($query);
1131
            self::assertEquals(0, $result->totalCount);
1132
        }
1133
    }
1134
1135
    /**
1136
     * Will create if not exists a simple content type for test purposes with just one required field name.
1137
     *
1138
     * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType
1139
     */
1140
    protected function createTestContentType()
1141
    {
1142
        $repository = $this->getRepository();
1143
        $contentTypeService = $repository->getContentTypeService();
1144
        $contentTypeIdentifier = 'test-type';
1145
        try {
1146
            return $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
1147
        } catch (NotFoundException $e) {
1148
            // continue creation process
1149
        }
1150
1151
        $nameField = $contentTypeService->newFieldDefinitionCreateStruct('name', 'ezstring');
1152
        $nameField->fieldGroup = 'main';
1153
        $nameField->position = 1;
1154
        $nameField->isTranslatable = true;
1155
        $nameField->isSearchable = true;
1156
        $nameField->isRequired = true;
1157
1158
        $contentTypeStruct = $contentTypeService->newContentTypeCreateStruct($contentTypeIdentifier);
1159
        $contentTypeStruct->mainLanguageCode = 'eng-GB';
1160
        $contentTypeStruct->creatorId = 14;
1161
        $contentTypeStruct->creationDate = new DateTime();
1162
        $contentTypeStruct->names = ['eng-GB' => 'Test Content Type'];
1163
        $contentTypeStruct->addFieldDefinition($nameField);
1164
1165
        $contentTypeGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
1166
1167
        $contentTypeDraft = $contentTypeService->createContentType($contentTypeStruct, [$contentTypeGroup]);
1168
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1169
1170
        return $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
1171
    }
1172
1173
    /**
1174
     * Will create and publish an content with a filed with a given content name in location provided into
1175
     * $parentLocationIdList.
1176
     *
1177
     * @param string $contentName
1178
     * @param array $parentLocationIdList
1179
     *
1180
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1181
     */
1182
    protected function createContentWithName($contentName, array $parentLocationIdList = array())
1183
    {
1184
        $contentService = $this->getRepository()->getContentService();
1185
        $locationService = $this->getRepository()->getLocationService();
1186
1187
        $testableContentType = $this->createTestContentType();
1188
1189
        $rootContentStruct = $contentService->newContentCreateStruct($testableContentType, 'eng-GB');
1190
        $rootContentStruct->setField('name', $contentName);
1191
1192
        $parentLocationList = [];
1193
        foreach ($parentLocationIdList as $locationID) {
1194
            $parentLocationList[] = $locationService->newLocationCreateStruct($locationID);
1195
        }
1196
1197
        $contentDraft = $contentService->createContent($rootContentStruct, $parentLocationList);
1198
        $publishedContent = $contentService->publishVersion($contentDraft->getVersionInfo());
1199
1200
        return $publishedContent;
1201
    }
1202
1203
    /**
1204
     * Create and publish a content with filled name and description fields in location provided into
1205
     * $parentLocationIdList.
1206
     *
1207
     * @param string $contentName
1208
     * @param $contentDescription
1209
     * @param array $parentLocationIdList
1210
     *
1211
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1212
     */
1213
    protected function createContentWithNameAndDescription($contentName, $contentDescription, array $parentLocationIdList = [])
1214
    {
1215
        $repository = $this->getRepository();
1216
        $contentService = $repository->getContentService();
1217
        $contentTypeService = $repository->getContentTypeService();
1218
        $publishedContent = $this->createContentWithName($contentName, $parentLocationIdList);
1219
        $descriptionField = $contentTypeService->newFieldDefinitionCreateStruct('description', 'ezstring');
1220
        $descriptionField->fieldGroup = 'main';
1221
        $descriptionField->position = 2;
1222
        $descriptionField->isTranslatable = true;
1223
        $descriptionField->isSearchable = true;
1224
        $descriptionField->isRequired = false;
1225
        $contentType = $contentTypeService->loadContentType($publishedContent->contentInfo->contentTypeId);
1226
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
1227
        $contentTypeService->addFieldDefinition($contentTypeDraft, $descriptionField);
1228
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1229
        $contentDraft = $contentService->createContentDraft($publishedContent->contentInfo);
1230
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1231
        $contentUpdateStruct->setField('description', $contentDescription);
1232
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
1233
1234
        return $contentService->publishVersion($contentDraft->versionInfo);
1235
    }
1236
1237
    /**
1238
     * Create and publish a content with specified, in multiple languages, fields.
1239
     *
1240
     * @param string[] $names multi-language name field in the form of: <code>['lang-code' => 'name']</code>
1241
     * @param int $parentLocationId
1242
     * @param bool $alwaysAvailable
1243
     *
1244
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1245
     */
1246
    protected function createMultiLanguageContent(array $names, $parentLocationId, $alwaysAvailable)
1247
    {
1248
        $repository = $this->getRepository();
1249
        $contentService = $repository->getContentService();
1250
        $locationService = $repository->getLocationService();
1251
1252
        $testableContentType = $this->createTestContentType();
1253
1254
        $contentCreateStruct = $contentService->newContentCreateStruct(
1255
            $testableContentType,
1256
            array_keys($names)[0]
1257
        );
1258
1259
        foreach ($names as $languageCode => $value) {
1260
            $contentCreateStruct->setField('name', $value, $languageCode);
1261
        }
1262
1263
        $contentCreateStruct->alwaysAvailable = $alwaysAvailable;
1264
1265
        $contentDraft = $contentService->createContent(
1266
            $contentCreateStruct,
1267
            [
1268
                $locationService->newLocationCreateStruct($parentLocationId),
1269
            ]
1270
        );
1271
        $publishedContent = $contentService->publishVersion($contentDraft->getVersionInfo());
1272
1273
        return $publishedContent;
1274
    }
1275
1276
    /**
1277
     * Asserts an content id if it exists still in the solr core.
1278
     *
1279
     * @param int $contentId
1280
     * @param int $expectedCount
1281
     */
1282
    protected function assertContentIdSearch($contentId, $expectedCount)
1283
    {
1284
        $searchService = $this->getRepository()->getSearchService();
1285
1286
        $criterion = new Criterion\ContentId($contentId);
1287
        $query = new Query(array('filter' => $criterion));
1288
        $result = $searchService->findContent($query);
1289
1290
        $this->assertEquals($expectedCount, $result->totalCount);
1291
        if ($expectedCount == 0) {
1292
            return;
1293
        }
1294
1295
        $this->assertEquals(
1296
            $contentId,
1297
            $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...
1298
        );
1299
    }
1300
1301
    /**
1302
     * Create & get new Location for tests.
1303
     *
1304
     * @return \eZ\Publish\API\Repository\Values\Content\Location
1305
     */
1306
    protected function createNewTestLocation()
1307
    {
1308
        $repository = $this->getRepository();
1309
        $locationService = $repository->getLocationService();
1310
        $contentService = $repository->getContentService();
1311
1312
        $rootLocationId = 2;
1313
        $membersContentId = 11;
1314
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
1315
1316
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
1317
1318
        return $locationService->createLocation($membersContentInfo, $locationCreateStruct);
1319
    }
1320
}
1321