Completed
Push — 2.x ( 043669...4fa139 )
by Mikaël
65:52 queued 32:03
created

Service::getSoapHeaderMethodName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
namespace WsdlToPhp\PackageGenerator\File;
4
5
use WsdlToPhp\PhpGenerator\Element\PhpFunctionParameter;
6
use WsdlToPhp\PackageGenerator\Parser\Wsdl\TagHeader;
7
use WsdlToPhp\PackageGenerator\Generator\Generator;
8
use WsdlToPhp\PackageGenerator\Container\PhpElement\Method as MethodContainer;
9
use WsdlToPhp\PackageGenerator\Container\PhpElement\Property as PropertyContainer;
10
use WsdlToPhp\PackageGenerator\Container\PhpElement\Constant as ConstantContainer;
11
use WsdlToPhp\PackageGenerator\Model\AbstractModel;
12
use WsdlToPhp\PackageGenerator\Model\Service as ServiceModel;
13
use WsdlToPhp\PackageGenerator\Model\Method as MethodModel;
14
use WsdlToPhp\PackageGenerator\Model\Struct as StructModel;
15
use WsdlToPhp\PhpGenerator\Element\PhpConstant;
16
use WsdlToPhp\PhpGenerator\Element\PhpProperty;
17
use WsdlToPhp\PhpGenerator\Element\PhpMethod;
18
use WsdlToPhp\PhpGenerator\Element\PhpAnnotation;
19
use WsdlToPhp\PhpGenerator\Element\PhpAnnotationBlock;
20
use WsdlToPhp\PackageGenerator\ConfigurationReader\GeneratorOptions;
21
22
class Service extends AbstractModelFile
23
{
24
    /**
25
     * @var string
26
     */
27
    const METHOD_SET_HEADER_PREFIX = 'setSoapHeader';
28
    /**
29
     * @var string
30
     */
31
    const PARAM_SET_HEADER_NAMESPACE = 'nameSpace';
32
    /**
33
     * @var string
34
     */
35
    const PARAM_SET_HEADER_MUSTUNDERSTAND = 'mustUnderstand';
36
    /**
37
     * @var string
38
     */
39
    const PARAM_SET_HEADER_ACTOR = 'actor';
40
    /**
41
     * @var string
42
     */
43
    const METHOD_GET_RESULT = 'getResult';
44
    /**
45
     * Method model can't be found in case the original method's name is unclean:
46
     * - ex: my.operation.name becomes my_operation_name
47
     * thus the Model from Model\Service::getMethod() can't be found
48
     * So we store the generated name associated to the original method object
49
     * @var array
50
     */
51
    protected $methods = array();
52
    /**
53
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getClassConstants()
54
     */
55 84
    protected function getClassConstants(ConstantContainer $constants)
56
    {
57 84
    }
58
    /**
59
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getConstantAnnotationBlock()
60
     */
61
    protected function getConstantAnnotationBlock(PhpConstant $constant)
62
    {
63
    }
64
    /**
65
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getClassProperties()
66
     */
67 84
    protected function getClassProperties(PropertyContainer $properties)
68
    {
69 84
    }
70
    /**
71
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getPropertyAnnotationBlock()
72
     */
73
    protected function getPropertyAnnotationBlock(PhpProperty $property)
74
    {
75
    }
76
    /**
77
     * @return string
78
     */
79 84
    protected function getClassDeclarationLineText()
80
    {
81 84
        return $this->getGenerator()->getOptionGatherMethods() === GeneratorOptions::VALUE_NONE ? 'This class stands for all operations' : parent::getClassDeclarationLineText();
82
    }
83
    /**
84
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getClassMethods()
85
     */
86 84
    protected function getClassMethods(MethodContainer $methods)
87
    {
88 84
        $this->addSoapHeaderMethods($methods)->addOperationsMethods($methods)->addGetResultMethod($methods);
89 84
    }
90
    /**
91
     * @param MethodContainer $methods
92
     * @return Service
93
     */
94 84
    protected function addSoapHeaderMethods(MethodContainer $methods)
95
    {
96 84
        foreach ($this->getModel()->getMethods() as $method) {
97 84
            $this->addSoapHeaderFromMethod($methods, $method);
98 63
        }
99 84
        return $this;
100
    }
101
    /**
102
     * @param MethodContainer $methods
103
     * @param MethodModel $method
104
     * @return Service
105
     */
106 84
    protected function addSoapHeaderFromMethod(MethodContainer $methods, MethodModel $method)
107
    {
108 84
        $soapHeaderNames = $method->getMetaValue(TagHeader::META_SOAP_HEADER_NAMES, array());
109 84
        $soapHeaderNamespaces = $method->getMetaValue(TagHeader::META_SOAP_HEADER_NAMESPACES, array());
110 84
        $soapHeaderTypes = $method->getMetaValue(TagHeader::META_SOAP_HEADER_TYPES, array());
111 84
        foreach ($soapHeaderNames as $index => $soapHeaderName) {
112 20
            $methodName = $this->getSoapHeaderMethodName($soapHeaderName);
113 20
            if ($methods->get($methodName) === null) {
114 20
                $soapHeaderNamespace = array_key_exists($index, $soapHeaderNamespaces) ? $soapHeaderNamespaces[$index] : null;
115 20
                $soapHeaderType = array_key_exists($index, $soapHeaderTypes) ? $soapHeaderTypes[$index] : null;
116 20
                $methods->add($this->getSoapHeaderMethod($methodName, $soapHeaderName, $soapHeaderNamespace, $soapHeaderType));
117 15
            }
118 63
        }
119 84
        return $this;
120
    }
121
    /**
122
     * @param string $methodName
123
     * @param string $soapHeaderName
124
     * @param string $soapHeaderNamespace
125
     * @param string $soapHeaderType
126
     * @return PhpMethod
127
     */
128 20
    protected function getSoapHeaderMethod($methodName, $soapHeaderName, $soapHeaderNamespace, $soapHeaderType)
129
    {
130
        try {
131 20
            $method = new PhpMethod($methodName, array(
132 20
                new PhpFunctionParameter(lcfirst($soapHeaderName), PhpFunctionParameter::NO_VALUE, $this->getTypeFromName($soapHeaderType, true)),
133 20
                new PhpFunctionParameter(self::PARAM_SET_HEADER_NAMESPACE, $soapHeaderNamespace),
134 20
                new PhpFunctionParameter(self::PARAM_SET_HEADER_MUSTUNDERSTAND, false),
135 20
                new PhpFunctionParameter(self::PARAM_SET_HEADER_ACTOR, null),
136 15
            ));
137 20
            $method->addChild(sprintf('return $this->%s($%s, \'%s\', $%s, $%s, $%s);', self::METHOD_SET_HEADER_PREFIX, self::PARAM_SET_HEADER_NAMESPACE, $soapHeaderName, lcfirst($soapHeaderName), self::PARAM_SET_HEADER_MUSTUNDERSTAND, self::PARAM_SET_HEADER_ACTOR));
138 15
        } catch (\InvalidArgumentException $exception) {
139
            throw new \InvalidArgumentException(sprintf('Unable to create function parameter for service "%s" with type "%s"', $this->getModel()->getName(), var_export($this->getTypeFromName($soapHeaderName, true), true)), __LINE__, $exception);
140
        }
141 20
        return $method;
142
    }
143
    /**
144
     * @param string $name
145
     * @param bool $namespaced
146
     * @return string
147
     */
148 20
    protected function getTypeFromName($name, $namespaced = false)
149
    {
150 20
        $type = $name;
151 20
        $model = $this->getModelByName($name);
152 20
        if ($model instanceof AbstractModel) {
153 20
            $type = $model->getPackagedName($namespaced);
154 15
        }
155 20
        return self::getValidType($type);
156
    }
157
    /**
158
     * @param string $soapHeaderName
159
     * @return string
160
     */
161 20
    protected function getSoapHeaderMethodName($soapHeaderName)
162
    {
163 20
        return sprintf('%s%s', self::METHOD_SET_HEADER_PREFIX, ucfirst($soapHeaderName));
164
    }
165
    /**
166
     * @param MethodContainer $methods
167
     * @return Service
168
     */
169 84
    protected function addOperationsMethods(MethodContainer $methods)
170
    {
171 84
        foreach ($this->getModel()->getMethods() as $method) {
172 84
            $this->addMainMethod($methods, $method);
173 63
        }
174 84
        return $this;
175
    }
176
    /**
177
     * @param MethodContainer $methods
178
     * @return Service
179
     */
180 84
    protected function addGetResultMethod(MethodContainer $methods)
181
    {
182 84
        $method = new PhpMethod(self::METHOD_GET_RESULT);
183 84
        $method->addChild('return parent::getResult();');
184 84
        $methods->add($method);
185 84
        return $this;
186
    }
187
    /**
188
     * @param MethodContainer $methods
189
     * @param MethodModel $method
190
     * @return Service
191
     */
192 84
    protected function addMainMethod(MethodContainer $methods, MethodModel $method)
193
    {
194 84
        $methodFile = new Operation($method, $this->getGenerator());
195 84
        $mainMethod = $methodFile->getMainMethod();
196 84
        $methods->add($mainMethod);
197 84
        $this->setModelFromMethod($mainMethod, $method);
198 84
        return $this;
199
    }
200
    /**
201
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getMethodAnnotationBlock()
202
     */
203 84
    protected function getMethodAnnotationBlock(PhpMethod $method)
204
    {
205 84
        $annotationBlock = new PhpAnnotationBlock();
206 84
        if (stripos($method->getName(), self::METHOD_SET_HEADER_PREFIX) === 0) {
207 20
            $this->addAnnotationBlockForSoapHeaderMethod($annotationBlock, $method);
208 84
        } elseif ($method->getName() === self::METHOD_GET_RESULT) {
209 84
            $this->addAnnnotationBlockForgetResultMethod($annotationBlock);
210 63
        } else {
211 84
            $this->addAnnotationBlockForOperationMethod($annotationBlock, $method);
212
        }
213 84
        return $annotationBlock;
214
    }
215
    /**
216
     * @param PhpAnnotationBlock $annotationBlock
217
     * @param PhpMethod $method
218
     * @return Service
219
     */
220 20
    protected function addAnnotationBlockForSoapHeaderMethod(PhpAnnotationBlock $annotationBlock, PhpMethod $method)
221
    {
222 20
        $methodParameters = $method->getParameters();
223 20
        $firstParameter = array_shift($methodParameters);
224 20
        if ($firstParameter instanceof PhpFunctionParameter) {
225 20
            $annotationBlock->addChild(sprintf('Sets the %s SoapHeader param', ucfirst($firstParameter->getName())))
226 20
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::setSoapHeader()', $this->getModel()->getExtends(true))))
227 20
                ->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('%s $%s', $firstParameter->getType(), $firstParameter->getName())))
228 20
                ->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('string $%s', self::PARAM_SET_HEADER_NAMESPACE)))
229 20
                ->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('bool $%s', self::PARAM_SET_HEADER_MUSTUNDERSTAND)))
230 20
                ->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('string $%s', self::PARAM_SET_HEADER_ACTOR)))
231 20
                ->addChild(new PhpAnnotation(self::ANNOTATION_RETURN, 'bool'));
232 15
        }
233 20
        return $this;
234
    }
235
    /**
236
     * @param PhpAnnotationBlock $annotationBlock
237
     * @param PhpMethod $method
238
     * @return Service
239
     */
240 84
    protected function addAnnotationBlockForOperationMethod(PhpAnnotationBlock $annotationBlock, PhpMethod $method)
241
    {
242 84
        if (($model = $this->getModelFromMethod($method)) instanceof MethodModel) {
243 84
            $operationAnnotationBlock = new OperationAnnotationBlock($model, $this->getGenerator());
244 84
            $operationAnnotationBlock->addAnnotationBlockForOperationMethod($annotationBlock);
245 63
        }
246 84
        return $this;
247
    }
248
    /**
249
     * @param PhpAnnotationBlock $annotationBlock
250
     * @return Service
251
     */
252 84
    protected function addAnnnotationBlockForgetResultMethod(PhpAnnotationBlock $annotationBlock)
253
    {
254 84
        $annotationBlock->addChild('Returns the result')->addChild(new PhpAnnotation(self::ANNOTATION_SEE, sprintf('%s::getResult()', $this->getModel()->getExtends(true))))->addChild(new PhpAnnotation(self::ANNOTATION_RETURN, $this->getServiceReturnTypes()));
255 84
        return $this;
256
    }
257
    /**
258
     * @return string
259
     */
260 84
    protected function getServiceReturnTypes()
261
    {
262 84
        $returnTypes = array();
263 84
        foreach ($this->getModel()->getMethods() as $method) {
264 84
            $returnTypes[] = self::getOperationMethodReturnType($method, $this->getGenerator());
265 63
        }
266 84
        natcasesort($returnTypes);
267 84
        return implode('|', array_unique($returnTypes));
268
    }
269
    /**
270
     * @param MethodModel $method
271
     * @return string
272
     */
273 84
    public static function getOperationMethodReturnType(MethodModel $method, Generator $generator)
274
    {
275 84
        $returnType = $method->getReturnType();
276 84
        if ((($struct = $generator->getStruct($returnType)) instanceof StructModel) && !$struct->getIsRestriction()) {
277 72
            if ($struct->getIsStruct()) {
278 72
                $returnType = $struct->getPackagedName(true);
279 58
            } elseif ($struct->isArray()) {
280 12
                if (($structInheritance = $struct->getInheritanceStruct()) instanceof StructModel) {
281 12
                    $returnType = sprintf('%s[]', $structInheritance->getPackagedName(true));
282 9
                } else {
283 8
                    $returnType = $struct->getInheritance();
284
                }
285 9
            }
286 54
        }
287 84
        return $returnType;
288
    }
289
    /**
290
     * @param PhpMethod $method
291
     * @return MethodModel|null
292
     */
293 84
    protected function getModelFromMethod(PhpMethod $method)
294
    {
295 84
        $model = $this->getGenerator()->getServiceMethod($method->getName());
296 84
        if (!$model instanceof MethodModel) {
297 16
            $model = array_key_exists($method->getName(), $this->methods) ? $this->methods[$method->getName()] : null;
298 12
        }
299 84
        return $model;
300
    }
301
    /**
302
     * @param PhpMethod $phpMethod
303
     * @param MethodModel $methodModel
304
     * @return Service
305
     */
306 84
    protected function setModelFromMethod(PhpMethod $phpMethod, MethodModel $methodModel)
307
    {
308 84
        $this->methods[$phpMethod->getName()] = $methodModel;
309 84
        return $this;
310
    }
311
    /**
312
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getModel()
313
     * @return ServiceModel
314
     */
315 88
    public function getModel()
316
    {
317 88
        return parent::getModel();
318
    }
319
    /**
320
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::setModel()
321
     * @throws \InvalidaArgumentException
322
     * @param AbstractModel $model
323
     * @return Service
324
     */
325 92
    public function setModel(AbstractModel $model)
326
    {
327 92
        if (!$model instanceof ServiceModel) {
328 4
            throw new \InvalidArgumentException('Model must be an instance of a Service', __LINE__);
329
        }
330 88
        return parent::setModel($model);
331
    }
332
}
333