Completed
Push — master ( 9c5fdf...27a5d2 )
by John
7s
created

resolveOperationBodyType()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
rs 8.8571
cc 5
eloc 6
nc 3
nop 1
1
<?php declare(strict_types = 1);
2
/*
3
 * This file is part of the KleijnWeb\SwaggerBundle package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
namespace KleijnWeb\SwaggerBundle\Serialize;
9
10
use KleijnWeb\SwaggerBundle\Document\Specification\Operation;
11
12
class SerializationTypeResolver
13
{
14
    /**
15
     * @var array
16
     */
17
    private $resourceNamespaces = [];
18
19
    /**
20
     * @var array
21
     */
22
    private $lookupTable = [];
23
24
    /**
25
     * SerializationTypeResolver constructor.
26
     *
27
     * @param array $resourceNamespaces
28
     */
29
    public function __construct(array $resourceNamespaces)
30
    {
31
        $this->resourceNamespaces = $resourceNamespaces;
32
    }
33
34
    /**
35
     * @param Operation $operationObject
36
     *
37
     * @return string
38
     */
39
    public function resolveOperationBodyType(Operation $operationObject): string
40
    {
41
        if ($operationObject->hasParameters()) {
42
            foreach ($operationObject->getParameters() as $parameterDefinition) {
43
                if ($parameterDefinition->in == 'body' && isset($parameterDefinition->schema)) {
44
                    return $this->resolveUsingSchema($parameterDefinition->schema);
45
                }
46
            }
47
        }
48
49
        throw new \InvalidArgumentException("Failed to resolve type");
50
    }
51
52
    /**
53
     * @param \stdClass $schema
54
     *
55
     * @return string
56
     */
57
    public function resolveUsingSchema(\stdClass $schema): string
58
    {
59
        $reference = isset($schema->{'$ref'})
60
            ? $schema->{'$ref'}
61
            : (isset($schema->{'x-ref-id'}) ? $schema->{'x-ref-id'} : null);
62
63
        if ($reference) {
64
            return $this->resolveUsingTypeName(
65
                substr($reference, strrpos($reference, '/') + 1)
66
            );
67
        }
68
69
        throw new \InvalidArgumentException("Failed to resolve type using schema");
70
    }
71
72
    /**
73
     * @param string $typeName
74
     *
75
     * @return string
76
     */
77
    public function resolveUsingTypeName(string $typeName): string
78
    {
79
        if (isset($this->lookupTable[$typeName])) {
80
            return $this->lookupTable[$typeName];
81
        }
82
83
        foreach ($this->resourceNamespaces as $resourceNamespace) {
84
            $resourceFullNamespacedName = $this->qualify($resourceNamespace, $typeName);
85
            if (class_exists($resourceFullNamespacedName)) {
86
                $this->lookupTable[$typeName] = $resourceFullNamespacedName;
87
88
                return $resourceFullNamespacedName;
89
            }
90
        }
91
92
        throw new \InvalidArgumentException("Failed to resolve type '$typeName' to a class name");
93
    }
94
95
    /**
96
     * @param string $resourceFullNamespacedName
97
     *
98
     * @return string
99
     */
100
    public function reverseLookup(string $resourceFullNamespacedName): string
101
    {
102
        $table = array_flip($this->lookupTable);
103
104
        if (isset($table[$resourceFullNamespacedName])) {
105
            return $table[$resourceFullNamespacedName];
106
        }
107
108
        throw new \InvalidArgumentException("Unknown class '$resourceFullNamespacedName' or not resolved yet");
109
110
    }
111
112
    /**
113
     * @param string $resourceNamespace
114
     * @param string $typeName
115
     *
116
     * @return string
117
     */
118
    protected function qualify(string $resourceNamespace, string $typeName): string
119
    {
120
        return ltrim($resourceNamespace . '\\' . $typeName, '\\');
121
    }
122
}
123