Completed
Push — master ( 161dc8...90572a )
by
unknown
27:22 queued 10:00
created

ContentServiceTest::assertDefaultContentStates()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 19

Duplication

Lines 19
Ratio 100 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 19
loc 19
rs 9.6333
c 0
b 0
f 0
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(array('limitationValues' => array(1))));
134
        $policyCreateStruct->addLimitation(new LocationLimitation(array('limitationValues' => array(2))));
135
        $policyCreateStruct->addLimitation(new ContentTypeLimitation(array('limitationValues' => array(1))));
136
        $roleDraft = $roleService->addPolicyByRoleDraft($roleDraft, $policyCreateStruct);
137
138
        $policyCreateStruct = $roleService->newPolicyCreateStruct('content', 'publish');
139
        $policyCreateStruct->addLimitation(new SectionLimitation(array('limitationValues' => array(1))));
140
        $policyCreateStruct->addLimitation(new LocationLimitation(array('limitationValues' => array(2))));
141
        $policyCreateStruct->addLimitation(new ContentTypeLimitation(array('limitationValues' => array(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
            array($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
            array(
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
            array(
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
            array(
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
            array(
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
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
302
     */
303
    public function testCreateContentThrowsInvalidArgumentException()
304
    {
305
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
306
307
        if ($this->isVersion4()) {
308
            $this->markTestSkipped('This test requires eZ Publish 5');
309
        }
310
311
        $repository = $this->getRepository();
312
313
        /* BEGIN: Use Case */
314
        $contentTypeService = $repository->getContentTypeService();
315
        $contentService = $repository->getContentService();
316
317
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
318
319
        $contentCreate1 = $contentService->newContentCreateStruct($contentType, 'eng-US');
320
        $contentCreate1->setField('name', 'An awesome Sidelfingen forum');
321
322
        $contentCreate1->remoteId = 'abcdef0123456789abcdef0123456789';
323
        $contentCreate1->alwaysAvailable = true;
324
325
        $draft = $contentService->createContent($contentCreate1);
326
        $contentService->publishVersion($draft->versionInfo);
327
328
        $contentCreate2 = $contentService->newContentCreateStruct($contentType, 'eng-GB');
329
        $contentCreate2->setField('name', 'An awesome Bielefeld forum');
330
331
        $contentCreate2->remoteId = 'abcdef0123456789abcdef0123456789';
332
        $contentCreate2->alwaysAvailable = false;
333
334
        // This call will fail with an "InvalidArgumentException", because the
335
        // remoteId is already in use.
336
        $contentService->createContent($contentCreate2);
337
        /* END: Use Case */
338
    }
339
340
    /**
341
     * Test for the createContent() method.
342
     *
343
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
344
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
345
     */
346
    public function testCreateContentThrowsInvalidArgumentExceptionOnFieldTypeNotAccept()
347
    {
348
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
349
350
        $repository = $this->getRepository();
351
352
        /* BEGIN: Use Case */
353
        $contentTypeService = $repository->getContentTypeService();
354
        $contentService = $repository->getContentService();
355
356
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
357
358
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
359
        // The name field does only accept strings and null as its values
360
        $contentCreate->setField('name', new \stdClass());
361
362
        // Throws InvalidArgumentException since the name field is filled
363
        // improperly
364
        $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...
365
        /* END: Use Case */
366
    }
367
368
    /**
369
     * Test for the createContent() method.
370
     *
371
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
372
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
373
     */
374
    public function testCreateContentThrowsContentFieldValidationException()
375
    {
376
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException::class);
377
378
        $repository = $this->getRepository();
379
380
        /* BEGIN: Use Case */
381
        $contentTypeService = $repository->getContentTypeService();
382
        $contentService = $repository->getContentService();
383
384
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
385
386
        $contentCreate1 = $contentService->newContentCreateStruct($contentType, 'eng-US');
387
        $contentCreate1->setField('name', 'An awesome Sidelfingen folder');
388
        // Violates string length constraint
389
        $contentCreate1->setField('short_name', str_repeat('a', 200));
390
391
        // Throws ContentFieldValidationException, since short_name does not pass
392
        // validation of the string length validator
393
        $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...
394
        /* END: Use Case */
395
    }
396
397
    /**
398
     * Test for the createContent() method.
399
     *
400
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
401
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
402
     */
403
    public function testCreateContentRequiredFieldMissing()
404
    {
405
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException::class);
406
407
        $repository = $this->getRepository();
408
409
        /* BEGIN: Use Case */
410
        $contentTypeService = $repository->getContentTypeService();
411
        $contentService = $repository->getContentService();
412
413
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
414
415
        $contentCreate1 = $contentService->newContentCreateStruct($contentType, 'eng-US');
416
        // Required field "name" is not set
417
418
        // Throws a ContentFieldValidationException, since a required field is
419
        // missing
420
        $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...
421
        /* END: Use Case */
422
    }
423
424
    /**
425
     * Test for the createContent() method.
426
     *
427
     * NOTE: We have bidirectional dependencies between the ContentService and
428
     * the LocationService, so that we cannot use PHPUnit's test dependencies
429
     * here.
430
     *
431
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
432
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
433
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationByRemoteId
434
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
435
     * @group user
436
     */
437
    public function testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately()
438
    {
439
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
440
441
        $repository = $this->getRepository();
442
443
        $locationService = $repository->getLocationService();
444
445
        /* BEGIN: Use Case */
446
        $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...
447
448
        // The location will not have been created, yet, so this throws an
449
        // exception
450
        $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...
451
            '0123456789abcdef0123456789abcdef'
452
        );
453
        /* END: Use Case */
454
    }
455
456
    /**
457
     * Test for the createContent() method.
458
     *
459
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
460
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
461
     */
462
    public function testCreateContentThrowsInvalidArgumentExceptionWithLocationCreateParameter()
463
    {
464
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
465
466
        $repository = $this->getRepository();
467
468
        $parentLocationId = $this->generateId('location', 56);
469
        /* BEGIN: Use Case */
470
        // $parentLocationId is a valid location ID
471
472
        $contentService = $repository->getContentService();
473
        $contentTypeService = $repository->getContentTypeService();
474
        $locationService = $repository->getLocationService();
475
476
        // Load content type
477
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
478
479
        // Configure new locations
480
        $locationCreate1 = $locationService->newLocationCreateStruct($parentLocationId);
481
482
        $locationCreate1->priority = 23;
483
        $locationCreate1->hidden = true;
484
        $locationCreate1->remoteId = '0123456789abcdef0123456789aaaaaa';
485
        $locationCreate1->sortField = Location::SORT_FIELD_NODE_ID;
486
        $locationCreate1->sortOrder = Location::SORT_ORDER_DESC;
487
488
        $locationCreate2 = $locationService->newLocationCreateStruct($parentLocationId);
489
490
        $locationCreate2->priority = 42;
491
        $locationCreate2->hidden = true;
492
        $locationCreate2->remoteId = '0123456789abcdef0123456789bbbbbb';
493
        $locationCreate2->sortField = Location::SORT_FIELD_NODE_ID;
494
        $locationCreate2->sortOrder = Location::SORT_ORDER_DESC;
495
496
        // Configure new content object
497
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
498
499
        $contentCreate->setField('name', 'A awesome Sindelfingen forum');
500
        $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
501
        $contentCreate->alwaysAvailable = true;
502
503
        // Create new content object under the specified location
504
        $draft = $contentService->createContent(
505
            $contentCreate,
506
            array($locationCreate1)
507
        );
508
        $contentService->publishVersion($draft->versionInfo);
509
510
        // This call will fail with an "InvalidArgumentException", because the
511
        // Content remoteId already exists,
512
        $contentService->createContent(
513
            $contentCreate,
514
            array($locationCreate2)
515
        );
516
        /* END: Use Case */
517
    }
518
519
    /**
520
     * Test for the loadContentInfo() method.
521
     *
522
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfo()
523
     * @group user
524
     */
525 View Code Duplication
    public function testLoadContentInfo()
526
    {
527
        $repository = $this->getRepository();
528
529
        $mediaFolderId = $this->generateId('object', 41);
530
        /* BEGIN: Use Case */
531
        $contentService = $repository->getContentService();
532
533
        // Load the ContentInfo for "Media" folder
534
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
535
        /* END: Use Case */
536
537
        $this->assertInstanceOf(
538
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo',
539
            $contentInfo
540
        );
541
542
        return $contentInfo;
543
    }
544
545
    /**
546
     * Test for the returned value of the loadContentInfo() method.
547
     *
548
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
549
     * @covers \eZ\Publish\API\Repository\ContentService::loadContentInfo
550
     *
551
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
552
     */
553
    public function testLoadContentInfoSetsExpectedContentInfo(ContentInfo $contentInfo)
554
    {
555
        $this->assertPropertiesCorrectUnsorted(
556
            $this->getExpectedMediaContentInfoProperties(),
557
            $contentInfo
558
        );
559
    }
560
561
    /**
562
     * Test for the loadContentInfo() method.
563
     *
564
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfo()
565
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
566
     */
567
    public function testLoadContentInfoThrowsNotFoundException()
568
    {
569
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
570
571
        $repository = $this->getRepository();
572
573
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
574
        /* BEGIN: Use Case */
575
        $contentService = $repository->getContentService();
576
577
        // This call will fail with a NotFoundException
578
        $contentService->loadContentInfo($nonExistentContentId);
579
        /* END: Use Case */
580
    }
581
582
    /**
583
     * Test for the loadContentInfoList() method.
584
     *
585
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoList()
586
     */
587
    public function testLoadContentInfoList()
588
    {
589
        $repository = $this->getRepository();
590
591
        $mediaFolderId = $this->generateId('object', 41);
592
        $contentService = $repository->getContentService();
593
        $list = $contentService->loadContentInfoList([$mediaFolderId]);
594
595
        $this->assertCount(1, $list);
596
        $this->assertEquals([$mediaFolderId], array_keys($list), 'Array key was not content id');
597
        $this->assertInstanceOf(
598
            ContentInfo::class,
599
            $list[$mediaFolderId]
600
        );
601
    }
602
603
    /**
604
     * Test for the loadContentInfoList() method.
605
     *
606
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoList()
607
     * @depends testLoadContentInfoList
608
     */
609 View Code Duplication
    public function testLoadContentInfoListSkipsNotFoundItems()
610
    {
611
        $repository = $this->getRepository();
612
613
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
614
        $contentService = $repository->getContentService();
615
        $list = $contentService->loadContentInfoList([$nonExistentContentId]);
616
617
        $this->assertCount(0, $list);
618
    }
619
620
    /**
621
     * Test for the loadContentInfoByRemoteId() method.
622
     *
623
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoByRemoteId()
624
     */
625
    public function testLoadContentInfoByRemoteId()
626
    {
627
        $repository = $this->getRepository();
628
629
        /* BEGIN: Use Case */
630
        $contentService = $repository->getContentService();
631
632
        // Load the ContentInfo for "Media" folder
633
        $contentInfo = $contentService->loadContentInfoByRemoteId('faaeb9be3bd98ed09f606fc16d144eca');
634
        /* END: Use Case */
635
636
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo', $contentInfo);
637
638
        return $contentInfo;
639
    }
640
641
    /**
642
     * Test for the returned value of the loadContentInfoByRemoteId() method.
643
     *
644
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfoByRemoteId
645
     * @covers \eZ\Publish\API\Repository\ContentService::loadContentInfoByRemoteId
646
     *
647
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
648
     */
649 View Code Duplication
    public function testLoadContentInfoByRemoteIdSetsExpectedContentInfo(ContentInfo $contentInfo)
650
    {
651
        $this->assertPropertiesCorrectUnsorted(
652
            [
653
                'id' => 10,
654
                'contentTypeId' => 4,
655
                'name' => 'Anonymous User',
656
                'sectionId' => 2,
657
                'currentVersionNo' => 2,
658
                'published' => true,
659
                'ownerId' => 14,
660
                'modificationDate' => $this->createDateTime(1072180405),
661
                'publishedDate' => $this->createDateTime(1033920665),
662
                'alwaysAvailable' => 1,
663
                'remoteId' => 'faaeb9be3bd98ed09f606fc16d144eca',
664
                'mainLanguageCode' => 'eng-US',
665
                'mainLocationId' => 45,
666
            ],
667
            $contentInfo
668
        );
669
    }
670
671
    /**
672
     * Test for the loadContentInfoByRemoteId() method.
673
     *
674
     * @see \eZ\Publish\API\Repository\ContentService::loadContentInfoByRemoteId()
675
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfoByRemoteId
676
     */
677
    public function testLoadContentInfoByRemoteIdThrowsNotFoundException()
678
    {
679
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
680
681
        $repository = $this->getRepository();
682
683
        /* BEGIN: Use Case */
684
        $contentService = $repository->getContentService();
685
686
        // This call will fail with a NotFoundException
687
        $contentService->loadContentInfoByRemoteId('abcdefghijklmnopqrstuvwxyz0123456789');
688
        /* END: Use Case */
689
    }
690
691
    /**
692
     * Test for the loadVersionInfo() method.
693
     *
694
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo()
695
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
696
     * @group user
697
     */
698 View Code Duplication
    public function testLoadVersionInfo()
699
    {
700
        $repository = $this->getRepository();
701
702
        $mediaFolderId = $this->generateId('object', 41);
703
        /* BEGIN: Use Case */
704
        // $mediaFolderId contains the ID of the "Media" folder
705
706
        $contentService = $repository->getContentService();
707
708
        // Load the ContentInfo for "Media" folder
709
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
710
711
        // Now load the current version info of the "Media" folder
712
        $versionInfo = $contentService->loadVersionInfo($contentInfo);
713
        /* END: Use Case */
714
715
        $this->assertInstanceOf(
716
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo',
717
            $versionInfo
718
        );
719
    }
720
721
    /**
722
     * Test for the loadVersionInfoById() method.
723
     *
724
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById()
725
     */
726 View Code Duplication
    public function testLoadVersionInfoById()
727
    {
728
        $repository = $this->getRepository();
729
730
        $mediaFolderId = $this->generateId('object', 41);
731
        /* BEGIN: Use Case */
732
        // $mediaFolderId contains the ID of the "Media" folder
733
734
        $contentService = $repository->getContentService();
735
736
        // Load the VersionInfo for "Media" folder
737
        $versionInfo = $contentService->loadVersionInfoById($mediaFolderId);
738
        /* END: Use Case */
739
740
        $this->assertInstanceOf(
741
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\VersionInfo',
742
            $versionInfo
743
        );
744
745
        return $versionInfo;
746
    }
747
748
    /**
749
     * Test for the returned value of the loadVersionInfoById() method.
750
     *
751
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoById
752
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersionInfoById
753
     *
754
     * @param \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfo
755
     */
756
    public function testLoadVersionInfoByIdSetsExpectedVersionInfo(VersionInfo $versionInfo)
757
    {
758
        $this->assertPropertiesCorrect(
759
            [
760
                'names' => [
761
                    'eng-US' => 'Media',
762
                ],
763
                'contentInfo' => new ContentInfo($this->getExpectedMediaContentInfoProperties()),
764
                'id' => 472,
765
                'versionNo' => 1,
766
                'modificationDate' => $this->createDateTime(1060695457),
767
                'creatorId' => 14,
768
                'creationDate' => $this->createDateTime(1060695450),
769
                'status' => VersionInfo::STATUS_PUBLISHED,
770
                'initialLanguageCode' => 'eng-US',
771
                'languageCodes' => [
772
                    'eng-US',
773
                ],
774
            ],
775
            $versionInfo
776
        );
777
        $this->assertTrue($versionInfo->isPublished());
778
        $this->assertFalse($versionInfo->isDraft());
779
        $this->assertFalse($versionInfo->isArchived());
780
    }
781
782
    /**
783
     * Test for the loadVersionInfoById() method.
784
     *
785
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById()
786
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoById
787
     */
788
    public function testLoadVersionInfoByIdThrowsNotFoundException()
789
    {
790
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
791
792
        $repository = $this->getRepository();
793
794
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
795
        /* BEGIN: Use Case */
796
        $contentService = $repository->getContentService();
797
798
        // This call will fail with a "NotFoundException"
799
        $contentService->loadVersionInfoById($nonExistentContentId);
800
        /* END: Use Case */
801
    }
802
803
    /**
804
     * Test for the loadContentByContentInfo() method.
805
     *
806
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo()
807
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
808
     */
809 View Code Duplication
    public function testLoadContentByContentInfo()
810
    {
811
        $repository = $this->getRepository();
812
813
        $mediaFolderId = $this->generateId('object', 41);
814
        /* BEGIN: Use Case */
815
        // $mediaFolderId contains the ID of the "Media" folder
816
817
        $contentService = $repository->getContentService();
818
819
        // Load the ContentInfo for "Media" folder
820
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
821
822
        // Now load the current content version for the info instance
823
        $content = $contentService->loadContentByContentInfo($contentInfo);
824
        /* END: Use Case */
825
826
        $this->assertInstanceOf(
827
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
828
            $content
829
        );
830
    }
831
832
    /**
833
     * Test for the loadContentByVersionInfo() method.
834
     *
835
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByVersionInfo()
836
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
837
     */
838
    public function testLoadContentByVersionInfo()
839
    {
840
        $repository = $this->getRepository();
841
842
        $mediaFolderId = $this->generateId('object', 41);
843
        /* BEGIN: Use Case */
844
        // $mediaFolderId contains the ID of the "Media" folder
845
846
        $contentService = $repository->getContentService();
847
848
        // Load the ContentInfo for "Media" folder
849
        $contentInfo = $contentService->loadContentInfo($mediaFolderId);
850
851
        // Load the current VersionInfo
852
        $versionInfo = $contentService->loadVersionInfo($contentInfo);
853
854
        // Now load the current content version for the info instance
855
        $content = $contentService->loadContentByVersionInfo($versionInfo);
856
        /* END: Use Case */
857
858
        $this->assertInstanceOf(
859
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
860
            $content
861
        );
862
    }
863
864
    /**
865
     * Test for the loadContent() method.
866
     *
867
     * @see \eZ\Publish\API\Repository\ContentService::loadContent()
868
     * @group user
869
     * @group field-type
870
     */
871 View Code Duplication
    public function testLoadContent()
872
    {
873
        $repository = $this->getRepository();
874
875
        $mediaFolderId = $this->generateId('object', 41);
876
        /* BEGIN: Use Case */
877
        // $mediaFolderId contains the ID of the "Media" folder
878
879
        $contentService = $repository->getContentService();
880
881
        // Load the Content for "Media" folder, any language and current version
882
        $content = $contentService->loadContent($mediaFolderId);
883
        /* END: Use Case */
884
885
        $this->assertInstanceOf(
886
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
887
            $content
888
        );
889
    }
890
891
    /**
892
     * Test for the loadContent() method.
893
     *
894
     * @see \eZ\Publish\API\Repository\ContentService::loadContent()
895
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
896
     */
897
    public function testLoadContentThrowsNotFoundException()
898
    {
899
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
900
901
        $repository = $this->getRepository();
902
903
        $nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
904
        /* BEGIN: Use Case */
905
        $contentService = $repository->getContentService();
906
907
        // This call will fail with a "NotFoundException"
908
        $contentService->loadContent($nonExistentContentId);
909
        /* END: Use Case */
910
    }
911
912
    /**
913
     * Data provider for testLoadContentByRemoteId().
914
     *
915
     * @return array
916
     */
917
    public function contentRemoteIdVersionLanguageProvider()
918
    {
919
        return [
920
            ['f5c88a2209584891056f987fd965b0ba', null, null],
921
            ['f5c88a2209584891056f987fd965b0ba', ['eng-US'], null],
922
            ['f5c88a2209584891056f987fd965b0ba', null, 1],
923
            ['f5c88a2209584891056f987fd965b0ba', ['eng-US'], 1],
924
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', null, null],
925
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', ['eng-US'], null],
926
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', null, 1],
927
            ['a6e35cbcb7cd6ae4b691f3eee30cd262', ['eng-US'], 1],
928
        ];
929
    }
930
931
    /**
932
     * Test for the loadContentByRemoteId() method.
933
     *
934
     * @covers \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId
935
     * @dataProvider contentRemoteIdVersionLanguageProvider
936
     *
937
     * @param string $remoteId
938
     * @param array|null $languages
939
     * @param int $versionNo
940
     */
941
    public function testLoadContentByRemoteId($remoteId, $languages, $versionNo)
942
    {
943
        $repository = $this->getRepository();
944
945
        $contentService = $repository->getContentService();
946
947
        $content = $contentService->loadContentByRemoteId($remoteId, $languages, $versionNo);
948
949
        $this->assertInstanceOf(
950
            Content::class,
951
            $content
952
        );
953
954
        $this->assertEquals($remoteId, $content->contentInfo->remoteId);
955
        if ($languages !== null) {
956
            $this->assertEquals($languages, $content->getVersionInfo()->languageCodes);
957
        }
958
        $this->assertEquals($versionNo ?: 1, $content->getVersionInfo()->versionNo);
959
    }
960
961
    /**
962
     * Test for the loadContentByRemoteId() method.
963
     *
964
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId()
965
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteId
966
     */
967
    public function testLoadContentByRemoteIdThrowsNotFoundException()
968
    {
969
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
970
971
        $repository = $this->getRepository();
972
973
        /* BEGIN: Use Case */
974
        $contentService = $repository->getContentService();
975
976
        // This call will fail with a "NotFoundException", because no content
977
        // object exists for the given remoteId
978
        $contentService->loadContentByRemoteId('a1b1c1d1e1f1a2b2c2d2e2f2a3b3c3d3');
979
        /* END: Use Case */
980
    }
981
982
    /**
983
     * Test for the publishVersion() method.
984
     *
985
     * @return \eZ\Publish\API\Repository\Values\Content\Content
986
     *
987
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
988
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
989
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
990
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
991
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
992
     * @group user
993
     * @group field-type
994
     */
995
    public function testPublishVersion()
996
    {
997
        $time = time();
998
        /* BEGIN: Use Case */
999
        $content = $this->createContentVersion1();
1000
        /* END: Use Case */
1001
1002
        $this->assertInstanceOf(Content::class, $content);
1003
        $this->assertTrue($content->contentInfo->published);
1004
        $this->assertEquals(VersionInfo::STATUS_PUBLISHED, $content->versionInfo->status);
1005
        $this->assertGreaterThanOrEqual($time, $content->contentInfo->publishedDate->getTimestamp());
1006
        $this->assertGreaterThanOrEqual($time, $content->contentInfo->modificationDate->getTimestamp());
1007
        $this->assertTrue($content->versionInfo->isPublished());
1008
        $this->assertFalse($content->versionInfo->isDraft());
1009
        $this->assertFalse($content->versionInfo->isArchived());
1010
1011
        return $content;
1012
    }
1013
1014
    /**
1015
     * Test for the publishVersion() method.
1016
     *
1017
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1018
     *
1019
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1020
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1021
     */
1022
    public function testPublishVersionSetsExpectedContentInfo($content)
1023
    {
1024
        $this->assertEquals(
1025
            array(
1026
                $content->id,
1027
                true,
1028
                1,
1029
                'abcdef0123456789abcdef0123456789',
1030
                'eng-US',
1031
                $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...
1032
                true,
1033
            ),
1034
            array(
1035
                $content->contentInfo->id,
1036
                $content->contentInfo->alwaysAvailable,
1037
                $content->contentInfo->currentVersionNo,
1038
                $content->contentInfo->remoteId,
1039
                $content->contentInfo->mainLanguageCode,
1040
                $content->contentInfo->ownerId,
1041
                $content->contentInfo->published,
1042
            )
1043
        );
1044
1045
        $this->assertNotNull($content->contentInfo->mainLocationId);
1046
        $date = new \DateTime('1984/01/01');
1047
        $this->assertGreaterThan(
1048
            $date->getTimestamp(),
1049
            $content->contentInfo->publishedDate->getTimestamp()
1050
        );
1051
    }
1052
1053
    /**
1054
     * Test for the publishVersion() method.
1055
     *
1056
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1057
     *
1058
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1059
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1060
     */
1061
    public function testPublishVersionSetsExpectedVersionInfo($content)
1062
    {
1063
        $this->assertEquals(
1064
            array(
1065
                $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...
1066
                'eng-US',
1067
                VersionInfo::STATUS_PUBLISHED,
1068
                1,
1069
            ),
1070
            array(
1071
                $content->getVersionInfo()->creatorId,
1072
                $content->getVersionInfo()->initialLanguageCode,
1073
                $content->getVersionInfo()->status,
1074
                $content->getVersionInfo()->versionNo,
1075
            )
1076
        );
1077
1078
        $date = new \DateTime('1984/01/01');
1079
        $this->assertGreaterThan(
1080
            $date->getTimestamp(),
1081
            $content->getVersionInfo()->modificationDate->getTimestamp()
1082
        );
1083
1084
        $this->assertNotNull($content->getVersionInfo()->modificationDate);
1085
        $this->assertTrue($content->getVersionInfo()->isPublished());
1086
        $this->assertFalse($content->getVersionInfo()->isDraft());
1087
        $this->assertFalse($content->getVersionInfo()->isArchived());
1088
    }
1089
1090
    /**
1091
     * Test for the publishVersion() method.
1092
     *
1093
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1094
     *
1095
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1096
     * @depends testPublishVersion
1097
     */
1098
    public function testPublishVersionSetsExpectedContentType($content)
1099
    {
1100
        $contentType = $content->getContentType();
1101
1102
        $this->assertEquals(
1103
            [
1104
                $contentType->id,
1105
                // won't be a match as it's set to true in createContentDraftVersion1()
1106
                //$contentType->defaultAlwaysAvailable,
1107
                //$contentType->defaultSortField,
1108
                //$contentType->defaultSortOrder,
1109
            ],
1110
            [
1111
                $content->contentInfo->contentTypeId,
1112
                //$content->contentInfo->alwaysAvailable,
1113
                //$location->sortField,
1114
                //$location->sortOrder,
1115
            ]
1116
        );
1117
    }
1118
1119
    /**
1120
     * Test for the publishVersion() method.
1121
     *
1122
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1123
     *
1124
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1125
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
1126
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1127
     */
1128
    public function testPublishVersionCreatesLocationsDefinedOnCreate()
1129
    {
1130
        $repository = $this->getRepository();
1131
1132
        /* BEGIN: Use Case */
1133
        $content = $this->createContentVersion1();
1134
        /* END: Use Case */
1135
1136
        $locationService = $repository->getLocationService();
1137
        $location = $locationService->loadLocationByRemoteId(
1138
            '0123456789abcdef0123456789abcdef'
1139
        );
1140
1141
        $this->assertEquals(
1142
            $location->getContentInfo(),
1143
            $content->getVersionInfo()->getContentInfo()
1144
        );
1145
1146
        return array($content, $location);
1147
    }
1148
1149
    /**
1150
     * Test for the publishVersion() method.
1151
     *
1152
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1153
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionCreatesLocationsDefinedOnCreate
1154
     */
1155
    public function testCreateContentWithLocationCreateParameterCreatesExpectedLocation(array $testData)
1156
    {
1157
        /** @var \eZ\Publish\API\Repository\Values\Content\Content $content */
1158
        /** @var \eZ\Publish\API\Repository\Values\Content\Location $location */
1159
        list($content, $location) = $testData;
1160
1161
        $parentLocationId = $this->generateId('location', 56);
1162
        $parentLocation = $this->getRepository()->getLocationService()->loadLocation($parentLocationId);
1163
        $mainLocationId = $content->getVersionInfo()->getContentInfo()->mainLocationId;
1164
1165
        $this->assertPropertiesCorrect(
1166
            array(
1167
                'id' => $mainLocationId,
1168
                'priority' => 23,
1169
                'hidden' => true,
1170
                'invisible' => true,
1171
                'remoteId' => '0123456789abcdef0123456789abcdef',
1172
                'parentLocationId' => $parentLocationId,
1173
                'pathString' => $parentLocation->pathString . $mainLocationId . '/',
1174
                'depth' => $parentLocation->depth + 1,
1175
                'sortField' => Location::SORT_FIELD_NODE_ID,
1176
                'sortOrder' => Location::SORT_ORDER_DESC,
1177
            ),
1178
            $location
1179
        );
1180
    }
1181
1182
    /**
1183
     * Test for the publishVersion() method.
1184
     *
1185
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1186
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1187
     */
1188
    public function testPublishVersionThrowsBadStateException()
1189
    {
1190
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
1191
1192
        $repository = $this->getRepository();
1193
1194
        $contentService = $repository->getContentService();
1195
1196
        /* BEGIN: Use Case */
1197
        $draft = $this->createContentDraftVersion1();
1198
1199
        // Publish the content draft
1200
        $contentService->publishVersion($draft->getVersionInfo());
1201
1202
        // This call will fail with a "BadStateException", because the version
1203
        // is already published.
1204
        $contentService->publishVersion($draft->getVersionInfo());
1205
        /* END: Use Case */
1206
    }
1207
1208
    /**
1209
     * Test that publishVersion() does not affect publishedDate (assuming previous version exists).
1210
     *
1211
     * @covers \eZ\Publish\API\Repository\ContentService::publishVersion
1212
     */
1213
    public function testPublishVersionDoesNotChangePublishedDate()
1214
    {
1215
        $repository = $this->getRepository();
1216
1217
        $contentService = $repository->getContentService();
1218
1219
        $publishedContent = $this->createContentVersion1();
1220
1221
        // force timestamps to differ
1222
        sleep(1);
1223
1224
        $contentDraft = $contentService->createContentDraft($publishedContent->contentInfo);
1225
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1226
        $contentUpdateStruct->setField('name', 'New name');
1227
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
1228
        $republishedContent = $contentService->publishVersion($contentDraft->versionInfo);
1229
1230
        $this->assertEquals(
1231
            $publishedContent->contentInfo->publishedDate->getTimestamp(),
1232
            $republishedContent->contentInfo->publishedDate->getTimestamp()
1233
        );
1234
        $this->assertGreaterThan(
1235
            $publishedContent->contentInfo->modificationDate->getTimestamp(),
1236
            $republishedContent->contentInfo->modificationDate->getTimestamp()
1237
        );
1238
    }
1239
1240
    /**
1241
     * Test for the createContentDraft() method.
1242
     *
1243
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1244
     *
1245
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1246
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1247
     * @group user
1248
     */
1249
    public function testCreateContentDraft()
1250
    {
1251
        $repository = $this->getRepository();
1252
1253
        $contentService = $repository->getContentService();
1254
1255
        /* BEGIN: Use Case */
1256
        $content = $this->createContentVersion1();
1257
1258
        // Now we create a new draft from the published content
1259
        $draftedContent = $contentService->createContentDraft($content->contentInfo);
1260
        /* END: Use Case */
1261
1262
        $this->assertInstanceOf(
1263
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1264
            $draftedContent
1265
        );
1266
1267
        return $draftedContent;
1268
    }
1269
1270
    /**
1271
     * Test for the createContentDraft() method.
1272
     *
1273
     * Test that editor has access to edit own draft.
1274
     * Note: Editors have access to version_read, which is needed to load content drafts.
1275
     *
1276
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1277
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1278
     * @group user
1279
     */
1280 View Code Duplication
    public function testCreateContentDraftAndLoadAccess()
1281
    {
1282
        $repository = $this->getRepository();
1283
1284
        /* BEGIN: Use Case */
1285
        $user = $this->createUserVersion1();
1286
1287
        // Set new editor as user
1288
        $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...
1289
1290
        // Create draft
1291
        $draft = $this->createContentDraftVersion1(2, 'folder');
1292
1293
        // Try to load the draft
1294
        $contentService = $repository->getContentService();
1295
        $loadedDraft = $contentService->loadContent($draft->id);
1296
1297
        /* END: Use Case */
1298
1299
        $this->assertEquals($draft->id, $loadedDraft->id);
1300
    }
1301
1302
    /**
1303
     * Test for the createContentDraft() method.
1304
     *
1305
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1306
     *
1307
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1308
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1309
     */
1310
    public function testCreateContentDraftSetsExpectedProperties($draft)
1311
    {
1312
        $this->assertEquals(
1313
            array(
1314
                'fieldCount' => 2,
1315
                'relationCount' => 0,
1316
            ),
1317
            array(
1318
                'fieldCount' => count($draft->getFields()),
1319
                'relationCount' => count($this->getRepository()->getContentService()->loadRelations($draft->getVersionInfo())),
1320
            )
1321
        );
1322
    }
1323
1324
    /**
1325
     * Test for the createContentDraft() method.
1326
     *
1327
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1328
     *
1329
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1330
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1331
     */
1332
    public function testCreateContentDraftSetsContentInfo($draft)
1333
    {
1334
        $contentInfo = $draft->contentInfo;
1335
1336
        $this->assertEquals(
1337
            array(
1338
                $draft->id,
1339
                true,
1340
                1,
1341
                'eng-US',
1342
                $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...
1343
                'abcdef0123456789abcdef0123456789',
1344
                1,
1345
            ),
1346
            array(
1347
                $contentInfo->id,
1348
                $contentInfo->alwaysAvailable,
1349
                $contentInfo->currentVersionNo,
1350
                $contentInfo->mainLanguageCode,
1351
                $contentInfo->ownerId,
1352
                $contentInfo->remoteId,
1353
                $contentInfo->sectionId,
1354
            )
1355
        );
1356
    }
1357
1358
    /**
1359
     * Test for the createContentDraft() method.
1360
     *
1361
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1362
     *
1363
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1364
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1365
     */
1366
    public function testCreateContentDraftSetsVersionInfo($draft)
1367
    {
1368
        $versionInfo = $draft->getVersionInfo();
1369
1370
        $this->assertEquals(
1371
            array(
1372
                '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...
1373
                'initialLanguageCode' => 'eng-US',
1374
                'languageCodes' => array(0 => 'eng-US'),
1375
                'status' => VersionInfo::STATUS_DRAFT,
1376
                'versionNo' => 2,
1377
            ),
1378
            array(
1379
                'creatorId' => $versionInfo->creatorId,
1380
                'initialLanguageCode' => $versionInfo->initialLanguageCode,
1381
                'languageCodes' => $versionInfo->languageCodes,
1382
                'status' => $versionInfo->status,
1383
                'versionNo' => $versionInfo->versionNo,
1384
            )
1385
        );
1386
        $this->assertTrue($versionInfo->isDraft());
1387
        $this->assertFalse($versionInfo->isPublished());
1388
        $this->assertFalse($versionInfo->isArchived());
1389
    }
1390
1391
    /**
1392
     * Test for the createContentDraft() method.
1393
     *
1394
     * @param \eZ\Publish\API\Repository\Values\Content\Content $draft
1395
     *
1396
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1397
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1398
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
1399
     */
1400 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...
1401
    {
1402
        $repository = $this->getRepository();
1403
1404
        $contentService = $repository->getContentService();
1405
1406
        /* BEGIN: Use Case */
1407
        $content = $this->createContentVersion1();
1408
1409
        // Now we create a new draft from the published content
1410
        $contentService->createContentDraft($content->contentInfo);
1411
1412
        // This call will still load the published version
1413
        $versionInfoPublished = $contentService->loadVersionInfo($content->contentInfo);
1414
        /* END: Use Case */
1415
1416
        $this->assertEquals(1, $versionInfoPublished->versionNo);
1417
    }
1418
1419
    /**
1420
     * Test for the createContentDraft() method.
1421
     *
1422
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1423
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
1424
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1425
     */
1426 View Code Duplication
    public function testCreateContentDraftLoadContentStillLoadsPublishedVersion()
1427
    {
1428
        $repository = $this->getRepository();
1429
1430
        $contentService = $repository->getContentService();
1431
1432
        /* BEGIN: Use Case */
1433
        $content = $this->createContentVersion1();
1434
1435
        // Now we create a new draft from the published content
1436
        $contentService->createContentDraft($content->contentInfo);
1437
1438
        // This call will still load the published content version
1439
        $contentPublished = $contentService->loadContent($content->id);
1440
        /* END: Use Case */
1441
1442
        $this->assertEquals(1, $contentPublished->getVersionInfo()->versionNo);
1443
    }
1444
1445
    /**
1446
     * Test for the createContentDraft() method.
1447
     *
1448
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1449
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteId
1450
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1451
     */
1452 View Code Duplication
    public function testCreateContentDraftLoadContentByRemoteIdStillLoadsPublishedVersion()
1453
    {
1454
        $repository = $this->getRepository();
1455
1456
        $contentService = $repository->getContentService();
1457
1458
        /* BEGIN: Use Case */
1459
        $content = $this->createContentVersion1();
1460
1461
        // Now we create a new draft from the published content
1462
        $contentService->createContentDraft($content->contentInfo);
1463
1464
        // This call will still load the published content version
1465
        $contentPublished = $contentService->loadContentByRemoteId('abcdef0123456789abcdef0123456789');
1466
        /* END: Use Case */
1467
1468
        $this->assertEquals(1, $contentPublished->getVersionInfo()->versionNo);
1469
    }
1470
1471
    /**
1472
     * Test for the createContentDraft() method.
1473
     *
1474
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
1475
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfo
1476
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1477
     */
1478 View Code Duplication
    public function testCreateContentDraftLoadContentByContentInfoStillLoadsPublishedVersion()
1479
    {
1480
        $repository = $this->getRepository();
1481
1482
        $contentService = $repository->getContentService();
1483
1484
        /* BEGIN: Use Case */
1485
        $content = $this->createContentVersion1();
1486
1487
        // Now we create a new draft from the published content
1488
        $contentService->createContentDraft($content->contentInfo);
1489
1490
        // This call will still load the published content version
1491
        $contentPublished = $contentService->loadContentByContentInfo($content->contentInfo);
1492
        /* END: Use Case */
1493
1494
        $this->assertEquals(1, $contentPublished->getVersionInfo()->versionNo);
1495
    }
1496
1497
    /**
1498
     * Test for the newContentUpdateStruct() method.
1499
     *
1500
     * @covers \eZ\Publish\API\Repository\ContentService::newContentUpdateStruct
1501
     * @group user
1502
     */
1503
    public function testNewContentUpdateStruct()
1504
    {
1505
        $repository = $this->getRepository();
1506
1507
        /* BEGIN: Use Case */
1508
        $contentService = $repository->getContentService();
1509
1510
        $updateStruct = $contentService->newContentUpdateStruct();
1511
        /* END: Use Case */
1512
1513
        $this->assertInstanceOf(
1514
            ContentUpdateStruct::class,
1515
            $updateStruct
1516
        );
1517
1518
        $this->assertPropertiesCorrect(
1519
            [
1520
                'initialLanguageCode' => null,
1521
                'fields' => [],
1522
            ],
1523
            $updateStruct
1524
        );
1525
    }
1526
1527
    /**
1528
     * Test for the updateContent() method.
1529
     *
1530
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1531
     *
1532
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1533
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentUpdateStruct
1534
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1535
     * @group user
1536
     * @group field-type
1537
     */
1538
    public function testUpdateContent()
1539
    {
1540
        /* BEGIN: Use Case */
1541
        $draftVersion2 = $this->createUpdatedDraftVersion2();
1542
        /* END: Use Case */
1543
1544
        $this->assertInstanceOf(
1545
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1546
            $draftVersion2
1547
        );
1548
1549
        $this->assertEquals(
1550
            $this->generateId('user', 10),
1551
            $draftVersion2->versionInfo->creatorId,
1552
            'creatorId is not properly set on new Version'
1553
        );
1554
1555
        return $draftVersion2;
1556
    }
1557
1558
    /**
1559
     * Test for the updateContent_WithDifferentUser() method.
1560
     *
1561
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1562
     *
1563
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1564
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentUpdateStruct
1565
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
1566
     * @group user
1567
     * @group field-type
1568
     */
1569
    public function testUpdateContentWithDifferentUser()
1570
    {
1571
        /* BEGIN: Use Case */
1572
        $arrayWithDraftVersion2 = $this->createUpdatedDraftVersion2NotAdmin();
1573
        /* END: Use Case */
1574
1575
        $this->assertInstanceOf(
1576
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
1577
            $arrayWithDraftVersion2[0]
1578
        );
1579
1580
        $this->assertEquals(
1581
            $this->generateId('user', $arrayWithDraftVersion2[1]),
1582
            $arrayWithDraftVersion2[0]->versionInfo->creatorId,
1583
            'creatorId is not properly set on new Version'
1584
        );
1585
1586
        return $arrayWithDraftVersion2[0];
1587
    }
1588
1589
    /**
1590
     * Test for the updateContent() method.
1591
     *
1592
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
1593
     *
1594
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1595
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1596
     */
1597
    public function testUpdateContentSetsExpectedFields($content)
1598
    {
1599
        $actual = $this->normalizeFields($content->getFields());
1600
1601
        $expected = array(
1602
            new Field(
1603
                array(
1604
                    'id' => 0,
1605
                    'value' => true,
1606
                    'languageCode' => 'eng-GB',
1607
                    'fieldDefIdentifier' => 'description',
1608
                    'fieldTypeIdentifier' => 'ezrichtext',
1609
                )
1610
            ),
1611
            new Field(
1612
                array(
1613
                    'id' => 0,
1614
                    'value' => true,
1615
                    'languageCode' => 'eng-US',
1616
                    'fieldDefIdentifier' => 'description',
1617
                    'fieldTypeIdentifier' => 'ezrichtext',
1618
                )
1619
            ),
1620
            new Field(
1621
                array(
1622
                    'id' => 0,
1623
                    'value' => true,
1624
                    'languageCode' => 'eng-GB',
1625
                    'fieldDefIdentifier' => 'name',
1626
                    'fieldTypeIdentifier' => 'ezstring',
1627
                )
1628
            ),
1629
            new Field(
1630
                array(
1631
                    'id' => 0,
1632
                    'value' => true,
1633
                    'languageCode' => 'eng-US',
1634
                    'fieldDefIdentifier' => 'name',
1635
                    'fieldTypeIdentifier' => 'ezstring',
1636
                )
1637
            ),
1638
        );
1639
1640
        $this->assertEquals($expected, $actual);
1641
    }
1642
1643
    /**
1644
     * Test for the updateContent() method.
1645
     *
1646
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1647
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1648
     */
1649
    public function testUpdateContentThrowsBadStateException()
1650
    {
1651
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
1652
1653
        $repository = $this->getRepository();
1654
1655
        $contentService = $repository->getContentService();
1656
1657
        /* BEGIN: Use Case */
1658
        $content = $this->createContentVersion1();
1659
1660
        // Now create an update struct and modify some fields
1661
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1662
        $contentUpdateStruct->setField('title', 'An awesome² story about ezp.');
1663
        $contentUpdateStruct->setField('title', 'An awesome²³ story about ezp.', 'eng-GB');
1664
1665
        $contentUpdateStruct->initialLanguageCode = 'eng-US';
1666
1667
        // This call will fail with a "BadStateException", because $publishedContent
1668
        // is not a draft.
1669
        $contentService->updateContent(
1670
            $content->getVersionInfo(),
1671
            $contentUpdateStruct
1672
        );
1673
        /* END: Use Case */
1674
    }
1675
1676
    /**
1677
     * Test for the updateContent() method.
1678
     *
1679
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1680
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1681
     */
1682 View Code Duplication
    public function testUpdateContentThrowsInvalidArgumentExceptionWhenFieldTypeDoesNotAccept()
1683
    {
1684
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
1685
1686
        $repository = $this->getRepository();
1687
1688
        $contentService = $repository->getContentService();
1689
1690
        /* BEGIN: Use Case */
1691
        $draft = $this->createContentDraftVersion1();
1692
1693
        // Now create an update struct and modify some fields
1694
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1695
        // The name field does not accept a stdClass object as its input
1696
        $contentUpdateStruct->setField('name', new \stdClass(), 'eng-US');
1697
1698
        // Throws an InvalidArgumentException, since the value for field "name"
1699
        // is not accepted
1700
        $contentService->updateContent(
1701
            $draft->getVersionInfo(),
1702
            $contentUpdateStruct
1703
        );
1704
        /* END: Use Case */
1705
    }
1706
1707
    /**
1708
     * Test for the updateContent() method.
1709
     *
1710
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1711
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1712
     */
1713 View Code Duplication
    public function testUpdateContentWhenMandatoryFieldIsEmpty()
1714
    {
1715
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException::class);
1716
1717
        $repository = $this->getRepository();
1718
1719
        $contentService = $repository->getContentService();
1720
1721
        /* BEGIN: Use Case */
1722
        $draft = $this->createContentDraftVersion1();
1723
1724
        // Now create an update struct and set a mandatory field to null
1725
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1726
        $contentUpdateStruct->setField('name', null);
1727
1728
        // Don't set this, then the above call without languageCode will fail
1729
        $contentUpdateStruct->initialLanguageCode = 'eng-US';
1730
1731
        // This call will fail with a "ContentFieldValidationException", because the
1732
        // mandatory "name" field is empty.
1733
        $contentService->updateContent(
1734
            $draft->getVersionInfo(),
1735
            $contentUpdateStruct
1736
        );
1737
        /* END: Use Case */
1738
    }
1739
1740
    /**
1741
     * Test for the updateContent() method.
1742
     *
1743
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1744
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1745
     */
1746 View Code Duplication
    public function testUpdateContentThrowsContentFieldValidationException()
1747
    {
1748
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException::class);
1749
1750
        $repository = $this->getRepository();
1751
1752
        /* BEGIN: Use Case */
1753
        $contentTypeService = $repository->getContentTypeService();
1754
        $contentService = $repository->getContentService();
1755
1756
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
1757
1758
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
1759
        $contentCreate->setField('name', 'An awesome Sidelfingen folder');
1760
1761
        $draft = $contentService->createContent($contentCreate);
1762
1763
        $contentUpdate = $contentService->newContentUpdateStruct();
1764
        // Violates string length constraint
1765
        $contentUpdate->setField('short_name', str_repeat('a', 200), 'eng-US');
1766
1767
        // Throws ContentFieldValidationException because the string length
1768
        // validation of the field "short_name" fails
1769
        $contentService->updateContent($draft->getVersionInfo(), $contentUpdate);
1770
        /* END: Use Case */
1771
    }
1772
1773
    /**
1774
     * Test for the updateContent() method.
1775
     *
1776
     * @covers \eZ\Publish\API\Repository\ContentService::updateContent()
1777
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1778
     */
1779
    public function testUpdateContentValidatorIgnoresRequiredFieldsOfNotUpdatedLanguages()
1780
    {
1781
        $repository = $this->getRepository();
1782
        /* BEGIN: Use Case */
1783
        $contentTypeService = $repository->getContentTypeService();
1784
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
1785
1786
        // Create multilangual content
1787
        $contentService = $repository->getContentService();
1788
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
1789
        $contentCreate->setField('name', 'An awesome Sidelfingen folder', 'eng-US');
1790
        $contentCreate->setField('name', 'An awesome Sidelfingen folder', 'eng-GB');
1791
1792
        $contentDraft = $contentService->createContent($contentCreate);
1793
1794
        // 2. Update content type definition
1795
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
1796
1797
        $fieldDefinition = $contentType->getFieldDefinition('description');
1798
        $fieldDefinitionUpdate = $contentTypeService->newFieldDefinitionUpdateStruct();
1799
        $fieldDefinitionUpdate->identifier = 'description';
1800
        $fieldDefinitionUpdate->isRequired = true;
1801
1802
        $contentTypeService->updateFieldDefinition(
1803
            $contentTypeDraft,
1804
            $fieldDefinition,
1805
            $fieldDefinitionUpdate
1806
        );
1807
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1808
1809
        // 3. Update only eng-US translation
1810
        $description = new DOMDocument();
1811
        $description->loadXML(<<<XML
1812
<?xml version="1.0" encoding="UTF-8"?>
1813
<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">
1814
    <para>Lorem ipsum dolor</para>
1815
</section>
1816
XML
1817
        );
1818
1819
        $contentUpdate = $contentService->newContentUpdateStruct();
1820
        $contentUpdate->setField('name', 'An awesome Sidelfingen folder (updated)', 'eng-US');
1821
        $contentUpdate->setField('description', $description);
1822
1823
        $contentService->updateContent($contentDraft->getVersionInfo(), $contentUpdate);
1824
        /* END: Use Case */
1825
    }
1826
1827
    /**
1828
     * Test for the updateContent() method.
1829
     *
1830
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
1831
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1832
     */
1833
    public function testUpdateContentWithNotUpdatingMandatoryField()
1834
    {
1835
        $repository = $this->getRepository();
1836
1837
        $contentService = $repository->getContentService();
1838
1839
        /* BEGIN: Use Case */
1840
        $draft = $this->createContentDraftVersion1();
1841
1842
        // Now create an update struct which does not overwrite mandatory
1843
        // fields
1844
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1845
        $contentUpdateStruct->setField(
1846
            'description',
1847
            '<?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"/>'
1848
        );
1849
1850
        // Don't set this, then the above call without languageCode will fail
1851
        $contentUpdateStruct->initialLanguageCode = 'eng-US';
1852
1853
        // This will only update the "description" field in the "eng-US"
1854
        // language
1855
        $updatedDraft = $contentService->updateContent(
1856
            $draft->getVersionInfo(),
1857
            $contentUpdateStruct
1858
        );
1859
        /* END: Use Case */
1860
1861
        foreach ($updatedDraft->getFields() as $field) {
1862
            if ($field->languageCode === 'eng-US' && $field->fieldDefIdentifier === 'name' && $field->value !== null) {
1863
                // Found field
1864
                return;
1865
            }
1866
        }
1867
        $this->fail(
1868
            'Field with identifier "name" in language "eng-US" could not be found or has empty value.'
1869
        );
1870
    }
1871
1872
    /**
1873
     * Test for the createContentDraft() method.
1874
     *
1875
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft($contentInfo, $versionInfo)
1876
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1877
     */
1878 View Code Duplication
    public function testCreateContentDraftWithSecondParameter()
1879
    {
1880
        $repository = $this->getRepository();
1881
1882
        $contentService = $repository->getContentService();
1883
1884
        /* BEGIN: Use Case */
1885
        $contentVersion2 = $this->createContentVersion2();
1886
1887
        // Now we create a new draft from the initial version
1888
        $draftedContentReloaded = $contentService->createContentDraft(
1889
            $contentVersion2->contentInfo,
1890
            $contentVersion2->getVersionInfo()
1891
        );
1892
        /* END: Use Case */
1893
1894
        $this->assertEquals(3, $draftedContentReloaded->getVersionInfo()->versionNo);
1895
    }
1896
1897
    /**
1898
     * Test for the createContentDraft() method with third parameter.
1899
     *
1900
     * @covers \eZ\Publish\Core\Repository\ContentService::createContentDraft
1901
     */
1902 View Code Duplication
    public function testCreateContentDraftWithThirdParameter()
1903
    {
1904
        $repository = $this->getRepository();
1905
1906
        $contentService = $repository->getContentService();
1907
1908
        $content = $contentService->loadContent(4);
1909
        $user = $this->createUserVersion1();
1910
1911
        $draftContent = $contentService->createContentDraft(
1912
            $content->contentInfo,
1913
            $content->getVersionInfo(),
1914
            $user
1915
        );
1916
1917
        $this->assertInstanceOf(
1918
            Content::class,
1919
            $draftContent
1920
        );
1921
    }
1922
1923
    /**
1924
     * Test for the publishVersion() method.
1925
     *
1926
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1927
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
1928
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
1929
     */
1930 View Code Duplication
    public function testPublishVersionFromContentDraft()
1931
    {
1932
        $repository = $this->getRepository();
1933
1934
        $contentService = $repository->getContentService();
1935
1936
        /* BEGIN: Use Case */
1937
        $contentVersion2 = $this->createContentVersion2();
1938
        /* END: Use Case */
1939
1940
        $versionInfo = $contentService->loadVersionInfo($contentVersion2->contentInfo);
1941
1942
        $this->assertEquals(
1943
            array(
1944
                'status' => VersionInfo::STATUS_PUBLISHED,
1945
                'versionNo' => 2,
1946
            ),
1947
            array(
1948
                'status' => $versionInfo->status,
1949
                'versionNo' => $versionInfo->versionNo,
1950
            )
1951
        );
1952
        $this->assertTrue($versionInfo->isPublished());
1953
        $this->assertFalse($versionInfo->isDraft());
1954
        $this->assertFalse($versionInfo->isArchived());
1955
    }
1956
1957
    /**
1958
     * Test for the publishVersion() method.
1959
     *
1960
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1961
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
1962
     */
1963 View Code Duplication
    public function testPublishVersionFromContentDraftArchivesOldVersion()
1964
    {
1965
        $repository = $this->getRepository();
1966
1967
        $contentService = $repository->getContentService();
1968
1969
        /* BEGIN: Use Case */
1970
        $contentVersion2 = $this->createContentVersion2();
1971
        /* END: Use Case */
1972
1973
        $versionInfo = $contentService->loadVersionInfo($contentVersion2->contentInfo, 1);
1974
1975
        $this->assertEquals(
1976
            array(
1977
                'status' => VersionInfo::STATUS_ARCHIVED,
1978
                'versionNo' => 1,
1979
            ),
1980
            array(
1981
                'status' => $versionInfo->status,
1982
                'versionNo' => $versionInfo->versionNo,
1983
            )
1984
        );
1985
        $this->assertTrue($versionInfo->isArchived());
1986
        $this->assertFalse($versionInfo->isDraft());
1987
        $this->assertFalse($versionInfo->isPublished());
1988
    }
1989
1990
    /**
1991
     * Test for the publishVersion() method.
1992
     *
1993
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
1994
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
1995
     */
1996
    public function testPublishVersionFromContentDraftUpdatesContentInfoCurrentVersion()
1997
    {
1998
        /* BEGIN: Use Case */
1999
        $contentVersion2 = $this->createContentVersion2();
2000
        /* END: Use Case */
2001
2002
        $this->assertEquals(2, $contentVersion2->contentInfo->currentVersionNo);
2003
    }
2004
2005
    /**
2006
     * Test for the publishVersion() method.
2007
     *
2008
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
2009
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2010
     */
2011 View Code Duplication
    public function testPublishVersionFromOldContentDraftArchivesNewerVersionNo()
2012
    {
2013
        $repository = $this->getRepository();
2014
2015
        $contentService = $repository->getContentService();
2016
2017
        /* BEGIN: Use Case */
2018
        $content = $this->createContentVersion1();
2019
2020
        // Create a new draft with versionNo = 2
2021
        $draftedContentVersion2 = $contentService->createContentDraft($content->contentInfo);
2022
2023
        // Create another new draft with versionNo = 3
2024
        $draftedContentVersion3 = $contentService->createContentDraft($content->contentInfo);
2025
2026
        // Publish draft with versionNo = 3
2027
        $contentService->publishVersion($draftedContentVersion3->getVersionInfo());
2028
2029
        // Publish the first draft with versionNo = 2
2030
        // currentVersionNo is now 2, versionNo 3 will be archived
2031
        $publishedDraft = $contentService->publishVersion($draftedContentVersion2->getVersionInfo());
2032
        /* END: Use Case */
2033
2034
        $this->assertEquals(2, $publishedDraft->contentInfo->currentVersionNo);
2035
    }
2036
2037
    /**
2038
     * Test for the publishVersion() method, and that it creates limited archives.
2039
     *
2040
     * @todo Adapt this when per content type archive limited is added on repository Content Type model.
2041
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
2042
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2043
     */
2044
    public function testPublishVersionNotCreatingUnlimitedArchives()
2045
    {
2046
        $repository = $this->getRepository();
2047
2048
        $contentService = $repository->getContentService();
2049
2050
        $content = $this->createContentVersion1();
2051
2052
        // load first to make sure list gets updated also (cache)
2053
        $versionInfoList = $contentService->loadVersions($content->contentInfo);
2054
        $this->assertEquals(1, count($versionInfoList));
2055
        $this->assertEquals(1, $versionInfoList[0]->versionNo);
2056
2057
        // Create a new draft with versionNo = 2
2058
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2059
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2060
2061
        // Create a new draft with versionNo = 3
2062
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2063
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2064
2065
        // Create a new draft with versionNo = 4
2066
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2067
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2068
2069
        // Create a new draft with versionNo = 5
2070
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2071
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2072
2073
        // Create a new draft with versionNo = 6
2074
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2075
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2076
2077
        // Create a new draft with versionNo = 7
2078
        $draftedContentVersion = $contentService->createContentDraft($content->contentInfo);
2079
        $contentService->publishVersion($draftedContentVersion->getVersionInfo());
2080
2081
        $versionInfoList = $contentService->loadVersions($content->contentInfo);
2082
2083
        $this->assertEquals(6, count($versionInfoList));
2084
        $this->assertEquals(2, $versionInfoList[0]->versionNo);
2085
        $this->assertEquals(7, $versionInfoList[5]->versionNo);
2086
2087
        $this->assertEquals(
2088
            [
2089
                VersionInfo::STATUS_ARCHIVED,
2090
                VersionInfo::STATUS_ARCHIVED,
2091
                VersionInfo::STATUS_ARCHIVED,
2092
                VersionInfo::STATUS_ARCHIVED,
2093
                VersionInfo::STATUS_ARCHIVED,
2094
                VersionInfo::STATUS_PUBLISHED,
2095
            ],
2096
            [
2097
                $versionInfoList[0]->status,
2098
                $versionInfoList[1]->status,
2099
                $versionInfoList[2]->status,
2100
                $versionInfoList[3]->status,
2101
                $versionInfoList[4]->status,
2102
                $versionInfoList[5]->status,
2103
            ]
2104
        );
2105
    }
2106
2107
    /**
2108
     * Test for the newContentMetadataUpdateStruct() method.
2109
     *
2110
     * @covers \eZ\Publish\API\Repository\ContentService::newContentMetadataUpdateStruct
2111
     * @group user
2112
     */
2113
    public function testNewContentMetadataUpdateStruct()
2114
    {
2115
        $repository = $this->getRepository();
2116
2117
        /* BEGIN: Use Case */
2118
        $contentService = $repository->getContentService();
2119
2120
        // Creates a new metadata update struct
2121
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
2122
2123
        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...
2124
            $this->assertNull($propertyValue, "Property '{$propertyName}' initial value should be null'");
2125
        }
2126
2127
        $metadataUpdate->remoteId = 'aaaabbbbccccddddeeeeffff11112222';
2128
        $metadataUpdate->mainLanguageCode = 'eng-GB';
2129
        $metadataUpdate->alwaysAvailable = false;
2130
        /* END: Use Case */
2131
2132
        $this->assertInstanceOf(
2133
            ContentMetadataUpdateStruct::class,
2134
            $metadataUpdate
2135
        );
2136
    }
2137
2138
    /**
2139
     * Test for the updateContentMetadata() method.
2140
     *
2141
     * @return \eZ\Publish\API\Repository\Values\Content\Content
2142
     *
2143
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2144
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
2145
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testNewContentMetadataUpdateStruct
2146
     * @group user
2147
     */
2148
    public function testUpdateContentMetadata()
2149
    {
2150
        $repository = $this->getRepository();
2151
2152
        $contentService = $repository->getContentService();
2153
2154
        /* BEGIN: Use Case */
2155
        $content = $this->createContentVersion1();
2156
2157
        // Creates a metadata update struct
2158
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
2159
2160
        $metadataUpdate->remoteId = 'aaaabbbbccccddddeeeeffff11112222';
2161
        $metadataUpdate->mainLanguageCode = 'eng-GB';
2162
        $metadataUpdate->alwaysAvailable = false;
2163
        $metadataUpdate->publishedDate = $this->createDateTime(441759600); // 1984/01/01
2164
        $metadataUpdate->modificationDate = $this->createDateTime(441759600); // 1984/01/01
2165
2166
        // Update the metadata of the published content object
2167
        $content = $contentService->updateContentMetadata(
2168
            $content->contentInfo,
2169
            $metadataUpdate
2170
        );
2171
        /* END: Use Case */
2172
2173
        $this->assertInstanceOf(
2174
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
2175
            $content
2176
        );
2177
2178
        return $content;
2179
    }
2180
2181
    /**
2182
     * Test for the updateContentMetadata() method.
2183
     *
2184
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
2185
     *
2186
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2187
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
2188
     */
2189
    public function testUpdateContentMetadataSetsExpectedProperties($content)
2190
    {
2191
        $contentInfo = $content->contentInfo;
2192
2193
        $this->assertEquals(
2194
            array(
2195
                'remoteId' => 'aaaabbbbccccddddeeeeffff11112222',
2196
                'sectionId' => $this->generateId('section', 1),
2197
                'alwaysAvailable' => false,
2198
                'currentVersionNo' => 1,
2199
                'mainLanguageCode' => 'eng-GB',
2200
                'modificationDate' => $this->createDateTime(441759600),
2201
                '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...
2202
                'published' => true,
2203
                'publishedDate' => $this->createDateTime(441759600),
2204
            ),
2205
            array(
2206
                'remoteId' => $contentInfo->remoteId,
2207
                'sectionId' => $contentInfo->sectionId,
2208
                'alwaysAvailable' => $contentInfo->alwaysAvailable,
2209
                'currentVersionNo' => $contentInfo->currentVersionNo,
2210
                'mainLanguageCode' => $contentInfo->mainLanguageCode,
2211
                'modificationDate' => $contentInfo->modificationDate,
2212
                'ownerId' => $contentInfo->ownerId,
2213
                'published' => $contentInfo->published,
2214
                'publishedDate' => $contentInfo->publishedDate,
2215
            )
2216
        );
2217
    }
2218
2219
    /**
2220
     * Test for the updateContentMetadata() method.
2221
     *
2222
     * @param \eZ\Publish\API\Repository\Values\Content\Content $content
2223
     *
2224
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2225
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
2226
     */
2227
    public function testUpdateContentMetadataNotUpdatesContentVersion($content)
2228
    {
2229
        $this->assertEquals(1, $content->getVersionInfo()->versionNo);
2230
    }
2231
2232
    /**
2233
     * Test for the updateContentMetadata() method.
2234
     *
2235
     * @covers \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
2236
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
2237
     */
2238 View Code Duplication
    public function testUpdateContentMetadataThrowsInvalidArgumentExceptionOnDuplicateRemoteId()
2239
    {
2240
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
2241
2242
        $repository = $this->getRepository();
2243
2244
        $contentService = $repository->getContentService();
2245
2246
        /* BEGIN: Use Case */
2247
        // RemoteId of the "Media" page of an eZ Publish demo installation
2248
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
2249
2250
        $content = $this->createContentVersion1();
2251
2252
        // Creates a metadata update struct
2253
        $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
2254
        $metadataUpdate->remoteId = $mediaRemoteId;
2255
2256
        // This call will fail with an "InvalidArgumentException", because the
2257
        // specified remoteId is already used by the "Media" page.
2258
        $contentService->updateContentMetadata(
2259
            $content->contentInfo,
2260
            $metadataUpdate
2261
        );
2262
        /* END: Use Case */
2263
    }
2264
2265
    /**
2266
     * Test for the updateContentMetadata() method.
2267
     *
2268
     * @covers \eZ\Publish\Core\Repository\ContentService::updateContentMetadata
2269
     */
2270
    public function testUpdateContentMetadataThrowsInvalidArgumentExceptionOnNoMetadataPropertiesSet()
2271
    {
2272
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
2273
2274
        $repository = $this->getRepository();
2275
2276
        $contentService = $repository->getContentService();
2277
2278
        $contentInfo = $contentService->loadContentInfo(4);
2279
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
2280
2281
        // Throws an exception because no properties are set in $contentMetadataUpdateStruct
2282
        $contentService->updateContentMetadata($contentInfo, $contentMetadataUpdateStruct);
2283
    }
2284
2285
    /**
2286
     * Test for the deleteContent() method.
2287
     *
2288
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
2289
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2290
     */
2291 View Code Duplication
    public function testDeleteContent()
2292
    {
2293
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
2294
2295
        $repository = $this->getRepository();
2296
2297
        $contentService = $repository->getContentService();
2298
        $locationService = $repository->getLocationService();
2299
2300
        /* BEGIN: Use Case */
2301
        $contentVersion2 = $this->createContentVersion2();
2302
2303
        // Load the locations for this content object
2304
        $locations = $locationService->loadLocations($contentVersion2->contentInfo);
2305
2306
        // This will delete the content, all versions and the associated locations
2307
        $contentService->deleteContent($contentVersion2->contentInfo);
2308
        /* END: Use Case */
2309
2310
        foreach ($locations as $location) {
2311
            $locationService->loadLocation($location->id);
2312
        }
2313
    }
2314
2315
    /**
2316
     * Test for the deleteContent() method.
2317
     *
2318
     * Test for issue EZP-21057:
2319
     * "contentService: Unable to delete a content with an empty file attribute"
2320
     *
2321
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
2322
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2323
     */
2324 View Code Duplication
    public function testDeleteContentWithEmptyBinaryField()
2325
    {
2326
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
2327
2328
        $repository = $this->getRepository();
2329
2330
        $contentService = $repository->getContentService();
2331
        $locationService = $repository->getLocationService();
2332
2333
        /* BEGIN: Use Case */
2334
        $contentVersion = $this->createContentVersion1EmptyBinaryField();
2335
2336
        // Load the locations for this content object
2337
        $locations = $locationService->loadLocations($contentVersion->contentInfo);
2338
2339
        // This will delete the content, all versions and the associated locations
2340
        $contentService->deleteContent($contentVersion->contentInfo);
2341
        /* END: Use Case */
2342
2343
        foreach ($locations as $location) {
2344
            $locationService->loadLocation($location->id);
2345
        }
2346
    }
2347
2348
    /**
2349
     * Test for the loadContentDrafts() method.
2350
     *
2351
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts()
2352
     */
2353
    public function testLoadContentDraftsReturnsEmptyArrayByDefault()
2354
    {
2355
        $repository = $this->getRepository();
2356
2357
        /* BEGIN: Use Case */
2358
        $contentService = $repository->getContentService();
2359
2360
        $contentDrafts = $contentService->loadContentDrafts();
2361
        /* END: Use Case */
2362
2363
        $this->assertSame(array(), $contentDrafts);
2364
    }
2365
2366
    /**
2367
     * Test for the loadContentDrafts() method.
2368
     *
2369
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts()
2370
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
2371
     */
2372
    public function testLoadContentDrafts()
2373
    {
2374
        $repository = $this->getRepository();
2375
2376
        /* BEGIN: Use Case */
2377
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
2378
        // of a eZ Publish demo installation.
2379
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
2380
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
2381
2382
        $contentService = $repository->getContentService();
2383
2384
        // "Media" content object
2385
        $mediaContentInfo = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
2386
2387
        // "eZ Publish Demo Design ..." content object
2388
        $demoDesignContentInfo = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
2389
2390
        // Create some drafts
2391
        $contentService->createContentDraft($mediaContentInfo);
2392
        $contentService->createContentDraft($demoDesignContentInfo);
2393
2394
        // Now $contentDrafts should contain two drafted versions
2395
        $draftedVersions = $contentService->loadContentDrafts();
2396
        /* END: Use Case */
2397
2398
        $actual = array(
2399
            $draftedVersions[0]->status,
2400
            $draftedVersions[0]->getContentInfo()->remoteId,
2401
            $draftedVersions[1]->status,
2402
            $draftedVersions[1]->getContentInfo()->remoteId,
2403
        );
2404
        sort($actual, SORT_STRING);
2405
2406
        $this->assertEquals(
2407
            array(
2408
                VersionInfo::STATUS_DRAFT,
2409
                VersionInfo::STATUS_DRAFT,
2410
                $demoDesignRemoteId,
2411
                $mediaRemoteId,
2412
            ),
2413
            $actual
2414
        );
2415
    }
2416
2417
    /**
2418
     * Test for the loadContentDrafts() method.
2419
     *
2420
     * @see \eZ\Publish\API\Repository\ContentService::loadContentDrafts($user)
2421
     */
2422
    public function testLoadContentDraftsWithFirstParameter()
2423
    {
2424
        $repository = $this->getRepository();
2425
2426
        /* BEGIN: Use Case */
2427
        $user = $this->createUserVersion1();
2428
2429
        // Get current user
2430
        $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...
2431
2432
        // Set new editor as user
2433
        $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...
2434
2435
        // Remote id of the "Media" content object in an eZ Publish demo installation.
2436
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
2437
2438
        $contentService = $repository->getContentService();
2439
2440
        // "Media" content object
2441
        $mediaContentInfo = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
2442
2443
        // Create a content draft
2444
        $contentService->createContentDraft($mediaContentInfo);
2445
2446
        // Reset to previous current user
2447
        $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...
2448
2449
        // Now $contentDrafts for the previous current user and the new user
2450
        $newCurrentUserDrafts = $contentService->loadContentDrafts($user);
2451
        $oldCurrentUserDrafts = $contentService->loadContentDrafts($oldCurrentUser);
2452
        /* END: Use Case */
2453
2454
        $this->assertSame(array(), $oldCurrentUserDrafts);
2455
2456
        $this->assertEquals(
2457
            array(
2458
                VersionInfo::STATUS_DRAFT,
2459
                $mediaRemoteId,
2460
            ),
2461
            array(
2462
                $newCurrentUserDrafts[0]->status,
2463
                $newCurrentUserDrafts[0]->getContentInfo()->remoteId,
2464
            )
2465
        );
2466
        $this->assertTrue($newCurrentUserDrafts[0]->isDraft());
2467
        $this->assertFalse($newCurrentUserDrafts[0]->isArchived());
2468
        $this->assertFalse($newCurrentUserDrafts[0]->isPublished());
2469
    }
2470
2471
    /**
2472
     * Test for the loadVersionInfo() method.
2473
     *
2474
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo($contentInfo, $versionNo)
2475
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2476
     */
2477
    public function testLoadVersionInfoWithSecondParameter()
2478
    {
2479
        $repository = $this->getRepository();
2480
2481
        $contentService = $repository->getContentService();
2482
2483
        /* BEGIN: Use Case */
2484
        $publishedContent = $this->createContentVersion1();
2485
2486
        $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...
2487
2488
        // Will return the VersionInfo of the $draftContent
2489
        $versionInfo = $contentService->loadVersionInfoById($publishedContent->id, 2);
2490
        /* END: Use Case */
2491
2492
        $this->assertEquals(2, $versionInfo->versionNo);
2493
2494
        // Check that ContentInfo contained in VersionInfo has correct main Location id set
2495
        $this->assertEquals(
2496
            $publishedContent->getVersionInfo()->getContentInfo()->mainLocationId,
2497
            $versionInfo->getContentInfo()->mainLocationId
2498
        );
2499
    }
2500
2501
    /**
2502
     * Test for the loadVersionInfo() method.
2503
     *
2504
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfo($contentInfo, $versionNo)
2505
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoWithSecondParameter
2506
     */
2507
    public function testLoadVersionInfoThrowsNotFoundExceptionWithSecondParameter()
2508
    {
2509
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
2510
2511
        $repository = $this->getRepository();
2512
2513
        $contentService = $repository->getContentService();
2514
2515
        /* BEGIN: Use Case */
2516
        $draft = $this->createContentDraftVersion1();
2517
2518
        // This call will fail with a "NotFoundException", because not versionNo
2519
        // 2 exists for this content object.
2520
        $contentService->loadVersionInfo($draft->contentInfo, 2);
2521
        /* END: Use Case */
2522
    }
2523
2524
    /**
2525
     * Test for the loadVersionInfoById() method.
2526
     *
2527
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById($contentId, $versionNo)
2528
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoWithSecondParameter
2529
     */
2530
    public function testLoadVersionInfoByIdWithSecondParameter()
2531
    {
2532
        $repository = $this->getRepository();
2533
2534
        $contentService = $repository->getContentService();
2535
2536
        /* BEGIN: Use Case */
2537
        $publishedContent = $this->createContentVersion1();
2538
2539
        $draftContent = $contentService->createContentDraft($publishedContent->contentInfo);
2540
2541
        // Will return the VersionInfo of the $draftContent
2542
        $versionInfo = $contentService->loadVersionInfoById($publishedContent->id, 2);
2543
        /* END: Use Case */
2544
2545
        $this->assertEquals(2, $versionInfo->versionNo);
2546
2547
        // Check that ContentInfo contained in VersionInfo has correct main Location id set
2548
        $this->assertEquals(
2549
            $publishedContent->getVersionInfo()->getContentInfo()->mainLocationId,
2550
            $versionInfo->getContentInfo()->mainLocationId
2551
        );
2552
2553
        return [
2554
            'versionInfo' => $versionInfo,
2555
            'draftContent' => $draftContent,
2556
        ];
2557
    }
2558
2559
    /**
2560
     * Test for the returned value of the loadVersionInfoById() method.
2561
     *
2562
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfoByIdWithSecondParameter
2563
     * @covers \eZ\Publish\API\Repository\ContentService::loadVersionInfoById
2564
     *
2565
     * @param array $data
2566
     */
2567
    public function testLoadVersionInfoByIdWithSecondParameterSetsExpectedVersionInfo(array $data)
2568
    {
2569
        /** @var \eZ\Publish\API\Repository\Values\Content\VersionInfo $versionInfo */
2570
        $versionInfo = $data['versionInfo'];
2571
        /** @var \eZ\Publish\API\Repository\Values\Content\Content $draftContent */
2572
        $draftContent = $data['draftContent'];
2573
2574
        $this->assertPropertiesCorrect(
2575
            [
2576
                'names' => [
2577
                    'eng-US' => 'An awesome forum',
2578
                ],
2579
                'contentInfo' => new ContentInfo([
2580
                    'id' => $draftContent->contentInfo->id,
2581
                    'contentTypeId' => 28,
2582
                    'name' => 'An awesome forum',
2583
                    'sectionId' => 1,
2584
                    'currentVersionNo' => 1,
2585
                    'published' => true,
2586
                    'ownerId' => 14,
2587
                    // this Content Object is created at the test runtime
2588
                    'modificationDate' => $versionInfo->contentInfo->modificationDate,
2589
                    'publishedDate' => $versionInfo->contentInfo->publishedDate,
2590
                    'alwaysAvailable' => 1,
2591
                    'remoteId' => 'abcdef0123456789abcdef0123456789',
2592
                    'mainLanguageCode' => 'eng-US',
2593
                    'mainLocationId' => $draftContent->contentInfo->mainLocationId,
2594
                    'status' => ContentInfo::STATUS_PUBLISHED,
2595
                ]),
2596
                'id' => $draftContent->versionInfo->id,
2597
                'versionNo' => 2,
2598
                'creatorId' => 14,
2599
                'status' => 0,
2600
                'initialLanguageCode' => 'eng-US',
2601
                'languageCodes' => [
2602
                    'eng-US',
2603
                ],
2604
            ],
2605
            $versionInfo
2606
        );
2607
    }
2608
2609
    /**
2610
     * Test for the loadVersionInfoById() method.
2611
     *
2612
     * @see \eZ\Publish\API\Repository\ContentService::loadVersionInfoById($contentId, $versionNo)
2613
     */
2614
    public function testLoadVersionInfoByIdThrowsNotFoundExceptionWithSecondParameter()
2615
    {
2616
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
2617
2618
        $repository = $this->getRepository();
2619
2620
        $contentService = $repository->getContentService();
2621
2622
        /* BEGIN: Use Case */
2623
        $content = $this->createContentVersion1();
2624
2625
        // This call will fail with a "NotFoundException", because not versionNo
2626
        // 2 exists for this content object.
2627
        $contentService->loadVersionInfoById($content->id, 2);
2628
        /* END: Use Case */
2629
    }
2630
2631
    /**
2632
     * Test for the loadContentByVersionInfo() method.
2633
     *
2634
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByVersionInfo($versionInfo, $languages)
2635
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
2636
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByVersionInfo
2637
     */
2638
    public function testLoadContentByVersionInfoWithSecondParameter()
2639
    {
2640
        $repository = $this->getRepository();
2641
2642
        $sectionId = $this->generateId('section', 1);
2643
        /* BEGIN: Use Case */
2644
        $contentTypeService = $repository->getContentTypeService();
2645
2646
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
2647
2648
        $contentService = $repository->getContentService();
2649
2650
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
2651
2652
        $contentCreateStruct->setField('name', 'Sindelfingen forum²');
2653
2654
        $contentCreateStruct->setField('name', 'Sindelfingen forum²³', 'eng-GB');
2655
2656
        $contentCreateStruct->remoteId = 'abcdef0123456789abcdef0123456789';
2657
        // $sectionId contains the ID of section 1
2658
        $contentCreateStruct->sectionId = $sectionId;
2659
        $contentCreateStruct->alwaysAvailable = true;
2660
2661
        // Create a new content draft
2662
        $content = $contentService->createContent($contentCreateStruct);
2663
2664
        // Now publish this draft
2665
        $publishedContent = $contentService->publishVersion($content->getVersionInfo());
2666
2667
        // Will return a content instance with fields in "eng-US"
2668
        $reloadedContent = $contentService->loadContentByVersionInfo(
2669
            $publishedContent->getVersionInfo(),
2670
            array(
2671
                'eng-GB',
2672
            ),
2673
            false
2674
        );
2675
        /* END: Use Case */
2676
2677
        $actual = array();
2678 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...
2679
            $actual[] = new Field(
2680
                array(
2681
                    'id' => 0,
2682
                    'value' => ($field->value !== null ? true : null), // Actual value tested by FieldType integration tests
2683
                    'languageCode' => $field->languageCode,
2684
                    'fieldDefIdentifier' => $field->fieldDefIdentifier,
2685
                )
2686
            );
2687
        }
2688
        usort(
2689
            $actual,
2690 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...
2691
                if (0 === ($return = strcasecmp($field1->fieldDefIdentifier, $field2->fieldDefIdentifier))) {
2692
                    return strcasecmp($field1->languageCode, $field2->languageCode);
2693
                }
2694
2695
                return $return;
2696
            }
2697
        );
2698
2699
        $expected = array(
2700
            new Field(
2701
                array(
2702
                    'id' => 0,
2703
                    'value' => true,
2704
                    'languageCode' => 'eng-GB',
2705
                    'fieldDefIdentifier' => 'description',
2706
                )
2707
            ),
2708
            new Field(
2709
                array(
2710
                    'id' => 0,
2711
                    'value' => true,
2712
                    'languageCode' => 'eng-GB',
2713
                    'fieldDefIdentifier' => 'name',
2714
                )
2715
            ),
2716
        );
2717
2718
        $this->assertEquals($expected, $actual);
2719
    }
2720
2721
    /**
2722
     * Test for the loadContentByContentInfo() method.
2723
     *
2724
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages)
2725
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfo
2726
     */
2727
    public function testLoadContentByContentInfoWithLanguageParameters()
2728
    {
2729
        $repository = $this->getRepository();
2730
2731
        $sectionId = $this->generateId('section', 1);
2732
        /* BEGIN: Use Case */
2733
        $contentTypeService = $repository->getContentTypeService();
2734
2735
        $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
2736
2737
        $contentService = $repository->getContentService();
2738
2739
        $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-US');
2740
2741
        $contentCreateStruct->setField('name', 'Sindelfingen forum²');
2742
2743
        $contentCreateStruct->setField('name', 'Sindelfingen forum²³', 'eng-GB');
2744
2745
        $contentCreateStruct->remoteId = 'abcdef0123456789abcdef0123456789';
2746
        // $sectionId contains the ID of section 1
2747
        $contentCreateStruct->sectionId = $sectionId;
2748
        $contentCreateStruct->alwaysAvailable = true;
2749
2750
        // Create a new content draft
2751
        $content = $contentService->createContent($contentCreateStruct);
2752
2753
        // Now publish this draft
2754
        $publishedContent = $contentService->publishVersion($content->getVersionInfo());
2755
2756
        // Will return a content instance with fields in "eng-US"
2757
        $reloadedContent = $contentService->loadContentByContentInfo(
2758
            $publishedContent->contentInfo,
2759
            array(
2760
                'eng-US',
2761
            ),
2762
            null,
2763
            false
2764
        );
2765
        /* END: Use Case */
2766
2767
        $actual = $this->normalizeFields($reloadedContent->getFields());
2768
2769
        $expected = array(
2770
            new Field(
2771
                array(
2772
                    'id' => 0,
2773
                    'value' => true,
2774
                    'languageCode' => 'eng-US',
2775
                    'fieldDefIdentifier' => 'description',
2776
                    'fieldTypeIdentifier' => 'ezrichtext',
2777
                )
2778
            ),
2779
            new Field(
2780
                array(
2781
                    'id' => 0,
2782
                    'value' => true,
2783
                    'languageCode' => 'eng-US',
2784
                    'fieldDefIdentifier' => 'name',
2785
                    'fieldTypeIdentifier' => 'ezstring',
2786
                )
2787
            ),
2788
        );
2789
2790
        $this->assertEquals($expected, $actual);
2791
2792
        // Will return a content instance with fields in "eng-GB" (versions prior to 6.0.0-beta9 returned "eng-US" also)
2793
        $reloadedContent = $contentService->loadContentByContentInfo(
2794
            $publishedContent->contentInfo,
2795
            array(
2796
                'eng-GB',
2797
            ),
2798
            null,
2799
            true
2800
        );
2801
2802
        $actual = $this->normalizeFields($reloadedContent->getFields());
2803
2804
        $expected = array(
2805
            new Field(
2806
                array(
2807
                    'id' => 0,
2808
                    'value' => true,
2809
                    'languageCode' => 'eng-GB',
2810
                    'fieldDefIdentifier' => 'description',
2811
                    'fieldTypeIdentifier' => 'ezrichtext',
2812
                )
2813
            ),
2814
            new Field(
2815
                array(
2816
                    'id' => 0,
2817
                    'value' => true,
2818
                    'languageCode' => 'eng-GB',
2819
                    'fieldDefIdentifier' => 'name',
2820
                    'fieldTypeIdentifier' => 'ezstring',
2821
                )
2822
            ),
2823
        );
2824
2825
        $this->assertEquals($expected, $actual);
2826
2827
        // Will return a content instance with fields in main language "eng-US", as "fre-FR" does not exists
2828
        $reloadedContent = $contentService->loadContentByContentInfo(
2829
            $publishedContent->contentInfo,
2830
            array(
2831
                'fre-FR',
2832
            ),
2833
            null,
2834
            true
2835
        );
2836
2837
        $actual = $this->normalizeFields($reloadedContent->getFields());
2838
2839
        $expected = array(
2840
            new Field(
2841
                array(
2842
                    'id' => 0,
2843
                    'value' => true,
2844
                    'languageCode' => 'eng-US',
2845
                    'fieldDefIdentifier' => 'description',
2846
                    'fieldTypeIdentifier' => 'ezrichtext',
2847
                )
2848
            ),
2849
            new Field(
2850
                array(
2851
                    'id' => 0,
2852
                    'value' => true,
2853
                    'languageCode' => 'eng-US',
2854
                    'fieldDefIdentifier' => 'name',
2855
                    'fieldTypeIdentifier' => 'ezstring',
2856
                )
2857
            ),
2858
        );
2859
2860
        $this->assertEquals($expected, $actual);
2861
    }
2862
2863
    /**
2864
     * Test for the loadContentByContentInfo() method.
2865
     *
2866
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages, $versionNo)
2867
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfo
2868
     */
2869 View Code Duplication
    public function testLoadContentByContentInfoWithVersionNumberParameter()
2870
    {
2871
        $repository = $this->getRepository();
2872
2873
        $contentService = $repository->getContentService();
2874
2875
        /* BEGIN: Use Case */
2876
        $publishedContent = $this->createContentVersion1();
2877
2878
        $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...
2879
2880
        // This content instance is identical to $draftContent
2881
        $draftContentReloaded = $contentService->loadContentByContentInfo(
2882
            $publishedContent->contentInfo,
2883
            null,
2884
            2
2885
        );
2886
        /* END: Use Case */
2887
2888
        $this->assertEquals(
2889
            2,
2890
            $draftContentReloaded->getVersionInfo()->versionNo
2891
        );
2892
2893
        // Check that ContentInfo contained in reloaded draft Content has correct main Location id set
2894
        $this->assertEquals(
2895
            $publishedContent->versionInfo->contentInfo->mainLocationId,
2896
            $draftContentReloaded->versionInfo->contentInfo->mainLocationId
2897
        );
2898
    }
2899
2900
    /**
2901
     * Test for the loadContentByContentInfo() method.
2902
     *
2903
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByContentInfo($contentInfo, $languages, $versionNo)
2904
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByContentInfoWithVersionNumberParameter
2905
     */
2906 View Code Duplication
    public function testLoadContentByContentInfoThrowsNotFoundExceptionWithVersionNumberParameter()
2907
    {
2908
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
2909
2910
        $repository = $this->getRepository();
2911
2912
        $contentService = $repository->getContentService();
2913
2914
        /* BEGIN: Use Case */
2915
        $content = $this->createContentVersion1();
2916
2917
        // This call will fail with a "NotFoundException", because no content
2918
        // with versionNo = 2 exists.
2919
        $contentService->loadContentByContentInfo($content->contentInfo, null, 2);
2920
        /* END: Use Case */
2921
    }
2922
2923
    /**
2924
     * Test for the loadContent() method.
2925
     *
2926
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages)
2927
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2928
     */
2929 View Code Duplication
    public function testLoadContentWithSecondParameter()
2930
    {
2931
        $repository = $this->getRepository();
2932
2933
        $contentService = $repository->getContentService();
2934
2935
        /* BEGIN: Use Case */
2936
        $draft = $this->createMultipleLanguageDraftVersion1();
2937
2938
        // This draft contains those fields localized with "eng-GB"
2939
        $draftLocalized = $contentService->loadContent($draft->id, array('eng-GB'), null, false);
2940
        /* END: Use Case */
2941
2942
        $this->assertLocaleFieldsEquals($draftLocalized->getFields(), 'eng-GB');
2943
2944
        return $draft;
2945
    }
2946
2947
    /**
2948
     * Test for the loadContent() method using undefined translation.
2949
     *
2950
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentWithSecondParameter
2951
     *
2952
     * @param \eZ\Publish\API\Repository\Values\Content\Content $contentDraft
2953
     */
2954
    public function testLoadContentWithSecondParameterThrowsNotFoundException(Content $contentDraft)
2955
    {
2956
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
2957
2958
        $repository = $this->getRepository();
2959
2960
        $contentService = $repository->getContentService();
2961
2962
        $contentService->loadContent($contentDraft->id, array('ger-DE'), null, false);
2963
    }
2964
2965
    /**
2966
     * Test for the loadContent() method.
2967
     *
2968
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages, $versionNo)
2969
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
2970
     */
2971 View Code Duplication
    public function testLoadContentWithThirdParameter()
2972
    {
2973
        $repository = $this->getRepository();
2974
2975
        $contentService = $repository->getContentService();
2976
2977
        /* BEGIN: Use Case */
2978
        $publishedContent = $this->createContentVersion1();
2979
2980
        $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...
2981
2982
        // This content instance is identical to $draftContent
2983
        $draftContentReloaded = $contentService->loadContent($publishedContent->id, null, 2);
2984
        /* END: Use Case */
2985
2986
        $this->assertEquals(2, $draftContentReloaded->getVersionInfo()->versionNo);
2987
2988
        // Check that ContentInfo contained in reloaded draft Content has correct main Location id set
2989
        $this->assertEquals(
2990
            $publishedContent->versionInfo->contentInfo->mainLocationId,
2991
            $draftContentReloaded->versionInfo->contentInfo->mainLocationId
2992
        );
2993
    }
2994
2995
    /**
2996
     * Test for the loadContent() method.
2997
     *
2998
     * @see \eZ\Publish\API\Repository\ContentService::loadContent($contentId, $languages, $versionNo)
2999
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentWithThirdParameter
3000
     */
3001
    public function testLoadContentThrowsNotFoundExceptionWithThirdParameter()
3002
    {
3003
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
3004
3005
        $repository = $this->getRepository();
3006
3007
        $contentService = $repository->getContentService();
3008
3009
        /* BEGIN: Use Case */
3010
        $content = $this->createContentVersion1();
3011
3012
        // This call will fail with a "NotFoundException", because for this
3013
        // content object no versionNo=2 exists.
3014
        $contentService->loadContent($content->id, null, 2);
3015
        /* END: Use Case */
3016
    }
3017
3018
    /**
3019
     * Test for the loadContentByRemoteId() method.
3020
     *
3021
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages)
3022
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3023
     */
3024 View Code Duplication
    public function testLoadContentByRemoteIdWithSecondParameter()
3025
    {
3026
        $repository = $this->getRepository();
3027
3028
        $contentService = $repository->getContentService();
3029
3030
        /* BEGIN: Use Case */
3031
        $draft = $this->createMultipleLanguageDraftVersion1();
3032
3033
        $contentService->publishVersion($draft->versionInfo);
3034
3035
        // This draft contains those fields localized with "eng-GB"
3036
        $draftLocalized = $contentService->loadContentByRemoteId(
3037
            $draft->contentInfo->remoteId,
3038
            array('eng-GB'),
3039
            null,
3040
            false
3041
        );
3042
        /* END: Use Case */
3043
3044
        $this->assertLocaleFieldsEquals($draftLocalized->getFields(), 'eng-GB');
3045
    }
3046
3047
    /**
3048
     * Test for the loadContentByRemoteId() method.
3049
     *
3050
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages, $versionNo)
3051
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3052
     */
3053 View Code Duplication
    public function testLoadContentByRemoteIdWithThirdParameter()
3054
    {
3055
        $repository = $this->getRepository();
3056
3057
        $contentService = $repository->getContentService();
3058
3059
        /* BEGIN: Use Case */
3060
        $publishedContent = $this->createContentVersion1();
3061
3062
        $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...
3063
3064
        // This content instance is identical to $draftContent
3065
        $draftContentReloaded = $contentService->loadContentByRemoteId(
3066
            $publishedContent->contentInfo->remoteId,
3067
            null,
3068
            2
3069
        );
3070
        /* END: Use Case */
3071
3072
        $this->assertEquals(2, $draftContentReloaded->getVersionInfo()->versionNo);
3073
3074
        // Check that ContentInfo contained in reloaded draft Content has correct main Location id set
3075
        $this->assertEquals(
3076
            $publishedContent->versionInfo->contentInfo->mainLocationId,
3077
            $draftContentReloaded->versionInfo->contentInfo->mainLocationId
3078
        );
3079
    }
3080
3081
    /**
3082
     * Test for the loadContentByRemoteId() method.
3083
     *
3084
     * @see \eZ\Publish\API\Repository\ContentService::loadContentByRemoteId($remoteId, $languages, $versionNo)
3085
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentByRemoteIdWithThirdParameter
3086
     */
3087
    public function testLoadContentByRemoteIdThrowsNotFoundExceptionWithThirdParameter()
3088
    {
3089
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
3090
3091
        $repository = $this->getRepository();
3092
3093
        $contentService = $repository->getContentService();
3094
3095
        /* BEGIN: Use Case */
3096
        $content = $this->createContentVersion1();
3097
3098
        // This call will fail with a "NotFoundException", because for this
3099
        // content object no versionNo=2 exists.
3100
        $contentService->loadContentByRemoteId(
3101
            $content->contentInfo->remoteId,
3102
            null,
3103
            2
3104
        );
3105
        /* END: Use Case */
3106
    }
3107
3108
    /**
3109
     * Test that retrieval of translated name field respects prioritized language list.
3110
     *
3111
     * @dataProvider getPrioritizedLanguageList
3112
     * @param string[]|null $languageCodes
3113
     */
3114
    public function testLoadContentWithPrioritizedLanguagesList($languageCodes)
3115
    {
3116
        $repository = $this->getRepository();
3117
3118
        $contentService = $repository->getContentService();
3119
3120
        $content = $this->createContentVersion2();
3121
3122
        $content = $contentService->loadContent($content->id, $languageCodes);
3123
3124
        $expectedName = $content->getVersionInfo()->getName(
3125
            isset($languageCodes[0]) ? $languageCodes[0] : null
3126
        );
3127
        $nameValue = $content->getFieldValue('name');
3128
        /** @var \eZ\Publish\Core\FieldType\TextLine\Value $nameValue */
3129
        self::assertEquals($expectedName, $nameValue->text);
3130
        self::assertEquals($expectedName, $content->getVersionInfo()->getName());
3131
        // Also check value on shortcut method on content
3132
        self::assertEquals($expectedName, $content->getName());
3133
    }
3134
3135
    /**
3136
     * @return array
3137
     */
3138
    public function getPrioritizedLanguageList()
3139
    {
3140
        return [
3141
            [['eng-US']],
3142
            [['eng-GB']],
3143
            [['eng-GB', 'eng-US']],
3144
            [['eng-US', 'eng-GB']],
3145
        ];
3146
    }
3147
3148
    /**
3149
     * Test for the deleteVersion() method.
3150
     *
3151
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
3152
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
3153
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
3154
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3155
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
3156
     */
3157
    public function testDeleteVersion()
3158
    {
3159
        $repository = $this->getRepository();
3160
3161
        $contentService = $repository->getContentService();
3162
3163
        /* BEGIN: Use Case */
3164
        $content = $this->createContentVersion1();
3165
3166
        // Create new draft, because published or last version of the Content can't be deleted
3167
        $draft = $contentService->createContentDraft(
3168
            $content->getVersionInfo()->getContentInfo()
3169
        );
3170
3171
        // Delete the previously created draft
3172
        $contentService->deleteVersion($draft->getVersionInfo());
3173
        /* END: Use Case */
3174
3175
        $versions = $contentService->loadVersions($content->getVersionInfo()->getContentInfo());
3176
3177
        $this->assertCount(1, $versions);
3178
        $this->assertEquals(
3179
            $content->getVersionInfo()->id,
3180
            $versions[0]->id
3181
        );
3182
    }
3183
3184
    /**
3185
     * Test for the deleteVersion() method.
3186
     *
3187
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
3188
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
3189
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
3190
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3191
     */
3192
    public function testDeleteVersionThrowsBadStateExceptionOnPublishedVersion()
3193
    {
3194
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
3195
3196
        $repository = $this->getRepository();
3197
3198
        $contentService = $repository->getContentService();
3199
3200
        /* BEGIN: Use Case */
3201
        $content = $this->createContentVersion1();
3202
3203
        // This call will fail with a "BadStateException", because the content
3204
        // version is currently published.
3205
        $contentService->deleteVersion($content->getVersionInfo());
3206
        /* END: Use Case */
3207
    }
3208
3209
    /**
3210
     * Test for the deleteVersion() method.
3211
     *
3212
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
3213
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
3214
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
3215
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3216
     */
3217
    public function testDeleteVersionWorksIfOnlyVersionIsDraft()
3218
    {
3219
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\NotFoundException::class);
3220
3221
        $repository = $this->getRepository();
3222
3223
        $contentService = $repository->getContentService();
3224
3225
        /* BEGIN: Use Case */
3226
        $draft = $this->createContentDraftVersion1();
3227
3228
        $contentService->deleteVersion($draft->getVersionInfo());
3229
3230
        // This call will fail with a "NotFound", because we allow to delete content if remaining version is draft.
3231
        // Can normally only happen if there where always only a draft to begin with, simplifies UI edit API usage.
3232
        $contentService->loadContent($draft->id);
3233
        /* END: Use Case */
3234
    }
3235
3236
    /**
3237
     * Test for the loadVersions() method.
3238
     *
3239
     * @see \eZ\Publish\API\Repository\ContentService::loadVersions()
3240
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
3241
     *
3242
     * @return \eZ\Publish\API\Repository\Values\Content\VersionInfo[]
3243
     */
3244
    public function testLoadVersions()
3245
    {
3246
        $repository = $this->getRepository();
3247
3248
        $contentService = $repository->getContentService();
3249
3250
        /* BEGIN: Use Case */
3251
        $contentVersion2 = $this->createContentVersion2();
3252
3253
        // Load versions of this ContentInfo instance
3254
        $versions = $contentService->loadVersions($contentVersion2->contentInfo);
3255
        /* END: Use Case */
3256
3257
        $expectedVersionsOrder = [
3258
            $contentService->loadVersionInfo($contentVersion2->contentInfo, 1),
3259
            $contentService->loadVersionInfo($contentVersion2->contentInfo, 2),
3260
        ];
3261
3262
        $this->assertEquals($expectedVersionsOrder, $versions);
3263
3264
        return $versions;
3265
    }
3266
3267
    /**
3268
     * Test for the loadVersions() method.
3269
     *
3270
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersions
3271
     * @covers \eZ\Publish\Core\Repository\ContentService::loadVersions
3272
     *
3273
     * @param \eZ\Publish\API\Repository\Values\Content\VersionInfo[] $versions
3274
     */
3275
    public function testLoadVersionsSetsExpectedVersionInfo(array $versions)
3276
    {
3277
        $this->assertCount(2, $versions);
3278
3279
        $expectedVersions = [
3280
            [
3281
                'versionNo' => 1,
3282
                'creatorId' => 14,
3283
                'status' => VersionInfo::STATUS_ARCHIVED,
3284
                'initialLanguageCode' => 'eng-US',
3285
                'languageCodes' => ['eng-US'],
3286
            ],
3287
            [
3288
                'versionNo' => 2,
3289
                'creatorId' => 10,
3290
                'status' => VersionInfo::STATUS_PUBLISHED,
3291
                'initialLanguageCode' => 'eng-US',
3292
                'languageCodes' => ['eng-US', 'eng-GB'],
3293
            ],
3294
        ];
3295
3296
        $this->assertPropertiesCorrect($expectedVersions[0], $versions[0]);
3297
        $this->assertPropertiesCorrect($expectedVersions[1], $versions[1]);
3298
        $this->assertEquals(
3299
            $versions[0]->creationDate->getTimestamp(),
3300
            $versions[1]->creationDate->getTimestamp(),
3301
            'Creation time did not match within delta of 2 seconds',
3302
            2
3303
        );
3304
        $this->assertEquals(
3305
            $versions[0]->modificationDate->getTimestamp(),
3306
            $versions[1]->modificationDate->getTimestamp(),
3307
            'Creation time did not match within delta of 2 seconds',
3308
            2
3309
        );
3310
        $this->assertTrue($versions[0]->isArchived());
3311
        $this->assertFalse($versions[0]->isDraft());
3312
        $this->assertFalse($versions[0]->isPublished());
3313
3314
        $this->assertTrue($versions[1]->isPublished());
3315
        $this->assertFalse($versions[1]->isDraft());
3316
        $this->assertFalse($versions[1]->isArchived());
3317
    }
3318
3319
    /**
3320
     * Test for the copyContent() method.
3321
     *
3322
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
3323
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3324
     * @group field-type
3325
     */
3326 View Code Duplication
    public function testCopyContent()
3327
    {
3328
        $parentLocationId = $this->generateId('location', 56);
3329
3330
        $repository = $this->getRepository();
3331
3332
        $contentService = $repository->getContentService();
3333
        $locationService = $repository->getLocationService();
3334
3335
        /* BEGIN: Use Case */
3336
        $contentVersion2 = $this->createMultipleLanguageContentVersion2();
3337
3338
        // Configure new target location
3339
        $targetLocationCreate = $locationService->newLocationCreateStruct($parentLocationId);
3340
3341
        $targetLocationCreate->priority = 42;
3342
        $targetLocationCreate->hidden = true;
3343
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
3344
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
3345
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
3346
3347
        // Copy content with all versions and drafts
3348
        $contentCopied = $contentService->copyContent(
3349
            $contentVersion2->contentInfo,
3350
            $targetLocationCreate
3351
        );
3352
        /* END: Use Case */
3353
3354
        $this->assertInstanceOf(
3355
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
3356
            $contentCopied
3357
        );
3358
3359
        $this->assertNotEquals(
3360
            $contentVersion2->contentInfo->remoteId,
3361
            $contentCopied->contentInfo->remoteId
3362
        );
3363
3364
        $this->assertNotEquals(
3365
            $contentVersion2->id,
3366
            $contentCopied->id
3367
        );
3368
3369
        $this->assertEquals(
3370
            2,
3371
            count($contentService->loadVersions($contentCopied->contentInfo))
3372
        );
3373
3374
        $this->assertEquals(2, $contentCopied->getVersionInfo()->versionNo);
3375
3376
        $this->assertAllFieldsEquals($contentCopied->getFields());
3377
3378
        $this->assertDefaultContentStates($contentCopied->contentInfo);
3379
3380
        $this->assertNotNull(
3381
            $contentCopied->contentInfo->mainLocationId,
3382
            'Expected main location to be set given we provided a LocationCreateStruct'
3383
        );
3384
    }
3385
3386
    /**
3387
     * Test for the copyContent() method with ezsettings.default.content.retain_owner_on_copy set to false
3388
     * See settings/test/integration_legacy.yml for service override.
3389
     *
3390
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
3391
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3392
     * @group field-type
3393
     */
3394
    public function testCopyContentWithNewOwner()
3395
    {
3396
        $parentLocationId = $this->generateId('location', 56);
3397
3398
        $repository = $this->getRepository();
3399
3400
        $contentService = $repository->getContentService();
3401
        $locationService = $repository->getLocationService();
3402
        $userService = $repository->getUserService();
3403
3404
        $newOwner = $this->createUser('new_owner', 'foo', 'bar');
3405
        /* BEGIN: Use Case */
3406
        /** @var \eZ\Publish\API\Repository\Values\Content\Content $contentVersion2 */
3407
        $contentVersion2 = $this->createContentDraftVersion1(
3408
            $parentLocationId,
3409
            'forum',
3410
            'name',
3411
            $newOwner
3412
        );
3413
3414
        // Configure new target location
3415
        $targetLocationCreate = $locationService->newLocationCreateStruct($parentLocationId);
3416
3417
        $targetLocationCreate->priority = 42;
3418
        $targetLocationCreate->hidden = true;
3419
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
3420
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
3421
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
3422
3423
        // Copy content with all versions and drafts
3424
        $contentCopied = $contentService->copyContent(
3425
            $contentVersion2->contentInfo,
3426
            $targetLocationCreate
3427
        );
3428
        /* END: Use Case */
3429
3430
        $this->assertEquals(
3431
            $newOwner->id,
3432
            $contentVersion2->contentInfo->ownerId
3433
        );
3434
        $this->assertEquals(
3435
            $userService->loadUserByLogin('admin')->getUserId(),
3436
            $contentCopied->contentInfo->ownerId
3437
        );
3438
    }
3439
3440
    /**
3441
     * Test for the copyContent() method.
3442
     *
3443
     * @see \eZ\Publish\API\Repository\ContentService::copyContent($contentInfo, $destinationLocationCreateStruct, $versionInfo)
3444
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContent
3445
     *
3446
     * @todo Fix to more descriptive name
3447
     */
3448 View Code Duplication
    public function testCopyContentWithThirdParameter()
3449
    {
3450
        $parentLocationId = $this->generateId('location', 56);
3451
3452
        $repository = $this->getRepository();
3453
3454
        $contentService = $repository->getContentService();
3455
        $locationService = $repository->getLocationService();
3456
3457
        /* BEGIN: Use Case */
3458
        $contentVersion2 = $this->createContentVersion2();
3459
3460
        // Configure new target location
3461
        $targetLocationCreate = $locationService->newLocationCreateStruct($parentLocationId);
3462
3463
        $targetLocationCreate->priority = 42;
3464
        $targetLocationCreate->hidden = true;
3465
        $targetLocationCreate->remoteId = '01234abcdef5678901234abcdef56789';
3466
        $targetLocationCreate->sortField = Location::SORT_FIELD_NODE_ID;
3467
        $targetLocationCreate->sortOrder = Location::SORT_ORDER_DESC;
3468
3469
        // Copy only the initial version
3470
        $contentCopied = $contentService->copyContent(
3471
            $contentVersion2->contentInfo,
3472
            $targetLocationCreate,
3473
            $contentService->loadVersionInfo($contentVersion2->contentInfo, 1)
3474
        );
3475
        /* END: Use Case */
3476
3477
        $this->assertInstanceOf(
3478
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Content',
3479
            $contentCopied
3480
        );
3481
3482
        $this->assertNotEquals(
3483
            $contentVersion2->contentInfo->remoteId,
3484
            $contentCopied->contentInfo->remoteId
3485
        );
3486
3487
        $this->assertNotEquals(
3488
            $contentVersion2->id,
3489
            $contentCopied->id
3490
        );
3491
3492
        $this->assertEquals(
3493
            1,
3494
            count($contentService->loadVersions($contentCopied->contentInfo))
3495
        );
3496
3497
        $this->assertEquals(1, $contentCopied->getVersionInfo()->versionNo);
3498
3499
        $this->assertNotNull(
3500
            $contentCopied->contentInfo->mainLocationId,
3501
            'Expected main location to be set given we provided a LocationCreateStruct'
3502
        );
3503
    }
3504
3505
    /**
3506
     * Test for the addRelation() method.
3507
     *
3508
     * @return \eZ\Publish\API\Repository\Values\Content\Content
3509
     *
3510
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3511
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersionFromContentDraft
3512
     */
3513
    public function testAddRelation()
3514
    {
3515
        $repository = $this->getRepository();
3516
3517
        $contentService = $repository->getContentService();
3518
3519
        /* BEGIN: Use Case */
3520
        // RemoteId of the "Media" content of an eZ Publish demo installation
3521
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3522
3523
        $draft = $this->createContentDraftVersion1();
3524
3525
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3526
3527
        // Create relation between new content object and "Media" page
3528
        $relation = $contentService->addRelation(
3529
            $draft->getVersionInfo(),
3530
            $media
3531
        );
3532
        /* END: Use Case */
3533
3534
        $this->assertInstanceOf(
3535
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Relation',
3536
            $relation
3537
        );
3538
3539
        return $contentService->loadRelations($draft->getVersionInfo());
3540
    }
3541
3542
    /**
3543
     * Test for the addRelation() method.
3544
     *
3545
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3546
     *
3547
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3548
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3549
     */
3550
    public function testAddRelationAddsRelationToContent($relations)
3551
    {
3552
        $this->assertEquals(
3553
            1,
3554
            count($relations)
3555
        );
3556
    }
3557
3558
    /**
3559
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3560
     */
3561
    protected function assertExpectedRelations($relations)
3562
    {
3563
        $this->assertEquals(
3564
            array(
3565
                'type' => Relation::COMMON,
3566
                'sourceFieldDefinitionIdentifier' => null,
3567
                'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3568
                'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3569
            ),
3570
            array(
3571
                'type' => $relations[0]->type,
3572
                'sourceFieldDefinitionIdentifier' => $relations[0]->sourceFieldDefinitionIdentifier,
3573
                'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3574
                'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3575
            )
3576
        );
3577
    }
3578
3579
    /**
3580
     * Test for the addRelation() method.
3581
     *
3582
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3583
     *
3584
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3585
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3586
     */
3587
    public function testAddRelationSetsExpectedRelations($relations)
3588
    {
3589
        $this->assertExpectedRelations($relations);
3590
    }
3591
3592
    /**
3593
     * Test for the createContentDraft() method.
3594
     *
3595
     * @return \eZ\Publish\API\Repository\Values\Content\Relation[]
3596
     *
3597
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
3598
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelationSetsExpectedRelations
3599
     */
3600
    public function testCreateContentDraftWithRelations()
3601
    {
3602
        $repository = $this->getRepository();
3603
3604
        $contentService = $repository->getContentService();
3605
3606
        // RemoteId of the "Media" content of an eZ Publish demo installation
3607
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3608
        $draft = $this->createContentDraftVersion1();
3609
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3610
3611
        // Create relation between new content object and "Media" page
3612
        $contentService->addRelation(
3613
            $draft->getVersionInfo(),
3614
            $media
3615
        );
3616
3617
        $content = $contentService->publishVersion($draft->versionInfo);
3618
        $newDraft = $contentService->createContentDraft($content->contentInfo);
3619
3620
        return $contentService->loadRelations($newDraft->getVersionInfo());
3621
    }
3622
3623
    /**
3624
     * Test for the createContentDraft() method.
3625
     *
3626
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3627
     *
3628
     * @return \eZ\Publish\API\Repository\Values\Content\Relation[]
3629
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraftWithRelations
3630
     */
3631
    public function testCreateContentDraftWithRelationsCreatesRelations($relations)
3632
    {
3633
        $this->assertEquals(
3634
            1,
3635
            count($relations)
3636
        );
3637
3638
        return $relations;
3639
    }
3640
3641
    /**
3642
     * Test for the createContentDraft() method.
3643
     *
3644
     * @param \eZ\Publish\API\Repository\Values\Content\Relation[] $relations
3645
     *
3646
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraftWithRelationsCreatesRelations
3647
     */
3648
    public function testCreateContentDraftWithRelationsCreatesExpectedRelations($relations)
3649
    {
3650
        $this->assertExpectedRelations($relations);
3651
    }
3652
3653
    /**
3654
     * Test for the addRelation() method.
3655
     *
3656
     * @see \eZ\Publish\API\Repository\ContentService::addRelation()
3657
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3658
     */
3659
    public function testAddRelationThrowsBadStateException()
3660
    {
3661
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
3662
3663
        $repository = $this->getRepository();
3664
3665
        $contentService = $repository->getContentService();
3666
3667
        /* BEGIN: Use Case */
3668
        // RemoteId of the "Media" page of an eZ Publish demo installation
3669
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3670
3671
        $content = $this->createContentVersion1();
3672
3673
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3674
3675
        // This call will fail with a "BadStateException", because content is
3676
        // published and not a draft.
3677
        $contentService->addRelation(
3678
            $content->getVersionInfo(),
3679
            $media
3680
        );
3681
        /* END: Use Case */
3682
    }
3683
3684
    /**
3685
     * Test for the loadRelations() method.
3686
     *
3687
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
3688
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3689
     */
3690
    public function testLoadRelations()
3691
    {
3692
        $repository = $this->getRepository();
3693
3694
        $contentService = $repository->getContentService();
3695
3696
        /* BEGIN: Use Case */
3697
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3698
        // of a eZ Publish demo installation.
3699
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3700
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3701
3702
        $draft = $this->createContentDraftVersion1();
3703
3704
        // Load other content objects
3705
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3706
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
3707
3708
        // Create relation between new content object and "Media" page
3709
        $contentService->addRelation(
3710
            $draft->getVersionInfo(),
3711
            $media
3712
        );
3713
3714
        // Create another relation with the "Demo Design" page
3715
        $contentService->addRelation(
3716
            $draft->getVersionInfo(),
3717
            $demoDesign
3718
        );
3719
3720
        // Load all relations
3721
        $relations = $contentService->loadRelations($draft->getVersionInfo());
3722
        /* END: Use Case */
3723
3724
        usort(
3725
            $relations,
3726
            function ($rel1, $rel2) {
3727
                return strcasecmp(
3728
                    $rel2->getDestinationContentInfo()->remoteId,
3729
                    $rel1->getDestinationContentInfo()->remoteId
3730
                );
3731
            }
3732
        );
3733
3734
        $this->assertEquals(
3735
            array(
3736
                array(
3737
                    'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3738
                    'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3739
                ),
3740
                array(
3741
                    'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3742
                    'destinationContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
3743
                ),
3744
            ),
3745
            array(
3746
                array(
3747
                    'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3748
                    'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3749
                ),
3750
                array(
3751
                    'sourceContentInfo' => $relations[1]->sourceContentInfo->remoteId,
3752
                    'destinationContentInfo' => $relations[1]->destinationContentInfo->remoteId,
3753
                ),
3754
            )
3755
        );
3756
    }
3757
3758
    /**
3759
     * Test for the loadRelations() method.
3760
     *
3761
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
3762
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3763
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
3764
     */
3765
    public function testLoadRelationsSkipsArchivedContent()
3766
    {
3767
        $repository = $this->getRepository();
3768
3769
        $contentService = $repository->getContentService();
3770
3771
        /* BEGIN: Use Case */
3772
        $trashService = $repository->getTrashService();
3773
        $locationService = $repository->getLocationService();
3774
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3775
        // of a eZ Publish demo installation.
3776
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3777
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3778
3779
        $draft = $this->createContentDraftVersion1();
3780
3781
        // Load other content objects
3782
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
3783
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
3784
3785
        // Create relation between new content object and "Media" page
3786
        $contentService->addRelation(
3787
            $draft->getVersionInfo(),
3788
            $media
3789
        );
3790
3791
        // Create another relation with the "Demo Design" page
3792
        $contentService->addRelation(
3793
            $draft->getVersionInfo(),
3794
            $demoDesign
3795
        );
3796
3797
        $demoDesignLocation = $locationService->loadLocation($demoDesign->mainLocationId);
3798
3799
        // Trashing Content's last Location will change its status to archived,
3800
        // in this case relation towards it will not be loaded.
3801
        $trashService->trash($demoDesignLocation);
3802
3803
        // Load all relations
3804
        $relations = $contentService->loadRelations($draft->getVersionInfo());
3805
        /* END: Use Case */
3806
3807
        $this->assertCount(1, $relations);
3808
        $this->assertEquals(
3809
            array(
3810
                array(
3811
                    'sourceContentInfo' => 'abcdef0123456789abcdef0123456789',
3812
                    'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3813
                ),
3814
            ),
3815
            array(
3816
                array(
3817
                    'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3818
                    'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3819
                ),
3820
            )
3821
        );
3822
    }
3823
3824
    /**
3825
     * Test for the loadRelations() method.
3826
     *
3827
     * @see \eZ\Publish\API\Repository\ContentService::loadRelations()
3828
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3829
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
3830
     */
3831
    public function testLoadRelationsSkipsDraftContent()
3832
    {
3833
        $repository = $this->getRepository();
3834
3835
        $contentService = $repository->getContentService();
3836
3837
        /* BEGIN: Use Case */
3838
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3839
        // of a eZ Publish demo installation.
3840
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3841
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3842
3843
        $draft = $this->createContentDraftVersion1();
3844
3845
        // Load other content objects
3846
        $media = $contentService->loadContentByRemoteId($mediaRemoteId);
3847
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
3848
3849
        // Create draft of "Media" page
3850
        $mediaDraft = $contentService->createContentDraft($media->contentInfo);
3851
3852
        // Create relation between "Media" page and new content object draft.
3853
        // This relation will not be loaded before the draft is published.
3854
        $contentService->addRelation(
3855
            $mediaDraft->getVersionInfo(),
3856
            $draft->getVersionInfo()->getContentInfo()
3857
        );
3858
3859
        // Create another relation with the "Demo Design" page
3860
        $contentService->addRelation(
3861
            $mediaDraft->getVersionInfo(),
3862
            $demoDesign
3863
        );
3864
3865
        // Load all relations
3866
        $relations = $contentService->loadRelations($mediaDraft->getVersionInfo());
3867
        /* END: Use Case */
3868
3869
        $this->assertCount(1, $relations);
3870
        $this->assertEquals(
3871
            array(
3872
                array(
3873
                    'sourceContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3874
                    'destinationContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
3875
                ),
3876
            ),
3877
            array(
3878
                array(
3879
                    'sourceContentInfo' => $relations[0]->sourceContentInfo->remoteId,
3880
                    'destinationContentInfo' => $relations[0]->destinationContentInfo->remoteId,
3881
                ),
3882
            )
3883
        );
3884
    }
3885
3886
    /**
3887
     * Test for the loadReverseRelations() method.
3888
     *
3889
     * @see \eZ\Publish\API\Repository\ContentService::loadReverseRelations()
3890
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3891
     */
3892
    public function testLoadReverseRelations()
3893
    {
3894
        $repository = $this->getRepository();
3895
3896
        $contentService = $repository->getContentService();
3897
3898
        /* BEGIN: Use Case */
3899
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3900
        // of a eZ Publish demo installation.
3901
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3902
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3903
3904
        $versionInfo = $this->createContentVersion1()->getVersionInfo();
3905
        $contentInfo = $versionInfo->getContentInfo();
3906
3907
        // Create some drafts
3908
        $mediaDraft = $contentService->createContentDraft(
3909
            $contentService->loadContentInfoByRemoteId($mediaRemoteId)
3910
        );
3911
        $demoDesignDraft = $contentService->createContentDraft(
3912
            $contentService->loadContentInfoByRemoteId($demoDesignRemoteId)
3913
        );
3914
3915
        // Create relation between new content object and "Media" page
3916
        $relation1 = $contentService->addRelation(
3917
            $mediaDraft->getVersionInfo(),
3918
            $contentInfo
3919
        );
3920
3921
        // Create another relation with the "Demo Design" page
3922
        $relation2 = $contentService->addRelation(
3923
            $demoDesignDraft->getVersionInfo(),
3924
            $contentInfo
3925
        );
3926
3927
        // Publish drafts, so relations become active
3928
        $contentService->publishVersion($mediaDraft->getVersionInfo());
3929
        $contentService->publishVersion($demoDesignDraft->getVersionInfo());
3930
3931
        // Load all relations
3932
        $relations = $contentService->loadRelations($versionInfo);
3933
        $reverseRelations = $contentService->loadReverseRelations($contentInfo);
3934
        /* END: Use Case */
3935
3936
        $this->assertEquals($contentInfo->id, $relation1->getDestinationContentInfo()->id);
3937
        $this->assertEquals($mediaDraft->id, $relation1->getSourceContentInfo()->id);
3938
3939
        $this->assertEquals($contentInfo->id, $relation2->getDestinationContentInfo()->id);
3940
        $this->assertEquals($demoDesignDraft->id, $relation2->getSourceContentInfo()->id);
3941
3942
        $this->assertEquals(0, count($relations));
3943
        $this->assertEquals(2, count($reverseRelations));
3944
3945
        usort(
3946
            $reverseRelations,
3947
            function ($rel1, $rel2) {
3948
                return strcasecmp(
3949
                    $rel2->getSourceContentInfo()->remoteId,
3950
                    $rel1->getSourceContentInfo()->remoteId
3951
                );
3952
            }
3953
        );
3954
3955
        $this->assertEquals(
3956
            array(
3957
                array(
3958
                    'sourceContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
3959
                    'destinationContentInfo' => 'abcdef0123456789abcdef0123456789',
3960
                ),
3961
                array(
3962
                    'sourceContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
3963
                    'destinationContentInfo' => 'abcdef0123456789abcdef0123456789',
3964
                ),
3965
            ),
3966
            array(
3967
                array(
3968
                    'sourceContentInfo' => $reverseRelations[0]->sourceContentInfo->remoteId,
3969
                    'destinationContentInfo' => $reverseRelations[0]->destinationContentInfo->remoteId,
3970
                ),
3971
                array(
3972
                    'sourceContentInfo' => $reverseRelations[1]->sourceContentInfo->remoteId,
3973
                    'destinationContentInfo' => $reverseRelations[1]->destinationContentInfo->remoteId,
3974
                ),
3975
            )
3976
        );
3977
    }
3978
3979
    /**
3980
     * Test for the loadReverseRelations() method.
3981
     *
3982
     * @see \eZ\Publish\API\Repository\ContentService::loadReverseRelations()
3983
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
3984
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadReverseRelations
3985
     */
3986
    public function testLoadReverseRelationsSkipsArchivedContent()
3987
    {
3988
        $repository = $this->getRepository();
3989
3990
        $contentService = $repository->getContentService();
3991
3992
        /* BEGIN: Use Case */
3993
        $trashService = $repository->getTrashService();
3994
        $locationService = $repository->getLocationService();
3995
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
3996
        // of a eZ Publish demo installation.
3997
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
3998
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
3999
4000
        $versionInfo = $this->createContentVersion1()->getVersionInfo();
4001
        $contentInfo = $versionInfo->getContentInfo();
4002
4003
        // Create some drafts
4004
        $mediaDraft = $contentService->createContentDraft(
4005
            $contentService->loadContentInfoByRemoteId($mediaRemoteId)
4006
        );
4007
        $demoDesignDraft = $contentService->createContentDraft(
4008
            $contentService->loadContentInfoByRemoteId($demoDesignRemoteId)
4009
        );
4010
4011
        // Create relation between new content object and "Media" page
4012
        $relation1 = $contentService->addRelation(
4013
            $mediaDraft->getVersionInfo(),
4014
            $contentInfo
4015
        );
4016
4017
        // Create another relation with the "Demo Design" page
4018
        $relation2 = $contentService->addRelation(
4019
            $demoDesignDraft->getVersionInfo(),
4020
            $contentInfo
4021
        );
4022
4023
        // Publish drafts, so relations become active
4024
        $contentService->publishVersion($mediaDraft->getVersionInfo());
4025
        $contentService->publishVersion($demoDesignDraft->getVersionInfo());
4026
4027
        $demoDesignLocation = $locationService->loadLocation($demoDesignDraft->contentInfo->mainLocationId);
4028
4029
        // Trashing Content's last Location will change its status to archived,
4030
        // in this case relation from it will not be loaded.
4031
        $trashService->trash($demoDesignLocation);
4032
4033
        // Load all relations
4034
        $relations = $contentService->loadRelations($versionInfo);
4035
        $reverseRelations = $contentService->loadReverseRelations($contentInfo);
4036
        /* END: Use Case */
4037
4038
        $this->assertEquals($contentInfo->id, $relation1->getDestinationContentInfo()->id);
4039
        $this->assertEquals($mediaDraft->id, $relation1->getSourceContentInfo()->id);
4040
4041
        $this->assertEquals($contentInfo->id, $relation2->getDestinationContentInfo()->id);
4042
        $this->assertEquals($demoDesignDraft->id, $relation2->getSourceContentInfo()->id);
4043
4044
        $this->assertEquals(0, count($relations));
4045
        $this->assertEquals(1, count($reverseRelations));
4046
4047
        $this->assertEquals(
4048
            array(
4049
                array(
4050
                    'sourceContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
4051
                    'destinationContentInfo' => 'abcdef0123456789abcdef0123456789',
4052
                ),
4053
            ),
4054
            array(
4055
                array(
4056
                    'sourceContentInfo' => $reverseRelations[0]->sourceContentInfo->remoteId,
4057
                    'destinationContentInfo' => $reverseRelations[0]->destinationContentInfo->remoteId,
4058
                ),
4059
            )
4060
        );
4061
    }
4062
4063
    /**
4064
     * Test for the loadReverseRelations() method.
4065
     *
4066
     * @see \eZ\Publish\API\Repository\ContentService::loadReverseRelations()
4067
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testAddRelation
4068
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadReverseRelations
4069
     */
4070
    public function testLoadReverseRelationsSkipsDraftContent()
4071
    {
4072
        $repository = $this->getRepository();
4073
4074
        $contentService = $repository->getContentService();
4075
4076
        /* BEGIN: Use Case */
4077
        // Remote ids of the "Media" and the "eZ Publish Demo Design ..." page
4078
        // of a eZ Publish demo installation.
4079
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4080
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
4081
4082
        // Load "Media" page Content
4083
        $media = $contentService->loadContentByRemoteId($mediaRemoteId);
4084
4085
        // Create some drafts
4086
        $newDraftVersionInfo = $this->createContentDraftVersion1()->getVersionInfo();
4087
        $demoDesignDraft = $contentService->createContentDraft(
4088
            $contentService->loadContentInfoByRemoteId($demoDesignRemoteId)
4089
        );
4090
4091
        // Create relation between "Media" page and new content object
4092
        $relation1 = $contentService->addRelation(
4093
            $newDraftVersionInfo,
4094
            $media->contentInfo
4095
        );
4096
4097
        // Create another relation with the "Demo Design" page
4098
        $relation2 = $contentService->addRelation(
4099
            $demoDesignDraft->getVersionInfo(),
4100
            $media->contentInfo
4101
        );
4102
4103
        // Publish drafts, so relations become active
4104
        $contentService->publishVersion($demoDesignDraft->getVersionInfo());
4105
        // We will not publish new Content draft, therefore relation from it
4106
        // will not be loaded as reverse relation for "Media" page
4107
        //$contentService->publishVersion( $newDraftVersionInfo );
4108
4109
        // Load all relations
4110
        $relations = $contentService->loadRelations($media->versionInfo);
4111
        $reverseRelations = $contentService->loadReverseRelations($media->contentInfo);
4112
        /* END: Use Case */
4113
4114
        $this->assertEquals($media->contentInfo->id, $relation1->getDestinationContentInfo()->id);
4115
        $this->assertEquals($newDraftVersionInfo->contentInfo->id, $relation1->getSourceContentInfo()->id);
4116
4117
        $this->assertEquals($media->contentInfo->id, $relation2->getDestinationContentInfo()->id);
4118
        $this->assertEquals($demoDesignDraft->id, $relation2->getSourceContentInfo()->id);
4119
4120
        $this->assertEquals(0, count($relations));
4121
        $this->assertEquals(1, count($reverseRelations));
4122
4123
        $this->assertEquals(
4124
            array(
4125
                array(
4126
                    'sourceContentInfo' => '8b8b22fe3c6061ed500fbd2b377b885f',
4127
                    'destinationContentInfo' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
4128
                ),
4129
            ),
4130
            array(
4131
                array(
4132
                    'sourceContentInfo' => $reverseRelations[0]->sourceContentInfo->remoteId,
4133
                    'destinationContentInfo' => $reverseRelations[0]->destinationContentInfo->remoteId,
4134
                ),
4135
            )
4136
        );
4137
    }
4138
4139
    /**
4140
     * Test for the deleteRelation() method.
4141
     *
4142
     * @see \eZ\Publish\API\Repository\ContentService::deleteRelation()
4143
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadRelations
4144
     */
4145
    public function testDeleteRelation()
4146
    {
4147
        $repository = $this->getRepository();
4148
4149
        $contentService = $repository->getContentService();
4150
4151
        /* BEGIN: Use Case */
4152
        // Remote ids of the "Media" and the "Demo Design" page of a eZ Publish
4153
        // demo installation.
4154
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4155
        $demoDesignRemoteId = '8b8b22fe3c6061ed500fbd2b377b885f';
4156
4157
        $draft = $this->createContentDraftVersion1();
4158
4159
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
4160
        $demoDesign = $contentService->loadContentInfoByRemoteId($demoDesignRemoteId);
4161
4162
        // Establish some relations
4163
        $contentService->addRelation($draft->getVersionInfo(), $media);
4164
        $contentService->addRelation($draft->getVersionInfo(), $demoDesign);
4165
4166
        // Delete one of the currently created relations
4167
        $contentService->deleteRelation($draft->getVersionInfo(), $media);
4168
4169
        // The relations array now contains only one element
4170
        $relations = $contentService->loadRelations($draft->getVersionInfo());
4171
        /* END: Use Case */
4172
4173
        $this->assertEquals(1, count($relations));
4174
    }
4175
4176
    /**
4177
     * Test for the deleteRelation() method.
4178
     *
4179
     * @see \eZ\Publish\API\Repository\ContentService::deleteRelation()
4180
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteRelation
4181
     */
4182
    public function testDeleteRelationThrowsBadStateException()
4183
    {
4184
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
4185
4186
        $repository = $this->getRepository();
4187
4188
        $contentService = $repository->getContentService();
4189
4190
        /* BEGIN: Use Case */
4191
        // RemoteId of the "Media" page of an eZ Publish demo installation
4192
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4193
4194
        $content = $this->createContentVersion1();
4195
4196
        // Load the destination object
4197
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
4198
4199
        // Create a new draft
4200
        $draftVersion2 = $contentService->createContentDraft($content->contentInfo);
4201
4202
        // Add a relation
4203
        $contentService->addRelation($draftVersion2->getVersionInfo(), $media);
4204
4205
        // Publish new version
4206
        $contentVersion2 = $contentService->publishVersion(
4207
            $draftVersion2->getVersionInfo()
4208
        );
4209
4210
        // This call will fail with a "BadStateException", because content is
4211
        // published and not a draft.
4212
        $contentService->deleteRelation(
4213
            $contentVersion2->getVersionInfo(),
4214
            $media
4215
        );
4216
        /* END: Use Case */
4217
    }
4218
4219
    /**
4220
     * Test for the deleteRelation() method.
4221
     *
4222
     * @see \eZ\Publish\API\Repository\ContentService::deleteRelation()
4223
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteRelation
4224
     */
4225
    public function testDeleteRelationThrowsInvalidArgumentException()
4226
    {
4227
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
4228
4229
        $repository = $this->getRepository();
4230
4231
        $contentService = $repository->getContentService();
4232
4233
        /* BEGIN: Use Case */
4234
        // RemoteId of the "Media" page of an eZ Publish demo installation
4235
        $mediaRemoteId = 'a6e35cbcb7cd6ae4b691f3eee30cd262';
4236
4237
        $draft = $this->createContentDraftVersion1();
4238
4239
        // Load the destination object
4240
        $media = $contentService->loadContentInfoByRemoteId($mediaRemoteId);
4241
4242
        // This call will fail with a "InvalidArgumentException", because no
4243
        // relation exists between $draft and $media.
4244
        $contentService->deleteRelation(
4245
            $draft->getVersionInfo(),
4246
            $media
4247
        );
4248
        /* END: Use Case */
4249
    }
4250
4251
    /**
4252
     * Test for the createContent() method.
4253
     *
4254
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
4255
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4256
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4257
     */
4258
    public function testCreateContentInTransactionWithRollback()
4259
    {
4260
        if ($this->isVersion4()) {
4261
            $this->markTestSkipped('This test requires eZ Publish 5');
4262
        }
4263
4264
        $repository = $this->getRepository();
4265
4266
        /* BEGIN: Use Case */
4267
        $contentTypeService = $repository->getContentTypeService();
4268
        $contentService = $repository->getContentService();
4269
4270
        // Start a transaction
4271
        $repository->beginTransaction();
4272
4273
        try {
4274
            $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
4275
4276
            // Get a content create struct and set mandatory properties
4277
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
4278
            $contentCreate->setField('name', 'Sindelfingen forum');
4279
4280
            $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
4281
            $contentCreate->alwaysAvailable = true;
4282
4283
            // Create a new content object
4284
            $contentId = $contentService->createContent($contentCreate)->id;
4285
        } catch (Exception $e) {
4286
            // Cleanup hanging transaction on error
4287
            $repository->rollback();
4288
            throw $e;
4289
        }
4290
4291
        // Rollback all changes
4292
        $repository->rollback();
4293
4294
        try {
4295
            // This call will fail with a "NotFoundException"
4296
            $contentService->loadContent($contentId);
4297
        } catch (NotFoundException $e) {
4298
            // This is expected
4299
            return;
4300
        }
4301
        /* END: Use Case */
4302
4303
        $this->fail('Content object still exists after rollback.');
4304
    }
4305
4306
    /**
4307
     * Test for the createContent() method.
4308
     *
4309
     * @see \eZ\Publish\API\Repository\ContentService::createContent()
4310
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4311
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4312
     */
4313
    public function testCreateContentInTransactionWithCommit()
4314
    {
4315
        if ($this->isVersion4()) {
4316
            $this->markTestSkipped('This test requires eZ Publish 5');
4317
        }
4318
4319
        $repository = $this->getRepository();
4320
4321
        /* BEGIN: Use Case */
4322
        $contentTypeService = $repository->getContentTypeService();
4323
        $contentService = $repository->getContentService();
4324
4325
        // Start a transaction
4326
        $repository->beginTransaction();
4327
4328
        try {
4329
            $contentType = $contentTypeService->loadContentTypeByIdentifier('forum');
4330
4331
            // Get a content create struct and set mandatory properties
4332
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
4333
            $contentCreate->setField('name', 'Sindelfingen forum');
4334
4335
            $contentCreate->remoteId = 'abcdef0123456789abcdef0123456789';
4336
            $contentCreate->alwaysAvailable = true;
4337
4338
            // Create a new content object
4339
            $contentId = $contentService->createContent($contentCreate)->id;
4340
4341
            // Commit changes
4342
            $repository->commit();
4343
        } catch (Exception $e) {
4344
            // Cleanup hanging transaction on error
4345
            $repository->rollback();
4346
            throw $e;
4347
        }
4348
4349
        // Load the new content object
4350
        $content = $contentService->loadContent($contentId);
4351
        /* END: Use Case */
4352
4353
        $this->assertEquals($contentId, $content->id);
4354
    }
4355
4356
    /**
4357
     * Test for the createContent() method.
4358
     *
4359
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
4360
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
4361
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentThrowsNotFoundException
4362
     */
4363
    public function testCreateContentWithLocationCreateParameterInTransactionWithRollback()
4364
    {
4365
        $repository = $this->getRepository();
4366
4367
        $contentService = $repository->getContentService();
4368
4369
        /* BEGIN: Use Case */
4370
        // Start a transaction
4371
        $repository->beginTransaction();
4372
4373
        try {
4374
            $draft = $this->createContentDraftVersion1();
4375
        } catch (Exception $e) {
4376
            // Cleanup hanging transaction on error
4377
            $repository->rollback();
4378
            throw $e;
4379
        }
4380
4381
        $contentId = $draft->id;
4382
4383
        // Roleback the transaction
4384
        $repository->rollback();
4385
4386
        try {
4387
            // This call will fail with a "NotFoundException"
4388
            $contentService->loadContent($contentId);
4389
        } catch (NotFoundException $e) {
4390
            return;
4391
        }
4392
        /* END: Use Case */
4393
4394
        $this->fail('Can still load content object after rollback.');
4395
    }
4396
4397
    /**
4398
     * Test for the createContent() method.
4399
     *
4400
     * @see \eZ\Publish\API\Repository\ContentService::createContent($contentCreateStruct, $locationCreateStructs)
4401
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentWithLocationCreateParameterDoesNotCreateLocationImmediately
4402
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentThrowsNotFoundException
4403
     */
4404 View Code Duplication
    public function testCreateContentWithLocationCreateParameterInTransactionWithCommit()
4405
    {
4406
        $repository = $this->getRepository();
4407
4408
        $contentService = $repository->getContentService();
4409
4410
        /* BEGIN: Use Case */
4411
        // Start a transaction
4412
        $repository->beginTransaction();
4413
4414
        try {
4415
            $draft = $this->createContentDraftVersion1();
4416
4417
            $contentId = $draft->id;
4418
4419
            // Roleback the transaction
4420
            $repository->commit();
4421
        } catch (Exception $e) {
4422
            // Cleanup hanging transaction on error
4423
            $repository->rollback();
4424
            throw $e;
4425
        }
4426
4427
        // Load the new content object
4428
        $content = $contentService->loadContent($contentId);
4429
        /* END: Use Case */
4430
4431
        $this->assertEquals($contentId, $content->id);
4432
    }
4433
4434
    /**
4435
     * Test for the createContentDraft() method.
4436
     *
4437
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
4438
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
4439
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4440
     */
4441
    public function testCreateContentDraftInTransactionWithRollback()
4442
    {
4443
        $repository = $this->getRepository();
4444
4445
        $contentId = $this->generateId('object', 12);
4446
        /* BEGIN: Use Case */
4447
        // $contentId is the ID of the "Administrator users" user group
4448
4449
        // Get the content service
4450
        $contentService = $repository->getContentService();
4451
4452
        // Load the user group content object
4453
        $content = $contentService->loadContent($contentId);
4454
4455
        // Start a new transaction
4456
        $repository->beginTransaction();
4457
4458
        try {
4459
            // Create a new draft
4460
            $drafted = $contentService->createContentDraft($content->contentInfo);
4461
4462
            // Store version number for later reuse
4463
            $versionNo = $drafted->versionInfo->versionNo;
4464
        } catch (Exception $e) {
4465
            // Cleanup hanging transaction on error
4466
            $repository->rollback();
4467
            throw $e;
4468
        }
4469
4470
        // Rollback
4471
        $repository->rollback();
4472
4473
        try {
4474
            // This call will fail with a "NotFoundException"
4475
            $contentService->loadContent($contentId, null, $versionNo);
4476
        } catch (NotFoundException $e) {
4477
            return;
4478
        }
4479
        /* END: Use Case */
4480
4481
        $this->fail('Can still load content draft after rollback');
4482
    }
4483
4484
    /**
4485
     * Test for the createContentDraft() method.
4486
     *
4487
     * @see \eZ\Publish\API\Repository\ContentService::createContentDraft()
4488
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContentDraft
4489
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4490
     */
4491 View Code Duplication
    public function testCreateContentDraftInTransactionWithCommit()
4492
    {
4493
        $repository = $this->getRepository();
4494
4495
        $contentId = $this->generateId('object', 12);
4496
        /* BEGIN: Use Case */
4497
        // $contentId is the ID of the "Administrator users" user group
4498
4499
        // Get the content service
4500
        $contentService = $repository->getContentService();
4501
4502
        // Load the user group content object
4503
        $content = $contentService->loadContent($contentId);
4504
4505
        // Start a new transaction
4506
        $repository->beginTransaction();
4507
4508
        try {
4509
            // Create a new draft
4510
            $drafted = $contentService->createContentDraft($content->contentInfo);
4511
4512
            // Store version number for later reuse
4513
            $versionNo = $drafted->versionInfo->versionNo;
4514
4515
            // Commit all changes
4516
            $repository->commit();
4517
        } catch (Exception $e) {
4518
            // Cleanup hanging transaction on error
4519
            $repository->rollback();
4520
            throw $e;
4521
        }
4522
4523
        $content = $contentService->loadContent($contentId, null, $versionNo);
4524
        /* END: Use Case */
4525
4526
        $this->assertEquals(
4527
            $versionNo,
4528
            $content->getVersionInfo()->versionNo
4529
        );
4530
    }
4531
4532
    /**
4533
     * Test for the publishVersion() method.
4534
     *
4535
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
4536
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
4537
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4538
     */
4539 View Code Duplication
    public function testPublishVersionInTransactionWithRollback()
4540
    {
4541
        $repository = $this->getRepository();
4542
4543
        $contentId = $this->generateId('object', 12);
4544
        /* BEGIN: Use Case */
4545
        // $contentId is the ID of the "Administrator users" user group
4546
4547
        // Get the content service
4548
        $contentService = $repository->getContentService();
4549
4550
        // Load the user group content object
4551
        $content = $contentService->loadContent($contentId);
4552
4553
        // Start a new transaction
4554
        $repository->beginTransaction();
4555
4556
        try {
4557
            $draftVersion = $contentService->createContentDraft($content->contentInfo)->getVersionInfo();
4558
4559
            // Publish a new version
4560
            $content = $contentService->publishVersion($draftVersion);
4561
4562
            // Store version number for later reuse
4563
            $versionNo = $content->versionInfo->versionNo;
4564
        } catch (Exception $e) {
4565
            // Cleanup hanging transaction on error
4566
            $repository->rollback();
4567
            throw $e;
4568
        }
4569
4570
        // Rollback
4571
        $repository->rollback();
4572
4573
        try {
4574
            // This call will fail with a "NotFoundException"
4575
            $contentService->loadContent($contentId, null, $versionNo);
4576
        } catch (NotFoundException $e) {
4577
            return;
4578
        }
4579
        /* END: Use Case */
4580
4581
        $this->fail('Can still load content draft after rollback');
4582
    }
4583
4584
    /**
4585
     * Test for the publishVersion() method.
4586
     *
4587
     * @see \eZ\Publish\API\Repository\ContentService::publishVersion()
4588
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testPublishVersion
4589
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadVersionInfo
4590
     */
4591 View Code Duplication
    public function testPublishVersionInTransactionWithCommit()
4592
    {
4593
        $repository = $this->getRepository();
4594
4595
        /* BEGIN: Use Case */
4596
        // ID of the "Administrator users" user group
4597
        $contentId = 12;
4598
4599
        // Get the content service
4600
        $contentService = $repository->getContentService();
4601
4602
        // Load the user group content object
4603
        $template = $contentService->loadContent($contentId);
4604
4605
        // Start a new transaction
4606
        $repository->beginTransaction();
4607
4608
        try {
4609
            // Publish a new version
4610
            $content = $contentService->publishVersion(
4611
                $contentService->createContentDraft($template->contentInfo)->getVersionInfo()
4612
            );
4613
4614
            // Store version number for later reuse
4615
            $versionNo = $content->versionInfo->versionNo;
4616
4617
            // Commit all changes
4618
            $repository->commit();
4619
        } catch (Exception $e) {
4620
            // Cleanup hanging transaction on error
4621
            $repository->rollback();
4622
            throw $e;
4623
        }
4624
4625
        // Load current version info
4626
        $versionInfo = $contentService->loadVersionInfo($content->contentInfo);
4627
        /* END: Use Case */
4628
4629
        $this->assertEquals($versionNo, $versionInfo->versionNo);
4630
    }
4631
4632
    /**
4633
     * Test for the updateContent() method.
4634
     *
4635
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
4636
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
4637
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4638
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4639
     */
4640 View Code Duplication
    public function testUpdateContentInTransactionWithRollback()
4641
    {
4642
        $repository = $this->getRepository();
4643
4644
        $contentId = $this->generateId('object', 12);
4645
        /* BEGIN: Use Case */
4646
        // $contentId is the ID of the "Administrator users" user group
4647
4648
        // Load content service
4649
        $contentService = $repository->getContentService();
4650
4651
        // Create a new user group draft
4652
        $draft = $contentService->createContentDraft(
4653
            $contentService->loadContentInfo($contentId)
4654
        );
4655
4656
        // Get an update struct and change the group name
4657
        $contentUpdate = $contentService->newContentUpdateStruct();
4658
        $contentUpdate->setField('name', 'Administrators', 'eng-US');
4659
4660
        // Start a transaction
4661
        $repository->beginTransaction();
4662
4663
        try {
4664
            // Update the group name
4665
            $draft = $contentService->updateContent(
4666
                $draft->getVersionInfo(),
4667
                $contentUpdate
4668
            );
4669
4670
            // Publish updated version
4671
            $contentService->publishVersion($draft->getVersionInfo());
4672
        } catch (Exception $e) {
4673
            // Cleanup hanging transaction on error
4674
            $repository->rollback();
4675
            throw $e;
4676
        }
4677
4678
        // Rollback all changes.
4679
        $repository->rollback();
4680
4681
        // Name will still be "Administrator users"
4682
        $name = $contentService->loadContent($contentId)->getFieldValue('name');
4683
        /* END: Use Case */
4684
4685
        $this->assertEquals('Administrator users', $name);
4686
    }
4687
4688
    /**
4689
     * Test for the updateContent() method.
4690
     *
4691
     * @see \eZ\Publish\API\Repository\ContentService::updateContent()
4692
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
4693
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContent
4694
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4695
     */
4696 View Code Duplication
    public function testUpdateContentInTransactionWithCommit()
4697
    {
4698
        $repository = $this->getRepository();
4699
4700
        $contentId = $this->generateId('object', 12);
4701
        /* BEGIN: Use Case */
4702
        // $contentId is the ID of the "Administrator users" user group
4703
4704
        // Load content service
4705
        $contentService = $repository->getContentService();
4706
4707
        // Create a new user group draft
4708
        $draft = $contentService->createContentDraft(
4709
            $contentService->loadContentInfo($contentId)
4710
        );
4711
4712
        // Get an update struct and change the group name
4713
        $contentUpdate = $contentService->newContentUpdateStruct();
4714
        $contentUpdate->setField('name', 'Administrators', 'eng-US');
4715
4716
        // Start a transaction
4717
        $repository->beginTransaction();
4718
4719
        try {
4720
            // Update the group name
4721
            $draft = $contentService->updateContent(
4722
                $draft->getVersionInfo(),
4723
                $contentUpdate
4724
            );
4725
4726
            // Publish updated version
4727
            $contentService->publishVersion($draft->getVersionInfo());
4728
4729
            // Commit all changes.
4730
            $repository->commit();
4731
        } catch (Exception $e) {
4732
            // Cleanup hanging transaction on error
4733
            $repository->rollback();
4734
            throw $e;
4735
        }
4736
4737
        // Name is now "Administrators"
4738
        $name = $contentService->loadContent($contentId)->getFieldValue('name', 'eng-US');
4739
        /* END: Use Case */
4740
4741
        $this->assertEquals('Administrators', $name);
4742
    }
4743
4744
    /**
4745
     * Test for the updateContentMetadata() method.
4746
     *
4747
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
4748
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
4749
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4750
     */
4751 View Code Duplication
    public function testUpdateContentMetadataInTransactionWithRollback()
4752
    {
4753
        $repository = $this->getRepository();
4754
4755
        $contentId = $this->generateId('object', 12);
4756
        /* BEGIN: Use Case */
4757
        // $contentId is the ID of the "Administrator users" user group
4758
4759
        // Get the content service
4760
        $contentService = $repository->getContentService();
4761
4762
        // Load a ContentInfo object
4763
        $contentInfo = $contentService->loadContentInfo($contentId);
4764
4765
        // Store remoteId for later testing
4766
        $remoteId = $contentInfo->remoteId;
4767
4768
        // Start a transaction
4769
        $repository->beginTransaction();
4770
4771
        try {
4772
            // Get metadata update struct and change remoteId
4773
            $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
4774
            $metadataUpdate->remoteId = md5(microtime(true));
4775
4776
            // Update the metadata of the published content object
4777
            $contentService->updateContentMetadata(
4778
                $contentInfo,
4779
                $metadataUpdate
4780
            );
4781
        } catch (Exception $e) {
4782
            // Cleanup hanging transaction on error
4783
            $repository->rollback();
4784
            throw $e;
4785
        }
4786
4787
        // Rollback all changes.
4788
        $repository->rollback();
4789
4790
        // Load current remoteId
4791
        $remoteIdReloaded = $contentService->loadContentInfo($contentId)->remoteId;
4792
        /* END: Use Case */
4793
4794
        $this->assertEquals($remoteId, $remoteIdReloaded);
4795
    }
4796
4797
    /**
4798
     * Test for the updateContentMetadata() method.
4799
     *
4800
     * @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
4801
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
4802
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4803
     */
4804 View Code Duplication
    public function testUpdateContentMetadataInTransactionWithCommit()
4805
    {
4806
        $repository = $this->getRepository();
4807
4808
        $contentId = $this->generateId('object', 12);
4809
        /* BEGIN: Use Case */
4810
        // $contentId is the ID of the "Administrator users" user group
4811
4812
        // Get the content service
4813
        $contentService = $repository->getContentService();
4814
4815
        // Load a ContentInfo object
4816
        $contentInfo = $contentService->loadContentInfo($contentId);
4817
4818
        // Store remoteId for later testing
4819
        $remoteId = $contentInfo->remoteId;
4820
4821
        // Start a transaction
4822
        $repository->beginTransaction();
4823
4824
        try {
4825
            // Get metadata update struct and change remoteId
4826
            $metadataUpdate = $contentService->newContentMetadataUpdateStruct();
4827
            $metadataUpdate->remoteId = md5(microtime(true));
4828
4829
            // Update the metadata of the published content object
4830
            $contentService->updateContentMetadata(
4831
                $contentInfo,
4832
                $metadataUpdate
4833
            );
4834
4835
            // Commit all changes.
4836
            $repository->commit();
4837
        } catch (Exception $e) {
4838
            // Cleanup hanging transaction on error
4839
            $repository->rollback();
4840
            throw $e;
4841
        }
4842
4843
        // Load current remoteId
4844
        $remoteIdReloaded = $contentService->loadContentInfo($contentId)->remoteId;
4845
        /* END: Use Case */
4846
4847
        $this->assertNotEquals($remoteId, $remoteIdReloaded);
4848
    }
4849
4850
    /**
4851
     * Test for the deleteVersion() method.
4852
     *
4853
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
4854
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4855
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4856
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentDrafts
4857
     */
4858
    public function testDeleteVersionInTransactionWithRollback()
4859
    {
4860
        $repository = $this->getRepository();
4861
4862
        $contentId = $this->generateId('object', 12);
4863
        /* BEGIN: Use Case */
4864
        // $contentId is the ID of the "Administrator users" user group
4865
4866
        // Get the content service
4867
        $contentService = $repository->getContentService();
4868
4869
        // Start a new transaction
4870
        $repository->beginTransaction();
4871
4872
        try {
4873
            // Create a new draft
4874
            $draft = $contentService->createContentDraft(
4875
                $contentService->loadContentInfo($contentId)
4876
            );
4877
4878
            $contentService->deleteVersion($draft->getVersionInfo());
4879
        } catch (Exception $e) {
4880
            // Cleanup hanging transaction on error
4881
            $repository->rollback();
4882
            throw $e;
4883
        }
4884
4885
        // Rollback all changes.
4886
        $repository->rollback();
4887
4888
        // This array will be empty
4889
        $drafts = $contentService->loadContentDrafts();
4890
        /* END: Use Case */
4891
4892
        $this->assertSame(array(), $drafts);
4893
    }
4894
4895
    /**
4896
     * Test for the deleteVersion() method.
4897
     *
4898
     * @see \eZ\Publish\API\Repository\ContentService::deleteVersion()
4899
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
4900
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4901
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentDrafts
4902
     */
4903
    public function testDeleteVersionInTransactionWithCommit()
4904
    {
4905
        $repository = $this->getRepository();
4906
4907
        $contentId = $this->generateId('object', 12);
4908
        /* BEGIN: Use Case */
4909
        // $contentId is the ID of the "Administrator users" user group
4910
4911
        // Get the content service
4912
        $contentService = $repository->getContentService();
4913
4914
        // Start a new transaction
4915
        $repository->beginTransaction();
4916
4917
        try {
4918
            // Create a new draft
4919
            $draft = $contentService->createContentDraft(
4920
                $contentService->loadContentInfo($contentId)
4921
            );
4922
4923
            $contentService->deleteVersion($draft->getVersionInfo());
4924
4925
            // Commit all changes.
4926
            $repository->commit();
4927
        } catch (Exception $e) {
4928
            // Cleanup hanging transaction on error
4929
            $repository->rollback();
4930
            throw $e;
4931
        }
4932
4933
        // This array will contain no element
4934
        $drafts = $contentService->loadContentDrafts();
4935
        /* END: Use Case */
4936
4937
        $this->assertSame(array(), $drafts);
4938
    }
4939
4940
    /**
4941
     * Test for the deleteContent() method.
4942
     *
4943
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
4944
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteContent
4945
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4946
     */
4947
    public function testDeleteContentInTransactionWithRollback()
4948
    {
4949
        $repository = $this->getRepository();
4950
4951
        $contentId = $this->generateId('object', 11);
4952
        /* BEGIN: Use Case */
4953
        // $contentId is the ID of the "Members" user group in an eZ Publish
4954
        // demo installation
4955
4956
        // Get content service
4957
        $contentService = $repository->getContentService();
4958
4959
        // Load a ContentInfo instance
4960
        $contentInfo = $contentService->loadContentInfo($contentId);
4961
4962
        // Start a new transaction
4963
        $repository->beginTransaction();
4964
4965
        try {
4966
            // Delete content object
4967
            $contentService->deleteContent($contentInfo);
4968
        } catch (Exception $e) {
4969
            // Cleanup hanging transaction on error
4970
            $repository->rollback();
4971
            throw $e;
4972
        }
4973
4974
        // Rollback all changes
4975
        $repository->rollback();
4976
4977
        // This call will return the original content object
4978
        $contentInfo = $contentService->loadContentInfo($contentId);
4979
        /* END: Use Case */
4980
4981
        $this->assertEquals($contentId, $contentInfo->id);
4982
    }
4983
4984
    /**
4985
     * Test for the deleteContent() method.
4986
     *
4987
     * @see \eZ\Publish\API\Repository\ContentService::deleteContent()
4988
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testDeleteContent
4989
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfo
4990
     */
4991
    public function testDeleteContentInTransactionWithCommit()
4992
    {
4993
        $repository = $this->getRepository();
4994
4995
        $contentId = $this->generateId('object', 11);
4996
        /* BEGIN: Use Case */
4997
        // $contentId is the ID of the "Members" user group in an eZ Publish
4998
        // demo installation
4999
5000
        // Get content service
5001
        $contentService = $repository->getContentService();
5002
5003
        // Load a ContentInfo instance
5004
        $contentInfo = $contentService->loadContentInfo($contentId);
5005
5006
        // Start a new transaction
5007
        $repository->beginTransaction();
5008
5009
        try {
5010
            // Delete content object
5011
            $contentService->deleteContent($contentInfo);
5012
5013
            // Commit all changes
5014
            $repository->commit();
5015
        } catch (Exception $e) {
5016
            // Cleanup hanging transaction on error
5017
            $repository->rollback();
5018
            throw $e;
5019
        }
5020
5021
        // Deleted content info is not found anymore
5022
        try {
5023
            $contentService->loadContentInfo($contentId);
5024
        } catch (NotFoundException $e) {
5025
            return;
5026
        }
5027
        /* END: Use Case */
5028
5029
        $this->fail('Can still load ContentInfo after commit.');
5030
    }
5031
5032
    /**
5033
     * Test for the copyContent() method.
5034
     *
5035
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
5036
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContent
5037
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
5038
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
5039
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
5040
     */
5041 View Code Duplication
    public function testCopyContentInTransactionWithRollback()
5042
    {
5043
        $repository = $this->getRepository();
5044
5045
        $contentId = $this->generateId('object', 11);
5046
        $locationId = $this->generateId('location', 13);
5047
        /* BEGIN: Use Case */
5048
        // $contentId is the ID of the "Members" user group in an eZ Publish
5049
        // demo installation
5050
5051
        // $locationId is the ID of the "Administrator users" group location
5052
5053
        // Get services
5054
        $contentService = $repository->getContentService();
5055
        $locationService = $repository->getLocationService();
5056
5057
        // Load content object to copy
5058
        $content = $contentService->loadContent($contentId);
5059
5060
        // Create new target location
5061
        $locationCreate = $locationService->newLocationCreateStruct($locationId);
5062
5063
        // Start a new transaction
5064
        $repository->beginTransaction();
5065
5066
        try {
5067
            // Copy content with all versions and drafts
5068
            $contentService->copyContent(
5069
                $content->contentInfo,
5070
                $locationCreate
5071
            );
5072
        } catch (Exception $e) {
5073
            // Cleanup hanging transaction on error
5074
            $repository->rollback();
5075
            throw $e;
5076
        }
5077
5078
        // Rollback all changes
5079
        $repository->rollback();
5080
5081
        $this->refreshSearch($repository);
5082
5083
        // This array will only contain a single admin user object
5084
        $locations = $locationService->loadLocationChildren(
5085
            $locationService->loadLocation($locationId)
5086
        )->locations;
5087
        /* END: Use Case */
5088
5089
        $this->assertEquals(1, count($locations));
5090
    }
5091
5092
    /**
5093
     * Test for the copyContent() method.
5094
     *
5095
     * @see \eZ\Publish\API\Repository\ContentService::copyContent()
5096
     * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCopyContent
5097
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
5098
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
5099
     * @depend(s) eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
5100
     */
5101 View Code Duplication
    public function testCopyContentInTransactionWithCommit()
5102
    {
5103
        $repository = $this->getRepository();
5104
5105
        $contentId = $this->generateId('object', 11);
5106
        $locationId = $this->generateId('location', 13);
5107
        /* BEGIN: Use Case */
5108
        // $contentId is the ID of the "Members" user group in an eZ Publish
5109
        // demo installation
5110
5111
        // $locationId is the ID of the "Administrator users" group location
5112
5113
        // Get services
5114
        $contentService = $repository->getContentService();
5115
        $locationService = $repository->getLocationService();
5116
5117
        // Load content object to copy
5118
        $content = $contentService->loadContent($contentId);
5119
5120
        // Create new target location
5121
        $locationCreate = $locationService->newLocationCreateStruct($locationId);
5122
5123
        // Start a new transaction
5124
        $repository->beginTransaction();
5125
5126
        try {
5127
            // Copy content with all versions and drafts
5128
            $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...
5129
                $content->contentInfo,
5130
                $locationCreate
5131
            );
5132
5133
            // Commit all changes
5134
            $repository->commit();
5135
        } catch (Exception $e) {
5136
            // Cleanup hanging transaction on error
5137
            $repository->rollback();
5138
            throw $e;
5139
        }
5140
5141
        $this->refreshSearch($repository);
5142
5143
        // This will contain the admin user and the new child location
5144
        $locations = $locationService->loadLocationChildren(
5145
            $locationService->loadLocation($locationId)
5146
        )->locations;
5147
        /* END: Use Case */
5148
5149
        $this->assertEquals(2, count($locations));
5150
    }
5151
5152
    public function testURLAliasesCreatedForNewContent()
5153
    {
5154
        $repository = $this->getRepository();
5155
5156
        $contentService = $repository->getContentService();
5157
        $locationService = $repository->getLocationService();
5158
        $urlAliasService = $repository->getURLAliasService();
5159
5160
        /* BEGIN: Use Case */
5161
        $draft = $this->createContentDraftVersion1();
5162
5163
        // Automatically creates a new URLAlias for the content
5164
        $liveContent = $contentService->publishVersion($draft->getVersionInfo());
5165
        /* END: Use Case */
5166
5167
        $location = $locationService->loadLocation(
5168
            $liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5169
        );
5170
5171
        $aliases = $urlAliasService->listLocationAliases($location, false);
5172
5173
        $this->assertAliasesCorrect(
5174
            array(
5175
                '/Design/Plain-site/An-awesome-forum' => array(
5176
                    'type' => URLAlias::LOCATION,
5177
                    'destination' => $location->id,
5178
                    'path' => '/Design/Plain-site/An-awesome-forum',
5179
                    'languageCodes' => array('eng-US'),
5180
                    'isHistory' => false,
5181
                    'isCustom' => false,
5182
                    'forward' => false,
5183
                ),
5184
            ),
5185
            $aliases
5186
        );
5187
    }
5188
5189
    public function testURLAliasesCreatedForUpdatedContent()
5190
    {
5191
        $repository = $this->getRepository();
5192
5193
        $contentService = $repository->getContentService();
5194
        $locationService = $repository->getLocationService();
5195
        $urlAliasService = $repository->getURLAliasService();
5196
5197
        /* BEGIN: Use Case */
5198
        $draft = $this->createUpdatedDraftVersion2();
5199
5200
        $location = $locationService->loadLocation(
5201
            $draft->getVersionInfo()->getContentInfo()->mainLocationId
5202
        );
5203
5204
        // Load and assert URL aliases before publishing updated Content, so that
5205
        // SPI cache is warmed up and cache invalidation is also tested.
5206
        $aliases = $urlAliasService->listLocationAliases($location, false);
5207
5208
        $this->assertAliasesCorrect(
5209
            array(
5210
                '/Design/Plain-site/An-awesome-forum' => array(
5211
                    'type' => URLAlias::LOCATION,
5212
                    'destination' => $location->id,
5213
                    'path' => '/Design/Plain-site/An-awesome-forum',
5214
                    'languageCodes' => array('eng-US'),
5215
                    'alwaysAvailable' => true,
5216
                    'isHistory' => false,
5217
                    'isCustom' => false,
5218
                    'forward' => false,
5219
                ),
5220
            ),
5221
            $aliases
5222
        );
5223
5224
        // Automatically marks old aliases for the content as history
5225
        // and creates new aliases, based on the changes
5226
        $liveContent = $contentService->publishVersion($draft->getVersionInfo());
5227
        /* END: Use Case */
5228
5229
        $location = $locationService->loadLocation(
5230
            $liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5231
        );
5232
5233
        $aliases = $urlAliasService->listLocationAliases($location, false);
5234
5235
        $this->assertAliasesCorrect(
5236
            array(
5237
                '/Design/Plain-site/An-awesome-forum2' => array(
5238
                    'type' => URLAlias::LOCATION,
5239
                    'destination' => $location->id,
5240
                    'path' => '/Design/Plain-site/An-awesome-forum2',
5241
                    'languageCodes' => array('eng-US'),
5242
                    'alwaysAvailable' => true,
5243
                    'isHistory' => false,
5244
                    'isCustom' => false,
5245
                    'forward' => false,
5246
                ),
5247
                '/Design/Plain-site/An-awesome-forum23' => array(
5248
                    'type' => URLAlias::LOCATION,
5249
                    'destination' => $location->id,
5250
                    'path' => '/Design/Plain-site/An-awesome-forum23',
5251
                    'languageCodes' => array('eng-GB'),
5252
                    'alwaysAvailable' => true,
5253
                    'isHistory' => false,
5254
                    'isCustom' => false,
5255
                    'forward' => false,
5256
                ),
5257
            ),
5258
            $aliases
5259
        );
5260
    }
5261
5262
    public function testCustomURLAliasesNotHistorizedOnUpdatedContent()
5263
    {
5264
        $repository = $this->getRepository();
5265
5266
        $contentService = $repository->getContentService();
5267
5268
        /* BEGIN: Use Case */
5269
        $urlAliasService = $repository->getURLAliasService();
5270
        $locationService = $repository->getLocationService();
5271
5272
        $content = $this->createContentVersion1();
5273
5274
        // Create a custom URL alias
5275
        $urlAliasService->createUrlAlias(
5276
            $locationService->loadLocation(
5277
                $content->getVersionInfo()->getContentInfo()->mainLocationId
5278
            ),
5279
            '/my/fancy/story-about-ez-publish',
5280
            'eng-US'
5281
        );
5282
5283
        $draftVersion2 = $contentService->createContentDraft($content->contentInfo);
5284
5285
        $contentUpdate = $contentService->newContentUpdateStruct();
5286
        $contentUpdate->initialLanguageCode = 'eng-US';
5287
        $contentUpdate->setField('name', 'Amazing Bielefeld forum');
5288
5289
        $draftVersion2 = $contentService->updateContent(
5290
            $draftVersion2->getVersionInfo(),
5291
            $contentUpdate
5292
        );
5293
5294
        // Only marks auto-generated aliases as history
5295
        // the custom one is left untouched
5296
        $liveContent = $contentService->publishVersion($draftVersion2->getVersionInfo());
5297
        /* END: Use Case */
5298
5299
        $location = $locationService->loadLocation(
5300
            $liveContent->getVersionInfo()->getContentInfo()->mainLocationId
5301
        );
5302
5303
        $aliases = $urlAliasService->listLocationAliases($location);
5304
5305
        $this->assertAliasesCorrect(
5306
            array(
5307
                '/my/fancy/story-about-ez-publish' => array(
5308
                    'type' => URLAlias::LOCATION,
5309
                    'destination' => $location->id,
5310
                    'path' => '/my/fancy/story-about-ez-publish',
5311
                    'languageCodes' => array('eng-US'),
5312
                    'isHistory' => false,
5313
                    'isCustom' => true,
5314
                    'forward' => false,
5315
                    'alwaysAvailable' => false,
5316
                ),
5317
            ),
5318
            $aliases
5319
        );
5320
    }
5321
5322
    /**
5323
     * Test to ensure that old versions are not affected by updates to newer
5324
     * drafts.
5325
     */
5326
    public function testUpdatingDraftDoesNotUpdateOldVersions()
5327
    {
5328
        $repository = $this->getRepository();
5329
5330
        $contentService = $repository->getContentService();
5331
5332
        $contentVersion2 = $this->createContentVersion2();
5333
5334
        $loadedContent1 = $contentService->loadContent($contentVersion2->id, null, 1);
5335
        $loadedContent2 = $contentService->loadContent($contentVersion2->id, null, 2);
5336
5337
        $this->assertNotEquals(
5338
            $loadedContent1->getFieldValue('name', 'eng-US'),
5339
            $loadedContent2->getFieldValue('name', 'eng-US')
5340
        );
5341
    }
5342
5343
    /**
5344
     * Test scenario with writer and publisher users.
5345
     * Writer can only create content. Publisher can publish this content.
5346
     */
5347
    public function testPublishWorkflow()
5348
    {
5349
        $repository = $this->getRepository();
5350
        $contentService = $repository->getContentService();
5351
5352
        $this->createRoleWithPolicies('Publisher', [
5353
            ['module' => 'content', 'function' => 'read'],
5354
            ['module' => 'content', 'function' => 'create'],
5355
            ['module' => 'content', 'function' => 'publish'],
5356
        ]);
5357
5358
        $this->createRoleWithPolicies('Writer', [
5359
            ['module' => 'content', 'function' => 'read'],
5360
            ['module' => 'content', 'function' => 'create'],
5361
        ]);
5362
5363
        $writerUser = $this->createCustomUserWithLogin(
5364
            'writer',
5365
            '[email protected]',
5366
            'Writers',
5367
            'Writer'
5368
        );
5369
5370
        $publisherUser = $this->createCustomUserWithLogin(
5371
            'publisher',
5372
            '[email protected]',
5373
            'Publishers',
5374
            'Publisher'
5375
        );
5376
5377
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5378
        $draft = $this->createContentDraftVersion1();
5379
5380
        $repository->getPermissionResolver()->setCurrentUserReference($publisherUser);
5381
        $content = $contentService->publishVersion($draft->versionInfo);
5382
5383
        $contentService->loadContent($content->id);
5384
    }
5385
5386
    /**
5387
     * Test publish / content policy is required to be able to publish content.
5388
     *
5389
     */
5390
    public function testPublishContentWithoutPublishPolicyThrowsException()
5391
    {
5392
        $this->expectException(\eZ\Publish\Core\Base\Exceptions\UnauthorizedException::class);
5393
        $this->expectExceptionMessageRegExp('/User does not have access to \'publish\' \'content\'/');
5394
5395
        $repository = $this->getRepository();
5396
5397
        $this->createRoleWithPolicies('Writer', [
5398
            ['module' => 'content', 'function' => 'read'],
5399
            ['module' => 'content', 'function' => 'create'],
5400
            ['module' => 'content', 'function' => 'edit'],
5401
        ]);
5402
        $writerUser = $this->createCustomUserWithLogin(
5403
            'writer',
5404
            '[email protected]',
5405
            'Writers',
5406
            'Writer'
5407
        );
5408
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5409
5410
        $this->createContentVersion1();
5411
    }
5412
5413
    /**
5414
     * Test removal of the specific translation from all the Versions of a Content Object.
5415
     *
5416
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5417
     */
5418 View Code Duplication
    public function testDeleteTranslation()
5419
    {
5420
        $repository = $this->getRepository();
5421
        $contentService = $repository->getContentService();
5422
        $content = $this->createContentVersion2();
5423
5424
        // create multiple versions to exceed archive limit
5425
        for ($i = 0; $i < 5; ++$i) {
5426
            $contentDraft = $contentService->createContentDraft($content->contentInfo);
5427
            $contentUpdateStruct = $contentService->newContentUpdateStruct();
5428
            $contentDraft = $contentService->updateContent(
5429
                $contentDraft->versionInfo,
5430
                $contentUpdateStruct
5431
            );
5432
            $contentService->publishVersion($contentDraft->versionInfo);
5433
        }
5434
5435
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
5436
5437
        $this->assertTranslationDoesNotExist('eng-GB', $content->id);
5438
    }
5439
5440
    /**
5441
     * Test deleting a Translation which is initial for some Version, updates initialLanguageCode
5442
     * with mainLanguageCode (assuming they are different).
5443
     */
5444
    public function testDeleteTranslationUpdatesInitialLanguageCodeVersion()
5445
    {
5446
        $repository = $this->getRepository();
5447
        $contentService = $repository->getContentService();
5448
5449
        $content = $this->createContentVersion2();
5450
        // create another, copied, version
5451
        $contentDraft = $contentService->updateContent(
5452
            $contentService->createContentDraft($content->contentInfo)->versionInfo,
5453
            $contentService->newContentUpdateStruct()
5454
        );
5455
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
5456
5457
        // remove first version with only one translation as it is not the subject of this test
5458
        $contentService->deleteVersion(
5459
            $contentService->loadVersionInfo($publishedContent->contentInfo, 1)
5460
        );
5461
5462
        // sanity check
5463
        self::assertEquals('eng-US', $content->contentInfo->mainLanguageCode);
5464
        self::assertEquals('eng-US', $content->versionInfo->initialLanguageCode);
5465
5466
        // update mainLanguageCode so it is different than initialLanguageCode for Version
5467
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
5468
        $contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
5469
        $content = $contentService->updateContentMetadata($publishedContent->contentInfo, $contentMetadataUpdateStruct);
5470
5471
        $contentService->deleteTranslation($content->contentInfo, 'eng-US');
5472
5473
        $this->assertTranslationDoesNotExist('eng-US', $content->id);
5474
    }
5475
5476
    /**
5477
     * Test removal of the specific translation properly updates languages of the URL alias.
5478
     *
5479
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5480
     */
5481
    public function testDeleteTranslationUpdatesUrlAlias()
5482
    {
5483
        $repository = $this->getRepository();
5484
        $contentService = $repository->getContentService();
5485
        $locationService = $repository->getLocationService();
5486
        $urlAliasService = $repository->getURLAliasService();
5487
5488
        $content = $this->createContentVersion2();
5489
        $mainLocation = $locationService->loadLocation($content->contentInfo->mainLocationId);
5490
5491
        // create custom URL alias for Content main Location
5492
        $urlAliasService->createUrlAlias($mainLocation, '/my-custom-url', 'eng-GB');
5493
5494
        // create secondary Location for Content
5495
        $secondaryLocation = $locationService->createLocation(
5496
            $content->contentInfo,
5497
            $locationService->newLocationCreateStruct(2)
5498
        );
5499
5500
        // create custom URL alias for Content secondary Location
5501
        $urlAliasService->createUrlAlias($secondaryLocation, '/my-secondary-url', 'eng-GB');
5502
5503
        // delete Translation
5504
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
5505
5506
        foreach ([$mainLocation, $secondaryLocation] as $location) {
5507
            // check auto-generated URL aliases
5508
            foreach ($urlAliasService->listLocationAliases($location, false) as $alias) {
5509
                self::assertNotContains('eng-GB', $alias->languageCodes);
5510
            }
5511
5512
            // check custom URL aliases
5513
            foreach ($urlAliasService->listLocationAliases($location) as $alias) {
5514
                self::assertNotContains('eng-GB', $alias->languageCodes);
5515
            }
5516
        }
5517
    }
5518
5519
    /**
5520
     * Test removal of a main translation throws BadStateException.
5521
     *
5522
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5523
     */
5524
    public function testDeleteTranslationMainLanguageThrowsBadStateException()
5525
    {
5526
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
5527
        $this->expectExceptionMessage('Specified translation is the main translation of the Content Object');
5528
5529
        $repository = $this->getRepository();
5530
        $contentService = $repository->getContentService();
5531
        $content = $this->createContentVersion2();
5532
5533
        // delete first version which has only one translation
5534
        $contentService->deleteVersion($contentService->loadVersionInfo($content->contentInfo, 1));
5535
5536
        // try to delete main translation
5537
        $contentService->deleteTranslation($content->contentInfo, $content->contentInfo->mainLanguageCode);
5538
    }
5539
5540
    /**
5541
     * Test removal of a Translation is possible when some archived Versions have only this Translation.
5542
     *
5543
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5544
     */
5545
    public function testDeleteTranslationDeletesSingleTranslationVersions()
5546
    {
5547
        $repository = $this->getRepository();
5548
        $contentService = $repository->getContentService();
5549
        // content created by the createContentVersion1 method has eng-US translation only.
5550
        $content = $this->createContentVersion1();
5551
5552
        // create new version and add eng-GB translation
5553
        $contentDraft = $contentService->createContentDraft($content->contentInfo);
5554
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
5555
        $contentUpdateStruct->setField('name', 'Awesome Board', 'eng-GB');
5556
        $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
5557
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
5558
5559
        // update mainLanguageCode to avoid exception related to that
5560
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
5561
        $contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
5562
5563
        $content = $contentService->updateContentMetadata($publishedContent->contentInfo, $contentMetadataUpdateStruct);
5564
5565
        $contentService->deleteTranslation($content->contentInfo, 'eng-US');
5566
5567
        $this->assertTranslationDoesNotExist('eng-US', $content->id);
5568
    }
5569
5570
    /**
5571
     * Test removal of the translation by the user who is not allowed to delete a content
5572
     * throws UnauthorizedException.
5573
     *
5574
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5575
     */
5576
    public function testDeleteTranslationThrowsUnauthorizedException()
5577
    {
5578
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\UnauthorizedException::class);
5579
        $this->expectExceptionMessage('User does not have access to \'remove\' \'content\'');
5580
5581
        $repository = $this->getRepository();
5582
        $contentService = $repository->getContentService();
5583
5584
        $content = $this->createContentVersion2();
5585
5586
        // create user that can read/create/edit but cannot delete content
5587
        $this->createRoleWithPolicies('Writer', [
5588
            ['module' => 'content', 'function' => 'read'],
5589
            ['module' => 'content', 'function' => 'versionread'],
5590
            ['module' => 'content', 'function' => 'create'],
5591
            ['module' => 'content', 'function' => 'edit'],
5592
        ]);
5593
        $writerUser = $this->createCustomUserWithLogin(
5594
            'writer',
5595
            '[email protected]',
5596
            'Writers',
5597
            'Writer'
5598
        );
5599
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5600
        $contentService->deleteTranslation($content->contentInfo, 'eng-GB');
5601
    }
5602
5603
    /**
5604
     * Test removal of a non-existent translation throws InvalidArgumentException.
5605
     *
5606
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslation
5607
     */
5608 View Code Duplication
    public function testDeleteTranslationThrowsInvalidArgumentException()
5609
    {
5610
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
5611
        $this->expectExceptionMessage('Argument \'$languageCode\' is invalid: ger-DE does not exist in the Content item');
5612
5613
        $repository = $this->getRepository();
5614
        $contentService = $repository->getContentService();
5615
        // content created by the createContentVersion1 method has eng-US translation only.
5616
        $content = $this->createContentVersion1();
5617
        $contentService->deleteTranslation($content->contentInfo, 'ger-DE');
5618
    }
5619
5620
    /**
5621
     * Test deleting a Translation from Draft.
5622
     *
5623
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5624
     */
5625
    public function testDeleteTranslationFromDraft()
5626
    {
5627
        $repository = $this->getRepository();
5628
        $contentService = $repository->getContentService();
5629
5630
        $languageCode = 'eng-GB';
5631
        $content = $this->createMultipleLanguageContentVersion2();
5632
        $draft = $contentService->createContentDraft($content->contentInfo);
5633
        $draft = $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5634
        $content = $contentService->publishVersion($draft->versionInfo);
5635
5636
        $loadedContent = $contentService->loadContent($content->id);
5637
        self::assertNotContains($languageCode, $loadedContent->versionInfo->languageCodes);
5638
        self::assertEmpty($loadedContent->getFieldsByLanguage($languageCode));
5639
    }
5640
5641
    /**
5642
     * Get values for multilingual field.
5643
     *
5644
     * @return array
5645
     */
5646
    public function providerForDeleteTranslationFromDraftRemovesUrlAliasOnPublishing()
5647
    {
5648
        return [
5649
            [
5650
                ['eng-US' => 'US Name', 'eng-GB' => 'GB Name'],
5651
            ],
5652
            [
5653
                ['eng-US' => 'Same Name', 'eng-GB' => 'Same Name'],
5654
            ],
5655
        ];
5656
    }
5657
5658
    /**
5659
     * Test deleting a Translation from Draft removes previously stored URL aliases for published Content.
5660
     *
5661
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5662
     *
5663
     * @dataProvider providerForDeleteTranslationFromDraftRemovesUrlAliasOnPublishing
5664
     *
5665
     * @param string[] $fieldValues translated field values
5666
     *
5667
     * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
5668
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
5669
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
5670
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
5671
     */
5672
    public function testDeleteTranslationFromDraftRemovesUrlAliasOnPublishing(array $fieldValues)
5673
    {
5674
        $repository = $this->getRepository();
5675
        $contentService = $repository->getContentService();
5676
        $locationService = $repository->getLocationService();
5677
        $urlAliasService = $repository->getURLAliasService();
5678
5679
        // set language code to be removed
5680
        $languageCode = 'eng-GB';
5681
        $draft = $this->createMultilingualContentDraft(
5682
            'folder',
5683
            2,
5684
            'eng-US',
5685
            [
5686
                'name' => [
5687
                    'eng-GB' => $fieldValues['eng-GB'],
5688
                    'eng-US' => $fieldValues['eng-US'],
5689
                ],
5690
            ]
5691
        );
5692
        $content = $contentService->publishVersion($draft->versionInfo);
5693
5694
        // create secondary location
5695
        $locationService->createLocation(
5696
            $content->contentInfo,
5697
            $locationService->newLocationCreateStruct(5)
5698
        );
5699
5700
        // sanity check
5701
        $locations = $locationService->loadLocations($content->contentInfo);
5702
        self::assertCount(2, $locations, 'Sanity check: Expected to find 2 Locations');
5703
        foreach ($locations as $location) {
5704
            $urlAliasService->createUrlAlias($location, '/us-custom_' . $location->id, 'eng-US');
5705
            $urlAliasService->createUrlAlias($location, '/gb-custom_' . $location->id, 'eng-GB');
5706
5707
            // check default URL aliases
5708
            $aliases = $urlAliasService->listLocationAliases($location, false, $languageCode);
5709
            self::assertNotEmpty($aliases, 'Sanity check: URL alias for the translation does not exist');
5710
5711
            // check custom URL aliases
5712
            $aliases = $urlAliasService->listLocationAliases($location, true, $languageCode);
5713
            self::assertNotEmpty($aliases, 'Sanity check: Custom URL alias for the translation does not exist');
5714
        }
5715
5716
        // delete translation and publish new version
5717
        $draft = $contentService->createContentDraft($content->contentInfo);
5718
        $draft = $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5719
        $contentService->publishVersion($draft->versionInfo);
5720
5721
        // check that aliases does not exist
5722
        foreach ($locations as $location) {
5723
            // check default URL aliases
5724
            $aliases = $urlAliasService->listLocationAliases($location, false, $languageCode);
5725
            self::assertEmpty($aliases, 'URL alias for the deleted translation still exists');
5726
5727
            // check custom URL aliases
5728
            $aliases = $urlAliasService->listLocationAliases($location, true, $languageCode);
5729
            self::assertEmpty($aliases, 'Custom URL alias for the deleted translation still exists');
5730
        }
5731
    }
5732
5733
    /**
5734
     * Test that URL aliases for deleted Translations are properly archived.
5735
     */
5736
    public function testDeleteTranslationFromDraftArchivesUrlAliasOnPublishing()
5737
    {
5738
        $repository = $this->getRepository();
5739
        $contentService = $repository->getContentService();
5740
        $urlAliasService = $repository->getURLAliasService();
5741
5742
        $content = $contentService->publishVersion(
5743
            $this->createMultilingualContentDraft(
5744
                'folder',
5745
                2,
5746
                'eng-US',
5747
                [
5748
                    'name' => [
5749
                        'eng-GB' => 'BritishEnglishContent',
5750
                        'eng-US' => 'AmericanEnglishContent',
5751
                    ],
5752
                ]
5753
            )->versionInfo
5754
        );
5755
5756
        $unrelatedContent = $contentService->publishVersion(
5757
            $this->createMultilingualContentDraft(
5758
                'folder',
5759
                2,
5760
                'eng-US',
5761
                [
5762
                    'name' => [
5763
                        'eng-GB' => 'AnotherBritishContent',
5764
                        'eng-US' => 'AnotherAmericanContent',
5765
                    ],
5766
                ]
5767
            )->versionInfo
5768
        );
5769
5770
        $urlAlias = $urlAliasService->lookup('/BritishEnglishContent');
5771
        self::assertFalse($urlAlias->isHistory);
5772
        self::assertEquals($urlAlias->path, '/BritishEnglishContent');
5773
        self::assertEquals($urlAlias->destination, $content->contentInfo->mainLocationId);
5774
5775
        $draft = $contentService->deleteTranslationFromDraft(
5776
            $contentService->createContentDraft($content->contentInfo)->versionInfo,
5777
            'eng-GB'
5778
        );
5779
        $content = $contentService->publishVersion($draft->versionInfo);
5780
5781
        $urlAlias = $urlAliasService->lookup('/BritishEnglishContent');
5782
        self::assertTrue($urlAlias->isHistory);
5783
        self::assertEquals($urlAlias->path, '/BritishEnglishContent');
5784
        self::assertEquals($urlAlias->destination, $content->contentInfo->mainLocationId);
5785
5786
        $unrelatedUrlAlias = $urlAliasService->lookup('/AnotherBritishContent');
5787
        self::assertFalse($unrelatedUrlAlias->isHistory);
5788
        self::assertEquals($unrelatedUrlAlias->path, '/AnotherBritishContent');
5789
        self::assertEquals($unrelatedUrlAlias->destination, $unrelatedContent->contentInfo->mainLocationId);
5790
    }
5791
5792
    /**
5793
     * Test deleting a Translation from Draft which has single Translation throws BadStateException.
5794
     *
5795
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5796
     */
5797
    public function testDeleteTranslationFromDraftThrowsBadStateExceptionOnSingleTranslation()
5798
    {
5799
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
5800
        $this->expectExceptionMessage('Specified Translation is the only one Content Object Version has');
5801
5802
        $repository = $this->getRepository();
5803
        $contentService = $repository->getContentService();
5804
5805
        // create Content with single Translation
5806
        $publishedContent = $contentService->publishVersion(
5807
            $this->createContentDraft(
5808
                'forum',
5809
                2,
5810
                ['name' => 'Eng-US Version name']
5811
            )->versionInfo
5812
        );
5813
5814
        // update mainLanguageCode to avoid exception related to trying to delete main Translation
5815
        $contentMetadataUpdateStruct = $contentService->newContentMetadataUpdateStruct();
5816
        $contentMetadataUpdateStruct->mainLanguageCode = 'eng-GB';
5817
        $publishedContent = $contentService->updateContentMetadata(
5818
            $publishedContent->contentInfo,
5819
            $contentMetadataUpdateStruct
5820
        );
5821
5822
        // create single Translation Version from the first one
5823
        $draft = $contentService->createContentDraft(
5824
            $publishedContent->contentInfo,
5825
            $publishedContent->versionInfo
5826
        );
5827
5828
        // attempt to delete Translation
5829
        $contentService->deleteTranslationFromDraft($draft->versionInfo, 'eng-US');
5830
    }
5831
5832
    /**
5833
     * Test deleting the Main Translation from Draft throws BadStateException.
5834
     *
5835
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5836
     */
5837
    public function testDeleteTranslationFromDraftThrowsBadStateExceptionOnMainTranslation()
5838
    {
5839
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
5840
        $this->expectExceptionMessage('Specified Translation is the main Translation of the Content Object');
5841
5842
        $repository = $this->getRepository();
5843
        $contentService = $repository->getContentService();
5844
5845
        $mainLanguageCode = 'eng-US';
5846
        $draft = $this->createMultilingualContentDraft(
5847
            'forum',
5848
            2,
5849
            $mainLanguageCode,
5850
            [
5851
                'name' => [
5852
                    'eng-US' => 'An awesome eng-US forum',
5853
                    'eng-GB' => 'An awesome eng-GB forum',
5854
                ],
5855
            ]
5856
        );
5857
        $contentService->deleteTranslationFromDraft($draft->versionInfo, $mainLanguageCode);
5858
    }
5859
5860
    /**
5861
     * Test deleting the Translation from Published Version throws BadStateException.
5862
     *
5863
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5864
     */
5865 View Code Duplication
    public function testDeleteTranslationFromDraftThrowsBadStateExceptionOnPublishedVersion()
5866
    {
5867
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\BadStateException::class);
5868
        $this->expectExceptionMessage('Version is not a draft');
5869
5870
        $repository = $this->getRepository();
5871
        $contentService = $repository->getContentService();
5872
5873
        $languageCode = 'eng-US';
5874
        $content = $this->createMultipleLanguageContentVersion2();
5875
        $draft = $contentService->createContentDraft($content->contentInfo);
5876
        $publishedContent = $contentService->publishVersion($draft->versionInfo);
5877
        $contentService->deleteTranslationFromDraft($publishedContent->versionInfo, $languageCode);
5878
    }
5879
5880
    /**
5881
     * Test deleting a Translation from Draft throws UnauthorizedException if user cannot edit Content.
5882
     *
5883
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5884
     */
5885
    public function testDeleteTranslationFromDraftThrowsUnauthorizedException()
5886
    {
5887
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\UnauthorizedException::class);
5888
        $this->expectExceptionMessage('User does not have access to \'edit\' \'content\'');
5889
5890
        $repository = $this->getRepository();
5891
        $contentService = $repository->getContentService();
5892
5893
        $languageCode = 'eng-GB';
5894
        $content = $this->createMultipleLanguageContentVersion2();
5895
        $draft = $contentService->createContentDraft($content->contentInfo);
5896
5897
        // create user that can read/create/delete but cannot edit or content
5898
        $this->createRoleWithPolicies('Writer', [
5899
            ['module' => 'content', 'function' => 'read'],
5900
            ['module' => 'content', 'function' => 'versionread'],
5901
            ['module' => 'content', 'function' => 'create'],
5902
            ['module' => 'content', 'function' => 'delete'],
5903
        ]);
5904
        $writerUser = $this->createCustomUserWithLogin(
5905
            'user',
5906
            '[email protected]',
5907
            'Writers',
5908
            'Writer'
5909
        );
5910
        $repository->getPermissionResolver()->setCurrentUserReference($writerUser);
5911
5912
        $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5913
    }
5914
5915
    /**
5916
     * Test deleting a non-existent Translation from Draft throws InvalidArgumentException.
5917
     *
5918
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteTranslationFromDraft
5919
     */
5920 View Code Duplication
    public function testDeleteTranslationFromDraftThrowsInvalidArgumentException()
5921
    {
5922
        $this->expectException(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException::class);
5923
        $this->expectExceptionMessageRegExp('/The Version \\(ContentId=\\d+, VersionNo=\\d+\\) is not translated into ger-DE/');
5924
5925
        $repository = $this->getRepository();
5926
        $contentService = $repository->getContentService();
5927
5928
        $languageCode = 'ger-DE';
5929
        $content = $this->createMultipleLanguageContentVersion2();
5930
        $draft = $contentService->createContentDraft($content->contentInfo);
5931
        $contentService->deleteTranslationFromDraft($draft->versionInfo, $languageCode);
5932
    }
5933
5934
    /**
5935
     * Test loading list of Content items.
5936
     */
5937
    public function testLoadContentListByContentInfo()
5938
    {
5939
        $repository = $this->getRepository();
5940
        $contentService = $repository->getContentService();
5941
        $locationService = $repository->getLocationService();
5942
5943
        $allLocationsCount = $locationService->getAllLocationsCount();
5944
        $contentInfoList = array_map(
5945
            function (Location $location) {
5946
                return $location->contentInfo;
5947
            },
5948
            $locationService->loadAllLocations(0, $allLocationsCount)
5949
        );
5950
5951
        $contentList = $contentService->loadContentListByContentInfo($contentInfoList);
5952
        self::assertCount(count($contentInfoList), $contentList);
5953
        foreach ($contentList as $content) {
5954
            try {
5955
                $loadedContent = $contentService->loadContent($content->id);
5956
                self::assertEquals($loadedContent, $content, "Failed to properly bulk-load Content {$content->id}");
5957
            } catch (NotFoundException $e) {
5958
                self::fail("Failed to load Content {$content->id}: {$e->getMessage()}");
5959
            } catch (UnauthorizedException $e) {
5960
                self::fail("Failed to load Content {$content->id}: {$e->getMessage()}");
5961
            }
5962
        }
5963
    }
5964
5965
    /**
5966
     * Test loading content versions after removing exactly two drafts.
5967
     *
5968
     * @see https://jira.ez.no/browse/EZP-30271
5969
     *
5970
     * @covers \eZ\Publish\Core\Repository\ContentService::deleteVersion
5971
     */
5972
    public function testLoadVersionsAfterDeletingTwoDrafts()
5973
    {
5974
        $repository = $this->getRepository();
5975
        $contentService = $repository->getContentService();
5976
5977
        $content = $this->createFolder(['eng-GB' => 'Foo'], 2);
5978
5979
        // First update and publish
5980
        $modifiedContent = $this->updateFolder($content, ['eng-GB' => 'Foo1']);
5981
        $content = $contentService->publishVersion($modifiedContent->versionInfo);
5982
5983
        // Second update and publish
5984
        $modifiedContent = $this->updateFolder($content, ['eng-GB' => 'Foo2']);
5985
        $content = $contentService->publishVersion($modifiedContent->versionInfo);
5986
5987
        // Create drafts
5988
        $this->updateFolder($content, ['eng-GB' => 'Foo3']);
5989
        $this->updateFolder($content, ['eng-GB' => 'Foo4']);
5990
5991
        $versions = $contentService->loadVersions($content->contentInfo);
5992
5993
        foreach ($versions as $key => $version) {
5994
            if ($version->isDraft()) {
5995
                $contentService->deleteVersion($version);
5996
                unset($versions[$key]);
5997
            }
5998
        }
5999
6000
        $this->assertEquals($versions, $contentService->loadVersions($content->contentInfo));
6001
    }
6002
6003
    /**
6004
     * Tests loading list of content versions of status draft.
6005
     */
6006
    public function testLoadVersionsOfStatusDraft()
6007
    {
6008
        $repository = $this->getRepository();
6009
6010
        $contentService = $repository->getContentService();
6011
6012
        $content = $this->createContentVersion1();
6013
6014
        $contentService->createContentDraft($content->contentInfo);
6015
        $contentService->createContentDraft($content->contentInfo);
6016
        $contentService->createContentDraft($content->contentInfo);
6017
6018
        $versions = $contentService->loadVersions($content->contentInfo, VersionInfo::STATUS_DRAFT);
6019
6020
        $this->assertSame(\count($versions), 3);
6021
    }
6022
6023
    /**
6024
     * Tests loading list of content versions of status archived.
6025
     */
6026
    public function testLoadVersionsOfStatusArchived()
6027
    {
6028
        $repository = $this->getRepository();
6029
6030
        $contentService = $repository->getContentService();
6031
6032
        $content = $this->createContentVersion1();
6033
6034
        $draft1 = $contentService->createContentDraft($content->contentInfo);
6035
        $contentService->publishVersion($draft1->versionInfo);
6036
6037
        $draft2 = $contentService->createContentDraft($content->contentInfo);
6038
        $contentService->publishVersion($draft2->versionInfo);
6039
6040
        $versions = $contentService->loadVersions($content->contentInfo, VersionInfo::STATUS_ARCHIVED);
6041
6042
        $this->assertSame(\count($versions), 2);
6043
    }
6044
6045
    /**
6046
     * Asserts that all aliases defined in $expectedAliasProperties with the
6047
     * given properties are available in $actualAliases and not more.
6048
     *
6049
     * @param array $expectedAliasProperties
6050
     * @param array $actualAliases
6051
     */
6052
    private function assertAliasesCorrect(array $expectedAliasProperties, array $actualAliases)
6053
    {
6054
        foreach ($actualAliases as $actualAlias) {
6055
            if (!isset($expectedAliasProperties[$actualAlias->path])) {
6056
                $this->fail(
6057
                    sprintf(
6058
                        'Alias with path "%s" in languages "%s" not expected.',
6059
                        $actualAlias->path,
6060
                        implode(', ', $actualAlias->languageCodes)
6061
                    )
6062
                );
6063
            }
6064
6065
            foreach ($expectedAliasProperties[$actualAlias->path] as $propertyName => $propertyValue) {
6066
                $this->assertEquals(
6067
                    $propertyValue,
6068
                    $actualAlias->$propertyName,
6069
                    sprintf(
6070
                        'Property $%s incorrect on alias with path "%s" in languages "%s".',
6071
                        $propertyName,
6072
                        $actualAlias->path,
6073
                        implode(', ', $actualAlias->languageCodes)
6074
                    )
6075
                );
6076
            }
6077
6078
            unset($expectedAliasProperties[$actualAlias->path]);
6079
        }
6080
6081
        if (!empty($expectedAliasProperties)) {
6082
            $this->fail(
6083
                sprintf(
6084
                    'Missing expected aliases with paths "%s".',
6085
                    implode('", "', array_keys($expectedAliasProperties))
6086
                )
6087
            );
6088
        }
6089
    }
6090
6091
    /**
6092
     * Asserts that the given fields are equal to the default fields fixture.
6093
     *
6094
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $fields
6095
     */
6096
    private function assertAllFieldsEquals(array $fields)
6097
    {
6098
        $actual = $this->normalizeFields($fields);
6099
        $expected = $this->normalizeFields($this->createFieldsFixture());
6100
6101
        $this->assertEquals($expected, $actual);
6102
    }
6103
6104
    /**
6105
     * Asserts that the given fields are equal to a language filtered set of the
6106
     * default fields fixture.
6107
     *
6108
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $fields
6109
     * @param string $languageCode
6110
     */
6111
    private function assertLocaleFieldsEquals(array $fields, $languageCode)
6112
    {
6113
        $actual = $this->normalizeFields($fields);
6114
6115
        $expected = array();
6116
        foreach ($this->normalizeFields($this->createFieldsFixture()) as $field) {
6117
            if ($field->languageCode !== $languageCode) {
6118
                continue;
6119
            }
6120
            $expected[] = $field;
6121
        }
6122
6123
        $this->assertEquals($expected, $actual);
6124
    }
6125
6126
    /**
6127
     * This method normalizes a set of fields and returns a normalized set.
6128
     *
6129
     * Normalization means it resets the storage specific field id to zero and
6130
     * it sorts the field by their identifier and their language code. In
6131
     * addition, the field value is removed, since this one depends on the
6132
     * specific FieldType, which is tested in a dedicated integration test.
6133
     *
6134
     * @param \eZ\Publish\API\Repository\Values\Content\Field[] $fields
6135
     *
6136
     * @return \eZ\Publish\API\Repository\Values\Content\Field[]
6137
     */
6138
    private function normalizeFields(array $fields)
6139
    {
6140
        $normalized = array();
6141 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...
6142
            $normalized[] = new Field(
6143
                array(
6144
                    'id' => 0,
6145
                    'value' => ($field->value !== null ? true : null),
6146
                    'languageCode' => $field->languageCode,
6147
                    'fieldDefIdentifier' => $field->fieldDefIdentifier,
6148
                    'fieldTypeIdentifier' => $field->fieldTypeIdentifier,
6149
                )
6150
            );
6151
        }
6152
        usort(
6153
            $normalized,
6154 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...
6155
                if (0 === ($return = strcasecmp($field1->fieldDefIdentifier, $field2->fieldDefIdentifier))) {
6156
                    return strcasecmp($field1->languageCode, $field2->languageCode);
6157
                }
6158
6159
                return $return;
6160
            }
6161
        );
6162
6163
        return $normalized;
6164
    }
6165
6166
    /**
6167
     * Returns a filtered set of the default fields fixture.
6168
     *
6169
     * @param string $languageCode
6170
     *
6171
     * @return \eZ\Publish\API\Repository\Values\Content\Field[]
6172
     */
6173
    private function createLocaleFieldsFixture($languageCode)
6174
    {
6175
        $fields = array();
6176
        foreach ($this->createFieldsFixture() as $field) {
6177
            if (null === $field->languageCode || $languageCode === $field->languageCode) {
6178
                $fields[] = $field;
6179
            }
6180
        }
6181
6182
        return $fields;
6183
    }
6184
6185
    /**
6186
     * Asserts that given Content has default ContentStates.
6187
     *
6188
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
6189
     */
6190 View Code Duplication
    private function assertDefaultContentStates(ContentInfo $contentInfo)
6191
    {
6192
        $repository = $this->getRepository();
6193
        $objectStateService = $repository->getObjectStateService();
6194
6195
        $objectStateGroups = $objectStateService->loadObjectStateGroups();
6196
6197
        foreach ($objectStateGroups as $objectStateGroup) {
6198
            $contentState = $objectStateService->getContentState($contentInfo, $objectStateGroup);
6199
            foreach ($objectStateService->loadObjectStates($objectStateGroup) as $objectState) {
6200
                // Only check the first object state which is the default one.
6201
                $this->assertEquals(
6202
                    $objectState,
6203
                    $contentState
6204
                );
6205
                break;
6206
            }
6207
        }
6208
    }
6209
6210
    /**
6211
     * Assert that given Content has no references to a translation specified by the $languageCode.
6212
     *
6213
     * @param string $languageCode
6214
     * @param int $contentId
6215
     */
6216
    private function assertTranslationDoesNotExist($languageCode, $contentId)
6217
    {
6218
        $repository = $this->getRepository();
6219
        $contentService = $repository->getContentService();
6220
6221
        $content = $contentService->loadContent($contentId);
6222
6223
        foreach ($content->fields as $fieldIdentifier => $field) {
6224
            /** @var array $field */
6225
            self::assertArrayNotHasKey($languageCode, $field);
6226
            self::assertNotEquals($languageCode, $content->contentInfo->mainLanguageCode);
6227
            self::assertArrayNotHasKey($languageCode, $content->versionInfo->getNames());
6228
            self::assertNotEquals($languageCode, $content->versionInfo->initialLanguageCode);
6229
            self::assertNotContains($languageCode, $content->versionInfo->languageCodes);
6230
        }
6231
        foreach ($contentService->loadVersions($content->contentInfo) as $versionInfo) {
6232
            self::assertArrayNotHasKey($languageCode, $versionInfo->getNames());
6233
            self::assertNotEquals($languageCode, $versionInfo->contentInfo->mainLanguageCode);
6234
            self::assertNotEquals($languageCode, $versionInfo->initialLanguageCode);
6235
            self::assertNotContains($languageCode, $versionInfo->languageCodes);
6236
        }
6237
    }
6238
6239
    /**
6240
     * Returns the default fixture of fields used in most tests.
6241
     *
6242
     * @return \eZ\Publish\API\Repository\Values\Content\Field[]
6243
     */
6244
    private function createFieldsFixture()
6245
    {
6246
        return array(
6247
            new Field(
6248
                array(
6249
                    'id' => 0,
6250
                    'value' => 'Foo',
6251
                    'languageCode' => 'eng-US',
6252
                    'fieldDefIdentifier' => 'description',
6253
                    'fieldTypeIdentifier' => 'ezrichtext',
6254
                )
6255
            ),
6256
            new Field(
6257
                array(
6258
                    'id' => 0,
6259
                    'value' => 'Bar',
6260
                    'languageCode' => 'eng-GB',
6261
                    'fieldDefIdentifier' => 'description',
6262
                    'fieldTypeIdentifier' => 'ezrichtext',
6263
                )
6264
            ),
6265
            new Field(
6266
                array(
6267
                    'id' => 0,
6268
                    'value' => 'An awesome multi-lang forum²',
6269
                    'languageCode' => 'eng-US',
6270
                    'fieldDefIdentifier' => 'name',
6271
                    'fieldTypeIdentifier' => 'ezstring',
6272
                )
6273
            ),
6274
            new Field(
6275
                array(
6276
                    'id' => 0,
6277
                    'value' => 'An awesome multi-lang forum²³',
6278
                    'languageCode' => 'eng-GB',
6279
                    'fieldDefIdentifier' => 'name',
6280
                    'fieldTypeIdentifier' => 'ezstring',
6281
                )
6282
            ),
6283
        );
6284
    }
6285
6286
    /**
6287
     * Gets expected property values for the "Media" ContentInfo ValueObject.
6288
     *
6289
     * @return array
6290
     */
6291 View Code Duplication
    private function getExpectedMediaContentInfoProperties()
6292
    {
6293
        return [
6294
            'id' => 41,
6295
            'contentTypeId' => 1,
6296
            'name' => 'Media',
6297
            'sectionId' => 3,
6298
            'currentVersionNo' => 1,
6299
            'published' => true,
6300
            'ownerId' => 14,
6301
            'modificationDate' => $this->createDateTime(1060695457),
6302
            'publishedDate' => $this->createDateTime(1060695457),
6303
            'alwaysAvailable' => 1,
6304
            'remoteId' => 'a6e35cbcb7cd6ae4b691f3eee30cd262',
6305
            'mainLanguageCode' => 'eng-US',
6306
            'mainLocationId' => 43,
6307
            'status' => ContentInfo::STATUS_PUBLISHED,
6308
        ];
6309
    }
6310
6311
    /**
6312
     * @covers \eZ\Publish\API\Repository\ContentService::hideContent
6313
     *
6314
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
6315
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
6316
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
6317
     */
6318
    public function testHideContent(): void
6319
    {
6320
        $repository = $this->getRepository();
6321
        $contentTypeService = $repository->getContentTypeService();
6322
        $contentService = $repository->getContentService();
6323
        $locationService = $repository->getLocationService();
6324
6325
        $locationCreateStructs = array_map(
6326
            function (Location $parentLocation) use ($locationService) {
6327
                return $locationService->newLocationCreateStruct($parentLocation->id);
6328
            },
6329
            $this->createParentLocationsForHideReveal($locationService, 2)
6330
        );
6331
6332
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6333
6334
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6335
        $contentCreate->setField('name', 'Folder to hide');
6336
6337
        $content = $contentService->createContent(
6338
            $contentCreate,
6339
            $locationCreateStructs
6340
        );
6341
6342
        $publishedContent = $contentService->publishVersion($content->versionInfo);
6343
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6344
6345
        // Sanity check
6346
        $this->assertCount(3, $locations);
6347
        $this->assertCount(0, $this->filterHiddenLocations($locations));
6348
6349
        /* BEGIN: Use Case */
6350
        $contentService->hideContent($publishedContent->contentInfo);
6351
        /* END: Use Case */
6352
6353
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6354
        $this->assertCount(3, $locations);
6355
        $this->assertCount(3, $this->filterHiddenLocations($locations));
6356
    }
6357
6358
    /**
6359
     * @covers \eZ\Publish\API\Repository\ContentService::revealContent
6360
     *
6361
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
6362
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
6363
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
6364
     */
6365
    public function testRevealContent()
6366
    {
6367
        $repository = $this->getRepository();
6368
        $contentTypeService = $repository->getContentTypeService();
6369
        $contentService = $repository->getContentService();
6370
        $locationService = $repository->getLocationService();
6371
6372
        $locationCreateStructs = array_map(
6373
            function (Location $parentLocation) use ($locationService) {
6374
                return $locationService->newLocationCreateStruct($parentLocation->id);
6375
            },
6376
            $this->createParentLocationsForHideReveal($locationService, 2)
6377
        );
6378
6379
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6380
6381
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6382
        $contentCreate->setField('name', 'Folder to hide');
6383
6384
        $locationCreateStructs[0]->hidden = true;
6385
6386
        $content = $contentService->createContent(
6387
            $contentCreate,
6388
            $locationCreateStructs
6389
        );
6390
6391
        $publishedContent = $contentService->publishVersion($content->versionInfo);
6392
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6393
6394
        // Sanity check
6395
        $hiddenLocations = $this->filterHiddenLocations($locations);
6396
        $this->assertCount(3, $locations);
6397
        $this->assertCount(1, $hiddenLocations);
6398
6399
        // BEGIN: Use Case
6400
        $contentService->hideContent($publishedContent->contentInfo);
6401
        $this->assertCount(
6402
            3,
6403
            $this->filterHiddenLocations(
6404
                $locationService->loadLocations($publishedContent->contentInfo)
6405
            )
6406
        );
6407
6408
        $contentService->revealContent($publishedContent->contentInfo);
6409
        // END: Use Case
6410
6411
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6412
        $hiddenLocationsAfterReveal = $this->filterHiddenLocations($locations);
6413
        $this->assertCount(3, $locations);
6414
        $this->assertCount(1, $hiddenLocationsAfterReveal);
6415
        $this->assertEquals($hiddenLocations, $hiddenLocationsAfterReveal);
6416
    }
6417
6418
    /**
6419
     * @depends testRevealContent
6420
     */
6421
    public function testRevealContentWithHiddenParent()
6422
    {
6423
        $repository = $this->getRepository();
6424
6425
        $contentTypeService = $repository->getContentTypeService();
6426
        $contentService = $repository->getContentService();
6427
        $locationService = $repository->getLocationService();
6428
6429
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6430
6431
        $contentNames = [
6432
            'Parent Content',
6433
            'Child (Nesting 1)',
6434
            'Child (Nesting 2)',
6435
            'Child (Nesting 3)',
6436
            'Child (Nesting 4)',
6437
        ];
6438
6439
        $parentLocation = $locationService->newLocationCreateStruct(
6440
            $this->generateId('location', 2)
6441
        );
6442
6443
        /** @var Content[] $contents */
6444
        $contents = [];
6445
6446 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...
6447
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6448
            $contentCreate->setField('name', $contentName);
6449
6450
            $content = $contentService->createContent($contentCreate, [$parentLocation]);
6451
            $contents[] = $publishedContent = $contentService->publishVersion($content->versionInfo);
6452
6453
            $parentLocation = $locationService->newLocationCreateStruct(
6454
                $this->generateId('location', $publishedContent->contentInfo->mainLocationId)
6455
            );
6456
        }
6457
6458
        $contentService->hideContent($contents[0]->contentInfo);
6459
        $contentService->hideContent($contents[2]->contentInfo);
6460
        $contentService->revealContent($contents[2]->contentInfo);
6461
6462
        $parentContent = $contentService->loadContent($contents[0]->id);
6463
        $parentLocation = $locationService->loadLocation($parentContent->contentInfo->mainLocationId);
6464
        $parentSublocations = $locationService->loadLocationList([
6465
            $contents[1]->contentInfo->mainLocationId,
6466
            $contents[2]->contentInfo->mainLocationId,
6467
            $contents[3]->contentInfo->mainLocationId,
6468
            $contents[4]->contentInfo->mainLocationId,
6469
        ]);
6470
6471
        // Parent remains invisible
6472
        self::assertTrue($parentLocation->invisible);
6473
6474
        // All parent sublocations remain invisible as well
6475
        foreach ($parentSublocations as $parentSublocation) {
6476
            self::assertTrue($parentSublocation->invisible);
6477
        }
6478
    }
6479
6480
    /**
6481
     * @depends testRevealContent
6482
     */
6483
    public function testRevealContentWithHiddenChildren()
6484
    {
6485
        $repository = $this->getRepository();
6486
6487
        $contentTypeService = $repository->getContentTypeService();
6488
        $contentService = $repository->getContentService();
6489
        $locationService = $repository->getLocationService();
6490
6491
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6492
6493
        $contentNames = [
6494
            'Parent Content',
6495
            'Child (Nesting 1)',
6496
            'Child (Nesting 2)',
6497
            'Child (Nesting 3)',
6498
            'Child (Nesting 4)',
6499
        ];
6500
6501
        $parentLocation = $locationService->newLocationCreateStruct(
6502
            $this->generateId('location', 2)
6503
        );
6504
6505
        /** @var Content[] $contents */
6506
        $contents = [];
6507
6508 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...
6509
            $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6510
            $contentCreate->setField('name', $contentName);
6511
6512
            $content = $contentService->createContent($contentCreate, [$parentLocation]);
6513
            $contents[] = $publishedContent = $contentService->publishVersion($content->versionInfo);
6514
6515
            $parentLocation = $locationService->newLocationCreateStruct(
6516
                $this->generateId('location', $publishedContent->contentInfo->mainLocationId)
6517
            );
6518
        }
6519
6520
        $contentService->hideContent($contents[0]->contentInfo);
6521
        $contentService->hideContent($contents[2]->contentInfo);
6522
        $contentService->revealContent($contents[0]->contentInfo);
6523
6524
        $directChildContent = $contentService->loadContent($contents[1]->id);
6525
        $directChildLocation = $locationService->loadLocation($directChildContent->contentInfo->mainLocationId);
6526
6527
        $childContent = $contentService->loadContent($contents[2]->id);
6528
        $childLocation = $locationService->loadLocation($childContent->contentInfo->mainLocationId);
6529
        $childSublocations = $locationService->loadLocationList([
6530
            $contents[3]->contentInfo->mainLocationId,
6531
            $contents[4]->contentInfo->mainLocationId,
6532
        ]);
6533
6534
        // Direct child content is not hidden
6535
        self::assertFalse($directChildContent->contentInfo->isHidden);
6536
6537
        // Direct child content location is still invisible
6538
        self::assertFalse($directChildLocation->invisible);
6539
6540
        // Child content is still hidden
6541
        self::assertTrue($childContent->contentInfo->isHidden);
6542
6543
        // Child content location is still invisible
6544
        self::assertTrue($childLocation->invisible);
6545
6546
        // All childs sublocations remain invisible as well
6547
        foreach ($childSublocations as $childSublocation) {
6548
            self::assertTrue($childSublocation->invisible);
6549
        }
6550
    }
6551
6552
    public function testHideContentWithParentLocation()
6553
    {
6554
        $repository = $this->getRepository();
6555
        $contentTypeService = $repository->getContentTypeService();
6556
6557
        $contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
6558
6559
        $contentService = $repository->getContentService();
6560
        $locationService = $repository->getLocationService();
6561
6562
        $contentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6563
        $contentCreate->setField('name', 'Parent');
6564
6565
        $content = $contentService->createContent(
6566
            $contentCreate,
6567
            [
6568
                $locationService->newLocationCreateStruct(
6569
                    $this->generateId('location', 2)
6570
                ),
6571
            ]
6572
        );
6573
6574
        $publishedContent = $contentService->publishVersion($content->versionInfo);
6575
6576
        /* BEGIN: Use Case */
6577
        $contentService->hideContent($publishedContent->contentInfo);
6578
        /* END: Use Case */
6579
6580
        $locations = $locationService->loadLocations($publishedContent->contentInfo);
6581
6582
        $childContentCreate = $contentService->newContentCreateStruct($contentType, 'eng-US');
6583
        $childContentCreate->setField('name', 'Child');
6584
6585
        $childContent = $contentService->createContent(
6586
            $childContentCreate,
6587
            [
6588
                $locationService->newLocationCreateStruct(
6589
                    $locations[0]->id
6590
                ),
6591
            ]
6592
        );
6593
6594
        $publishedChildContent = $contentService->publishVersion($childContent->versionInfo);
6595
6596
        $childLocations = $locationService->loadLocations($publishedChildContent->contentInfo);
6597
6598
        $this->assertTrue($locations[0]->hidden);
6599
        $this->assertTrue($locations[0]->invisible);
6600
6601
        $this->assertFalse($childLocations[0]->hidden);
6602
        $this->assertTrue($childLocations[0]->invisible);
6603
    }
6604
6605
    public function testChangeContentName()
6606
    {
6607
        $repository = $this->getRepository();
6608
6609
        $contentService = $repository->getContentService();
6610
        $contentDraft = $this->createContentDraft(
6611
            'folder',
6612
            $this->generateId('location', 2),
6613
            [
6614
                'name' => 'Marco',
6615
            ]
6616
        );
6617
6618
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
6619
        $contentMetadataUpdateStruct = new ContentMetadataUpdateStruct([
6620
            'name' => 'Polo',
6621
        ]);
6622
        $contentService->updateContentMetadata($publishedContent->contentInfo, $contentMetadataUpdateStruct);
6623
6624
        $updatedContent = $contentService->loadContent($publishedContent->id);
6625
6626
        $this->assertEquals('Marco', $publishedContent->contentInfo->name);
6627
        $this->assertEquals('Polo', $updatedContent->contentInfo->name);
6628
    }
6629
6630
    public function testCopyTranslationsFromPublishedToDraft()
6631
    {
6632
        $repository = $this->getRepository();
6633
6634
        $contentService = $repository->getContentService();
6635
6636
        $contentDraft = $this->createContentDraft(
6637
            'folder',
6638
            $this->generateId('location', 2),
6639
            [
6640
                'name' => 'Folder US',
6641
            ]
6642
        );
6643
6644
        $publishedContent = $contentService->publishVersion($contentDraft->versionInfo);
6645
6646
        $deDraft = $contentService->createContentDraft($publishedContent->contentInfo);
6647
6648
        $contentUpdateStruct = new ContentUpdateStruct([
6649
            'initialLanguageCode' => 'ger-DE',
6650
            'fields' => $contentDraft->getFields(),
6651
        ]);
6652
6653
        $contentUpdateStruct->setField('name', 'Folder GER', 'ger-DE');
6654
6655
        $deContent = $contentService->updateContent($deDraft->versionInfo, $contentUpdateStruct);
6656
6657
        $updatedContent = $contentService->loadContent($deContent->id, null, $deContent->versionInfo->versionNo);
6658
        $this->assertEquals(
6659
            [
6660
                'eng-US' => 'Folder US',
6661
                'ger-DE' => 'Folder GER',
6662
            ],
6663
            $updatedContent->fields['name']
6664
        );
6665
6666
        $gbDraft = $contentService->createContentDraft($publishedContent->contentInfo);
6667
6668
        $contentUpdateStruct = new ContentUpdateStruct([
6669
            'initialLanguageCode' => 'eng-GB',
6670
            'fields' => $contentDraft->getFields(),
6671
        ]);
6672
6673
        $contentUpdateStruct->setField('name', 'Folder GB', 'eng-GB');
6674
6675
        $gbContent = $contentService->updateContent($gbDraft->versionInfo, $contentUpdateStruct);
6676
        $contentService->publishVersion($gbDraft->versionInfo);
6677
        $updatedContent = $contentService->loadContent($gbContent->id, null, $gbContent->versionInfo->versionNo);
6678
        $this->assertEquals(
6679
            [
6680
                'eng-US' => 'Folder US',
6681
                'eng-GB' => 'Folder GB',
6682
            ],
6683
            $updatedContent->fields['name']
6684
        );
6685
6686
        $dePublished = $contentService->publishVersion($deDraft->versionInfo);
6687
        $this->assertEquals(
6688
            [
6689
                'eng-US' => 'Folder US',
6690
                'ger-DE' => 'Folder GER',
6691
                'eng-GB' => 'Folder GB',
6692
            ],
6693
            $dePublished->fields['name']
6694
        );
6695
    }
6696
6697
    /**
6698
     * Create structure of parent folders with Locations to be used for Content hide/reveal tests.
6699
     *
6700
     * @param \eZ\Publish\API\Repository\LocationService $locationService
6701
     * @param int $parentLocationId
6702
     *
6703
     * @return \eZ\Publish\API\Repository\Values\Content\Location[] A list of Locations aimed to be parents
6704
     *
6705
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
6706
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
6707
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
6708
     */
6709
    private function createParentLocationsForHideReveal(LocationService $locationService, int $parentLocationId): array
6710
    {
6711
        $parentFoldersLocationsIds = [
6712
            $this->createFolder(['eng-US' => 'P1'], $parentLocationId)->contentInfo->mainLocationId,
6713
            $this->createFolder(['eng-US' => 'P2'], $parentLocationId)->contentInfo->mainLocationId,
6714
            $this->createFolder(['eng-US' => 'P3'], $parentLocationId)->contentInfo->mainLocationId,
6715
        ];
6716
6717
        return array_values($locationService->loadLocationList($parentFoldersLocationsIds));
6718
    }
6719
6720
    /**
6721
     * Filter Locations list by hidden only.
6722
     *
6723
     * @param \eZ\Publish\API\Repository\Values\Content\Location[] $locations
6724
     *
6725
     * @return array
6726
     */
6727
    private function filterHiddenLocations(array $locations): array
6728
    {
6729
        return array_values(
6730
            array_filter(
6731
                $locations,
6732
                function (Location $location) {
6733
                    return $location->hidden;
6734
                }
6735
            )
6736
        );
6737
    }
6738
6739
    public function testPublishVersionWithSelectedLanguages()
6740
    {
6741
        $repository = $this->getRepository();
6742
6743
        $contentService = $repository->getContentService();
6744
6745
        $publishedContent = $this->createFolder(
6746
            [
6747
                'eng-US' => 'Published US',
6748
                'ger-DE' => 'Published DE',
6749
            ],
6750
            $this->generateId('location', 2)
6751
        );
6752
6753
        $draft = $contentService->createContentDraft($publishedContent->contentInfo);
6754
        $contentUpdateStruct = new ContentUpdateStruct([
6755
            'initialLanguageCode' => 'eng-US',
6756
        ]);
6757
        $contentUpdateStruct->setField('name', 'Draft 1 US', 'eng-US');
6758
        $contentUpdateStruct->setField('name', 'Draft 1 DE', 'ger-DE');
6759
6760
        $contentService->updateContent($draft->versionInfo, $contentUpdateStruct);
6761
6762
        $contentService->publishVersion($draft->versionInfo, ['ger-DE']);
6763
        $content = $contentService->loadContent($draft->contentInfo->id);
6764
        $this->assertEquals(
6765
            [
6766
                'eng-US' => 'Published US',
6767
                'ger-DE' => 'Draft 1 DE',
6768
            ],
6769
            $content->fields['name']
6770
        );
6771
    }
6772
}
6773