Issues (3627)

bundles/CoreBundle/Command/ApplyUpdatesCommand.php (1 issue)

1
<?php
2
3
/*
4
 * @copyright   2014 Mautic Contributors. All rights reserved
5
 * @author      Mautic
6
 *
7
 * @link        http://mautic.org
8
 *
9
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
10
 */
11
12
namespace Mautic\CoreBundle\Command;
13
14
use Mautic\CoreBundle\Exception\UpdateFailedException;
15
use Mautic\CoreBundle\Helper\CoreParametersHelper;
16
use Mautic\CoreBundle\Helper\ProgressBarHelper;
17
use Mautic\CoreBundle\Update\StepProvider;
18
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
19
use Symfony\Component\Console\Helper\ProgressBar;
20
use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
21
use Symfony\Component\Console\Input\InputInterface;
22
use Symfony\Component\Console\Input\InputOption;
23
use Symfony\Component\Console\Output\OutputInterface;
24
use Symfony\Component\Console\Question\ConfirmationQuestion;
25
use Symfony\Component\Translation\TranslatorInterface;
26
27
/**
28
 * CLI Command to update the application.
29
 */
30
class ApplyUpdatesCommand extends ContainerAwareCommand
31
{
32
    /**
33
     * @var TranslatorInterface
34
     */
35
    private $translator;
36
37
    /**
38
     * @var CoreParametersHelper
39
     */
40
    private $coreParametersHelper;
41
42
    /**
43
     * @var StepProvider
44
     */
45
    private $stepProvider;
46
47
    /**
48
     * @var InputInterface
49
     */
50
    private $input;
51
52
    /**
53
     * @var OutputInterface
54
     */
55
    private $output;
56
57
    /**
58
     * @var ProgressBar
59
     */
60
    private $progressBar;
61
62
    public function __construct(TranslatorInterface $translator, CoreParametersHelper $coreParametersHelper, StepProvider $stepProvider)
63
    {
64
        parent::__construct();
65
66
        $this->translator           = $translator;
67
        $this->coreParametersHelper = $coreParametersHelper;
68
        $this->stepProvider         = $stepProvider;
69
    }
70
71
    protected function configure()
72
    {
73
        $this->setName('mautic:update:apply')
74
            ->setDescription('Updates the Mautic application')
75
            ->setDefinition(
76
                [
77
                    new InputOption(
78
                        'force', null, InputOption::VALUE_NONE,
79
                        'Bypasses the verification check.'
80
                    ),
81
                    new InputOption(
82
                        'update-package',
83
                        'p', InputOption::VALUE_OPTIONAL, 'Optional full path to the update package to apply.'
84
                    ),
85
                    new InputOption(
86
                        'finish', null, InputOption::VALUE_NONE,
87
                        'Finalize the upgrade.'
88
                    ),
89
                ]
90
            )
91
            ->setHelp(
92
                <<<'EOT'
93
                The <info>%command.name%</info> command updates the Mautic application.
94
95
<info>php %command.full_name%</info>
96
97
You can optionally specify to bypass the verification check with the --force option:
98
99
<info>php %command.full_name% --force</info>
100
101
To force install a local package, pass the full path to the package as follows:
102
103
<info>php %command.full_name% --update-package=/path/to/updatepackage.zip</info>
104
EOT
105
            );
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     */
111
    protected function execute(InputInterface $input, OutputInterface $output)
112
    {
113
        $this->input  = $input;
114
        $this->output = $output;
115
116
        $options = $input->getOptions();
117
118
        // Set the locale for the translator
119
        $this->translator->setLocale($this->coreParametersHelper->get('locale'));
120
121
        // Start a progress bar, don't give a max number of steps because it is conditional
122
        $this->progressBar = ProgressBarHelper::init($this->output);
123
        $this->progressBar->setFormat('Step %current% [%bar%] <info>%message%</info>');
124
125
        // Define this just in case
126
        defined('MAUTIC_ENV') or define('MAUTIC_ENV', (isset($options['env'])) ? $options['env'] : 'prod');
127
128
        try {
129
            if (empty($options['finish'])) {
130
                $returnCode = $this->startUpgrade();
131
132
                $output->writeln(
133
                    "\n\n<warning>".$this->translator->trans('mautic.core.command.update.finalize_instructions').'</warning>'
134
                );
135
136
                // Must hard exit here to prevent Symfony from trying to use the kernel while in the same PHP process
137
                exit($returnCode);
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
138
            }
139
140
            return $this->finishUpgrade();
141
        } catch (UpdateFailedException $exception) {
142
            $output->writeln(
143
                "\n\n<error>".$exception->getMessage().'</error>'
144
            );
145
        }
146
147
        return 1;
148
    }
149
150
    /**
151
     * @throws UpdateFailedException
152
     */
153
    private function startUpgrade(): int
154
    {
155
        if (!$this->input->getOption('force')) {
156
            /** @var SymfonyQuestionHelper $helper */
157
            $helper   = $this->getHelperSet()->get('question');
158
            $question = new ConfirmationQuestion($this->translator->trans('mautic.core.update.confirm_application_update').' ', false);
159
160
            if (!$helper->ask($this->input, $this->output, $question)) {
161
                throw new UpdateFailedException($this->translator->trans('mautic.core.update.aborted'));
162
            }
163
        }
164
165
        foreach ($this->stepProvider->getInitialSteps() as $step) {
166
            $step->execute($this->progressBar, $this->input, $this->output);
167
        }
168
169
        return 0;
170
    }
171
172
    /**
173
     * @throws UpdateFailedException
174
     */
175
    private function finishUpgrade(): int
176
    {
177
        foreach ($this->stepProvider->getFinalSteps() as $step) {
178
            $step->execute($this->progressBar, $this->input, $this->output);
179
        }
180
181
        return 0;
182
    }
183
}
184