ContainerFactory   A
last analyzed

Complexity

Total Complexity 2

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Importance

Changes 14
Bugs 0 Features 0
Metric Value
eloc 102
c 14
b 0
f 0
dl 0
loc 135
rs 10
wmc 2

1 Method

Rating   Name   Duplication   Size   Complexity  
B __invoke() 0 133 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chinstrap\Core\Kernel;
6
7
use Chinstrap\Core\Contracts\Exceptions\Handler;
8
use Chinstrap\Core\Contracts\Factories\FormFactory;
9
use Chinstrap\Core\Contracts\Generators\Sitemap;
10
use Chinstrap\Core\Contracts\Sources\Source;
11
use Chinstrap\Core\Contracts\Views\Renderer;
12
use Chinstrap\Core\Events\RegisterDynamicRoutes;
13
use Chinstrap\Core\Events\RegisterViewHelpers;
14
use Chinstrap\Core\Exceptions\LogHandler;
15
use Chinstrap\Core\Factories\FlysystemFactory;
16
use Chinstrap\Core\Factories\Forms\LaminasFormFactory;
17
use Chinstrap\Core\Factories\MonologFactory;
18
use Chinstrap\Core\Generators\XmlStringSitemap;
19
use Chinstrap\Core\Listeners\RegisterSystemDynamicRoutes;
20
use Chinstrap\Core\Listeners\RegisterViews;
21
use Chinstrap\Core\Views\TwigRenderer;
22
use Clockwork\Support\Vanilla\Clockwork;
23
use Laminas\Diactoros\Response;
24
use Laminas\Diactoros\Stream;
25
use Laminas\EventManager\EventManager;
26
use Laminas\EventManager\EventManagerInterface;
27
use Laminas\Mail\Transport\InMemory;
28
use Laminas\Mail\Transport\TransportInterface;
29
use Laminas\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory;
30
use Laminas\ServiceManager\ServiceManager;
31
use League\Flysystem\FilesystemInterface;
32
use League\Flysystem\MountManager;
33
use League\Glide\Responses\PsrResponseFactory;
34
use League\Glide\Server;
35
use League\Glide\ServerFactory;
36
use League\Route\Router;
37
use League\Route\Strategy\ApplicationStrategy;
38
use Psr\Cache\CacheItemPoolInterface;
39
use Psr\Container\ContainerInterface;
40
use Psr\Http\Message\ResponseInterface;
41
use Psr\Log\LoggerInterface;
42
use PSR7Sessions\Storageless\Http\SessionMiddleware;
43
use PublishingKit\Cache\Contracts\Factories\CacheFactory;
44
use PublishingKit\Cache\Contracts\Services\CacheContract;
45
use PublishingKit\Cache\Factories\StashCacheFactory;
46
use PublishingKit\Cache\Services\Cache\Psr6Cache;
47
use PublishingKit\Config\Config;
48
use Stash\Pool;
49
use Twig\Environment;
50
use Twig\Loader\FilesystemLoader;
51
use Whoops\Run;
52
use Whoops\RunInterface;
53
54
final class ContainerFactory
55
{
56
    public function __invoke(): ServiceManager
57
    {
58
        return new ServiceManager([
59
            'abstract_factories' => [
60
                ReflectionBasedAbstractFactory::class,
61
            ],
62
            'lazy_services' => [
63
                'classmap' => [
64
                    \Faker\Generator::class => \Faker\Generator::class,
65
                ],
66
            ],
67
            'aliases' => [
68
                Renderer::class => TwigRenderer::class,
69
                ContainerInterface::class => ServiceManager::class,
70
                Handler::class => LogHandler::class,
71
                Sitemap::class => XmlStringSitemap::class,
72
                TransportInterface::class => InMemory::class,
73
                FormFactory::class => LaminasFormFactory::class,
74
                CacheFactory::class => StashCacheFactory::class,
75
                CacheItemPoolInterface::class => Pool::class,
76
                ResponseInterface::class => Response::class,
77
                RunInterface::class => Run::class,
78
                'response' => Response::class,
79
            ],
80
            'factories' => [
81
                SessionMiddleware::class => function (
82
                    ContainerInterface $container
83
                ): SessionMiddleware {
84
                    $config = $container->get(Config::class);
85
                    $key = $config->get('key');
86
                    assert(is_string($key));
87
                    $time = (int)$config->get('session_time');
88
                    return SessionMiddleware::fromSymmetricKeyDefaults(
89
                        $key,
90
                        $time
91
                    );
92
                },
93
                \Faker\Generator::class => function (
94
                    ContainerInterface $container
95
): \Faker\Generator {
96
                    $config = $container->get(Config::class);
97
                    return \Faker\Factory::create($config->get('locale'));
98
                },
99
                Clockwork::class => function (): Clockwork {
100
                    return Clockwork::init();
101
                },
102
                Config::class => function (): Config {
103
                    return Config::fromFiles(glob(ROOT_DIR . 'config/*.*'));
104
                },
105
                FilesystemInterface::class => function (
106
                    ContainerInterface $container
107
): MountManager {
108
                    $factory = $container->get(FlysystemFactory::class);
109
                    $config = $container->get(Config::class);
110
111
                    // Decorate the adapter
112
                    $contentFilesystem = $factory->make($config->filesystem->content);
113
                    $assetFilesystem = $factory->make($config->filesystem->assets);
114
                    $mediaFilesystem = $factory->make($config->filesystem->media);
115
                    $cacheFilesystem = $factory->make($config->filesystem->cache);
116
117
                    return new MountManager([
118
                        'content' => $contentFilesystem,
119
                        'assets' => $assetFilesystem,
120
                        'media' => $mediaFilesystem,
121
                        'cache' => $cacheFilesystem,
122
                    ]);
123
                },
124
                Source::class => function (ContainerInterface $container): Source {
125
                    $config = $container->get(Config::class)->get('source');
126
                    /** @var class-string<Source> $config **/
127
                    return $container->get($config);
128
                },
129
                LoggerInterface::class => function (
130
                    ContainerInterface $container
131
): LoggerInterface {
132
                    /** @var Config **/
133
                    $config = $container->get('PublishingKit\Config\Config');
134
                    $factory = new MonologFactory();
135
                    return $factory->make($config->get('loggers'));
136
                },
137
                FilesystemLoader::class => function (
138
                    ContainerInterface $container
139
): FilesystemLoader {
140
                    return new FilesystemLoader(ROOT_DIR . 'resources' . DIRECTORY_SEPARATOR . 'views');
141
                },
142
                Environment::class => function (ContainerInterface $container): Environment {
143
                    $config = [];
144
                    if ($_ENV['APP_ENV'] !== 'development') {
145
                        $config['cache'] = ROOT_DIR . '/cache/views';
146
                    }
147
                    return new Environment($container->get('Twig\Loader\FilesystemLoader'), $config);
148
                },
149
                Router::class => function (ContainerInterface $container): Router {
150
                    $strategy = (new ApplicationStrategy())->setContainer($container);
151
                    $router = new Router();
152
                    $router->setStrategy($strategy);
153
                    return $router;
154
                },
155
                EventManagerInterface::class => function (
156
                    ContainerInterface $container
157
): EventManagerInterface {
158
                    /** @var EventManagerInterface **/
159
                    $manager = $container->get(EventManager::class);
160
                    $manager->attach(
161
                        RegisterDynamicRoutes::class,
162
                        $container->get(RegisterSystemDynamicRoutes::class)
163
                    );
164
                    $manager->attach(
165
                        RegisterViewHelpers::class,
166
                        $container->get(RegisterViews::class)
167
                    );
168
                    return $manager;
169
                },
170
                Server::class => function (ContainerInterface $container) {
171
                    $fs = $container->get('League\Flysystem\FilesystemInterface');
172
                    $source = $fs->getFilesystem('media');
173
                    $cache = $fs->getFilesystem('cache');
174
                    return ServerFactory::create([
175
                        'source' => $source,
176
                        'cache' => $cache,
177
                        'response' => new PsrResponseFactory(new Response(), function ($stream) {
178
                            return new Stream($stream);
179
                        }),
180
                    ]);
181
                },
182
                CacheContract::class => function (ContainerInterface $container): CacheContract {
183
                    return new Psr6Cache($container->get(CacheItemPoolInterface::class));
184
                },
185
                Pool::class => function (ContainerInterface $container): Pool {
186
                    $factory = $container->get(CacheFactory::class);
187
                    $config = $container->get(Config::class);
188
                    return $factory->make($config->cache->toArray());
189
                }
190
            ]
191
        ]);
192
    }
193
}
194