Completed
Push — master ( f27e2e...5dd696 )
by Asmir
10s
created

SoapContainerBuilder::createSerializerBuilder()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 0
cts 14
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 11
nc 2
nop 2
crap 12
1
<?php
2
namespace GoetasWebservices\SoapServices\SoapClient\Builder;
3
4
5
use GoetasWebservices\SoapServices\SoapClient\DependencyInjection\Compiler\CleanupPass;
6
use GoetasWebservices\SoapServices\SoapClient\DependencyInjection\SoapClientExtension;
7
use GoetasWebservices\Xsd\XsdToPhpRuntime\Jms\Handler\BaseTypesHandler;
8
use GoetasWebservices\Xsd\XsdToPhpRuntime\Jms\Handler\XmlSchemaDateHandler;
9
use JMS\Serializer\Handler\HandlerRegistryInterface;
10
use JMS\Serializer\SerializerBuilder;
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\Compiler\CompilerPassInterface;
16
use Symfony\Component\DependencyInjection\ContainerBuilder;
17
use Symfony\Component\DependencyInjection\ContainerInterface;
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
    private $className = 'SoapClientContainer';
26
    private $classNs = 'SoapServicesStub';
27
28
    protected $configFile = 'config.yml';
29
    protected $extensions = [];
30
    protected $compilerPasses = [];
31
32
    /**
33
     * @var LoggerInterface
34
     */
35
    private $logger;
36
37 2
    public function __construct($configFile = null, LoggerInterface $logger = null)
38
    {
39 2
        $this->logger = $logger;
40 2
        $this->setConfigFile($configFile);
41 2
        $this->addExtension(new SoapClientExtension());
42 2
        $this->addCompilerPass(new CleanupPass());
43 2
    }
44
45 2
    public function setConfigFile($configFile)
46
    {
47 2
        $this->configFile = $configFile;
48 2
    }
49
50 2
    protected function addExtension(ExtensionInterface $extension)
51
    {
52 2
        $this->extensions[] = $extension;
53 2
    }
54
55 2
    protected function addCompilerPass(CompilerPassInterface $pass)
56
    {
57 2
        $this->compilerPasses[] = $pass;
58 2
    }
59
60
    public function setContainerClassName($fqcn)
61
    {
62
        $fqcn = strtr($fqcn, ['.' => '\\', '/' => '\\',]);
63
        $pos = strrpos($fqcn, '\\');
64
        $this->className = substr($fqcn, $pos + 1);
65
        $this->classNs = substr($fqcn, 0, $pos);
66
    }
67
68
    /**
69
     * @param array $metadata
70
     * @return ContainerBuilder
71
     */
72 2
    protected function getContainerBuilder(array $metadata = array())
73
    {
74 2
        $container = new ContainerBuilder();
75
76 2
        foreach ($this->extensions as $extension) {
77 2
            $container->registerExtension($extension);
78 2
        }
79
80 2
        foreach ($this->compilerPasses as $pass) {
81 2
            $container->addCompilerPass($pass);
82 2
        }
83
84 2
        $locator = new FileLocator('.');
85
        $loaders = array(
86 2
            new YamlFileLoader($container, $locator),
87 2
            new XmlFileLoader($container, $locator)
88 2
        );
89 2
        $delegatingLoader = new DelegatingLoader(new LoaderResolver($loaders));
90 2
        $delegatingLoader->load($this->configFile);
91
92
93
        // set the production soap metadata
94 2
        $container->setParameter('goetas_webservices.soap_client.metadata', $metadata);
95
96 2
        $container->compile();
97
98 2
        return $container;
99
    }
100
101
    /**
102
     * @param ContainerInterface $debugContainer
103
     * @return array
104
     */
105 1
    protected function fetchMetadata(ContainerInterface $debugContainer)
106
    {
107 1
        $metadataReader = $debugContainer->get('goetas_webservices.soap_client.metadata_loader.dev');
108 1
        $wsdlMetadata = $debugContainer->getParameter('goetas_webservices.soap_client.config')['metadata'];
109 1
        $metadata = [];
110 1
        foreach (array_keys($wsdlMetadata) as $uri) {
111 1
            $metadata[$uri] = $metadataReader->load($uri);
112 1
        }
113
114 1
        return $metadata;
115
    }
116
117 2
    public function getDebugContainer()
118
    {
119 2
        return $this->getContainerBuilder();
120
    }
121
122
    /**
123
     * @return ContainerInterface
124
     */
125
    public function getProdContainer()
126
    {
127
        $ref = new \ReflectionClass("{$this->classNs}\\{$this->className}");
128
        return $ref->newInstance();
129
    }
130
131
    /**
132
     * @param $dir
133
     * @param ContainerInterface $debugContainer
134
     */
135 1
    public function dumpContainerForProd($dir, ContainerInterface $debugContainer)
136
    {
137 1
        $metadata = $this->fetchMetadata($debugContainer);
138
139 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...
140
            throw new \Exception("Empty metadata can not be used for production");
141
        }
142 1
        $forProdContainer = $this->getContainerBuilder($metadata);
143 1
        $this->dump($forProdContainer, $dir);
144 1
    }
145
146 1
    private function dump(ContainerBuilder $container, $dir)
147
    {
148 1
        $dumper = new PhpDumper($container);
149
        $options = [
150 1
            'debug' => false,
151 1
            'class' => $this->className,
152 1
            'namespace' => $this->classNs
153 1
        ];
154
155 1
        if (!is_dir($dir)) {
156
            mkdir($dir, 0777, true);
157
        }
158
159 1
        file_put_contents($dir . '/' . $this->className . '.php', $dumper->dump($options));
160 1
    }
161
162
    /**
163
     * @param ContainerInterface $container
164
     * @param callable $callback
165
     * @return SerializerBuilder
166
     */
167
    public static function createSerializerBuilderFromContainer(ContainerInterface $container, callable $callback = null)
168
    {
169
        $destinations = $container->getParameter('goetas_webservices.soap_client.config')['destinations_jms'];
170
        return self::createSerializerBuilder($destinations, $callback);
171
    }
172
173
    /**
174
     * @param array $jmsMetadata
175
     * @param callable $callback
176
     * @return SerializerBuilder
177
     */
178
    public static function createSerializerBuilder(array $jmsMetadata, callable $callback = null)
179
    {
180
        $serializerBuilder = SerializerBuilder::create();
181
        $serializerBuilder->configureHandlers(function (HandlerRegistryInterface $handler) use ($callback, $serializerBuilder) {
182
            $serializerBuilder->addDefaultHandlers();
183
            $handler->registerSubscribingHandler(new BaseTypesHandler()); // XMLSchema List handling
184
            $handler->registerSubscribingHandler(new XmlSchemaDateHandler()); // XMLSchema date handling
185
            if ($callback) {
186
                call_user_func($callback, $handler);
187
            }
188
        });
189
190
191
        foreach ($jmsMetadata as $php => $dir) {
192
            $serializerBuilder->addMetadataDir($dir, $php);
193
        }
194
        return $serializerBuilder;
195
    }
196
}
197
198