Completed
Push — 6.6 ( f44349...3dd0ff )
by André
43:44 queued 29:29
created

testIndexingSpecialFullTextCases()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

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