Completed
Push — master ( a8052f...413f40 )
by André
20:01 queued 05:56
created

createMultiLanguageContent()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

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