Completed
Push — test-EZP-26707-issearchable-fu... ( 54c9f1...f8a822 )
by
unknown
26:26 queued 13:16
created

testFindLocationsFullTextIsSearchable()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 15
nc 2
nop 1
dl 0
loc 28
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the eZ Publish Kernel package.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 *
9
 * @version //autogentag//
10
 */
11
namespace eZ\Publish\API\Repository\Tests;
12
13
use EzSystems\EzPlatformSolrSearchEngine\Tests\SetupFactory\LegacySetupFactory as LegacySolrSetupFactory;
14
use eZ\Publish\API\Repository\Tests\SetupFactory\LegacyElasticsearch as LegacyElasticsearchSetupFactory;
15
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
16
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
17
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
18
use eZ\Publish\API\Repository\Values\Content\Query;
19
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
20
use DateTime;
21
22
/**
23
 * Test case for indexing operations with a search engine.
24
 *
25
 * @group integration
26
 * @group search
27
 * @group indexing
28
 */
29
class SearchEngineIndexingTest extends BaseTest
30
{
31
    /**
32
     * EZP-26186: Make sure index is NOT deleted on removal of version draft (affected Solr & content index on Elastic).
33
     */
34
    public function testDeleteVersion()
35
    {
36
        $repository = $this->getRepository();
37
        $contentService = $repository->getContentService();
38
        $searchService = $repository->getSearchService();
39
40
        $membersContentId = $this->generateId('content', 11);
41
        $contentInfo = $contentService->loadContentInfo($membersContentId);
42
43
        $draft = $contentService->createContentDraft($contentInfo);
44
        $contentService->deleteVersion($draft->getVersionInfo());
45
46
        $this->refreshSearch($repository);
47
48
        // Found
49
        $criterion = new Criterion\LocationId($contentInfo->mainLocationId);
50
        $query = new Query(array('filter' => $criterion));
51
        $result = $searchService->findContentInfo($query);
52
        $this->assertEquals(1, $result->totalCount);
53
        $this->assertEquals(
54
            $contentInfo->id,
55
            $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...
56
        );
57
    }
58
59
    /**
60
     * EZP-26186: Make sure affected child locations are deleted on content deletion (affected Solr & Elastic).
61
     */
62
    public function testDeleteContent()
63
    {
64
        $repository = $this->getRepository();
65
        $contentService = $repository->getContentService();
66
        $searchService = $repository->getSearchService();
67
68
        $anonymousUsersContentId = $this->generateId('content', 42);
69
        $contentInfo = $contentService->loadContentInfo($anonymousUsersContentId);
70
71
        $contentService->deleteContent($contentInfo);
72
73
        $this->refreshSearch($repository);
74
75
        // Should not be found
76
        $criterion = new Criterion\ParentLocationId($contentInfo->mainLocationId);
77
        $query = new LocationQuery(array('filter' => $criterion));
78
        $result = $searchService->findLocations($query);
79
        $this->assertEquals(0, $result->totalCount);
80
    }
81
82
    public function testCreateLocation()
83
    {
84
        $repository = $this->getRepository();
85
        $locationService = $repository->getLocationService();
86
        $contentService = $repository->getContentService();
87
        $searchService = $repository->getSearchService();
88
89
        $rootLocationId = 2;
90
        $membersContentId = 11;
91
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
92
93
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
94
        $membersLocation = $locationService->createLocation($membersContentInfo, $locationCreateStruct);
95
96
        $this->refreshSearch($repository);
97
98
        // Found
99
        $criterion = new Criterion\LocationId($membersLocation->id);
100
        $query = new LocationQuery(array('filter' => $criterion));
101
        $result = $searchService->findLocations($query);
102
        $this->assertEquals(1, $result->totalCount);
103
        $this->assertEquals(
104
            $membersLocation->id,
105
            $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...
106
        );
107
    }
108
109
    public function testMoveSubtree()
110
    {
111
        $repository = $this->getRepository();
112
        $locationService = $repository->getLocationService();
113
        $contentService = $repository->getContentService();
114
        $searchService = $repository->getSearchService();
115
116
        $rootLocationId = 2;
117
        $membersContentId = 11;
118
        $adminsContentId = 12;
119
        $editorsContentId = 13;
120
        $membersContentInfo = $contentService->loadContentInfo($membersContentId);
121
        $adminsContentInfo = $contentService->loadContentInfo($adminsContentId);
122
        $editorsContentInfo = $contentService->loadContentInfo($editorsContentId);
123
124
        $locationCreateStruct = $locationService->newLocationCreateStruct($rootLocationId);
125
        $membersLocation = $locationService->createLocation($membersContentInfo, $locationCreateStruct);
126
        $editorsLocation = $locationService->createLocation($editorsContentInfo, $locationCreateStruct);
127
        $adminsLocation = $locationService->createLocation(
128
            $adminsContentInfo,
129
            $locationService->newLocationCreateStruct($membersLocation->id)
130
        );
131
132
        $this->refreshSearch($repository);
133
134
        // Not found under Editors
135
        $criterion = new Criterion\ParentLocationId($editorsLocation->id);
136
        $query = new LocationQuery(array('filter' => $criterion));
137
        $result = $searchService->findLocations($query);
138
        $this->assertEquals(0, $result->totalCount);
139
140
        // Found under Members
141
        $criterion = new Criterion\ParentLocationId($membersLocation->id);
142
        $query = new LocationQuery(array('filter' => $criterion));
143
        $result = $searchService->findLocations($query);
144
        $this->assertEquals(1, $result->totalCount);
145
        $this->assertEquals(
146
            $adminsLocation->id,
147
            $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...
148
        );
149
150
        $locationService->moveSubtree($adminsLocation, $editorsLocation);
151
        $this->refreshSearch($repository);
152
153
        // Found under Editors
154
        $criterion = new Criterion\ParentLocationId($editorsLocation->id);
155
        $query = new LocationQuery(array('filter' => $criterion));
156
        $result = $searchService->findLocations($query);
157
        $this->assertEquals(1, $result->totalCount);
158
        $this->assertEquals(
159
            $adminsLocation->id,
160
            $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...
161
        );
162
163
        // Not found under Members
164
        $criterion = new Criterion\ParentLocationId($membersLocation->id);
165
        $query = new LocationQuery(array('filter' => $criterion));
166
        $result = $searchService->findLocations($query);
167
        $this->assertEquals(0, $result->totalCount);
168
    }
169
170
    /**
171
     * Testing that content is indexed even when containing only fields with values
172
     * considered to be empty by the search engine.
173
     */
174
    public function testIndexContentWithNullField()
175
    {
176
        $repository = $this->getRepository();
177
        $contentService = $repository->getContentService();
178
        $contentTypeService = $repository->getContentTypeService();
179
        $searchService = $repository->getSearchService();
180
181
        $createStruct = $contentTypeService->newContentTypeCreateStruct('test-type');
182
        $createStruct->mainLanguageCode = 'eng-GB';
183
        $createStruct->names = array('eng-GB' => 'Test type');
184
        $createStruct->creatorId = 14;
185
        $createStruct->creationDate = new DateTime();
186
187
        $translatableFieldCreate = $contentTypeService->newFieldDefinitionCreateStruct(
188
            'integer',
189
            'ezinteger'
190
        );
191
        $translatableFieldCreate->names = array('eng-GB' => 'Simple translatable integer field');
192
        $translatableFieldCreate->fieldGroup = 'main';
193
        $translatableFieldCreate->position = 1;
194
        $translatableFieldCreate->isTranslatable = true;
195
        $translatableFieldCreate->isSearchable = true;
196
197
        $createStruct->addFieldDefinition($translatableFieldCreate);
198
199
        $contentGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
200
        $contentTypeDraft = $contentTypeService->createContentType(
201
            $createStruct,
202
            array($contentGroup)
203
        );
204
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
205
        $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...
206
207
        $createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
208
        $createStruct->alwaysAvailable = false;
209
        $createStruct->mainLanguageCode = 'eng-GB';
210
211
        $draft = $contentService->createContent($createStruct);
212
        $content = $contentService->publishVersion($draft->getVersionInfo());
213
214
        $this->refreshSearch($repository);
215
216
        // Found
217
        $criterion = new Criterion\ContentId($content->id);
218
        $query = new Query(array('filter' => $criterion));
219
        $result = $searchService->findContent($query);
220
        $this->assertEquals(1, $result->totalCount);
221
        $this->assertEquals(
222
            $content->id,
223
            $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...
224
        );
225
    }
226
227
    public function testUpdateLocation()
228
    {
229
        $repository = $this->getRepository();
230
        $locationService = $repository->getLocationService();
231
        $searchService = $repository->getSearchService();
232
233
        $rootLocationId = 2;
234
        $locationToUpdate = $locationService->loadLocation($rootLocationId);
235
236
        $criterion = new Criterion\LogicalAnd([
237
            new Criterion\LocationId($rootLocationId),
238
            new Criterion\Location\Priority(Criterion\Operator::GT, 0),
239
        ]);
240
241
        $query = new LocationQuery(array('filter' => $criterion));
242
        $result = $searchService->findLocations($query);
243
244
        $this->assertEquals(0, $result->totalCount);
245
246
        $locationUpdateStruct = $locationService->newLocationUpdateStruct();
247
        $locationUpdateStruct->priority = 4;
248
        $locationService->updateLocation($locationToUpdate, $locationUpdateStruct);
249
250
        $this->refreshSearch($repository);
251
252
        $result = $searchService->findLocations($query);
253
254
        $this->assertEquals(1, $result->totalCount);
255
        $this->assertEquals(
256
            $locationToUpdate->id,
257
            $result->searchHits[0]->valueObject->id
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<eZ\Publish\API\Re...ory\Values\ValueObject>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
258
        );
259
    }
260
261
    /**
262
     * Testing that content will be deleted with all of its subitems but subitems with additional location will stay as
263
     * they are.
264
     */
265
    public function testDeleteLocation()
266
    {
267
        $repository = $this->getRepository();
268
        $locationService = $repository->getLocationService();
269
270
        $treeContainerContent = $this->createContentWithName('Tree Container', [2]);
271
        $supposeBeDeletedSubItem = $this->createContentWithName(
272
            'Suppose to be deleted sub-item',
273
            [$treeContainerContent->contentInfo->mainLocationId]
274
        );
275
        $supposeSurviveSubItem = $this->createContentWithName(
276
            'Suppose to Survive Item',
277
            [2, $treeContainerContent->contentInfo->mainLocationId]
278
        );
279
280
        $treeContainerLocation = $locationService->loadLocation($treeContainerContent->contentInfo->mainLocationId);
281
282
        $this->refreshSearch($repository);
283
284
        $this->assertContentIdSearch($treeContainerContent->id, 1);
285
        $this->assertContentIdSearch($supposeSurviveSubItem->id, 1);
286
        $this->assertContentIdSearch($supposeBeDeletedSubItem->id, 1);
287
288
        $locationService->deleteLocation($treeContainerLocation);
289
290
        $this->refreshSearch($repository);
291
292
        $this->assertContentIdSearch($supposeSurviveSubItem->id, 1);
293
        $this->assertContentIdSearch($treeContainerContent->id, 0);
294
        $this->assertContentIdSearch($supposeBeDeletedSubItem->id, 0);
295
    }
296
297
    /**
298
     * Test that swapping locations affects properly Search Engine Index.
299
     */
300
    public function testSwapLocation()
301
    {
302
        $repository = $this->getRepository();
303
        $locationService = $repository->getLocationService();
304
        $searchService = $repository->getSearchService();
305
306
        $content01 = $this->createContentWithName('content01', [2]);
307
        $location01 = $locationService->loadLocation($content01->contentInfo->mainLocationId);
308
309
        $content02 = $this->createContentWithName('content02', [2]);
310
        $location02 = $locationService->loadLocation($content02->contentInfo->mainLocationId);
311
312
        $locationService->swapLocation($location01, $location02);
313
        $this->refreshSearch($repository);
314
315
        // content02 should be at location01
316
        $criterion = new Criterion\LocationId($location01->id);
317
        $query = new Query(['filter' => $criterion]);
318
        $results = $searchService->findContent($query);
319
        $this->assertEquals(1, $results->totalCount);
320
        $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...
321
322
        // content01 should be at location02
323
        $criterion = new Criterion\LocationId($location02->id);
324
        $query = new Query(['filter' => $criterion]);
325
        $results = $searchService->findContent($query);
326
        $this->assertEquals(1, $results->totalCount);
327
        $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...
328
    }
329
330
    /**
331
     * Test that updating Content metadata affects properly Search Engine Index.
332
     */
333
    public function testUpdateContentMetadata()
334
    {
335
        $repository = $this->getRepository();
336
        $contentService = $repository->getContentService();
337
        $locationService = $repository->getLocationService();
338
        $searchService = $repository->getSearchService();
339
340
        $publishedContent = $this->createContentWithName('updateMetadataTest', [2]);
341
        $newLocationCreateStruct = $locationService->newLocationCreateStruct(60);
342
        $newLocation = $locationService->createLocation($publishedContent->contentInfo, $newLocationCreateStruct);
343
344
        $newContentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
345
        $newContentMetadataUpdateStruct->remoteId = md5('Test');
346
        $newContentMetadataUpdateStruct->publishedDate = new \DateTime();
347
        $newContentMetadataUpdateStruct->publishedDate->add(new \DateInterval('P1D'));
348
        $newContentMetadataUpdateStruct->mainLocationId = $newLocation->id;
349
350
        $contentService->updateContentMetadata($publishedContent->contentInfo, $newContentMetadataUpdateStruct);
351
        $this->refreshSearch($repository);
352
353
        // find Content by Id, calling findContentInfo which is using the Search Index
354
        $criterion = new Criterion\ContentId($publishedContent->id);
355
        $query = new Query(['filter' => $criterion]);
356
        $results = $searchService->findContentInfo($query);
357
        $this->assertEquals(1, $results->totalCount);
358
        $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...
359
360
        // find Content using updated RemoteId
361
        $criterion = new Criterion\RemoteId($newContentMetadataUpdateStruct->remoteId);
362
        $query = new Query(['filter' => $criterion]);
363
        $results = $searchService->findContent($query);
364
        $this->assertEquals(1, $results->totalCount);
365
        $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...
366
        /** @var \eZ\Publish\Core\Repository\Values\Content\Content $foundContentInfo */
367
        $this->assertEquals($publishedContent->id, $foundContentInfo->id);
368
        $this->assertEquals($newContentMetadataUpdateStruct->publishedDate, $foundContentInfo->publishedDate);
0 ignored issues
show
Documentation introduced by
The property publishedDate does not exist on object<eZ\Publish\Core\R...Values\Content\Content>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
369
        $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...
370
        $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...
371
    }
372
373
    /**
374
     * Test that assigning section to content object properly affects Search Engine Index.
375
     */
376
    public function testAssignSection()
377
    {
378
        $repository = $this->getRepository();
379
        $sectionService = $repository->getSectionService();
380
        $searchService = $repository->getSearchService();
381
382
        $section = $sectionService->loadSection(2);
383
        $content = $this->createContentWithName('testAssignSection', [2]);
384
385
        $sectionService->assignSection($content->contentInfo, $section);
386
        $this->refreshSearch($repository);
387
388
        $criterion = new Criterion\ContentId($content->id);
389
        $query = new Query(['filter' => $criterion]);
390
        $results = $searchService->findContentInfo($query);
391
        $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...
392
    }
393
394
    /**
395
     * Will create if not exists an simple content type for test purposes with just one required field name.
396
     *
397
     * @return \eZ\Publish\API\Repository\Values\ContentType\ContentType
398
     */
399
    protected function createTestContentType()
400
    {
401
        $repository = $this->getRepository();
402
        $contentTypeService = $repository->getContentTypeService();
403
        $contentTypeIdentifier = 'test-type';
404
        try {
405
            return $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
406
        } catch (NotFoundException $e) {
407
            // continue creation process
408
        }
409
410
        $nameField = $contentTypeService->newFieldDefinitionCreateStruct('name', 'ezstring');
411
        $nameField->fieldGroup = 'main';
412
        $nameField->position = 1;
413
        $nameField->isTranslatable = true;
414
        $nameField->isSearchable = true;
415
        $nameField->isRequired = true;
416
        $contentTypeStruct = $contentTypeService->newContentTypeCreateStruct($contentTypeIdentifier);
417
        $contentTypeStruct->mainLanguageCode = 'eng-GB';
418
        $contentTypeStruct->creatorId = 14;
419
        $contentTypeStruct->creationDate = new DateTime();
420
        $contentTypeStruct->names = ['eng-GB' => 'Test Content Type'];
421
        $contentTypeStruct->addFieldDefinition($nameField);
422
423
        $contentTypeGroup = $contentTypeService->loadContentTypeGroupByIdentifier('Content');
424
425
        $contentTypeDraft = $contentTypeService->createContentType($contentTypeStruct, [$contentTypeGroup]);
426
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
427
428
        return $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
429
    }
430
431
    /**
432
     * Will create and publish an content with a filed with a given content name in location provided into
433
     * $parentLocationIdList.
434
     *
435
     * @param string $contentName
436
     * @param array $parentLocationIdList
437
     *
438
     * @return \eZ\Publish\API\Repository\Values\Content\Content
439
     */
440
    protected function createContentWithName($contentName, array $parentLocationIdList = array())
441
    {
442
        $contentService = $this->getRepository()->getContentService();
443
        $locationService = $this->getRepository()->getLocationService();
444
445
        $testableContentType = $this->createTestContentType();
446
447
        $rootContentStruct = $contentService->newContentCreateStruct($testableContentType, 'eng-GB');
448
        $rootContentStruct->setField('name', $contentName);
449
450
        $parentLocationList = [];
451
        foreach ($parentLocationIdList as $locationID) {
452
            $parentLocationList[] = $locationService->newLocationCreateStruct($locationID);
453
        }
454
455
        $contentDraft = $contentService->createContent($rootContentStruct, $parentLocationList);
456
        $publishedContent = $contentService->publishVersion($contentDraft->getVersionInfo());
457
458
        return $publishedContent;
459
    }
460
461
    /**
462
     * Asserts an content id if it exists still in the solr core.
463
     *
464
     * @param int $contentId
465
     * @param int $expectedCount
466
     */
467
    protected function assertContentIdSearch($contentId, $expectedCount)
468
    {
469
        $searchService = $this->getRepository()->getSearchService();
470
471
        $criterion = new Criterion\ContentId($contentId);
472
        $query = new Query(array('filter' => $criterion));
473
        $result = $searchService->findContent($query);
474
475
        $this->assertEquals($expectedCount, $result->totalCount);
476
        if ($expectedCount == 0) {
477
            return;
478
        }
479
480
        $this->assertEquals(
481
            $contentId,
482
            $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...
483
        );
484
    }
485
486
    /**
487
     * Test that indexing full text data depends on the isSearchable flag on the field definition.
488
     */
489
    public function testFindContentInfoFullTextIsSearchable()
490
    {
491
        $setupFactory = $this->getSetupFactory();
492
        if (!$setupFactory instanceof LegacySolrSetupFactory && !$setupFactory instanceof LegacyElasticsearch) {
0 ignored issues
show
Bug introduced by
The class EzSystems\EzPlatformSolr...tory\LegacySetupFactory does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
Bug introduced by
The class eZ\Publish\API\Repositor...sts\LegacyElasticsearch does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
493
            $this->markTestSkipped(
494
                'Legacy Search Engine is missing full text indexing implementation'
495
            );
496
        }
497
498
        $searchTerm = 'pamplemousse';
499
        $content = $this->createFullTextIsSearchableContent($searchTerm, true);
500
501
        $repository = $this->getRepository();
502
        $searchService = $repository->getSearchService();
503
504
        $query = new Query(
505
            [
506
                'query' => new Criterion\FullText($searchTerm),
507
            ]
508
        );
509
510
        $searchResult = $searchService->findContentInfo($query);
511
512
        $this->assertEquals(1, $searchResult->totalCount);
513
        $contentInfo = $searchResult->searchHits[0]->valueObject;
514
        $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...
515
516
        return $contentInfo;
517
    }
518
519
    /**
520
     * Test that indexing full text data depends on the isSearchable flag on the field definition.
521
     *
522
     * @depends testFindContentInfoFullTextIsSearchable
523
     *
524
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
525
     */
526
    public function testFindLocationsFullTextIsSearchable(ContentInfo $contentInfo)
527
    {
528
        $setupFactory = $this->getSetupFactory();
529
        if ($setupFactory instanceof LegacyElasticsearchSetupFactory) {
530
            $this->markTestSkipped(
531
                'Elasticsearch Search Engine is missing full text Location search implementation'
532
            );
533
        }
534
535
        $searchTerm = 'pamplemousse';
536
537
        $repository = $this->getRepository(false);
538
        $searchService = $repository->getSearchService();
539
540
        $query = new LocationQuery(
541
            [
542
                'query' => new Criterion\FullText($searchTerm),
543
            ]
544
        );
545
546
        $searchResult = $searchService->findLocations($query);
547
548
        $this->assertEquals(1, $searchResult->totalCount);
549
        $this->assertEquals(
550
            $contentInfo->mainLocationId,
551
            $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...
552
        );
553
    }
554
555
    /**
556
     * Test that indexing full text data depends on the isSearchable flag on the field definition.
557
     *
558
     * @depends testFindContentInfoFullTextIsSearchable
559
     */
560 View Code Duplication
    public function testFindContentInfoFullTextIsNotSearchable()
561
    {
562
        $searchTerm = 'pamplemousse';
563
        $this->createFullTextIsSearchableContent($searchTerm, false);
564
565
        $repository = $this->getRepository();
566
        $searchService = $repository->getSearchService();
567
568
        $query = new Query(
569
            [
570
                'query' => new Criterion\FullText($searchTerm),
571
            ]
572
        );
573
574
        $searchResult = $searchService->findContentInfo($query);
575
576
        $this->assertEquals(0, $searchResult->totalCount);
577
    }
578
579
    /**
580
     * Test that indexing full text data depends on the isSearchable flag on the field definition.
581
     *
582
     * @depends testFindLocationsFullTextIsSearchable
583
     */
584 View Code Duplication
    public function testFindLocationsFullTextIsNotSearchable()
585
    {
586
        $searchTerm = 'pamplemousse';
587
588
        $repository = $this->getRepository(false);
589
        $searchService = $repository->getSearchService();
590
591
        $query = new LocationQuery(
592
            [
593
                'query' => new Criterion\FullText($searchTerm),
594
            ]
595
        );
596
597
        $searchResult = $searchService->findLocations($query);
598
599
        $this->assertEquals(0, $searchResult->totalCount);
600
    }
601
602
    /**
603
     * Creates Content for testing full text search depending on the isSearchable flag.
604
     *
605
     * @see testFindContentInfoFullTextIsearchable
606
     * @see testFindLocationsFullTextIsSearchable
607
     * @see testFindContentInfoFullTextIsNotSearchable
608
     * @see testFindLocationsFullTextIsNotSearchable
609
     *
610
     * @param string $searchText
611
     * @param bool $isSearchable
612
     *
613
     * @return \eZ\Publish\API\Repository\Values\Content\Content
614
     */
615
    protected function createFullTextIsSearchableContent($searchText, $isSearchable)
616
    {
617
        $repository = $this->getRepository();
618
        $contentService = $repository->getContentService();
619
        $contentTypeService = $repository->getContentTypeService();
620
        $locationService = $repository->getLocationService();
621
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
622
623
        if (!$isSearchable) {
624
            $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
625
            $fieldDefinitionUpdateStruct = $contentTypeService->newFieldDefinitionUpdateStruct();
626
            $fieldDefinitionUpdateStruct->isSearchable = false;
627
628
            $fieldDefinition = $contentType->getFieldDefinition('name');
629
630
            $contentTypeService->updateFieldDefinition(
631
                $contentTypeDraft,
632
                $fieldDefinition,
633
                $fieldDefinitionUpdateStruct
634
            );
635
636
            $contentTypeService->publishContentTypeDraft($contentTypeDraft);
637
            $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
638
        }
639
640
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
641
642
        $contentCreateStruct->setField('name', $searchText);
643
        $contentCreateStruct->setField('short_name', 'hello world');
644
        $content = $contentService->publishVersion(
645
            $contentService->createContent(
646
                $contentCreateStruct,
647
                [$locationService->newLocationCreateStruct(2)]
648
            )->versionInfo
649
        );
650
651
        $this->refreshSearch($repository);
652
653
        return $content;
654
    }
655
}
656