Completed
Push — EZP-30796 ( f39111...1b67d5 )
by
unknown
24:32
created

testCopyContentWithGivenVersion()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 56

Duplication

Lines 56
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 56
loc 56
rs 8.9599
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * File containing the ContentServiceTest class.
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\LocationService;
12
use eZ\Publish\API\Repository\Values\Content\Content;
13
use eZ\Publish\API\Repository\Exceptions\UnauthorizedException;
14
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
15
use eZ\Publish\API\Repository\Values\Content\ContentMetadataUpdateStruct;
16
use eZ\Publish\API\Repository\Values\Content\Field;
17
use eZ\Publish\API\Repository\Values\Content\Location;
18
use eZ\Publish\API\Repository\Values\Content\URLAlias;
19
use eZ\Publish\API\Repository\Values\Content\Relation;
20
use eZ\Publish\API\Repository\Values\Content\VersionInfo;
21
use eZ\Publish\API\Repository\Values\User\Limitation\SectionLimitation;
22
use eZ\Publish\API\Repository\Values\User\Limitation\LocationLimitation;
23
use eZ\Publish\API\Repository\Values\User\Limitation\ContentTypeLimitation;
24
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
25
use DOMDocument;
26
use Exception;
27
use eZ\Publish\Core\Repository\Values\Content\ContentUpdateStruct;
28
29
/**
30
 * Test case for operations in the ContentService using in memory storage.
31
 *
32
 * @see \eZ\Publish\API\Repository\ContentService
33
 * @group content
34
 */
35
class ContentServiceTest extends BaseContentServiceTest
36
{
37
    /**
38
     * Test for the newContentCreateStruct() method.
39
     *
40
     * @see \eZ\Publish\API\Repository\ContentService::newContentCreateStruct()
41
     * @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
42
     * @group user
43
     * @group field-type
44
     */
45
    public function testNewContentCreateStruct()
46
    {
47
        $repository = $this->getRepository();
48
49
        /* BEGIN: Use Case */
50
        // Create a content type
51
        $contentTypeService = $repository->getContentTypeService();
52
53
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
54
55
        $contentService = $repository->getContentService();
56
57
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
58
        /* END: Use Case */
59
60
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentCreateStruct', $contentCreate);
61
    }
62
63
    /**
64
     * Test for the createContent() method.
65
     *
66
     * @return \eZ\Publish\API\Repository\Values\Content\Content
67
     *
68
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
69
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentCreateStruct
70
     * @group user
71
     * @group field-type
72
     */
73
    public function testCreateContent()
74
    {
75
        if ($this->isVersion4()) {
76
            $this->markTestSkipped('This test requires eZ Publish 5');
77
        }
78
79
        $repository = $this->getRepository();
80
81
        /* BEGIN: Use Case */
82
        $contentTypeService = $repository->getContentTypeService();
83
84
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
85
86
        $contentService = $repository->getContentService();
87
88
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
89
        $contentCreate->setField('name', 'My awesome forum');
90
91
        $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
92
        $contentCreate->alwaysAvailable = true;
93
94
        $content = $contentService->createContent($contentCreate);
95
        /* END: Use Case */
96
97
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content', $content);
98
99
        return $content;
100
    }
101
102
    /**
103
     * Test for the createContent() method.
104
     *
105
     * Tests made for issue #EZP-20955 where Anonymous user is granted access to create content
106
     * and should have access to do that.
107
     *
108
     * @return \eZ\Publish\API\Repository\Values\Content\Content
109
     *
110
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
111
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentCreateStruct
112
     * @group user
113
     * @group field-type
114
     */
115
    public function testCreateContentAndPublishWithPrivilegedAnonymousUser()
116
    {
117
        if ($this->isVersion4()) {
118
            $this->markTestSkipped('This test requires eZ Publish 5');
119
        }
120
121
        $anonymousUserId = $this->generateId('user', 10);
122
123
        $repository = $this->getRepository();
124
        $contentService = $repository->getContentService();
125
        $contentTypeService = $repository->getContentTypeService();
126
        $locationService = $repository->getLocationService();
127
        $roleService = $repository->getRoleService();
128
129
        // Give Anonymous user role additional rights
130
        $role = $roleService->loadRoleByIdentifier('Anonymous');
131
        $roleDraft = $roleService->createRoleDraft($role);
132
        $policyCreateStruct = $roleService->newPolicyCreateStruct('content', 'create');
133
        $policyCreateStruct->addLimitation(new SectionLimitation(['limitationValues' => [1]]));
134
        $policyCreateStruct->addLimitation(new LocationLimitation(['limitationValues' => [2]]));
135
        $policyCreateStruct->addLimitation(new ContentTypeLimitation(['limitationValues' => [1]]));
136
        $roleDraft = $roleService->addPolicyByRoleDraft($roleDraft, $policyCreateStruct);
137
138
        $policyCreateStruct = $roleService->newPolicyCreateStruct('content', 'publish');
139
        $policyCreateStruct->addLimitation(new SectionLimitation(['limitationValues' => [1]]));
140
        $policyCreateStruct->addLimitation(new LocationLimitation(['limitationValues' => [2]]));
141
        $policyCreateStruct->addLimitation(new ContentTypeLimitation(['limitationValues' => [1]]));
142
        $roleDraft = $roleService->addPolicyByRoleDraft($roleDraft, $policyCreateStruct);
143
        $roleService->publishRoleDraft($roleDraft);
144
145
        // Set Anonymous user as current
146
        $repository->getPermissionResolver()->setCurrentUserReference($repository->getUserService()->loadUser($anonymousUserId));
147
148
        // Create a new content object:
149
        $contentCreate = $contentService->newContentCreateStruct(
150
            $contentTypeService->loadContentTypeByIdentifier('folder'),
151
            'eng-GB'
152
        );
153
154
        $contentCreate->setField('name', 'Folder 1');
155
156
        $content = $contentService->createContent(
157
            $contentCreate,
158
            [$locationService->newLocationCreateStruct(2)]
159
        );
160
161
        $contentService->publishVersion(
162
            $content->getVersionInfo()
163
        );
164
    }
165
166
    /**
167
     * Test for the createContent() method.
168
     *
169
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
170
     *
171
     * @return \eZ\Publish\API\Repository\Values\Content\Content
172
     *
173
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
174
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
175
     */
176
    public function testCreateContentSetsContentInfo($content)
177
    {
178
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo', $content->contentInfo);
179
180
        return $content;
181
    }
182
183
    /**
184
     * Test for the createContent() method.
185
     *
186
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
187
     *
188
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
189
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentSetsContentInfo
190
     */
191
    public function testCreateContentSetsExpectedContentInfo($content)
192
    {
193
        $this->assertEquals(
194
            [
195
                $content->id,
196
                28, // id of content type "forum"
197
                true,
198
                1,
199
                'abcdef0123456789abcdef0123456789',
200
                'eng-US',
201
                $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
202
                false,
203
                null,
204
                // Main Location id for unpublished Content should be null
205
                null,
206
            ],
207
            [
208
                $content->contentInfo->id,
209
                $content->contentInfo->contentTypeId,
210
                $content->contentInfo->alwaysAvailable,
211
                $content->contentInfo->currentVersionNo,
212
                $content->contentInfo->remoteId,
213
                $content->contentInfo->mainLanguageCode,
214
                $content->contentInfo->ownerId,
215
                $content->contentInfo->published,
216
                $content->contentInfo->publishedDate,
217
                $content->contentInfo->mainLocationId,
218
            ]
219
        );
220
    }
221
222
    /**
223
     * Test for the createContent() method.
224
     *
225
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
226
     *
227
     * @return \eZ\Publish\API\Repository\Values\Content\Content
228
     *
229
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
230
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
231
     */
232
    public function testCreateContentSetsVersionInfo($content)
233
    {
234
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo', $content->getVersionInfo());
235
236
        return $content;
237
    }
238
239
    /**
240
     * Test for the createContent() method.
241
     *
242
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
243
     *
244
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
245
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentSetsVersionInfo
246
     */
247
    public function testCreateContentSetsExpectedVersionInfo($content)
248
    {
249
        $this->assertEquals(
250
            [
251
                'status' => VersionInfo::STATUS_DRAFT,
252
                'versionNo' => 1,
253
                'creatorId' => $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
254
                'initialLanguageCode' => 'eng-US',
255
            ],
256
            [
257
                'status' => $content->getVersionInfo()->status,
258
                'versionNo' => $content->getVersionInfo()->versionNo,
259
                'creatorId' => $content->getVersionInfo()->creatorId,
260
                'initialLanguageCode' => $content->getVersionInfo()->initialLanguageCode,
261
            ]
262
        );
263
        $this->assertTrue($content->getVersionInfo()->isDraft());
264
        $this->assertFalse($content->getVersionInfo()->isPublished());
265
        $this->assertFalse($content->getVersionInfo()->isArchived());
266
    }
267
268
    /**
269
     * Test for the createContent() method.
270
     *
271
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
272
     *
273
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
274
     * @depends testCreateContent
275
     */
276
    public function testCreateContentSetsExpectedContentType($content)
277
    {
278
        $contentType = $content->getContentType();
279
280
        $this->assertEquals(
281
            [
282
                $contentType->id,
283
                // Won't match as it's set to true in createContentDraftVersion1()
284
                //$contentType->defaultAlwaysAvailable,
285
                //$contentType->defaultSortField,
286
                //$contentType->defaultSortOrder,
287
            ],
288
            [
289
                $content->contentInfo->contentTypeId,
290
                //$content->contentInfo->alwaysAvailable,
291
                //$location->sortField,
292
                //$location->sortOrder,
293
            ]
294
        );
295
    }
296
297
    /**
298
     * Test for the createContent() method.
299
     *
300
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
301
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
302
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
303
     */
304
    public function testCreateContentThrowsInvalidArgumentException()
305
    {
306
        if ($this->isVersion4()) {
307
            $this->markTestSkipped('This test requires eZ Publish 5');
308
        }
309
310
        $repository = $this->getRepository();
311
312
        /* BEGIN: Use Case */
313
        $contentTypeService = $repository->getContentTypeService();
314
        $contentService = $repository->getContentService();
315
316
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
317
318
        $contentCreate1 = $contentService->newContentCreateStruct($contentType, 'eng-US');
319
        $contentCreate1->setField('name', 'An awesome Sidelfingen forum');
320
321
        $contentCreate1->remoteId = 'abcdef0123456789abcdef0123456789';
322
        $contentCreate1->alwaysAvailable = true;
323
324
        $draft = $contentService->createContent($contentCreate1);
325
        $contentService->publishVersion($draft->versionInfo);
326
327
        $contentCreate2 = $contentService->newContentCreateStruct($contentType, 'eng-GB');
328
        $contentCreate2->setField('name', 'An awesome Bielefeld forum');
329
330
        $contentCreate2->remoteId = 'abcdef0123456789abcdef0123456789';
331
        $contentCreate2->alwaysAvailable = false;
332
333
        // This call will fail with an "InvalidArgumentException", because the
334
        // remoteId is already in use.
335
        $contentService->createContent($contentCreate2);
336
        /* END: Use Case */
337
    }
338
339
    /**
340
     * Test for the createContent() method.
341
     *
342
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
343
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
344
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
345
     */
346 View Code Duplication
    public function testCreateContentThrowsInvalidArgumentExceptionOnFieldTypeNotAccept()
347
    {
348
        $repository = $this->getRepository();
349
350
        /* BEGIN: Use Case */
351
        $contentTypeService = $repository->getContentTypeService();
352
        $contentService = $repository->getContentService();
353
354
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
355
356
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
357
        // The name field does only accept strings and null as its values
358
        $contentCreate->setField('name', new \stdClass());
359
360
        // Throws InvalidArgumentException since the name field is filled
361
        // improperly
362
        $draft = $contentService->createContent($contentCreate);
0 ignored issues
show
Unused Code introduced by
$draft is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
363
        /* END: Use Case */
364
    }
365
366
    /**
367
     * Test for the createContent() method.
368
     *
369
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
370
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
371
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
372
     */
373
    public function testCreateContentThrowsContentFieldValidationException()
374
    {
375
        $repository = $this->getRepository();
376
377
        /* BEGIN: Use Case */
378
        $contentTypeService = $repository->getContentTypeService();
379
        $contentService = $repository->getContentService();
380
381
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
382
383
        $contentCreate1 = $contentService->newContentCreateStruct($contentType, 'eng-US');
384
        $contentCreate1->setField('name', 'An awesome Sidelfingen folder');
385
        // Violates string length constraint
386
        $contentCreate1->setField('short_name', str_repeat('a', 200));
387
388
        // Throws ContentFieldValidationException, since short_name does not pass
389
        // validation of the string length validator
390
        $draft = $contentService->createContent($contentCreate1);
0 ignored issues
show
Unused Code introduced by
$draft is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
391
        /* END: Use Case */
392
    }
393
394
    /**
395
     * Test for the createContent() method.
396
     *
397
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
398
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
399
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
400
     */
401 View Code Duplication
    public function testCreateContentRequiredFieldMissing()
402
    {
403
        $repository = $this->getRepository();
404
405
        /* BEGIN: Use Case */
406
        $contentTypeService = $repository->getContentTypeService();
407
        $contentService = $repository->getContentService();
408
409
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
410
411
        $contentCreate1 = $contentService->newContentCreateStruct($contentType, 'eng-US');
412
        // Required field "name" is not set
413
414
        // Throws a ContentFieldValidationException, since a required field is
415
        // missing
416
        $draft = $contentService->createContent($contentCreate1);
0 ignored issues
show
Unused Code introduced by
$draft is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
417
        /* END: Use Case */
418
    }
419
420
    /**
421
     * Test for the createContent() method.
422
     *
423
     * NOTE: We have bidirectional dependencies between the ContentService and
424
     * the LocationService, so that we cannot use PHPUnit's test dependencies
425
     * here.
426
     *
427
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
428
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
429
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationByRemoteId
430
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
431
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
432
     * @group user
433
     */
434
    public function testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately()
435
    {
436
        $repository = $this->getRepository();
437
438
        $locationService = $repository->getLocationService();
439
440
        /* BEGIN: Use Case */
441
        $draft = $this->createContentDraftVersion1();
0 ignored issues
show
Unused Code introduced by
$draft is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
442
443
        // The location will not have been created, yet, so this throws an
444
        // exception
445
        $location = $locationService->loadLocationByRemoteId(
0 ignored issues
show
Unused Code introduced by
$location is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
446
            '0123456789abcdef0123456789abcdef'
447
        );
448
        /* END: Use Case */
449
    }
450
451
    /**
452
     * Test for the createContent() method.
453
     *
454
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
455
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
456
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
457
     */
458
    public function testCreateContentThrowsInvalidArgumentExceptionWithLocationCreateParameter()
459
    {
460
        $repository = $this->getRepository();
461
462
        $parentLocationId = $this->generateId('location', 56);
463
        /* BEGIN: Use Case */
464
        // $parentLocationId is a valid location ID
465
466
        $contentService = $repository->getContentService();
467
        $contentTypeService = $repository->getContentTypeService();
468
        $locationService = $repository->getLocationService();
469
470
        // Load content type
471
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
472
473
        // Configure new locations
474
        $locationCreate1 = $locationService->newLocationCreateStruct($parentLocationId);
475
476
        $locationCreate1->priority = 23;
477
        $locationCreate1->hidden = true;
478
        $locationCreate1->remoteId = '0123456789abcdef0123456789aaaaaa';
479
        $locationCreate1->sortField = Location::SORT_FIELD_NODE_ID;
480
        $locationCreate1->sortOrder = Location::SORT_ORDER_DESC;
481
482
        $locationCreate2 = $locationService->newLocationCreateStruct($parentLocationId);
483
484
        $locationCreate2->priority = 42;
485
        $locationCreate2->hidden = true;
486
        $locationCreate2->remoteId = '0123456789abcdef0123456789bbbbbb';
487
        $locationCreate2->sortField = Location::SORT_FIELD_NODE_ID;
488
        $locationCreate2->sortOrder = Location::SORT_ORDER_DESC;
489
490
        // Configure new content object
491
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
492
493
        $contentCreate->setField('name', 'A awesome Sindelfingen forum');
494
        $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
495
        $contentCreate->alwaysAvailable = true;
496
497
        // Create new content object under the specified location
498
        $draft = $contentService->createContent(
499
            $contentCreate,
500
            [$locationCreate1]
501
        );
502
        $contentService->publishVersion($draft->versionInfo);
503
504
        // This call will fail with an "InvalidArgumentException", because the
505
        // Content remoteId already exists,
506
        $contentService->createContent(
507
            $contentCreate,
508
            [$locationCreate2]
509
        );
510
        /* END: Use Case */
511
    }
512
513
    /**
514
     * Test for the loadContentInfo() method.
515
     *
516
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfo()
517
     * @group user
518
     */
519 View Code Duplication
    public function testLoadContentInfo()
520
    {
521
        $repository = $this->getRepository();
522
523
        $mediaFolderId = $this->generateId('object', 41);
524
        /* BEGIN: Use Case */
525
        $contentService = $repository->getContentService();
526
527
        // Load the ContentInfo for "Media" folder
528
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
529
        /* END: Use Case */
530
531
        $this->assertInstanceOf(
532
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo',
533
            $contentInfo
534
        );
535
536
        return $contentInfo;
537
    }
538
539
    /**
540
     * Test for the returned value of the loadContentInfo() method.
541
     *
542
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
543
     * @covers \eZ\Publish\API\Repository\ContentService::loadContentInfo
544
     *
545
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
546
     */
547
    public function testLoadContentInfoSetsExpectedContentInfo(ContentInfo $contentInfo)
548
    {
549
        $this->assertPropertiesCorrectUnsorted(
550
            $this->getExpectedMediaContentInfoProperties(),
551
            $contentInfo
552
        );
553
    }
554
555
    /**
556
     * Test for the loadContentInfo() method.
557
     *
558
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfo()
559
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
560
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
561
     */
562 View Code Duplication
    public function testLoadContentInfoThrowsNotFoundException()
563
    {
564
        $repository = $this->getRepository();
565
566
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
567
        /* BEGIN: Use Case */
568
        $contentService = $repository->getContentService();
569
570
        // This call will fail with a NotFoundException
571
        $contentService->loadContentInfo($nonExistentContentId);
572
        /* END: Use Case */
573
    }
574
575
    /**
576
     * Test for the loadContentInfoList() method.
577
     *
578
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoList()
579
     */
580
    public function testLoadContentInfoList()
581
    {
582
        $repository = $this->getRepository();
583
584
        $mediaFolderId = $this->generateId('object', 41);
585
        $contentService = $repository->getContentService();
586
        $list = $contentService->loadContentInfoList([$mediaFolderId]);
587
588
        $this->assertCount(1, $list);
589
        $this->assertEquals([$mediaFolderId], array_keys($list), 'Array key was not content id');
590
        $this->assertInstanceOf(
591
            ContentInfo::class,
592
            $list[$mediaFolderId]
593
        );
594
    }
595
596
    /**
597
     * Test for the loadContentInfoList() method.
598
     *
599
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoList()
600
     * @depends testLoadContentInfoList
601
     */
602 View Code Duplication
    public function testLoadContentInfoListSkipsNotFoundItems()
603
    {
604
        $repository = $this->getRepository();
605
606
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
607
        $contentService = $repository->getContentService();
608
        $list = $contentService->loadContentInfoList([$nonExistentContentId]);
609
610
        $this->assertCount(0, $list);
611
    }
612
613
    /**
614
     * Test for the loadContentInfoByRemoteId() method.
615
     *
616
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoByRemoteId()
617
     */
618
    public function testLoadContentInfoByRemoteId()
619
    {
620
        $repository = $this->getRepository();
621
622
        /* BEGIN: Use Case */
623
        $contentService = $repository->getContentService();
624
625
        // Load the ContentInfo for "Media" folder
626
        $contentInfo = $contentService->loadContentInfoByRemoteId('faaeb9be3bd98ed09f606fc16d144eca');
627
        /* END: Use Case */
628
629
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo', $contentInfo);
630
631
        return $contentInfo;
632
    }
633
634
    /**
635
     * Test for the returned value of the loadContentInfoByRemoteId() method.
636
     *
637
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfoByRemoteId
638
     * @covers \eZ\Publish\API\Repository\ContentService::loadContentInfoByRemoteId
639
     *
640
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
641
     */
642 View Code Duplication
    public function testLoadContentInfoByRemoteIdSetsExpectedContentInfo(ContentInfo $contentInfo)
643
    {
644
        $this->assertPropertiesCorrectUnsorted(
645
            [
646
                'id' => 10,
647
                'contentTypeId' => 4,
648
                'name' => 'Anonymous User',
649
                'sectionId' => 2,
650
                'currentVersionNo' => 2,
651
                'published' => true,
652
                'ownerId' => 14,
653
                'modificationDate' => $this->createDateTime(1072180405),
654
                'publishedDate' => $this->createDateTime(1033920665),
655
                'alwaysAvailable' => 1,
656
                'remoteId' => 'faaeb9be3bd98ed09f606fc16d144eca',
657
                'mainLanguageCode' => 'eng-US',
658
                'mainLocationId' => 45,
659
            ],
660
            $contentInfo
661
        );
662
    }
663
664
    /**
665
     * Test for the loadContentInfoByRemoteId() method.
666
     *
667
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoByRemoteId()
668
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
669
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfoByRemoteId
670
     */
671
    public function testLoadContentInfoByRemoteIdThrowsNotFoundException()
672
    {
673
        $repository = $this->getRepository();
674
675
        /* BEGIN: Use Case */
676
        $contentService = $repository->getContentService();
677
678
        // This call will fail with a NotFoundException
679
        $contentService->loadContentInfoByRemoteId('abcdefghijklmnopqrstuvwxyz0123456789');
680
        /* END: Use Case */
681
    }
682
683
    /**
684
     * Test for the loadVersionInfo() method.
685
     *
686
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo()
687
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
688
     * @group user
689
     */
690 View Code Duplication
    public function testLoadVersionInfo()
691
    {
692
        $repository = $this->getRepository();
693
694
        $mediaFolderId = $this->generateId('object', 41);
695
        /* BEGIN: Use Case */
696
        // $mediaFolderId contains the ID of the "Media" folder
697
698
        $contentService = $repository->getContentService();
699
700
        // Load the ContentInfo for "Media" folder
701
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
702
703
        // Now load the current version info of the "Media" folder
704
        $versionInfo = $contentService->loadVersionInfo($contentInfo);
705
        /* END: Use Case */
706
707
        $this->assertInstanceOf(
708
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo',
709
            $versionInfo
710
        );
711
    }
712
713
    /**
714
     * Test for the loadVersionInfoById() method.
715
     *
716
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById()
717
     */
718 View Code Duplication
    public function testLoadVersionInfoById()
719
    {
720
        $repository = $this->getRepository();
721
722
        $mediaFolderId = $this->generateId('object', 41);
723
        /* BEGIN: Use Case */
724
        // $mediaFolderId contains the ID of the "Media" folder
725
726
        $contentService = $repository->getContentService();
727
728
        // Load the VersionInfo for "Media" folder
729
        $versionInfo = $contentService->loadVersionInfoById($mediaFolderId);
730
        /* END: Use Case */
731
732
        $this->assertInstanceOf(
733
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo',
734
            $versionInfo
735
        );
736
737
        return $versionInfo;
738
    }
739
740
    /**
741
     * Test for the returned value of the loadVersionInfoById() method.
742
     *
743
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoById
744
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
745
     *
746
     * @param \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfo
747
     */
748
    public function testLoadVersionInfoByIdSetsExpectedVersionInfo(VersionInfo $versionInfo)
749
    {
750
        $this->assertPropertiesCorrect(
751
            [
752
                'names' => [
753
                    'eng-US' => 'Media',
754
                ],
755
                'contentInfo' => new ContentInfo($this->getExpectedMediaContentInfoProperties()),
756
                'id' => 472,
757
                'versionNo' => 1,
758
                'modificationDate' => $this->createDateTime(1060695457),
759
                'creatorId' => 14,
760
                'creationDate' => $this->createDateTime(1060695450),
761
                'status' => VersionInfo::STATUS_PUBLISHED,
762
                'initialLanguageCode' => 'eng-US',
763
                'languageCodes' => [
764
                    'eng-US',
765
                ],
766
            ],
767
            $versionInfo
768
        );
769
        $this->assertTrue($versionInfo->isPublished());
770
        $this->assertFalse($versionInfo->isDraft());
771
        $this->assertFalse($versionInfo->isArchived());
772
    }
773
774
    /**
775
     * Test for the loadVersionInfoById() method.
776
     *
777
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById()
778
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
779
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoById
780
     */
781 View Code Duplication
    public function testLoadVersionInfoByIdThrowsNotFoundException()
782
    {
783
        $repository = $this->getRepository();
784
785
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
786
        /* BEGIN: Use Case */
787
        $contentService = $repository->getContentService();
788
789
        // This call will fail with a "NotFoundException"
790
        $contentService->loadVersionInfoById($nonExistentContentId);
791
        /* END: Use Case */
792
    }
793
794
    /**
795
     * Test for the loadContentByContentInfo() method.
796
     *
797
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo()
798
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
799
     */
800 View Code Duplication
    public function testLoadContentByContentInfo()
801
    {
802
        $repository = $this->getRepository();
803
804
        $mediaFolderId = $this->generateId('object', 41);
805
        /* BEGIN: Use Case */
806
        // $mediaFolderId contains the ID of the "Media" folder
807
808
        $contentService = $repository->getContentService();
809
810
        // Load the ContentInfo for "Media" folder
811
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
812
813
        // Now load the current content version for the info instance
814
        $content = $contentService->loadContentByContentInfo($contentInfo);
815
        /* END: Use Case */
816
817
        $this->assertInstanceOf(
818
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
819
            $content
820
        );
821
    }
822
823
    /**
824
     * Test for the loadContentByVersionInfo() method.
825
     *
826
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByVersionInfo()
827
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
828
     */
829 View Code Duplication
    public function testLoadContentByVersionInfo()
830
    {
831
        $repository = $this->getRepository();
832
833
        $mediaFolderId = $this->generateId('object', 41);
834
        /* BEGIN: Use Case */
835
        // $mediaFolderId contains the ID of the "Media" folder
836
837
        $contentService = $repository->getContentService();
838
839
        // Load the ContentInfo for "Media" folder
840
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
841
842
        // Load the current VersionInfo
843
        $versionInfo = $contentService->loadVersionInfo($contentInfo);
844
845
        // Now load the current content version for the info instance
846
        $content = $contentService->loadContentByVersionInfo($versionInfo);
847
        /* END: Use Case */
848
849
        $this->assertInstanceOf(
850
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
851
            $content
852
        );
853
    }
854
855
    /**
856
     * Test for the loadContent() method.
857
     *
858
     * @see \eZ\Publish\API\Repository\ContentService::loadContent()
859
     * @group user
860
     * @group field-type
861
     */
862 View Code Duplication
    public function testLoadContent()
863
    {
864
        $repository = $this->getRepository();
865
866
        $mediaFolderId = $this->generateId('object', 41);
867
        /* BEGIN: Use Case */
868
        // $mediaFolderId contains the ID of the "Media" folder
869
870
        $contentService = $repository->getContentService();
871
872
        // Load the Content for "Media" folder, any language and current version
873
        $content = $contentService->loadContent($mediaFolderId);
874
        /* END: Use Case */
875
876
        $this->assertInstanceOf(
877
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
878
            $content
879
        );
880
    }
881
882
    /**
883
     * Test for the loadContent() method.
884
     *
885
     * @see \eZ\Publish\API\Repository\ContentService::loadContent()
886
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
887
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
888
     */
889 View Code Duplication
    public function testLoadContentThrowsNotFoundException()
890
    {
891
        $repository = $this->getRepository();
892
893
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
894
        /* BEGIN: Use Case */
895
        $contentService = $repository->getContentService();
896
897
        // This call will fail with a "NotFoundException"
898
        $contentService->loadContent($nonExistentContentId);
899
        /* END: Use Case */
900
    }
901
902
    /**
903
     * Data provider for testLoadContentByRemoteId().
904
     *
905
     * @return array
906
     */
907
    public function contentRemoteIdVersionLanguageProvider()
908
    {
909
        return [
910
            ['f5c88a2209584891056f987fd965b0ba', null, null],
911
            ['f5c88a2209584891056f987fd965b0ba', ['eng-US'], null],
912
            ['f5c88a2209584891056f987fd965b0ba', null, 1],
913
            ['f5c88a2209584891056f987fd965b0ba', ['eng-US'], 1],
914
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', null, null],
915
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', ['eng-US'], null],
916
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', null, 1],
917
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', ['eng-US'], 1],
918
        ];
919
    }
920
921
    /**
922
     * Test for the loadContentByRemoteId() method.
923
     *
924
     * @covers \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId
925
     * @dataProvider contentRemoteIdVersionLanguageProvider
926
     *
927
     * @param string $remoteId
928
     * @param array|null $languages
929
     * @param int $versionNo
930
     */
931
    public function testLoadContentByRemoteId($remoteId, $languages, $versionNo)
932
    {
933
        $repository = $this->getRepository();
934
935
        $contentService = $repository->getContentService();
936
937
        $content = $contentService->loadContentByRemoteId($remoteId, $languages, $versionNo);
938
939
        $this->assertInstanceOf(
940
            Content::class,
941
            $content
942
        );
943
944
        $this->assertEquals($remoteId, $content->contentInfo->remoteId);
945
        if ($languages !== null) {
946
            $this->assertEquals($languages, $content->getVersionInfo()->languageCodes);
947
        }
948
        $this->assertEquals($versionNo ?: 1, $content->getVersionInfo()->versionNo);
949
    }
950
951
    /**
952
     * Test for the loadContentByRemoteId() method.
953
     *
954
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId()
955
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
956
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteId
957
     */
958
    public function testLoadContentByRemoteIdThrowsNotFoundException()
959
    {
960
        $repository = $this->getRepository();
961
962
        /* BEGIN: Use Case */
963
        $contentService = $repository->getContentService();
964
965
        // This call will fail with a "NotFoundException", because no content
966
        // object exists for the given remoteId
967
        $contentService->loadContentByRemoteId('a1b1c1d1e1f1a2b2c2d2e2f2a3b3c3d3');
968
        /* END: Use Case */
969
    }
970
971
    /**
972
     * Test for the publishVersion() method.
973
     *
974
     * @return \eZ\Publish\API\Repository\Values\Content\Content
975
     *
976
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
977
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
978
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
979
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
980
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
981
     * @group user
982
     * @group field-type
983
     */
984
    public function testPublishVersion()
985
    {
986
        $time = time();
987
        /* BEGIN: Use Case */
988
        $content = $this->createContentVersion1();
989
        /* END: Use Case */
990
991
        $this->assertInstanceOf(Content::class, $content);
992
        $this->assertTrue($content->contentInfo->published);
993
        $this->assertEquals(VersionInfo::STATUS_PUBLISHED, $content->versionInfo->status);
994
        $this->assertGreaterThanOrEqual($time, $content->contentInfo->publishedDate->getTimestamp());
995
        $this->assertGreaterThanOrEqual($time, $content->contentInfo->modificationDate->getTimestamp());
996
        $this->assertTrue($content->versionInfo->isPublished());
997
        $this->assertFalse($content->versionInfo->isDraft());
998
        $this->assertFalse($content->versionInfo->isArchived());
999
1000
        return $content;
1001
    }
1002
1003
    /**
1004
     * Test for the publishVersion() method.
1005
     *
1006
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1007
     *
1008
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1009
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1010
     */
1011
    public function testPublishVersionSetsExpectedContentInfo($content)
1012
    {
1013
        $this->assertEquals(
1014
            [
1015
                $content->id,
1016
                true,
1017
                1,
1018
                'abcdef0123456789abcdef0123456789',
1019
                'eng-US',
1020
                $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1021
                true,
1022
            ],
1023
            [
1024
                $content->contentInfo->id,
1025
                $content->contentInfo->alwaysAvailable,
1026
                $content->contentInfo->currentVersionNo,
1027
                $content->contentInfo->remoteId,
1028
                $content->contentInfo->mainLanguageCode,
1029
                $content->contentInfo->ownerId,
1030
                $content->contentInfo->published,
1031
            ]
1032
        );
1033
1034
        $this->assertNotNull($content->contentInfo->mainLocationId);
1035
        $date = new \DateTime('1984/01/01');
1036
        $this->assertGreaterThan(
1037
            $date->getTimestamp(),
1038
            $content->contentInfo->publishedDate->getTimestamp()
1039
        );
1040
    }
1041
1042
    /**
1043
     * Test for the publishVersion() method.
1044
     *
1045
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1046
     *
1047
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1048
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1049
     */
1050
    public function testPublishVersionSetsExpectedVersionInfo($content)
1051
    {
1052
        $this->assertEquals(
1053
            [
1054
                $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1055
                'eng-US',
1056
                VersionInfo::STATUS_PUBLISHED,
1057
                1,
1058
            ],
1059
            [
1060
                $content->getVersionInfo()->creatorId,
1061
                $content->getVersionInfo()->initialLanguageCode,
1062
                $content->getVersionInfo()->status,
1063
                $content->getVersionInfo()->versionNo,
1064
            ]
1065
        );
1066
1067
        $date = new \DateTime('1984/01/01');
1068
        $this->assertGreaterThan(
1069
            $date->getTimestamp(),
1070
            $content->getVersionInfo()->modificationDate->getTimestamp()
1071
        );
1072
1073
        $this->assertNotNull($content->getVersionInfo()->modificationDate);
1074
        $this->assertTrue($content->getVersionInfo()->isPublished());
1075
        $this->assertFalse($content->getVersionInfo()->isDraft());
1076
        $this->assertFalse($content->getVersionInfo()->isArchived());
1077
    }
1078
1079
    /**
1080
     * Test for the publishVersion() method.
1081
     *
1082
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1083
     *
1084
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1085
     * @depends testPublishVersion
1086
     */
1087
    public function testPublishVersionSetsExpectedContentType($content)
1088
    {
1089
        $contentType = $content->getContentType();
1090
1091
        $this->assertEquals(
1092
            [
1093
                $contentType->id,
1094
                // won't be a match as it's set to true in createContentDraftVersion1()
1095
                //$contentType->defaultAlwaysAvailable,
1096
                //$contentType->defaultSortField,
1097
                //$contentType->defaultSortOrder,
1098
            ],
1099
            [
1100
                $content->contentInfo->contentTypeId,
1101
                //$content->contentInfo->alwaysAvailable,
1102
                //$location->sortField,
1103
                //$location->sortOrder,
1104
            ]
1105
        );
1106
    }
1107
1108
    /**
1109
     * Test for the publishVersion() method.
1110
     *
1111
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1112
     *
1113
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1114
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
1115
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1116
     */
1117
    public function testPublishVersionCreatesLocationsDefinedOnCreate()
1118
    {
1119
        $repository = $this->getRepository();
1120
1121
        /* BEGIN: Use Case */
1122
        $content = $this->createContentVersion1();
1123
        /* END: Use Case */
1124
1125
        $locationService = $repository->getLocationService();
1126
        $location = $locationService->loadLocationByRemoteId(
1127
            '0123456789abcdef0123456789abcdef'
1128
        );
1129
1130
        $this->assertEquals(
1131
            $location->getContentInfo(),
1132
            $content->getVersionInfo()->getContentInfo()
1133
        );
1134
1135
        return [$content, $location];
1136
    }
1137
1138
    /**
1139
     * Test for the publishVersion() method.
1140
     *
1141
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1142
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionCreatesLocationsDefinedOnCreate
1143
     */
1144
    public function testCreateContentWithLocationCreateParameterCreatesExpectedLocation(array $testData)
1145
    {
1146
        /** @var \eZ\Publish\API\Repository\Values\Content\Content $content */
1147
        /** @var \eZ\Publish\API\Repository\Values\Content\Location $location */
1148
        list($content, $location) = $testData;
1149
1150
        $parentLocationId = $this->generateId('location', 56);
1151
        $parentLocation = $this->getRepository()->getLocationService()->loadLocation($parentLocationId);
1152
        $mainLocationId = $content->getVersionInfo()->getContentInfo()->mainLocationId;
1153
1154
        $this->assertPropertiesCorrect(
1155
            [
1156
                'id' => $mainLocationId,
1157
                'priority' => 23,
1158
                'hidden' => true,
1159
                'invisible' => true,
1160
                'remoteId' => '0123456789abcdef0123456789abcdef',
1161
                'parentLocationId' => $parentLocationId,
1162
                'pathString' => $parentLocation->pathString . $mainLocationId . '/',
1163
                'depth' => $parentLocation->depth + 1,
1164
                'sortField' => Location::SORT_FIELD_NODE_ID,
1165
                'sortOrder' => Location::SORT_ORDER_DESC,
1166
            ],
1167
            $location
1168
        );
1169
    }
1170
1171
    /**
1172
     * Test for the publishVersion() method.
1173
     *
1174
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1175
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
1176
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1177
     */
1178 View Code Duplication
    public function testPublishVersionThrowsBadStateException()
1179
    {
1180
        $repository = $this->getRepository();
1181
1182
        $contentService = $repository->getContentService();
1183
1184
        /* BEGIN: Use Case */
1185
        $draft = $this->createContentDraftVersion1();
1186
1187
        // Publish the content draft
1188
        $contentService->publishVersion($draft->getVersionInfo());
1189
1190
        // This call will fail with a "BadStateException", because the version
1191
        // is already published.
1192
        $contentService->publishVersion($draft->getVersionInfo());
1193
        /* END: Use Case */
1194
    }
1195
1196
    /**
1197
     * Test that publishVersion() does not affect publishedDate (assuming previous version exists).
1198
     *
1199
     * @covers \eZ\Publish\API\Repository\ContentService::publishVersion
1200
     */
1201
    public function testPublishVersionDoesNotChangePublishedDate()
1202
    {
1203
        $repository = $this->getRepository();
1204
1205
        $contentService = $repository->getContentService();
1206
1207
        $publishedContent = $this->createContentVersion1();
1208
1209
        // force timestamps to differ
1210
        sleep(1);
1211
1212
        $contentDraft = $contentService->createContentDraft($publishedContent->contentInfo);
1213
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1214
        $contentUpdateStruct->setField('name', 'New name');
1215
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
1216
        $republishedContent = $contentService->publishVersion($contentDraft->versionInfo);
1217
1218
        $this->assertEquals(
1219
            $publishedContent->contentInfo->publishedDate->getTimestamp(),
1220
            $republishedContent->contentInfo->publishedDate->getTimestamp()
1221
        );
1222
        $this->assertGreaterThan(
1223
            $publishedContent->contentInfo->modificationDate->getTimestamp(),
1224
            $republishedContent->contentInfo->modificationDate->getTimestamp()
1225
        );
1226
    }
1227
1228
    /**
1229
     * Test for the createContentDraft() method.
1230
     *
1231
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1232
     *
1233
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1234
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1235
     * @group user
1236
     */
1237
    public function testCreateContentDraft()
1238
    {
1239
        $repository = $this->getRepository();
1240
1241
        $contentService = $repository->getContentService();
1242
1243
        /* BEGIN: Use Case */
1244
        $content = $this->createContentVersion1();
1245
1246
        // Now we create a new draft from the published content
1247
        $draftedContent = $contentService->createContentDraft($content->contentInfo);
1248
        /* END: Use Case */
1249
1250
        $this->assertInstanceOf(
1251
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1252
            $draftedContent
1253
        );
1254
1255
        return $draftedContent;
1256
    }
1257
1258
    /**
1259
     * Test for the createContentDraft() method.
1260
     *
1261
     * Test that editor has access to edit own draft.
1262
     * Note: Editors have access to version_read, which is needed to load content drafts.
1263
     *
1264
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1265
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1266
     * @group user
1267
     */
1268 View Code Duplication
    public function testCreateContentDraftAndLoadAccess()
1269
    {
1270
        $repository = $this->getRepository();
1271
1272
        /* BEGIN: Use Case */
1273
        $user = $this->createUserVersion1();
1274
1275
        // Set new editor as user
1276
        $repository->setCurrentUser($user);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::setCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::setCurrentUserReference() instead. Sets the current user to the given $user.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1277
1278
        // Create draft
1279
        $draft = $this->createContentDraftVersion1(2, 'folder');
1280
1281
        // Try to load the draft
1282
        $contentService = $repository->getContentService();
1283
        $loadedDraft = $contentService->loadContent($draft->id);
1284
1285
        /* END: Use Case */
1286
1287
        $this->assertEquals($draft->id, $loadedDraft->id);
1288
    }
1289
1290
    /**
1291
     * Test for the createContentDraft() method.
1292
     *
1293
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1294
     *
1295
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1296
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1297
     */
1298
    public function testCreateContentDraftSetsExpectedProperties($draft)
1299
    {
1300
        $this->assertEquals(
1301
            [
1302
                'fieldCount' => 2,
1303
                'relationCount' => 0,
1304
            ],
1305
            [
1306
                'fieldCount' => count($draft->getFields()),
1307
                'relationCount' => count($this->getRepository()->getContentService()->loadRelations($draft->getVersionInfo())),
1308
            ]
1309
        );
1310
    }
1311
1312
    /**
1313
     * Test for the createContentDraft() method.
1314
     *
1315
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1316
     *
1317
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1318
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1319
     */
1320
    public function testCreateContentDraftSetsContentInfo($draft)
1321
    {
1322
        $contentInfo = $draft->contentInfo;
1323
1324
        $this->assertEquals(
1325
            [
1326
                $draft->id,
1327
                true,
1328
                1,
1329
                'eng-US',
1330
                $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1331
                'abcdef0123456789abcdef0123456789',
1332
                1,
1333
            ],
1334
            [
1335
                $contentInfo->id,
1336
                $contentInfo->alwaysAvailable,
1337
                $contentInfo->currentVersionNo,
1338
                $contentInfo->mainLanguageCode,
1339
                $contentInfo->ownerId,
1340
                $contentInfo->remoteId,
1341
                $contentInfo->sectionId,
1342
            ]
1343
        );
1344
    }
1345
1346
    /**
1347
     * Test for the createContentDraft() method.
1348
     *
1349
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1350
     *
1351
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1352
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1353
     */
1354
    public function testCreateContentDraftSetsVersionInfo($draft)
1355
    {
1356
        $versionInfo = $draft->getVersionInfo();
1357
1358
        $this->assertEquals(
1359
            [
1360
                'creatorId' => $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1361
                'initialLanguageCode' => 'eng-US',
1362
                'languageCodes' => [0 => 'eng-US'],
1363
                'status' => VersionInfo::STATUS_DRAFT,
1364
                'versionNo' => 2,
1365
            ],
1366
            [
1367
                'creatorId' => $versionInfo->creatorId,
1368
                'initialLanguageCode' => $versionInfo->initialLanguageCode,
1369
                'languageCodes' => $versionInfo->languageCodes,
1370
                'status' => $versionInfo->status,
1371
                'versionNo' => $versionInfo->versionNo,
1372
            ]
1373
        );
1374
        $this->assertTrue($versionInfo->isDraft());
1375
        $this->assertFalse($versionInfo->isPublished());
1376
        $this->assertFalse($versionInfo->isArchived());
1377
    }
1378
1379
    /**
1380
     * Test for the createContentDraft() method.
1381
     *
1382
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1383
     *
1384
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1385
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1386
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
1387
     */
1388 View Code Duplication
    public function testCreateContentDraftLoadVersionInfoStillLoadsPublishedVersion($draft)
0 ignored issues
show
Unused Code introduced by
The parameter $draft is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1389
    {
1390
        $repository = $this->getRepository();
1391
1392
        $contentService = $repository->getContentService();
1393
1394
        /* BEGIN: Use Case */
1395
        $content = $this->createContentVersion1();
1396
1397
        // Now we create a new draft from the published content
1398
        $contentService->createContentDraft($content->contentInfo);
1399
1400
        // This call will still load the published version
1401
        $versionInfoPublished = $contentService->loadVersionInfo($content->contentInfo);
1402
        /* END: Use Case */
1403
1404
        $this->assertEquals(1, $versionInfoPublished->versionNo);
1405
    }
1406
1407
    /**
1408
     * Test for the createContentDraft() method.
1409
     *
1410
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1411
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
1412
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1413
     */
1414 View Code Duplication
    public function testCreateContentDraftLoadContentStillLoadsPublishedVersion()
1415
    {
1416
        $repository = $this->getRepository();
1417
1418
        $contentService = $repository->getContentService();
1419
1420
        /* BEGIN: Use Case */
1421
        $content = $this->createContentVersion1();
1422
1423
        // Now we create a new draft from the published content
1424
        $contentService->createContentDraft($content->contentInfo);
1425
1426
        // This call will still load the published content version
1427
        $contentPublished = $contentService->loadContent($content->id);
1428
        /* END: Use Case */
1429
1430
        $this->assertEquals(1, $contentPublished->getVersionInfo()->versionNo);
1431
    }
1432
1433
    /**
1434
     * Test for the createContentDraft() method.
1435
     *
1436
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1437
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteId
1438
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1439
     */
1440 View Code Duplication
    public function testCreateContentDraftLoadContentByRemoteIdStillLoadsPublishedVersion()
1441
    {
1442
        $repository = $this->getRepository();
1443
1444
        $contentService = $repository->getContentService();
1445
1446
        /* BEGIN: Use Case */
1447
        $content = $this->createContentVersion1();
1448
1449
        // Now we create a new draft from the published content
1450
        $contentService->createContentDraft($content->contentInfo);
1451
1452
        // This call will still load the published content version
1453
        $contentPublished = $contentService->loadContentByRemoteId('abcdef0123456789abcdef0123456789');
1454
        /* END: Use Case */
1455
1456
        $this->assertEquals(1, $contentPublished->getVersionInfo()->versionNo);
1457
    }
1458
1459
    /**
1460
     * Test for the createContentDraft() method.
1461
     *
1462
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1463
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfo
1464
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1465
     */
1466 View Code Duplication
    public function testCreateContentDraftLoadContentByContentInfoStillLoadsPublishedVersion()
1467
    {
1468
        $repository = $this->getRepository();
1469
1470
        $contentService = $repository->getContentService();
1471
1472
        /* BEGIN: Use Case */
1473
        $content = $this->createContentVersion1();
1474
1475
        // Now we create a new draft from the published content
1476
        $contentService->createContentDraft($content->contentInfo);
1477
1478
        // This call will still load the published content version
1479
        $contentPublished = $contentService->loadContentByContentInfo($content->contentInfo);
1480
        /* END: Use Case */
1481
1482
        $this->assertEquals(1, $contentPublished->getVersionInfo()->versionNo);
1483
    }
1484
1485
    /**
1486
     * Test for the newContentUpdateStruct() method.
1487
     *
1488
     * @covers \eZ\Publish\API\Repository\ContentService::newContentUpdateStruct
1489
     * @group user
1490
     */
1491
    public function testNewContentUpdateStruct()
1492
    {
1493
        $repository = $this->getRepository();
1494
1495
        /* BEGIN: Use Case */
1496
        $contentService = $repository->getContentService();
1497
1498
        $updateStruct = $contentService->newContentUpdateStruct();
1499
        /* END: Use Case */
1500
1501
        $this->assertInstanceOf(
1502
            ContentUpdateStruct::class,
1503
            $updateStruct
1504
        );
1505
1506
        $this->assertPropertiesCorrect(
1507
            [
1508
                'initialLanguageCode' => null,
1509
                'fields' => [],
1510
            ],
1511
            $updateStruct
1512
        );
1513
    }
1514
1515
    /**
1516
     * Test for the updateContent() method.
1517
     *
1518
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1519
     *
1520
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1521
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentUpdateStruct
1522
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1523
     * @group user
1524
     * @group field-type
1525
     */
1526
    public function testUpdateContent()
1527
    {
1528
        /* BEGIN: Use Case */
1529
        $draftVersion2 = $this->createUpdatedDraftVersion2();
1530
        /* END: Use Case */
1531
1532
        $this->assertInstanceOf(
1533
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1534
            $draftVersion2
1535
        );
1536
1537
        $this->assertEquals(
1538
            $this->generateId('user', 10),
1539
            $draftVersion2->versionInfo->creatorId,
1540
            'creatorId is not properly set on new Version'
1541
        );
1542
1543
        return $draftVersion2;
1544
    }
1545
1546
    /**
1547
     * Test for the updateContent_WithDifferentUser() method.
1548
     *
1549
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1550
     *
1551
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1552
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentUpdateStruct
1553
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1554
     * @group user
1555
     * @group field-type
1556
     */
1557
    public function testUpdateContentWithDifferentUser()
1558
    {
1559
        /* BEGIN: Use Case */
1560
        $arrayWithDraftVersion2 = $this->createUpdatedDraftVersion2NotAdmin();
1561
        /* END: Use Case */
1562
1563
        $this->assertInstanceOf(
1564
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1565
            $arrayWithDraftVersion2[0]
1566
        );
1567
1568
        $this->assertEquals(
1569
            $this->generateId('user', $arrayWithDraftVersion2[1]),
1570
            $arrayWithDraftVersion2[0]->versionInfo->creatorId,
1571
            'creatorId is not properly set on new Version'
1572
        );
1573
1574
        return $arrayWithDraftVersion2[0];
1575
    }
1576
1577
    /**
1578
     * Test for the updateContent() method.
1579
     *
1580
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1581
     *
1582
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1583
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1584
     */
1585
    public function testUpdateContentSetsExpectedFields($content)
1586
    {
1587
        $actual = $this->normalizeFields($content->getFields());
1588
1589
        $expected = [
1590
            new Field(
1591
                [
1592
                    'id' => 0,
1593
                    'value' => true,
1594
                    'languageCode' => 'eng-GB',
1595
                    'fieldDefIdentifier' => 'description',
1596
                    'fieldTypeIdentifier' => 'ezrichtext',
1597
                ]
1598
            ),
1599
            new Field(
1600
                [
1601
                    'id' => 0,
1602
                    'value' => true,
1603
                    'languageCode' => 'eng-US',
1604
                    'fieldDefIdentifier' => 'description',
1605
                    'fieldTypeIdentifier' => 'ezrichtext',
1606
                ]
1607
            ),
1608
            new Field(
1609
                [
1610
                    'id' => 0,
1611
                    'value' => true,
1612
                    'languageCode' => 'eng-GB',
1613
                    'fieldDefIdentifier' => 'name',
1614
                    'fieldTypeIdentifier' => 'ezstring',
1615
                ]
1616
            ),
1617
            new Field(
1618
                [
1619
                    'id' => 0,
1620
                    'value' => true,
1621
                    'languageCode' => 'eng-US',
1622
                    'fieldDefIdentifier' => 'name',
1623
                    'fieldTypeIdentifier' => 'ezstring',
1624
                ]
1625
            ),
1626
        ];
1627
1628
        $this->assertEquals($expected, $actual);
1629
    }
1630
1631
    /**
1632
     * Test for the updateContent() method.
1633
     *
1634
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1635
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
1636
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1637
     */
1638 View Code Duplication
    public function testUpdateContentThrowsBadStateException()
1639
    {
1640
        $repository = $this->getRepository();
1641
1642
        $contentService = $repository->getContentService();
1643
1644
        /* BEGIN: Use Case */
1645
        $content = $this->createContentVersion1();
1646
1647
        // Now create an update struct and modify some fields
1648
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1649
        $contentUpdateStruct->setField('title', 'An awesome² story about ezp.');
1650
        $contentUpdateStruct->setField('title', 'An awesome²³ story about ezp.', 'eng-GB');
1651
1652
        $contentUpdateStruct->initialLanguageCode = 'eng-US';
1653
1654
        // This call will fail with a "BadStateException", because $publishedContent
1655
        // is not a draft.
1656
        $contentService->updateContent(
1657
            $content->getVersionInfo(),
1658
            $contentUpdateStruct
1659
        );
1660
        /* END: Use Case */
1661
    }
1662
1663
    /**
1664
     * Test for the updateContent() method.
1665
     *
1666
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1667
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1668
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1669
     */
1670 View Code Duplication
    public function testUpdateContentThrowsInvalidArgumentExceptionWhenFieldTypeDoesNotAccept()
1671
    {
1672
        $repository = $this->getRepository();
1673
1674
        $contentService = $repository->getContentService();
1675
1676
        /* BEGIN: Use Case */
1677
        $draft = $this->createContentDraftVersion1();
1678
1679
        // Now create an update struct and modify some fields
1680
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1681
        // The name field does not accept a stdClass object as its input
1682
        $contentUpdateStruct->setField('name', new \stdClass(), 'eng-US');
1683
1684
        // Throws an InvalidArgumentException, since the value for field "name"
1685
        // is not accepted
1686
        $contentService->updateContent(
1687
            $draft->getVersionInfo(),
1688
            $contentUpdateStruct
1689
        );
1690
        /* END: Use Case */
1691
    }
1692
1693
    /**
1694
     * Test for the updateContent() method.
1695
     *
1696
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1697
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
1698
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1699
     */
1700 View Code Duplication
    public function testUpdateContentWhenMandatoryFieldIsEmpty()
1701
    {
1702
        $repository = $this->getRepository();
1703
1704
        $contentService = $repository->getContentService();
1705
1706
        /* BEGIN: Use Case */
1707
        $draft = $this->createContentDraftVersion1();
1708
1709
        // Now create an update struct and set a mandatory field to null
1710
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1711
        $contentUpdateStruct->setField('name', null);
1712
1713
        // Don't set this, then the above call without languageCode will fail
1714
        $contentUpdateStruct->initialLanguageCode = 'eng-US';
1715
1716
        // This call will fail with a "ContentFieldValidationException", because the
1717
        // mandatory "name" field is empty.
1718
        $contentService->updateContent(
1719
            $draft->getVersionInfo(),
1720
            $contentUpdateStruct
1721
        );
1722
        /* END: Use Case */
1723
    }
1724
1725
    /**
1726
     * Test for the updateContent() method.
1727
     *
1728
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1729
     * @expectedException \eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException
1730
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1731
     */
1732
    public function testUpdateContentThrowsContentFieldValidationException()
1733
    {
1734
        $repository = $this->getRepository();
1735
1736
        /* BEGIN: Use Case */
1737
        $contentTypeService = $repository->getContentTypeService();
1738
        $contentService = $repository->getContentService();
1739
1740
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
1741
1742
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
1743
        $contentCreate->setField('name', 'An awesome Sidelfingen folder');
1744
1745
        $draft = $contentService->createContent($contentCreate);
1746
1747
        $contentUpdate = $contentService->newContentUpdateStruct();
1748
        // Violates string length constraint
1749
        $contentUpdate->setField('short_name', str_repeat('a', 200), 'eng-US');
1750
1751
        // Throws ContentFieldValidationException because the string length
1752
        // validation of the field "short_name" fails
1753
        $contentService->updateContent($draft->getVersionInfo(), $contentUpdate);
1754
        /* END: Use Case */
1755
    }
1756
1757
    /**
1758
     * Test for the updateContent() method.
1759
     *
1760
     * @covers \eZ\Publish\API\Repository\ContentService::updateContent()
1761
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1762
     */
1763
    public function testUpdateContentValidatorIgnoresRequiredFieldsOfNotUpdatedLanguages()
1764
    {
1765
        $repository = $this->getRepository();
1766
        /* BEGIN: Use Case */
1767
        $contentTypeService = $repository->getContentTypeService();
1768
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
1769
1770
        // Create multilangual content
1771
        $contentService = $repository->getContentService();
1772
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
1773
        $contentCreate->setField('name', 'An awesome Sidelfingen folder', 'eng-US');
1774
        $contentCreate->setField('name', 'An awesome Sidelfingen folder', 'eng-GB');
1775
1776
        $contentDraft = $contentService->createContent($contentCreate);
1777
1778
        // 2. Update content type definition
1779
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
1780
1781
        $fieldDefinition = $contentType->getFieldDefinition('description');
1782
        $fieldDefinitionUpdate = $contentTypeService->newFieldDefinitionUpdateStruct();
1783
        $fieldDefinitionUpdate->identifier = 'description';
1784
        $fieldDefinitionUpdate->isRequired = true;
1785
1786
        $contentTypeService->updateFieldDefinition(
1787
            $contentTypeDraft,
1788
            $fieldDefinition,
1789
            $fieldDefinitionUpdate
1790
        );
1791
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1792
1793
        // 3. Update only eng-US translation
1794
        $description = new DOMDocument();
1795
        $description->loadXML(<<<XML
1796
<?xml version="1.0" encoding="UTF-8"?>
1797
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ezxhtml="http://ez.no/xmlns/ezpublish/docbook/xhtml" xmlns:ezcustom="http://ez.no/xmlns/ezpublish/docbook/custom" version="5.0-variant ezpublish-1.0">
1798
    <para>Lorem ipsum dolor</para>
1799
</section>
1800
XML
1801
        );
1802
1803
        $contentUpdate = $contentService->newContentUpdateStruct();
1804
        $contentUpdate->setField('name', 'An awesome Sidelfingen folder (updated)', 'eng-US');
1805
        $contentUpdate->setField('description', $description);
1806
1807
        $contentService->updateContent($contentDraft->getVersionInfo(), $contentUpdate);
1808
        /* END: Use Case */
1809
    }
1810
1811
    /**
1812
     * Test for the updateContent() method.
1813
     *
1814
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1815
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1816
     */
1817
    public function testUpdateContentWithNotUpdatingMandatoryField()
1818
    {
1819
        $repository = $this->getRepository();
1820
1821
        $contentService = $repository->getContentService();
1822
1823
        /* BEGIN: Use Case */
1824
        $draft = $this->createContentDraftVersion1();
1825
1826
        // Now create an update struct which does not overwrite mandatory
1827
        // fields
1828
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1829
        $contentUpdateStruct->setField(
1830
            'description',
1831
            '<?xml version="1.0" encoding="UTF-8"?><section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0-variant ezpublish-1.0"/>'
1832
        );
1833
1834
        // Don't set this, then the above call without languageCode will fail
1835
        $contentUpdateStruct->initialLanguageCode = 'eng-US';
1836
1837
        // This will only update the "description" field in the "eng-US"
1838
        // language
1839
        $updatedDraft = $contentService->updateContent(
1840
            $draft->getVersionInfo(),
1841
            $contentUpdateStruct
1842
        );
1843
        /* END: Use Case */
1844
1845
        foreach ($updatedDraft->getFields() as $field) {
1846
            if ($field->languageCode === 'eng-US' && $field->fieldDefIdentifier === 'name' && $field->value !== null) {
1847
                // Found field
1848
                return;
1849
            }
1850
        }
1851
        $this->fail(
1852
            'Field with identifier "name" in language "eng-US" could not be found or has empty value.'
1853
        );
1854
    }
1855
1856
    /**
1857
     * Test for the createContentDraft() method.
1858
     *
1859
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft($contentInfo, $versionInfo)
1860
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1861
     */
1862 View Code Duplication
    public function testCreateContentDraftWithSecondParameter()
1863
    {
1864
        $repository = $this->getRepository();
1865
1866
        $contentService = $repository->getContentService();
1867
1868
        /* BEGIN: Use Case */
1869
        $contentVersion2 = $this->createContentVersion2();
1870
1871
        // Now we create a new draft from the initial version
1872
        $draftedContentReloaded = $contentService->createContentDraft(
1873
            $contentVersion2->contentInfo,
1874
            $contentVersion2->getVersionInfo()
1875
        );
1876
        /* END: Use Case */
1877
1878
        $this->assertEquals(3, $draftedContentReloaded->getVersionInfo()->versionNo);
1879
    }
1880
1881
    /**
1882
     * Test for the createContentDraft() method with third parameter.
1883
     *
1884
     * @covers \eZ\Publish\Core\Repository\ContentService::createContentDraft
1885
     */
1886 View Code Duplication
    public function testCreateContentDraftWithThirdParameter()
1887
    {
1888
        $repository = $this->getRepository();
1889
1890
        $contentService = $repository->getContentService();
1891
1892
        $content = $contentService->loadContent(4);
1893
        $user = $this->createUserVersion1();
1894
1895
        $draftContent = $contentService->createContentDraft(
1896
            $content->contentInfo,
1897
            $content->getVersionInfo(),
1898
            $user
1899
        );
1900
1901
        $this->assertInstanceOf(
1902
            Content::class,
1903
            $draftContent
1904
        );
1905
    }
1906
1907
    /**
1908
     * Test for the publishVersion() method.
1909
     *
1910
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1911
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1912
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1913
     */
1914 View Code Duplication
    public function testPublishVersionFromContentDraft()
1915
    {
1916
        $repository = $this->getRepository();
1917
1918
        $contentService = $repository->getContentService();
1919
1920
        /* BEGIN: Use Case */
1921
        $contentVersion2 = $this->createContentVersion2();
1922
        /* END: Use Case */
1923
1924
        $versionInfo = $contentService->loadVersionInfo($contentVersion2->contentInfo);
1925
1926
        $this->assertEquals(
1927
            [
1928
                'status' => VersionInfo::STATUS_PUBLISHED,
1929
                'versionNo' => 2,
1930
            ],
1931
            [
1932
                'status' => $versionInfo->status,
1933
                'versionNo' => $versionInfo->versionNo,
1934
            ]
1935
        );
1936
        $this->assertTrue($versionInfo->isPublished());
1937
        $this->assertFalse($versionInfo->isDraft());
1938
        $this->assertFalse($versionInfo->isArchived());
1939
    }
1940
1941
    /**
1942
     * Test for the publishVersion() method.
1943
     *
1944
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1945
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
1946
     */
1947 View Code Duplication
    public function testPublishVersionFromContentDraftArchivesOldVersion()
1948
    {
1949
        $repository = $this->getRepository();
1950
1951
        $contentService = $repository->getContentService();
1952
1953
        /* BEGIN: Use Case */
1954
        $contentVersion2 = $this->createContentVersion2();
1955
        /* END: Use Case */
1956
1957
        $versionInfo = $contentService->loadVersionInfo($contentVersion2->contentInfo, 1);
1958
1959
        $this->assertEquals(
1960
            [
1961
                'status' => VersionInfo::STATUS_ARCHIVED,
1962
                'versionNo' => 1,
1963
            ],
1964
            [
1965
                'status' => $versionInfo->status,
1966
                'versionNo' => $versionInfo->versionNo,
1967
            ]
1968
        );
1969
        $this->assertTrue($versionInfo->isArchived());
1970
        $this->assertFalse($versionInfo->isDraft());
1971
        $this->assertFalse($versionInfo->isPublished());
1972
    }
1973
1974
    /**
1975
     * Test for the publishVersion() method.
1976
     *
1977
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1978
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
1979
     */
1980
    public function testPublishVersionFromContentDraftUpdatesContentInfoCurrentVersion()
1981
    {
1982
        /* BEGIN: Use Case */
1983
        $contentVersion2 = $this->createContentVersion2();
1984
        /* END: Use Case */
1985
1986
        $this->assertEquals(2, $contentVersion2->contentInfo->currentVersionNo);
1987
    }
1988
1989
    /**
1990
     * Test for the publishVersion() method.
1991
     *
1992
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1993
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
1994
     */
1995 View Code Duplication
    public function testPublishVersionFromOldContentDraftArchivesNewerVersionNo()
1996
    {
1997
        $repository = $this->getRepository();
1998
1999
        $contentService = $repository->getContentService();
2000
2001
        /* BEGIN: Use Case */
2002
        $content = $this->createContentVersion1();
2003
2004
        // Create a new draft with versionNo = 2
2005
        $draftedContentVersion2 = $contentService->createContentDraft($content->contentInfo);
2006
2007
        // Create another new draft with versionNo = 3
2008
        $draftedContentVersion3 = $contentService->createContentDraft($content->contentInfo);
2009
2010
        // Publish draft with versionNo = 3
2011
        $contentService->publishVersion($draftedContentVersion3->getVersionInfo());
2012
2013
        // Publish the first draft with versionNo = 2
2014
        // currentVersionNo is now 2, versionNo 3 will be archived
2015
        $publishedDraft = $contentService->publishVersion($draftedContentVersion2->getVersionInfo());
2016
        /* END: Use Case */
2017
2018
        $this->assertEquals(2, $publishedDraft->contentInfo->currentVersionNo);
2019
    }
2020
2021
    /**
2022
     * Test for the publishVersion() method, and that it creates limited archives.
2023
     *
2024
     * @todo Adapt this when per content type archive limited is added on repository Content Type model.
2025
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
2026
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2027
     */
2028
    public function testPublishVersionNotCreatingUnlimitedArchives()
2029
    {
2030
        $repository = $this->getRepository();
2031
2032
        $contentService = $repository->getContentService();
2033
2034
        $content = $this->createContentVersion1();
2035
2036
        // load first to make sure list gets updated also (cache)
2037
        $versionInfoList = $contentService->loadVersions($content->contentInfo);
2038
        $this->assertEquals(1, count($versionInfoList));
2039
        $this->assertEquals(1, $versionInfoList[0]->versionNo);
2040
2041
        // Create a new draft with versionNo = 2
2042
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2043
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2044
2045
        // Create a new draft with versionNo = 3
2046
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2047
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2048
2049
        // Create a new draft with versionNo = 4
2050
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2051
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2052
2053
        // Create a new draft with versionNo = 5
2054
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2055
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2056
2057
        // Create a new draft with versionNo = 6
2058
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2059
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2060
2061
        // Create a new draft with versionNo = 7
2062
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2063
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2064
2065
        $versionInfoList = $contentService->loadVersions($content->contentInfo);
2066
2067
        $this->assertEquals(6, count($versionInfoList));
2068
        $this->assertEquals(2, $versionInfoList[0]->versionNo);
2069
        $this->assertEquals(7, $versionInfoList[5]->versionNo);
2070
2071
        $this->assertEquals(
2072
            [
2073
                VersionInfo::STATUS_ARCHIVED,
2074
                VersionInfo::STATUS_ARCHIVED,
2075
                VersionInfo::STATUS_ARCHIVED,
2076
                VersionInfo::STATUS_ARCHIVED,
2077
                VersionInfo::STATUS_ARCHIVED,
2078
                VersionInfo::STATUS_PUBLISHED,
2079
            ],
2080
            [
2081
                $versionInfoList[0]->status,
2082
                $versionInfoList[1]->status,
2083
                $versionInfoList[2]->status,
2084
                $versionInfoList[3]->status,
2085
                $versionInfoList[4]->status,
2086
                $versionInfoList[5]->status,
2087
            ]
2088
        );
2089
    }
2090
2091
    /**
2092
     * Test for the newContentMetadataUpdateStruct() method.
2093
     *
2094
     * @covers \eZ\Publish\API\Repository\ContentService::newContentMetadataUpdateStruct
2095
     * @group user
2096
     */
2097
    public function testNewContentMetadataUpdateStruct()
2098
    {
2099
        $repository = $this->getRepository();
2100
2101
        /* BEGIN: Use Case */
2102
        $contentService = $repository->getContentService();
2103
2104
        // Creates a new metadata update struct
2105
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
2106
2107
        foreach ($metadataUpdate as $propertyName => $propertyValue) {
0 ignored issues
show
Bug introduced by
The expression $metadataUpdate of type object<eZ\Publish\API\Re...ntMetadataUpdateStruct> is not traversable.
Loading history...
2108
            $this->assertNull($propertyValue, "Property '{$propertyName}' initial value should be null'");
2109
        }
2110
2111
        $metadataUpdate->remoteId = 'aaaabbbbccccddddeeeeffff11112222';
2112
        $metadataUpdate->mainLanguageCode = 'eng-GB';
2113
        $metadataUpdate->alwaysAvailable = false;
2114
        /* END: Use Case */
2115
2116
        $this->assertInstanceOf(
2117
            ContentMetadataUpdateStruct::class,
2118
            $metadataUpdate
2119
        );
2120
    }
2121
2122
    /**
2123
     * Test for the updateContentMetadata() method.
2124
     *
2125
     * @return \eZ\Publish\API\Repository\Values\Content\Content
2126
     *
2127
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2128
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
2129
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentMetadataUpdateStruct
2130
     * @group user
2131
     */
2132
    public function testUpdateContentMetadata()
2133
    {
2134
        $repository = $this->getRepository();
2135
2136
        $contentService = $repository->getContentService();
2137
2138
        /* BEGIN: Use Case */
2139
        $content = $this->createContentVersion1();
2140
2141
        // Creates a metadata update struct
2142
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
2143
2144
        $metadataUpdate->remoteId = 'aaaabbbbccccddddeeeeffff11112222';
2145
        $metadataUpdate->mainLanguageCode = 'eng-GB';
2146
        $metadataUpdate->alwaysAvailable = false;
2147
        $metadataUpdate->publishedDate = $this->createDateTime(441759600); // 1984/01/01
2148
        $metadataUpdate->modificationDate = $this->createDateTime(441759600); // 1984/01/01
2149
2150
        // Update the metadata of the published content object
2151
        $content = $contentService->updateContentMetadata(
2152
            $content->contentInfo,
2153
            $metadataUpdate
2154
        );
2155
        /* END: Use Case */
2156
2157
        $this->assertInstanceOf(
2158
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
2159
            $content
2160
        );
2161
2162
        return $content;
2163
    }
2164
2165
    /**
2166
     * Test for the updateContentMetadata() method.
2167
     *
2168
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
2169
     *
2170
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2171
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
2172
     */
2173
    public function testUpdateContentMetadataSetsExpectedProperties($content)
2174
    {
2175
        $contentInfo = $content->contentInfo;
2176
2177
        $this->assertEquals(
2178
            [
2179
                'remoteId' => 'aaaabbbbccccddddeeeeffff11112222',
2180
                'sectionId' => $this->generateId('section', 1),
2181
                'alwaysAvailable' => false,
2182
                'currentVersionNo' => 1,
2183
                'mainLanguageCode' => 'eng-GB',
2184
                'modificationDate' => $this->createDateTime(441759600),
2185
                'ownerId' => $this->getRepository()->getCurrentUser()->id,
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
2186
                'published' => true,
2187
                'publishedDate' => $this->createDateTime(441759600),
2188
            ],
2189
            [
2190
                'remoteId' => $contentInfo->remoteId,
2191
                'sectionId' => $contentInfo->sectionId,
2192
                'alwaysAvailable' => $contentInfo->alwaysAvailable,
2193
                'currentVersionNo' => $contentInfo->currentVersionNo,
2194
                'mainLanguageCode' => $contentInfo->mainLanguageCode,
2195
                'modificationDate' => $contentInfo->modificationDate,
2196
                'ownerId' => $contentInfo->ownerId,
2197
                'published' => $contentInfo->published,
2198
                'publishedDate' => $contentInfo->publishedDate,
2199
            ]
2200
        );
2201
    }
2202
2203
    /**
2204
     * Test for the updateContentMetadata() method.
2205
     *
2206
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
2207
     *
2208
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2209
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
2210
     */
2211
    public function testUpdateContentMetadataNotUpdatesContentVersion($content)
2212
    {
2213
        $this->assertEquals(1, $content->getVersionInfo()->versionNo);
2214
    }
2215
2216
    /**
2217
     * Test for the updateContentMetadata() method.
2218
     *
2219
     * @covers \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2220
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2221
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
2222
     */
2223
    public function testUpdateContentMetadataThrowsInvalidArgumentExceptionOnDuplicateRemoteId()
2224
    {
2225
        $repository = $this->getRepository();
2226
2227
        $contentService = $repository->getContentService();
2228
2229
        /* BEGIN: Use Case */
2230
        // RemoteId of the "Media" page of an eZ Publish demo installation
2231
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
2232
2233
        $content = $this->createContentVersion1();
2234
2235
        // Creates a metadata update struct
2236
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
2237
        $metadataUpdate->remoteId = $mediaRemoteId;
2238
2239
        // This call will fail with an "InvalidArgumentException", because the
2240
        // specified remoteId is already used by the "Media" page.
2241
        $contentService->updateContentMetadata(
2242
            $content->contentInfo,
2243
            $metadataUpdate
2244
        );
2245
        /* END: Use Case */
2246
    }
2247
2248
    /**
2249
     * Test for the updateContentMetadata() method.
2250
     *
2251
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContentMetadata
2252
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2253
     */
2254
    public function testUpdateContentMetadataThrowsInvalidArgumentExceptionOnNoMetadataPropertiesSet()
2255
    {
2256
        $repository = $this->getRepository();
2257
2258
        $contentService = $repository->getContentService();
2259
2260
        $contentInfo = $contentService->loadContentInfo(4);
2261
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
2262
2263
        // Throws an exception because no properties are set in $contentMetadataUpdateStruct
2264
        $contentService->updateContentMetadata($contentInfo, $contentMetadataUpdateStruct);
2265
    }
2266
2267
    /**
2268
     * Test for the deleteContent() method.
2269
     *
2270
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
2271
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2272
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2273
     */
2274 View Code Duplication
    public function testDeleteContent()
2275
    {
2276
        $repository = $this->getRepository();
2277
2278
        $contentService = $repository->getContentService();
2279
        $locationService = $repository->getLocationService();
2280
2281
        /* BEGIN: Use Case */
2282
        $contentVersion2 = $this->createContentVersion2();
2283
2284
        // Load the locations for this content object
2285
        $locations = $locationService->loadLocations($contentVersion2->contentInfo);
2286
2287
        // This will delete the content, all versions and the associated locations
2288
        $contentService->deleteContent($contentVersion2->contentInfo);
2289
        /* END: Use Case */
2290
2291
        foreach ($locations as $location) {
2292
            $locationService->loadLocation($location->id);
2293
        }
2294
    }
2295
2296
    /**
2297
     * Test for the deleteContent() method.
2298
     *
2299
     * Test for issue EZP-21057:
2300
     * "contentService: Unable to delete a content with an empty file attribute"
2301
     *
2302
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
2303
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2304
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2305
     */
2306 View Code Duplication
    public function testDeleteContentWithEmptyBinaryField()
2307
    {
2308
        $repository = $this->getRepository();
2309
2310
        $contentService = $repository->getContentService();
2311
        $locationService = $repository->getLocationService();
2312
2313
        /* BEGIN: Use Case */
2314
        $contentVersion = $this->createContentVersion1EmptyBinaryField();
2315
2316
        // Load the locations for this content object
2317
        $locations = $locationService->loadLocations($contentVersion->contentInfo);
2318
2319
        // This will delete the content, all versions and the associated locations
2320
        $contentService->deleteContent($contentVersion->contentInfo);
2321
        /* END: Use Case */
2322
2323
        foreach ($locations as $location) {
2324
            $locationService->loadLocation($location->id);
2325
        }
2326
    }
2327
2328
    /**
2329
     * Test for the loadContentDrafts() method.
2330
     *
2331
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts()
2332
     */
2333
    public function testLoadContentDraftsReturnsEmptyArrayByDefault()
2334
    {
2335
        $repository = $this->getRepository();
2336
2337
        /* BEGIN: Use Case */
2338
        $contentService = $repository->getContentService();
2339
2340
        $contentDrafts = $contentService->loadContentDrafts();
2341
        /* END: Use Case */
2342
2343
        $this->assertSame([], $contentDrafts);
2344
    }
2345
2346
    /**
2347
     * Test for the loadContentDrafts() method.
2348
     *
2349
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts()
2350
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
2351
     */
2352
    public function testLoadContentDrafts()
2353
    {
2354
        $repository = $this->getRepository();
2355
2356
        /* BEGIN: Use Case */
2357
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
2358
        // of a eZ Publish demo installation.
2359
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
2360
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
2361
2362
        $contentService = $repository->getContentService();
2363
2364
        // "Media" content object
2365
        $mediaContentInfo = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
2366
2367
        // "eZ Publish Demo Design ..." content object
2368
        $demoDesignContentInfo = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
2369
2370
        // Create some drafts
2371
        $contentService->createContentDraft($mediaContentInfo);
2372
        $contentService->createContentDraft($demoDesignContentInfo);
2373
2374
        // Now $contentDrafts should contain two drafted versions
2375
        $draftedVersions = $contentService->loadContentDrafts();
2376
        /* END: Use Case */
2377
2378
        $actual = [
2379
            $draftedVersions[0]->status,
2380
            $draftedVersions[0]->getContentInfo()->remoteId,
2381
            $draftedVersions[1]->status,
2382
            $draftedVersions[1]->getContentInfo()->remoteId,
2383
        ];
2384
        sort($actual, SORT_STRING);
2385
2386
        $this->assertEquals(
2387
            [
2388
                VersionInfo::STATUS_DRAFT,
2389
                VersionInfo::STATUS_DRAFT,
2390
                $demoDesignRemoteId,
2391
                $mediaRemoteId,
2392
            ],
2393
            $actual
2394
        );
2395
    }
2396
2397
    /**
2398
     * Test for the loadContentDrafts() method.
2399
     *
2400
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts($user)
2401
     */
2402
    public function testLoadContentDraftsWithFirstParameter()
2403
    {
2404
        $repository = $this->getRepository();
2405
2406
        /* BEGIN: Use Case */
2407
        $user = $this->createUserVersion1();
2408
2409
        // Get current user
2410
        $oldCurrentUser = $repository->getCurrentUser();
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::getCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::getCurrentUserReference() instead. Get current user. Loads the full user object if not already loaded, if you only need to know user id use {@see getCurrentUserReference()}

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
2411
2412
        // Set new editor as user
2413
        $repository->setCurrentUser($user);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::setCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::setCurrentUserReference() instead. Sets the current user to the given $user.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
2414
2415
        // Remote id of the "Media" content object in an eZ Publish demo installation.
2416
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
2417
2418
        $contentService = $repository->getContentService();
2419
2420
        // "Media" content object
2421
        $mediaContentInfo = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
2422
2423
        // Create a content draft
2424
        $contentService->createContentDraft($mediaContentInfo);
2425
2426
        // Reset to previous current user
2427
        $repository->setCurrentUser($oldCurrentUser);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::setCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::setCurrentUserReference() instead. Sets the current user to the given $user.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
2428
2429
        // Now $contentDrafts for the previous current user and the new user
2430
        $newCurrentUserDrafts = $contentService->loadContentDrafts($user);
2431
        $oldCurrentUserDrafts = $contentService->loadContentDrafts($oldCurrentUser);
2432
        /* END: Use Case */
2433
2434
        $this->assertSame([], $oldCurrentUserDrafts);
2435
2436
        $this->assertEquals(
2437
            [
2438
                VersionInfo::STATUS_DRAFT,
2439
                $mediaRemoteId,
2440
            ],
2441
            [
2442
                $newCurrentUserDrafts[0]->status,
2443
                $newCurrentUserDrafts[0]->getContentInfo()->remoteId,
2444
            ]
2445
        );
2446
        $this->assertTrue($newCurrentUserDrafts[0]->isDraft());
2447
        $this->assertFalse($newCurrentUserDrafts[0]->isArchived());
2448
        $this->assertFalse($newCurrentUserDrafts[0]->isPublished());
2449
    }
2450
2451
    /**
2452
     * Test for the loadVersionInfo() method.
2453
     *
2454
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo($contentInfo, $versionNo)
2455
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2456
     */
2457
    public function testLoadVersionInfoWithSecondParameter()
2458
    {
2459
        $repository = $this->getRepository();
2460
2461
        $contentService = $repository->getContentService();
2462
2463
        /* BEGIN: Use Case */
2464
        $publishedContent = $this->createContentVersion1();
2465
2466
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
0 ignored issues
show
Unused Code introduced by
$draftContent is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2467
2468
        // Will return the VersionInfo of the $draftContent
2469
        $versionInfo = $contentService->loadVersionInfoById($publishedContent->id, 2);
2470
        /* END: Use Case */
2471
2472
        $this->assertEquals(2, $versionInfo->versionNo);
2473
2474
        // Check that ContentInfo contained in VersionInfo has correct main Location id set
2475
        $this->assertEquals(
2476
            $publishedContent->getVersionInfo()->getContentInfo()->mainLocationId,
2477
            $versionInfo->getContentInfo()->mainLocationId
2478
        );
2479
    }
2480
2481
    /**
2482
     * Test for the loadVersionInfo() method.
2483
     *
2484
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo($contentInfo, $versionNo)
2485
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2486
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoWithSecondParameter
2487
     */
2488
    public function testLoadVersionInfoThrowsNotFoundExceptionWithSecondParameter()
2489
    {
2490
        $repository = $this->getRepository();
2491
2492
        $contentService = $repository->getContentService();
2493
2494
        /* BEGIN: Use Case */
2495
        $draft = $this->createContentDraftVersion1();
2496
2497
        // This call will fail with a "NotFoundException", because not versionNo
2498
        // 2 exists for this content object.
2499
        $contentService->loadVersionInfo($draft->contentInfo, 2);
2500
        /* END: Use Case */
2501
    }
2502
2503
    /**
2504
     * Test for the loadVersionInfoById() method.
2505
     *
2506
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById($contentId, $versionNo)
2507
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoWithSecondParameter
2508
     */
2509
    public function testLoadVersionInfoByIdWithSecondParameter()
2510
    {
2511
        $repository = $this->getRepository();
2512
2513
        $contentService = $repository->getContentService();
2514
2515
        /* BEGIN: Use Case */
2516
        $publishedContent = $this->createContentVersion1();
2517
2518
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
2519
2520
        // Will return the VersionInfo of the $draftContent
2521
        $versionInfo = $contentService->loadVersionInfoById($publishedContent->id, 2);
2522
        /* END: Use Case */
2523
2524
        $this->assertEquals(2, $versionInfo->versionNo);
2525
2526
        // Check that ContentInfo contained in VersionInfo has correct main Location id set
2527
        $this->assertEquals(
2528
            $publishedContent->getVersionInfo()->getContentInfo()->mainLocationId,
2529
            $versionInfo->getContentInfo()->mainLocationId
2530
        );
2531
2532
        return [
2533
            'versionInfo' => $versionInfo,
2534
            'draftContent' => $draftContent,
2535
        ];
2536
    }
2537
2538
    /**
2539
     * Test for the returned value of the loadVersionInfoById() method.
2540
     *
2541
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoByIdWithSecondParameter
2542
     * @covers \eZ\Publish\API\Repository\ContentService::loadVersionInfoById
2543
     *
2544
     * @param array $data
2545
     */
2546
    public function testLoadVersionInfoByIdWithSecondParameterSetsExpectedVersionInfo(array $data)
2547
    {
2548
        /** @var \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfo */
2549
        $versionInfo = $data['versionInfo'];
2550
        /** @var \eZ\Publish\API\Repository\Values\Content\Content $draftContent */
2551
        $draftContent = $data['draftContent'];
2552
2553
        $this->assertPropertiesCorrect(
2554
            [
2555
                'names' => [
2556
                    'eng-US' => 'An awesome forum',
2557
                ],
2558
                'contentInfo' => new ContentInfo([
2559
                    'id' => $draftContent->contentInfo->id,
2560
                    'contentTypeId' => 28,
2561
                    'name' => 'An awesome forum',
2562
                    'sectionId' => 1,
2563
                    'currentVersionNo' => 1,
2564
                    'published' => true,
2565
                    'ownerId' => 14,
2566
                    // this Content Object is created at the test runtime
2567
                    'modificationDate' => $versionInfo->contentInfo->modificationDate,
2568
                    'publishedDate' => $versionInfo->contentInfo->publishedDate,
2569
                    'alwaysAvailable' => 1,
2570
                    'remoteId' => 'abcdef0123456789abcdef0123456789',
2571
                    'mainLanguageCode' => 'eng-US',
2572
                    'mainLocationId' => $draftContent->contentInfo->mainLocationId,
2573
                    'status' => ContentInfo::STATUS_PUBLISHED,
2574
                ]),
2575
                'id' => $draftContent->versionInfo->id,
2576
                'versionNo' => 2,
2577
                'creatorId' => 14,
2578
                'status' => 0,
2579
                'initialLanguageCode' => 'eng-US',
2580
                'languageCodes' => [
2581
                    'eng-US',
2582
                ],
2583
            ],
2584
            $versionInfo
2585
        );
2586
    }
2587
2588
    /**
2589
     * Test for the loadVersionInfoById() method.
2590
     *
2591
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById($contentId, $versionNo)
2592
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2593
     */
2594 View Code Duplication
    public function testLoadVersionInfoByIdThrowsNotFoundExceptionWithSecondParameter()
2595
    {
2596
        $repository = $this->getRepository();
2597
2598
        $contentService = $repository->getContentService();
2599
2600
        /* BEGIN: Use Case */
2601
        $content = $this->createContentVersion1();
2602
2603
        // This call will fail with a "NotFoundException", because not versionNo
2604
        // 2 exists for this content object.
2605
        $contentService->loadVersionInfoById($content->id, 2);
2606
        /* END: Use Case */
2607
    }
2608
2609
    /**
2610
     * Test for the loadContentByVersionInfo() method.
2611
     *
2612
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByVersionInfo($versionInfo, $languages)
2613
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
2614
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByVersionInfo
2615
     */
2616
    public function testLoadContentByVersionInfoWithSecondParameter()
2617
    {
2618
        $repository = $this->getRepository();
2619
2620
        $sectionId = $this->generateId('section', 1);
2621
        /* BEGIN: Use Case */
2622
        $contentTypeService = $repository->getContentTypeService();
2623
2624
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
2625
2626
        $contentService = $repository->getContentService();
2627
2628
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
2629
2630
        $contentCreateStruct->setField('name', 'Sindelfingen forum²');
2631
2632
        $contentCreateStruct->setField('name', 'Sindelfingen forum²³', 'eng-GB');
2633
2634
        $contentCreateStruct->remoteId = 'abcdef0123456789abcdef0123456789';
2635
        // $sectionId contains the ID of section 1
2636
        $contentCreateStruct->sectionId = $sectionId;
2637
        $contentCreateStruct->alwaysAvailable = true;
2638
2639
        // Create a new content draft
2640
        $content = $contentService->createContent($contentCreateStruct);
2641
2642
        // Now publish this draft
2643
        $publishedContent = $contentService->publishVersion($content->getVersionInfo());
2644
2645
        // Will return a content instance with fields in "eng-US"
2646
        $reloadedContent = $contentService->loadContentByVersionInfo(
2647
            $publishedContent->getVersionInfo(),
2648
            [
2649
                'eng-GB',
2650
            ],
2651
            false
2652
        );
2653
        /* END: Use Case */
2654
2655
        $actual = [];
2656 View Code Duplication
        foreach ($reloadedContent->getFields() as $field) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2657
            $actual[] = new Field(
2658
                [
2659
                    'id' => 0,
2660
                    'value' => ($field->value !== null ? true : null), // Actual value tested by FieldType integration tests
2661
                    'languageCode' => $field->languageCode,
2662
                    'fieldDefIdentifier' => $field->fieldDefIdentifier,
2663
                ]
2664
            );
2665
        }
2666
        usort(
2667
            $actual,
2668 View Code Duplication
            function ($field1, $field2) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2669
                if (0 === ($return = strcasecmp($field1->fieldDefIdentifier, $field2->fieldDefIdentifier))) {
2670
                    return strcasecmp($field1->languageCode, $field2->languageCode);
2671
                }
2672
2673
                return $return;
2674
            }
2675
        );
2676
2677
        $expected = [
2678
            new Field(
2679
                [
2680
                    'id' => 0,
2681
                    'value' => true,
2682
                    'languageCode' => 'eng-GB',
2683
                    'fieldDefIdentifier' => 'description',
2684
                ]
2685
            ),
2686
            new Field(
2687
                [
2688
                    'id' => 0,
2689
                    'value' => true,
2690
                    'languageCode' => 'eng-GB',
2691
                    'fieldDefIdentifier' => 'name',
2692
                ]
2693
            ),
2694
        ];
2695
2696
        $this->assertEquals($expected, $actual);
2697
    }
2698
2699
    /**
2700
     * Test for the loadContentByContentInfo() method.
2701
     *
2702
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages)
2703
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfo
2704
     */
2705
    public function testLoadContentByContentInfoWithLanguageParameters()
2706
    {
2707
        $repository = $this->getRepository();
2708
2709
        $sectionId = $this->generateId('section', 1);
2710
        /* BEGIN: Use Case */
2711
        $contentTypeService = $repository->getContentTypeService();
2712
2713
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
2714
2715
        $contentService = $repository->getContentService();
2716
2717
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
2718
2719
        $contentCreateStruct->setField('name', 'Sindelfingen forum²');
2720
2721
        $contentCreateStruct->setField('name', 'Sindelfingen forum²³', 'eng-GB');
2722
2723
        $contentCreateStruct->remoteId = 'abcdef0123456789abcdef0123456789';
2724
        // $sectionId contains the ID of section 1
2725
        $contentCreateStruct->sectionId = $sectionId;
2726
        $contentCreateStruct->alwaysAvailable = true;
2727
2728
        // Create a new content draft
2729
        $content = $contentService->createContent($contentCreateStruct);
2730
2731
        // Now publish this draft
2732
        $publishedContent = $contentService->publishVersion($content->getVersionInfo());
2733
2734
        // Will return a content instance with fields in "eng-US"
2735
        $reloadedContent = $contentService->loadContentByContentInfo(
2736
            $publishedContent->contentInfo,
2737
            [
2738
                'eng-US',
2739
            ],
2740
            null,
2741
            false
2742
        );
2743
        /* END: Use Case */
2744
2745
        $actual = $this->normalizeFields($reloadedContent->getFields());
2746
2747
        $expected = [
2748
            new Field(
2749
                [
2750
                    'id' => 0,
2751
                    'value' => true,
2752
                    'languageCode' => 'eng-US',
2753
                    'fieldDefIdentifier' => 'description',
2754
                    'fieldTypeIdentifier' => 'ezrichtext',
2755
                ]
2756
            ),
2757
            new Field(
2758
                [
2759
                    'id' => 0,
2760
                    'value' => true,
2761
                    'languageCode' => 'eng-US',
2762
                    'fieldDefIdentifier' => 'name',
2763
                    'fieldTypeIdentifier' => 'ezstring',
2764
                ]
2765
            ),
2766
        ];
2767
2768
        $this->assertEquals($expected, $actual);
2769
2770
        // Will return a content instance with fields in "eng-GB" (versions prior to 6.0.0-beta9 returned "eng-US" also)
2771
        $reloadedContent = $contentService->loadContentByContentInfo(
2772
            $publishedContent->contentInfo,
2773
            [
2774
                'eng-GB',
2775
            ],
2776
            null,
2777
            true
2778
        );
2779
2780
        $actual = $this->normalizeFields($reloadedContent->getFields());
2781
2782
        $expected = [
2783
            new Field(
2784
                [
2785
                    'id' => 0,
2786
                    'value' => true,
2787
                    'languageCode' => 'eng-GB',
2788
                    'fieldDefIdentifier' => 'description',
2789
                    'fieldTypeIdentifier' => 'ezrichtext',
2790
                ]
2791
            ),
2792
            new Field(
2793
                [
2794
                    'id' => 0,
2795
                    'value' => true,
2796
                    'languageCode' => 'eng-GB',
2797
                    'fieldDefIdentifier' => 'name',
2798
                    'fieldTypeIdentifier' => 'ezstring',
2799
                ]
2800
            ),
2801
        ];
2802
2803
        $this->assertEquals($expected, $actual);
2804
2805
        // Will return a content instance with fields in main language "eng-US", as "fre-FR" does not exists
2806
        $reloadedContent = $contentService->loadContentByContentInfo(
2807
            $publishedContent->contentInfo,
2808
            [
2809
                'fre-FR',
2810
            ],
2811
            null,
2812
            true
2813
        );
2814
2815
        $actual = $this->normalizeFields($reloadedContent->getFields());
2816
2817
        $expected = [
2818
            new Field(
2819
                [
2820
                    'id' => 0,
2821
                    'value' => true,
2822
                    'languageCode' => 'eng-US',
2823
                    'fieldDefIdentifier' => 'description',
2824
                    'fieldTypeIdentifier' => 'ezrichtext',
2825
                ]
2826
            ),
2827
            new Field(
2828
                [
2829
                    'id' => 0,
2830
                    'value' => true,
2831
                    'languageCode' => 'eng-US',
2832
                    'fieldDefIdentifier' => 'name',
2833
                    'fieldTypeIdentifier' => 'ezstring',
2834
                ]
2835
            ),
2836
        ];
2837
2838
        $this->assertEquals($expected, $actual);
2839
    }
2840
2841
    /**
2842
     * Test for the loadContentByContentInfo() method.
2843
     *
2844
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages, $versionNo)
2845
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfo
2846
     */
2847 View Code Duplication
    public function testLoadContentByContentInfoWithVersionNumberParameter()
2848
    {
2849
        $repository = $this->getRepository();
2850
2851
        $contentService = $repository->getContentService();
2852
2853
        /* BEGIN: Use Case */
2854
        $publishedContent = $this->createContentVersion1();
2855
2856
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
0 ignored issues
show
Unused Code introduced by
$draftContent is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2857
2858
        // This content instance is identical to $draftContent
2859
        $draftContentReloaded = $contentService->loadContentByContentInfo(
2860
            $publishedContent->contentInfo,
2861
            null,
2862
            2
2863
        );
2864
        /* END: Use Case */
2865
2866
        $this->assertEquals(
2867
            2,
2868
            $draftContentReloaded->getVersionInfo()->versionNo
2869
        );
2870
2871
        // Check that ContentInfo contained in reloaded draft Content has correct main Location id set
2872
        $this->assertEquals(
2873
            $publishedContent->versionInfo->contentInfo->mainLocationId,
2874
            $draftContentReloaded->versionInfo->contentInfo->mainLocationId
2875
        );
2876
    }
2877
2878
    /**
2879
     * Test for the loadContentByContentInfo() method.
2880
     *
2881
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages, $versionNo)
2882
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2883
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfoWithVersionNumberParameter
2884
     */
2885 View Code Duplication
    public function testLoadContentByContentInfoThrowsNotFoundExceptionWithVersionNumberParameter()
2886
    {
2887
        $repository = $this->getRepository();
2888
2889
        $contentService = $repository->getContentService();
2890
2891
        /* BEGIN: Use Case */
2892
        $content = $this->createContentVersion1();
2893
2894
        // This call will fail with a "NotFoundException", because no content
2895
        // with versionNo = 2 exists.
2896
        $contentService->loadContentByContentInfo($content->contentInfo, null, 2);
2897
        /* END: Use Case */
2898
    }
2899
2900
    /**
2901
     * Test for the loadContent() method.
2902
     *
2903
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages)
2904
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2905
     */
2906 View Code Duplication
    public function testLoadContentWithSecondParameter()
2907
    {
2908
        $repository = $this->getRepository();
2909
2910
        $contentService = $repository->getContentService();
2911
2912
        /* BEGIN: Use Case */
2913
        $draft = $this->createMultipleLanguageDraftVersion1();
2914
2915
        // This draft contains those fields localized with "eng-GB"
2916
        $draftLocalized = $contentService->loadContent($draft->id, ['eng-GB'], null, false);
2917
        /* END: Use Case */
2918
2919
        $this->assertLocaleFieldsEquals($draftLocalized->getFields(), 'eng-GB');
2920
2921
        return $draft;
2922
    }
2923
2924
    /**
2925
     * Test for the loadContent() method using undefined translation.
2926
     *
2927
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentWithSecondParameter
2928
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2929
     *
2930
     * @param \eZ\Publish\API\Repository\Values\Content\Content $contentDraft
2931
     */
2932
    public function testLoadContentWithSecondParameterThrowsNotFoundException(Content $contentDraft)
2933
    {
2934
        $repository = $this->getRepository();
2935
2936
        $contentService = $repository->getContentService();
2937
2938
        $contentService->loadContent($contentDraft->id, ['ger-DE'], null, false);
2939
    }
2940
2941
    /**
2942
     * Test for the loadContent() method.
2943
     *
2944
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages, $versionNo)
2945
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2946
     */
2947 View Code Duplication
    public function testLoadContentWithThirdParameter()
2948
    {
2949
        $repository = $this->getRepository();
2950
2951
        $contentService = $repository->getContentService();
2952
2953
        /* BEGIN: Use Case */
2954
        $publishedContent = $this->createContentVersion1();
2955
2956
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
0 ignored issues
show
Unused Code introduced by
$draftContent is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2957
2958
        // This content instance is identical to $draftContent
2959
        $draftContentReloaded = $contentService->loadContent($publishedContent->id, null, 2);
2960
        /* END: Use Case */
2961
2962
        $this->assertEquals(2, $draftContentReloaded->getVersionInfo()->versionNo);
2963
2964
        // Check that ContentInfo contained in reloaded draft Content has correct main Location id set
2965
        $this->assertEquals(
2966
            $publishedContent->versionInfo->contentInfo->mainLocationId,
2967
            $draftContentReloaded->versionInfo->contentInfo->mainLocationId
2968
        );
2969
    }
2970
2971
    /**
2972
     * Test for the loadContent() method.
2973
     *
2974
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages, $versionNo)
2975
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
2976
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentWithThirdParameter
2977
     */
2978 View Code Duplication
    public function testLoadContentThrowsNotFoundExceptionWithThirdParameter()
2979
    {
2980
        $repository = $this->getRepository();
2981
2982
        $contentService = $repository->getContentService();
2983
2984
        /* BEGIN: Use Case */
2985
        $content = $this->createContentVersion1();
2986
2987
        // This call will fail with a "NotFoundException", because for this
2988
        // content object no versionNo=2 exists.
2989
        $contentService->loadContent($content->id, null, 2);
2990
        /* END: Use Case */
2991
    }
2992
2993
    /**
2994
     * Test for the loadContentByRemoteId() method.
2995
     *
2996
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages)
2997
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2998
     */
2999 View Code Duplication
    public function testLoadContentByRemoteIdWithSecondParameter()
3000
    {
3001
        $repository = $this->getRepository();
3002
3003
        $contentService = $repository->getContentService();
3004
3005
        /* BEGIN: Use Case */
3006
        $draft = $this->createMultipleLanguageDraftVersion1();
3007
3008
        $contentService->publishVersion($draft->versionInfo);
3009
3010
        // This draft contains those fields localized with "eng-GB"
3011
        $draftLocalized = $contentService->loadContentByRemoteId(
3012
            $draft->contentInfo->remoteId,
3013
            ['eng-GB'],
3014
            null,
3015
            false
3016
        );
3017
        /* END: Use Case */
3018
3019
        $this->assertLocaleFieldsEquals($draftLocalized->getFields(), 'eng-GB');
3020
    }
3021
3022
    /**
3023
     * Test for the loadContentByRemoteId() method.
3024
     *
3025
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages, $versionNo)
3026
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3027
     */
3028 View Code Duplication
    public function testLoadContentByRemoteIdWithThirdParameter()
3029
    {
3030
        $repository = $this->getRepository();
3031
3032
        $contentService = $repository->getContentService();
3033
3034
        /* BEGIN: Use Case */
3035
        $publishedContent = $this->createContentVersion1();
3036
3037
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
0 ignored issues
show
Unused Code introduced by
$draftContent is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
3038
3039
        // This content instance is identical to $draftContent
3040
        $draftContentReloaded = $contentService->loadContentByRemoteId(
3041
            $publishedContent->contentInfo->remoteId,
3042
            null,
3043
            2
3044
        );
3045
        /* END: Use Case */
3046
3047
        $this->assertEquals(2, $draftContentReloaded->getVersionInfo()->versionNo);
3048
3049
        // Check that ContentInfo contained in reloaded draft Content has correct main Location id set
3050
        $this->assertEquals(
3051
            $publishedContent->versionInfo->contentInfo->mainLocationId,
3052
            $draftContentReloaded->versionInfo->contentInfo->mainLocationId
3053
        );
3054
    }
3055
3056
    /**
3057
     * Test for the loadContentByRemoteId() method.
3058
     *
3059
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages, $versionNo)
3060
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
3061
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteIdWithThirdParameter
3062
     */
3063
    public function testLoadContentByRemoteIdThrowsNotFoundExceptionWithThirdParameter()
3064
    {
3065
        $repository = $this->getRepository();
3066
3067
        $contentService = $repository->getContentService();
3068
3069
        /* BEGIN: Use Case */
3070
        $content = $this->createContentVersion1();
3071
3072
        // This call will fail with a "NotFoundException", because for this
3073
        // content object no versionNo=2 exists.
3074
        $contentService->loadContentByRemoteId(
3075
            $content->contentInfo->remoteId,
3076
            null,
3077
            2
3078
        );
3079
        /* END: Use Case */
3080
    }
3081
3082
    /**
3083
     * Test that retrieval of translated name field respects prioritized language list.
3084
     *
3085
     * @dataProvider getPrioritizedLanguageList
3086
     * @param string[]|null $languageCodes
3087
     */
3088
    public function testLoadContentWithPrioritizedLanguagesList($languageCodes)
3089
    {
3090
        $repository = $this->getRepository();
3091
3092
        $contentService = $repository->getContentService();
3093
3094
        $content = $this->createContentVersion2();
3095
3096
        $content = $contentService->loadContent($content->id, $languageCodes);
3097
3098
        $expectedName = $content->getVersionInfo()->getName(
3099
            isset($languageCodes[0]) ? $languageCodes[0] : null
3100
        );
3101
        $nameValue = $content->getFieldValue('name');
3102
        /** @var \eZ\Publish\Core\FieldType\TextLine\Value $nameValue */
3103
        self::assertEquals($expectedName, $nameValue->text);
3104
        self::assertEquals($expectedName, $content->getVersionInfo()->getName());
3105
        // Also check value on shortcut method on content
3106
        self::assertEquals($expectedName, $content->getName());
3107
    }
3108
3109
    /**
3110
     * @return array
3111
     */
3112
    public function getPrioritizedLanguageList()
3113
    {
3114
        return [
3115
            [['eng-US']],
3116
            [['eng-GB']],
3117
            [['eng-GB', 'eng-US']],
3118
            [['eng-US', 'eng-GB']],
3119
        ];
3120
    }
3121
3122
    /**
3123
     * Test for the deleteVersion() method.
3124
     *
3125
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
3126
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
3127
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
3128
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3129
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
3130
     */
3131
    public function testDeleteVersion()
3132
    {
3133
        $repository = $this->getRepository();
3134
3135
        $contentService = $repository->getContentService();
3136
3137
        /* BEGIN: Use Case */
3138
        $content = $this->createContentVersion1();
3139
3140
        // Create new draft, because published or last version of the Content can't be deleted
3141
        $draft = $contentService->createContentDraft(
3142
            $content->getVersionInfo()->getContentInfo()
3143
        );
3144
3145
        // Delete the previously created draft
3146
        $contentService->deleteVersion($draft->getVersionInfo());
3147
        /* END: Use Case */
3148
3149
        $versions = $contentService->loadVersions($content->getVersionInfo()->getContentInfo());
3150
3151
        $this->assertCount(1, $versions);
3152
        $this->assertEquals(
3153
            $content->getVersionInfo()->id,
3154
            $versions[0]->id
3155
        );
3156
    }
3157
3158
    /**
3159
     * Test for the deleteVersion() method.
3160
     *
3161
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
3162
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
3163
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
3164
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
3165
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3166
     */
3167
    public function testDeleteVersionThrowsBadStateExceptionOnPublishedVersion()
3168
    {
3169
        $repository = $this->getRepository();
3170
3171
        $contentService = $repository->getContentService();
3172
3173
        /* BEGIN: Use Case */
3174
        $content = $this->createContentVersion1();
3175
3176
        // This call will fail with a "BadStateException", because the content
3177
        // version is currently published.
3178
        $contentService->deleteVersion($content->getVersionInfo());
3179
        /* END: Use Case */
3180
    }
3181
3182
    /**
3183
     * Test for the deleteVersion() method.
3184
     *
3185
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
3186
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
3187
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
3188
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
3189
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3190
     */
3191
    public function testDeleteVersionWorksIfOnlyVersionIsDraft()
3192
    {
3193
        $repository = $this->getRepository();
3194
3195
        $contentService = $repository->getContentService();
3196
3197
        /* BEGIN: Use Case */
3198
        $draft = $this->createContentDraftVersion1();
3199
3200
        $contentService->deleteVersion($draft->getVersionInfo());
3201
3202
        // This call will fail with a "NotFound", because we allow to delete content if remaining version is draft.
3203
        // Can normally only happen if there where always only a draft to begin with, simplifies UI edit API usage.
3204
        $contentService->loadContent($draft->id);
3205
        /* END: Use Case */
3206
    }
3207
3208
    /**
3209
     * Test for the loadVersions() method.
3210
     *
3211
     * @see \eZ\Publish\API\Repository\ContentService::loadVersions()
3212
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3213
     *
3214
     * @return \eZ\Publish\API\Repository\Values\Content\VersionInfo[]
3215
     */
3216
    public function testLoadVersions()
3217
    {
3218
        $repository = $this->getRepository();
3219
3220
        $contentService = $repository->getContentService();
3221
3222
        /* BEGIN: Use Case */
3223
        $contentVersion2 = $this->createContentVersion2();
3224
3225
        // Load versions of this ContentInfo instance
3226
        $versions = $contentService->loadVersions($contentVersion2->contentInfo);
3227
        /* END: Use Case */
3228
3229
        $expectedVersionsOrder = [
3230
            $contentService->loadVersionInfo($contentVersion2->contentInfo, 1),
3231
            $contentService->loadVersionInfo($contentVersion2->contentInfo, 2),
3232
        ];
3233
3234
        $this->assertEquals($expectedVersionsOrder, $versions);
3235
3236
        return $versions;
3237
    }
3238
3239
    /**
3240
     * Test for the loadVersions() method.
3241
     *
3242
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersions
3243
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersions
3244
     *
3245
     * @param \eZ\Publish\API\Repository\Values\Content\VersionInfo[] $versions
3246
     */
3247
    public function testLoadVersionsSetsExpectedVersionInfo(array $versions)
3248
    {
3249
        $this->assertCount(2, $versions);
3250
3251
        $expectedVersions = [
3252
            [
3253
                'versionNo' => 1,
3254
                'creatorId' => 14,
3255
                'status' => VersionInfo::STATUS_ARCHIVED,
3256
                'initialLanguageCode' => 'eng-US',
3257
                'languageCodes' => ['eng-US'],
3258
            ],
3259
            [
3260
                'versionNo' => 2,
3261
                'creatorId' => 10,
3262
                'status' => VersionInfo::STATUS_PUBLISHED,
3263
                'initialLanguageCode' => 'eng-US',
3264
                'languageCodes' => ['eng-US', 'eng-GB'],
3265
            ],
3266
        ];
3267
3268
        $this->assertPropertiesCorrect($expectedVersions[0], $versions[0]);
3269
        $this->assertPropertiesCorrect($expectedVersions[1], $versions[1]);
3270
        $this->assertEquals(
3271
            $versions[0]->creationDate->getTimestamp(),
3272
            $versions[1]->creationDate->getTimestamp(),
3273
            'Creation time did not match within delta of 2 seconds',
3274
            2
3275
        );
3276
        $this->assertEquals(
3277
            $versions[0]->modificationDate->getTimestamp(),
3278
            $versions[1]->modificationDate->getTimestamp(),
3279
            'Creation time did not match within delta of 2 seconds',
3280
            2
3281
        );
3282
        $this->assertTrue($versions[0]->isArchived());
3283
        $this->assertFalse($versions[0]->isDraft());
3284
        $this->assertFalse($versions[0]->isPublished());
3285
3286
        $this->assertTrue($versions[1]->isPublished());
3287
        $this->assertFalse($versions[1]->isDraft());
3288
        $this->assertFalse($versions[1]->isArchived());
3289
    }
3290
3291
    /**
3292
     * Test for the copyContent() method.
3293
     *
3294
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
3295
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3296
     * @group field-type
3297
     */
3298 View Code Duplication
    public function testCopyContent()
3299
    {
3300
        $parentLocationId = $this->generateId('location', 56);
3301
3302
        $repository = $this->getRepository();
3303
3304
        $contentService = $repository->getContentService();
3305
        $locationService = $repository->getLocationService();
3306
3307
        /* BEGIN: Use Case */
3308
        $contentVersion2 = $this->createMultipleLanguageContentVersion2();
3309
3310
        // Configure new target location
3311
        $targetLocationCreate = $locationService->newLocationCreateStruct($parentLocationId);
3312
3313
        $targetLocationCreate->priority = 42;
3314
        $targetLocationCreate->hidden = true;
3315
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
3316
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
3317
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
3318
3319
        // Copy content with all versions and drafts
3320
        $contentCopied = $contentService->copyContent(
3321
            $contentVersion2->contentInfo,
3322
            $targetLocationCreate
3323
        );
3324
        /* END: Use Case */
3325
3326
        $this->assertInstanceOf(
3327
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
3328
            $contentCopied
3329
        );
3330
3331
        $this->assertNotEquals(
3332
            $contentVersion2->contentInfo->remoteId,
3333
            $contentCopied->contentInfo->remoteId
3334
        );
3335
3336
        $this->assertNotEquals(
3337
            $contentVersion2->id,
3338
            $contentCopied->id
3339
        );
3340
3341
        $this->assertEquals(
3342
            2,
3343
            count($contentService->loadVersions($contentCopied->contentInfo))
3344
        );
3345
3346
        $this->assertEquals(2, $contentCopied->getVersionInfo()->versionNo);
3347
3348
        $this->assertAllFieldsEquals($contentCopied->getFields());
3349
3350
        $this->assertDefaultContentStates($contentCopied->contentInfo);
3351
3352
        $this->assertNotNull(
3353
            $contentCopied->contentInfo->mainLocationId,
3354
            'Expected main location to be set given we provided a LocationCreateStruct'
3355
        );
3356
    }
3357
3358
    /**
3359
     * Test for the copyContent() method with ezsettings.default.content.retain_owner_on_copy set to false
3360
     * See settings/test/integration_legacy.yml for service override.
3361
     *
3362
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
3363
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3364
     * @group field-type
3365
     */
3366
    public function testCopyContentWithNewOwner()
3367
    {
3368
        $parentLocationId = $this->generateId('location', 56);
3369
3370
        $repository = $this->getRepository();
3371
3372
        $contentService = $repository->getContentService();
3373
        $locationService = $repository->getLocationService();
3374
        $userService = $repository->getUserService();
3375
3376
        $newOwner = $this->createUser('new_owner', 'foo', 'bar');
3377
        /* BEGIN: Use Case */
3378
        /** @var \eZ\Publish\API\Repository\Values\Content\Content $contentVersion2 */
3379
        $contentVersion2 = $this->createContentDraftVersion1(
3380
            $parentLocationId,
3381
            'forum',
3382
            'name',
3383
            $newOwner
3384
        );
3385
3386
        // Configure new target location
3387
        $targetLocationCreate = $locationService->newLocationCreateStruct($parentLocationId);
3388
3389
        $targetLocationCreate->priority = 42;
3390
        $targetLocationCreate->hidden = true;
3391
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
3392
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
3393
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
3394
3395
        // Copy content with all versions and drafts
3396
        $contentCopied = $contentService->copyContent(
3397
            $contentVersion2->contentInfo,
3398
            $targetLocationCreate
3399
        );
3400
        /* END: Use Case */
3401
3402
        $this->assertEquals(
3403
            $newOwner->id,
3404
            $contentVersion2->contentInfo->ownerId
3405
        );
3406
        $this->assertEquals(
3407
            $userService->loadUserByLogin('admin')->getUserId(),
3408
            $contentCopied->contentInfo->ownerId
3409
        );
3410
    }
3411
3412
    /**
3413
     * Test for the copyContent() method.
3414
     *
3415
     * @see \eZ\Publish\API\Repository\ContentService::copyContent($contentInfo, $destinationLocationCreateStruct, $versionInfo)
3416
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContent
3417
     */
3418 View Code Duplication
    public function testCopyContentWithGivenVersion()
3419
    {
3420
        $parentLocationId = $this->generateId('location', 56);
3421
3422
        $repository = $this->getRepository();
3423
3424
        $contentService = $repository->getContentService();
3425
        $locationService = $repository->getLocationService();
3426
3427
        /* BEGIN: Use Case */
3428
        $contentVersion2 = $this->createContentVersion2();
3429
3430
        // Configure new target location
3431
        $targetLocationCreate = $locationService->newLocationCreateStruct($parentLocationId);
3432
3433
        $targetLocationCreate->priority = 42;
3434
        $targetLocationCreate->hidden = true;
3435
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
3436
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
3437
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
3438
3439
        // Copy only the initial version
3440
        $contentCopied = $contentService->copyContent(
3441
            $contentVersion2->contentInfo,
3442
            $targetLocationCreate,
3443
            $contentService->loadVersionInfo($contentVersion2->contentInfo, 1)
3444
        );
3445
        /* END: Use Case */
3446
3447
        $this->assertInstanceOf(
3448
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
3449
            $contentCopied
3450
        );
3451
3452
        $this->assertNotEquals(
3453
            $contentVersion2->contentInfo->remoteId,
3454
            $contentCopied->contentInfo->remoteId
3455
        );
3456
3457
        $this->assertNotEquals(
3458
            $contentVersion2->id,
3459
            $contentCopied->id
3460
        );
3461
3462
        $this->assertEquals(
3463
            1,
3464
            count($contentService->loadVersions($contentCopied->contentInfo))
3465
        );
3466
3467
        $this->assertEquals(1, $contentCopied->getVersionInfo()->versionNo);
3468
3469
        $this->assertNotNull(
3470
            $contentCopied->contentInfo->mainLocationId,
3471
            'Expected main location to be set given we provided a LocationCreateStruct'
3472
        );
3473
    }
3474
3475
    /**
3476
     * Test for the addRelation() method.
3477
     *
3478
     * @return \eZ\Publish\API\Repository\Values\Content\Content
3479
     *
3480
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3481
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3482
     */
3483
    public function testAddRelation()
3484
    {
3485
        $repository = $this->getRepository();
3486
3487
        $contentService = $repository->getContentService();
3488
3489
        /* BEGIN: Use Case */
3490
        // RemoteId of the "Media" content of an eZ Publish demo installation
3491
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3492
3493
        $draft = $this->createContentDraftVersion1();
3494
3495
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3496
3497
        // Create relation between new content object and "Media" page
3498
        $relation = $contentService->addRelation(
3499
            $draft->getVersionInfo(),
3500
            $media
3501
        );
3502
        /* END: Use Case */
3503
3504
        $this->assertInstanceOf(
3505
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Relation',
3506
            $relation
3507
        );
3508
3509
        return $contentService->loadRelations($draft->getVersionInfo());
3510
    }
3511
3512
    /**
3513
     * Test for the addRelation() method.
3514
     *
3515
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3516
     *
3517
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3518
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3519
     */
3520
    public function testAddRelationAddsRelationToContent($relations)
3521
    {
3522
        $this->assertEquals(
3523
            1,
3524
            count($relations)
3525
        );
3526
    }
3527
3528
    /**
3529
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3530
     */
3531
    protected function assertExpectedRelations($relations)
3532
    {
3533
        $this->assertEquals(
3534
            [
3535
                'type' => Relation::COMMON,
3536
                'sourceFieldDefinitionIdentifier' => null,
3537
                'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3538
                'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3539
            ],
3540
            [
3541
                'type' => $relations[0]->type,
3542
                'sourceFieldDefinitionIdentifier' => $relations[0]->sourceFieldDefinitionIdentifier,
3543
                'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3544
                'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3545
            ]
3546
        );
3547
    }
3548
3549
    /**
3550
     * Test for the addRelation() method.
3551
     *
3552
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3553
     *
3554
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3555
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3556
     */
3557
    public function testAddRelationSetsExpectedRelations($relations)
3558
    {
3559
        $this->assertExpectedRelations($relations);
3560
    }
3561
3562
    /**
3563
     * Test for the createContentDraft() method.
3564
     *
3565
     * @return \eZ\Publish\API\Repository\Values\Content\Relation[]
3566
     *
3567
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
3568
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelationSetsExpectedRelations
3569
     */
3570 View Code Duplication
    public function testCreateContentDraftWithRelations()
3571
    {
3572
        $repository = $this->getRepository();
3573
3574
        $contentService = $repository->getContentService();
3575
3576
        // RemoteId of the "Media" content of an eZ Publish demo installation
3577
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3578
        $draft = $this->createContentDraftVersion1();
3579
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3580
3581
        // Create relation between new content object and "Media" page
3582
        $contentService->addRelation(
3583
            $draft->getVersionInfo(),
3584
            $media
3585
        );
3586
3587
        $content = $contentService->publishVersion($draft->versionInfo);
3588
        $newDraft = $contentService->createContentDraft($content->contentInfo);
3589
3590
        return $contentService->loadRelations($newDraft->getVersionInfo());
3591
    }
3592
3593
    /**
3594
     * Test for the createContentDraft() method.
3595
     *
3596
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3597
     *
3598
     * @return \eZ\Publish\API\Repository\Values\Content\Relation[]
3599
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraftWithRelations
3600
     */
3601
    public function testCreateContentDraftWithRelationsCreatesRelations($relations)
3602
    {
3603
        $this->assertEquals(
3604
            1,
3605
            count($relations)
3606
        );
3607
3608
        return $relations;
3609
    }
3610
3611
    /**
3612
     * Test for the createContentDraft() method.
3613
     *
3614
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3615
     *
3616
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraftWithRelationsCreatesRelations
3617
     */
3618
    public function testCreateContentDraftWithRelationsCreatesExpectedRelations($relations)
3619
    {
3620
        $this->assertExpectedRelations($relations);
3621
    }
3622
3623
    /**
3624
     * Test for the addRelation() method.
3625
     *
3626
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3627
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
3628
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3629
     */
3630 View Code Duplication
    public function testAddRelationThrowsBadStateException()
3631
    {
3632
        $repository = $this->getRepository();
3633
3634
        $contentService = $repository->getContentService();
3635
3636
        /* BEGIN: Use Case */
3637
        // RemoteId of the "Media" page of an eZ Publish demo installation
3638
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3639
3640
        $content = $this->createContentVersion1();
3641
3642
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3643
3644
        // This call will fail with a "BadStateException", because content is
3645
        // published and not a draft.
3646
        $contentService->addRelation(
3647
            $content->getVersionInfo(),
3648
            $media
3649
        );
3650
        /* END: Use Case */
3651
    }
3652
3653
    /**
3654
     * Test for the loadRelations() method.
3655
     *
3656
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
3657
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3658
     */
3659
    public function testLoadRelations()
3660
    {
3661
        $repository = $this->getRepository();
3662
3663
        $contentService = $repository->getContentService();
3664
3665
        /* BEGIN: Use Case */
3666
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3667
        // of a eZ Publish demo installation.
3668
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3669
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3670
3671
        $draft = $this->createContentDraftVersion1();
3672
3673
        // Load other content objects
3674
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3675
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
3676
3677
        // Create relation between new content object and "Media" page
3678
        $contentService->addRelation(
3679
            $draft->getVersionInfo(),
3680
            $media
3681
        );
3682
3683
        // Create another relation with the "Demo Design" page
3684
        $contentService->addRelation(
3685
            $draft->getVersionInfo(),
3686
            $demoDesign
3687
        );
3688
3689
        // Load all relations
3690
        $relations = $contentService->loadRelations($draft->getVersionInfo());
3691
        /* END: Use Case */
3692
3693
        usort(
3694
            $relations,
3695
            function ($rel1, $rel2) {
3696
                return strcasecmp(
3697
                    $rel2->getDestinationContentInfo()->remoteId,
3698
                    $rel1->getDestinationContentInfo()->remoteId
3699
                );
3700
            }
3701
        );
3702
3703
        $this->assertEquals(
3704
            [
3705
                [
3706
                    'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3707
                    'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3708
                ],
3709
                [
3710
                    'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3711
                    'destinationContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
3712
                ],
3713
            ],
3714
            [
3715
                [
3716
                    'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3717
                    'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3718
                ],
3719
                [
3720
                    'sourceContentInfo' => $relations[1]->sourceContentInfo->remoteId,
3721
                    'destinationContentInfo' => $relations[1]->destinationContentInfo->remoteId,
3722
                ],
3723
            ]
3724
        );
3725
    }
3726
3727
    /**
3728
     * Test for the loadRelations() method.
3729
     *
3730
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
3731
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3732
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
3733
     */
3734
    public function testLoadRelationsSkipsArchivedContent()
3735
    {
3736
        $repository = $this->getRepository();
3737
3738
        $contentService = $repository->getContentService();
3739
3740
        /* BEGIN: Use Case */
3741
        $trashService = $repository->getTrashService();
3742
        $locationService = $repository->getLocationService();
3743
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3744
        // of a eZ Publish demo installation.
3745
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3746
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3747
3748
        $draft = $this->createContentDraftVersion1();
3749
3750
        // Load other content objects
3751
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3752
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
3753
3754
        // Create relation between new content object and "Media" page
3755
        $contentService->addRelation(
3756
            $draft->getVersionInfo(),
3757
            $media
3758
        );
3759
3760
        // Create another relation with the "Demo Design" page
3761
        $contentService->addRelation(
3762
            $draft->getVersionInfo(),
3763
            $demoDesign
3764
        );
3765
3766
        $demoDesignLocation = $locationService->loadLocation($demoDesign->mainLocationId);
3767
3768
        // Trashing Content's last Location will change its status to archived,
3769
        // in this case relation towards it will not be loaded.
3770
        $trashService->trash($demoDesignLocation);
3771
3772
        // Load all relations
3773
        $relations = $contentService->loadRelations($draft->getVersionInfo());
3774
        /* END: Use Case */
3775
3776
        $this->assertCount(1, $relations);
3777
        $this->assertEquals(
3778
            [
3779
                [
3780
                    'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3781
                    'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3782
                ],
3783
            ],
3784
            [
3785
                [
3786
                    'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3787
                    'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3788
                ],
3789
            ]
3790
        );
3791
    }
3792
3793
    /**
3794
     * Test for the loadRelations() method.
3795
     *
3796
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
3797
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3798
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
3799
     */
3800
    public function testLoadRelationsSkipsDraftContent()
3801
    {
3802
        $repository = $this->getRepository();
3803
3804
        $contentService = $repository->getContentService();
3805
3806
        /* BEGIN: Use Case */
3807
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3808
        // of a eZ Publish demo installation.
3809
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3810
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3811
3812
        $draft = $this->createContentDraftVersion1();
3813
3814
        // Load other content objects
3815
        $media = $contentService->loadContentByRemoteId($mediaRemoteId);
3816
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
3817
3818
        // Create draft of "Media" page
3819
        $mediaDraft = $contentService->createContentDraft($media->contentInfo);
3820
3821
        // Create relation between "Media" page and new content object draft.
3822
        // This relation will not be loaded before the draft is published.
3823
        $contentService->addRelation(
3824
            $mediaDraft->getVersionInfo(),
3825
            $draft->getVersionInfo()->getContentInfo()
3826
        );
3827
3828
        // Create another relation with the "Demo Design" page
3829
        $contentService->addRelation(
3830
            $mediaDraft->getVersionInfo(),
3831
            $demoDesign
3832
        );
3833
3834
        // Load all relations
3835
        $relations = $contentService->loadRelations($mediaDraft->getVersionInfo());
3836
        /* END: Use Case */
3837
3838
        $this->assertCount(1, $relations);
3839
        $this->assertEquals(
3840
            [
3841
                [
3842
                    'sourceContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3843
                    'destinationContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
3844
                ],
3845
            ],
3846
            [
3847
                [
3848
                    'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3849
                    'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3850
                ],
3851
            ]
3852
        );
3853
    }
3854
3855
    /**
3856
     * Test for the loadReverseRelations() method.
3857
     *
3858
     * @see \eZ\Publish\API\Repository\ContentService::loadReverseRelations()
3859
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3860
     */
3861
    public function testLoadReverseRelations()
3862
    {
3863
        $repository = $this->getRepository();
3864
3865
        $contentService = $repository->getContentService();
3866
3867
        /* BEGIN: Use Case */
3868
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3869
        // of a eZ Publish demo installation.
3870
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3871
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3872
3873
        $versionInfo = $this->createContentVersion1()->getVersionInfo();
3874
        $contentInfo = $versionInfo->getContentInfo();
3875
3876
        // Create some drafts
3877
        $mediaDraft = $contentService->createContentDraft(
3878
            $contentService->loadContentInfoByRemoteId($mediaRemoteId)
3879
        );
3880
        $demoDesignDraft = $contentService->createContentDraft(
3881
            $contentService->loadContentInfoByRemoteId($demoDesignRemoteId)
3882
        );
3883
3884
        // Create relation between new content object and "Media" page
3885
        $relation1 = $contentService->addRelation(
3886
            $mediaDraft->getVersionInfo(),
3887
            $contentInfo
3888
        );
3889
3890
        // Create another relation with the "Demo Design" page
3891
        $relation2 = $contentService->addRelation(
3892
            $demoDesignDraft->getVersionInfo(),
3893
            $contentInfo
3894
        );
3895
3896
        // Publish drafts, so relations become active
3897
        $contentService->publishVersion($mediaDraft->getVersionInfo());
3898
        $contentService->publishVersion($demoDesignDraft->getVersionInfo());
3899
3900
        // Load all relations
3901
        $relations = $contentService->loadRelations($versionInfo);
3902
        $reverseRelations = $contentService->loadReverseRelations($contentInfo);
3903
        /* END: Use Case */
3904
3905
        $this->assertEquals($contentInfo->id, $relation1->getDestinationContentInfo()->id);
3906
        $this->assertEquals($mediaDraft->id, $relation1->getSourceContentInfo()->id);
3907
3908
        $this->assertEquals($contentInfo->id, $relation2->getDestinationContentInfo()->id);
3909
        $this->assertEquals($demoDesignDraft->id, $relation2->getSourceContentInfo()->id);
3910
3911
        $this->assertEquals(0, count($relations));
3912
        $this->assertEquals(2, count($reverseRelations));
3913
3914
        usort(
3915
            $reverseRelations,
3916
            function ($rel1, $rel2) {
3917
                return strcasecmp(
3918
                    $rel2->getSourceContentInfo()->remoteId,
3919
                    $rel1->getSourceContentInfo()->remoteId
3920
                );
3921
            }
3922
        );
3923
3924
        $this->assertEquals(
3925
            [
3926
                [
3927
                    'sourceContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3928
                    'destinationContentInfo' => 'abcdef0123456789abcdef0123456789',
3929
                ],
3930
                [
3931
                    'sourceContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
3932
                    'destinationContentInfo' => 'abcdef0123456789abcdef0123456789',
3933
                ],
3934
            ],
3935
            [
3936
                [
3937
                    'sourceContentInfo' => $reverseRelations[0]->sourceContentInfo->remoteId,
3938
                    'destinationContentInfo' => $reverseRelations[0]->destinationContentInfo->remoteId,
3939
                ],
3940
                [
3941
                    'sourceContentInfo' => $reverseRelations[1]->sourceContentInfo->remoteId,
3942
                    'destinationContentInfo' => $reverseRelations[1]->destinationContentInfo->remoteId,
3943
                ],
3944
            ]
3945
        );
3946
    }
3947
3948
    /**
3949
     * Test for the loadReverseRelations() method.
3950
     *
3951
     * @see \eZ\Publish\API\Repository\ContentService::loadReverseRelations()
3952
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3953
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadReverseRelations
3954
     */
3955
    public function testLoadReverseRelationsSkipsArchivedContent()
3956
    {
3957
        $repository = $this->getRepository();
3958
3959
        $contentService = $repository->getContentService();
3960
3961
        /* BEGIN: Use Case */
3962
        $trashService = $repository->getTrashService();
3963
        $locationService = $repository->getLocationService();
3964
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3965
        // of a eZ Publish demo installation.
3966
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3967
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3968
3969
        $versionInfo = $this->createContentVersion1()->getVersionInfo();
3970
        $contentInfo = $versionInfo->getContentInfo();
3971
3972
        // Create some drafts
3973
        $mediaDraft = $contentService->createContentDraft(
3974
            $contentService->loadContentInfoByRemoteId($mediaRemoteId)
3975
        );
3976
        $demoDesignDraft = $contentService->createContentDraft(
3977
            $contentService->loadContentInfoByRemoteId($demoDesignRemoteId)
3978
        );
3979
3980
        // Create relation between new content object and "Media" page
3981
        $relation1 = $contentService->addRelation(
3982
            $mediaDraft->getVersionInfo(),
3983
            $contentInfo
3984
        );
3985
3986
        // Create another relation with the "Demo Design" page
3987
        $relation2 = $contentService->addRelation(
3988
            $demoDesignDraft->getVersionInfo(),
3989
            $contentInfo
3990
        );
3991
3992
        // Publish drafts, so relations become active
3993
        $contentService->publishVersion($mediaDraft->getVersionInfo());
3994
        $contentService->publishVersion($demoDesignDraft->getVersionInfo());
3995
3996
        $demoDesignLocation = $locationService->loadLocation($demoDesignDraft->contentInfo->mainLocationId);
3997
3998
        // Trashing Content's last Location will change its status to archived,
3999
        // in this case relation from it will not be loaded.
4000
        $trashService->trash($demoDesignLocation);
4001
4002
        // Load all relations
4003
        $relations = $contentService->loadRelations($versionInfo);
4004
        $reverseRelations = $contentService->loadReverseRelations($contentInfo);
4005
        /* END: Use Case */
4006
4007
        $this->assertEquals($contentInfo->id, $relation1->getDestinationContentInfo()->id);
4008
        $this->assertEquals($mediaDraft->id, $relation1->getSourceContentInfo()->id);
4009
4010
        $this->assertEquals($contentInfo->id, $relation2->getDestinationContentInfo()->id);
4011
        $this->assertEquals($demoDesignDraft->id, $relation2->getSourceContentInfo()->id);
4012
4013
        $this->assertEquals(0, count($relations));
4014
        $this->assertEquals(1, count($reverseRelations));
4015
4016
        $this->assertEquals(
4017
            [
4018
                [
4019
                    'sourceContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
4020
                    'destinationContentInfo' => 'abcdef0123456789abcdef0123456789',
4021
                ],
4022
            ],
4023
            [
4024
                [
4025
                    'sourceContentInfo' => $reverseRelations[0]->sourceContentInfo->remoteId,
4026
                    'destinationContentInfo' => $reverseRelations[0]->destinationContentInfo->remoteId,
4027
                ],
4028
            ]
4029
        );
4030
    }
4031
4032
    /**
4033
     * Test for the loadReverseRelations() method.
4034
     *
4035
     * @see \eZ\Publish\API\Repository\ContentService::loadReverseRelations()
4036
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
4037
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadReverseRelations
4038
     */
4039
    public function testLoadReverseRelationsSkipsDraftContent()
4040
    {
4041
        $repository = $this->getRepository();
4042
4043
        $contentService = $repository->getContentService();
4044
4045
        /* BEGIN: Use Case */
4046
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
4047
        // of a eZ Publish demo installation.
4048
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4049
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
4050
4051
        // Load "Media" page Content
4052
        $media = $contentService->loadContentByRemoteId($mediaRemoteId);
4053
4054
        // Create some drafts
4055
        $newDraftVersionInfo = $this->createContentDraftVersion1()->getVersionInfo();
4056
        $demoDesignDraft = $contentService->createContentDraft(
4057
            $contentService->loadContentInfoByRemoteId($demoDesignRemoteId)
4058
        );
4059
4060
        // Create relation between "Media" page and new content object
4061
        $relation1 = $contentService->addRelation(
4062
            $newDraftVersionInfo,
4063
            $media->contentInfo
4064
        );
4065
4066
        // Create another relation with the "Demo Design" page
4067
        $relation2 = $contentService->addRelation(
4068
            $demoDesignDraft->getVersionInfo(),
4069
            $media->contentInfo
4070
        );
4071
4072
        // Publish drafts, so relations become active
4073
        $contentService->publishVersion($demoDesignDraft->getVersionInfo());
4074
        // We will not publish new Content draft, therefore relation from it
4075
        // will not be loaded as reverse relation for "Media" page
4076
        //$contentService->publishVersion( $newDraftVersionInfo );
4077
4078
        // Load all relations
4079
        $relations = $contentService->loadRelations($media->versionInfo);
4080
        $reverseRelations = $contentService->loadReverseRelations($media->contentInfo);
4081
        /* END: Use Case */
4082
4083
        $this->assertEquals($media->contentInfo->id, $relation1->getDestinationContentInfo()->id);
4084
        $this->assertEquals($newDraftVersionInfo->contentInfo->id, $relation1->getSourceContentInfo()->id);
4085
4086
        $this->assertEquals($media->contentInfo->id, $relation2->getDestinationContentInfo()->id);
4087
        $this->assertEquals($demoDesignDraft->id, $relation2->getSourceContentInfo()->id);
4088
4089
        $this->assertEquals(0, count($relations));
4090
        $this->assertEquals(1, count($reverseRelations));
4091
4092
        $this->assertEquals(
4093
            [
4094
                [
4095
                    'sourceContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
4096
                    'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
4097
                ],
4098
            ],
4099
            [
4100
                [
4101
                    'sourceContentInfo' => $reverseRelations[0]->sourceContentInfo->remoteId,
4102
                    'destinationContentInfo' => $reverseRelations[0]->destinationContentInfo->remoteId,
4103
                ],
4104
            ]
4105
        );
4106
    }
4107
4108
    /**
4109
     * Test for the deleteRelation() method.
4110
     *
4111
     * @see \eZ\Publish\API\Repository\ContentService::deleteRelation()
4112
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
4113
     */
4114
    public function testDeleteRelation()
4115
    {
4116
        $repository = $this->getRepository();
4117
4118
        $contentService = $repository->getContentService();
4119
4120
        /* BEGIN: Use Case */
4121
        // Remote ids of the "Media" and the "Demo Design" page of a eZ Publish
4122
        // demo installation.
4123
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4124
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
4125
4126
        $draft = $this->createContentDraftVersion1();
4127
4128
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
4129
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
4130
4131
        // Establish some relations
4132
        $contentService->addRelation($draft->getVersionInfo(), $media);
4133
        $contentService->addRelation($draft->getVersionInfo(), $demoDesign);
4134
4135
        // Delete one of the currently created relations
4136
        $contentService->deleteRelation($draft->getVersionInfo(), $media);
4137
4138
        // The relations array now contains only one element
4139
        $relations = $contentService->loadRelations($draft->getVersionInfo());
4140
        /* END: Use Case */
4141
4142
        $this->assertEquals(1, count($relations));
4143
    }
4144
4145
    /**
4146
     * Test for the deleteRelation() method.
4147
     *
4148
     * @see \eZ\Publish\API\Repository\ContentService::deleteRelation()
4149
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
4150
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteRelation
4151
     */
4152 View Code Duplication
    public function testDeleteRelationThrowsBadStateException()
4153
    {
4154
        $repository = $this->getRepository();
4155
4156
        $contentService = $repository->getContentService();
4157
4158
        /* BEGIN: Use Case */
4159
        // RemoteId of the "Media" page of an eZ Publish demo installation
4160
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4161
4162
        $content = $this->createContentVersion1();
4163
4164
        // Load the destination object
4165
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
4166
4167
        // Create a new draft
4168
        $draftVersion2 = $contentService->createContentDraft($content->contentInfo);
4169
4170
        // Add a relation
4171
        $contentService->addRelation($draftVersion2->getVersionInfo(), $media);
4172
4173
        // Publish new version
4174
        $contentVersion2 = $contentService->publishVersion(
4175
            $draftVersion2->getVersionInfo()
4176
        );
4177
4178
        // This call will fail with a "BadStateException", because content is
4179
        // published and not a draft.
4180
        $contentService->deleteRelation(
4181
            $contentVersion2->getVersionInfo(),
4182
            $media
4183
        );
4184
        /* END: Use Case */
4185
    }
4186
4187
    /**
4188
     * Test for the deleteRelation() method.
4189
     *
4190
     * @see \eZ\Publish\API\Repository\ContentService::deleteRelation()
4191
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
4192
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteRelation
4193
     */
4194 View Code Duplication
    public function testDeleteRelationThrowsInvalidArgumentException()
4195
    {
4196
        $repository = $this->getRepository();
4197
4198
        $contentService = $repository->getContentService();
4199
4200
        /* BEGIN: Use Case */
4201
        // RemoteId of the "Media" page of an eZ Publish demo installation
4202
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4203
4204
        $draft = $this->createContentDraftVersion1();
4205
4206
        // Load the destination object
4207
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
4208
4209
        // This call will fail with a "InvalidArgumentException", because no
4210
        // relation exists between $draft and $media.
4211
        $contentService->deleteRelation(
4212
            $draft->getVersionInfo(),
4213
            $media
4214
        );
4215
        /* END: Use Case */
4216
    }
4217
4218
    /**
4219
     * Test for the createContent() method.
4220
     *
4221
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
4222
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4223
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4224
     */
4225
    public function testCreateContentInTransactionWithRollback()
4226
    {
4227
        if ($this->isVersion4()) {
4228
            $this->markTestSkipped('This test requires eZ Publish 5');
4229
        }
4230
4231
        $repository = $this->getRepository();
4232
4233
        /* BEGIN: Use Case */
4234
        $contentTypeService = $repository->getContentTypeService();
4235
        $contentService = $repository->getContentService();
4236
4237
        // Start a transaction
4238
        $repository->beginTransaction();
4239
4240
        try {
4241
            $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
4242
4243
            // Get a content create struct and set mandatory properties
4244
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
4245
            $contentCreate->setField('name', 'Sindelfingen forum');
4246
4247
            $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
4248
            $contentCreate->alwaysAvailable = true;
4249
4250
            // Create a new content object
4251
            $contentId = $contentService->createContent($contentCreate)->id;
4252
        } catch (Exception $e) {
4253
            // Cleanup hanging transaction on error
4254
            $repository->rollback();
4255
            throw $e;
4256
        }
4257
4258
        // Rollback all changes
4259
        $repository->rollback();
4260
4261
        try {
4262
            // This call will fail with a "NotFoundException"
4263
            $contentService->loadContent($contentId);
4264
        } catch (NotFoundException $e) {
4265
            // This is expected
4266
            return;
4267
        }
4268
        /* END: Use Case */
4269
4270
        $this->fail('Content object still exists after rollback.');
4271
    }
4272
4273
    /**
4274
     * Test for the createContent() method.
4275
     *
4276
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
4277
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4278
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4279
     */
4280
    public function testCreateContentInTransactionWithCommit()
4281
    {
4282
        if ($this->isVersion4()) {
4283
            $this->markTestSkipped('This test requires eZ Publish 5');
4284
        }
4285
4286
        $repository = $this->getRepository();
4287
4288
        /* BEGIN: Use Case */
4289
        $contentTypeService = $repository->getContentTypeService();
4290
        $contentService = $repository->getContentService();
4291
4292
        // Start a transaction
4293
        $repository->beginTransaction();
4294
4295
        try {
4296
            $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
4297
4298
            // Get a content create struct and set mandatory properties
4299
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
4300
            $contentCreate->setField('name', 'Sindelfingen forum');
4301
4302
            $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
4303
            $contentCreate->alwaysAvailable = true;
4304
4305
            // Create a new content object
4306
            $contentId = $contentService->createContent($contentCreate)->id;
4307
4308
            // Commit changes
4309
            $repository->commit();
4310
        } catch (Exception $e) {
4311
            // Cleanup hanging transaction on error
4312
            $repository->rollback();
4313
            throw $e;
4314
        }
4315
4316
        // Load the new content object
4317
        $content = $contentService->loadContent($contentId);
4318
        /* END: Use Case */
4319
4320
        $this->assertEquals($contentId, $content->id);
4321
    }
4322
4323
    /**
4324
     * Test for the createContent() method.
4325
     *
4326
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
4327
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
4328
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentThrowsNotFoundException
4329
     */
4330 View Code Duplication
    public function testCreateContentWithLocationCreateParameterInTransactionWithRollback()
4331
    {
4332
        $repository = $this->getRepository();
4333
4334
        $contentService = $repository->getContentService();
4335
4336
        /* BEGIN: Use Case */
4337
        // Start a transaction
4338
        $repository->beginTransaction();
4339
4340
        try {
4341
            $draft = $this->createContentDraftVersion1();
4342
        } catch (Exception $e) {
4343
            // Cleanup hanging transaction on error
4344
            $repository->rollback();
4345
            throw $e;
4346
        }
4347
4348
        $contentId = $draft->id;
4349
4350
        // Roleback the transaction
4351
        $repository->rollback();
4352
4353
        try {
4354
            // This call will fail with a "NotFoundException"
4355
            $contentService->loadContent($contentId);
4356
        } catch (NotFoundException $e) {
4357
            return;
4358
        }
4359
        /* END: Use Case */
4360
4361
        $this->fail('Can still load content object after rollback.');
4362
    }
4363
4364
    /**
4365
     * Test for the createContent() method.
4366
     *
4367
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
4368
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
4369
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentThrowsNotFoundException
4370
     */
4371 View Code Duplication
    public function testCreateContentWithLocationCreateParameterInTransactionWithCommit()
4372
    {
4373
        $repository = $this->getRepository();
4374
4375
        $contentService = $repository->getContentService();
4376
4377
        /* BEGIN: Use Case */
4378
        // Start a transaction
4379
        $repository->beginTransaction();
4380
4381
        try {
4382
            $draft = $this->createContentDraftVersion1();
4383
4384
            $contentId = $draft->id;
4385
4386
            // Roleback the transaction
4387
            $repository->commit();
4388
        } catch (Exception $e) {
4389
            // Cleanup hanging transaction on error
4390
            $repository->rollback();
4391
            throw $e;
4392
        }
4393
4394
        // Load the new content object
4395
        $content = $contentService->loadContent($contentId);
4396
        /* END: Use Case */
4397
4398
        $this->assertEquals($contentId, $content->id);
4399
    }
4400
4401
    /**
4402
     * Test for the createContentDraft() method.
4403
     *
4404
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
4405
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
4406
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4407
     */
4408
    public function testCreateContentDraftInTransactionWithRollback()
4409
    {
4410
        $repository = $this->getRepository();
4411
4412
        $contentId = $this->generateId('object', 12);
4413
        /* BEGIN: Use Case */
4414
        // $contentId is the ID of the "Administrator users" user group
4415
4416
        // Get the content service
4417
        $contentService = $repository->getContentService();
4418
4419
        // Load the user group content object
4420
        $content = $contentService->loadContent($contentId);
4421
4422
        // Start a new transaction
4423
        $repository->beginTransaction();
4424
4425
        try {
4426
            // Create a new draft
4427
            $drafted = $contentService->createContentDraft($content->contentInfo);
4428
4429
            // Store version number for later reuse
4430
            $versionNo = $drafted->versionInfo->versionNo;
4431
        } catch (Exception $e) {
4432
            // Cleanup hanging transaction on error
4433
            $repository->rollback();
4434
            throw $e;
4435
        }
4436
4437
        // Rollback
4438
        $repository->rollback();
4439
4440
        try {
4441
            // This call will fail with a "NotFoundException"
4442
            $contentService->loadContent($contentId, null, $versionNo);
4443
        } catch (NotFoundException $e) {
4444
            return;
4445
        }
4446
        /* END: Use Case */
4447
4448
        $this->fail('Can still load content draft after rollback');
4449
    }
4450
4451
    /**
4452
     * Test for the createContentDraft() method.
4453
     *
4454
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
4455
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
4456
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4457
     */
4458 View Code Duplication
    public function testCreateContentDraftInTransactionWithCommit()
4459
    {
4460
        $repository = $this->getRepository();
4461
4462
        $contentId = $this->generateId('object', 12);
4463
        /* BEGIN: Use Case */
4464
        // $contentId is the ID of the "Administrator users" user group
4465
4466
        // Get the content service
4467
        $contentService = $repository->getContentService();
4468
4469
        // Load the user group content object
4470
        $content = $contentService->loadContent($contentId);
4471
4472
        // Start a new transaction
4473
        $repository->beginTransaction();
4474
4475
        try {
4476
            // Create a new draft
4477
            $drafted = $contentService->createContentDraft($content->contentInfo);
4478
4479
            // Store version number for later reuse
4480
            $versionNo = $drafted->versionInfo->versionNo;
4481
4482
            // Commit all changes
4483
            $repository->commit();
4484
        } catch (Exception $e) {
4485
            // Cleanup hanging transaction on error
4486
            $repository->rollback();
4487
            throw $e;
4488
        }
4489
4490
        $content = $contentService->loadContent($contentId, null, $versionNo);
4491
        /* END: Use Case */
4492
4493
        $this->assertEquals(
4494
            $versionNo,
4495
            $content->getVersionInfo()->versionNo
4496
        );
4497
    }
4498
4499
    /**
4500
     * Test for the publishVersion() method.
4501
     *
4502
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
4503
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
4504
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4505
     */
4506 View Code Duplication
    public function testPublishVersionInTransactionWithRollback()
4507
    {
4508
        $repository = $this->getRepository();
4509
4510
        $contentId = $this->generateId('object', 12);
4511
        /* BEGIN: Use Case */
4512
        // $contentId is the ID of the "Administrator users" user group
4513
4514
        // Get the content service
4515
        $contentService = $repository->getContentService();
4516
4517
        // Load the user group content object
4518
        $content = $contentService->loadContent($contentId);
4519
4520
        // Start a new transaction
4521
        $repository->beginTransaction();
4522
4523
        try {
4524
            $draftVersion = $contentService->createContentDraft($content->contentInfo)->getVersionInfo();
4525
4526
            // Publish a new version
4527
            $content = $contentService->publishVersion($draftVersion);
4528
4529
            // Store version number for later reuse
4530
            $versionNo = $content->versionInfo->versionNo;
4531
        } catch (Exception $e) {
4532
            // Cleanup hanging transaction on error
4533
            $repository->rollback();
4534
            throw $e;
4535
        }
4536
4537
        // Rollback
4538
        $repository->rollback();
4539
4540
        try {
4541
            // This call will fail with a "NotFoundException"
4542
            $contentService->loadContent($contentId, null, $versionNo);
4543
        } catch (NotFoundException $e) {
4544
            return;
4545
        }
4546
        /* END: Use Case */
4547
4548
        $this->fail('Can still load content draft after rollback');
4549
    }
4550
4551
    /**
4552
     * Test for the publishVersion() method.
4553
     *
4554
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
4555
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
4556
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
4557
     */
4558 View Code Duplication
    public function testPublishVersionInTransactionWithCommit()
4559
    {
4560
        $repository = $this->getRepository();
4561
4562
        /* BEGIN: Use Case */
4563
        // ID of the "Administrator users" user group
4564
        $contentId = 12;
4565
4566
        // Get the content service
4567
        $contentService = $repository->getContentService();
4568
4569
        // Load the user group content object
4570
        $template = $contentService->loadContent($contentId);
4571
4572
        // Start a new transaction
4573
        $repository->beginTransaction();
4574
4575
        try {
4576
            // Publish a new version
4577
            $content = $contentService->publishVersion(
4578
                $contentService->createContentDraft($template->contentInfo)->getVersionInfo()
4579
            );
4580
4581
            // Store version number for later reuse
4582
            $versionNo = $content->versionInfo->versionNo;
4583
4584
            // Commit all changes
4585
            $repository->commit();
4586
        } catch (Exception $e) {
4587
            // Cleanup hanging transaction on error
4588
            $repository->rollback();
4589
            throw $e;
4590
        }
4591
4592
        // Load current version info
4593
        $versionInfo = $contentService->loadVersionInfo($content->contentInfo);
4594
        /* END: Use Case */
4595
4596
        $this->assertEquals($versionNo, $versionInfo->versionNo);
4597
    }
4598
4599
    /**
4600
     * Test for the updateContent() method.
4601
     *
4602
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
4603
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
4604
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4605
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4606
     */
4607 View Code Duplication
    public function testUpdateContentInTransactionWithRollback()
4608
    {
4609
        $repository = $this->getRepository();
4610
4611
        $contentId = $this->generateId('object', 12);
4612
        /* BEGIN: Use Case */
4613
        // $contentId is the ID of the "Administrator users" user group
4614
4615
        // Load content service
4616
        $contentService = $repository->getContentService();
4617
4618
        // Create a new user group draft
4619
        $draft = $contentService->createContentDraft(
4620
            $contentService->loadContentInfo($contentId)
4621
        );
4622
4623
        // Get an update struct and change the group name
4624
        $contentUpdate = $contentService->newContentUpdateStruct();
4625
        $contentUpdate->setField('name', 'Administrators', 'eng-US');
4626
4627
        // Start a transaction
4628
        $repository->beginTransaction();
4629
4630
        try {
4631
            // Update the group name
4632
            $draft = $contentService->updateContent(
4633
                $draft->getVersionInfo(),
4634
                $contentUpdate
4635
            );
4636
4637
            // Publish updated version
4638
            $contentService->publishVersion($draft->getVersionInfo());
4639
        } catch (Exception $e) {
4640
            // Cleanup hanging transaction on error
4641
            $repository->rollback();
4642
            throw $e;
4643
        }
4644
4645
        // Rollback all changes.
4646
        $repository->rollback();
4647
4648
        // Name will still be "Administrator users"
4649
        $name = $contentService->loadContent($contentId)->getFieldValue('name');
4650
        /* END: Use Case */
4651
4652
        $this->assertEquals('Administrator users', $name);
4653
    }
4654
4655
    /**
4656
     * Test for the updateContent() method.
4657
     *
4658
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
4659
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
4660
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4661
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4662
     */
4663 View Code Duplication
    public function testUpdateContentInTransactionWithCommit()
4664
    {
4665
        $repository = $this->getRepository();
4666
4667
        $contentId = $this->generateId('object', 12);
4668
        /* BEGIN: Use Case */
4669
        // $contentId is the ID of the "Administrator users" user group
4670
4671
        // Load content service
4672
        $contentService = $repository->getContentService();
4673
4674
        // Create a new user group draft
4675
        $draft = $contentService->createContentDraft(
4676
            $contentService->loadContentInfo($contentId)
4677
        );
4678
4679
        // Get an update struct and change the group name
4680
        $contentUpdate = $contentService->newContentUpdateStruct();
4681
        $contentUpdate->setField('name', 'Administrators', 'eng-US');
4682
4683
        // Start a transaction
4684
        $repository->beginTransaction();
4685
4686
        try {
4687
            // Update the group name
4688
            $draft = $contentService->updateContent(
4689
                $draft->getVersionInfo(),
4690
                $contentUpdate
4691
            );
4692
4693
            // Publish updated version
4694
            $contentService->publishVersion($draft->getVersionInfo());
4695
4696
            // Commit all changes.
4697
            $repository->commit();
4698
        } catch (Exception $e) {
4699
            // Cleanup hanging transaction on error
4700
            $repository->rollback();
4701
            throw $e;
4702
        }
4703
4704
        // Name is now "Administrators"
4705
        $name = $contentService->loadContent($contentId)->getFieldValue('name', 'eng-US');
4706
        /* END: Use Case */
4707
4708
        $this->assertEquals('Administrators', $name);
4709
    }
4710
4711
    /**
4712
     * Test for the updateContentMetadata() method.
4713
     *
4714
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
4715
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
4716
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4717
     */
4718 View Code Duplication
    public function testUpdateContentMetadataInTransactionWithRollback()
4719
    {
4720
        $repository = $this->getRepository();
4721
4722
        $contentId = $this->generateId('object', 12);
4723
        /* BEGIN: Use Case */
4724
        // $contentId is the ID of the "Administrator users" user group
4725
4726
        // Get the content service
4727
        $contentService = $repository->getContentService();
4728
4729
        // Load a ContentInfo object
4730
        $contentInfo = $contentService->loadContentInfo($contentId);
4731
4732
        // Store remoteId for later testing
4733
        $remoteId = $contentInfo->remoteId;
4734
4735
        // Start a transaction
4736
        $repository->beginTransaction();
4737
4738
        try {
4739
            // Get metadata update struct and change remoteId
4740
            $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
4741
            $metadataUpdate->remoteId = md5(microtime(true));
4742
4743
            // Update the metadata of the published content object
4744
            $contentService->updateContentMetadata(
4745
                $contentInfo,
4746
                $metadataUpdate
4747
            );
4748
        } catch (Exception $e) {
4749
            // Cleanup hanging transaction on error
4750
            $repository->rollback();
4751
            throw $e;
4752
        }
4753
4754
        // Rollback all changes.
4755
        $repository->rollback();
4756
4757
        // Load current remoteId
4758
        $remoteIdReloaded = $contentService->loadContentInfo($contentId)->remoteId;
4759
        /* END: Use Case */
4760
4761
        $this->assertEquals($remoteId, $remoteIdReloaded);
4762
    }
4763
4764
    /**
4765
     * Test for the updateContentMetadata() method.
4766
     *
4767
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
4768
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
4769
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4770
     */
4771 View Code Duplication
    public function testUpdateContentMetadataInTransactionWithCommit()
4772
    {
4773
        $repository = $this->getRepository();
4774
4775
        $contentId = $this->generateId('object', 12);
4776
        /* BEGIN: Use Case */
4777
        // $contentId is the ID of the "Administrator users" user group
4778
4779
        // Get the content service
4780
        $contentService = $repository->getContentService();
4781
4782
        // Load a ContentInfo object
4783
        $contentInfo = $contentService->loadContentInfo($contentId);
4784
4785
        // Store remoteId for later testing
4786
        $remoteId = $contentInfo->remoteId;
4787
4788
        // Start a transaction
4789
        $repository->beginTransaction();
4790
4791
        try {
4792
            // Get metadata update struct and change remoteId
4793
            $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
4794
            $metadataUpdate->remoteId = md5(microtime(true));
4795
4796
            // Update the metadata of the published content object
4797
            $contentService->updateContentMetadata(
4798
                $contentInfo,
4799
                $metadataUpdate
4800
            );
4801
4802
            // Commit all changes.
4803
            $repository->commit();
4804
        } catch (Exception $e) {
4805
            // Cleanup hanging transaction on error
4806
            $repository->rollback();
4807
            throw $e;
4808
        }
4809
4810
        // Load current remoteId
4811
        $remoteIdReloaded = $contentService->loadContentInfo($contentId)->remoteId;
4812
        /* END: Use Case */
4813
4814
        $this->assertNotEquals($remoteId, $remoteIdReloaded);
4815
    }
4816
4817
    /**
4818
     * Test for the deleteVersion() method.
4819
     *
4820
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
4821
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4822
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4823
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentDrafts
4824
     */
4825 View Code Duplication
    public function testDeleteVersionInTransactionWithRollback()
4826
    {
4827
        $repository = $this->getRepository();
4828
4829
        $contentId = $this->generateId('object', 12);
4830
        /* BEGIN: Use Case */
4831
        // $contentId is the ID of the "Administrator users" user group
4832
4833
        // Get the content service
4834
        $contentService = $repository->getContentService();
4835
4836
        // Start a new transaction
4837
        $repository->beginTransaction();
4838
4839
        try {
4840
            // Create a new draft
4841
            $draft = $contentService->createContentDraft(
4842
                $contentService->loadContentInfo($contentId)
4843
            );
4844
4845
            $contentService->deleteVersion($draft->getVersionInfo());
4846
        } catch (Exception $e) {
4847
            // Cleanup hanging transaction on error
4848
            $repository->rollback();
4849
            throw $e;
4850
        }
4851
4852
        // Rollback all changes.
4853
        $repository->rollback();
4854
4855
        // This array will be empty
4856
        $drafts = $contentService->loadContentDrafts();
4857
        /* END: Use Case */
4858
4859
        $this->assertSame([], $drafts);
4860
    }
4861
4862
    /**
4863
     * Test for the deleteVersion() method.
4864
     *
4865
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
4866
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4867
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4868
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentDrafts
4869
     */
4870 View Code Duplication
    public function testDeleteVersionInTransactionWithCommit()
4871
    {
4872
        $repository = $this->getRepository();
4873
4874
        $contentId = $this->generateId('object', 12);
4875
        /* BEGIN: Use Case */
4876
        // $contentId is the ID of the "Administrator users" user group
4877
4878
        // Get the content service
4879
        $contentService = $repository->getContentService();
4880
4881
        // Start a new transaction
4882
        $repository->beginTransaction();
4883
4884
        try {
4885
            // Create a new draft
4886
            $draft = $contentService->createContentDraft(
4887
                $contentService->loadContentInfo($contentId)
4888
            );
4889
4890
            $contentService->deleteVersion($draft->getVersionInfo());
4891
4892
            // Commit all changes.
4893
            $repository->commit();
4894
        } catch (Exception $e) {
4895
            // Cleanup hanging transaction on error
4896
            $repository->rollback();
4897
            throw $e;
4898
        }
4899
4900
        // This array will contain no element
4901
        $drafts = $contentService->loadContentDrafts();
4902
        /* END: Use Case */
4903
4904
        $this->assertSame([], $drafts);
4905
    }
4906
4907
    /**
4908
     * Test for the deleteContent() method.
4909
     *
4910
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
4911
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteContent
4912
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4913
     */
4914 View Code Duplication
    public function testDeleteContentInTransactionWithRollback()
4915
    {
4916
        $repository = $this->getRepository();
4917
4918
        $contentId = $this->generateId('object', 11);
4919
        /* BEGIN: Use Case */
4920
        // $contentId is the ID of the "Members" user group in an eZ Publish
4921
        // demo installation
4922
4923
        // Get content service
4924
        $contentService = $repository->getContentService();
4925
4926
        // Load a ContentInfo instance
4927
        $contentInfo = $contentService->loadContentInfo($contentId);
4928
4929
        // Start a new transaction
4930
        $repository->beginTransaction();
4931
4932
        try {
4933
            // Delete content object
4934
            $contentService->deleteContent($contentInfo);
4935
        } catch (Exception $e) {
4936
            // Cleanup hanging transaction on error
4937
            $repository->rollback();
4938
            throw $e;
4939
        }
4940
4941
        // Rollback all changes
4942
        $repository->rollback();
4943
4944
        // This call will return the original content object
4945
        $contentInfo = $contentService->loadContentInfo($contentId);
4946
        /* END: Use Case */
4947
4948
        $this->assertEquals($contentId, $contentInfo->id);
4949
    }
4950
4951
    /**
4952
     * Test for the deleteContent() method.
4953
     *
4954
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
4955
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteContent
4956
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4957
     */
4958 View Code Duplication
    public function testDeleteContentInTransactionWithCommit()
4959
    {
4960
        $repository = $this->getRepository();
4961
4962
        $contentId = $this->generateId('object', 11);
4963
        /* BEGIN: Use Case */
4964
        // $contentId is the ID of the "Members" user group in an eZ Publish
4965
        // demo installation
4966
4967
        // Get content service
4968
        $contentService = $repository->getContentService();
4969
4970
        // Load a ContentInfo instance
4971
        $contentInfo = $contentService->loadContentInfo($contentId);
4972
4973
        // Start a new transaction
4974
        $repository->beginTransaction();
4975
4976
        try {
4977
            // Delete content object
4978
            $contentService->deleteContent($contentInfo);
4979
4980
            // Commit all changes
4981
            $repository->commit();
4982
        } catch (Exception $e) {
4983
            // Cleanup hanging transaction on error
4984
            $repository->rollback();
4985
            throw $e;
4986
        }
4987
4988
        // Deleted content info is not found anymore
4989
        try {
4990
            $contentService->loadContentInfo($contentId);
4991
        } catch (NotFoundException $e) {
4992
            return;
4993
        }
4994
        /* END: Use Case */
4995
4996
        $this->fail('Can still load ContentInfo after commit.');
4997
    }
4998
4999
    /**
5000
     * Test for the copyContent() method.
5001
     *
5002
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
5003
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContent
5004
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
5005
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
5006
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
5007
     */
5008 View Code Duplication
    public function testCopyContentInTransactionWithRollback()
5009
    {
5010
        $repository = $this->getRepository();
5011
5012
        $contentId = $this->generateId('object', 11);
5013
        $locationId = $this->generateId('location', 13);
5014
        /* BEGIN: Use Case */
5015
        // $contentId is the ID of the "Members" user group in an eZ Publish
5016
        // demo installation
5017
5018
        // $locationId is the ID of the "Administrator users" group location
5019
5020
        // Get services
5021
        $contentService = $repository->getContentService();
5022
        $locationService = $repository->getLocationService();
5023
5024
        // Load content object to copy
5025
        $content = $contentService->loadContent($contentId);
5026
5027
        // Create new target location
5028
        $locationCreate = $locationService->newLocationCreateStruct($locationId);
5029
5030
        // Start a new transaction
5031
        $repository->beginTransaction();
5032
5033
        try {
5034
            // Copy content with all versions and drafts
5035
            $contentService->copyContent(
5036
                $content->contentInfo,
5037
                $locationCreate
5038
            );
5039
        } catch (Exception $e) {
5040
            // Cleanup hanging transaction on error
5041
            $repository->rollback();
5042
            throw $e;
5043
        }
5044
5045
        // Rollback all changes
5046
        $repository->rollback();
5047
5048
        $this->refreshSearch($repository);
5049
5050
        // This array will only contain a single admin user object
5051
        $locations = $locationService->loadLocationChildren(
5052
            $locationService->loadLocation($locationId)
5053
        )->locations;
5054
        /* END: Use Case */
5055
5056
        $this->assertEquals(1, count($locations));
5057
    }
5058
5059
    /**
5060
     * Test for the copyContent() method.
5061
     *
5062
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
5063
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContent
5064
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
5065
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
5066
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
5067
     */
5068 View Code Duplication
    public function testCopyContentInTransactionWithCommit()
5069
    {
5070
        $repository = $this->getRepository();
5071
5072
        $contentId = $this->generateId('object', 11);
5073
        $locationId = $this->generateId('location', 13);
5074
        /* BEGIN: Use Case */
5075
        // $contentId is the ID of the "Members" user group in an eZ Publish
5076
        // demo installation
5077
5078
        // $locationId is the ID of the "Administrator users" group location
5079
5080
        // Get services
5081
        $contentService = $repository->getContentService();
5082
        $locationService = $repository->getLocationService();
5083
5084
        // Load content object to copy
5085
        $content = $contentService->loadContent($contentId);
5086
5087
        // Create new target location
5088
        $locationCreate = $locationService->newLocationCreateStruct($locationId);
5089
5090
        // Start a new transaction
5091
        $repository->beginTransaction();
5092
5093
        try {
5094
            // Copy content with all versions and drafts
5095
            $contentCopied = $contentService->copyContent(
0 ignored issues
show
Unused Code introduced by
$contentCopied is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
5096
                $content->contentInfo,
5097
                $locationCreate
5098
            );
5099
5100
            // Commit all changes
5101
            $repository->commit();
5102
        } catch (Exception $e) {
5103
            // Cleanup hanging transaction on error
5104
            $repository->rollback();
5105
            throw $e;
5106
        }
5107
5108
        $this->refreshSearch($repository);
5109
5110
        // This will contain the admin user and the new child location
5111
        $locations = $locationService->loadLocationChildren(
5112
            $locationService->loadLocation($locationId)
5113
        )->locations;
5114
        /* END: Use Case */
5115
5116
        $this->assertEquals(2, count($locations));
5117
    }
5118
5119
    public function testURLAliasesCreatedForNewContent()
5120
    {
5121
        $repository = $this->getRepository();
5122
5123
        $contentService = $repository->getContentService();
5124
        $locationService = $repository->getLocationService();
5125
        $urlAliasService = $repository->getURLAliasService();
5126
5127
        /* BEGIN: Use Case */
5128
        $draft = $this->createContentDraftVersion1();
5129
5130
        // Automatically creates a new URLAlias for the content
5131
        $liveContent = $contentService->publishVersion($draft->getVersionInfo());
5132
        /* END: Use Case */
5133
5134
        $location = $locationService->loadLocation(
5135
            $liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5136
        );
5137
5138
        $aliases = $urlAliasService->listLocationAliases($location, false);
5139
5140
        $this->assertAliasesCorrect(
5141
            [
5142
                '/Design/Plain-site/An-awesome-forum' => [
5143
                    'type' => URLAlias::LOCATION,
5144
                    'destination' => $location->id,
5145
                    'path' => '/Design/Plain-site/An-awesome-forum',
5146
                    'languageCodes' => ['eng-US'],
5147
                    'isHistory' => false,
5148
                    'isCustom' => false,
5149
                    'forward' => false,
5150
                ],
5151
            ],
5152
            $aliases
5153
        );
5154
    }
5155
5156
    public function testURLAliasesCreatedForUpdatedContent()
5157
    {
5158
        $repository = $this->getRepository();
5159
5160
        $contentService = $repository->getContentService();
5161
        $locationService = $repository->getLocationService();
5162
        $urlAliasService = $repository->getURLAliasService();
5163
5164
        /* BEGIN: Use Case */
5165
        $draft = $this->createUpdatedDraftVersion2();
5166
5167
        $location = $locationService->loadLocation(
5168
            $draft->getVersionInfo()->getContentInfo()->mainLocationId
5169
        );
5170
5171
        // Load and assert URL aliases before publishing updated Content, so that
5172
        // SPI cache is warmed up and cache invalidation is also tested.
5173
        $aliases = $urlAliasService->listLocationAliases($location, false);
5174
5175
        $this->assertAliasesCorrect(
5176
            [
5177
                '/Design/Plain-site/An-awesome-forum' => [
5178
                    'type' => URLAlias::LOCATION,
5179
                    'destination' => $location->id,
5180
                    'path' => '/Design/Plain-site/An-awesome-forum',
5181
                    'languageCodes' => ['eng-US'],
5182
                    'alwaysAvailable' => true,
5183
                    'isHistory' => false,
5184
                    'isCustom' => false,
5185
                    'forward' => false,
5186
                ],
5187
            ],
5188
            $aliases
5189
        );
5190
5191
        // Automatically marks old aliases for the content as history
5192
        // and creates new aliases, based on the changes
5193
        $liveContent = $contentService->publishVersion($draft->getVersionInfo());
5194
        /* END: Use Case */
5195
5196
        $location = $locationService->loadLocation(
5197
            $liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5198
        );
5199
5200
        $aliases = $urlAliasService->listLocationAliases($location, false);
5201
5202
        $this->assertAliasesCorrect(
5203
            [
5204
                '/Design/Plain-site/An-awesome-forum2' => [
5205
                    'type' => URLAlias::LOCATION,
5206
                    'destination' => $location->id,
5207
                    'path' => '/Design/Plain-site/An-awesome-forum2',
5208
                    'languageCodes' => ['eng-US'],
5209
                    'alwaysAvailable' => true,
5210
                    'isHistory' => false,
5211
                    'isCustom' => false,
5212
                    'forward' => false,
5213
                ],
5214
                '/Design/Plain-site/An-awesome-forum23' => [
5215
                    'type' => URLAlias::LOCATION,
5216
                    'destination' => $location->id,
5217
                    'path' => '/Design/Plain-site/An-awesome-forum23',
5218
                    'languageCodes' => ['eng-GB'],
5219
                    'alwaysAvailable' => true,
5220
                    'isHistory' => false,
5221
                    'isCustom' => false,
5222
                    'forward' => false,
5223
                ],
5224
            ],
5225
            $aliases
5226
        );
5227
    }
5228
5229
    public function testCustomURLAliasesNotHistorizedOnUpdatedContent()
5230
    {
5231
        $repository = $this->getRepository();
5232
5233
        $contentService = $repository->getContentService();
5234
5235
        /* BEGIN: Use Case */
5236
        $urlAliasService = $repository->getURLAliasService();
5237
        $locationService = $repository->getLocationService();
5238
5239
        $content = $this->createContentVersion1();
5240
5241
        // Create a custom URL alias
5242
        $urlAliasService->createUrlAlias(
5243
            $locationService->loadLocation(
5244
                $content->getVersionInfo()->getContentInfo()->mainLocationId
5245
            ),
5246
            '/my/fancy/story-about-ez-publish',
5247
            'eng-US'
5248
        );
5249
5250
        $draftVersion2 = $contentService->createContentDraft($content->contentInfo);
5251
5252
        $contentUpdate = $contentService->newContentUpdateStruct();
5253
        $contentUpdate->initialLanguageCode = 'eng-US';
5254
        $contentUpdate->setField('name', 'Amazing Bielefeld forum');
5255
5256
        $draftVersion2 = $contentService->updateContent(
5257
            $draftVersion2->getVersionInfo(),
5258
            $contentUpdate
5259
        );
5260
5261
        // Only marks auto-generated aliases as history
5262
        // the custom one is left untouched
5263
        $liveContent = $contentService->publishVersion($draftVersion2->getVersionInfo());
5264
        /* END: Use Case */
5265
5266
        $location = $locationService->loadLocation(
5267
            $liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5268
        );
5269
5270
        $aliases = $urlAliasService->listLocationAliases($location);
5271
5272
        $this->assertAliasesCorrect(
5273
            [
5274
                '/my/fancy/story-about-ez-publish' => [
5275
                    'type' => URLAlias::LOCATION,
5276
                    'destination' => $location->id,
5277
                    'path' => '/my/fancy/story-about-ez-publish',
5278
                    'languageCodes' => ['eng-US'],
5279
                    'isHistory' => false,
5280
                    'isCustom' => true,
5281
                    'forward' => false,
5282
                    'alwaysAvailable' => false,
5283
                ],
5284
            ],
5285
            $aliases
5286
        );
5287
    }
5288
5289
    /**
5290
     * Test to ensure that old versions are not affected by updates to newer
5291
     * drafts.
5292
     */
5293
    public function testUpdatingDraftDoesNotUpdateOldVersions()
5294
    {
5295
        $repository = $this->getRepository();
5296
5297
        $contentService = $repository->getContentService();
5298
5299
        $contentVersion2 = $this->createContentVersion2();
5300
5301
        $loadedContent1 = $contentService->loadContent($contentVersion2->id, null, 1);
5302
        $loadedContent2 = $contentService->loadContent($contentVersion2->id, null, 2);
5303
5304
        $this->assertNotEquals(
5305
            $loadedContent1->getFieldValue('name', 'eng-US'),
5306
            $loadedContent2->getFieldValue('name', 'eng-US')
5307
        );
5308
    }
5309
5310
    /**
5311
     * Test scenario with writer and publisher users.
5312
     * Writer can only create content. Publisher can publish this content.
5313
     */
5314
    public function testPublishWorkflow()
5315
    {
5316
        $repository = $this->getRepository();
5317
        $contentService = $repository->getContentService();
5318
5319
        $this->createRoleWithPolicies('Publisher', [
5320
            ['module' => 'content', 'function' => 'read'],
5321
            ['module' => 'content', 'function' => 'create'],
5322
            ['module' => 'content', 'function' => 'publish'],
5323
        ]);
5324
5325
        $this->createRoleWithPolicies('Writer', [
5326
            ['module' => 'content', 'function' => 'read'],
5327
            ['module' => 'content', 'function' => 'create'],
5328
        ]);
5329
5330
        $writerUser = $this->createCustomUserWithLogin(
5331
            'writer',
5332
            '[email protected]',
5333
            'Writers',
5334
            'Writer'
5335
        );
5336
5337
        $publisherUser = $this->createCustomUserWithLogin(
5338
            'publisher',
5339
            '[email protected]',
5340
            'Publishers',
5341
            'Publisher'
5342
        );
5343
5344
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5345
        $draft = $this->createContentDraftVersion1();
5346
5347
        $repository->getPermissionResolver()->setCurrentUserReference($publisherUser);
5348
        $content = $contentService->publishVersion($draft->versionInfo);
5349
5350
        $contentService->loadContent($content->id);
5351
    }
5352
5353
    /**
5354
     * Test publish / content policy is required to be able to publish content.
5355
     *
5356
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
5357
     * @expectedExceptionMessageRegExp /User does not have access to 'publish' 'content'/
5358
     */
5359
    public function testPublishContentWithoutPublishPolicyThrowsException()
5360
    {
5361
        $repository = $this->getRepository();
5362
5363
        $this->createRoleWithPolicies('Writer', [
5364
            ['module' => 'content', 'function' => 'read'],
5365
            ['module' => 'content', 'function' => 'create'],
5366
            ['module' => 'content', 'function' => 'edit'],
5367
        ]);
5368
        $writerUser = $this->createCustomUserWithLogin(
5369
            'writer',
5370
            '[email protected]',
5371
            'Writers',
5372
            'Writer'
5373
        );
5374
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5375
5376
        $this->createContentVersion1();
5377
    }
5378
5379
    /**
5380
     * Test removal of the specific translation from all the Versions of a Content Object.
5381
     *
5382
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5383
     */
5384 View Code Duplication
    public function testDeleteTranslation()
5385
    {
5386
        $repository = $this->getRepository();
5387
        $contentService = $repository->getContentService();
5388
        $content = $this->createContentVersion2();
5389
5390
        // create multiple versions to exceed archive limit
5391
        for ($i = 0; $i < 5; ++$i) {
5392
            $contentDraft = $contentService->createContentDraft($content->contentInfo);
5393
            $contentUpdateStruct = $contentService->newContentUpdateStruct();
5394
            $contentDraft = $contentService->updateContent(
5395
                $contentDraft->versionInfo,
5396
                $contentUpdateStruct
5397
            );
5398
            $contentService->publishVersion($contentDraft->versionInfo);
5399
        }
5400
5401
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
5402
5403
        $this->assertTranslationDoesNotExist('eng-GB', $content->id);
5404
    }
5405
5406
    /**
5407
     * Test deleting a Translation which is initial for some Version, updates initialLanguageCode
5408
     * with mainLanguageCode (assuming they are different).
5409
     */
5410
    public function testDeleteTranslationUpdatesInitialLanguageCodeVersion()
5411
    {
5412
        $repository = $this->getRepository();
5413
        $contentService = $repository->getContentService();
5414
5415
        $content = $this->createContentVersion2();
5416
        // create another, copied, version
5417
        $contentDraft = $contentService->updateContent(
5418
            $contentService->createContentDraft($content->contentInfo)->versionInfo,
5419
            $contentService->newContentUpdateStruct()
5420
        );
5421
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
5422
5423
        // remove first version with only one translation as it is not the subject of this test
5424
        $contentService->deleteVersion(
5425
            $contentService->loadVersionInfo($publishedContent->contentInfo, 1)
5426
        );
5427
5428
        // sanity check
5429
        self::assertEquals('eng-US', $content->contentInfo->mainLanguageCode);
5430
        self::assertEquals('eng-US', $content->versionInfo->initialLanguageCode);
5431
5432
        // update mainLanguageCode so it is different than initialLanguageCode for Version
5433
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
5434
        $contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
5435
        $content = $contentService->updateContentMetadata($publishedContent->contentInfo, $contentMetadataUpdateStruct);
5436
5437
        $contentService->deleteTranslation($content->contentInfo, 'eng-US');
5438
5439
        $this->assertTranslationDoesNotExist('eng-US', $content->id);
5440
    }
5441
5442
    /**
5443
     * Test removal of the specific translation properly updates languages of the URL alias.
5444
     *
5445
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5446
     */
5447
    public function testDeleteTranslationUpdatesUrlAlias()
5448
    {
5449
        $repository = $this->getRepository();
5450
        $contentService = $repository->getContentService();
5451
        $locationService = $repository->getLocationService();
5452
        $urlAliasService = $repository->getURLAliasService();
5453
5454
        $content = $this->createContentVersion2();
5455
        $mainLocation = $locationService->loadLocation($content->contentInfo->mainLocationId);
5456
5457
        // create custom URL alias for Content main Location
5458
        $urlAliasService->createUrlAlias($mainLocation, '/my-custom-url', 'eng-GB');
5459
5460
        // create secondary Location for Content
5461
        $secondaryLocation = $locationService->createLocation(
5462
            $content->contentInfo,
5463
            $locationService->newLocationCreateStruct(2)
5464
        );
5465
5466
        // create custom URL alias for Content secondary Location
5467
        $urlAliasService->createUrlAlias($secondaryLocation, '/my-secondary-url', 'eng-GB');
5468
5469
        // delete Translation
5470
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
5471
5472
        foreach ([$mainLocation, $secondaryLocation] as $location) {
5473
            // check auto-generated URL aliases
5474
            foreach ($urlAliasService->listLocationAliases($location, false) as $alias) {
5475
                self::assertNotContains('eng-GB', $alias->languageCodes);
5476
            }
5477
5478
            // check custom URL aliases
5479
            foreach ($urlAliasService->listLocationAliases($location) as $alias) {
5480
                self::assertNotContains('eng-GB', $alias->languageCodes);
5481
            }
5482
        }
5483
    }
5484
5485
    /**
5486
     * Test removal of a main translation throws BadStateException.
5487
     *
5488
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5489
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
5490
     * @expectedExceptionMessage Specified translation is the main translation of the Content Object
5491
     */
5492
    public function testDeleteTranslationMainLanguageThrowsBadStateException()
5493
    {
5494
        $repository = $this->getRepository();
5495
        $contentService = $repository->getContentService();
5496
        $content = $this->createContentVersion2();
5497
5498
        // delete first version which has only one translation
5499
        $contentService->deleteVersion($contentService->loadVersionInfo($content->contentInfo, 1));
5500
5501
        // try to delete main translation
5502
        $contentService->deleteTranslation($content->contentInfo, $content->contentInfo->mainLanguageCode);
5503
    }
5504
5505
    /**
5506
     * Test removal of a Translation is possible when some archived Versions have only this Translation.
5507
     *
5508
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5509
     */
5510
    public function testDeleteTranslationDeletesSingleTranslationVersions()
5511
    {
5512
        $repository = $this->getRepository();
5513
        $contentService = $repository->getContentService();
5514
        // content created by the createContentVersion1 method has eng-US translation only.
5515
        $content = $this->createContentVersion1();
5516
5517
        // create new version and add eng-GB translation
5518
        $contentDraft = $contentService->createContentDraft($content->contentInfo);
5519
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
5520
        $contentUpdateStruct->setField('name', 'Awesome Board', 'eng-GB');
5521
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
5522
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
5523
5524
        // update mainLanguageCode to avoid exception related to that
5525
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
5526
        $contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
5527
5528
        $content = $contentService->updateContentMetadata($publishedContent->contentInfo, $contentMetadataUpdateStruct);
5529
5530
        $contentService->deleteTranslation($content->contentInfo, 'eng-US');
5531
5532
        $this->assertTranslationDoesNotExist('eng-US', $content->id);
5533
    }
5534
5535
    /**
5536
     * Test removal of the translation by the user who is not allowed to delete a content
5537
     * throws UnauthorizedException.
5538
     *
5539
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5540
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
5541
     * @expectedExceptionMessage User does not have access to 'remove' 'content'
5542
     */
5543
    public function testDeleteTranslationThrowsUnauthorizedException()
5544
    {
5545
        $repository = $this->getRepository();
5546
        $contentService = $repository->getContentService();
5547
5548
        $content = $this->createContentVersion2();
5549
5550
        // create user that can read/create/edit but cannot delete content
5551
        $this->createRoleWithPolicies('Writer', [
5552
            ['module' => 'content', 'function' => 'read'],
5553
            ['module' => 'content', 'function' => 'versionread'],
5554
            ['module' => 'content', 'function' => 'create'],
5555
            ['module' => 'content', 'function' => 'edit'],
5556
        ]);
5557
        $writerUser = $this->createCustomUserWithLogin(
5558
            'writer',
5559
            '[email protected]',
5560
            'Writers',
5561
            'Writer'
5562
        );
5563
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5564
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
5565
    }
5566
5567
    /**
5568
     * Test removal of a non-existent translation throws InvalidArgumentException.
5569
     *
5570
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5571
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
5572
     * @expectedExceptionMessage Argument '$languageCode' is invalid: ger-DE does not exist in the Content item
5573
     */
5574
    public function testDeleteTranslationThrowsInvalidArgumentException()
5575
    {
5576
        $repository = $this->getRepository();
5577
        $contentService = $repository->getContentService();
5578
        // content created by the createContentVersion1 method has eng-US translation only.
5579
        $content = $this->createContentVersion1();
5580
        $contentService->deleteTranslation($content->contentInfo, 'ger-DE');
5581
    }
5582
5583
    /**
5584
     * Test deleting a Translation from Draft.
5585
     *
5586
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5587
     */
5588
    public function testDeleteTranslationFromDraft()
5589
    {
5590
        $repository = $this->getRepository();
5591
        $contentService = $repository->getContentService();
5592
5593
        $languageCode = 'eng-GB';
5594
        $content = $this->createMultipleLanguageContentVersion2();
5595
        $draft = $contentService->createContentDraft($content->contentInfo);
5596
        $draft = $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5597
        $content = $contentService->publishVersion($draft->versionInfo);
5598
5599
        $loadedContent = $contentService->loadContent($content->id);
5600
        self::assertNotContains($languageCode, $loadedContent->versionInfo->languageCodes);
5601
        self::assertEmpty($loadedContent->getFieldsByLanguage($languageCode));
5602
    }
5603
5604
    /**
5605
     * Get values for multilingual field.
5606
     *
5607
     * @return array
5608
     */
5609
    public function providerForDeleteTranslationFromDraftRemovesUrlAliasOnPublishing()
5610
    {
5611
        return [
5612
            [
5613
                ['eng-US' => 'US Name', 'eng-GB' => 'GB Name'],
5614
            ],
5615
            [
5616
                ['eng-US' => 'Same Name', 'eng-GB' => 'Same Name'],
5617
            ],
5618
        ];
5619
    }
5620
5621
    /**
5622
     * Test deleting a Translation from Draft removes previously stored URL aliases for published Content.
5623
     *
5624
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5625
     *
5626
     * @dataProvider providerForDeleteTranslationFromDraftRemovesUrlAliasOnPublishing
5627
     *
5628
     * @param string[] $fieldValues translated field values
5629
     *
5630
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
5631
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
5632
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
5633
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
5634
     */
5635
    public function testDeleteTranslationFromDraftRemovesUrlAliasOnPublishing(array $fieldValues)
5636
    {
5637
        $repository = $this->getRepository();
5638
        $contentService = $repository->getContentService();
5639
        $locationService = $repository->getLocationService();
5640
        $urlAliasService = $repository->getURLAliasService();
5641
5642
        // set language code to be removed
5643
        $languageCode = 'eng-GB';
5644
        $draft = $this->createMultilingualContentDraft(
5645
            'folder',
5646
            2,
5647
            'eng-US',
5648
            [
5649
                'name' => [
5650
                    'eng-GB' => $fieldValues['eng-GB'],
5651
                    'eng-US' => $fieldValues['eng-US'],
5652
                ],
5653
            ]
5654
        );
5655
        $content = $contentService->publishVersion($draft->versionInfo);
5656
5657
        // create secondary location
5658
        $locationService->createLocation(
5659
            $content->contentInfo,
5660
            $locationService->newLocationCreateStruct(5)
5661
        );
5662
5663
        // sanity check
5664
        $locations = $locationService->loadLocations($content->contentInfo);
5665
        self::assertCount(2, $locations, 'Sanity check: Expected to find 2 Locations');
5666
        foreach ($locations as $location) {
5667
            $urlAliasService->createUrlAlias($location, '/us-custom_' . $location->id, 'eng-US');
5668
            $urlAliasService->createUrlAlias($location, '/gb-custom_' . $location->id, 'eng-GB');
5669
5670
            // check default URL aliases
5671
            $aliases = $urlAliasService->listLocationAliases($location, false, $languageCode);
5672
            self::assertNotEmpty($aliases, 'Sanity check: URL alias for the translation does not exist');
5673
5674
            // check custom URL aliases
5675
            $aliases = $urlAliasService->listLocationAliases($location, true, $languageCode);
5676
            self::assertNotEmpty($aliases, 'Sanity check: Custom URL alias for the translation does not exist');
5677
        }
5678
5679
        // delete translation and publish new version
5680
        $draft = $contentService->createContentDraft($content->contentInfo);
5681
        $draft = $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5682
        $contentService->publishVersion($draft->versionInfo);
5683
5684
        // check that aliases does not exist
5685
        foreach ($locations as $location) {
5686
            // check default URL aliases
5687
            $aliases = $urlAliasService->listLocationAliases($location, false, $languageCode);
5688
            self::assertEmpty($aliases, 'URL alias for the deleted translation still exists');
5689
5690
            // check custom URL aliases
5691
            $aliases = $urlAliasService->listLocationAliases($location, true, $languageCode);
5692
            self::assertEmpty($aliases, 'Custom URL alias for the deleted translation still exists');
5693
        }
5694
    }
5695
5696
    /**
5697
     * Test that URL aliases for deleted Translations are properly archived.
5698
     */
5699
    public function testDeleteTranslationFromDraftArchivesUrlAliasOnPublishing()
5700
    {
5701
        $repository = $this->getRepository();
5702
        $contentService = $repository->getContentService();
5703
        $urlAliasService = $repository->getURLAliasService();
5704
5705
        $content = $contentService->publishVersion(
5706
            $this->createMultilingualContentDraft(
5707
                'folder',
5708
                2,
5709
                'eng-US',
5710
                [
5711
                    'name' => [
5712
                        'eng-GB' => 'BritishEnglishContent',
5713
                        'eng-US' => 'AmericanEnglishContent',
5714
                    ],
5715
                ]
5716
            )->versionInfo
5717
        );
5718
5719
        $unrelatedContent = $contentService->publishVersion(
5720
            $this->createMultilingualContentDraft(
5721
                'folder',
5722
                2,
5723
                'eng-US',
5724
                [
5725
                    'name' => [
5726
                        'eng-GB' => 'AnotherBritishContent',
5727
                        'eng-US' => 'AnotherAmericanContent',
5728
                    ],
5729
                ]
5730
            )->versionInfo
5731
        );
5732
5733
        $urlAlias = $urlAliasService->lookup('/BritishEnglishContent');
5734
        self::assertFalse($urlAlias->isHistory);
5735
        self::assertEquals($urlAlias->path, '/BritishEnglishContent');
5736
        self::assertEquals($urlAlias->destination, $content->contentInfo->mainLocationId);
5737
5738
        $draft = $contentService->deleteTranslationFromDraft(
5739
            $contentService->createContentDraft($content->contentInfo)->versionInfo,
5740
            'eng-GB'
5741
        );
5742
        $content = $contentService->publishVersion($draft->versionInfo);
5743
5744
        $urlAlias = $urlAliasService->lookup('/BritishEnglishContent');
5745
        self::assertTrue($urlAlias->isHistory);
5746
        self::assertEquals($urlAlias->path, '/BritishEnglishContent');
5747
        self::assertEquals($urlAlias->destination, $content->contentInfo->mainLocationId);
5748
5749
        $unrelatedUrlAlias = $urlAliasService->lookup('/AnotherBritishContent');
5750
        self::assertFalse($unrelatedUrlAlias->isHistory);
5751
        self::assertEquals($unrelatedUrlAlias->path, '/AnotherBritishContent');
5752
        self::assertEquals($unrelatedUrlAlias->destination, $unrelatedContent->contentInfo->mainLocationId);
5753
    }
5754
5755
    /**
5756
     * Test deleting a Translation from Draft which has single Translation throws BadStateException.
5757
     *
5758
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5759
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
5760
     * @expectedExceptionMessage Specified Translation is the only one Content Object Version has
5761
     */
5762
    public function testDeleteTranslationFromDraftThrowsBadStateExceptionOnSingleTranslation()
5763
    {
5764
        $repository = $this->getRepository();
5765
        $contentService = $repository->getContentService();
5766
5767
        // create Content with single Translation
5768
        $publishedContent = $contentService->publishVersion(
5769
            $this->createContentDraft(
5770
                'forum',
5771
                2,
5772
                ['name' => 'Eng-US Version name']
5773
            )->versionInfo
5774
        );
5775
5776
        // update mainLanguageCode to avoid exception related to trying to delete main Translation
5777
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
5778
        $contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
5779
        $publishedContent = $contentService->updateContentMetadata(
5780
            $publishedContent->contentInfo,
5781
            $contentMetadataUpdateStruct
5782
        );
5783
5784
        // create single Translation Version from the first one
5785
        $draft = $contentService->createContentDraft(
5786
            $publishedContent->contentInfo,
5787
            $publishedContent->versionInfo
5788
        );
5789
5790
        // attempt to delete Translation
5791
        $contentService->deleteTranslationFromDraft($draft->versionInfo, 'eng-US');
5792
    }
5793
5794
    /**
5795
     * Test deleting the Main Translation from Draft throws BadStateException.
5796
     *
5797
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5798
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
5799
     * @expectedExceptionMessage Specified Translation is the main Translation of the Content Object
5800
     */
5801
    public function testDeleteTranslationFromDraftThrowsBadStateExceptionOnMainTranslation()
5802
    {
5803
        $repository = $this->getRepository();
5804
        $contentService = $repository->getContentService();
5805
5806
        $mainLanguageCode = 'eng-US';
5807
        $draft = $this->createMultilingualContentDraft(
5808
            'forum',
5809
            2,
5810
            $mainLanguageCode,
5811
            [
5812
                'name' => [
5813
                    'eng-US' => 'An awesome eng-US forum',
5814
                    'eng-GB' => 'An awesome eng-GB forum',
5815
                ],
5816
            ]
5817
        );
5818
        $contentService->deleteTranslationFromDraft($draft->versionInfo, $mainLanguageCode);
5819
    }
5820
5821
    /**
5822
     * Test deleting the Translation from Published Version throws BadStateException.
5823
     *
5824
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5825
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
5826
     * @expectedExceptionMessage Version is not a draft
5827
     */
5828 View Code Duplication
    public function testDeleteTranslationFromDraftThrowsBadStateExceptionOnPublishedVersion()
5829
    {
5830
        $repository = $this->getRepository();
5831
        $contentService = $repository->getContentService();
5832
5833
        $languageCode = 'eng-US';
5834
        $content = $this->createMultipleLanguageContentVersion2();
5835
        $draft = $contentService->createContentDraft($content->contentInfo);
5836
        $publishedContent = $contentService->publishVersion($draft->versionInfo);
5837
        $contentService->deleteTranslationFromDraft($publishedContent->versionInfo, $languageCode);
5838
    }
5839
5840
    /**
5841
     * Test deleting a Translation from Draft throws UnauthorizedException if user cannot edit Content.
5842
     *
5843
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5844
     * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
5845
     * @expectedExceptionMessage User does not have access to 'edit' 'content'
5846
     */
5847
    public function testDeleteTranslationFromDraftThrowsUnauthorizedException()
5848
    {
5849
        $repository = $this->getRepository();
5850
        $contentService = $repository->getContentService();
5851
5852
        $languageCode = 'eng-GB';
5853
        $content = $this->createMultipleLanguageContentVersion2();
5854
        $draft = $contentService->createContentDraft($content->contentInfo);
5855
5856
        // create user that can read/create/delete but cannot edit or content
5857
        $this->createRoleWithPolicies('Writer', [
5858
            ['module' => 'content', 'function' => 'read'],
5859
            ['module' => 'content', 'function' => 'versionread'],
5860
            ['module' => 'content', 'function' => 'create'],
5861
            ['module' => 'content', 'function' => 'delete'],
5862
        ]);
5863
        $writerUser = $this->createCustomUserWithLogin(
5864
            'user',
5865
            '[email protected]',
5866
            'Writers',
5867
            'Writer'
5868
        );
5869
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5870
5871
        $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5872
    }
5873
5874
    /**
5875
     * Test deleting a non-existent Translation from Draft throws InvalidArgumentException.
5876
     *
5877
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5878
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
5879
     * @expectedExceptionMessageRegExp /The Version \(ContentId=\d+, VersionNo=\d+\) is not translated into ger-DE/
5880
     */
5881
    public function testDeleteTranslationFromDraftThrowsInvalidArgumentException()
5882
    {
5883
        $repository = $this->getRepository();
5884
        $contentService = $repository->getContentService();
5885
5886
        $languageCode = 'ger-DE';
5887
        $content = $this->createMultipleLanguageContentVersion2();
5888
        $draft = $contentService->createContentDraft($content->contentInfo);
5889
        $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5890
    }
5891
5892
    /**
5893
     * Test loading list of Content items.
5894
     */
5895
    public function testLoadContentListByContentInfo()
5896
    {
5897
        $repository = $this->getRepository();
5898
        $contentService = $repository->getContentService();
5899
        $locationService = $repository->getLocationService();
5900
5901
        $allLocationsCount = $locationService->getAllLocationsCount();
5902
        $contentInfoList = array_map(
5903
            function (Location $location) {
5904
                return $location->contentInfo;
5905
            },
5906
            $locationService->loadAllLocations(0, $allLocationsCount)
5907
        );
5908
5909
        $contentList = $contentService->loadContentListByContentInfo($contentInfoList);
5910
        self::assertCount(count($contentInfoList), $contentList);
5911
        foreach ($contentList as $content) {
5912
            try {
5913
                $loadedContent = $contentService->loadContent($content->id);
5914
                self::assertEquals($loadedContent, $content, "Failed to properly bulk-load Content {$content->id}");
5915
            } catch (NotFoundException $e) {
5916
                self::fail("Failed to load Content {$content->id}: {$e->getMessage()}");
5917
            } catch (UnauthorizedException $e) {
5918
                self::fail("Failed to load Content {$content->id}: {$e->getMessage()}");
5919
            }
5920
        }
5921
    }
5922
5923
    /**
5924
     * Test loading content versions after removing exactly two drafts.
5925
     *
5926
     * @see https://jira.ez.no/browse/EZP-30271
5927
     *
5928
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteVersion
5929
     */
5930
    public function testLoadVersionsAfterDeletingTwoDrafts()
5931
    {
5932
        $repository = $this->getRepository();
5933
        $contentService = $repository->getContentService();
5934
5935
        $content = $this->createFolder(['eng-GB' => 'Foo'], 2);
5936
5937
        // First update and publish
5938
        $modifiedContent = $this->updateFolder($content, ['eng-GB' => 'Foo1']);
5939
        $content = $contentService->publishVersion($modifiedContent->versionInfo);
5940
5941
        // Second update and publish
5942
        $modifiedContent = $this->updateFolder($content, ['eng-GB' => 'Foo2']);
5943
        $content = $contentService->publishVersion($modifiedContent->versionInfo);
5944
5945
        // Create drafts
5946
        $this->updateFolder($content, ['eng-GB' => 'Foo3']);
5947
        $this->updateFolder($content, ['eng-GB' => 'Foo4']);
5948
5949
        $versions = $contentService->loadVersions($content->contentInfo);
5950
5951
        foreach ($versions as $key => $version) {
5952
            if ($version->isDraft()) {
5953
                $contentService->deleteVersion($version);
5954
                unset($versions[$key]);
5955
            }
5956
        }
5957
5958
        $this->assertEquals($versions, $contentService->loadVersions($content->contentInfo));
5959
    }
5960
5961
    /**
5962
     * Tests loading list of content versions of status draft.
5963
     */
5964
    public function testLoadVersionsOfStatusDraft()
5965
    {
5966
        $repository = $this->getRepository();
5967
5968
        $contentService = $repository->getContentService();
5969
5970
        $content = $this->createContentVersion1();
5971
5972
        $contentService->createContentDraft($content->contentInfo);
5973
        $contentService->createContentDraft($content->contentInfo);
5974
        $contentService->createContentDraft($content->contentInfo);
5975
5976
        $versions = $contentService->loadVersions($content->contentInfo, VersionInfo::STATUS_DRAFT);
5977
5978
        $this->assertSame(\count($versions), 3);
5979
    }
5980
5981
    /**
5982
     * Tests loading list of content versions of status archived.
5983
     */
5984
    public function testLoadVersionsOfStatusArchived()
5985
    {
5986
        $repository = $this->getRepository();
5987
5988
        $contentService = $repository->getContentService();
5989
5990
        $content = $this->createContentVersion1();
5991
5992
        $draft1 = $contentService->createContentDraft($content->contentInfo);
5993
        $contentService->publishVersion($draft1->versionInfo);
5994
5995
        $draft2 = $contentService->createContentDraft($content->contentInfo);
5996
        $contentService->publishVersion($draft2->versionInfo);
5997
5998
        $versions = $contentService->loadVersions($content->contentInfo, VersionInfo::STATUS_ARCHIVED);
5999
6000
        $this->assertSame(\count($versions), 2);
6001
    }
6002
6003
    /**
6004
     * Asserts that all aliases defined in $expectedAliasProperties with the
6005
     * given properties are available in $actualAliases and not more.
6006
     *
6007
     * @param array $expectedAliasProperties
6008
     * @param array $actualAliases
6009
     */
6010
    private function assertAliasesCorrect(array $expectedAliasProperties, array $actualAliases)
6011
    {
6012
        foreach ($actualAliases as $actualAlias) {
6013
            if (!isset($expectedAliasProperties[$actualAlias->path])) {
6014
                $this->fail(
6015
                    sprintf(
6016
                        'Alias with path "%s" in languages "%s" not expected.',
6017
                        $actualAlias->path,
6018
                        implode(', ', $actualAlias->languageCodes)
6019
                    )
6020
                );
6021
            }
6022
6023
            foreach ($expectedAliasProperties[$actualAlias->path] as $propertyName => $propertyValue) {
6024
                $this->assertEquals(
6025
                    $propertyValue,
6026
                    $actualAlias->$propertyName,
6027
                    sprintf(
6028
                        'Property $%s incorrect on alias with path "%s" in languages "%s".',
6029
                        $propertyName,
6030
                        $actualAlias->path,
6031
                        implode(', ', $actualAlias->languageCodes)
6032
                    )
6033
                );
6034
            }
6035
6036
            unset($expectedAliasProperties[$actualAlias->path]);
6037
        }
6038
6039
        if (!empty($expectedAliasProperties)) {
6040
            $this->fail(
6041
                sprintf(
6042
                    'Missing expected aliases with paths "%s".',
6043
                    implode('", "', array_keys($expectedAliasProperties))
6044
                )
6045
            );
6046
        }
6047
    }
6048
6049
    /**
6050
     * Asserts that the given fields are equal to the default fields fixture.
6051
     *
6052
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $fields
6053
     */
6054
    private function assertAllFieldsEquals(array $fields)
6055
    {
6056
        $actual = $this->normalizeFields($fields);
6057
        $expected = $this->normalizeFields($this->createFieldsFixture());
6058
6059
        $this->assertEquals($expected, $actual);
6060
    }
6061
6062
    /**
6063
     * Asserts that the given fields are equal to a language filtered set of the
6064
     * default fields fixture.
6065
     *
6066
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $fields
6067
     * @param string $languageCode
6068
     */
6069
    private function assertLocaleFieldsEquals(array $fields, $languageCode)
6070
    {
6071
        $actual = $this->normalizeFields($fields);
6072
6073
        $expected = [];
6074
        foreach ($this->normalizeFields($this->createFieldsFixture()) as $field) {
6075
            if ($field->languageCode !== $languageCode) {
6076
                continue;
6077
            }
6078
            $expected[] = $field;
6079
        }
6080
6081
        $this->assertEquals($expected, $actual);
6082
    }
6083
6084
    /**
6085
     * This method normalizes a set of fields and returns a normalized set.
6086
     *
6087
     * Normalization means it resets the storage specific field id to zero and
6088
     * it sorts the field by their identifier and their language code. In
6089
     * addition, the field value is removed, since this one depends on the
6090
     * specific FieldType, which is tested in a dedicated integration test.
6091
     *
6092
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $fields
6093
     *
6094
     * @return \eZ\Publish\API\Repository\Values\Content\Field[]
6095
     */
6096
    private function normalizeFields(array $fields)
6097
    {
6098
        $normalized = [];
6099 View Code Duplication
        foreach ($fields as $field) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
6100
            $normalized[] = new Field(
6101
                [
6102
                    'id' => 0,
6103
                    'value' => ($field->value !== null ? true : null),
6104
                    'languageCode' => $field->languageCode,
6105
                    'fieldDefIdentifier' => $field->fieldDefIdentifier,
6106
                    'fieldTypeIdentifier' => $field->fieldTypeIdentifier,
6107
                ]
6108
            );
6109
        }
6110
        usort(
6111
            $normalized,
6112 View Code Duplication
            function ($field1, $field2) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
6113
                if (0 === ($return = strcasecmp($field1->fieldDefIdentifier, $field2->fieldDefIdentifier))) {
6114
                    return strcasecmp($field1->languageCode, $field2->languageCode);
6115
                }
6116
6117
                return $return;
6118
            }
6119
        );
6120
6121
        return $normalized;
6122
    }
6123
6124
    /**
6125
     * Returns a filtered set of the default fields fixture.
6126
     *
6127
     * @param string $languageCode
6128
     *
6129
     * @return \eZ\Publish\API\Repository\Values\Content\Field[]
6130
     */
6131
    private function createLocaleFieldsFixture($languageCode)
6132
    {
6133
        $fields = [];
6134
        foreach ($this->createFieldsFixture() as $field) {
6135
            if (null === $field->languageCode || $languageCode === $field->languageCode) {
6136
                $fields[] = $field;
6137
            }
6138
        }
6139
6140
        return $fields;
6141
    }
6142
6143
    /**
6144
     * Asserts that given Content has default ContentStates.
6145
     *
6146
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
6147
     */
6148 View Code Duplication
    private function assertDefaultContentStates(ContentInfo $contentInfo)
6149
    {
6150
        $repository = $this->getRepository();
6151
        $objectStateService = $repository->getObjectStateService();
6152
6153
        $objectStateGroups = $objectStateService->loadObjectStateGroups();
6154
6155
        foreach ($objectStateGroups as $objectStateGroup) {
6156
            $contentState = $objectStateService->getContentState($contentInfo, $objectStateGroup);
6157
            foreach ($objectStateService->loadObjectStates($objectStateGroup) as $objectState) {
6158
                // Only check the first object state which is the default one.
6159
                $this->assertEquals(
6160
                    $objectState,
6161
                    $contentState
6162
                );
6163
                break;
6164
            }
6165
        }
6166
    }
6167
6168
    /**
6169
     * Assert that given Content has no references to a translation specified by the $languageCode.
6170
     *
6171
     * @param string $languageCode
6172
     * @param int $contentId
6173
     */
6174
    private function assertTranslationDoesNotExist($languageCode, $contentId)
6175
    {
6176
        $repository = $this->getRepository();
6177
        $contentService = $repository->getContentService();
6178
6179
        $content = $contentService->loadContent($contentId);
6180
6181
        foreach ($content->fields as $fieldIdentifier => $field) {
6182
            /** @var array $field */
6183
            self::assertArrayNotHasKey($languageCode, $field);
6184
            self::assertNotEquals($languageCode, $content->contentInfo->mainLanguageCode);
6185
            self::assertArrayNotHasKey($languageCode, $content->versionInfo->getNames());
6186
            self::assertNotEquals($languageCode, $content->versionInfo->initialLanguageCode);
6187
            self::assertNotContains($languageCode, $content->versionInfo->languageCodes);
6188
        }
6189
        foreach ($contentService->loadVersions($content->contentInfo) as $versionInfo) {
6190
            self::assertArrayNotHasKey($languageCode, $versionInfo->getNames());
6191
            self::assertNotEquals($languageCode, $versionInfo->contentInfo->mainLanguageCode);
6192
            self::assertNotEquals($languageCode, $versionInfo->initialLanguageCode);
6193
            self::assertNotContains($languageCode, $versionInfo->languageCodes);
6194
        }
6195
    }
6196
6197
    /**
6198
     * Returns the default fixture of fields used in most tests.
6199
     *
6200
     * @return \eZ\Publish\API\Repository\Values\Content\Field[]
6201
     */
6202
    private function createFieldsFixture()
6203
    {
6204
        return [
6205
            new Field(
6206
                [
6207
                    'id' => 0,
6208
                    'value' => 'Foo',
6209
                    'languageCode' => 'eng-US',
6210
                    'fieldDefIdentifier' => 'description',
6211
                    'fieldTypeIdentifier' => 'ezrichtext',
6212
                ]
6213
            ),
6214
            new Field(
6215
                [
6216
                    'id' => 0,
6217
                    'value' => 'Bar',
6218
                    'languageCode' => 'eng-GB',
6219
                    'fieldDefIdentifier' => 'description',
6220
                    'fieldTypeIdentifier' => 'ezrichtext',
6221
                ]
6222
            ),
6223
            new Field(
6224
                [
6225
                    'id' => 0,
6226
                    'value' => 'An awesome multi-lang forum²',
6227
                    'languageCode' => 'eng-US',
6228
                    'fieldDefIdentifier' => 'name',
6229
                    'fieldTypeIdentifier' => 'ezstring',
6230
                ]
6231
            ),
6232
            new Field(
6233
                [
6234
                    'id' => 0,
6235
                    'value' => 'An awesome multi-lang forum²³',
6236
                    'languageCode' => 'eng-GB',
6237
                    'fieldDefIdentifier' => 'name',
6238
                    'fieldTypeIdentifier' => 'ezstring',
6239
                ]
6240
            ),
6241
        ];
6242
    }
6243
6244
    /**
6245
     * Gets expected property values for the "Media" ContentInfo ValueObject.
6246
     *
6247
     * @return array
6248
     */
6249 View Code Duplication
    private function getExpectedMediaContentInfoProperties()
6250
    {
6251
        return [
6252
            'id' => 41,
6253
            'contentTypeId' => 1,
6254
            'name' => 'Media',
6255
            'sectionId' => 3,
6256
            'currentVersionNo' => 1,
6257
            'published' => true,
6258
            'ownerId' => 14,
6259
            'modificationDate' => $this->createDateTime(1060695457),
6260
            'publishedDate' => $this->createDateTime(1060695457),
6261
            'alwaysAvailable' => 1,
6262
            'remoteId' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
6263
            'mainLanguageCode' => 'eng-US',
6264
            'mainLocationId' => 43,
6265
            'status' => ContentInfo::STATUS_PUBLISHED,
6266
        ];
6267
    }
6268
6269
    /**
6270
     * @covers \eZ\Publish\API\Repository\ContentService::hideContent
6271
     *
6272
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
6273
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
6274
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
6275
     */
6276
    public function testHideContent(): void
6277
    {
6278
        $repository = $this->getRepository();
6279
        $contentTypeService = $repository->getContentTypeService();
6280
        $contentService = $repository->getContentService();
6281
        $locationService = $repository->getLocationService();
6282
6283
        $locationCreateStructs = array_map(
6284
            function (Location $parentLocation) use ($locationService) {
6285
                return $locationService->newLocationCreateStruct($parentLocation->id);
6286
            },
6287
            $this->createParentLocationsForHideReveal($locationService, 2)
6288
        );
6289
6290
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6291
6292
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6293
        $contentCreate->setField('name', 'Folder to hide');
6294
6295
        $content = $contentService->createContent(
6296
            $contentCreate,
6297
            $locationCreateStructs
6298
        );
6299
6300
        $publishedContent = $contentService->publishVersion($content->versionInfo);
6301
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6302
6303
        // Sanity check
6304
        $this->assertCount(3, $locations);
6305
        $this->assertCount(0, $this->filterHiddenLocations($locations));
6306
6307
        /* BEGIN: Use Case */
6308
        $contentService->hideContent($publishedContent->contentInfo);
6309
        /* END: Use Case */
6310
6311
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6312
        $this->assertCount(3, $locations);
6313
        $this->assertCount(3, $this->filterHiddenLocations($locations));
6314
    }
6315
6316
    /**
6317
     * @covers \eZ\Publish\API\Repository\ContentService::revealContent
6318
     *
6319
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
6320
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
6321
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
6322
     */
6323
    public function testRevealContent()
6324
    {
6325
        $repository = $this->getRepository();
6326
        $contentTypeService = $repository->getContentTypeService();
6327
        $contentService = $repository->getContentService();
6328
        $locationService = $repository->getLocationService();
6329
6330
        $locationCreateStructs = array_map(
6331
            function (Location $parentLocation) use ($locationService) {
6332
                return $locationService->newLocationCreateStruct($parentLocation->id);
6333
            },
6334
            $this->createParentLocationsForHideReveal($locationService, 2)
6335
        );
6336
6337
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6338
6339
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6340
        $contentCreate->setField('name', 'Folder to hide');
6341
6342
        $locationCreateStructs[0]->hidden = true;
6343
6344
        $content = $contentService->createContent(
6345
            $contentCreate,
6346
            $locationCreateStructs
6347
        );
6348
6349
        $publishedContent = $contentService->publishVersion($content->versionInfo);
6350
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6351
6352
        // Sanity check
6353
        $hiddenLocations = $this->filterHiddenLocations($locations);
6354
        $this->assertCount(3, $locations);
6355
        $this->assertCount(1, $hiddenLocations);
6356
6357
        // BEGIN: Use Case
6358
        $contentService->hideContent($publishedContent->contentInfo);
6359
        $this->assertCount(
6360
            3,
6361
            $this->filterHiddenLocations(
6362
                $locationService->loadLocations($publishedContent->contentInfo)
6363
            )
6364
        );
6365
6366
        $contentService->revealContent($publishedContent->contentInfo);
6367
        // END: Use Case
6368
6369
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6370
        $hiddenLocationsAfterReveal = $this->filterHiddenLocations($locations);
6371
        $this->assertCount(3, $locations);
6372
        $this->assertCount(1, $hiddenLocationsAfterReveal);
6373
        $this->assertEquals($hiddenLocations, $hiddenLocationsAfterReveal);
6374
    }
6375
6376
    /**
6377
     * @depends testRevealContent
6378
     */
6379
    public function testRevealContentWithHiddenParent()
6380
    {
6381
        $repository = $this->getRepository();
6382
6383
        $contentTypeService = $repository->getContentTypeService();
6384
        $contentService = $repository->getContentService();
6385
        $locationService = $repository->getLocationService();
6386
6387
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6388
6389
        $contentNames = [
6390
            'Parent Content',
6391
            'Child (Nesting 1)',
6392
            'Child (Nesting 2)',
6393
            'Child (Nesting 3)',
6394
            'Child (Nesting 4)',
6395
        ];
6396
6397
        $parentLocation = $locationService->newLocationCreateStruct(
6398
            $this->generateId('location', 2)
6399
        );
6400
6401
        /** @var Content[] $contents */
6402
        $contents = [];
6403
6404 View Code Duplication
        foreach ($contentNames as $contentName) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
6405
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6406
            $contentCreate->setField('name', $contentName);
6407
6408
            $content = $contentService->createContent($contentCreate, [$parentLocation]);
6409
            $contents[] = $publishedContent = $contentService->publishVersion($content->versionInfo);
6410
6411
            $parentLocation = $locationService->newLocationCreateStruct(
6412
                $this->generateId('location', $publishedContent->contentInfo->mainLocationId)
6413
            );
6414
        }
6415
6416
        $contentService->hideContent($contents[0]->contentInfo);
6417
        $contentService->hideContent($contents[2]->contentInfo);
6418
        $contentService->revealContent($contents[2]->contentInfo);
6419
6420
        $parentContent = $contentService->loadContent($contents[0]->id);
6421
        $parentLocation = $locationService->loadLocation($parentContent->contentInfo->mainLocationId);
6422
        $parentSublocations = $locationService->loadLocationList([
6423
            $contents[1]->contentInfo->mainLocationId,
6424
            $contents[2]->contentInfo->mainLocationId,
6425
            $contents[3]->contentInfo->mainLocationId,
6426
            $contents[4]->contentInfo->mainLocationId,
6427
        ]);
6428
6429
        // Parent remains invisible
6430
        self::assertTrue($parentLocation->invisible);
6431
6432
        // All parent sublocations remain invisible as well
6433
        foreach ($parentSublocations as $parentSublocation) {
6434
            self::assertTrue($parentSublocation->invisible);
6435
        }
6436
    }
6437
6438
    /**
6439
     * @depends testRevealContent
6440
     */
6441
    public function testRevealContentWithHiddenChildren()
6442
    {
6443
        $repository = $this->getRepository();
6444
6445
        $contentTypeService = $repository->getContentTypeService();
6446
        $contentService = $repository->getContentService();
6447
        $locationService = $repository->getLocationService();
6448
6449
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6450
6451
        $contentNames = [
6452
            'Parent Content',
6453
            'Child (Nesting 1)',
6454
            'Child (Nesting 2)',
6455
            'Child (Nesting 3)',
6456
            'Child (Nesting 4)',
6457
        ];
6458
6459
        $parentLocation = $locationService->newLocationCreateStruct(
6460
            $this->generateId('location', 2)
6461
        );
6462
6463
        /** @var Content[] $contents */
6464
        $contents = [];
6465
6466 View Code Duplication
        foreach ($contentNames as $contentName) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
6467
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6468
            $contentCreate->setField('name', $contentName);
6469
6470
            $content = $contentService->createContent($contentCreate, [$parentLocation]);
6471
            $contents[] = $publishedContent = $contentService->publishVersion($content->versionInfo);
6472
6473
            $parentLocation = $locationService->newLocationCreateStruct(
6474
                $this->generateId('location', $publishedContent->contentInfo->mainLocationId)
6475
            );
6476
        }
6477
6478
        $contentService->hideContent($contents[0]->contentInfo);
6479
        $contentService->hideContent($contents[2]->contentInfo);
6480
        $contentService->revealContent($contents[0]->contentInfo);
6481
6482
        $directChildContent = $contentService->loadContent($contents[1]->id);
6483
        $directChildLocation = $locationService->loadLocation($directChildContent->contentInfo->mainLocationId);
6484
6485
        $childContent = $contentService->loadContent($contents[2]->id);
6486
        $childLocation = $locationService->loadLocation($childContent->contentInfo->mainLocationId);
6487
        $childSublocations = $locationService->loadLocationList([
6488
            $contents[3]->contentInfo->mainLocationId,
6489
            $contents[4]->contentInfo->mainLocationId,
6490
        ]);
6491
6492
        // Direct child content is not hidden
6493
        self::assertFalse($directChildContent->contentInfo->isHidden);
6494
6495
        // Direct child content location is still invisible
6496
        self::assertFalse($directChildLocation->invisible);
6497
6498
        // Child content is still hidden
6499
        self::assertTrue($childContent->contentInfo->isHidden);
6500
6501
        // Child content location is still invisible
6502
        self::assertTrue($childLocation->invisible);
6503
6504
        // All childs sublocations remain invisible as well
6505
        foreach ($childSublocations as $childSublocation) {
6506
            self::assertTrue($childSublocation->invisible);
6507
        }
6508
    }
6509
6510
    public function testHideContentWithParentLocation()
6511
    {
6512
        $repository = $this->getRepository();
6513
        $contentTypeService = $repository->getContentTypeService();
6514
6515
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6516
6517
        $contentService = $repository->getContentService();
6518
        $locationService = $repository->getLocationService();
6519
6520
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6521
        $contentCreate->setField('name', 'Parent');
6522
6523
        $content = $contentService->createContent(
6524
            $contentCreate,
6525
            [
6526
                $locationService->newLocationCreateStruct(
6527
                    $this->generateId('location', 2)
6528
                ),
6529
            ]
6530
        );
6531
6532
        $publishedContent = $contentService->publishVersion($content->versionInfo);
6533
6534
        /* BEGIN: Use Case */
6535
        $contentService->hideContent($publishedContent->contentInfo);
6536
        /* END: Use Case */
6537
6538
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6539
6540
        $childContentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6541
        $childContentCreate->setField('name', 'Child');
6542
6543
        $childContent = $contentService->createContent(
6544
            $childContentCreate,
6545
            [
6546
                $locationService->newLocationCreateStruct(
6547
                    $locations[0]->id
6548
                ),
6549
            ]
6550
        );
6551
6552
        $publishedChildContent = $contentService->publishVersion($childContent->versionInfo);
6553
6554
        $childLocations = $locationService->loadLocations($publishedChildContent->contentInfo);
6555
6556
        $this->assertTrue($locations[0]->hidden);
6557
        $this->assertTrue($locations[0]->invisible);
6558
6559
        $this->assertFalse($childLocations[0]->hidden);
6560
        $this->assertTrue($childLocations[0]->invisible);
6561
    }
6562
6563
    public function testChangeContentName()
6564
    {
6565
        $repository = $this->getRepository();
6566
6567
        $contentService = $repository->getContentService();
6568
        $contentDraft = $this->createContentDraft(
6569
            'folder',
6570
            $this->generateId('location', 2),
6571
            [
6572
                'name' => 'Marco',
6573
            ]
6574
        );
6575
6576
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
6577
        $contentMetadataUpdateStruct = new ContentMetadataUpdateStruct([
6578
            'name' => 'Polo',
6579
        ]);
6580
        $contentService->updateContentMetadata($publishedContent->contentInfo, $contentMetadataUpdateStruct);
6581
6582
        $updatedContent = $contentService->loadContent($publishedContent->id);
6583
6584
        $this->assertEquals('Marco', $publishedContent->contentInfo->name);
6585
        $this->assertEquals('Polo', $updatedContent->contentInfo->name);
6586
    }
6587
6588
    public function testCopyTranslationsFromPublishedToDraft()
6589
    {
6590
        $repository = $this->getRepository();
6591
6592
        $contentService = $repository->getContentService();
6593
6594
        $contentDraft = $this->createContentDraft(
6595
            'folder',
6596
            $this->generateId('location', 2),
6597
            [
6598
                'name' => 'Folder US',
6599
            ]
6600
        );
6601
6602
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
6603
6604
        $deDraft = $contentService->createContentDraft($publishedContent->contentInfo);
6605
6606
        $contentUpdateStruct = new ContentUpdateStruct([
6607
            'initialLanguageCode' => 'ger-DE',
6608
            'fields' => $contentDraft->getFields(),
6609
        ]);
6610
6611
        $contentUpdateStruct->setField('name', 'Folder GER', 'ger-DE');
6612
6613
        $deContent = $contentService->updateContent($deDraft->versionInfo, $contentUpdateStruct);
6614
6615
        $updatedContent = $contentService->loadContent($deContent->id, null, $deContent->versionInfo->versionNo);
6616
        $this->assertEquals(
6617
            [
6618
                'eng-US' => 'Folder US',
6619
                'ger-DE' => 'Folder GER',
6620
            ],
6621
            $updatedContent->fields['name']
6622
        );
6623
6624
        $gbDraft = $contentService->createContentDraft($publishedContent->contentInfo);
6625
6626
        $contentUpdateStruct = new ContentUpdateStruct([
6627
            'initialLanguageCode' => 'eng-GB',
6628
            'fields' => $contentDraft->getFields(),
6629
        ]);
6630
6631
        $contentUpdateStruct->setField('name', 'Folder GB', 'eng-GB');
6632
6633
        $gbContent = $contentService->updateContent($gbDraft->versionInfo, $contentUpdateStruct);
6634
        $contentService->publishVersion($gbDraft->versionInfo);
6635
        $updatedContent = $contentService->loadContent($gbContent->id, null, $gbContent->versionInfo->versionNo);
6636
        $this->assertEquals(
6637
            [
6638
                'eng-US' => 'Folder US',
6639
                'eng-GB' => 'Folder GB',
6640
            ],
6641
            $updatedContent->fields['name']
6642
        );
6643
6644
        $dePublished = $contentService->publishVersion($deDraft->versionInfo);
6645
        $this->assertEquals(
6646
            [
6647
                'eng-US' => 'Folder US',
6648
                'ger-DE' => 'Folder GER',
6649
                'eng-GB' => 'Folder GB',
6650
            ],
6651
            $dePublished->fields['name']
6652
        );
6653
    }
6654
6655
    /**
6656
     * Create structure of parent folders with Locations to be used for Content hide/reveal tests.
6657
     *
6658
     * @param \eZ\Publish\API\Repository\LocationService $locationService
6659
     * @param int $parentLocationId
6660
     *
6661
     * @return \eZ\Publish\API\Repository\Values\Content\Location[] A list of Locations aimed to be parents
6662
     *
6663
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
6664
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
6665
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
6666
     */
6667
    private function createParentLocationsForHideReveal(LocationService $locationService, int $parentLocationId): array
6668
    {
6669
        $parentFoldersLocationsIds = [
6670
            $this->createFolder(['eng-US' => 'P1'], $parentLocationId)->contentInfo->mainLocationId,
6671
            $this->createFolder(['eng-US' => 'P2'], $parentLocationId)->contentInfo->mainLocationId,
6672
            $this->createFolder(['eng-US' => 'P3'], $parentLocationId)->contentInfo->mainLocationId,
6673
        ];
6674
6675
        return array_values($locationService->loadLocationList($parentFoldersLocationsIds));
6676
    }
6677
6678
    /**
6679
     * Filter Locations list by hidden only.
6680
     *
6681
     * @param \eZ\Publish\API\Repository\Values\Content\Location[] $locations
6682
     *
6683
     * @return array
6684
     */
6685
    private function filterHiddenLocations(array $locations): array
6686
    {
6687
        return array_values(
6688
            array_filter(
6689
                $locations,
6690
                function (Location $location) {
6691
                    return $location->hidden;
6692
                }
6693
            )
6694
        );
6695
    }
6696
6697
    public function testPublishVersionWithSelectedLanguages()
6698
    {
6699
        $repository = $this->getRepository();
6700
6701
        $contentService = $repository->getContentService();
6702
6703
        $publishedContent = $this->createFolder(
6704
            [
6705
                'eng-US' => 'Published US',
6706
                'ger-DE' => 'Published DE',
6707
            ],
6708
            $this->generateId('location', 2)
6709
        );
6710
6711
        $draft = $contentService->createContentDraft($publishedContent->contentInfo);
6712
        $contentUpdateStruct = new ContentUpdateStruct([
6713
            'initialLanguageCode' => 'eng-US',
6714
        ]);
6715
        $contentUpdateStruct->setField('name', 'Draft 1 US', 'eng-US');
6716
        $contentUpdateStruct->setField('name', 'Draft 1 DE', 'ger-DE');
6717
6718
        $contentService->updateContent($draft->versionInfo, $contentUpdateStruct);
6719
6720
        $contentService->publishVersion($draft->versionInfo, ['ger-DE']);
6721
        $content = $contentService->loadContent($draft->contentInfo->id);
6722
        $this->assertEquals(
6723
            [
6724
                'eng-US' => 'Published US',
6725
                'ger-DE' => 'Draft 1 DE',
6726
            ],
6727
            $content->fields['name']
6728
        );
6729
    }
6730
6731
    public function testCreateContentWithRomanianSpecialCharsInTitle()
6732
    {
6733
        $repository = $this->getRepository();
6734
6735
        $baseName = 'ȘșțȚdfdf';
6736
        $expectedPath = '/SstTdfdf';
6737
6738
        $this->createFolder(['eng-US' => $baseName], 2);
6739
6740
        $urlAliasService = $repository->getURLAliasService();
6741
        $urlAlias = $urlAliasService->lookup($expectedPath);
6742
        $this->assertSame($expectedPath, $urlAlias->path);
6743
    }
6744
}
6745