SoapContainerBuilder   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 211
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 15

Test Coverage

Coverage 59.38%

Importance

Changes 0
Metric Value
wmc 22
lcom 2
cbo 15
dl 0
loc 211
ccs 57
cts 96
cp 0.5938
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A setConfigFile() 0 4 1
A addExtension() 0 4 1
A addCompilerPass() 0 4 1
A setContainerClassName() 0 10 1
A getContainerBuilder() 0 27 3
A fetchMetadata() 0 11 2
A getDebugContainer() 0 4 1
A getProdContainer() 0 5 1
A dumpContainerForProd() 0 10 2
A dump() 0 15 2
A createSerializerBuilderFromContainer() 0 12 2
A createSerializerBuilder() 0 20 3
A getMetadataForSoapEnvelope() 0 4 1
1
<?php
2
namespace GoetasWebservices\SoapServices\SoapClient\Builder;
3
4
use GoetasWebservices\SoapServices\SoapClient\DependencyInjection\SoapClientExtension;
5
use GoetasWebservices\SoapServices\SoapClient\DependencyInjection\Compiler\CleanupPass;
6
use GoetasWebservices\SoapServices\SoapClient\Envelope\Handler\FaultHandler;
7
use GoetasWebservices\Xsd\XsdToPhpRuntime\Jms\Handler\BaseTypesHandler;
8
use GoetasWebservices\Xsd\XsdToPhpRuntime\Jms\Handler\XmlSchemaDateHandler;
9
use JMS\Serializer\SerializerBuilder;
10
use JMS\Serializer\Handler\HandlerRegistryInterface;
11
use Psr\Log\LoggerInterface;
12
use Symfony\Component\Config\FileLocator;
13
use Symfony\Component\Config\Loader\DelegatingLoader;
14
use Symfony\Component\Config\Loader\LoaderResolver;
15
use Symfony\Component\DependencyInjection\ContainerBuilder;
16
use Symfony\Component\DependencyInjection\ContainerInterface;
17
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
18
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
19
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
20
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
21
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
22
23
class SoapContainerBuilder
24
{
25
26
    private $className = 'SoapClientContainer';
27
28
    private $classNs = 'SoapServicesStub';
29
30
    protected $configFile = 'config.yml';
31
32
    protected $extensions = [];
33
34
    protected $compilerPasses = [];
35
36
    protected static $metadataForSoapEnvelope = [
37
        'GoetasWebservices\SoapServices\SoapClient\Envelope\SoapEnvelope12' => __DIR__ . '/../Resources/metadata/jms12',
38
        'GoetasWebservices\SoapServices\SoapClient\Envelope\SoapEnvelope' => __DIR__ . '/../Resources/metadata/jms'
39
    ];
40
41
    /**
42
     *
43
     * @var LoggerInterface
44
     */
45
    private $logger;
46
47 2
    public function __construct($configFile = null, LoggerInterface $logger = null)
48
    {
49 2
        $this->logger = $logger;
50 2
        $this->setConfigFile($configFile);
51 2
        $this->addExtension(new SoapClientExtension());
52 2
        $this->addCompilerPass(new CleanupPass());
53 2
    }
54
55 2
    public function setConfigFile($configFile)
56
    {
57 2
        $this->configFile = $configFile;
58 2
    }
59
60 2
    protected function addExtension(ExtensionInterface $extension)
61
    {
62 2
        $this->extensions[] = $extension;
63 2
    }
64
65 2
    protected function addCompilerPass(CompilerPassInterface $pass)
66
    {
67 2
        $this->compilerPasses[] = $pass;
68 2
    }
69
70
    public function setContainerClassName($fqcn)
71
    {
72
        $fqcn = strtr($fqcn, [
73
            '.' => '\\',
74
            '/' => '\\'
75
        ]);
76
        $pos = strrpos($fqcn, '\\');
77
        $this->className = substr($fqcn, $pos + 1);
78
        $this->classNs = substr($fqcn, 0, $pos);
79
    }
80
81
    /**
82
     *
83
     * @param array $metadata
84
     * @return ContainerBuilder
85
     */
86 2
    protected function getContainerBuilder(array $metadata = array())
87
    {
88 2
        $container = new ContainerBuilder();
89
90 2
        foreach ($this->extensions as $extension) {
91 2
            $container->registerExtension($extension);
92 2
        }
93
94 2
        foreach ($this->compilerPasses as $pass) {
95 2
            $container->addCompilerPass($pass);
96 2
        }
97
98 2
        $locator = new FileLocator('.');
99
        $loaders = array(
100 2
            new YamlFileLoader($container, $locator),
101 2
            new XmlFileLoader($container, $locator)
102 2
        );
103 2
        $delegatingLoader = new DelegatingLoader(new LoaderResolver($loaders));
104 2
        $delegatingLoader->load($this->configFile);
105
106
        // set the production soap metadata
107 2
        $container->setParameter('goetas_webservices.soap_client.metadata', $metadata);
108
109 2
        $container->compile();
110
111 2
        return $container;
112
    }
113
114
    /**
115
     *
116
     * @param ContainerInterface $debugContainer
117
     * @return array
118
     */
119 1
    protected function fetchMetadata(ContainerInterface $debugContainer)
120
    {
121 1
        $metadataReader = $debugContainer->get('goetas_webservices.soap_client.metadata_loader.dev');
122 1
        $wsdlMetadata = $debugContainer->getParameter('goetas_webservices.soap_client.config')['metadata'];
123 1
        $metadata = [];
124 1
        foreach (array_keys($wsdlMetadata) as $uri) {
125 1
            $metadata[$uri] = $metadataReader->load($uri);
126 1
        }
127
128 1
        return $metadata;
129
    }
130
131 2
    public function getDebugContainer()
132
    {
133 2
        return $this->getContainerBuilder();
134
    }
135
136
    /**
137
     *
138
     * @return ContainerInterface
139
     */
140
    public function getProdContainer()
141
    {
142
        $ref = new \ReflectionClass("{$this->classNs}\\{$this->className}");
143
        return $ref->newInstance();
144
    }
145
146
    /**
147
     *
148
     * @param
149
     *            $dir
150
     * @param ContainerInterface $debugContainer
151
     */
152 1
    public function dumpContainerForProd($dir, ContainerInterface $debugContainer)
153
    {
154 1
        $metadata = $this->fetchMetadata($debugContainer);
155
156 1
        if (! $metadata) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $metadata of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
157
            throw new \Exception("Empty metadata can not be used for production");
158
        }
159 1
        $forProdContainer = $this->getContainerBuilder($metadata);
160 1
        $this->dump($forProdContainer, $dir);
161 1
    }
162
163 1
    private function dump(ContainerBuilder $container, $dir)
164
    {
165 1
        $dumper = new PhpDumper($container);
166
        $options = [
167 1
            'debug' => false,
168 1
            'class' => $this->className,
169 1
            'namespace' => $this->classNs
170 1
        ];
171
172 1
        if (! is_dir($dir)) {
173
            mkdir($dir, 0777, true);
174
        }
175
176 1
        file_put_contents($dir . '/' . $this->className . '.php', $dumper->dump($options));
177 1
    }
178
179
    /**
180
     * @param ContainerInterface $container
181
     * @param callable $callback
182
     * @param string $metadataDirPrefix
183
     * @return SerializerBuilder
184
     */
185
    public static function createSerializerBuilderFromContainer(ContainerInterface $container, callable $callback = null, $metadataDirPrefix = null)
186
    {
187
        $destinations = $container->getParameter('goetas_webservices.soap_client.config')['destinations_jms'];
188
189
        if ($metadataDirPrefix !== null) {
190
            $destinations = array_map(function ($dir) use ($metadataDirPrefix) {
191
                return rtrim($metadataDirPrefix, '/') . '/' . $dir;
192
            }, $destinations);
193
        }
194
195
        return self::createSerializerBuilder($destinations, $callback);
196
    }
197
198
    /**
199
     *
200
     * @param array $jmsMetadata
201
     * @param callable $callback
202
     * @return SerializerBuilder
203
     */
204
    public static function createSerializerBuilder(array $jmsMetadata, callable $callback = null)
205
    {
206
        $jmsMetadata = array_merge(self::getMetadataForSoapEnvelope(), $jmsMetadata);
207
208
        $serializerBuilder = SerializerBuilder::create();
209
        $serializerBuilder->configureHandlers(function (HandlerRegistryInterface $handler) use ($callback, $serializerBuilder) {
210
            $serializerBuilder->addDefaultHandlers();
211
            $handler->registerSubscribingHandler(new BaseTypesHandler()); // XMLSchema List handling
212
            $handler->registerSubscribingHandler(new XmlSchemaDateHandler()); // XMLSchema date handling
213
            $handler->registerSubscribingHandler(new FaultHandler());
214
            if ($callback) {
215
                call_user_func($callback, $handler);
216
            }
217
        });
218
219
        foreach ($jmsMetadata as $php => $dir) {
220
            $serializerBuilder->addMetadataDir($dir, $php);
221
        }
222
        return $serializerBuilder;
223
    }
224
225
    /**
226
     *
227
     * @return string[]
228
     */
229
    public static function getMetadataForSoapEnvelope()
230
    {
231
        return self::$metadataForSoapEnvelope;
232
    }
233
}
234