TransferServiceProvider::getTargetDirectory()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 1
c 1
b 0
f 1
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jellyfish\Transfer;
6
7
use ArrayObject;
8
use Jellyfish\Transfer\Command\TransferGenerateCommand;
9
use Jellyfish\Transfer\Definition\ClassDefinitionMapLoader;
10
use Jellyfish\Transfer\Definition\ClassDefinitionMapLoaderInterface;
11
use Jellyfish\Transfer\Definition\ClassDefinitionMapMapper;
12
use Jellyfish\Transfer\Definition\ClassDefinitionMapMapperInterface;
13
use Jellyfish\Transfer\Definition\ClassDefinitionMapMerger;
14
use Jellyfish\Transfer\Definition\ClassDefinitionMapMergerInterface;
15
use Jellyfish\Transfer\Definition\DefinitionFinder;
16
use Jellyfish\Transfer\Definition\DefinitionFinderInterface;
17
use Jellyfish\Transfer\Generator\ClassGenerator;
18
use Jellyfish\Transfer\Generator\FactoryClassGenerator;
19
use Jellyfish\Transfer\Generator\FactoryRegistryGenerator;
20
use Jellyfish\Transfer\Generator\FactoryRegistryGeneratorInterface;
21
use Pimple\Container;
22
use Pimple\ServiceProviderInterface;
23
use Twig\Environment;
24
use Twig\Loader\FilesystemLoader;
25
26
class TransferServiceProvider implements ServiceProviderInterface
27
{
28
    /**
29
     * @var \Twig\Environment|null
30
     */
31
    protected $twigEnvironment;
32
33
    /**
34
     * @param \Pimple\Container $pimple
35
     *
36
     * @return void
37
     */
38
    public function register(Container $pimple): void
39
    {
40
        $this->registerCommands($pimple)
41
            ->registerFactories($pimple);
42
    }
43
44
    /**
45
     * @param \Pimple\Container $container
46
     *
47
     * @return \Jellyfish\Transfer\TransferServiceProvider
48
     */
49
    protected function registerCommands(Container $container): TransferServiceProvider
50
    {
51
        $self = $this;
52
53
        $container->extend('commands', function (array $commands, Container $container) use ($self) {
54
            $commands[] = new TransferGenerateCommand(
55
                $self->createTransferGenerator($container),
56
                $self->createTransferCleaner($container),
57
                $container->offsetGet('logger')
58
            );
59
60
            return $commands;
61
        });
62
63
        return $this;
64
    }
65
66
    /**
67
     * @param \Pimple\Container $container
68
     *
69
     * @return \Jellyfish\Transfer\TransferGeneratorInterface
70
     */
71
    protected function createTransferGenerator(Container $container): TransferGeneratorInterface
72
    {
73
        return new TransferGenerator(
74
            $this->createClassDefinitionMapLoader($container),
75
            $this->createFactoryRegistryGenerator($container),
76
            $this->createClassGenerators($container)
77
        );
78
    }
79
80
    /**
81
     * @param \Pimple\Container $container
82
     *
83
     * @return \Jellyfish\Transfer\Definition\ClassDefinitionMapLoaderInterface
84
     */
85
    protected function createClassDefinitionMapLoader(Container $container): ClassDefinitionMapLoaderInterface
86
    {
87
        return new ClassDefinitionMapLoader(
88
            $this->createDefinitionFinder($container),
89
            $container->offsetGet('filesystem'),
90
            $this->createClassDefinitionMapMapper($container),
91
            $this->createClassDefinitionMapMerger()
92
        );
93
    }
94
95
    /**
96
     * @param \Pimple\Container $container
97
     *
98
     * @return \Jellyfish\Transfer\Definition\DefinitionFinderInterface
99
     */
100
    protected function createDefinitionFinder(Container $container): DefinitionFinderInterface
101
    {
102
        return new DefinitionFinder(
103
            $container->offsetGet('finder_factory'),
104
            $container->offsetGet('root_dir')
105
        );
106
    }
107
108
    /**
109
     * @param \Pimple\Container $container
110
     *
111
     * @return \Jellyfish\Transfer\Definition\ClassDefinitionMapMapperInterface
112
     */
113
    protected function createClassDefinitionMapMapper(Container $container): ClassDefinitionMapMapperInterface
114
    {
115
        return new ClassDefinitionMapMapper($container->offsetGet('serializer'));
116
    }
117
118
    /**
119
     * @return \Jellyfish\Transfer\Definition\ClassDefinitionMapMergerInterface
120
     */
121
    protected function createClassDefinitionMapMerger(): ClassDefinitionMapMergerInterface
122
    {
123
        return new ClassDefinitionMapMerger();
124
    }
125
126
    /**
127
     * @param \Pimple\Container $container
128
     *
129
     * @return \Jellyfish\Transfer\Generator\FactoryRegistryGeneratorInterface
130
     */
131
    protected function createFactoryRegistryGenerator(Container $container): FactoryRegistryGeneratorInterface
132
    {
133
        $targetDirectory = $this->getTargetDirectory($container);
134
        $twigEnvironment = $this->getTwigEnvironment();
135
136
        return new FactoryRegistryGenerator($container->offsetGet('filesystem'), $twigEnvironment, $targetDirectory);
137
    }
138
139
    /**
140
     * @param \Pimple\Container $container
141
     *
142
     * @return array
143
     */
144
    protected function createClassGenerators(Container $container): array
145
    {
146
        $targetDirectory = $this->getTargetDirectory($container);
147
        $twigEnvironment = $this->getTwigEnvironment();
148
149
        return [
150
            new ClassGenerator(
151
                $container->offsetGet('filesystem'),
152
                $twigEnvironment,
153
                $targetDirectory
154
            ),
155
            new FactoryClassGenerator(
156
                $container->offsetGet('filesystem'),
157
                $twigEnvironment,
158
                $targetDirectory
159
            ),
160
        ];
161
    }
162
163
    /**
164
     * @return \Twig\Environment
165
     */
166
    protected function getTwigEnvironment(): Environment
167
    {
168
        if ($this->twigEnvironment === null) {
169
            $pathToTemplates = __DIR__ . DIRECTORY_SEPARATOR . 'Templates' . DIRECTORY_SEPARATOR;
170
            $loader = new FilesystemLoader($pathToTemplates);
171
            $this->twigEnvironment = new Environment($loader, []);
172
        }
173
174
        return $this->twigEnvironment;
175
    }
176
177
    /**
178
     * @param \Pimple\Container $container
179
     *
180
     * @return string
181
     */
182
    protected function getTargetDirectory(Container $container): string
183
    {
184
        return $container->offsetGet('root_dir') . 'src/Generated/Transfer/';
185
    }
186
187
    /**
188
     * @param \Pimple\Container $container
189
     *
190
     * @return \Jellyfish\Transfer\TransferCleanerInterface
191
     */
192
    protected function createTransferCleaner(Container $container): TransferCleanerInterface
193
    {
194
        $targetDirectory = $this->getTargetDirectory($container);
195
196
        return new TransferCleaner(
197
            $container->offsetGet('finder_factory'),
198
            $container->offsetGet('filesystem'),
199
            $targetDirectory
200
        );
201
    }
202
203
    /**
204
     * @param \Pimple\Container $container
205
     *
206
     * @return \Jellyfish\Transfer\TransferServiceProvider
207
     */
208
    protected function registerFactories(Container $container): TransferServiceProvider
209
    {
210
        $pathToFactoryRegistry = $this->getTargetDirectory($container) . 'factory-registry.php';
211
        $factoryRegistry = new ArrayObject();
212
213
        if (\file_exists($pathToFactoryRegistry)) {
214
            include $pathToFactoryRegistry;
215
        }
216
217
        foreach ($factoryRegistry as $factoryId => $factory) {
218
            $container->offsetSet((string)$factoryId, function () use ($factory) {
219
                return $factory;
220
            });
221
        }
222
223
        return $this;
224
    }
225
}
226