MageApplication::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 13
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 20
ccs 14
cts 14
cp 1
crap 1
rs 9.8333
1
<?php
2
3
/*
4
 * This file is part of the Magallanes package.
5
 *
6
 * (c) Andrés Montañez <[email protected]>
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 Mage;
13
14
use Mage\Command\AbstractCommand;
15
use Mage\Runtime\Runtime;
16
use Symfony\Component\Finder\Finder;
17
use Symfony\Component\Finder\SplFileInfo;
18
use Monolog\Logger;
19
use Monolog\Handler\StreamHandler;
20
use Symfony\Component\EventDispatcher\EventDispatcher;
21
use Symfony\Component\Console\Event\ConsoleErrorEvent;
22
use Symfony\Component\Console\ConsoleEvents;
23
use Symfony\Component\Console\Application;
24
use Symfony\Component\Yaml\Parser;
25
use Symfony\Component\Yaml\Exception\ParseException;
26
use Mage\Runtime\Exception\RuntimeException;
27
use Symfony\Component\Filesystem\Filesystem;
28
29
/**
30
 * The Console Application for launching the Mage command in a standalone instance
31
 *
32
 * @author Andrés Montañez <[email protected]>
33
 */
34
class MageApplication extends Application
35
{
36
    protected Runtime $runtime;
37
    protected string $file;
38
39
    /**
40
     * @param string $file The YAML file from which to read the configuration
41
     */
42 63
    public function __construct(string $file)
43
    {
44 63
        parent::__construct('Magallanes', Mage::VERSION);
45
46 63
        $this->file = $file;
47 63
        $dispatcher = new EventDispatcher();
48 63
        $this->setDispatcher($dispatcher);
49
50 63
        $dispatcher->addListener(ConsoleEvents::ERROR, function (ConsoleErrorEvent $event) {
51 1
            $output = $event->getOutput();
52 1
            $command = $event->getCommand();
53 1
            $output->writeln(
54 1
                sprintf('Oops, exception thrown while running command <info>%s</info>', $command->getName())
55
            );
56 1
            $exitCode = $event->getExitCode();
57 1
            $event->setError(new \LogicException('Caught exception', $exitCode, $event->getError()));
58
        });
59
60 63
        $this->runtime = $this->instantiateRuntime();
61 63
        $this->loadBuiltInCommands();
62
    }
63
64
    /**
65
     * Configure the Magallanes Application
66
     *
67
     * @throws RuntimeException
68
     */
69 60
    public function configure(): void
70
    {
71 60
        if (!file_exists($this->file) || !is_readable($this->file)) {
72 1
            throw new RuntimeException(sprintf('The file "%s" does not exists or is not readable.', $this->file));
73
        }
74
75
        try {
76 59
            $parser = new Parser();
77 59
            $config = $parser->parse(file_get_contents($this->file));
78 1
        } catch (ParseException $exception) {
79 1
            throw new RuntimeException(sprintf('Error parsing the file "%s".', $this->file));
80
        }
81
82 58
        if (array_key_exists('magephp', $config) && is_array($config['magephp'])) {
83 57
            $logger = null;
84
            if (
85 57
                array_key_exists('log_dir', $config['magephp']) &&
86 57
                file_exists($config['magephp']['log_dir']) && is_dir($config['magephp']['log_dir'])
87
            ) {
88 52
                $logfile = sprintf('%s/%s.log', $config['magephp']['log_dir'], date('Ymd_His'));
89 52
                $config['magephp']['log_file'] = $logfile;
90
91 52
                $logger = new Logger('magephp');
92 52
                $logger->pushHandler(new StreamHandler($logfile));
93
94 52
                $logLimit = isset($config['magephp']['log_limit']) ? intval($config['magephp']['log_limit']) : 30;
95 52
                $this->clearOldLogs($config['magephp']['log_dir'], $logLimit);
96 5
            } elseif (array_key_exists('log_dir', $config['magephp']) && !is_dir($config['magephp']['log_dir'])) {
97 1
                throw new RuntimeException(
98 1
                    sprintf(
99
                        'The configured log_dir "%s" does not exists or is not a directory.',
100 1
                        $config['magephp']['log_dir']
101
                    )
102
                );
103
            }
104
105 56
            $this->runtime->setConfiguration($config['magephp']);
106 56
            $this->runtime->setLogger($logger);
107 56
            return;
108
        }
109
110 1
        throw new RuntimeException(
111 1
            sprintf('The file "%s" does not have a valid Magallanes configuration.', $this->file)
112
        );
113
    }
114
115 52
    protected function clearOldLogs(string $logDir, int $logLimit): void
116
    {
117 52
        $filesystem = new Filesystem();
118 52
        $finder = new Finder();
119
120
        $finder
121 52
            ->files()
122 52
            ->followLinks()
123 52
            ->in($logDir)
124 52
            ->name('*.log')
125 52
            ->sortByModifiedTime()
126 52
            ->reverseSorting();
127
128 52
        $logs = iterator_to_array($finder);
129 52
        $logsToRemove = array_slice($logs, $logLimit - 1);
130 52
        $filesystem->remove($logsToRemove);
131
    }
132
133
    /**
134
     * Loads the BuiltIn Commands
135
     */
136 63
    protected function loadBuiltInCommands(): void
137
    {
138 63
        $finder = new Finder();
139 63
        $finder->files()->in(__DIR__ . '/Command/BuiltIn')->name('*Command.php');
140
141
        /** @var SplFileInfo $file */
142 63
        foreach ($finder as $file) {
143 63
            $class = substr('\\Mage\\Command\\BuiltIn\\' . str_replace('/', '\\', $file->getRelativePathname()), 0, -4);
144 63
            if (class_exists($class)) {
145 63
                $reflex = new \ReflectionClass($class);
146 63
                if ($reflex->isInstantiable()) {
147 63
                    $command = new $class();
148 63
                    if ($command instanceof AbstractCommand) {
149 63
                        $command->setRuntime($this->runtime);
150 63
                        $this->add($command);
151
                    }
152
                }
153
            }
154
        }
155
    }
156
157
    /**
158
     * Gets the Runtime instance to use
159
     */
160 5
    protected function instantiateRuntime(): Runtime
161
    {
162 5
        return new Runtime();
163
    }
164
165
    /**
166
     * Get the Runtime instance
167
     */
168 34
    public function getRuntime(): Runtime
169
    {
170 34
        return $this->runtime;
171
    }
172
}
173