xref: /dokuwiki/inc/Remote/OpenApiDoc/DocBlockMethod.php (revision dd7472d3f89d3f537224163206d7dbf31ffdad22)
18ddd9b69SAndreas Gohr<?php
28ddd9b69SAndreas Gohr
38ddd9b69SAndreas Gohrnamespace dokuwiki\Remote\OpenApiDoc;
48ddd9b69SAndreas Gohr
5*dd7472d3SAndreas Gohruse ReflectionFunction;
68ddd9b69SAndreas Gohruse ReflectionMethod;
78ddd9b69SAndreas Gohr
88ddd9b69SAndreas Gohrclass DocBlockMethod extends DocBlock
98ddd9b69SAndreas Gohr{
108ddd9b69SAndreas Gohr
118ddd9b69SAndreas Gohr    /**
128ddd9b69SAndreas Gohr     * Parse the given docblock
138ddd9b69SAndreas Gohr     *
148ddd9b69SAndreas Gohr     * The docblock can be of a method, class or property.
158ddd9b69SAndreas Gohr     *
16*dd7472d3SAndreas Gohr     * @param ReflectionMethod|ReflectionFunction $reflector
178ddd9b69SAndreas Gohr     */
18*dd7472d3SAndreas Gohr    public function __construct($reflector)
198ddd9b69SAndreas Gohr    {
208ddd9b69SAndreas Gohr        parent::__construct($reflector);
218ddd9b69SAndreas Gohr        $this->refineParam();
228ddd9b69SAndreas Gohr        $this->refineReturn();
238ddd9b69SAndreas Gohr    }
248ddd9b69SAndreas Gohr
25*dd7472d3SAndreas Gohr    protected function getContext()
26*dd7472d3SAndreas Gohr    {
27*dd7472d3SAndreas Gohr        if($this->reflector instanceof ReflectionFunction) {
28*dd7472d3SAndreas Gohr            return null;
29*dd7472d3SAndreas Gohr        }
30*dd7472d3SAndreas Gohr        return parent::getContext();
31*dd7472d3SAndreas Gohr    }
328ddd9b69SAndreas Gohr
33*dd7472d3SAndreas Gohr    /**
34*dd7472d3SAndreas Gohr     * Convenience method to access the method parameters
35*dd7472d3SAndreas Gohr     *
36*dd7472d3SAndreas Gohr     * @return array
37*dd7472d3SAndreas Gohr     */
38*dd7472d3SAndreas Gohr    public function getParameters()
39*dd7472d3SAndreas Gohr    {
40*dd7472d3SAndreas Gohr        return $this->getTag('param');
41*dd7472d3SAndreas Gohr    }
42*dd7472d3SAndreas Gohr
43*dd7472d3SAndreas Gohr    /**
44*dd7472d3SAndreas Gohr     * Convenience method to access the method return
45*dd7472d3SAndreas Gohr     *
46*dd7472d3SAndreas Gohr     * @return array
47*dd7472d3SAndreas Gohr     */
48*dd7472d3SAndreas Gohr    public function getReturn()
49*dd7472d3SAndreas Gohr    {
50*dd7472d3SAndreas Gohr        return $this->getTag('return');
51*dd7472d3SAndreas Gohr    }
528ddd9b69SAndreas Gohr
538ddd9b69SAndreas Gohr    /**
548ddd9b69SAndreas Gohr     * Parse the param tag into its components
558ddd9b69SAndreas Gohr     *
568ddd9b69SAndreas Gohr     * @return void
578ddd9b69SAndreas Gohr     */
588ddd9b69SAndreas Gohr    protected function refineParam()
598ddd9b69SAndreas Gohr    {
608ddd9b69SAndreas Gohr        $result = [];
618ddd9b69SAndreas Gohr
628ddd9b69SAndreas Gohr        // prefill from reflection
638ddd9b69SAndreas Gohr        foreach ($this->reflector->getParameters() as $parameter) {
648ddd9b69SAndreas Gohr            $refType = $parameter->getType();
658ddd9b69SAndreas Gohr            $result[$parameter->getName()] = [
668ddd9b69SAndreas Gohr                'type' => new Type($refType ? $refType->getName() : 'string', $this->getContext()),
678ddd9b69SAndreas Gohr                'optional' => $parameter->isOptional(),
688ddd9b69SAndreas Gohr                'description' => '',
698ddd9b69SAndreas Gohr            ];
708ddd9b69SAndreas Gohr            if($parameter->isDefaultValueAvailable()) {
718ddd9b69SAndreas Gohr                $result[$parameter->getName()]['default'] = $parameter->getDefaultValue();
728ddd9b69SAndreas Gohr            }
738ddd9b69SAndreas Gohr        }
748ddd9b69SAndreas Gohr
758ddd9b69SAndreas Gohr        // refine from doc tags
768ddd9b69SAndreas Gohr        foreach ($this->tags['param'] ?? [] as $param) {
778ddd9b69SAndreas Gohr            [$type, $name, $description] = array_map('trim', sexplode(' ', $param, 3, ''));
788ddd9b69SAndreas Gohr            if ($name === '' || $name[0] !== '$') continue;
798ddd9b69SAndreas Gohr            $name = substr($name, 1);
808ddd9b69SAndreas Gohr            if (!isset($result[$name])) continue; // reflection says this param does not exist
818ddd9b69SAndreas Gohr
828ddd9b69SAndreas Gohr            $result[$name]['type'] = new Type($type, $this->getContext());
838ddd9b69SAndreas Gohr            $result[$name]['description'] = $description;
848ddd9b69SAndreas Gohr        }
858ddd9b69SAndreas Gohr        $this->tags['param'] = $result;
868ddd9b69SAndreas Gohr    }
878ddd9b69SAndreas Gohr
888ddd9b69SAndreas Gohr    /**
898ddd9b69SAndreas Gohr     * Parse the return tag into its components
908ddd9b69SAndreas Gohr     *
918ddd9b69SAndreas Gohr     * @return void
928ddd9b69SAndreas Gohr     */
938ddd9b69SAndreas Gohr    protected function refineReturn()
948ddd9b69SAndreas Gohr    {
958ddd9b69SAndreas Gohr
968ddd9b69SAndreas Gohr
978ddd9b69SAndreas Gohr        // prefill from reflection
988ddd9b69SAndreas Gohr        $refType = $this->reflector->getReturnType();
998ddd9b69SAndreas Gohr        $result = [
1008ddd9b69SAndreas Gohr            'type' => new Type($refType ? $refType->getName() : 'void', $this->getContext()),
1018ddd9b69SAndreas Gohr            'description' => '',
1028ddd9b69SAndreas Gohr        ];
1038ddd9b69SAndreas Gohr
1048ddd9b69SAndreas Gohr        // refine from doc tag
1058ddd9b69SAndreas Gohr        foreach ($this->tags['return'] ?? [] as $return) {
1068ddd9b69SAndreas Gohr            [$type, $description] = array_map('trim', sexplode(' ', $return, 2, ''));
107*dd7472d3SAndreas Gohr            $result['type'] = new Type($type, $this->getContext());
1088ddd9b69SAndreas Gohr            $result['description'] = $description;
1098ddd9b69SAndreas Gohr
1108ddd9b69SAndreas Gohr        }
1118ddd9b69SAndreas Gohr        $this->tags['return'] = $result;
1128ddd9b69SAndreas Gohr    }
1138ddd9b69SAndreas Gohr}
114