/** * Factory depuis une reflection * * @param ReflectionProperty $reflection * @return static */ public static function fromReflection(ReflectionProperty $reflection) { // gestion du type $type = implode('|', $reflection->getDocBlockTypeStrings()); // cas de la valeur null $value = $reflection->getDefaultValue(); if (is_null($value)) { $value = Maker::NO_VALUE; $class = $reflection->getDeclaringClass(); foreach ($class->getAst()->stmts as $stmt) { // si pas un attribut, on zap if (!$stmt instanceof \PhpParser\Node\Stmt\Property) { continue; } foreach ($stmt->props as $prop) { if ($prop instanceof \PhpParser\Node\Stmt\PropertyProperty) { // lecture du fichier $file = file($class->getFileName()); if (!empty($line = $file[$prop->getLine() - 1])) { if (strpos($line, '=')) { $value = null; } } } } } } // construction $property = new static($reflection->getName(), $value, $type); // docblock $docblock = new \phpDocumentor\Reflection\DocBlock($reflection->getDocComment()); $property->setSummary($docblock->getShortDescription()); $property->setDescription($docblock->getLongDescription()); // gestion des modifiers $reflection->isPrivate() ? $property->enablePrivate() : $property->disablePrivate(); $reflection->isProtected() ? $property->enableProtected() : $property->disabledProtected(); $reflection->isPublic() ? $property->enablePublic() : $property->disablePublic(); $reflection->isStatic() ? $property->enableStatic() : $property->disableStatic(); return $property; }
protected function loadClassMethods(\ReflectionClass $reflectedObject) { $this->classMethods = array(); $classMethods = $reflectedObject->getMethods(); if (!empty($classMethods)) { foreach ($classMethods as $classMethod) { $reflectedMethod = $reflectedObject->getMethod($classMethod->name); $method = new Object\Method(); $method->setName($reflectedMethod->getName()); $method->setLevel($this->level + 1); // static if ($reflectedMethod->isStatic()) { $method->setStatic(); } // visibility if ($reflectedMethod->isPublic()) { $method->setVisibility(Object\VisibilityInterface::VISIBILITY_PUBLIC); $this->publicMethodsNumber++; } elseif ($reflectedMethod->isProtected()) { $method->setVisibility(Object\VisibilityInterface::VISIBILITY_PROTECTED); $this->protectedMethodsNumber++; } elseif ($reflectedMethod->isPrivate()) { $method->setVisibility(Object\VisibilityInterface::VISIBILITY_PRIVATE); $this->privateMethodsNumber++; } // phpdoc comment if (class_exists('\\phpDocumentor\\Reflection\\DocBlock')) { $phpdoc = new \phpDocumentor\Reflection\DocBlock($reflectedMethod->getDocComment()); $method->setShortDescription($phpdoc->getShortDescription()); $method->setLongDescription($phpdoc->getLongDescription()); } // parameters $methodParameters = $reflectedMethod->getParameters(); foreach ($methodParameters as $methodParameterReflected) { $methodParameter = new Object\MethodParameter(); $methodParameter->setName($methodParameterReflected->getName()); $class = $methodParameterReflected->getClass(); if ($class instanceof \ReflectionClass) { $methodParameter->setType($class->getName()); } elseif ($methodParameterReflected->isArray()) { $methodParameter->setType('array'); } if ($methodParameterReflected->isPassedByReference()) { $methodParameter->setReference(); } if ($methodParameterReflected->isDefaultValueAvailable()) { $default = $methodParameterReflected->getDefaultValue(); $defaultValueType = $this->factory->factory($default, $this->level + 1); $methodParameter->setDefaultValue($defaultValueType); } $method->addMethodParameter($methodParameter); } $this->classMethods[] = $method; } } // order methods usort($this->classMethods, function (Object\Method $methodA, Object\Method $methodB) { $orderValueA = $methodA->getVisibility() . $methodA->getName(); $orderValueB = $methodB->getVisibility() . $methodB->getName(); return strcasecmp($orderValueA, $orderValueB); }); }
/** * Analyse $class for extract self content * * @return $this */ protected function reflect() { $reflection = $this->getClass(); // docblock $docblock = new \phpDocumentor\Reflection\DocBlock($reflection->getDocComment()); $this->setSummary($docblock->getShortDescription()); $this->setDescription($docblock->getLongDescription()); // NAMESPACE $namespace = $reflection->getNamespaceName(); if (!empty($namespace)) { $this->setNamespace($namespace); } // ALIAS $file = $reflection->getFileName(); $this->setFilename($file); // lecture du fichier if (file_exists($file)) { $file = file($file); //Première lignes du fichier foreach (array_slice($file, 0, $reflection->getStartLine()) as $line) { // analyse de partern d'alias if (preg_match('#use (?<class>[^\\s^;]+)(\\s+as\\s+(?<alias>[^\\s^;]+))?\\s*;?#', $line, $match)) { $class = $match['class']; $alias = empty($match['alias']) ? collect(explode('\\', $class))->last() : $match['alias']; $this->addAlias($alias, $class); } } } // PARENT CLASS $parent = $reflection->getParentClass(); if (!empty($parent)) { $this->setParent($parent->getName()); } // CONSTANT $this->setConstants($reflection->getConstants()); // PROPERTIES foreach ($reflection->getProperties() as $property) { $this->addProperty(Property::fromReflection($property)); } // METHODS foreach ($reflection->getImmediateMethods() as $method) { $this->addMethod(Method::fromReflection($method)); } return $this; }
/** * @param $route * @return array */ private function addRouteDefinition(\DC\Router\IRoute $route) { $path = $this->simplifyPathForSwagger($route->getPath()); $method = strtolower($route->getMethod()); $callable = $route->getCallable(); $reflection = $this->reflector->getReflectionFunctionForCallable($callable); if ($reflection instanceof \ReflectionMethod) { if (!$reflection->getDeclaringClass()->implementsInterface('\\DC\\Router\\Swagger\\ISwaggerAPI')) { return; } } $phpdoc = new \phpDocumentor\Reflection\DocBlock($reflection); if (count($phpdoc->getTagsByName(SwaggerExcludeTag::$name)) > 0) { return; } $routeDef = ["produces" => ["application/json"], "responses" => []]; if ($method == "post" || $method == "put") { $routeDef["consumes"] = ["application/json"]; } if ($reflection instanceof \ReflectionMethod) { $reflectionClass = $reflection->getDeclaringClass(); $routeDef["tags"] = [$this->addTagForController($reflectionClass)]; } $parameters = $this->routeMatcher->getParameterInfo($route); $paramTags = $phpdoc->getTagsByName("param"); $reflectionParameters = $reflection->getParameters(); $reflectionParametersByName = []; foreach ($reflectionParameters as $parameter) { $reflectionParametersByName[$parameter->getName()] = $parameter; } foreach ($parameters as $parameter) { $matchingParamTags = array_filter($paramTags, function ($t) use($parameter) { return $t->getVariableName() == '$' . $parameter->getInternalName(); }); $paramTag = reset($matchingParamTags); $reflectionParameter = $reflectionParametersByName[$parameter->getInternalName()]; $required = !isset($reflectionParameter) || !$reflectionParameter->isOptional(); $paramDef = ["name" => $parameter->getQueryName(), "in" => $parameter->getPlacement(), "required" => $required]; if ($paramTag != null) { $paramDef["description"] = $paramTag->getDescription(); $paramDef += $this->getTypeDefinition($paramTag->getType()); } else { $paramDef["type"] = "string"; } $routeDef["parameters"][] = $paramDef; } /** * @var $returnTag \phpDocumentor\Reflection\DocBlock\Tag\ReturnTag[] */ $returnTag = $phpdoc->getTagsByName("return"); if (count($returnTag) > 0) { $returnTypes = $returnTag[0]->getTypes(); if (!isset($returnTypes)) { $returnTypes = [$returnTag[0]->getType()]; } foreach ($returnTypes as $type) { $defRef = $this->getTypeDefinitionOrReference($type); $routeDef["responses"][200] = ["schema" => $defRef, "description" => $returnTag[0]->getDescription()]; } } /** @var $throwsTags \phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag[] */ $throwsTags = $phpdoc->getTagsByName("throws"); if (count($throwsTags) > 0) { foreach ($throwsTags as $throwsTag) { $type = $throwsTag->getType(); $defRef = $this->getTypeDefinitionOrReference($type); $routeDef["responses"][500] = ["schema" => $defRef, "description" => $throwsTag->getDescription()]; } } $routeDef["summary"] = $phpdoc->getShortDescription(); $description = $phpdoc->getLongDescription()->getContents(); if (strlen($description) > 0) { $routeDef["description"] = $description; } $this->def['paths'][$path][$method] = $routeDef; }
/** * * * @param ReflectionMethod $reflection * @return Method */ public static function fromReflection(ReflectionMethod $reflection) { // gestion du type // $type = implode('|', $reflection->getDocBlockTypeStrings()); // // construction $method = new static($reflection->getName(), [], $reflection->getBodyCode()); // docblock $docblock = new \phpDocumentor\Reflection\DocBlock($reflection->getDocComment()); $method->setSummary($docblock->getShortDescription()); $method->setDescription($docblock->getLongDescription()); // gestion des modifiers $reflection->isPrivate() ? $method->enablePrivate() : $method->disablePrivate(); $reflection->isProtected() ? $method->enableProtected() : $method->disabledProtected(); $reflection->isPublic() ? $method->enablePublic() : $method->disablePublic(); $reflection->isStatic() ? $method->enableStatic() : $method->disableStatic(); $reflection->isFinal() ? $method->enableFinal() : $method->disableFinal(); foreach ($reflection->getParameters() as $parameter) { $method->addParameter(Parameter::fromReflection($parameter)); } return $method; }