Passed
Branch main (b6a268)
by Iain
04:04
created

Common::configurePdf()   C

Complexity

Conditions 12
Paths 8

Size

Total Lines 30
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 12
eloc 18
c 2
b 0
f 0
nc 8
nop 3
dl 0
loc 30
rs 6.9666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * Copyright Humbly Arrogant Ltd 2020-2022.
7
 *
8
 * Use of this software is governed by the Business Source License included in the LICENSE file and at https://getparthenon.com/docs/next/license.
9
 *
10
 * Change Date: TBD ( 3 years after 2.0.0 release )
11
 *
12
 * On the date above, in accordance with the Business Source License, use of this software will be governed by the open source license specified in the LICENSE file.
13
 */
14
15
namespace Parthenon\DependencyInjection\Modules;
16
17
use DocRaptor\Doc;
18
use Mpdf\Mpdf;
19
use Parthenon\Common\Exception\MissingDependencyException;
20
use Parthenon\Common\Exception\ParameterNotSetException;
21
use Parthenon\Common\RequestHandler\RequestHandlerInterface;
22
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
23
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
24
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
25
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
26
use Symfony\Component\Config\FileLocator;
27
use Symfony\Component\DependencyInjection\ContainerBuilder;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Depend...ection\ContainerBuilder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Depend...on\Loader\XmlFileLoader was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
29
30
final class Common implements ModuleConfigurationInterface
31
{
32
    public function addConfig(NodeBuilder $nodeBuilder): void
33
    {
34
        $nodeBuilder->arrayNode('common')
35
            ->children()
36
                ->scalarNode('site_url')->end()
37
                ->arrayNode('elasticsearch')
0 ignored issues
show
Bug introduced by
The method arrayNode() does not exist on Symfony\Component\Config...der\NodeParentInterface. It seems like you code against a sub-type of Symfony\Component\Config...der\NodeParentInterface such as Symfony\Component\Config...ion\Builder\NodeBuilder. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

37
                ->/** @scrutinizer ignore-call */ arrayNode('elasticsearch')
Loading history...
38
                    ->children()
39
                        ->arrayNode('hosts')->scalarPrototype()->end()->end()
40
                        ->scalarNode('connection_type')->end()
41
                        ->scalarNode('cloud_id')->end()
42
                        ->scalarNode('api_key')->end()
43
                        ->scalarNode('api_id')->end()
44
                        ->scalarNode('basic_username')->end()
45
                        ->scalarNode('basic_password')->end()
46
                    ->end()
47
                ->end()
48
                ->arrayNode('pdf')
49
                    ->children()
50
                        ->scalarNode('generator')->end()
51
                        ->arrayNode('mpdf')
52
                            ->children()
53
                                ->scalarNode('tmp_dir')->defaultValue('/tmp')->end()
54
                            ->end()
55
                        ->end()
56
                        ->arrayNode('docraptor')
57
                            ->children()
58
                                ->scalarNode('api_key')->end()
59
                            ->end()
60
                        ->end()
61
                        ->arrayNode('wkhtmltopdf')
62
                            ->children()
63
                                ->scalarNode('bin')->defaultValue('/usr/bin/wkhtmltopdf')->end()
64
                            ->end()
65
                        ->end()
66
                    ->end()
67
                ->end()
68
            ->end()
69
            ->fixXmlConfig('uploaders')
70
            ->append($this->getUploadersNode())
71
        ->end();
72
    }
73
74
    public function handleDefaultParameters(ContainerBuilder $container): void
75
    {
76
        $container->setParameter('parthenon_common_site_url', 'http://localhost');
77
        $container->setParameter('parthenon_common_pdf_wkhtmltopdf_bin', '');
78
        $container->setParameter('parthenon_common_pdf_docraptor_api_key', '');
79
        $container->setParameter('parthenon_common_uploaders', []);
80
    }
81
82
    public function handleConfiguration(array $config, ContainerBuilder $container): void
83
    {
84
        $container->registerForAutoconfiguration(RequestHandlerInterface::class)->addTag('parthenon.common.request_handler');
85
86
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../Resources/config'));
87
        $loader->load('services/common.xml');
88
89
        if (!isset($config['common'])) {
90
            return;
91
        }
92
93
        $container->setParameter('parthenon_common_site_url', $config['common']['site_url'] ?? '');
94
95
        $config = $this->configureUploader($config, $container);
96
        $config = $this->configurePdf($config, $container, $loader);
97
98
        $this->configureElasticsearch($config, $container);
99
    }
100
101
    private function getUploadersNode(): NodeDefinition
102
    {
103
        $treeBuilder = new TreeBuilder('uploader');
104
        $node = $treeBuilder->getRootNode();
105
106
        /** @var ArrayNodeDefinition $uploaderNode */
107
        $uploaderNode = $node
108
            ->requiresAtLeastOneElement()
0 ignored issues
show
Bug introduced by
The method requiresAtLeastOneElement() does not exist on Symfony\Component\Config...\Builder\NodeDefinition. It seems like you code against a sub-type of Symfony\Component\Config...\Builder\NodeDefinition such as Symfony\Component\Config...der\ArrayNodeDefinition. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

108
            ->/** @scrutinizer ignore-call */ requiresAtLeastOneElement()
Loading history...
109
            ->useAttributeAsKey('name')
110
            ->prototype('array');
111
112
        $uploaderNode
113
            ->children()
114
                ->scalarNode('provider')->end()
115
                ->scalarNode('naming_strategy')->end()
0 ignored issues
show
Bug introduced by
The method scalarNode() does not exist on Symfony\Component\Config...der\NodeParentInterface. It seems like you code against a sub-type of Symfony\Component\Config...der\NodeParentInterface such as Symfony\Component\Config...ion\Builder\NodeBuilder. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

115
                ->/** @scrutinizer ignore-call */ scalarNode('naming_strategy')->end()
Loading history...
116
                ->scalarNode('url')->end()
117
                ->arrayNode('local')
118
                    ->children()
119
                        ->scalarNode('path')->end()
120
                    ->end()
121
                ->end()
122
                ->arrayNode('s3')
123
                    ->children()
124
                        ->scalarNode('key')->end()
125
                        ->scalarNode('secret')->end()
126
                        ->scalarNode('region')->end()
127
                        ->scalarNode('endpoint')->end()
128
                        ->scalarNode('bucket_name')->end()
129
                        ->scalarNode('version')->end()
130
                        ->scalarNode('visibility')->end()
131
                    ->end()
132
                ->end()
133
            ->end();
134
135
        return $node;
136
    }
137
138
    private function configureElasticsearch(array $config, ContainerBuilder $container): void
139
    {
140
        if (isset($config['common']['elasticsearch'])) {
141
            $elasticsearchConfig = $config['common']['elasticsearch'];
142
143
            $definition = $container->getDefinition('parthenon.common.elasticsearch.config');
144
145
            if (isset($elasticsearchConfig['connection_type'])) {
146
                $definition->addMethodCall('setConnectionType', [$elasticsearchConfig['connection_type']]);
147
            }
148
149
            if (isset($elasticsearchConfig['hosts'])) {
150
                $definition->addMethodCall('setHosts', [$elasticsearchConfig['hosts']]);
151
            }
152
153
            if (isset($elasticsearchConfig['api_id'])) {
154
                $definition->addMethodCall('setApiId', [$elasticsearchConfig['api_id']]);
155
            }
156
157
            if (isset($elasticsearchConfig['api_key'])) {
158
                $definition->addMethodCall('setApiKey', [$elasticsearchConfig['api_key']]);
159
            }
160
161
            if (isset($elasticsearchConfig['basic_username'])) {
162
                $definition->addMethodCall('setBasicUsername', [$elasticsearchConfig['basic_username']]);
163
            }
164
165
            if (isset($elasticsearchConfig['basic_password'])) {
166
                $definition->addMethodCall('setBasicPassword', [$elasticsearchConfig['basic_password']]);
167
            }
168
            $container->setDefinition('parthenon.common.elasticsearch.config', $definition);
169
        }
170
    }
171
172
    /**
173
     * @throws ParameterNotSetException
174
     */
175
    private function configurePdf(array $config, ContainerBuilder $container, XmlFileLoader $loader): array
176
    {
177
        if (isset($config['common']['pdf']['generator']) && 'docraptor' === $config['common']['pdf']['generator']) {
178
            if (!class_exists(Doc::class)) {
179
                throw new MissingDependencyException('To use docraptor you need to have the docraptor/docraptor package installed. Do composer require docraptor/docraptor.');
180
            }
181
182
            if (!isset($config['common']['pdf']['docraptor']) || !$config['common']['pdf']['docraptor']['api_key']) {
183
                throw new ParameterNotSetException('When pdf generator is docraptor you need to set parthenon.common.pdf.docraptor.api_key');
184
            }
185
            $container->setParameter('parthenon_common_pdf_docraptor_api_key', $config['common']['pdf']['docraptor']['api_key']);
186
187
            $loader->load('services/common/pdf/docraptor.xml');
188
        } elseif (isset($config['common']['pdf']['generator']) && 'mpdf' === $config['common']['pdf']['generator']) {
189
            if (!class_exists(Mpdf::class)) {
190
                throw new MissingDependencyException('To use mpdf you need to have the mpdf/mpdf package installed. Do composer require mpdf/mpdf.');
191
            }
192
193
            $container->setParameter('parthenon.common.pdf.mpdf.tmp_dir', $config['common']['pdf']['mpdf']['tmp_dir']);
194
            $loader->load('services/common/pdf/mpdf.xml');
195
        } elseif (isset($config['common']['pdf']['generator']) && 'wkhtmltopdf' === $config['common']['pdf']['generator']) {
196
            if (!class_exists(\Knp\Snappy\Pdf::class)) {
197
                throw new MissingDependencyException('To use wkhtmltopdf you need to have the knplabs/knp-snappy. Do composer require knplabs/knp-snappy.');
198
            }
199
200
            $container->setParameter('parthenon_common_pdf_wkhtmltopdf_bin', $config['common']['pdf']['wkhtmltopdf']['bin']);
201
            $loader->load('services/common/pdf/wkhtmltopdf.xml');
202
        }
203
204
        return $config;
205
    }
206
207
    private function configureUploader(array $config, ContainerBuilder $container): array
208
    {
209
        if (isset($config['common']['uploader']) && is_array($config['common']['uploader'])) {
210
            $container->setParameter('parthenon_common_uploaders', $config['common']['uploader']);
211
        }
212
213
        return $config;
214
    }
215
}
216