Passed
Pull Request — master (#3)
by Koldo
02:28
created

FileStructure::getConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 32
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 35
ccs 3
cts 3
cp 1
crap 1
rs 9.408
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Antidot\Installer\Template\Micro;
6
7
use RuntimeException;
8
9
use function file_put_contents;
10
use function is_dir;
11
use function mkdir;
12
use function scandir;
13
use function sprintf;
14
15
class FileStructure
16
{
17
    private const FILES = [
18
        'getGitignore' => '.gitignore',
19
        'getConfig' => 'config/config.php',
20
        'getFrameworkConfig' => 'config/framework.prod.php',
21
        'getContainer' => 'config/container.php',
22
        'getIndex' => 'public/index.php',
23
        'getReadme' => 'README.md',
24
    ];
25
26
    private const DIRECTORIES = [
27
        'public',
28
        'config',
29
        'var/cache',
30
        'test',
31
    ];
32
33 3
    public function create(string $installationPath): void
34
    {
35 3
        if (!is_dir($installationPath) && !mkdir($dir = $installationPath, 0755, true) && !is_dir($dir)) {
36
            throw new RuntimeException(sprintf('Directory "%s" was not created', $dir));
37
        }
38
39 3
        if (!is_readable($installationPath)) {
40
            throw new RuntimeException(sprintf('Given directory "%s" is not readable.', $installationPath));
41
        }
42
43 3
        foreach (self::DIRECTORIES as $directory) {
44 3
            if (!mkdir($dir = sprintf('%s/%s', $installationPath, $directory), 0755, true) && !is_dir($dir)) {
45 1
                throw new RuntimeException(sprintf('Directory "%s" was not created', $dir));
46
            }
47
        }
48
49 2
        foreach (self::FILES as $method => $filename) {
50 2
            file_put_contents(sprintf('%s/%s', $installationPath, $filename), $this->$method());
51
        }
52 2
    }
53
54 2
    public static function getGitignore(): string
55
    {
56
        $gitignoreContents = <<<EOT
57 2
/composer.lock
58
59
/config/*.dev.php
60
/config/*.local.php
61
/config/development.config.php
62
63
/vendor
64
/var/cache/*
65
!/var/cache/.gitkeep
66
/var/log/*
67
!/var/log/.gitkeep
68
EOT;
69
70 2
        return $gitignoreContents;
71
    }
72
73 2
    public static function getConfig(): string
74
    {
75
        $configContent = <<<'PHP'
76 2
<?php
77
78
declare(strict_types=1);
79
80
use Antidot\DevTools\Container\Config\ConfigProvider as DevToolsConfigProvider;
81
use Laminas\ConfigAggregator\ConfigAggregator;
82
use Laminas\ConfigAggregator\ArrayProvider;
83
use Laminas\ConfigAggregator\PhpFileProvider;
84
85
// To enable or disable caching, set the `ConfigAggregator::ENABLE_CACHE` boolean in
86
// `config/autoload/local.php`.
87
$cacheConfig = [
88
    'config_cache_path' => 'var/cache/config-cache.php',
89
];
90
91
$aggregator = new ConfigAggregator([
92
    class_exists(DevToolsConfigProvider::class) ? DevToolsConfigProvider::class : fn() => [],
93
    // Load application config in a pre-defined order in such a way that local settings
94
    // overwrite global settings. (Loaded as first to last):
95
    //   - `*.php`
96
    //   - `*.global.php`
97
    //   - `*.local.php`
98
    //   - `*.dev.php`
99
    new PhpFileProvider(realpath(__DIR__).'/{{,*.}prod,{,*.}local,{,*.}dev}.php'),
100
    new ArrayProvider($cacheConfig),
101
], $cacheConfig['config_cache_path']);
102
103
return $aggregator->getMergedConfig();
104
105
PHP;
106
107 2
        return $configContent;
108
    }
109
110 2
    public static function getContainer(): string
111
    {
112
        $containerContent = <<<'PHP'
113 2
<?php
114
115
declare(strict_types=1);
116
117
// Load configuration
118
use Antidot\Container\Builder;
119
120
$config = require __DIR__ . '/../config/config.php';
121
122
return Builder::build($config, true);
123
124
PHP;
125
126 2
        return $containerContent;
127
    }
128
129 2
    public static function getIndex(): string
130
    {
131
        $indexContent = <<<'PHP'
132 2
<?php
133
134
declare(strict_types=1);
135
136
use Antidot\Application\Http\Application;
137
use Antidot\Application\Http\Middleware\ErrorMiddleware;
138
use Antidot\Application\Http\Middleware\RouteDispatcherMiddleware;
139
use Antidot\Application\Http\Middleware\RouteNotFoundMiddleware;
140
use Laminas\Diactoros\Response\JsonResponse;
141
use Psr\Http\Message\ServerRequestInterface;
142
use Psr\Http\Server\RequestHandlerInterface;
143
use Psr\Http\Message\ResponseInterface;
144
145
if (PHP_SAPI === 'cli-server' && $_SERVER['SCRIPT_FILENAME'] !== __FILE__) {
146
    return false;
147
}
148
\chdir(\dirname(__DIR__));
149
require 'vendor/autoload.php';
150
/**
151
 * Self-called anonymous function that creates its own scope and keep the global namespace clean.
152
 */
153
\call_user_func(static function (): void {
154
    \error_reporting(E_ALL & ~E_USER_DEPRECATED & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE);
155
156
    /** @var \Psr\Container\ContainerInterface $container */
157
    $container = require 'config/container.php';
158
    /** @var Application $app */
159
    $app = $container->get(Application::class);
160
    
161
    // Global Pipeline Configuration
162
    $app->pipe(ErrorMiddleware::class);
163
    $app->pipe(RouteDispatcherMiddleware::class);
164
    $app->pipe(RouteNotFoundMiddleware::class);
165
166
    // Application Routes    
167
    $app->get('/', [
168
        static function(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
169
            $request = $request->withAttribute('docs_url', 'https://antidotfw.io');
170
            return $handler->handle($request);
171
        },
172
        static function(ServerRequestInterface $request): ResponseInterface {
173
            return new JsonResponse([
174
                'message' => 'Welcome to Antidot Framework Micro HTTP App.',
175
                'docs' => $request->getAttribute('docs_url'),
176
            ]);
177
        }
178
    ], 'homepage');
179
180
    $app->run();
181
});
182
183
PHP;
184
185 2
        return $indexContent;
186
    }
187
188 2
    public static function getReadme(): string
189
    {
190
        $readmeContents = <<<'EOT'
191 2
# Antidot Framework Micro HTTP App
192
193
Lightweight PSR-15 middleware application.
194
195
## Routing
196
197
You can add your routes with it custom middlewares in `public/index.php` file, take a look at the example:
198
199
```php 
200
<?php
201
// public/index.php
202
declare(strict_types=1);
203
204
use Psr\Http\Message\ServerRequestInterface;
205
use Psr\Http\Server\RequestHandlerInterface;
206
use Psr\Http\Message\ResponseInterface;
207
...
208
209
    // Application Routes    
210
    $app->get('/', [
211
        static function(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
212
            $request = $request->withAttribute('docs_url', 'https://antidotfw.io');
213
            return $handler->handle($request);
214
        },
215
        static function(ServerRequestInterface $request): ResponseInterface {
216
            return new JsonResponse([
217
                'message' => 'Welcome to Antidot Framework Micro HTTP App.',
218
                'docs' => $request->getAttribute('docs_url'),
219
            ]);
220
        }
221
    ], 'homepage');
222
...
223
224
```
225
226
## File structure
227
228
```
229
config/
230
    config.php
231
    container.php
232
    framework.prod.php
233
public/
234
    index.php
235
test/
236
var/
237
    cache/
238
.gitignore
239
composer.json
240
phpcs.xml.dist
241
phpunit.xml.dist
242
README.md        
243
```
244
245
246
EOT;
247
248 2
        return $readmeContents;
249
    }
250
251 2
    public static function getFrameworkConfig(): string
252
    {
253
        $frameworkConfigContents = <<<'PHP'
254 2
<?php
255
256
declare(strict_types=1);
257
258
return [
259
    'debug' => false,
260
    'config_cache_enabled' => true
261
];
262
263
PHP;
264
265 2
        return $frameworkConfigContents;
266
    }
267
}
268