Completed
Push — 6.5 ( c54d85...ba75da )
by André
36:08 queued 23:02
created

testRemovedContentFieldValueIsNotFound()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 20
nc 1
nop 0
dl 0
loc 27
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the eZ Publish Kernel package.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 *
9
 * @version //autogentag//
10
 */
11
namespace eZ\Publish\API\Repository\Tests;
12
13
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
14
use eZ\Publish\API\Repository\SearchService;
15
use eZ\Publish\API\Repository\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
    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
     * Test that a newly created user is available for search.
83
     */
84
    public function testCreateUser()
85
    {
86
        $repository = $this->getRepository();
87
        $userService = $repository->getUserService();
88
        $searchService = $repository->getSearchService();
89
90
        // ID of the "Editors" user group
91
        $editorsGroupId = 13;
92
        $userCreate = $userService->newUserCreateStruct(
93
            'user',
94
            '[email protected]',
95
            'secret',
96
            'eng-US'
97
        );
98
        $userCreate->enabled = true;
99
        $userCreate->setField('first_name', 'Example');
100
        $userCreate->setField('last_name', 'User');
101
102
        // Load parent group for the user
103
        $group = $userService->loadUserGroup($editorsGroupId);
104
105
        // Create a new user instance.
106
        $user = $userService->createUser($userCreate, array($group));
107
108
        $this->refreshSearch($repository);
109
110
        // Should be found
111
        $criterion = new Criterion\ContentId($user->id);
112
        $query = new Query(array('filter' => $criterion));
113
        $result = $searchService->findContentInfo($query);
114
        $this->assertEquals(1, $result->totalCount);
115
    }
116
117
    /**
118
     * Test that a newly created user group is available for search.
119
     */
120
    public function testCreateUserGroup()
121
    {
122
        $repository = $this->getRepository();
123
        $userService = $repository->getUserService();
124
        $searchService = $repository->getSearchService();
125
        $mainGroupId = $this->generateId('group', 4);
126
127
        $parentUserGroup = $userService->loadUserGroup($mainGroupId);
128
        $userGroupCreateStruct = $userService->newUserGroupCreateStruct('eng-GB');
129
        $userGroupCreateStruct->setField('name', 'Example Group');
130
131
        // Create a new user group
132
        $userGroup = $userService->createUserGroup(
133
            $userGroupCreateStruct,
134
            $parentUserGroup
135
        );
136
137
        $this->refreshSearch($repository);
138
139
        // Should be found
140
        $criterion = new Criterion\ContentId($userGroup->id);
141
        $query = new Query(array('filter' => $criterion));
142
        $result = $searchService->findContentInfo($query);
143
        $this->assertEquals(1, $result->totalCount);
144
    }
145
146
    /**
147
     * Test that a newly created Location is available for search.
148
     */
149
    public function testCreateLocation()
150
    {
151
        $repository = $this->getRepository();
152
        $searchService = $repository->getSearchService();
153
        $membersLocation = $this->createNewTestLocation();
154
155
        $this->refreshSearch($repository);
156
157
        // Found
158
        $criterion = new Criterion\LocationId($membersLocation->id);
159
        $query = new LocationQuery(array('filter' => $criterion));
160
        $result = $searchService->findLocations($query);
161
        $this->assertEquals(1, $result->totalCount);
162
        $this->assertEquals(
163
            $membersLocation->id,
164
            $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...
165
        );
166
    }
167
168
    /**
169
     * Test that hiding a Location makes it unavailable for search.
170
     */
171
    public function testHideSubtree()
172
    {
173
        $repository = $this->getRepository();
174
        $searchService = $repository->getSearchService();
175
176
        // 5 is the ID of an existing location
177
        $locationId = $this->generateId('location', 5);
178
        $locationService = $repository->getLocationService();
179
        $location = $locationService->loadLocation($locationId);
180
        $locationService->hideLocation($location);
181
        $this->refreshSearch($repository);
182
183
        // Check if parent location is hidden
184
        $criterion = new Criterion\LocationId($locationId);
185
        $query = new LocationQuery(array('filter' => $criterion));
186
        $result = $searchService->findLocations($query);
187
        $this->assertEquals(1, $result->totalCount);
188
        $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...
189
190
        // Check if children locations are invisible
191
        $this->assertSubtreeInvisibleProperty($searchService, $locationId, true);
192
    }
193
194
    /**
195
     * Test that hiding and revealing a Location makes it available for search.
196
     */
197
    public function testRevealSubtree()
198
    {
199
        $repository = $this->getRepository();
200
        $searchService = $repository->getSearchService();
201
202
        // 5 is the ID of an existing location
203
        $locationId = $this->generateId('location', 5);
204
        $locationService = $repository->getLocationService();
205
        $location = $locationService->loadLocation($locationId);
206
        $locationService->hideLocation($location);
207
        $this->refreshSearch($repository);
208
        $locationService->unhideLocation($location);
209
        $this->refreshSearch($repository);
210
211
        // Check if parent location is not hidden
212
        $criterion = new Criterion\LocationId($locationId);
213
        $query = new LocationQuery(array('filter' => $criterion));
214
        $result = $searchService->findLocations($query);
215
        $this->assertEquals(1, $result->totalCount);
216
        $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...
217
218
        // Check if children locations are not invisible
219
        $this->assertSubtreeInvisibleProperty($searchService, $locationId, false);
220
    }
221
222
    /**
223
     * Test that a copied subtree is available for search.
224
     */
225
    public function testCopySubtree()
226
    {
227
        $repository = $this->getRepository();
228
        $locationService = $repository->getLocationService();
229
        $contentService = $repository->getContentService();
230
        $searchService = $repository->getSearchService();
231
232
        $rootLocationId = 2;
233
        $membersContentId = 11;
234
        $adminsContentId = 12;
235
        $editorsContentId = 13;
236
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
237
        $adminsContentInfo = $contentService->loadContentInfo($adminsContentId);
238
        $editorsContentInfo = $contentService->loadContentInfo($editorsContentId);
239
240
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
241
        $membersLocation = $locationService->createLocation($membersContentInfo, $locationCreateStruct);
242
        $editorsLocation = $locationService->createLocation($editorsContentInfo, $locationCreateStruct);
243
        $adminsLocation = $locationService->createLocation(
244
            $adminsContentInfo,
245
            $locationService->newLocationCreateStruct($membersLocation->id)
246
        );
247
248
        $copiedLocation = $locationService->copySubtree($adminsLocation, $editorsLocation);
249
        $this->refreshSearch($repository);
250
251
        // Found under Members
252
        $criterion = new Criterion\ParentLocationId($membersLocation->id);
253
        $query = new LocationQuery(array('filter' => $criterion));
254
        $result = $searchService->findLocations($query);
255
        $this->assertEquals(1, $result->totalCount);
256
        $this->assertEquals(
257
            $adminsLocation->id,
258
            $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...
259
        );
260
261
        // Found under Editors
262
        $criterion = new Criterion\ParentLocationId($editorsLocation->id);
263
        $query = new LocationQuery(array('filter' => $criterion));
264
        $result = $searchService->findLocations($query);
265
        $this->assertEquals(1, $result->totalCount);
266
        $this->assertEquals(
267
            $copiedLocation->id,
268
            $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...
269
        );
270
    }
271
272
    /**
273
     * Test that moved subtree is available for search and found only under a specific parent Location.
274
     */
275
    public function testMoveSubtree()
276
    {
277
        $repository = $this->getRepository();
278
        $locationService = $repository->getLocationService();
279
        $contentService = $repository->getContentService();
280
        $searchService = $repository->getSearchService();
281
282
        $rootLocationId = 2;
283
        $membersContentId = 11;
284
        $adminsContentId = 12;
285
        $editorsContentId = 13;
286
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
287
        $adminsContentInfo = $contentService->loadContentInfo($adminsContentId);
288
        $editorsContentInfo = $contentService->loadContentInfo($editorsContentId);
289
290
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
291
        $membersLocation = $locationService->createLocation($membersContentInfo, $locationCreateStruct);
292
        $editorsLocation = $locationService->createLocation($editorsContentInfo, $locationCreateStruct);
293
        $adminsLocation = $locationService->createLocation(
294
            $adminsContentInfo,
295
            $locationService->newLocationCreateStruct($membersLocation->id)
296
        );
297
298
        $this->refreshSearch($repository);
299
300
        // Not found under Editors
301
        $criterion = new Criterion\ParentLocationId($editorsLocation->id);
302
        $query = new LocationQuery(array('filter' => $criterion));
303
        $result = $searchService->findLocations($query);
304
        $this->assertEquals(0, $result->totalCount);
305
306
        // Found under Members
307
        $criterion = new Criterion\ParentLocationId($membersLocation->id);
308
        $query = new LocationQuery(array('filter' => $criterion));
309
        $result = $searchService->findLocations($query);
310
        $this->assertEquals(1, $result->totalCount);
311
        $this->assertEquals(
312
            $adminsLocation->id,
313
            $result->searchHits[0]->valueObject->id
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

If the property has read access only, you can use the @property-read annotation instead.

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

See also the PhpDoc documentation for @property.

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