Completed
Push — master ( 74371a...6da8c0 )
by Vladimir
02:21
created

Application::makeCacheDir()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
3
/**
4
 * @copyright 2017 Vladimir Jimenez
5
 * @license   https://github.com/allejo/stakx/blob/master/LICENSE.md MIT
6
 */
7
8
namespace allejo\stakx\Core;
9
10
use allejo\stakx\Configuration;
11
use allejo\stakx\DataTransformer\DataTransformer;
12
use allejo\stakx\DependencyInjection\Compiler\DataTransformerPass;
13
use allejo\stakx\Filesystem\FilesystemPath;
14
use allejo\stakx\Templating\Twig\Extension\TwigFilterInterface;
15
use allejo\stakx\Templating\Twig\Extension\TwigFunctionInterface;
16
use Symfony\Component\Config\FileLocator;
17
use Symfony\Component\Console\Application as BaseApplication;
18
use Symfony\Component\Console\Input\ArgvInput;
19
use Symfony\Component\Console\Input\InputInterface;
20
use Symfony\Component\Console\Output\OutputInterface;
21
use Symfony\Component\DependencyInjection\Container;
22
use Symfony\Component\DependencyInjection\ContainerBuilder;
23
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
24
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
25
use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
26
27
/**
28
 * The base application class for stakx.
29
 */
30
class Application extends BaseApplication
31
{
32
    /** @var bool */
33
    private $safeMode;
34
    /** @var bool */
35
    private $useCache;
36
    /** @var Container */
37
    private $container;
38
39
    /**
40
     * {@inheritdoc}
41
     */
42
    public function run(InputInterface $input = null, OutputInterface $output = null)
43
    {
44
        $input = new ArgvInput();
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $input. This often makes code more readable.
Loading history...
45
        $this->handleApplicationFlags($input);
46
47
        $this->loadContainer([
48
            'parameters' => [
49
                'root_dir' => __DIR__ . '/../',
50
            ],
51
        ]);
52
53
        $output = $this->getContainer()->get('output');
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $output. This often makes code more readable.
Loading history...
54
55
        if (extension_loaded('xdebug') && !getenv('STAKX_DISABLE_XDEBUG_WARN'))
56
        {
57
            $output->writeln('<fg=black;bg=yellow>You are running Stakx with xdebug enabled. This has a major impact on runtime performance.</>');
58
        }
59
60
        return parent::run($input, $output);
61
    }
62
63
    ///
64
    // Application Settings
65
    ///
66
67
    /**
68
     * Get whether or not the application is being run in safe mode.
69
     *
70
     * @return bool
71
     */
72
    public function inSafeMode()
73
    {
74
        return (bool)$this->safeMode;
75
    }
76
77
    /**
78
     * Set safe mode for the application.
79
     *
80
     * @param bool $safeMode
81
     */
82
    public function setSafeMode($safeMode)
83
    {
84
        $this->safeMode = $safeMode;
85
    }
86
87
    /**
88
     * Get whether or not to look for and use the application cache.
89
     *
90
     * @return bool
91
     */
92
    public function useCache()
93
    {
94
        return (bool)$this->useCache;
95
    }
96
97
    /**
98
     * Set whether or not to use an existing cache.
99
     *
100
     * @param bool $useCache
101
     */
102
    public function setUseCache($useCache)
103
    {
104
        $this->useCache = $useCache;
105
    }
106
107
    /**
108
     * Handle application wide flags.
109
     *
110
     * @param InputInterface $input
111
     */
112
    private function handleApplicationFlags(InputInterface $input)
113
    {
114
        $this->setUseCache($input->hasParameterOption('--use-cache'));
115
        $this->setSafeMode($input->hasParameterOption('--safe'));
116
    }
117
118
    ///
119
    // Container Settings
120
    ///
121
122
    /**
123
     * Get the Service container.
124
     *
125
     * @return Container
126
     */
127
    public function getContainer()
128
    {
129
        return $this->container;
130
    }
131
132
    /**
133
     * Load the cached application container or build a new one.
134
     *
135
     * @param array $containerOptions
136
     */
137
    private function loadContainer(array $containerOptions)
138
    {
139
        $cachedContainerPath = new FilesystemPath(getcwd() . '/' . Configuration::CACHE_FOLDER . '/container-cache.php');
140
141
        if (!$this->useCache() || !file_exists($cachedContainerPath))
142
        {
143
            $this->makeCacheDir();
144
            $this->buildContainer($cachedContainerPath, $containerOptions);
145
        }
146
147
        require $cachedContainerPath;
148
149
        $this->container = new \ProjectServiceContainer();
150
    }
151
152
    /**
153
     * Build and compile the application container.
154
     *
155
     * @param string $cachePath
156
     * @param array  $containerOptions
157
     */
158
    private function buildContainer($cachePath, array $containerOptions)
159
    {
160
        $container = new ContainerBuilder();
161
162
        foreach ($containerOptions['parameters'] as $key => $value)
163
        {
164
            $container->setParameter($key, $value);
165
        }
166
167
        $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../app/'));
168
        $loader->load('services.yml');
169
170
        $container
171
            ->registerForAutoconfiguration(DataTransformer::class)
172
            ->addTag(DataTransformer::CONTAINER_TAG)
173
        ;
174
175
        $container
176
            ->registerForAutoconfiguration(TwigFilterInterface::class)
177
            ->addTag(TwigFilterInterface::CONTAINER_TAG)
178
        ;
179
180
        $container
181
            ->registerForAutoconfiguration(TwigFunctionInterface::class)
182
            ->addTag(TwigFunctionInterface::CONTAINER_TAG)
183
        ;
184
185
        $container->compile();
186
        $dumper = new PhpDumper($container);
187
188
        file_put_contents($cachePath, $dumper->dump());
189
    }
190
191
    /**
192
     * Create a cache directory if it doesn't exist.
193
     */
194
    private function makeCacheDir()
195
    {
196
        $cachedFolder = new FilesystemPath(getcwd() . '/' . Configuration::CACHE_FOLDER);
197
198
        if (!file_exists($cachedFolder))
199
        {
200
            mkdir($cachedFolder);
201
        }
202
    }
203
}
204