Completed
Push — develop ( e4a933...b1fd58 )
by Tom
03:38
created

RunCommand::printException()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
3
namespace N98\Magento\Command\System\Setup;
4
5
use Exception;
6
use N98\Magento\Command\AbstractMagentoCommand;
7
use Symfony\Component\Console\Input\InputInterface;
8
use Symfony\Component\Console\Input\InputOption;
9
use Symfony\Component\Console\Input\StringInput;
10
use Symfony\Component\Console\Output\NullOutput;
11
use Symfony\Component\Console\Output\OutputInterface;
12
13
class RunCommand extends AbstractMagentoCommand
14
{
15
    protected function configure()
16
    {
17
        $this
18
            ->setName('sys:setup:run')
19
            ->addOption(
20
                '--no-implicit-cache-flush',
21
                null,
22
                InputOption::VALUE_NONE,
23
                'Do not flush the cache'
24
            )
25
            ->setDescription('Runs all new setup scripts.');
26
        $help = <<<HELP
27
Runs all setup scripts (no need to call frontend).
28
This command is useful if you update your system with enabled maintenance mode.
29
HELP;
30
        $this->setHelp($help);
31
    }
32
33
    /**
34
     * @param InputInterface $input
35
     * @param OutputInterface $output
36
     * @return int|null
37
     */
38
    protected function execute(InputInterface $input, OutputInterface $output)
39
    {
40
        $this->detectMagento($output);
41
        if (!$this->initMagento()) {
42
            return;
43
        }
44
45
        try {
46
            if (false === $input->getOption('no-implicit-cache-flush')) {
47
                $this->flushCache();
48
            }
49
50
            /**
51
             * Put output in buffer. \Mage_Core_Model_Resource_Setup::_modifyResourceDb should print any error
52
             * directly to stdout. Use exception which will be thrown to show error
53
             */
54
            \ob_start();
55
            \Mage_Core_Model_Resource_Setup::applyAllUpdates();
56
            if (is_callable(array('\Mage_Core_Model_Resource_Setup', 'applyAllDataUpdates'))) {
57
                \Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
58
            }
59
            \ob_end_clean();
60
            $output->writeln('<info>done</info>');
61
        } catch (Exception $e) {
62
            \ob_end_clean();
63
            $this->getApplication()->renderException($e, $output);
64
            $this->printStackTrace($output, $e);
65
            $this->printFile($output, $e);
66
67
            return 1; // exit with error status
68
        }
69
    }
70
71
    /**
72
     * @param OutputInterface $output
73
     * @param Exception $e
74
     *
75
     * @return void
76
     */
77
    protected function printStackTrace(OutputInterface $output, Exception $e)
78
    {
79
        $rootFolder = $this->getApplication()->getMagentoRootFolder();
80
        $trace = array_filter($e->getTrace(), function (&$row) use ($rootFolder) {
81
            if (!strstr($row['file'], $rootFolder)) {
82
                return false;
83
            }
84
85
            $row['file'] = ltrim(str_replace($rootFolder, '', $row['file']), '/');
86
87
            return $row;
88
        });
89
90
        $table = $this->getHelper('table');
91
        $rows = array();
92
        $i = 1;
93
        foreach ($trace as $row) {
94
            $rows[] = array(
95
                $i++,
96
                $row['file'] . ':' . $row['line'],
97
                $row['class'] . '::' . $row['function'],
98
            );
99
        }
100
        $table->setHeaders(array('#', 'File/Line', 'Method'));
101
        $table->setRows($rows);
102
        $table->render($output);
103
    }
104
105
    /**
106
     * @param OutputInterface $output
107
     * @param Exception $e
108
     */
109
    protected function printFile(OutputInterface $output, Exception $e)
110
    {
111
        if (preg_match('/Error\sin\sfile\:\s"(.+)\"\s-/', $e->getMessage(), $matches)) {
112
            $table = $this->getHelper('table');
113
            $lines = \file($matches[1]);
114
            $rows = array();
115
            $i = 0;
116
            foreach ($lines as $line) {
117
                $rows[] = array(++$i, rtrim($line));
118
            }
119
            $table->setHeaders(array('Line', 'Code'));
120
            $table->setRows($rows);
121
            $table->render($output);
122
        }
123
    }
124
125
    private function flushCache()
126
    {
127
        /**
128
         * Get events before cache flush command is called.
129
         */
130
        $reflectionApp = new \ReflectionObject(\Mage::app());
131
        $appEventReflectionProperty = $reflectionApp->getProperty('_events');
132
        $appEventReflectionProperty->setAccessible(true);
133
        $eventsBeforeCacheFlush = $appEventReflectionProperty->getValue(\Mage::app());
134
135
        $application = $this->getApplication();
136
        $application->setAutoExit(false);
137
        $application->run(new StringInput('cache:flush'), new NullOutput());
138
        $application->setAutoExit(true);
139
140
        /**
141
         * Restore initially loaded events which was reset during setup script run
142
         */
143
        $appEventReflectionProperty->setValue(\Mage::app(), $eventsBeforeCacheFlush);
144
    }
145
}
146