VesloAppExtension::load()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 47
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 34
c 2
b 0
f 0
dl 0
loc 47
rs 9.376
cc 2
nc 2
nop 2
1
<?php
2
3
/*
4
 * This file is part of the Veslo project <https://github.com/symfony-doge/veslo>.
5
 *
6
 * (C) 2019 Pavel Petrov <[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
 * @license https://opensource.org/licenses/GPL-3.0 GPL-3.0
12
 */
13
14
declare(strict_types=1);
15
16
namespace Veslo\AppBundle\DependencyInjection;
17
18
use Symfony\Component\Config\FileLocator;
19
use Symfony\Component\Config\Loader\LoaderInterface;
20
use Symfony\Component\DependencyInjection\ContainerBuilder;
21
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
22
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
23
24
/**
25
 * AppBundle dependency injection extension.
26
 *
27
 * TODO: "blueprints" directory and custom loading instead of constants.
28
 */
29
class VesloAppExtension extends Extension
30
{
31
    /**
32
     * Blueprint is a configuration file with services that can be injected optionally (e.g. by specific condition)
33
     *
34
     * @const string
35
     */
36
    private const BLUEPRINT_DERECTORY = 'blueprints';
37
38
    /**
39
     * Service alias for http client at application level
40
     *
41
     * @const string
42
     */
43
    private const SERVICE_ALIAS_HTTP_CLIENT = 'veslo.app.http.client.base';
44
45
    /**
46
     * Service alias for a proxy locator
47
     *
48
     * @const string
49
     */
50
    private const SERVICE_ALIAS_PROXY_LOCATOR = 'veslo.app.http.proxy.locator';
51
52
    /**
53
     * Service id for verbose http client
54
     *
55
     * @const string
56
     */
57
    private const SERVICE_ID_HTTP_CLIENT_VERBOSE = 'veslo.app.http.client.verbose';
58
59
    /**
60
     * Service id of locator responsible for fetching proxy list if URI is used
61
     *
62
     * @const string
63
     */
64
    private const SERVICE_ID_PROXY_CHAIN_LOCATOR = 'veslo.app.http.proxy.locator_chain';
65
66
    /**
67
     * {@inheritdoc}
68
     */
69
    public function load(array $configs, ContainerBuilder $container)
70
    {
71
        $locator = new FileLocator(__DIR__ . implode(DIRECTORY_SEPARATOR, ['', '..', 'Resources']));
72
        $loader  = new YamlFileLoader($container, $locator);
73
74
        $configFiles = [
75
            'twig_extensions.yml',
76
            'monolog.yml',
77
            'shared_cache.yml',
78
            'event_listeners.yml',
79
            'decoders.yml',
80
            'html.yml',
81
            'workflow.yml',
82
            'menu.yml',
83
            'proxy_locators.yml',
84
            'proxy_managers.yml',
85
            'clients.yml',
86
            'services.yml',
87
        ];
88
89
        foreach ($configFiles as $configFile) {
90
            $loader->load('config' . DIRECTORY_SEPARATOR . $configFile);
91
        }
92
93
        $configuration = new Configuration();
94
        $config        = $this->processConfiguration($configuration, $configs);
95
96
        $this->configureHttpClient($config['http']['client'], $container, $loader);
97
        $this->configureHttpProxy($config['http']['proxy'], $container, $loader);
98
99
        $amqpClientOptions = [
100
            'host'      => $config['amqp_client']['host'],
101
            'vhost'     => $config['amqp_client']['vhost'],
102
            'user'      => $config['amqp_client']['user'],
103
            'password'  => $config['amqp_client']['password'],
104
            'heartbeat' => $config['amqp_client']['heartbeat'],
105
        ];
106
        $container->setParameter('veslo.app.amqp_client.options', $amqpClientOptions);
107
108
        $container->setParameter(
109
            'veslo.app.workflow.vacancy_research.transitions.queue_prefix',
110
            $config['workflow']['vacancy_research']['transitions']['queue_prefix']
111
        );
112
113
        $container->setParameter(
114
            'veslo.app.monolog.formatter.line_formatter.format',
115
            $config['monolog']['formatter']['line']['format']
116
        );
117
    }
118
119
    /**
120
     * Configures global http client for application level
121
     *
122
     * @param array            $config    Http client node configuration
123
     * @param ContainerBuilder $container Container
124
     * @param LoaderInterface  $loader    Loads a configuration file with services
125
     *
126
     * @return void
127
     */
128
    private function configureHttpClient(array $config, ContainerBuilder $container, LoaderInterface $loader): void
129
    {
130
        $isVerboseHttpClient = filter_var($config['logging'], FILTER_VALIDATE_BOOLEAN);
131
132
        if ($isVerboseHttpClient) {
133
            $container->setAlias(self::SERVICE_ALIAS_HTTP_CLIENT, self::SERVICE_ID_HTTP_CLIENT_VERBOSE);
134
        }
135
136
        $httpClientConfig = [
137
            'headers' => [
138
                'User-Agent' => $config['headers']['user_agent'],
139
            ],
140
        ];
141
        $container->setParameter('veslo.app.http.client.config', $httpClientConfig);
142
143
        $isProxyEnabled = $config['proxy']['enabled'];
144
145
        // Http client stability options: proxy, fingerprint faking, etc.
146
        $httpClientStabilityOptions = [
147
            'proxy' => [
148
                'enabled' => $isProxyEnabled,
149
            ],
150
        ];
151
        $container->setParameter('veslo.app.http.client.stability_options', $httpClientStabilityOptions);
152
153
        // Activating HTTP client events (making a client event dispatcher referencing a real service).
154
        $clientEventDispatcherDefinitionFile = implode(
155
            DIRECTORY_SEPARATOR,
156
            ['config', self::BLUEPRINT_DERECTORY, 'client_event_dispatcher.yml']
157
        );
158
        $loader->load($clientEventDispatcherDefinitionFile);
159
    }
160
161
    /**
162
     * Configures proxy settings for http clients
163
     *
164
     * @param array            $config    Http proxy node configuration
165
     * @param ContainerBuilder $container Container
166
     * @param LoaderInterface  $loader    Loads a configuration file with services
167
     *
168
     * @return void
169
     */
170
    private function configureHttpProxy(array $config, ContainerBuilder $container, LoaderInterface $loader): void
171
    {
172
        $proxyLocatorUriOptions = [
173
            'uri'             => $config['dynamic']['fetch_uri'],
174
            'format'          => $config['dynamic']['format'],
175
            'decoder_context' => $config['dynamic']['decoder_context'],
176
        ];
177
        $container->setParameter('veslo.app.http.proxy.locator.uri_locator.options', $proxyLocatorUriOptions);
178
179
        if (!empty($proxyLocatorUriOptions['uri'])) {
180
            $container->setAlias(self::SERVICE_ALIAS_PROXY_LOCATOR, self::SERVICE_ID_PROXY_CHAIN_LOCATOR);
181
        }
182
183
        $container->setParameter('veslo.app.http.proxy.static_list', $config['static_list']);
184
185
        // Using an optional proxy cacher.
186
        if (!empty($config['dynamic']['cache']['enabled'])) {
187
            $proxyCacherOptions = [
188
                'key'      => $config['dynamic']['cache']['key'],
189
                'lifetime' => $config['dynamic']['cache']['lifetime'],
190
            ];
191
            $container->setParameter('veslo.app.http.proxy.cacher.options', $proxyCacherOptions);
192
193
            $proxyCacherDefinitionFile = implode(
194
                DIRECTORY_SEPARATOR,
195
                ['config', self::BLUEPRINT_DERECTORY, 'proxy_cacher.yml']
196
            );
197
            $loader->load($proxyCacherDefinitionFile);
198
        }
199
    }
200
}
201