Completed
Push — master ( 900879...537117 )
by Asmir
02:18
created

SoapContainerBuilder::getDebugContainer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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