Completed
Push — 6.5 ( b8bacb...a330c2 )
by André
47:40 queued 18:15
created

testUpdateContentMetadata()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 47
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 35
nc 1
nop 0
dl 0
loc 47
rs 9.0303
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the eZ Publish Kernel package.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 *
9
 * @version //autogentag//
10
 */
11
namespace eZ\Publish\API\Repository\Tests;
12
13
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
14
use eZ\Publish\API\Repository\SearchService;
15
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
16
use eZ\Publish\API\Repository\Values\Content\Query;
17
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
18
use DateTime;
19
20
/**
21
 * Test case for indexing operations with a search engine.
22
 *
23
 * @group integration
24
 * @group search
25
 * @group indexing
26
 */
27
class SearchEngineIndexingTest extends BaseTest
28
{
29
    /**
30
     * EZP-26186: Make sure index is NOT deleted on removal of version draft (affected Solr & content index on Elastic).
31
     */
32
    public function testDeleteVersion()
33
    {
34
        $repository = $this->getRepository();
35
        $contentService = $repository->getContentService();
36
        $searchService = $repository->getSearchService();
37
38
        $membersContentId = $this->generateId('content', 11);
39
        $contentInfo = $contentService->loadContentInfo($membersContentId);
40
41
        $draft = $contentService->createContentDraft($contentInfo);
42
        $contentService->deleteVersion($draft->getVersionInfo());
43
44
        $this->refreshSearch($repository);
45
46
        // Found
47
        $criterion = new Criterion\LocationId($contentInfo->mainLocationId);
48
        $query = new Query(array('filter' => $criterion));
49
        $result = $searchService->findContentInfo($query);
50
        $this->assertEquals(1, $result->totalCount);
51
        $this->assertEquals(
52
            $contentInfo->id,
53
            $result->searchHits[0]->valueObject->id
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

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