xref: /dokuwiki/inc/Remote/OpenApiDoc/DocBlockMethod.php (revision d48c2b252a339bed693da46fae768d93f4b3fe41)
18ddd9b69SAndreas Gohr<?php
28ddd9b69SAndreas Gohr
38ddd9b69SAndreas Gohrnamespace dokuwiki\Remote\OpenApiDoc;
48ddd9b69SAndreas Gohr
5dd7472d3SAndreas Gohruse ReflectionFunction;
68ddd9b69SAndreas Gohruse ReflectionMethod;
78ddd9b69SAndreas Gohr
88ddd9b69SAndreas Gohrclass DocBlockMethod extends DocBlock
98ddd9b69SAndreas Gohr{
108ddd9b69SAndreas Gohr    /**
118ddd9b69SAndreas Gohr     * Parse the given docblock
128ddd9b69SAndreas Gohr     *
138ddd9b69SAndreas Gohr     * The docblock can be of a method, class or property.
148ddd9b69SAndreas Gohr     *
15dd7472d3SAndreas Gohr     * @param ReflectionMethod|ReflectionFunction $reflector
168ddd9b69SAndreas Gohr     */
17dd7472d3SAndreas Gohr    public function __construct($reflector)
188ddd9b69SAndreas Gohr    {
198ddd9b69SAndreas Gohr        parent::__construct($reflector);
208ddd9b69SAndreas Gohr        $this->refineParam();
218ddd9b69SAndreas Gohr        $this->refineReturn();
228ddd9b69SAndreas Gohr    }
238ddd9b69SAndreas Gohr
24*d48c2b25SAndreas Gohr    /** @inheritdoc */
25dd7472d3SAndreas Gohr    protected function getContext()
26dd7472d3SAndreas Gohr    {
27dd7472d3SAndreas Gohr        if ($this->reflector instanceof ReflectionFunction) {
28dd7472d3SAndreas Gohr            return null;
29dd7472d3SAndreas Gohr        }
30dd7472d3SAndreas Gohr        return parent::getContext();
31dd7472d3SAndreas Gohr    }
328ddd9b69SAndreas Gohr
33dd7472d3SAndreas Gohr    /**
34dd7472d3SAndreas Gohr     * Convenience method to access the method parameters
35dd7472d3SAndreas Gohr     *
36dd7472d3SAndreas Gohr     * @return array
37dd7472d3SAndreas Gohr     */
38dd7472d3SAndreas Gohr    public function getParameters()
39dd7472d3SAndreas Gohr    {
40dd7472d3SAndreas Gohr        return $this->getTag('param');
41dd7472d3SAndreas Gohr    }
42dd7472d3SAndreas Gohr
43dd7472d3SAndreas Gohr    /**
44dd7472d3SAndreas Gohr     * Convenience method to access the method return
45dd7472d3SAndreas Gohr     *
46dd7472d3SAndreas Gohr     * @return array
47dd7472d3SAndreas Gohr     */
48dd7472d3SAndreas Gohr    public function getReturn()
49dd7472d3SAndreas Gohr    {
50dd7472d3SAndreas Gohr        return $this->getTag('return');
51dd7472d3SAndreas 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, ''));
107dd7472d3SAndreas Gohr            $result['type'] = new Type($type, $this->getContext());
1088ddd9b69SAndreas Gohr            $result['description'] = $description;
1098ddd9b69SAndreas Gohr        }
1108ddd9b69SAndreas Gohr        $this->tags['return'] = $result;
1118ddd9b69SAndreas Gohr    }
1128ddd9b69SAndreas Gohr}
113