xref: /dokuwiki/inc/Remote/OpenApiDoc/Type.php (revision dd7472d3f89d3f537224163206d7dbf31ffdad22)
18ddd9b69SAndreas Gohr<?php
28ddd9b69SAndreas Gohr
38ddd9b69SAndreas Gohrnamespace dokuwiki\Remote\OpenApiDoc;
48ddd9b69SAndreas Gohr
58ddd9b69SAndreas Gohrclass Type
68ddd9b69SAndreas Gohr{
78ddd9b69SAndreas Gohr    protected $typehint;
88ddd9b69SAndreas Gohr    protected $context;
98ddd9b69SAndreas Gohr
108ddd9b69SAndreas Gohr    /**
118ddd9b69SAndreas Gohr     * @param string $typehint The typehint as read from the docblock
128ddd9b69SAndreas Gohr     * @param string $context A fully qualified class name in which context the typehint is used
138ddd9b69SAndreas Gohr     */
148ddd9b69SAndreas Gohr    public function __construct($typehint, $context = '')
158ddd9b69SAndreas Gohr    {
168ddd9b69SAndreas Gohr        $this->typehint = $typehint;
178ddd9b69SAndreas Gohr        $this->context = $context;
188ddd9b69SAndreas Gohr    }
198ddd9b69SAndreas Gohr
208ddd9b69SAndreas Gohr    /**
2153c2a557SAndreas Gohr     * Return the typehint as read from the docblock
2253c2a557SAndreas Gohr     *
2353c2a557SAndreas Gohr     * @return string
2453c2a557SAndreas Gohr     */
2553c2a557SAndreas Gohr    public function __toString()
2653c2a557SAndreas Gohr    {
2753c2a557SAndreas Gohr        return $this->typehint;
2853c2a557SAndreas Gohr    }
2953c2a557SAndreas Gohr
3053c2a557SAndreas Gohr    /**
31*dd7472d3SAndreas Gohr     * Return the base type
328ddd9b69SAndreas Gohr     *
33*dd7472d3SAndreas Gohr     * This is the type this variable is. Eg. a string[] is an array.
34*dd7472d3SAndreas Gohr     *
358ddd9b69SAndreas Gohr     * @return string
368ddd9b69SAndreas Gohr     */
37*dd7472d3SAndreas Gohr    public function getBaseType()
388ddd9b69SAndreas Gohr    {
39*dd7472d3SAndreas Gohr        $typehint = $this->typehint;
40*dd7472d3SAndreas Gohr
418ddd9b69SAndreas Gohr        if (str_ends_with($typehint, '[]')) {
428ddd9b69SAndreas Gohr            return 'array';
438ddd9b69SAndreas Gohr        }
448ddd9b69SAndreas Gohr
458ddd9b69SAndreas Gohr        if (in_array($typehint, ['boolean', 'false', 'true'])) {
468ddd9b69SAndreas Gohr            return 'bool';
478ddd9b69SAndreas Gohr        }
488ddd9b69SAndreas Gohr
498ddd9b69SAndreas Gohr        if (in_array($typehint, ['integer', 'date'])) {
508ddd9b69SAndreas Gohr            return 'int';
518ddd9b69SAndreas Gohr        }
528ddd9b69SAndreas Gohr
538ddd9b69SAndreas Gohr        if ($typehint === 'file') {
548ddd9b69SAndreas Gohr            return 'string';
558ddd9b69SAndreas Gohr        }
568ddd9b69SAndreas Gohr
578ddd9b69SAndreas Gohr        // fully qualified class name
588ddd9b69SAndreas Gohr        if ($typehint[0] === '\\') {
598ddd9b69SAndreas Gohr            return ltrim($typehint, '\\');
608ddd9b69SAndreas Gohr        }
618ddd9b69SAndreas Gohr
628ddd9b69SAndreas Gohr        // relative class name, try to resolve
638ddd9b69SAndreas Gohr        if ($this->context && ctype_upper($typehint[0])) {
648ddd9b69SAndreas Gohr            return ClassResolver::getInstance()->resolve($typehint, $this->context);
658ddd9b69SAndreas Gohr        }
668ddd9b69SAndreas Gohr
678ddd9b69SAndreas Gohr        return $typehint;
688ddd9b69SAndreas Gohr    }
698ddd9b69SAndreas Gohr
708ddd9b69SAndreas Gohr    /**
718ddd9b69SAndreas Gohr     * Return a primitive type understood by the XMLRPC server
728ddd9b69SAndreas Gohr     *
738ddd9b69SAndreas Gohr     * @param string $typehint
748ddd9b69SAndreas Gohr     * @return string
758ddd9b69SAndreas Gohr     */
768ddd9b69SAndreas Gohr    public function getJSONRPCType()
778ddd9b69SAndreas Gohr    {
78*dd7472d3SAndreas Gohr        return $this->getBaseType();
798ddd9b69SAndreas Gohr    }
808ddd9b69SAndreas Gohr
818ddd9b69SAndreas Gohr    /**
82*dd7472d3SAndreas Gohr     * Get the base type as one of the supported OpenAPI types
83*dd7472d3SAndreas Gohr     *
84*dd7472d3SAndreas Gohr     * Formats (eg. int32 or double) are not supported
85*dd7472d3SAndreas Gohr     *
86*dd7472d3SAndreas Gohr     * @link https://swagger.io/docs/specification/data-models/data-types/
87*dd7472d3SAndreas Gohr     * @return string
88*dd7472d3SAndreas Gohr     */
89*dd7472d3SAndreas Gohr    public function getOpenApiType()
90*dd7472d3SAndreas Gohr    {
91*dd7472d3SAndreas Gohr        switch ($this->getBaseType()) {
92*dd7472d3SAndreas Gohr            case 'int':
93*dd7472d3SAndreas Gohr                return 'integer';
94*dd7472d3SAndreas Gohr            case 'bool':
95*dd7472d3SAndreas Gohr                return 'boolean';
96*dd7472d3SAndreas Gohr            case 'array':
97*dd7472d3SAndreas Gohr                return 'array';
98*dd7472d3SAndreas Gohr            case 'string':
99*dd7472d3SAndreas Gohr            case 'mixed':
100*dd7472d3SAndreas Gohr                return 'string';
101*dd7472d3SAndreas Gohr            case 'double':
102*dd7472d3SAndreas Gohr            case 'float':
103*dd7472d3SAndreas Gohr                return 'number';
104*dd7472d3SAndreas Gohr            default:
105*dd7472d3SAndreas Gohr                return 'object';
106*dd7472d3SAndreas Gohr        }
107*dd7472d3SAndreas Gohr    }
108*dd7472d3SAndreas Gohr
109*dd7472d3SAndreas Gohr
110*dd7472d3SAndreas Gohr    /**
1118ddd9b69SAndreas Gohr     * If this is an array, return the type of the array elements
1128ddd9b69SAndreas Gohr     *
1138ddd9b69SAndreas Gohr     * @return Type|null null if this is not a typed array
1148ddd9b69SAndreas Gohr     */
1158ddd9b69SAndreas Gohr    public function getSubType()
1168ddd9b69SAndreas Gohr    {
1178ddd9b69SAndreas Gohr        $type = $this->typehint;
1188ddd9b69SAndreas Gohr        if (!str_ends_with($type, '[]')) {
1198ddd9b69SAndreas Gohr            return null;
1208ddd9b69SAndreas Gohr        }
1218ddd9b69SAndreas Gohr        $type = substr($type, 0, -2);
1228ddd9b69SAndreas Gohr        return new Type($type, $this->context);
1238ddd9b69SAndreas Gohr    }
1248ddd9b69SAndreas Gohr
1258ddd9b69SAndreas Gohr    /**
1268ddd9b69SAndreas Gohr     * Return a type understood by the XMLRPC server
1278ddd9b69SAndreas Gohr     *
1288ddd9b69SAndreas Gohr     * @return string
1298ddd9b69SAndreas Gohr     */
1308ddd9b69SAndreas Gohr    public function getXMLRPCType()
1318ddd9b69SAndreas Gohr    {
1328ddd9b69SAndreas Gohr        $type = $this->typehint;
1338ddd9b69SAndreas Gohr
1348ddd9b69SAndreas Gohr        // keep custom types
1358ddd9b69SAndreas Gohr        if (in_array($type, ['date', 'file', 'struct'])) {
1368ddd9b69SAndreas Gohr            return $type;
1378ddd9b69SAndreas Gohr        }
1388ddd9b69SAndreas Gohr
139*dd7472d3SAndreas Gohr        $type = $this->getBaseType($this->typehint);
1408ddd9b69SAndreas Gohr
1418ddd9b69SAndreas Gohr        // primitive types
1428ddd9b69SAndreas Gohr        if (in_array($type, ['int', 'string', 'double', 'bool', 'array'])) {
1438ddd9b69SAndreas Gohr            return $type;
1448ddd9b69SAndreas Gohr        }
1458ddd9b69SAndreas Gohr
1468ddd9b69SAndreas Gohr        // everything else is an object
1478ddd9b69SAndreas Gohr        return 'object'; //should this return 'struct'?
1488ddd9b69SAndreas Gohr    }
1498ddd9b69SAndreas Gohr}
150