Completed
Push — master ( 0cfd9b...0455f1 )
by André
27:37
created

SearchEngineIndexingTest::testCopySubtree()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 46
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 34
nc 1
nop 0
dl 0
loc 46
rs 8.9411
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
     * Test updating Content field value with empty value removes it from search index.
671
     */
672
    public function testRemovedContentFieldValueIsNotFound()
673
    {
674
        $repository = $this->getRepository();
675
        $contentService = $repository->getContentService();
676
        $searchService = $repository->getSearchService();
677
        $publishedContent = $this->createContentWithNameAndDescription('testRemovedContentFieldValueIsNotFound', 'descriptionToBeRemoved', [2]);
678
        $this->refreshSearch($repository);
679
680
        $contentDraft = $contentService->createContentDraft($publishedContent->contentInfo);
681
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
682
        $contentUpdateStruct->setField('description', null);
683
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
684
        $contentService->publishVersion($contentDraft->versionInfo);
685
        $this->refreshSearch($repository);
686
687
        // Removed field value should not be found
688
        $criterion = new Criterion\FullText('descriptionToBeRemoved');
689
        $query = new Query(['filter' => $criterion]);
690
        $results = $searchService->findContent($query);
691
        $this->assertEquals(0, $results->totalCount);
692
693
        // Should be found
694
        $criterion = new Criterion\FullText('testRemovedContentFieldValueIsNotFound');
695
        $query = new Query(['filter' => $criterion]);
696
        $results = $searchService->findContent($query);
697
        $this->assertEquals(1, $results->totalCount);
698
    }
699
700
    /**
701
     * Check if children locations are/are not ivisible.
702
     *
703
     * @param \eZ\Publish\API\Repository\SearchService $searchService
704
     * @param int $parentLocationId parent location Id
705
     * @param bool $expected expected value of {invisible} property in subtree
706
     */
707
    private function assertSubtreeInvisibleProperty(SearchService $searchService, $parentLocationId, $expected)
708
    {
709
        $criterion = new Criterion\ParentLocationId($parentLocationId);
710
        $query = new LocationQuery(array('filter' => $criterion));
711
        $result = $searchService->findLocations($query);
712
        foreach ($result->searchHits as $searchHit) {
713
            $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...
714
            // Perform recursive check for children locations
715
            $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...
716
        }
717
    }
718
719
    /**
720
     * Test that swapping locations affects properly Search Engine Index.
721
     */
722
    public function testSwapLocation()
723
    {
724
        $repository = $this->getRepository();
725
        $locationService = $repository->getLocationService();
726
        $searchService = $repository->getSearchService();
727
728
        $content01 = $this->createContentWithName('content01', [2]);
729
        $location01 = $locationService->loadLocation($content01->contentInfo->mainLocationId);
730
731
        $content02 = $this->createContentWithName('content02', [2]);
732
        $location02 = $locationService->loadLocation($content02->contentInfo->mainLocationId);
733
734
        $locationService->swapLocation($location01, $location02);
735
        $this->refreshSearch($repository);
736
737
        // content02 should be at location01
738
        $criterion = new Criterion\LocationId($location01->id);
739
        $query = new Query(['filter' => $criterion]);
740
        $results = $searchService->findContent($query);
741
        $this->assertEquals(1, $results->totalCount);
742
        $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...
743
744
        // content01 should be at location02
745
        $criterion = new Criterion\LocationId($location02->id);
746
        $query = new Query(['filter' => $criterion]);
747
        $results = $searchService->findContent($query);
748
        $this->assertEquals(1, $results->totalCount);
749
        $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...
750
    }
751
752
    /**
753
     * Test that updating Content metadata affects properly Search Engine Index.
754
     */
755
    public function testUpdateContentMetadata()
756
    {
757
        $repository = $this->getRepository();
758
        $contentService = $repository->getContentService();
759
        $locationService = $repository->getLocationService();
760
        $searchService = $repository->getSearchService();
761
762
        $publishedContent = $this->createContentWithName('updateMetadataTest', [2]);
763
        $newLocationCreateStruct = $locationService->newLocationCreateStruct(60);
764
        $newLocation = $locationService->createLocation($publishedContent->contentInfo, $newLocationCreateStruct);
765
766
        $newContentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
767
        $newContentMetadataUpdateStruct->remoteId = md5('Test');
768
        $newContentMetadataUpdateStruct->publishedDate = new \DateTime();
769
        $newContentMetadataUpdateStruct->publishedDate->add(new \DateInterval('P1D'));
770
        $newContentMetadataUpdateStruct->mainLocationId = $newLocation->id;
771
772
        $contentService->updateContentMetadata($publishedContent->contentInfo, $newContentMetadataUpdateStruct);
773
        $this->refreshSearch($repository);
774
775
        // find Content by Id, calling findContentInfo which is using the Search Index
776
        $criterion = new Criterion\ContentId($publishedContent->id);
777
        $query = new Query(['filter' => $criterion]);
778
        $results = $searchService->findContentInfo($query);
779
        $this->assertEquals(1, $results->totalCount);
780
        $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...
781
782
        // find Content using updated RemoteId
783
        $criterion = new Criterion\RemoteId($newContentMetadataUpdateStruct->remoteId);
784
        $query = new Query(['filter' => $criterion]);
785
        $results = $searchService->findContent($query);
786
        $this->assertEquals(1, $results->totalCount);
787
        $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...
788
        /** @var \eZ\Publish\Core\Repository\Values\Content\Content $foundContentInfo */
789
        $this->assertEquals($publishedContent->id, $foundContentInfo->id);
790
        $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...
791
        $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...
792
        $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...
793
    }
794
795
    /**
796
     * Test that assigning section to content object properly affects Search Engine Index.
797
     */
798
    public function testAssignSection()
799
    {
800
        $repository = $this->getRepository();
801
        $sectionService = $repository->getSectionService();
802
        $searchService = $repository->getSearchService();
803
804
        $section = $sectionService->loadSection(2);
805
        $content = $this->createContentWithName('testAssignSection', [2]);
806
807
        $sectionService->assignSection($content->contentInfo, $section);
808
        $this->refreshSearch($repository);
809
810
        $criterion = new Criterion\ContentId($content->id);
811
        $query = new Query(['filter' => $criterion]);
812
        $results = $searchService->findContentInfo($query);
813
        $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...
814
    }
815
816
    /**
817
     * Will create if not exists a simple content type for test purposes with just one required field name.
818
     *
819
     * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType
820
     */
821
    protected function createTestContentType()
822
    {
823
        $repository = $this->getRepository();
824
        $contentTypeService = $repository->getContentTypeService();
825
        $contentTypeIdentifier = 'test-type';
826
        try {
827
            return $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
828
        } catch (NotFoundException $e) {
829
            // continue creation process
830
        }
831
832
        $nameField = $contentTypeService->newFieldDefinitionCreateStruct('name', 'ezstring');
833
        $nameField->fieldGroup = 'main';
834
        $nameField->position = 1;
835
        $nameField->isTranslatable = true;
836
        $nameField->isSearchable = true;
837
        $nameField->isRequired = true;
838
839
        $contentTypeStruct = $contentTypeService->newContentTypeCreateStruct($contentTypeIdentifier);
840
        $contentTypeStruct->mainLanguageCode = 'eng-GB';
841
        $contentTypeStruct->creatorId = 14;
842
        $contentTypeStruct->creationDate = new DateTime();
843
        $contentTypeStruct->names = ['eng-GB' => 'Test Content Type'];
844
        $contentTypeStruct->addFieldDefinition($nameField);
845
846
        $contentTypeGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
847
848
        $contentTypeDraft = $contentTypeService->createContentType($contentTypeStruct, [$contentTypeGroup]);
849
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
850
851
        return $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
852
    }
853
854
    /**
855
     * Will create and publish an content with a filed with a given content name in location provided into
856
     * $parentLocationIdList.
857
     *
858
     * @param string $contentName
859
     * @param array $parentLocationIdList
860
     *
861
     * @return \eZ\Publish\API\Repository\Values\Content\Content
862
     */
863
    protected function createContentWithName($contentName, array $parentLocationIdList = array())
864
    {
865
        $contentService = $this->getRepository()->getContentService();
866
        $locationService = $this->getRepository()->getLocationService();
867
868
        $testableContentType = $this->createTestContentType();
869
870
        $rootContentStruct = $contentService->newContentCreateStruct($testableContentType, 'eng-GB');
871
        $rootContentStruct->setField('name', $contentName);
872
873
        $parentLocationList = [];
874
        foreach ($parentLocationIdList as $locationID) {
875
            $parentLocationList[] = $locationService->newLocationCreateStruct($locationID);
876
        }
877
878
        $contentDraft = $contentService->createContent($rootContentStruct, $parentLocationList);
879
        $publishedContent = $contentService->publishVersion($contentDraft->getVersionInfo());
880
881
        return $publishedContent;
882
    }
883
884
    /**
885
     * Create and publish a content with filled name and description fields in location provided into
886
     * $parentLocationIdList.
887
     *
888
     * @param string $contentName
889
     * @param $contentDescription
890
     * @param array $parentLocationIdList
891
     *
892
     * @return \eZ\Publish\API\Repository\Values\Content\Content
893
     */
894
    protected function createContentWithNameAndDescription($contentName, $contentDescription, array $parentLocationIdList = [])
895
    {
896
        $repository = $this->getRepository();
897
        $contentService = $repository->getContentService();
898
        $contentTypeService = $repository->getContentTypeService();
899
        $publishedContent = $this->createContentWithName($contentName, $parentLocationIdList);
900
        $descriptionField = $contentTypeService->newFieldDefinitionCreateStruct('description', 'ezstring');
901
        $descriptionField->fieldGroup = 'main';
902
        $descriptionField->position = 2;
903
        $descriptionField->isTranslatable = true;
904
        $descriptionField->isSearchable = true;
905
        $descriptionField->isRequired = false;
906
        $contentType = $contentTypeService->loadContentType($publishedContent->contentInfo->contentTypeId);
907
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
908
        $contentTypeService->addFieldDefinition($contentTypeDraft, $descriptionField);
909
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
910
        $contentDraft = $contentService->createContentDraft($publishedContent->contentInfo);
911
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
912
        $contentUpdateStruct->setField('description', $contentDescription);
913
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
914
915
        return $contentService->publishVersion($contentDraft->versionInfo);
916
    }
917
918
    /**
919
     * Asserts an content id if it exists still in the solr core.
920
     *
921
     * @param int $contentId
922
     * @param int $expectedCount
923
     */
924
    protected function assertContentIdSearch($contentId, $expectedCount)
925
    {
926
        $searchService = $this->getRepository()->getSearchService();
927
928
        $criterion = new Criterion\ContentId($contentId);
929
        $query = new Query(array('filter' => $criterion));
930
        $result = $searchService->findContent($query);
931
932
        $this->assertEquals($expectedCount, $result->totalCount);
933
        if ($expectedCount == 0) {
934
            return;
935
        }
936
937
        $this->assertEquals(
938
            $contentId,
939
            $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...
940
        );
941
    }
942
943
    /**
944
     * Create & get new Location for tests.
945
     *
946
     * @return \eZ\Publish\API\Repository\Values\Content\Location
947
     */
948
    protected function createNewTestLocation()
949
    {
950
        $repository = $this->getRepository();
951
        $locationService = $repository->getLocationService();
952
        $contentService = $repository->getContentService();
953
954
        $rootLocationId = 2;
955
        $membersContentId = 11;
956
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
957
958
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
959
960
        return $locationService->createLocation($membersContentInfo, $locationCreateStruct);
961
    }
962
}
963