Completed
Push — feature-EZP-25696 ( d6b5d6...ab4954 )
by André
356:19 queued 326:15
created

SearchEngineIndexingTest::testCreateUser()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

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