Completed
Push — master ( c9d304...dc2e58 )
by André
58:11 queued 43:32
created

SearchEngineIndexingTest::testMoveSubtree()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 60
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 43
nc 1
nop 0
dl 0
loc 60
rs 9.5555
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Exceptions\NotFoundException;
12
use eZ\Publish\API\Repository\SearchService;
13
use eZ\Publish\API\Repository\Tests\SetupFactory\LegacyElasticsearch;
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
     * EZP-26186: Make sure index is NOT deleted on removal of version draft (affected Solr & content index on Elastic).
30
     */
31
    public function testDeleteVersion()
32
    {
33
        $repository = $this->getRepository();
34
        $contentService = $repository->getContentService();
35
        $searchService = $repository->getSearchService();
36
37
        $membersContentId = $this->generateId('content', 11);
38
        $contentInfo = $contentService->loadContentInfo($membersContentId);
39
40
        $draft = $contentService->createContentDraft($contentInfo);
41
        $contentService->deleteVersion($draft->getVersionInfo());
42
43
        $this->refreshSearch($repository);
44
45
        // Found
46
        $criterion = new Criterion\LocationId($contentInfo->mainLocationId);
47
        $query = new Query(array('filter' => $criterion));
48
        $result = $searchService->findContentInfo($query);
49
        $this->assertEquals(1, $result->totalCount);
50
        $this->assertEquals(
51
            $contentInfo->id,
52
            $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...
53
        );
54
    }
55
56
    /**
57
     * EZP-26186: Make sure affected child locations are deleted on content deletion (affected Solr & Elastic).
58
     */
59 View Code Duplication
    public function testDeleteContent()
60
    {
61
        $repository = $this->getRepository();
62
        $contentService = $repository->getContentService();
63
        $searchService = $repository->getSearchService();
64
65
        $anonymousUsersContentId = $this->generateId('content', 42);
66
        $contentInfo = $contentService->loadContentInfo($anonymousUsersContentId);
67
68
        $contentService->deleteContent($contentInfo);
69
70
        $this->refreshSearch($repository);
71
72
        // Should not be found
73
        $criterion = new Criterion\ParentLocationId($contentInfo->mainLocationId);
74
        $query = new LocationQuery(array('filter' => $criterion));
75
        $result = $searchService->findLocations($query);
76
        $this->assertEquals(0, $result->totalCount);
77
    }
78
79
    /**
80
     * EZP-26186: Make sure index is deleted on removal of Users  (affected Solr & Elastic).
81
     */
82 View Code Duplication
    public function testDeleteUser()
83
    {
84
        $repository = $this->getRepository();
85
        $userService = $repository->getUserService();
86
        $searchService = $repository->getSearchService();
87
88
        $anonymousContentId = $this->generateId('user', 10);
89
        $user = $userService->loadUser($anonymousContentId);
90
91
        $userService->deleteUser($user);
92
93
        $this->refreshSearch($repository);
94
95
        // Should not be found
96
        $criterion = new Criterion\ContentId($user->id);
97
        $query = new Query(array('filter' => $criterion));
98
        $result = $searchService->findContentInfo($query);
99
        $this->assertEquals(0, $result->totalCount);
100
    }
101
102
    /**
103
     * EZP-26186: Make sure index is deleted on removal of UserGroups  (affected Solr & Elastic).
104
     */
105 View Code Duplication
    public function testDeleteUserGroup()
106
    {
107
        $repository = $this->getRepository();
108
        $userService = $repository->getUserService();
109
        $searchService = $repository->getSearchService();
110
111
        $membersContentId = $this->generateId('user_group', 11);
112
        $userGroup = $userService->loadUserGroup($membersContentId);
113
114
        $userService->deleteUserGroup($userGroup);
115
116
        $this->refreshSearch($repository);
117
118
        // Should not be found
119
        $criterion = new Criterion\ContentId($userGroup->id);
120
        $query = new Query(array('filter' => $criterion));
121
        $result = $searchService->findContentInfo($query);
122
        $this->assertEquals(0, $result->totalCount);
123
    }
124
125
   /*
126
    * Test that a newly created user is available for search.
127
    */
128
    public function testCreateUser()
129
    {
130
        $repository = $this->getRepository();
131
        $userService = $repository->getUserService();
132
        $searchService = $repository->getSearchService();
133
134
        // ID of the "Editors" user group
135
        $editorsGroupId = 13;
136
        $userCreate = $userService->newUserCreateStruct(
137
            'user',
138
            '[email protected]',
139
            'secret',
140
            'eng-US'
141
        );
142
        $userCreate->enabled = true;
143
        $userCreate->setField('first_name', 'Example');
144
        $userCreate->setField('last_name', 'User');
145
146
        // Load parent group for the user
147
        $group = $userService->loadUserGroup($editorsGroupId);
148
149
        // Create a new user instance.
150
        $user = $userService->createUser($userCreate, array($group));
151
152
        $this->refreshSearch($repository);
153
154
        // Should be found
155
        $criterion = new Criterion\ContentId($user->id);
156
        $query = new Query(array('filter' => $criterion));
157
        $result = $searchService->findContentInfo($query);
158
        $this->assertEquals(1, $result->totalCount);
159
    }
160
161
    /**
162
     * Test that a newly created user group is available for search.
163
     */
164
    public function testCreateUserGroup()
165
    {
166
        $repository = $this->getRepository();
167
        $userService = $repository->getUserService();
168
        $searchService = $repository->getSearchService();
169
170
        $mainGroupId = $this->generateId('group', 4);
171
172
        $parentUserGroup = $userService->loadUserGroup($mainGroupId);
173
        $userGroupCreateStruct = $userService->newUserGroupCreateStruct('eng-GB');
174
        $userGroupCreateStruct->setField('name', 'Example Group');
175
176
        // Create a new user group
177
        $userGroup = $userService->createUserGroup(
178
            $userGroupCreateStruct,
179
            $parentUserGroup
180
        );
181
182
        $this->refreshSearch($repository);
183
184
        // Should be found
185
        $criterion = new Criterion\ContentId($userGroup->id);
186
        $query = new Query(array('filter' => $criterion));
187
        $result = $searchService->findContentInfo($query);
188
        $this->assertEquals(1, $result->totalCount);
189
    }
190
191
    /**
192
     * Test that a newly created Location is available for search.
193
     */
194
    public function testCreateLocation()
195
    {
196
        $repository = $this->getRepository();
197
        $searchService = $repository->getSearchService();
198
        $membersLocation = $this->createNewTestLocation();
199
200
        $this->refreshSearch($repository);
201
202
        // Found
203
        $criterion = new Criterion\LocationId($membersLocation->id);
204
        $query = new LocationQuery(array('filter' => $criterion));
205
        $result = $searchService->findLocations($query);
206
        $this->assertEquals(1, $result->totalCount);
207
        $this->assertEquals(
208
            $membersLocation->id,
209
            $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...
210
        );
211
    }
212
213
    /**
214
     * Test that hiding a Location makes it unavailable for search.
215
     */
216
    public function testHideSubtree()
217
    {
218
        $repository = $this->getRepository();
219
        $searchService = $repository->getSearchService();
220
221
        // 5 is the ID of an existing location
222
        $locationId = $this->generateId('location', 5);
223
        $locationService = $repository->getLocationService();
224
        $location = $locationService->loadLocation($locationId);
225
        $locationService->hideLocation($location);
226
        $this->refreshSearch($repository);
227
228
        // Check if parent location is hidden
229
        $criterion = new Criterion\LocationId($locationId);
230
        $query = new LocationQuery(array('filter' => $criterion));
231
        $result = $searchService->findLocations($query);
232
        $this->assertEquals(1, $result->totalCount);
233
        $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...
234
235
        // Check if children locations are invisible
236
        $this->assertSubtreeInvisibleProperty($searchService, $locationId, true);
237
    }
238
239
    /**
240
     * Test that hiding and revealing a Location makes it available for search.
241
     */
242
    public function testRevealSubtree()
243
    {
244
        $repository = $this->getRepository();
245
        $searchService = $repository->getSearchService();
246
247
        // 5 is the ID of an existing location
248
        $locationId = $this->generateId('location', 5);
249
        $locationService = $repository->getLocationService();
250
        $location = $locationService->loadLocation($locationId);
251
        $locationService->hideLocation($location);
252
        $this->refreshSearch($repository);
253
        $locationService->unhideLocation($location);
254
        $this->refreshSearch($repository);
255
256
        // Check if parent location is not hidden
257
        $criterion = new Criterion\LocationId($locationId);
258
        $query = new LocationQuery(array('filter' => $criterion));
259
        $result = $searchService->findLocations($query);
260
        $this->assertEquals(1, $result->totalCount);
261
        $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...
262
263
        // Check if children locations are not invisible
264
        $this->assertSubtreeInvisibleProperty($searchService, $locationId, false);
265
    }
266
267
    /**
268
     * Test that a copied subtree is available for search.
269
     */
270
    public function testCopySubtree()
271
    {
272
        $repository = $this->getRepository();
273
        $locationService = $repository->getLocationService();
274
        $contentService = $repository->getContentService();
275
        $searchService = $repository->getSearchService();
276
277
        $rootLocationId = 2;
278
        $membersContentId = 11;
279
        $adminsContentId = 12;
280
        $editorsContentId = 13;
281
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
282
        $adminsContentInfo = $contentService->loadContentInfo($adminsContentId);
283
        $editorsContentInfo = $contentService->loadContentInfo($editorsContentId);
284
285
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
286
        $membersLocation = $locationService->createLocation($membersContentInfo, $locationCreateStruct);
287
        $editorsLocation = $locationService->createLocation($editorsContentInfo, $locationCreateStruct);
288
        $adminsLocation = $locationService->createLocation(
289
            $adminsContentInfo,
290
            $locationService->newLocationCreateStruct($membersLocation->id)
291
        );
292
293
        $copiedLocation = $locationService->copySubtree($adminsLocation, $editorsLocation);
294
        $this->refreshSearch($repository);
295
296
        // Found under Members
297
        $criterion = new Criterion\ParentLocationId($membersLocation->id);
298
        $query = new LocationQuery(array('filter' => $criterion));
299
        $result = $searchService->findLocations($query);
300
        $this->assertEquals(1, $result->totalCount);
301
        $this->assertEquals(
302
            $adminsLocation->id,
303
            $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...
304
        );
305
306
        // Found under Editors
307
        $criterion = new Criterion\ParentLocationId($editorsLocation->id);
308
        $query = new LocationQuery(array('filter' => $criterion));
309
        $result = $searchService->findLocations($query);
310
        $this->assertEquals(1, $result->totalCount);
311
        $this->assertEquals(
312
            $copiedLocation->id,
313
            $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...
314
        );
315
    }
316
317
    /**
318
     * Test that moved subtree is available for search and found only under a specific parent Location.
319
     */
320
    public function testMoveSubtree()
321
    {
322
        $repository = $this->getRepository();
323
        $locationService = $repository->getLocationService();
324
        $contentService = $repository->getContentService();
325
        $searchService = $repository->getSearchService();
326
327
        $rootLocationId = 2;
328
        $membersContentId = 11;
329
        $adminsContentId = 12;
330
        $editorsContentId = 13;
331
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
332
        $adminsContentInfo = $contentService->loadContentInfo($adminsContentId);
333
        $editorsContentInfo = $contentService->loadContentInfo($editorsContentId);
334
335
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
336
        $membersLocation = $locationService->createLocation($membersContentInfo, $locationCreateStruct);
337
        $editorsLocation = $locationService->createLocation($editorsContentInfo, $locationCreateStruct);
338
        $adminsLocation = $locationService->createLocation(
339
            $adminsContentInfo,
340
            $locationService->newLocationCreateStruct($membersLocation->id)
341
        );
342
343
        $this->refreshSearch($repository);
344
345
        // Not found under Editors
346
        $criterion = new Criterion\ParentLocationId($editorsLocation->id);
347
        $query = new LocationQuery(array('filter' => $criterion));
348
        $result = $searchService->findLocations($query);
349
        $this->assertEquals(0, $result->totalCount);
350
351
        // Found under Members
352
        $criterion = new Criterion\ParentLocationId($membersLocation->id);
353
        $query = new LocationQuery(array('filter' => $criterion));
354
        $result = $searchService->findLocations($query);
355
        $this->assertEquals(1, $result->totalCount);
356
        $this->assertEquals(
357
            $adminsLocation->id,
358
            $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...
359
        );
360
361
        $locationService->moveSubtree($adminsLocation, $editorsLocation);
362
        $this->refreshSearch($repository);
363
364
        // Found under Editors
365
        $criterion = new Criterion\ParentLocationId($editorsLocation->id);
366
        $query = new LocationQuery(array('filter' => $criterion));
367
        $result = $searchService->findLocations($query);
368
        $this->assertEquals(1, $result->totalCount);
369
        $this->assertEquals(
370
            $adminsLocation->id,
371
            $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...
372
        );
373
374
        // Not found under Members
375
        $criterion = new Criterion\ParentLocationId($membersLocation->id);
376
        $query = new LocationQuery(array('filter' => $criterion));
377
        $result = $searchService->findLocations($query);
378
        $this->assertEquals(0, $result->totalCount);
379
    }
380
381
    /**
382
     * Testing that content is indexed even when containing only fields with values
383
     * considered to be empty by the search engine.
384
     */
385
    public function testIndexContentWithNullField()
386
    {
387
        $repository = $this->getRepository();
388
        $contentService = $repository->getContentService();
389
        $contentTypeService = $repository->getContentTypeService();
390
        $searchService = $repository->getSearchService();
391
392
        $createStruct = $contentTypeService->newContentTypeCreateStruct('test-type');
393
        $createStruct->mainLanguageCode = 'eng-GB';
394
        $createStruct->names = array('eng-GB' => 'Test type');
395
        $createStruct->creatorId = 14;
396
        $createStruct->creationDate = new DateTime();
397
398
        $translatableFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct(
399
            'integer',
400
            'ezinteger'
401
        );
402
        $translatableFieldCreate->names = array('eng-GB' => 'Simple translatable integer field');
403
        $translatableFieldCreate->fieldGroup = 'main';
404
        $translatableFieldCreate->position = 1;
405
        $translatableFieldCreate->isTranslatable = true;
406
        $translatableFieldCreate->isSearchable = true;
407
408
        $createStruct->addFieldDefinition($translatableFieldCreate);
409
410
        $contentGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
411
        $contentTypeDraft = $contentTypeService->createContentType(
412
            $createStruct,
413
            array($contentGroup)
414
        );
415
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
416
        $contentType = $contentTypeService->loadContentType($contentTypeDraft->id);
0 ignored issues
show
Documentation introduced by
The property $id is declared protected in eZ\Publish\API\Repositor...ContentType\ContentType. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

Since the property has write access only, you can use the @property-write annotation instead.

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

See also the PhpDoc documentation for @property.

Loading history...
417
418
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
419
        $createStruct->alwaysAvailable = false;
420
        $createStruct->mainLanguageCode = 'eng-GB';
421
422
        $draft = $contentService->createContent($createStruct);
423
        $content = $contentService->publishVersion($draft->getVersionInfo());
424
425
        $this->refreshSearch($repository);
426
427
        // Found
428
        $criterion = new Criterion\ContentId($content->id);
429
        $query = new Query(array('filter' => $criterion));
430
        $result = $searchService->findContent($query);
431
        $this->assertEquals(1, $result->totalCount);
432
        $this->assertEquals(
433
            $content->id,
434
            $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...
435
        );
436
    }
437
438
    /**
439
     * Test that updated Location is available for search.
440
     */
441
    public function testUpdateLocation()
442
    {
443
        $repository = $this->getRepository();
444
        $locationService = $repository->getLocationService();
445
        $searchService = $repository->getSearchService();
446
447
        $rootLocationId = 2;
448
        $locationToUpdate = $locationService->loadLocation($rootLocationId);
449
450
        $criterion = new Criterion\LogicalAnd([
451
            new Criterion\LocationId($rootLocationId),
452
            new Criterion\Location\Priority(Criterion\Operator::GT, 0),
453
        ]);
454
455
        $query = new LocationQuery(array('filter' => $criterion));
456
        $result = $searchService->findLocations($query);
457
458
        $this->assertEquals(0, $result->totalCount);
459
460
        $locationUpdateStruct = $locationService->newLocationUpdateStruct();
461
        $locationUpdateStruct->priority = 4;
462
        $locationService->updateLocation($locationToUpdate, $locationUpdateStruct);
463
464
        $this->refreshSearch($repository);
465
466
        $result = $searchService->findLocations($query);
467
468
        $this->assertEquals(1, $result->totalCount);
469
        $this->assertEquals(
470
            $locationToUpdate->id,
471
            $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...
472
        );
473
    }
474
475
    /**
476
     * Testing that content will be deleted with all of its subitems but subitems with additional location will stay as
477
     * they are.
478
     */
479
    public function testDeleteLocation()
480
    {
481
        $repository = $this->getRepository();
482
        $locationService = $repository->getLocationService();
483
484
        $treeContainerContent = $this->createContentWithName('Tree Container', [2]);
485
        $supposeBeDeletedSubItem = $this->createContentWithName(
486
            'Suppose to be deleted sub-item',
487
            [$treeContainerContent->contentInfo->mainLocationId]
488
        );
489
        $supposeSurviveSubItem = $this->createContentWithName(
490
            'Suppose to Survive Item',
491
            [2, $treeContainerContent->contentInfo->mainLocationId]
492
        );
493
494
        $treeContainerLocation = $locationService->loadLocation($treeContainerContent->contentInfo->mainLocationId);
495
496
        $this->refreshSearch($repository);
497
498
        $this->assertContentIdSearch($treeContainerContent->id, 1);
499
        $this->assertContentIdSearch($supposeSurviveSubItem->id, 1);
500
        $this->assertContentIdSearch($supposeBeDeletedSubItem->id, 1);
501
502
        $locationService->deleteLocation($treeContainerLocation);
503
504
        $this->refreshSearch($repository);
505
506
        $this->assertContentIdSearch($supposeSurviveSubItem->id, 1);
507
        $this->assertContentIdSearch($treeContainerContent->id, 0);
508
        $this->assertContentIdSearch($supposeBeDeletedSubItem->id, 0);
509
    }
510
511
    /**
512
     * Test content is available for search after being published.
513
     */
514
    public function testPublishVersion()
515
    {
516
        $repository = $this->getRepository();
517
        $searchService = $repository->getSearchService();
518
519
        $publishedContent = $this->createContentWithName('publishedContent', [2]);
520
        $this->refreshSearch($repository);
521
522
        $criterion = new Criterion\FullText('publishedContent');
523
        $query = new Query(['filter' => $criterion]);
524
        $result = $searchService->findContent($query);
525
526
        $this->assertCount(1, $result->searchHits);
527
        $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...
528
529
        // Searching for children of locationId=2 should also hit this content
530
        $criterion = new Criterion\ParentLocationId(2);
531
        $query = new LocationQuery(array('filter' => $criterion));
532
        $result = $searchService->findLocations($query);
533
534
        foreach ($result->searchHits as $searchHit) {
535
            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...
536
                return;
537
            }
538
        }
539
        $this->fail('Parent location sub-items do not contain published content');
540
    }
541
542
    /**
543
     * Test recovered content is available for search.
544
     */
545
    public function testRecoverLocation()
546
    {
547
        $repository = $this->getRepository();
548
        $locationService = $repository->getLocationService();
549
        $trashService = $repository->getTrashService();
550
        $searchService = $repository->getSearchService();
551
552
        $publishedContent = $this->createContentWithName('recovery-test', [2]);
553
        $location = $locationService->loadLocation($publishedContent->contentInfo->mainLocationId);
554
555
        $trashService->trash($location);
556
        $this->refreshSearch($repository);
557
558
        $criterion = new Criterion\LocationId($location->id);
559
        $query = new LocationQuery(['filter' => $criterion]);
560
        $locations = $searchService->findLocations($query);
561
        $this->assertEquals(0, $locations->totalCount);
562
563
        $trashItem = $trashService->loadTrashItem($location->id);
564
        $trashService->recover($trashItem);
565
        $this->refreshSearch($repository);
566
567
        $locations = $searchService->findLocations($query);
568
        $this->assertEquals(0, $locations->totalCount);
569
        $this->assertContentIdSearch($publishedContent->contentInfo->id, 1);
570
    }
571
572
    /**
573
     * Test copied content is available for search.
574
     */
575
    public function testCopyContent()
576
    {
577
        $repository = $this->getRepository();
578
        $searchService = $repository->getSearchService();
579
        $contentService = $repository->getContentService();
580
        $locationService = $repository->getLocationService();
581
582
        $publishedContent = $this->createContentWithName('copyTest', [2]);
583
        $this->refreshSearch($repository);
584
        $criterion = new Criterion\FullText('copyTest');
585
        $query = new Query(['filter' => $criterion]);
586
        $result = $searchService->findContent($query);
587
        $this->assertCount(1, $result->searchHits);
588
589
        $copiedContent = $contentService->copyContent($publishedContent->contentInfo, $locationService->newLocationCreateStruct(2));
590
        $this->refreshSearch($repository);
591
        $result = $searchService->findContent($query);
592
        $this->assertCount(2, $result->searchHits);
593
594
        $this->assertContentIdSearch($publishedContent->contentInfo->id, 1);
595
        $this->assertContentIdSearch($copiedContent->contentInfo->id, 1);
596
    }
597
598
    /**
599
     * Test that setting object content state to locked and then unlocked does not affect search index.
600
     */
601
    public function testSetContentState()
602
    {
603
        $repository = $this->getRepository();
604
        $objectStateService = $repository->getObjectStateService();
605
606
        // get Object States
607
        $stateNotLocked = $objectStateService->loadObjectState(1);
608
        $stateLocked = $objectStateService->loadObjectState(2);
609
610
        $publishedContent = $this->createContentWithName('setContentStateTest', [2]);
611
        $objectStateService->setContentState($publishedContent->contentInfo, $stateLocked->getObjectStateGroup(), $stateLocked);
612
        $this->refreshSearch($repository);
613
614
        // Setting Content State to "locked" should not affect search index
615
        $this->assertContentIdSearch($publishedContent->contentInfo->id, 1);
616
617
        $objectStateService->setContentState($publishedContent->contentInfo, $stateNotLocked->getObjectStateGroup(), $stateNotLocked);
618
        $this->refreshSearch($repository);
619
620
        // Setting Content State back to "not locked" should not affect search index
621
        $this->assertContentIdSearch($publishedContent->contentInfo->id, 1);
622
    }
623
624
    /**
625
     * Check if FullText indexing works for special cases of text.
626
     *
627
     * @param string $text Content Item field value text (to be indexed)
628
     * @param string $searchForText text based on which Content Item should be found
629
     * @param array $ignoreForSetupFactories list of SetupFactories to be ignored
630
     * @dataProvider getSpecialFullTextCases
631
     */
632
    public function testIndexingSpecialFullTextCases($text, $searchForText, array $ignoreForSetupFactories = [])
633
    {
634
        // check if provided data should be ignored for the current Search Engine (via SetupFactory)
635
        if (!empty($ignoreForSetupFactories) && in_array(get_class($this->getSetupFactory()), $ignoreForSetupFactories)) {
636
            $this->markTestIncomplete(sprintf(
637
                'Handling FullText Searching for the phrase {%s} is incomplete for %s',
638
                $searchForText,
639
                get_class($this->getSetupFactory())
640
            ));
641
        }
642
643
        $repository = $this->getRepository();
644
        $searchService = $repository->getSearchService();
645
646
        $content = $this->createContentWithName($text, [2]);
647
        $this->refreshSearch($repository);
648
649
        $criterion = new Criterion\FullText($searchForText);
650
        $query = new Query(['filter' => $criterion]);
651
        $result = $searchService->findContent($query);
652
653
        // for some cases there might be more than one hit, so check if proper one was found
654
        foreach ($result->searchHits as $searchHit) {
655
            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...
656
                return;
657
            }
658
        }
659
        $this->fail('Failed to find required Content in search results');
660
    }
661
662
    /**
663
     * Data Provider for {@see testIndexingSpecialFullTextCases()} method.
664
     *
665
     * @return array
666
     */
667
    public function getSpecialFullTextCases()
668
    {
669
        return [
670
            ['UPPERCASE TEXT', 'uppercase text'],
671
            ['lowercase text', 'LOWERCASE TEXT'],
672
            ['text-with-hyphens', 'text-with-hyphens'],
673
            ['text containing spaces', 'text containing spaces'],
674
            ['"quoted text"', 'quoted text'],
675
            ['ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝ', 'àáâãäåçèéêëìíîïðñòóôõöøùúûüý'],
676
            ['with boundary.', 'with boundary'],
677
            // @todo: Remove as soon as elastic is updated to later version not affected
678
            ["it's", "it's", [LegacyElasticsearch::class]],
679
            ['with_underscore', 'with_underscore'],
680
        ];
681
    }
682
683
    /**
684
     * Test updating Content field value with empty value removes it from search index.
685
     */
686
    public function testRemovedContentFieldValueIsNotFound()
687
    {
688
        $repository = $this->getRepository();
689
        $contentService = $repository->getContentService();
690
        $searchService = $repository->getSearchService();
691
        $publishedContent = $this->createContentWithNameAndDescription('testRemovedContentFieldValueIsNotFound', 'descriptionToBeRemoved', [2]);
692
        $this->refreshSearch($repository);
693
694
        $contentDraft = $contentService->createContentDraft($publishedContent->contentInfo);
695
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
696
        $contentUpdateStruct->setField('description', null);
697
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
698
        $contentService->publishVersion($contentDraft->versionInfo);
699
        $this->refreshSearch($repository);
700
701
        // Removed field value should not be found
702
        $criterion = new Criterion\FullText('descriptionToBeRemoved');
703
        $query = new Query(['filter' => $criterion]);
704
        $results = $searchService->findContent($query);
705
        $this->assertEquals(0, $results->totalCount);
706
707
        // Should be found
708
        $criterion = new Criterion\FullText('testRemovedContentFieldValueIsNotFound');
709
        $query = new Query(['filter' => $criterion]);
710
        $results = $searchService->findContent($query);
711
        $this->assertEquals(1, $results->totalCount);
712
    }
713
714
    /**
715
     * Check if children locations are/are not ivisible.
716
     *
717
     * @param \eZ\Publish\API\Repository\SearchService $searchService
718
     * @param int $parentLocationId parent location Id
719
     * @param bool $expected expected value of {invisible} property in subtree
720
     */
721
    private function assertSubtreeInvisibleProperty(SearchService $searchService, $parentLocationId, $expected)
722
    {
723
        $criterion = new Criterion\ParentLocationId($parentLocationId);
724
        $query = new LocationQuery(array('filter' => $criterion));
725
        $result = $searchService->findLocations($query);
726
        foreach ($result->searchHits as $searchHit) {
727
            $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...
728
            // Perform recursive check for children locations
729
            $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...
730
        }
731
    }
732
733
    /**
734
     * Test that swapping locations affects properly Search Engine Index.
735
     */
736
    public function testSwapLocation()
737
    {
738
        $repository = $this->getRepository();
739
        $locationService = $repository->getLocationService();
740
        $searchService = $repository->getSearchService();
741
742
        $content01 = $this->createContentWithName('content01', [2]);
743
        $location01 = $locationService->loadLocation($content01->contentInfo->mainLocationId);
744
745
        $content02 = $this->createContentWithName('content02', [2]);
746
        $location02 = $locationService->loadLocation($content02->contentInfo->mainLocationId);
747
748
        $locationService->swapLocation($location01, $location02);
749
        $this->refreshSearch($repository);
750
751
        // content02 should be at location01
752
        $criterion = new Criterion\LocationId($location01->id);
753
        $query = new Query(['filter' => $criterion]);
754
        $results = $searchService->findContent($query);
755
        $this->assertEquals(1, $results->totalCount);
756
        $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...
757
758
        // content01 should be at location02
759
        $criterion = new Criterion\LocationId($location02->id);
760
        $query = new Query(['filter' => $criterion]);
761
        $results = $searchService->findContent($query);
762
        $this->assertEquals(1, $results->totalCount);
763
        $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...
764
    }
765
766
    /**
767
     * Test that updating Content metadata affects properly Search Engine Index.
768
     */
769
    public function testUpdateContentMetadata()
770
    {
771
        $repository = $this->getRepository();
772
        $contentService = $repository->getContentService();
773
        $locationService = $repository->getLocationService();
774
        $searchService = $repository->getSearchService();
775
776
        $publishedContent = $this->createContentWithName('updateMetadataTest', [2]);
777
        $originalMainLocationId = $publishedContent->contentInfo->mainLocationId;
778
        $newLocationCreateStruct = $locationService->newLocationCreateStruct(60);
779
        $newLocation = $locationService->createLocation($publishedContent->contentInfo, $newLocationCreateStruct);
780
781
        $newContentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
782
        $newContentMetadataUpdateStruct->remoteId = md5('Test');
783
        $newContentMetadataUpdateStruct->publishedDate = new \DateTime();
784
        $newContentMetadataUpdateStruct->publishedDate->add(new \DateInterval('P1D'));
785
        $newContentMetadataUpdateStruct->mainLocationId = $newLocation->id;
786
787
        $contentService->updateContentMetadata($publishedContent->contentInfo, $newContentMetadataUpdateStruct);
788
        $this->refreshSearch($repository);
789
790
        // find Content by Id, calling findContentInfo which is using the Search Index
791
        $criterion = new Criterion\ContentId($publishedContent->id);
792
        $query = new Query(['filter' => $criterion]);
793
        $results = $searchService->findContentInfo($query);
794
        $this->assertEquals(1, $results->totalCount);
795
        $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...
796
797
        // find Content using updated RemoteId
798
        $criterion = new Criterion\RemoteId($newContentMetadataUpdateStruct->remoteId);
799
        $query = new Query(['filter' => $criterion]);
800
        $results = $searchService->findContent($query);
801
        $this->assertEquals(1, $results->totalCount);
802
        $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...
803
        /** @var \eZ\Publish\Core\Repository\Values\Content\Content $foundContentInfo */
804
        $this->assertEquals($publishedContent->id, $foundContentInfo->id);
805
        $this->assertEquals($newContentMetadataUpdateStruct->publishedDate, $foundContentInfo->publishedDate);
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...
806
        $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...
807
        $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...
808
809
        // find Content using old main location
810
        $criterion = new Criterion\LocationId($originalMainLocationId);
811
        $query = new LocationQuery(['filter' => $criterion]);
812
        $results = $searchService->findLocations($query);
813
        $this->assertEquals(1, $results->totalCount);
814
        $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...
815
    }
816
817
    /**
818
     * Test that updating Content Draft metadata does not affect Search Engine Index.
819
     */
820
    public function testUpdateContentDraftMetadataIsNotIndexed()
821
    {
822
        $repository = $this->getRepository();
823
        $contentService = $repository->getContentService();
824
        $locationService = $repository->getLocationService();
825
826
        $testableContentType = $this->createTestContentType();
827
        $rootContentStruct = $contentService->newContentCreateStruct($testableContentType, 'eng-GB');
828
        $rootContentStruct->setField('name', 'TestUpdatingContentDraftMetadata');
829
830
        $contentDraft = $contentService->createContent($rootContentStruct, [$locationService->newLocationCreateStruct(2)]);
831
832
        $newContentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
833
        $newContentMetadataUpdateStruct->ownerId = 10;
834
        $newContentMetadataUpdateStruct->remoteId = md5('Test');
835
836
        $contentService->updateContentMetadata($contentDraft->contentInfo, $newContentMetadataUpdateStruct);
837
838
        $this->refreshSearch($repository);
839
        $this->assertContentIdSearch($contentDraft->contentInfo->id, 0);
840
    }
841
842
    /**
843
     * Test that assigning section to content object properly affects Search Engine Index.
844
     */
845
    public function testAssignSection()
846
    {
847
        $repository = $this->getRepository();
848
        $sectionService = $repository->getSectionService();
849
        $searchService = $repository->getSearchService();
850
851
        $section = $sectionService->loadSection(2);
852
        $content = $this->createContentWithName('testAssignSection', [2]);
853
854
        $sectionService->assignSection($content->contentInfo, $section);
855
        $this->refreshSearch($repository);
856
857
        $criterion = new Criterion\ContentId($content->id);
858
        $query = new Query(['filter' => $criterion]);
859
        $results = $searchService->findContentInfo($query);
860
        $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...
861
    }
862
863
    /**
864
     * Will create if not exists a simple content type for test purposes with just one required field name.
865
     *
866
     * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType
867
     */
868
    protected function createTestContentType()
869
    {
870
        $repository = $this->getRepository();
871
        $contentTypeService = $repository->getContentTypeService();
872
        $contentTypeIdentifier = 'test-type';
873
        try {
874
            return $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
875
        } catch (NotFoundException $e) {
876
            // continue creation process
877
        }
878
879
        $nameField = $contentTypeService->newFieldDefinitionCreateStruct('name', 'ezstring');
880
        $nameField->fieldGroup = 'main';
881
        $nameField->position = 1;
882
        $nameField->isTranslatable = true;
883
        $nameField->isSearchable = true;
884
        $nameField->isRequired = true;
885
886
        $contentTypeStruct = $contentTypeService->newContentTypeCreateStruct($contentTypeIdentifier);
887
        $contentTypeStruct->mainLanguageCode = 'eng-GB';
888
        $contentTypeStruct->creatorId = 14;
889
        $contentTypeStruct->creationDate = new DateTime();
890
        $contentTypeStruct->names = ['eng-GB' => 'Test Content Type'];
891
        $contentTypeStruct->addFieldDefinition($nameField);
892
893
        $contentTypeGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
894
895
        $contentTypeDraft = $contentTypeService->createContentType($contentTypeStruct, [$contentTypeGroup]);
896
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
897
898
        return $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
899
    }
900
901
    /**
902
     * Will create and publish an content with a filed with a given content name in location provided into
903
     * $parentLocationIdList.
904
     *
905
     * @param string $contentName
906
     * @param array $parentLocationIdList
907
     *
908
     * @return \eZ\Publish\API\Repository\Values\Content\Content
909
     */
910
    protected function createContentWithName($contentName, array $parentLocationIdList = array())
911
    {
912
        $contentService = $this->getRepository()->getContentService();
913
        $locationService = $this->getRepository()->getLocationService();
914
915
        $testableContentType = $this->createTestContentType();
916
917
        $rootContentStruct = $contentService->newContentCreateStruct($testableContentType, 'eng-GB');
918
        $rootContentStruct->setField('name', $contentName);
919
920
        $parentLocationList = [];
921
        foreach ($parentLocationIdList as $locationID) {
922
            $parentLocationList[] = $locationService->newLocationCreateStruct($locationID);
923
        }
924
925
        $contentDraft = $contentService->createContent($rootContentStruct, $parentLocationList);
926
        $publishedContent = $contentService->publishVersion($contentDraft->getVersionInfo());
927
928
        return $publishedContent;
929
    }
930
931
    /**
932
     * Create and publish a content with filled name and description fields in location provided into
933
     * $parentLocationIdList.
934
     *
935
     * @param string $contentName
936
     * @param $contentDescription
937
     * @param array $parentLocationIdList
938
     *
939
     * @return \eZ\Publish\API\Repository\Values\Content\Content
940
     */
941
    protected function createContentWithNameAndDescription($contentName, $contentDescription, array $parentLocationIdList = [])
942
    {
943
        $repository = $this->getRepository();
944
        $contentService = $repository->getContentService();
945
        $contentTypeService = $repository->getContentTypeService();
946
        $publishedContent = $this->createContentWithName($contentName, $parentLocationIdList);
947
        $descriptionField = $contentTypeService->newFieldDefinitionCreateStruct('description', 'ezstring');
948
        $descriptionField->fieldGroup = 'main';
949
        $descriptionField->position = 2;
950
        $descriptionField->isTranslatable = true;
951
        $descriptionField->isSearchable = true;
952
        $descriptionField->isRequired = false;
953
        $contentType = $contentTypeService->loadContentType($publishedContent->contentInfo->contentTypeId);
954
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
955
        $contentTypeService->addFieldDefinition($contentTypeDraft, $descriptionField);
956
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
957
        $contentDraft = $contentService->createContentDraft($publishedContent->contentInfo);
958
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
959
        $contentUpdateStruct->setField('description', $contentDescription);
960
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
961
962
        return $contentService->publishVersion($contentDraft->versionInfo);
963
    }
964
965
    /**
966
     * Asserts an content id if it exists still in the solr core.
967
     *
968
     * @param int $contentId
969
     * @param int $expectedCount
970
     */
971
    protected function assertContentIdSearch($contentId, $expectedCount)
972
    {
973
        $searchService = $this->getRepository()->getSearchService();
974
975
        $criterion = new Criterion\ContentId($contentId);
976
        $query = new Query(array('filter' => $criterion));
977
        $result = $searchService->findContent($query);
978
979
        $this->assertEquals($expectedCount, $result->totalCount);
980
        if ($expectedCount == 0) {
981
            return;
982
        }
983
984
        $this->assertEquals(
985
            $contentId,
986
            $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...
987
        );
988
    }
989
990
    /**
991
     * Create & get new Location for tests.
992
     *
993
     * @return \eZ\Publish\API\Repository\Values\Content\Location
994
     */
995
    protected function createNewTestLocation()
996
    {
997
        $repository = $this->getRepository();
998
        $locationService = $repository->getLocationService();
999
        $contentService = $repository->getContentService();
1000
1001
        $rootLocationId = 2;
1002
        $membersContentId = 11;
1003
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
1004
1005
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
1006
1007
        return $locationService->createLocation($membersContentInfo, $locationCreateStruct);
1008
    }
1009
}
1010