Passed
Push — master ( 80e8d3...7b53d1 )
by Daniel
07:04
created

prependApiAPlatformConfig()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 37
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 26
nc 3
nop 2
dl 0
loc 37
ccs 13
cts 13
cp 1
crap 3
rs 9.504
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Components Bundle Project
5
 *
6
 * (c) Daniel West <[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
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentsBundle\DependencyInjection;
15
16
use Exception;
17
use Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType;
18
use Silverback\ApiComponentsBundle\AnnotationReader\UploadableAnnotationReader;
19
use Silverback\ApiComponentsBundle\Doctrine\Extension\ORM\TablePrefixExtension;
20
use Silverback\ApiComponentsBundle\Entity\Core\ComponentInterface;
21
use Silverback\ApiComponentsBundle\EventListener\Doctrine\UserListener;
22
use Silverback\ApiComponentsBundle\Factory\Mailer\User\ChangeEmailVerificationEmailFactory;
23
use Silverback\ApiComponentsBundle\Factory\Mailer\User\PasswordChangedEmailFactory;
24
use Silverback\ApiComponentsBundle\Factory\Mailer\User\PasswordResetEmailFactory;
25
use Silverback\ApiComponentsBundle\Factory\Mailer\User\UserEnabledEmailFactory;
26
use Silverback\ApiComponentsBundle\Factory\Mailer\User\UsernameChangedEmailFactory;
27
use Silverback\ApiComponentsBundle\Factory\Mailer\User\WelcomeEmailFactory;
28
use Silverback\ApiComponentsBundle\Factory\Uploadable\MediaObjectFactory;
29
use Silverback\ApiComponentsBundle\Factory\User\UserFactory;
30
use Silverback\ApiComponentsBundle\Form\FormTypeInterface;
31
use Silverback\ApiComponentsBundle\Form\Type\User\ChangePasswordType;
32
use Silverback\ApiComponentsBundle\Form\Type\User\NewEmailAddressType;
33
use Silverback\ApiComponentsBundle\Form\Type\User\UserRegisterType;
34
use Silverback\ApiComponentsBundle\Helper\Publishable\PublishableHelper;
35
use Silverback\ApiComponentsBundle\Helper\Uploadable\UploadableHelper;
36
use Silverback\ApiComponentsBundle\Mailer\UserMailer;
37
use Silverback\ApiComponentsBundle\Manager\User\PasswordManager;
38
use Silverback\ApiComponentsBundle\Repository\User\UserRepository;
39
use Silverback\ApiComponentsBundle\Security\TokenAuthenticator;
40
use Silverback\ApiComponentsBundle\Security\UserChecker;
41
use Silverback\ApiComponentsBundle\Serializer\Normalizer\MetadataNormalizer;
42
use Symfony\Component\Config\FileLocator;
43
use Symfony\Component\DependencyInjection\ContainerBuilder;
44
use Symfony\Component\DependencyInjection\Extension\Extension;
45
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
46
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
47
use Symfony\Component\DependencyInjection\Reference;
48
49
/**
50
 * @author Daniel West <[email protected]>
51
 */
52
class SilverbackApiComponentsExtension extends Extension implements PrependExtensionInterface
53
{
54
    /**
55
     * @throws Exception
56
     */
57 1
    public function load(array $configs, ContainerBuilder $container): void
58
    {
59 1
        $configuration = new Configuration();
60 1
        $config = $this->processConfiguration($configuration, $configs);
61
62 1
        $this->loadServiceConfig($container);
63
64 1
        $definition = $container->getDefinition(TablePrefixExtension::class);
65 1
        $definition->setArgument('$prefix', $config['table_prefix']);
66
67 1
        $definition = $container->getDefinition(TokenAuthenticator::class);
68 1
        $definition->setArgument('$tokens', $config['security']['tokens']);
69
70 1
        $definition = $container->getDefinition(PasswordManager::class);
71 1
        $definition->setArgument('$tokenTtl', $config['user']['password_reset']['repeat_ttl_seconds']);
72
73 1
        $definition = $container->getDefinition(UserRepository::class);
74 1
        $definition->setArgument('$passwordRequestTimeout', $config['user']['password_reset']['request_timeout_seconds']);
75 1
        $definition->setArgument('$entityClass', $config['user']['class_name']);
76
77 1
        $definition = $container->getDefinition(PublishableHelper::class);
78 1
        $definition->setArgument('$permission', $config['publishable']['permission']);
79
80 1
        $definition = $container->getDefinition(MetadataNormalizer::class);
81 1
        $definition->setArgument('$metadataKey', $config['metadata_key']);
82
83 1
        $this->setEmailVerificationArguments($container, $config['user']['email_verification']);
84 1
        $this->setUserClassArguments($container, $config['user']['class_name']);
85 1
        $this->setMailerServiceArguments($container, $config);
86
87 1
        $imagineEnabled = $container->getParameter('api_component.imagine_enabled');
88 1
        $definition = $container->getDefinition(UploadableAnnotationReader::class);
89 1
        $definition->setArgument('$imagineBundleEnabled', $imagineEnabled);
90
91 1
        if ($imagineEnabled) {
92 1
            $definition = $container->getDefinition(UploadableHelper::class);
93 1
            $definition->setArgument('$filterService', new Reference('liip_imagine.service.filter'));
94
95 1
            $definition = $container->getDefinition(MediaObjectFactory::class);
96 1
            $definition->setArgument('$filterService', new Reference('liip_imagine.service.filter'));
97
        }
98 1
    }
99
100 1
    private function setEmailVerificationArguments(ContainerBuilder $container, array $emailVerificationConfig): void
101
    {
102 1
        $definition = $container->getDefinition(UserChecker::class);
103 1
        $definition->setArgument('$denyUnverifiedLogin', $emailVerificationConfig['deny_unverified_login']);
104
105 1
        $definition = $container->getDefinition(UserListener::class);
106 1
        $definition->setArgument('$initialEmailVerifiedState', $emailVerificationConfig['default_value']);
107 1
        $definition->setArgument('$verifyEmailOnRegister', $emailVerificationConfig['verify_on_register']);
108 1
        $definition->setArgument('$verifyEmailOnChange', $emailVerificationConfig['verify_on_change']);
109 1
    }
110
111 1
    private function setUserClassArguments(ContainerBuilder $container, string $userClass): void
112
    {
113 1
        $definition = $container->getDefinition(UserFactory::class);
114 1
        $definition->setArgument('$userClass', $userClass);
115
116 1
        $definition = $container->getDefinition(ChangePasswordType::class);
117 1
        $definition->setArgument('$userClass', $userClass);
118
119 1
        $definition = $container->getDefinition(NewEmailAddressType::class);
120 1
        $definition->setArgument('$userClass', $userClass);
121
122 1
        $definition = $container->getDefinition(UserRegisterType::class);
123 1
        $definition->setArgument('$userClass', $userClass);
124 1
    }
125
126 1
    private function setMailerServiceArguments(ContainerBuilder $container, array $config): void
127
    {
128 1
        $definition = $container->getDefinition(UserMailer::class);
129 1
        $definition->setArgument('$context', [
130 1
            'website_name' => $config['website_name'],
131
        ]);
132
133
        $mapping = [
134 1
            PasswordChangedEmailFactory::class => 'password_changed',
135
            UserEnabledEmailFactory::class => 'user_enabled',
136
            UsernameChangedEmailFactory::class => 'username_changed',
137
            WelcomeEmailFactory::class => 'welcome',
138
        ];
139 1
        foreach ($mapping as $class => $key) {
140 1
            $definition = $container->getDefinition($class);
141 1
            $definition->setArgument('$subject', $config['user']['emails'][$key]['subject']);
142 1
            $definition->setArgument('$enabled', $config['user']['emails'][$key]['enabled']);
143 1
            if (WelcomeEmailFactory::class === $class) {
144 1
                $definition->setArgument('$defaultRedirectPath', $config['user']['email_verification']['email']['default_redirect_path']);
145 1
                $definition->setArgument('$redirectPathQueryKey', $config['user']['email_verification']['email']['redirect_path_query']);
146
            }
147
        }
148
149
        $mapping = [
150 1
            ChangeEmailVerificationEmailFactory::class => 'email_verification',
151
            PasswordResetEmailFactory::class => 'password_reset',
152
        ];
153 1
        foreach ($mapping as $class => $key) {
154 1
            $definition = $container->getDefinition($class);
155 1
            $definition->setArgument('$subject', $config['user'][$key]['email']['subject']);
156 1
            $definition->setArgument('$enabled', true);
157 1
            $definition->setArgument('$defaultRedirectPath', $config['user'][$key]['email']['default_redirect_path']);
158 1
            $definition->setArgument('$redirectPathQueryKey', $config['user'][$key]['email']['redirect_path_query']);
159
        }
160 1
    }
161
162
    /**
163
     * @throws Exception
164
     */
165 1
    private function loadServiceConfig(ContainerBuilder $container): void
166
    {
167 1
        $container->registerForAutoconfiguration(FormTypeInterface::class)
168 1
            ->addTag('silverback_api_components.form_type');
169
170 1
        $container->registerForAutoconfiguration(ComponentInterface::class)
171 1
            ->addTag('silverback_api_components.entity.component');
172
173 1
        $loader = new PhpFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
174 1
        $loader->load('services.php');
175 1
    }
176
177 1
    public function prepend(ContainerBuilder $container): void
178
    {
179 1
        $configs = $container->getExtensionConfig($this->getAlias());
180 1
        $configuration = new Configuration();
181 1
        $config = $this->processConfiguration($configuration, $configs);
182 1
        $this->prependApiAPlatformConfig($container, $config);
183 1
        $this->prependDoctrineConfiguration($container);
184 1
    }
185
186 1
    private function prependDoctrineConfiguration(ContainerBuilder $container): void
187
    {
188 1
        $container->prependExtensionConfig('doctrine', [
189
            'dbal' => [
190
                'types' => [
191 1
                    'uuid_binary_ordered_time' => UuidBinaryOrderedTimeType::class,
192
                ],
193
                'mapping_types' => [
194
                    'uuid_binary_ordered_time' => 'binary',
195
                ],
196
            ],
197
        ]);
198 1
    }
199
200 1
    private function prependApiAPlatformConfig(ContainerBuilder $container, array $config): void
201
    {
202 1
        $srcBase = __DIR__ . '/..';
203 1
        $configBasePath = $srcBase . '/Resources/config/api_platform';
204
205 1
        $mappingPaths = [$srcBase . '/Entity/Core'];
206 1
        $mappingPaths[] = sprintf('%s/%s.xml', $configBasePath, 'uploadable');
207 1
        foreach ($config['enabled_components'] as $key => $enabled_component) {
208 1
            if (true === $enabled_component) {
209 1
                $mappingPaths[] = sprintf('%s/%s.xml', $configBasePath, $key);
210
            }
211
        }
212
213 1
        $websiteName = $config['website_name'];
214
215 1
        $container->prependExtensionConfig('api_platform', [
216 1
            'title' => $websiteName,
217 1
            'description' => sprintf('API for %s', $websiteName),
218
            'collection' => [
219
                'pagination' => [
220
                    'client_items_per_page' => true,
221
                    'items_per_page_parameter_name' => 'perPage',
222
                    'maximum_items_per_page' => 100,
223
                ],
224
            ],
225
            'mapping' => [
226 1
                'paths' => $mappingPaths,
227
            ],
228
            'swagger' => [
229
                'api_keys' => [
230
                    'API Token' => [
231
                        'name' => 'X-AUTH-TOKEN',
232
                        'type' => 'header',
233
                    ],
234
                    'JWT (use prefix `Bearer`)' => [
235
                        'name' => 'Authorization',
236
                        'type' => 'header',
237
                    ],
238
                ],
239
            ],
240
        ]);
241 1
    }
242
}
243