Completed
Push — 6.13 ( 254dd2...055733 )
by André
13:14
created

sions()   B

Complexity

Conditions 7
Paths 3

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 11
nc 3
nop 2
dl 0
loc 21
rs 7.551
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the eZ Publish Kernel package.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Bundle\EzPublishCoreBundle\Command;
10
11
use eZ\Publish\API\Repository\Repository;
12
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
13
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException;
14
use Symfony\Component\Console\Command\Command;
15
use Symfony\Component\Console\Input\InputArgument;
16
use Symfony\Component\Console\Input\InputInterface;
17
use Symfony\Component\Console\Input\InputOption;
18
use Symfony\Component\Console\Output\OutputInterface;
19
use Symfony\Component\Console\Question\ChoiceQuestion;
20
use Symfony\Component\Console\Question\ConfirmationQuestion;
21
use Exception;
22
23
/**
24
 * Console Command which deletes a given Translation from all the Versions of a given Content Item.
25
 */
26
class DeleteContentTranslationCommand extends Command
27
{
28
    /**
29
     * @var \eZ\Publish\API\Repository\Repository
30
     */
31
    private $repository;
32
33
    /**
34
     * @var \eZ\Publish\API\Repository\ContentService
35
     */
36
    private $contentService;
37
38
    /**
39
     * @var \Symfony\Component\Console\Input\InputInterface
40
     */
41
    private $input;
42
43
    /**
44
     * @var \Symfony\Component\Console\Output\OutputInterface
45
     */
46
    private $output;
47
48
    /**
49
     * @var \Symfony\Component\Console\Helper\QuestionHelper
50
     */
51
    private $questionHelper;
52
53
    public function __construct(Repository $repository)
54
    {
55
        parent::__construct(null);
56
        $this->repository = $repository;
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    protected function configure()
63
    {
64
        $this
65
            ->setName('ezplatform:delete-content-translation')
66
            ->addArgument('content-id', InputArgument::REQUIRED, 'Content Object Id')
67
            ->addArgument(
68
                'language-code',
69
                InputArgument::REQUIRED,
70
                'Language code of the Translation to be deleted'
71
            )
72
            ->addOption(
73
                'user',
74
                'u',
75
                InputOption::VALUE_OPTIONAL,
76
                'eZ Platform username (with Role containing at least Content policies: read, versionread, edit, remove, versionremove)',
77
                'admin'
78
            )
79
            ->setDescription('Delete Translation from all the Versions of a Content Item');
80
    }
81
82
    protected function initialize(InputInterface $input, OutputInterface $output)
83
    {
84
        parent::initialize($input, $output);
85
        $this->input = $input;
86
        $this->output = $output;
87
        $this->questionHelper = $this->getHelper('question');
88
        $this->contentService = $this->repository->getContentService();
89
90
        $this->repository->getPermissionResolver()->setCurrentUserReference(
91
            $this->repository->getUserService()->loadUserByLogin($input->getOption('user'))
92
        );
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    protected function execute(InputInterface $input, OutputInterface $output)
99
    {
100
        $contentId = (int) ($input->getArgument('content-id'));
101
        $languageCode = $input->getArgument('language-code');
102
103
        if ($contentId === 0) {
104
            throw new InvalidArgumentException(
105
                'content-id',
106
                'Content Object Id has to be an integer'
107
            );
108
        }
109
110
        $this->output->writeln(
111
            '<comment>**NOTE**: Make sure to run this command using the same SYMFONY_ENV setting as your eZ Platform installation does</comment>'
112
        );
113
114
        $versionInfo = $this->contentService->loadVersionInfoById($contentId);
115
        $contentInfo = $versionInfo->contentInfo;
116
117
        $this->repository->beginTransaction();
118
        try {
119
            if ($contentInfo->mainLanguageCode === $languageCode) {
120
                $contentInfo = $this->promptUserForMainLanguageChange(
121
                    $contentInfo,
122
                    $languageCode,
123
                    // allow to change Main Translation to only those existing in the last Version
124
                    $versionInfo->languageCodes
125
                );
126
            }
127
128
            // Confirm operation
129
            $contentName = "#{$contentInfo->id} ($contentInfo->name)";
130
            $question = new ConfirmationQuestion(
131
                "Are you sure you want to delete {$languageCode} Translation from the Content {$contentName}? This operation is permanent. [y/N] ",
132
                false
133
            );
134
            if (!$this->questionHelper->ask($this->input, $this->output, $question)) {
135
                // Rollback any cleanup change (see above)
136
                $this->repository->rollback();
137
                $this->output->writeln('Reverting and aborting.');
138
139
                return;
140
            }
141
142
            // Delete Translation
143
            $output->writeln(
144
                "<info>Deleting {$languageCode} Translation of the Content {$contentName}</info>"
145
            );
146
            $this->contentService->deleteTranslation($contentInfo, $languageCode);
147
148
            $output->writeln('<info>Translation deleted</info>');
149
150
            $this->repository->commit();
151
        } catch (Exception $e) {
152
            $this->repository->rollback();
153
            throw $e;
154
        }
155
    }
156
157
    /**
158
     * Interact with user to update main Language of a Content Object.
159
     *
160
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
161
     * @param string $languageCode language code of the Translation to be deleted
162
     * @param string[] $lastVersionLanguageCodes all Translations last Version has.
163
     *
164
     * @return \eZ\Publish\API\Repository\Values\Content\ContentInfo
165
     */
166
    private function promptUserForMainLanguageChange(
167
        ContentInfo $contentInfo,
168
        $languageCode,
169
        array $lastVersionLanguageCodes
170
    ) {
171
        $contentName = "#{$contentInfo->id} ($contentInfo->name)";
172
        $this->output->writeln(
173
            "<comment>The specified Translation '{$languageCode}' is the Main Translation of the Content {$contentName}. It needs to be changed before removal.</comment>"
174
        );
175
176
        // get main Translation candidates w/o Translation being removed
177
        $mainTranslationCandidates = array_filter(
178
            $lastVersionLanguageCodes,
179
            function ($versionLanguageCode) use ($languageCode) {
180
                return $versionLanguageCode !== $languageCode;
181
            }
182
        );
183
        if (empty($mainTranslationCandidates)) {
184
            throw new InvalidArgumentException(
185
                'language-code',
186
                "The last Version of the Content {$contentName} has no other Translations beside the main one"
187
            );
188
        }
189
        $question = new ChoiceQuestion(
190
            "Set the Main Translation of the Content {$contentName} to:",
191
            array_values($mainTranslationCandidates)
192
        );
193
194
        $newMainLanguageCode = $this->questionHelper->ask($this->input, $this->output, $question);
195
        $this->output->writeln(
196
            "<info>Updating Main Translation of the Content {$contentName} to {$newMainLanguageCode}</info>"
197
        );
198
199
        $contentMetadataUpdateStruct = $this->contentService->newContentMetadataUpdateStruct();
200
        $contentMetadataUpdateStruct->mainLanguageCode = $newMainLanguageCode;
201
202
        return $this->contentService->updateContentMetadata(
203
            $contentInfo,
204
            $contentMetadataUpdateStruct
205
        )->contentInfo;
206
    }
207
}
208