Completed
Push — symfony3-wololo ( 50a832...8a87df )
by Kamil
18:56
created

SetupCommand::getAdministratorPassword()   B

Complexity

Conditions 4
Paths 2

Size

Total Lines 37
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 37
rs 8.5806
c 1
b 0
f 0
cc 4
eloc 22
nc 2
nop 2
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Bundle\CoreBundle\Command;
13
14
use Sylius\Component\Core\Model\AdminUserInterface;
15
use Sylius\Component\Core\Model\ChannelInterface;
16
use Sylius\Component\Currency\Model\CurrencyInterface;
17
use Sylius\Component\Locale\Model\LocaleInterface;
18
use Symfony\Component\Console\Helper\QuestionHelper;
19
use Symfony\Component\Console\Input\InputInterface;
20
use Symfony\Component\Console\Output\OutputInterface;
21
use Symfony\Component\Console\Question\Question;
22
use Symfony\Component\Intl\Intl;
23
use Symfony\Component\Validator\Constraints\Email;
24
use Symfony\Component\Validator\Constraints\NotBlank;
25
use Symfony\Component\Validator\ConstraintViolationListInterface;
26
27
/**
28
 * @author Paweł Jędrzejewski <[email protected]>
29
 */
30
final class SetupCommand extends AbstractInstallCommand
31
{
32
    /**
33
     * @var CurrencyInterface
34
     */
35
    private $currency;
36
37
    /**
38
     * @var LocaleInterface
39
     */
40
    private $locale;
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    protected function configure()
46
    {
47
        $this
48
            ->setName('sylius:install:setup')
49
            ->setDescription('Sylius configuration setup.')
50
            ->setHelp(<<<EOT
51
The <info>%command.name%</info> command allows user to configure basic Sylius data.
52
EOT
53
            )
54
        ;
55
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60
    protected function execute(InputInterface $input, OutputInterface $output)
61
    {
62
        $this->setupCurrency($input, $output);
63
        $this->setupLocale($input, $output);
64
        $this->setupChannel();
65
        $this->setupAdministratorUser($input, $output);
66
    }
67
68
    /**
69
     * @param InputInterface $input
70
     * @param OutputInterface $output
71
     *
72
     * @return int
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
73
     */
74
    protected function setupAdministratorUser(InputInterface $input, OutputInterface $output)
75
    {
76
        /** @var QuestionHelper $questionHelper */
77
        $questionHelper = $this->getHelper('question');
78
79
        $output->writeln('Create your administrator account.');
80
81
        $userManager = $this->get('sylius.manager.admin_user');
82
        $userRepository = $this->get('sylius.repository.admin_user');
83
        $userFactory = $this->get('sylius.factory.admin_user');
84
85
        /** @var AdminUserInterface $user */
86
        $user = $userFactory->createNew();
87
88
        if ($input->getOption('no-interaction')) {
89
            $exists = null !== $userRepository->findOneByEmail('[email protected]');
90
91
            if ($exists) {
92
                return 0;
93
            }
94
95
            $user->setEmail('[email protected]');
96
            $user->setPlainPassword('sylius');
97
        } else {
98
            do {
99
                $question = new Question('E-mail: ');
100
                $question->setValidator(function ($value) use ($output) {
101
                    /** @var ConstraintViolationListInterface $errors */
102
                    $errors = $this->get('validator')->validate((string) $value, [new Email(), new NotBlank()]);
103
                    foreach ($errors as $error) {
104
                        $output->writeln(sprintf('<error>%s</error>', $error->getMessage()));
105
                    }
106
107
                    return count($errors) === 0;
108
                });
109
                $email = $questionHelper->ask($input, $output, $question);
110
                $exists = null !== $userRepository->findOneByEmail($email);
111
112
                if ($exists) {
113
                    $output->writeln('<error>E-Mail is already in use!</error>');
114
                }
115
            } while ($exists);
116
117
            $user->setEmail($email);
118
            $user->setPlainPassword($this->getAdministratorPassword($input, $output));
119
        }
120
121
        $user->setEnabled(true);
122
        $user->setLocaleCode($this->locale->getCode());
123
124
        $userManager->persist($user);
125
        $userManager->flush();
126
        $output->writeln('Administrator account successfully registered.');
127
    }
128
129
    /**
130
     * @param InputInterface  $input
131
     * @param OutputInterface $output
132
     */
133
    protected function setupLocale(InputInterface $input, OutputInterface $output)
0 ignored issues
show
Unused Code introduced by
The parameter $input 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...
134
    {
135
        $localeRepository = $this->get('sylius.repository.locale');
136
        $localeManager = $this->get('sylius.manager.locale');
137
        $localeFactory = $this->get('sylius.factory.locale');
138
139
        $code = trim($this->getContainer()->getParameter('locale'));
140
        $name = Intl::getLanguageBundle()->getLanguageName($code);
141
        $output->writeln(sprintf('Adding <info>%s</info> locale.', $name));
142
143
        if (null !== $existingLocale = $localeRepository->findOneBy(['code' => $code])) {
144
            $this->locale = $existingLocale;
145
146
            return;
147
        }
148
149
        $locale = $localeFactory->createNew();
150
        $locale->setCode($code);
151
152
        $localeManager->persist($locale);
153
        $localeManager->flush();
154
155
        $this->locale = $locale;
156
    }
157
158
    /**
159
     * @param InputInterface  $input
160
     * @param OutputInterface $output
161
     */
162
    protected function setupCurrency(InputInterface $input, OutputInterface $output)
0 ignored issues
show
Unused Code introduced by
The parameter $input 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...
163
    {
164
        $currencyRepository = $this->get('sylius.repository.currency');
165
        $currencyManager = $this->get('sylius.manager.currency');
166
        $currencyFactory = $this->get('sylius.factory.currency');
167
168
        $code = trim($this->getContainer()->getParameter('currency'));
169
        $name = Intl::getCurrencyBundle()->getCurrencyName($code);
170
        $output->writeln(sprintf('Adding <info>%s</info> currency.', $name));
171
172
        if (null !== $existingCurrency = $currencyRepository->findOneBy(['code' => $code])) {
173
            $this->currency = $existingCurrency;
174
175
            return;
176
        }
177
178
        $currency = $currencyFactory->createNew();
179
        $currency->setExchangeRate(1.00);
180
        $currency->setCode($code);
181
182
        $currencyManager->persist($currency);
183
        $currencyManager->flush();
184
185
        $this->currency = $currency;
186
    }
187
188
    protected function setupChannel()
189
    {
190
        $channelRepository = $this->get('sylius.repository.channel');
191
        $channelManager = $this->get('sylius.manager.channel');
192
        $channelFactory = $this->get('sylius.factory.channel');
193
194
        /** @var ChannelInterface $channel */
195
        $channel = $channelRepository->findOneBy([]);
196
197
        if (null === $channel) {
198
            $channel = $channelFactory->createNew();
199
            $channel->setCode('default');
200
            $channel->setName('Default');
201
            $channel->setTaxCalculationStrategy('order_items_based');
202
203
            $channelManager->persist($channel);
204
        }
205
206
        $channel->addCurrency($this->currency);
207
        $channel->addLocale($this->locale);
208
        $channel->setBaseCurrency($this->currency);
209
        $channel->setDefaultLocale($this->locale);
210
211
        $channelManager->flush();
212
    }
213
214
    /**
215
     * @param InputInterface $input
216
     * @param OutputInterface $output
217
     *
218
     * @return mixed
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use string.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
219
     */
220
    private function getAdministratorPassword(InputInterface $input, OutputInterface $output)
221
    {
222
        /** @var QuestionHelper $questionHelper */
223
        $questionHelper = $this->getHelper('question');
224
225
        $validator = function ($value) use ($output) {
226
            /** @var ConstraintViolationListInterface $errors */
227
            $errors = $this->get('validator')->validate($value, [new NotBlank()]);
228
            foreach ($errors as $error) {
229
                $output->writeln(sprintf('<error>%s</error>', $error->getMessage()));
230
            }
231
232
            return count($errors) === 0;
233
        };
234
235
        do {
236
            $passwordQuestion = (new Question('Choose password: '))
237
                ->setValidator($validator)
238
                ->setHidden(true)
239
                ->setHiddenFallback(false)
240
            ;
241
            $confirmPasswordQuestion = (new Question('Confirm password: '))
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $confirmPasswordQuestion exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
242
                ->setValidator($validator)
243
                ->setHidden(true)
244
                ->setHiddenFallback(false)
245
            ;
246
247
            $password = $questionHelper->ask($input, $output, $passwordQuestion);
248
            $repeatedPassword = $questionHelper->ask($input, $output, $confirmPasswordQuestion);
249
250
            if ($repeatedPassword !== $password) {
251
                $output->writeln('<error>Passwords do not match!</error>');
252
            }
253
        } while ($repeatedPassword !== $password);
254
255
        return $password;
256
    }
257
}
258