Completed
Push — EZP-30461 ( f31212...2bcc5c )
by
unknown
27:37
created

SearchEngineIndexingTest::testPublishVersion()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 0
dl 0
loc 27
rs 9.488
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\Values\Content\ContentInfo;
12
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
13
use eZ\Publish\API\Repository\SearchService;
14
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
15
use eZ\Publish\API\Repository\Values\Content\Query;
16
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
17
use DateTime;
18
19
/**
20
 * Test case for indexing operations with a search engine.
21
 *
22
 * @group integration
23
 * @group search
24
 * @group indexing
25
 */
26
class SearchEngineIndexingTest extends BaseTest
27
{
28
    /**
29
     * Test that indexing full text data depends on the isSearchable flag on the field definition.
30
     */
31
    public function testFindContentInfoFullTextIsSearchable()
32
    {
33
        $searchTerm = 'pamplemousse';
34
        $content = $this->createFullTextIsSearchableContent($searchTerm, true);
35
36
        $repository = $this->getRepository();
37
        $searchService = $repository->getSearchService();
38
39
        $query = new Query(
40
            [
41
                'query' => new Criterion\FullText($searchTerm),
42
            ]
43
        );
44
45
        $searchResult = $searchService->findContentInfo($query);
46
47
        $this->assertEquals(1, $searchResult->totalCount);
48
        $contentInfo = $searchResult->searchHits[0]->valueObject;
49
        $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...
50
51
        return $contentInfo;
52
    }
53
54
    /**
55
     * Test that indexing full text data depends on the isSearchable flag on the field definition.
56
     *
57
     * @depends testFindContentInfoFullTextIsSearchable
58
     *
59
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
60
     */
61 View Code Duplication
    public function testFindLocationsFullTextIsSearchable(ContentInfo $contentInfo)
62
    {
63
        $searchTerm = 'pamplemousse';
64
65
        $repository = $this->getRepository(false);
66
        $searchService = $repository->getSearchService();
67
68
        $query = new LocationQuery(
69
            [
70
                'query' => new Criterion\FullText($searchTerm),
71
            ]
72
        );
73
74
        $searchResult = $searchService->findLocations($query);
75
76
        $this->assertEquals(1, $searchResult->totalCount);
77
        $this->assertEquals(
78
            $contentInfo->mainLocationId,
79
            $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...
80
        );
81
    }
82
83
    /**
84
     * Test that indexing full text data depends on the isSearchable flag on the field definition.
85
     *
86
     * @depends testFindContentInfoFullTextIsSearchable
87
     */
88 View Code Duplication
    public function testFindContentInfoFullTextIsNotSearchable()
89
    {
90
        $searchTerm = 'pamplemousse';
91
        $this->createFullTextIsSearchableContent($searchTerm, false);
92
93
        $repository = $this->getRepository();
94
        $searchService = $repository->getSearchService();
95
96
        $query = new Query(
97
            [
98
                'query' => new Criterion\FullText($searchTerm),
99
            ]
100
        );
101
102
        $searchResult = $searchService->findContentInfo($query);
103
104
        $this->assertEquals(0, $searchResult->totalCount);
105
    }
106
107
    /**
108
     * Test that indexing full text data depends on the isSearchable flag on the field definition.
109
     *
110
     * @depends testFindLocationsFullTextIsSearchable
111
     */
112 View Code Duplication
    public function testFindLocationsFullTextIsNotSearchable()
113
    {
114
        $searchTerm = 'pamplemousse';
115
116
        $repository = $this->getRepository(false);
117
        $searchService = $repository->getSearchService();
118
119
        $query = new LocationQuery(
120
            [
121
                'query' => new Criterion\FullText($searchTerm),
122
            ]
123
        );
124
125
        $searchResult = $searchService->findLocations($query);
126
127
        $this->assertEquals(0, $searchResult->totalCount);
128
    }
129
130
    /**
131
     * Creates Content for testing full text search depending on the isSearchable flag.
132
     *
133
     * @see testFindContentInfoFullTextIsearchable
134
     * @see testFindLocationsFullTextIsSearchable
135
     * @see testFindContentInfoFullTextIsNotSearchable
136
     * @see testFindLocationsFullTextIsNotSearchable
137
     *
138
     * @param string $searchText
139
     * @param bool $isSearchable
140
     *
141
     * @return \eZ\Publish\API\Repository\Values\Content\Content
142
     */
143
    protected function createFullTextIsSearchableContent($searchText, $isSearchable)
144
    {
145
        $repository = $this->getRepository();
146
        $contentService = $repository->getContentService();
147
        $contentTypeService = $repository->getContentTypeService();
148
        $locationService = $repository->getLocationService();
149
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
150
151
        if (!$isSearchable) {
152
            $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
153
            $fieldDefinitionUpdateStruct = $contentTypeService->newFieldDefinitionUpdateStruct();
154
            $fieldDefinitionUpdateStruct->isSearchable = false;
155
156
            $fieldDefinition = $contentType->getFieldDefinition('name');
157
158
            $contentTypeService->updateFieldDefinition(
159
                $contentTypeDraft,
160
                $fieldDefinition,
161
                $fieldDefinitionUpdateStruct
162
            );
163
164
            $contentTypeService->publishContentTypeDraft($contentTypeDraft);
165
            $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
166
        }
167
168
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
169
170
        $contentCreateStruct->setField('name', $searchText);
171
        $contentCreateStruct->setField('short_name', 'hello world');
172
        $content = $contentService->publishVersion(
173
            $contentService->createContent(
174
                $contentCreateStruct,
175
                [$locationService->newLocationCreateStruct(2)]
176
            )->versionInfo
177
        );
178
179
        $this->refreshSearch($repository);
180
181
        return $content;
182
    }
183
184
    /**
185
     * EZP-26186: Make sure index is NOT deleted on removal of version draft (affected Solr).
186
     */
187
    public function testDeleteVersion()
188
    {
189
        $repository = $this->getRepository();
190
        $contentService = $repository->getContentService();
191
        $searchService = $repository->getSearchService();
192
193
        $membersContentId = $this->generateId('content', 11);
194
        $contentInfo = $contentService->loadContentInfo($membersContentId);
195
196
        $draft = $contentService->createContentDraft($contentInfo);
197
        $contentService->deleteVersion($draft->getVersionInfo());
198
199
        $this->refreshSearch($repository);
200
201
        // Found
202
        $criterion = new Criterion\LocationId($contentInfo->mainLocationId);
203
        $query = new Query(array('filter' => $criterion));
204
        $result = $searchService->findContentInfo($query);
205
        $this->assertEquals(1, $result->totalCount);
206
        $this->assertEquals(
207
            $contentInfo->id,
208
            $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...
209
        );
210
    }
211
212
    /**
213
     * EZP-26186: Make sure affected child locations are deleted on content deletion (affected Solr).
214
     */
215 View Code Duplication
    public function testDeleteContent()
216
    {
217
        $repository = $this->getRepository();
218
        $contentService = $repository->getContentService();
219
        $searchService = $repository->getSearchService();
220
221
        $anonymousUsersContentId = $this->generateId('content', 42);
222
        $contentInfo = $contentService->loadContentInfo($anonymousUsersContentId);
223
224
        $contentService->deleteContent($contentInfo);
225
226
        $this->refreshSearch($repository);
227
228
        // Should not be found
229
        $criterion = new Criterion\ParentLocationId($contentInfo->mainLocationId);
230
        $query = new LocationQuery(array('filter' => $criterion));
231
        $result = $searchService->findLocations($query);
232
        $this->assertEquals(0, $result->totalCount);
233
    }
234
235
    /**
236
     * EZP-26186: Make sure index is deleted on removal of Users  (affected Solr).
237
     */
238 View Code Duplication
    public function testDeleteUser()
239
    {
240
        $repository = $this->getRepository();
241
        $userService = $repository->getUserService();
242
        $searchService = $repository->getSearchService();
243
244
        $anonymousContentId = $this->generateId('user', 10);
245
        $user = $userService->loadUser($anonymousContentId);
246
247
        $userService->deleteUser($user);
248
249
        $this->refreshSearch($repository);
250
251
        // Should not be found
252
        $criterion = new Criterion\ContentId($user->id);
253
        $query = new Query(array('filter' => $criterion));
254
        $result = $searchService->findContentInfo($query);
255
        $this->assertEquals(0, $result->totalCount);
256
    }
257
258
    /**
259
     * EZP-26186: Make sure index is deleted on removal of UserGroups  (affected Solr).
260
     */
261 View Code Duplication
    public function testDeleteUserGroup()
262
    {
263
        $repository = $this->getRepository();
264
        $userService = $repository->getUserService();
265
        $searchService = $repository->getSearchService();
266
267
        $membersContentId = $this->generateId('user_group', 11);
268
        $userGroup = $userService->loadUserGroup($membersContentId);
269
270
        $userService->deleteUserGroup($userGroup);
271
272
        $this->refreshSearch($repository);
273
274
        // Should not be found
275
        $criterion = new Criterion\ContentId($userGroup->id);
276
        $query = new Query(array('filter' => $criterion));
277
        $result = $searchService->findContentInfo($query);
278
        $this->assertEquals(0, $result->totalCount);
279
    }
280
281
    /**
282
     * Test that a newly created user is available for search.
283
     */
284
    public function testCreateUser()
285
    {
286
        $repository = $this->getRepository();
287
        $userService = $repository->getUserService();
288
        $searchService = $repository->getSearchService();
289
290
        // ID of the "Editors" user group
291
        $editorsGroupId = 13;
292
        $userCreate = $userService->newUserCreateStruct(
293
            'user',
294
            '[email protected]',
295
            'secret',
296
            'eng-US'
297
        );
298
        $userCreate->enabled = true;
299
        $userCreate->setField('first_name', 'Example');
300
        $userCreate->setField('last_name', 'User');
301
302
        // Load parent group for the user
303
        $group = $userService->loadUserGroup($editorsGroupId);
304
305
        // Create a new user instance.
306
        $user = $userService->createUser($userCreate, array($group));
307
308
        $this->refreshSearch($repository);
309
310
        // Should be found
311
        $criterion = new Criterion\ContentId($user->id);
312
        $query = new Query(array('filter' => $criterion));
313
        $result = $searchService->findContentInfo($query);
314
        $this->assertEquals(1, $result->totalCount);
315
    }
316
317
    /**
318
     * Test that a newly updated user is available for search.
319
     */
320
    public function testUpdateUser()
321
    {
322
        $repository = $this->getRepository();
323
        $userService = $repository->getUserService();
324
        $contentService = $repository->getContentService();
325
        $searchService = $repository->getSearchService();
326
327
        $user = $this->createUserVersion1();
328
329
        $newName = 'Drizzt Do\'Urden';
330
        $userUpdate = $userService->newUserUpdateStruct();
331
        $userUpdate->contentUpdateStruct = $contentService->newContentUpdateStruct();
332
        $userUpdate->contentUpdateStruct->setField('first_name', $newName);
333
334
        $userService->updateUser($user, $userUpdate);
335
336
        $this->refreshSearch($repository);
337
338
        // Should be found
339
        $query = new Query(
340
            [
341
                'query' => new Criterion\FullText($newName),
342
            ]
343
        );
344
        $result = $searchService->findContentInfo($query);
345
346
        $this->assertEquals(1, $result->totalCount);
347
    }
348
349
    /**
350
     * Test that a newly created user group is available for search.
351
     */
352
    public function testCreateUserGroup()
353
    {
354
        $repository = $this->getRepository();
355
        $userService = $repository->getUserService();
356
        $searchService = $repository->getSearchService();
357
358
        $mainGroupId = $this->generateId('group', 4);
359
360
        $parentUserGroup = $userService->loadUserGroup($mainGroupId);
361
        $userGroupCreateStruct = $userService->newUserGroupCreateStruct('eng-GB');
362
        $userGroupCreateStruct->setField('name', 'Example Group');
363
364
        // Create a new user group
365
        $userGroup = $userService->createUserGroup(
366
            $userGroupCreateStruct,
367
            $parentUserGroup
368
        );
369
370
        $this->refreshSearch($repository);
371
372
        // Should be found
373
        $criterion = new Criterion\ContentId($userGroup->id);
374
        $query = new Query(array('filter' => $criterion));
375
        $result = $searchService->findContentInfo($query);
376
        $this->assertEquals(1, $result->totalCount);
377
    }
378
379
    /**
380
     * Test that a newly created Location is available for search.
381
     */
382
    public function testCreateLocation()
383
    {
384
        $repository = $this->getRepository();
385
        $searchService = $repository->getSearchService();
386
        $membersLocation = $this->createNewTestLocation();
387
388
        $this->refreshSearch($repository);
389
390
        // Found
391
        $criterion = new Criterion\LocationId($membersLocation->id);
392
        $query = new LocationQuery(array('filter' => $criterion));
393
        $result = $searchService->findLocations($query);
394
        $this->assertEquals(1, $result->totalCount);
395
        $this->assertEquals(
396
            $membersLocation->id,
397
            $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...
398
        );
399
    }
400
401
    /**
402
     * Test that hiding a Location makes it unavailable for search.
403
     */
404
    public function testHideSubtree()
405
    {
406
        $repository = $this->getRepository();
407
        $searchService = $repository->getSearchService();
408
409
        // 5 is the ID of an existing location
410
        $locationId = $this->generateId('location', 5);
411
        $locationService = $repository->getLocationService();
412
        $location = $locationService->loadLocation($locationId);
413
        $locationService->hideLocation($location);
414
        $this->refreshSearch($repository);
415
416
        // Check if parent location is hidden
417
        $criterion = new Criterion\LocationId($locationId);
418
        $query = new LocationQuery(array('filter' => $criterion));
419
        $result = $searchService->findLocations($query);
420
        $this->assertEquals(1, $result->totalCount);
421
        $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...
422
423
        // Check if children locations are invisible
424
        $this->assertSubtreeInvisibleProperty($searchService, $locationId, true);
425
    }
426
427
    /**
428
     * Test that hiding and revealing a Location makes it available for search.
429
     */
430
    public function testRevealSubtree()
431
    {
432
        $repository = $this->getRepository();
433
        $searchService = $repository->getSearchService();
434
435
        // 5 is the ID of an existing location
436
        $locationId = $this->generateId('location', 5);
437
        $locationService = $repository->getLocationService();
438
        $location = $locationService->loadLocation($locationId);
439
        $locationService->hideLocation($location);
440
        $this->refreshSearch($repository);
441
        $locationService->unhideLocation($location);
442
        $this->refreshSearch($repository);
443
444
        // Check if parent location is not hidden
445
        $criterion = new Criterion\LocationId($locationId);
446
        $query = new LocationQuery(array('filter' => $criterion));
447
        $result = $searchService->findLocations($query);
448
        $this->assertEquals(1, $result->totalCount);
449
        $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...
450
451
        // Check if children locations are not invisible
452
        $this->assertSubtreeInvisibleProperty($searchService, $locationId, false);
453
    }
454
455
    /**
456
     * Test that a copied subtree is available for search.
457
     */
458
    public function testCopySubtree()
459
    {
460
        $repository = $this->getRepository();
461
        $locationService = $repository->getLocationService();
462
        $contentService = $repository->getContentService();
463
        $searchService = $repository->getSearchService();
464
465
        $rootLocationId = 2;
466
        $membersContentId = 11;
467
        $adminsContentId = 12;
468
        $editorsContentId = 13;
469
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
470
        $adminsContentInfo = $contentService->loadContentInfo($adminsContentId);
471
        $editorsContentInfo = $contentService->loadContentInfo($editorsContentId);
472
473
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
474
        $membersLocation = $locationService->createLocation($membersContentInfo, $locationCreateStruct);
475
        $editorsLocation = $locationService->createLocation($editorsContentInfo, $locationCreateStruct);
476
        $adminsLocation = $locationService->createLocation(
477
            $adminsContentInfo,
478
            $locationService->newLocationCreateStruct($membersLocation->id)
479
        );
480
481
        $copiedLocation = $locationService->copySubtree($adminsLocation, $editorsLocation);
482
        $this->refreshSearch($repository);
483
484
        // Found under Members
485
        $criterion = new Criterion\ParentLocationId($membersLocation->id);
486
        $query = new LocationQuery(array('filter' => $criterion));
487
        $result = $searchService->findLocations($query);
488
        $this->assertEquals(1, $result->totalCount);
489
        $this->assertEquals(
490
            $adminsLocation->id,
491
            $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...
492
        );
493
494
        // Found under Editors
495
        $criterion = new Criterion\ParentLocationId($editorsLocation->id);
496
        $query = new LocationQuery(array('filter' => $criterion));
497
        $result = $searchService->findLocations($query);
498
        $this->assertEquals(1, $result->totalCount);
499
        $this->assertEquals(
500
            $copiedLocation->id,
501
            $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...
502
        );
503
    }
504
505
    /**
506
     * Test that moved subtree is available for search and found only under a specific parent Location.
507
     */
508
    public function testMoveSubtree()
509
    {
510
        $repository = $this->getRepository();
511
        $locationService = $repository->getLocationService();
512
        $contentService = $repository->getContentService();
513
        $searchService = $repository->getSearchService();
514
515
        $rootLocationId = 2;
516
        $membersContentId = 11;
517
        $adminsContentId = 12;
518
        $editorsContentId = 13;
519
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
520
        $adminsContentInfo = $contentService->loadContentInfo($adminsContentId);
521
        $editorsContentInfo = $contentService->loadContentInfo($editorsContentId);
522
523
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
524
        $membersLocation = $locationService->createLocation($membersContentInfo, $locationCreateStruct);
525
        $editorsLocation = $locationService->createLocation($editorsContentInfo, $locationCreateStruct);
526
        $adminsLocation = $locationService->createLocation(
527
            $adminsContentInfo,
528
            $locationService->newLocationCreateStruct($membersLocation->id)
529
        );
530
531
        $this->refreshSearch($repository);
532
533
        // Not found under Editors
534
        $criterion = new Criterion\ParentLocationId($editorsLocation->id);
535
        $query = new LocationQuery(array('filter' => $criterion));
536
        $result = $searchService->findLocations($query);
537
        $this->assertEquals(0, $result->totalCount);
538
539
        // Found under Members
540
        $criterion = new Criterion\ParentLocationId($membersLocation->id);
541
        $query = new LocationQuery(array('filter' => $criterion));
542
        $result = $searchService->findLocations($query);
543
        $this->assertEquals(1, $result->totalCount);
544
        $this->assertEquals(
545
            $adminsLocation->id,
546
            $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...
547
        );
548
549
        $locationService->moveSubtree($adminsLocation, $editorsLocation);
550
        $this->refreshSearch($repository);
551
552
        // Found under Editors
553
        $criterion = new Criterion\ParentLocationId($editorsLocation->id);
554
        $query = new LocationQuery(array('filter' => $criterion));
555
        $result = $searchService->findLocations($query);
556
        $this->assertEquals(1, $result->totalCount);
557
        $this->assertEquals(
558
            $adminsLocation->id,
559
            $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...
560
        );
561
562
        // Not found under Members
563
        $criterion = new Criterion\ParentLocationId($membersLocation->id);
564
        $query = new LocationQuery(array('filter' => $criterion));
565
        $result = $searchService->findLocations($query);
566
        $this->assertEquals(0, $result->totalCount);
567
    }
568
569
    /**
570
     * Testing that content is indexed even when containing only fields with values
571
     * considered to be empty by the search engine.
572
     */
573
    public function testIndexContentWithNullField()
574
    {
575
        $repository = $this->getRepository();
576
        $contentService = $repository->getContentService();
577
        $contentTypeService = $repository->getContentTypeService();
578
        $searchService = $repository->getSearchService();
579
580
        $createStruct = $contentTypeService->newContentTypeCreateStruct('test-type');
581
        $createStruct->mainLanguageCode = 'eng-GB';
582
        $createStruct->names = array('eng-GB' => 'Test type');
583
        $createStruct->creatorId = 14;
584
        $createStruct->creationDate = new DateTime();
585
586
        $translatableFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct(
587
            'integer',
588
            'ezinteger'
589
        );
590
        $translatableFieldCreate->names = array('eng-GB' => 'Simple translatable integer field');
591
        $translatableFieldCreate->fieldGroup = 'main';
592
        $translatableFieldCreate->position = 1;
593
        $translatableFieldCreate->isTranslatable = true;
594
        $translatableFieldCreate->isSearchable = true;
595
596
        $createStruct->addFieldDefinition($translatableFieldCreate);
597
598
        $contentGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
599
        $contentTypeDraft = $contentTypeService->createContentType(
600
            $createStruct,
601
            array($contentGroup)
602
        );
603
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
604
        $contentType = $contentTypeService->loadContentType($contentTypeDraft->id);
605
606
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
607
        $createStruct->alwaysAvailable = false;
608
        $createStruct->mainLanguageCode = 'eng-GB';
609
610
        $draft = $contentService->createContent($createStruct);
611
        $content = $contentService->publishVersion($draft->getVersionInfo());
612
613
        $this->refreshSearch($repository);
614
615
        // Found
616
        $criterion = new Criterion\ContentId($content->id);
617
        $query = new Query(array('filter' => $criterion));
618
        $result = $searchService->findContent($query);
619
        $this->assertEquals(1, $result->totalCount);
620
        $this->assertEquals(
621
            $content->id,
622
            $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...
623
        );
624
    }
625
626
    /**
627
     * Test that updated Location is available for search.
628
     */
629
    public function testUpdateLocation()
630
    {
631
        $repository = $this->getRepository();
632
        $locationService = $repository->getLocationService();
633
        $searchService = $repository->getSearchService();
634
635
        $rootLocationId = 2;
636
        $locationToUpdate = $locationService->loadLocation($rootLocationId);
637
638
        $criterion = new Criterion\LogicalAnd([
639
            new Criterion\LocationId($rootLocationId),
640
            new Criterion\Location\Priority(Criterion\Operator::GT, 0),
641
        ]);
642
643
        $query = new LocationQuery(array('filter' => $criterion));
644
        $result = $searchService->findLocations($query);
645
646
        $this->assertEquals(0, $result->totalCount);
647
648
        $locationUpdateStruct = $locationService->newLocationUpdateStruct();
649
        $locationUpdateStruct->priority = 4;
650
        $locationService->updateLocation($locationToUpdate, $locationUpdateStruct);
651
652
        $this->refreshSearch($repository);
653
654
        $result = $searchService->findLocations($query);
655
656
        $this->assertEquals(1, $result->totalCount);
657
        $this->assertEquals(
658
            $locationToUpdate->id,
659
            $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...
660
        );
661
    }
662
663
    /**
664
     * Testing that content will be deleted with all of its subitems but subitems with additional location will stay as
665
     * they are.
666
     */
667
    public function testDeleteLocation()
668
    {
669
        $repository = $this->getRepository();
670
        $locationService = $repository->getLocationService();
671
672
        $treeContainerContent = $this->createContentWithName('Tree Container', [2]);
673
        $supposeBeDeletedSubItem = $this->createContentWithName(
674
            'Suppose to be deleted sub-item',
675
            [$treeContainerContent->contentInfo->mainLocationId]
676
        );
677
        $supposeSurviveSubItem = $this->createContentWithName(
678
            'Suppose to Survive Item',
679
            [2, $treeContainerContent->contentInfo->mainLocationId]
680
        );
681
682
        $treeContainerLocation = $locationService->loadLocation($treeContainerContent->contentInfo->mainLocationId);
683
684
        $this->refreshSearch($repository);
685
686
        $this->assertContentIdSearch($treeContainerContent->id, 1);
687
        $this->assertContentIdSearch($supposeSurviveSubItem->id, 1);
688
        $this->assertContentIdSearch($supposeBeDeletedSubItem->id, 1);
689
690
        $locationService->deleteLocation($treeContainerLocation);
691
692
        $this->refreshSearch($repository);
693
694
        $this->assertContentIdSearch($supposeSurviveSubItem->id, 1);
695
        $this->assertContentIdSearch($treeContainerContent->id, 0);
696
        $this->assertContentIdSearch($supposeBeDeletedSubItem->id, 0);
697
    }
698
699
    /**
700
     * Test content is available for search after being published.
701
     */
702
    public function testPublishVersion()
703
    {
704
        $repository = $this->getRepository();
705
        $searchService = $repository->getSearchService();
706
707
        $publishedContent = $this->createContentWithName('publishedContent', [2]);
708
        $this->refreshSearch($repository);
709
710
        $criterion = new Criterion\FullText('publishedContent');
711
        $query = new Query(['filter' => $criterion]);
712
        $result = $searchService->findContent($query);
713
714
        $this->assertCount(1, $result->searchHits);
715
        $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...
716
717
        // Searching for children of locationId=2 should also hit this content
718
        $criterion = new Criterion\ParentLocationId(2);
719
        $query = new LocationQuery(array('filter' => $criterion));
720
        $result = $searchService->findLocations($query);
721
722
        foreach ($result->searchHits as $searchHit) {
723
            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...
724
                return;
725
            }
726
        }
727
        $this->fail('Parent location sub-items do not contain published content');
728
    }
729
730
    /**
731
     * Test recovered content is available for search.
732
     */
733
    public function testRecoverLocation()
734
    {
735
        $repository = $this->getRepository();
736
        $locationService = $repository->getLocationService();
737
        $trashService = $repository->getTrashService();
738
        $searchService = $repository->getSearchService();
739
740
        $publishedContent = $this->createContentWithName('recovery-test', [2]);
741
        $location = $locationService->loadLocation($publishedContent->contentInfo->mainLocationId);
742
743
        $trashService->trash($location);
744
        $this->refreshSearch($repository);
745
746
        $criterion = new Criterion\LocationId($location->id);
747
        $query = new LocationQuery(['filter' => $criterion]);
748
        $locations = $searchService->findLocations($query);
749
        $this->assertEquals(0, $locations->totalCount);
750
751
        $trashItem = $trashService->loadTrashItem($location->id);
752
        $trashService->recover($trashItem);
753
        $this->refreshSearch($repository);
754
755
        $locations = $searchService->findLocations($query);
756
        $this->assertEquals(0, $locations->totalCount);
757
        $this->assertContentIdSearch($publishedContent->contentInfo->id, 1);
758
    }
759
760
    /**
761
     * Test copied content is available for search.
762
     */
763
    public function testCopyContent()
764
    {
765
        $repository = $this->getRepository();
766
        $searchService = $repository->getSearchService();
767
        $contentService = $repository->getContentService();
768
        $locationService = $repository->getLocationService();
769
770
        $publishedContent = $this->createContentWithName('copyTest', [2]);
771
        $this->refreshSearch($repository);
772
        $criterion = new Criterion\FullText('copyTest');
773
        $query = new Query(['filter' => $criterion]);
774
        $result = $searchService->findContent($query);
775
        $this->assertCount(1, $result->searchHits);
776
777
        $copiedContent = $contentService->copyContent($publishedContent->contentInfo, $locationService->newLocationCreateStruct(2));
778
        $this->refreshSearch($repository);
779
        $result = $searchService->findContent($query);
780
        $this->assertCount(2, $result->searchHits);
781
782
        $this->assertContentIdSearch($publishedContent->contentInfo->id, 1);
783
        $this->assertContentIdSearch($copiedContent->contentInfo->id, 1);
784
    }
785
786
    /**
787
     * Test that setting object content state to locked and then unlocked does not affect search index.
788
     */
789
    public function testSetContentState()
790
    {
791
        $repository = $this->getRepository();
792
        $objectStateService = $repository->getObjectStateService();
793
794
        // get Object States
795
        $stateNotLocked = $objectStateService->loadObjectState(1);
796
        $stateLocked = $objectStateService->loadObjectState(2);
797
798
        $publishedContent = $this->createContentWithName('setContentStateTest', [2]);
799
        $objectStateService->setContentState($publishedContent->contentInfo, $stateLocked->getObjectStateGroup(), $stateLocked);
800
        $this->refreshSearch($repository);
801
802
        // Setting Content State to "locked" should not affect search index
803
        $this->assertContentIdSearch($publishedContent->contentInfo->id, 1);
804
805
        $objectStateService->setContentState($publishedContent->contentInfo, $stateNotLocked->getObjectStateGroup(), $stateNotLocked);
806
        $this->refreshSearch($repository);
807
808
        // Setting Content State back to "not locked" should not affect search index
809
        $this->assertContentIdSearch($publishedContent->contentInfo->id, 1);
810
    }
811
812
    /**
813
     * Check if FullText indexing works for special cases of text.
814
     *
815
     * @param string $text Content Item field value text (to be indexed)
816
     * @param string $searchForText text based on which Content Item should be found
817
     * @param array $ignoreForSetupFactories list of SetupFactories to be ignored
0 ignored issues
show
Bug introduced by
There is no parameter named $ignoreForSetupFactories. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
818
     * @dataProvider getSpecialFullTextCases
819
     */
820
    public function testIndexingSpecialFullTextCases($text, $searchForText)
821
    {
822
        $repository = $this->getRepository();
823
        $searchService = $repository->getSearchService();
824
825
        $content = $this->createContentWithName($text, [2]);
826
        $this->refreshSearch($repository);
827
828
        $criterion = new Criterion\FullText($searchForText);
829
        $query = new Query(['filter' => $criterion]);
830
        $result = $searchService->findContent($query);
831
832
        // for some cases there might be more than one hit, so check if proper one was found
833
        foreach ($result->searchHits as $searchHit) {
834
            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...
835
                return;
836
            }
837
        }
838
        $this->fail('Failed to find required Content in search results');
839
    }
840
841
    /**
842
     * Data Provider for {@see testIndexingSpecialFullTextCases()} method.
843
     *
844
     * @return array
845
     */
846
    public function getSpecialFullTextCases()
847
    {
848
        return [
849
            ['UPPERCASE TEXT', 'uppercase text'],
850
            ['lowercase text', 'LOWERCASE TEXT'],
851
            ['text-with-hyphens', 'text-with-hyphens'],
852
            ['text containing spaces', 'text containing spaces'],
853
            ['"quoted text"', 'quoted text'],
854
            ['ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝ', 'àáâãäåçèéêëìíîïðñòóôõöøùúûüý'],
855
            ['with boundary.', 'with boundary'],
856
            ['Folder1.', 'Folder1.'],
857
            ['whitespaces', "     whitespaces  \n \t "],
858
            ["it's", "it's"],
859
            ['with_underscore', 'with_underscore'],
860
        ];
861
    }
862
863
    /**
864
     * Test FullText search on user first name and last name.
865
     *
866
     * @see https://jira.ez.no/browse/EZP-27250
867
     */
868
    public function testUserFullTextSearch()
869
    {
870
        $repository = $this->getRepository();
871
        $searchService = $repository->getSearchService();
872
        $user = $this->createUser('TestUser', 'Jon', 'Snow');
873
874
        $criterion = new Criterion\LogicalAnd(
875
            [
876
                new Criterion\FullText('Jon Snow'),
877
                new Criterion\ContentTypeIdentifier('user'),
878
            ]
879
        );
880
        $query = new Query(['filter' => $criterion]);
881
        $this->refreshSearch($repository);
882
        $results = $searchService->findContent($query);
883
        self::assertEquals(1, $results->totalCount);
884
        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...
885
    }
886
887
    /**
888
     * Test updating Content field value with empty value removes it from search index.
889
     */
890
    public function testRemovedContentFieldValueIsNotFound()
891
    {
892
        $repository = $this->getRepository();
893
        $contentService = $repository->getContentService();
894
        $searchService = $repository->getSearchService();
895
        $publishedContent = $this->createContentWithNameAndDescription('testRemovedContentFieldValueIsNotFound', 'descriptionToBeRemoved', [2]);
896
        $this->refreshSearch($repository);
897
898
        $contentDraft = $contentService->createContentDraft($publishedContent->contentInfo);
899
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
900
        $contentUpdateStruct->setField('description', null);
901
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
902
        $contentService->publishVersion($contentDraft->versionInfo);
903
        $this->refreshSearch($repository);
904
905
        // Removed field value should not be found
906
        $criterion = new Criterion\FullText('descriptionToBeRemoved');
907
        $query = new Query(['filter' => $criterion]);
908
        $results = $searchService->findContent($query);
909
        $this->assertEquals(0, $results->totalCount);
910
911
        // Should be found
912
        $criterion = new Criterion\FullText('testRemovedContentFieldValueIsNotFound');
913
        $query = new Query(['filter' => $criterion]);
914
        $results = $searchService->findContent($query);
915
        $this->assertEquals(1, $results->totalCount);
916
    }
917
918
    /**
919
     * Check if children locations are/are not ivisible.
920
     *
921
     * @param \eZ\Publish\API\Repository\SearchService $searchService
922
     * @param int $parentLocationId parent location Id
923
     * @param bool $expected expected value of {invisible} property in subtree
924
     */
925
    private function assertSubtreeInvisibleProperty(SearchService $searchService, $parentLocationId, $expected)
926
    {
927
        $criterion = new Criterion\ParentLocationId($parentLocationId);
928
        $query = new LocationQuery(array('filter' => $criterion));
929
        $result = $searchService->findLocations($query);
930
        foreach ($result->searchHits as $searchHit) {
931
            $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...
932
            // Perform recursive check for children locations
933
            $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...
934
        }
935
    }
936
937
    /**
938
     * Test that swapping locations affects properly Search Engine Index.
939
     */
940
    public function testSwapLocation()
941
    {
942
        $repository = $this->getRepository();
943
        $locationService = $repository->getLocationService();
944
        $searchService = $repository->getSearchService();
945
946
        $content01 = $this->createContentWithName('content01', [2]);
947
        $location01 = $locationService->loadLocation($content01->contentInfo->mainLocationId);
948
949
        $content02 = $this->createContentWithName('content02', [2]);
950
        $location02 = $locationService->loadLocation($content02->contentInfo->mainLocationId);
951
952
        $locationService->swapLocation($location01, $location02);
953
        $this->refreshSearch($repository);
954
955
        // content02 should be at location01
956
        $criterion = new Criterion\LocationId($location01->id);
957
        $query = new Query(['filter' => $criterion]);
958
        $results = $searchService->findContent($query);
959
        $this->assertEquals(1, $results->totalCount);
960
        $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...
961
962
        // content01 should be at location02
963
        $criterion = new Criterion\LocationId($location02->id);
964
        $query = new Query(['filter' => $criterion]);
965
        $results = $searchService->findContent($query);
966
        $this->assertEquals(1, $results->totalCount);
967
        $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...
968
    }
969
970
    /**
971
     * Test that updating Content metadata affects properly Search Engine Index.
972
     */
973
    public function testUpdateContentMetadata()
974
    {
975
        $repository = $this->getRepository();
976
        $contentService = $repository->getContentService();
977
        $locationService = $repository->getLocationService();
978
        $searchService = $repository->getSearchService();
979
980
        $publishedContent = $this->createContentWithName('updateMetadataTest', [2]);
981
        $originalMainLocationId = $publishedContent->contentInfo->mainLocationId;
982
        $newLocationCreateStruct = $locationService->newLocationCreateStruct(60);
983
        $newLocation = $locationService->createLocation($publishedContent->contentInfo, $newLocationCreateStruct);
984
985
        $newContentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
986
        $newContentMetadataUpdateStruct->remoteId = md5('Test');
987
        $newContentMetadataUpdateStruct->publishedDate = new \DateTime();
988
        $newContentMetadataUpdateStruct->publishedDate->add(new \DateInterval('P1D'));
989
        $newContentMetadataUpdateStruct->mainLocationId = $newLocation->id;
990
991
        $contentService->updateContentMetadata($publishedContent->contentInfo, $newContentMetadataUpdateStruct);
992
        $this->refreshSearch($repository);
993
994
        // find Content by Id, calling findContentInfo which is using the Search Index
995
        $criterion = new Criterion\ContentId($publishedContent->id);
996
        $query = new Query(['filter' => $criterion]);
997
        $results = $searchService->findContentInfo($query);
998
        $this->assertEquals(1, $results->totalCount);
999
        $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...
1000
1001
        // find Content using updated RemoteId
1002
        $criterion = new Criterion\RemoteId($newContentMetadataUpdateStruct->remoteId);
1003
        $query = new Query(['filter' => $criterion]);
1004
        $results = $searchService->findContent($query);
1005
        $this->assertEquals(1, $results->totalCount);
1006
        $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...
1007
        /** @var \eZ\Publish\Core\Repository\Values\Content\Content $foundContentInfo */
1008
        $this->assertEquals($publishedContent->id, $foundContentInfo->id);
1009
        $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...
1010
        $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...
1011
        $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...
1012
1013
        // find Content using old main location
1014
        $criterion = new Criterion\LocationId($originalMainLocationId);
1015
        $query = new LocationQuery(['filter' => $criterion]);
1016
        $results = $searchService->findLocations($query);
1017
        $this->assertEquals(1, $results->totalCount);
1018
        $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...
1019
    }
1020
1021
    /**
1022
     * Test that updating Content Draft metadata does not affect Search Engine Index.
1023
     */
1024
    public function testUpdateContentDraftMetadataIsNotIndexed()
1025
    {
1026
        $repository = $this->getRepository();
1027
        $contentService = $repository->getContentService();
1028
        $locationService = $repository->getLocationService();
1029
1030
        $testableContentType = $this->createTestContentType();
1031
        $rootContentStruct = $contentService->newContentCreateStruct($testableContentType, 'eng-GB');
1032
        $rootContentStruct->setField('name', 'TestUpdatingContentDraftMetadata');
1033
1034
        $contentDraft = $contentService->createContent($rootContentStruct, [$locationService->newLocationCreateStruct(2)]);
1035
1036
        $newContentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
1037
        $newContentMetadataUpdateStruct->ownerId = 10;
1038
        $newContentMetadataUpdateStruct->remoteId = md5('Test');
1039
1040
        $contentService->updateContentMetadata($contentDraft->contentInfo, $newContentMetadataUpdateStruct);
1041
1042
        $this->refreshSearch($repository);
1043
        $this->assertContentIdSearch($contentDraft->contentInfo->id, 0);
1044
    }
1045
1046
    /**
1047
     * Test that assigning section to content object properly affects Search Engine Index.
1048
     */
1049
    public function testAssignSection()
1050
    {
1051
        $repository = $this->getRepository();
1052
        $sectionService = $repository->getSectionService();
1053
        $searchService = $repository->getSearchService();
1054
1055
        $section = $sectionService->loadSection(2);
1056
        $content = $this->createContentWithName('testAssignSection', [2]);
1057
1058
        $sectionService->assignSection($content->contentInfo, $section);
1059
        $this->refreshSearch($repository);
1060
1061
        $criterion = new Criterion\ContentId($content->id);
1062
        $query = new Query(['filter' => $criterion]);
1063
        $results = $searchService->findContentInfo($query);
1064
        $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...
1065
    }
1066
1067
    /**
1068
     * Test search engine is updated after removal of the translation from all the Versions.
1069
     */
1070
    public function testDeleteTranslation()
1071
    {
1072
        $repository = $this->getRepository();
1073
        $searchService = $repository->getSearchService();
1074
        $contentService = $repository->getContentService();
1075
1076
        $content = $this->createMultiLanguageContent(
1077
            [
1078
                'eng-US' => 'AmE Name',
1079
                'eng-GB' => 'BrE Name',
1080
            ],
1081
            2,
1082
            false
1083
        );
1084
1085
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
1086
1087
        $this->refreshSearch($repository);
1088
1089
        // Test ContentId search returns Content without removed Translation
1090
        $query = new Query([
1091
            'query' => new Criterion\ContentId($content->contentInfo->id),
1092
            'filter' => new Criterion\LanguageCode('eng-GB', false),
1093
        ]);
1094
        $result = $searchService->findContent($query);
1095
        self::assertEquals(0, $result->totalCount);
1096
1097
        // Test FullText search for removed unique name part returns no results
1098
        $query = new Query([
1099
            'query' => new Criterion\FullText('BrE'),
1100
        ]);
1101
        $result = $searchService->findContent($query);
1102
        self::assertEquals(0, $result->totalCount);
1103
1104
        // Test Location Search returns Content without removed Translation
1105
        $query = new LocationQuery(
1106
            [
1107
                'query' => new Criterion\FullText('BrE'),
1108
            ]
1109
        );
1110
        $result = $searchService->findLocations($query);
1111
        self::assertEquals(0, $result->totalCount);
1112
    }
1113
1114
    /**
1115
     * Will create if not exists a simple content type for test purposes with just one required field name.
1116
     *
1117
     * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType
1118
     */
1119
    protected function createTestContentType()
1120
    {
1121
        $repository = $this->getRepository();
1122
        $contentTypeService = $repository->getContentTypeService();
1123
        $contentTypeIdentifier = 'test-type';
1124
        try {
1125
            return $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
1126
        } catch (NotFoundException $e) {
1127
            // continue creation process
1128
        }
1129
1130
        $nameField = $contentTypeService->newFieldDefinitionCreateStruct('name', 'ezstring');
1131
        $nameField->fieldGroup = 'main';
1132
        $nameField->position = 1;
1133
        $nameField->isTranslatable = true;
1134
        $nameField->isSearchable = true;
1135
        $nameField->isRequired = true;
1136
1137
        $contentTypeStruct = $contentTypeService->newContentTypeCreateStruct($contentTypeIdentifier);
1138
        $contentTypeStruct->mainLanguageCode = 'eng-GB';
1139
        $contentTypeStruct->creatorId = 14;
1140
        $contentTypeStruct->creationDate = new DateTime();
1141
        $contentTypeStruct->names = ['eng-GB' => 'Test Content Type'];
1142
        $contentTypeStruct->addFieldDefinition($nameField);
1143
1144
        $contentTypeGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
1145
1146
        $contentTypeDraft = $contentTypeService->createContentType($contentTypeStruct, [$contentTypeGroup]);
1147
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1148
1149
        return $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
1150
    }
1151
1152
    /**
1153
     * Will create and publish an content with a filed with a given content name in location provided into
1154
     * $parentLocationIdList.
1155
     *
1156
     * @param string $contentName
1157
     * @param array $parentLocationIdList
1158
     *
1159
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1160
     */
1161
    protected function createContentWithName($contentName, array $parentLocationIdList = array())
1162
    {
1163
        $contentService = $this->getRepository()->getContentService();
1164
        $locationService = $this->getRepository()->getLocationService();
1165
1166
        $testableContentType = $this->createTestContentType();
1167
1168
        $rootContentStruct = $contentService->newContentCreateStruct($testableContentType, 'eng-GB');
1169
        $rootContentStruct->setField('name', $contentName);
1170
1171
        $parentLocationList = [];
1172
        foreach ($parentLocationIdList as $locationID) {
1173
            $parentLocationList[] = $locationService->newLocationCreateStruct($locationID);
1174
        }
1175
1176
        $contentDraft = $contentService->createContent($rootContentStruct, $parentLocationList);
1177
        $publishedContent = $contentService->publishVersion($contentDraft->getVersionInfo());
1178
1179
        return $publishedContent;
1180
    }
1181
1182
    /**
1183
     * Create and publish a content with filled name and description fields in location provided into
1184
     * $parentLocationIdList.
1185
     *
1186
     * @param string $contentName
1187
     * @param $contentDescription
1188
     * @param array $parentLocationIdList
1189
     *
1190
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1191
     */
1192
    protected function createContentWithNameAndDescription($contentName, $contentDescription, array $parentLocationIdList = [])
1193
    {
1194
        $repository = $this->getRepository();
1195
        $contentService = $repository->getContentService();
1196
        $contentTypeService = $repository->getContentTypeService();
1197
        $publishedContent = $this->createContentWithName($contentName, $parentLocationIdList);
1198
        $descriptionField = $contentTypeService->newFieldDefinitionCreateStruct('description', 'ezstring');
1199
        $descriptionField->fieldGroup = 'main';
1200
        $descriptionField->position = 2;
1201
        $descriptionField->isTranslatable = true;
1202
        $descriptionField->isSearchable = true;
1203
        $descriptionField->isRequired = false;
1204
        $contentType = $contentTypeService->loadContentType($publishedContent->contentInfo->contentTypeId);
1205
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
1206
        $contentTypeService->addFieldDefinition($contentTypeDraft, $descriptionField);
1207
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1208
        $contentDraft = $contentService->createContentDraft($publishedContent->contentInfo);
1209
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1210
        $contentUpdateStruct->setField('description', $contentDescription);
1211
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
1212
1213
        return $contentService->publishVersion($contentDraft->versionInfo);
1214
    }
1215
1216
    /**
1217
     * Create and publish a content with specified, in multiple languages, fields.
1218
     *
1219
     * @param string[] $names multi-language name field in the form of: <code>['lang-code' => 'name']</code>
1220
     * @param int $parentLocationId
1221
     * @param bool $alwaysAvailable
1222
     *
1223
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1224
     */
1225
    protected function createMultiLanguageContent(array $names, $parentLocationId, $alwaysAvailable)
1226
    {
1227
        $repository = $this->getRepository();
1228
        $contentService = $repository->getContentService();
1229
        $locationService = $repository->getLocationService();
1230
1231
        $testableContentType = $this->createTestContentType();
1232
1233
        $contentCreateStruct = $contentService->newContentCreateStruct(
1234
            $testableContentType,
1235
            array_keys($names)[0]
1236
        );
1237
1238
        foreach ($names as $languageCode => $value) {
1239
            $contentCreateStruct->setField('name', $value, $languageCode);
1240
        }
1241
1242
        $contentCreateStruct->alwaysAvailable = $alwaysAvailable;
1243
1244
        $contentDraft = $contentService->createContent(
1245
            $contentCreateStruct,
1246
            [
1247
                $locationService->newLocationCreateStruct($parentLocationId),
1248
            ]
1249
        );
1250
        $publishedContent = $contentService->publishVersion($contentDraft->getVersionInfo());
1251
1252
        return $publishedContent;
1253
    }
1254
1255
    /**
1256
     * Asserts an content id if it exists still in the solr core.
1257
     *
1258
     * @param int $contentId
1259
     * @param int $expectedCount
1260
     */
1261
    protected function assertContentIdSearch($contentId, $expectedCount)
1262
    {
1263
        $searchService = $this->getRepository()->getSearchService();
1264
1265
        $criterion = new Criterion\ContentId($contentId);
1266
        $query = new Query(array('filter' => $criterion));
1267
        $result = $searchService->findContent($query);
1268
1269
        $this->assertEquals($expectedCount, $result->totalCount);
1270
        if ($expectedCount == 0) {
1271
            return;
1272
        }
1273
1274
        $this->assertEquals(
1275
            $contentId,
1276
            $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...
1277
        );
1278
    }
1279
1280
    /**
1281
     * Create & get new Location for tests.
1282
     *
1283
     * @return \eZ\Publish\API\Repository\Values\Content\Location
1284
     */
1285
    protected function createNewTestLocation()
1286
    {
1287
        $repository = $this->getRepository();
1288
        $locationService = $repository->getLocationService();
1289
        $contentService = $repository->getContentService();
1290
1291
        $rootLocationId = 2;
1292
        $membersContentId = 11;
1293
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
1294
1295
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
1296
1297
        return $locationService->createLocation($membersContentInfo, $locationCreateStruct);
1298
    }
1299
}
1300