Completed
Push — master ( 59db0f...abafe8 )
by Kamil
18:55
created

SetupCommand::setupCurrency()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 40
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 40
rs 8.5806
cc 4
eloc 24
nc 4
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\InstallerBundle\Command;
13
14
use Symfony\Component\Console\Input\InputInterface;
15
use Symfony\Component\Console\Output\OutputInterface;
16
use Symfony\Component\Intl\Intl;
17
use Symfony\Component\Validator\Constraints\Currency;
18
use Symfony\Component\Validator\Constraints\Email;
19
use Symfony\Component\Validator\Constraints\NotBlank;
20
21
/**
22
 * @author Paweł Jędrzejewski <[email protected]>
23
 */
24
class SetupCommand extends AbstractInstallCommand
25
{
26
    /**
27
     * @var Currency
28
     */
29
    private $currency;
30
31
    /**
32
     * {@inheritdoc}
33
     */
34
    protected function configure()
35
    {
36
        $this
37
            ->setName('sylius:install:setup')
38
            ->setDescription('Sylius configuration setup.')
39
            ->setHelp(<<<EOT
40
The <info>%command.name%</info> command allows user to configure basic Sylius data.
41
EOT
42
            )
43
        ;
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49
    protected function execute(InputInterface $input, OutputInterface $output)
50
    {
51
        $this->setupCurrency($input, $output);
52
        $this->setupChannel();
53
        $this->setupAdministratorUser($input, $output);
54
    }
55
56
    /**
57
     * @param InputInterface $input
58
     * @param OutputInterface $output
59
     *
60
     * @return int
61
     */
62
    protected function setupAdministratorUser(InputInterface $input, OutputInterface $output)
63
    {
64
        $output->writeln('Create your administrator account.');
65
66
        $userManager = $this->get('sylius.manager.user');
67
        $userRepository = $this->get('sylius.repository.user');
68
        $userFactory = $this->get('sylius.factory.user');
69
        $customerFactory = $this->get('sylius.factory.customer');
70
71
        $rbacInitializer = $this->get('sylius.rbac.initializer');
72
        $rbacInitializer->initialize();
73
74
        $user = $userFactory->createNew();
75
        $customer = $customerFactory->createNew();
76
        $user->setCustomer($customer);
77
78
        if ($input->getOption('no-interaction')) {
79
            $exists = null !== $userRepository->findOneByEmail('[email protected]');
80
81
            if ($exists) {
82
                return 0;
83
            }
84
85
            $customer->setFirstname('Sylius');
86
            $customer->setLastname('Admin');
87
            $user->setEmail('[email protected]');
88
            $user->setPlainPassword('sylius');
89
        } else {
90
            $customer->setFirstname($this->ask($output, 'Your firstname:', [new NotBlank()]));
91
            $customer->setLastname($this->ask($output, 'Lastname:', [new NotBlank()]));
92
93
            do {
94
                $email = $this->ask($output, 'E-Mail:', [new NotBlank(), new Email()]);
95
                $exists = null !== $userRepository->findOneByEmail($email);
96
97
                if ($exists) {
98
                    $output->writeln('<error>E-Mail is already in use!</error>');
99
                }
100
            } while ($exists);
101
102
            $user->setEmail($email);
103
            $user->setPlainPassword($this->getAdministratorPassword($output));
104
        }
105
106
        $user->setEnabled(true);
107
        $user->addAuthorizationRole($this->get('sylius.repository.role')->findOneBy(['code' => 'administrator']));
108
109
        $userManager->persist($user);
110
        $userManager->flush();
111
        $output->writeln('Administrator account successfully registered.');
112
    }
113
114
    /**
115
     * @param InputInterface  $input
116
     * @param OutputInterface $output
117
     */
118
    protected function setupCurrency(InputInterface $input, OutputInterface $output)
119
    {
120
        $currencyRepository = $this->get('sylius.repository.currency');
121
        $currencyManager = $this->get('sylius.manager.currency');
122
        $currencyFactory = $this->get('sylius.factory.currency');
123
124
        do {
125
            $code = $this->getCurrencyCode($input, $output);
126
127
            $valid = true;
128
129
            if (0 !== count($errors = $this->validate(trim($code), [new Currency()]))) {
130
                $valid = false;
131
            }
132
133
134
                $this->writeErrors($output, $errors);
135
        } while (!$valid);
136
137
        $code = trim($code);
138
        $name = Intl::getCurrencyBundle()->getCurrencyName($code);
139
        $output->writeln(sprintf('Adding <info>%s</info>', $name));
140
141
        if (null !== $existingCurrency = $currencyRepository->findOneBy(['code' => $code])) {
142
            $this->currency = $existingCurrency;
143
144
            return;
145
        }
146
147
        $currency = $currencyFactory->createNew();
148
149
        $currency->setExchangeRate(1);
150
        $currency->setBase(true);
151
        $currency->setCode($code);
152
153
        $this->currency = $currency;
154
155
        $currencyManager->persist($currency);
156
        $currencyManager->flush();
157
    }
158
159
    protected function setupChannel()
160
    {
161
        $channelRepository = $this->get('sylius.repository.channel');
162
        $channelManager = $this->get('sylius.manager.channel');
163
        $channelFactory = $this->get('sylius.factory.channel');
164
165
        $channel = $channelRepository->findOneByCode('DEFAULT');
166
167
        if (null !== $channel) {
168
            return;
169
        }
170
171
        $channel = $channelFactory->createNew();
172
        $channel->setCode('DEFAULT');
173
        $channel->setName('DEFAULT');
174
        $channel->setDefaultCurrency($this->currency);
175
176
        $channelManager->persist($channel);
177
        $channelManager->flush();
178
    }
179
180
    /**
181
     * @param InputInterface  $input
182
     * @param OutputInterface $output
183
     *
184
     * @return array
185
     */
186
    private function getCurrencyCode(InputInterface $input, OutputInterface $output)
187
    {
188
        return $this->getCode(
189
            $input,
190
            $output,
191
            'In which currency can your customers buy goods?',
192
            'Please enter a currency code (For example "GBP") or press ENTER to use "USD".',
193
            'USD'
194
        );
195
    }
196
197
    /**
198
     * @param InputInterface  $input
199
     * @param OutputInterface $output
200
     * @param string          $question
201
     * @param string          $description
202
     * @param string          $defaultAnswer
203
     *
204
     * @return array
205
     */
206
    private function getCode(InputInterface $input, OutputInterface $output, $question, $description, $defaultAnswer)
207
    {
208
        if ($input->getOption('no-interaction')) {
209
            return [$defaultAnswer];
210
        }
211
212
        $output->writeln($description);
213
        $code = $this->ask($output, '<question>'.$question.'</question> ', [], $defaultAnswer);
214
215
        return $code;
216
    }
217
218
    /**
219
     * @param OutputInterface $output
220
     *
221
     * @return mixed
222
     */
223
    private function getAdministratorPassword(OutputInterface $output)
224
    {
225
        do {
226
            $password = $this->askHidden($output, 'Choose password:', [new NotBlank()]);
227
            $repeatedPassword = $this->askHidden($output, 'Confirm password:', [new NotBlank()]);
228
229
            if ($repeatedPassword !== $password) {
230
                $output->writeln('<error>Passwords do not match!</error>');
231
            }
232
        } while ($repeatedPassword !== $password);
233
234
        return $password;
235
    }
236
}
237