aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/inc/Remote/OpenApiDoc/Type.php
blob: 209fba4706db8e4a460628747829cf3eb64b1ecd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<?php

namespace dokuwiki\Remote\OpenApiDoc;

class Type
{
    protected $typehint;
    protected $context;

    /**
     * @param string $typehint The typehint as read from the docblock
     * @param string $context A fully qualified class name in which context the typehint is used
     */
    public function __construct($typehint, $context = '')
    {
        $this->typehint = $typehint;
        $this->context = $context;
    }

    /**
     * Return the typehint as read from the docblock
     *
     * @return string
     */
    public function __toString()
    {
        return $this->typehint;
    }

    /**
     * Return the base type
     *
     * This is the type this variable is. Eg. a string[] is an array.
     *
     * @return string
     */
    public function getBaseType()
    {
        $typehint = $this->typehint;

        if (str_ends_with($typehint, '[]')) {
            return 'array';
        }

        if (in_array($typehint, ['boolean', 'false', 'true'])) {
            return 'bool';
        }

        if (in_array($typehint, ['integer', 'date'])) {
            return 'int';
        }

        if ($typehint === 'file') {
            return 'string';
        }

        // fully qualified class name
        if ($typehint[0] === '\\') {
            return ltrim($typehint, '\\');
        }

        // relative class name, try to resolve
        if ($this->context && ctype_upper($typehint[0])) {
            return ClassResolver::getInstance()->resolve($typehint, $this->context);
        }

        return $typehint;
    }

    /**
     * Return a primitive type understood by the XMLRPC server
     *
     * @param string $typehint
     * @return string
     */
    public function getJSONRPCType()
    {
        return $this->getBaseType();
    }

    /**
     * Get the base type as one of the supported OpenAPI types
     *
     * Formats (eg. int32 or double) are not supported
     *
     * @link https://swagger.io/docs/specification/data-models/data-types/
     * @return string
     */
    public function getOpenApiType()
    {
        switch ($this->getBaseType()) {
            case 'int':
                return 'integer';
            case 'bool':
                return 'boolean';
            case 'array':
                return 'array';
            case 'string':
            case 'mixed':
                return 'string';
            case 'double':
            case 'float':
                return 'number';
            default:
                return 'object';
        }
    }


    /**
     * If this is an array, return the type of the array elements
     *
     * @return Type|null null if this is not a typed array
     */
    public function getSubType()
    {
        $type = $this->typehint;
        if (!str_ends_with($type, '[]')) {
            return null;
        }
        $type = substr($type, 0, -2);
        return new Type($type, $this->context);
    }

    /**
     * Return a type understood by the XMLRPC server
     *
     * @return string
     */
    public function getXMLRPCType()
    {
        $type = $this->typehint;

        // keep custom types
        if (in_array($type, ['date', 'file', 'struct'])) {
            return $type;
        }

        $type = $this->getBaseType($this->typehint);

        // primitive types
        if (in_array($type, ['int', 'string', 'double', 'bool', 'array'])) {
            return $type;
        }

        // everything else is an object
        return 'object'; //should this return 'struct'?
    }
}