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