public function testRetrievingMethodsShouldReturnClassMethodObjects() { $methods = $this->parser->getMethods(); $this->assertEquals(count($this->class->getMethods(\ReflectionMethod::IS_PUBLIC)), count($methods)); foreach ($methods as $method) { $this->assertInstanceOf('Zend\DocBook\ClassMethod', $method); } }
/** * Retrieve parsed methods for this class * * @return ClassMethod[] Array of ClassMethod objects */ public function getMethods() { if (null !== $this->methods) { return $this->methods; } $rMethods = $this->reflection->getMethods(ReflectionMethod::IS_PUBLIC); $methods = array(); foreach ($rMethods as $method) { $methods[] = new ClassMethod($method); } $this->methods = $methods; return $this->methods; }
/** * Build a Code Generation Php Object from a Class Reflection * * @param ClassReflection $classReflection * @return TraitGenerator */ public static function fromReflection(ClassReflection $classReflection) { // class generator $cg = new static($classReflection->getName()); $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $cg->setDocBlock(DocBlockGenerator::fromReflection($classReflection->getDocBlock())); } // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } $properties = array(); foreach ($classReflection->getProperties() as $reflectionProperty) { if ($reflectionProperty->getDeclaringClass()->getName() == $classReflection->getName()) { $properties[] = PropertyGenerator::fromReflection($reflectionProperty); } } $cg->addProperties($properties); $methods = array(); foreach ($classReflection->getMethods() as $reflectionMethod) { $className = $cg->getNamespaceName() ? $cg->getNamespaceName() . '\\' . $cg->getName() : $cg->getName(); if ($reflectionMethod->getDeclaringClass()->getName() == $className) { $methods[] = MethodGenerator::fromReflection($reflectionMethod); } } $cg->addMethods($methods); return $cg; }
/** * Build a Code Generation Php Object from a Class Reflection * * @param ClassReflection $classReflection * @return InterfaceGenerator */ public static function fromReflection(ClassReflection $classReflection) { if (!$classReflection->isInterface()) { throw new Exception\InvalidArgumentException(sprintf('Class %s is not a interface', $classReflection->getName())); } // class generator $cg = new static($classReflection->getName()); $methods = []; $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $cg->setDocBlock(DocBlockGenerator::fromReflection($classReflection->getDocBlock())); } // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } foreach ($classReflection->getMethods() as $reflectionMethod) { $className = $cg->getNamespaceName() ? $cg->getNamespaceName() . '\\' . $cg->getName() : $cg->getName(); if ($reflectionMethod->getDeclaringClass()->getName() == $className) { $methods[] = MethodGenerator::fromReflection($reflectionMethod); } } foreach ($classReflection->getConstants() as $name => $value) { $cg->addConstant($name, $value); } $cg->addMethods($methods); return $cg; }
public function testMethodReturns() { $reflectionClass = new ClassReflection('ZendTest\\Code\\Reflection\\TestAsset\\TestSampleClass2'); $methodByName = $reflectionClass->getMethod('getProp1'); $this->assertEquals('Zend\\Code\\Reflection\\MethodReflection', get_class($methodByName)); $methodsAll = $reflectionClass->getMethods(); $this->assertEquals(3, count($methodsAll)); $firstMethod = array_shift($methodsAll); $this->assertEquals('getProp1', $firstMethod->getName()); }
/** * Process the command * * @return integer */ public function processCommandTask() { // initialize action list $loadedActions = []; // loop through controllers by module foreach ($this->params->loadedControllers as $moduleKey => $controllerTypes) { $loadedActions[$moduleKey] = []; $moduleViewPath = $this->filterCamelCaseToDash($moduleKey); // loop through controllers by controller type foreach ($controllerTypes as $controllerList) { // loop through controllers foreach ($controllerList as $controllerKey => $controllerClass) { $loadedActions[$moduleKey][$controllerKey] = []; // start class reflection $classReflection = new ClassReflection($controllerClass); // convert method name to get dashed action $controllerName = substr($classReflection->getShortName(), 0, -10); $controllerName = $this->filterCamelCaseToDash($controllerName); // get public methods $methods = $classReflection->getMethods(ReflectionMethod::IS_PUBLIC); // loop through methods foreach ($methods as $method) { // get class and method name $methodClass = $method->getDeclaringClass()->getName(); $methodName = $method->name; // continue for methods from extended class if ($methodClass != $controllerClass) { continue; } // continue for no-action methods if (substr($methodName, -6) != 'Action') { continue; } // convert method name to get dashed action $actionName = substr($methodName, 0, -6); $actionName = $this->filterCamelCaseToDash($actionName); // build action file $actionFile = '/module/' . $moduleKey . '/view/' . $moduleViewPath . '/' . $controllerName . '/' . $actionName . '.phtml'; // check action file exists if (!file_exists($this->params->workingPath . $actionFile)) { $actionFile = false; } // add action to list $loadedActions[$moduleKey][$controllerKey][$actionName] = $actionFile; } } } } // set loaded modules $this->params->loadedActions = $loadedActions; return 0; }
/** * Use reflection to load the method information * * @param string $interfaceName * @return array */ private function getMethodMapViaReflection($interfaceName) { $methodMap = []; $class = new ClassReflection($interfaceName); $baseClassMethods = false; foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { // Include all the methods of classes inheriting from AbstractExtensibleObject. // Ignore all the methods of AbstractExtensibleModel's parent classes if ($method->class === self::BASE_MODEL_CLASS) { $baseClassMethods = true; } elseif ($baseClassMethods) { // ReflectionClass::getMethods() sorts the methods by class (lowest in inheritance tree first) // then by the order they are defined in the class definition break; } if ($this->isSuitableMethod($method)) { $methodMap[$method->getName()] = $this->typeProcessor->getGetterReturnType($method); } } return $methodMap; }
/** * fromReflection() - build a Code Generation Php Object from a Class Reflection * * @param ReflectionClass $classReflection * @return ClassGenerator */ public static function fromReflection(ClassReflection $classReflection) { // class generator $cg = new static($classReflection->getName()); $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $cg->setDocblock(DocblockGenerator::fromReflection($classReflection->getDocblock())); } $cg->setAbstract($classReflection->isAbstract()); // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } /* @var $parentClass \Zend\Code\Reflection\ReflectionClass */ if ($parentClass = $classReflection->getParentClass()) { $cg->setExtendedClass($parentClass->getName()); $interfaces = array_diff($classReflection->getInterfaces(), $parentClass->getInterfaces()); } else { $interfaces = $classReflection->getInterfaces(); } $interfaceNames = array(); foreach ($interfaces as $interface) { /* @var $interface \Zend\Code\Reflection\ReflectionClass */ $interfaceNames[] = $interface->getName(); } $cg->setImplementedInterfaces($interfaceNames); $properties = array(); foreach ($classReflection->getProperties() as $reflectionProperty) { /* @var $reflectionProperty \PropertyReflection\Code\Reflection\ReflectionProperty */ if ($reflectionProperty->getDeclaringClass()->getName() == $cg->getName()) { $properties[] = PropertyGenerator::fromReflection($reflectionProperty); } } $cg->setProperties($properties); $methods = array(); foreach ($classReflection->getMethods() as $reflectionMethod) { /* @var $reflectionMethod \MethodReflection\Code\Reflection\ReflectionMethod */ if ($reflectionMethod->getDeclaringClass()->getName() == $cg->getName()) { $methods[] = MethodGenerator::fromReflection($reflectionMethod); } } $cg->setMethods($methods); return $cg; }
/** * Build a Code Generation Php Object from a Class Reflection * * @param ClassReflection $classReflection * @return ClassGenerator */ public static function fromReflection(ClassReflection $classReflection) { $cg = new static($classReflection->getName()); $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $cg->setDocBlock(DocBlockGenerator::fromReflection($classReflection->getDocBlock())); } $cg->setAbstract($classReflection->isAbstract()); // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } /* @var \Zend\Code\Reflection\ClassReflection $parentClass */ $parentClass = $classReflection->getParentClass(); $interfaces = $classReflection->getInterfaces(); if ($parentClass) { $cg->setExtendedClass($parentClass->getName()); $interfaces = array_diff($interfaces, $parentClass->getInterfaces()); } $interfaceNames = array(); foreach ($interfaces as $interface) { /* @var \Zend\Code\Reflection\ClassReflection $interface */ $interfaceNames[] = $interface->getName(); } $cg->setImplementedInterfaces($interfaceNames); $properties = array(); foreach ($classReflection->getProperties() as $reflectionProperty) { if ($reflectionProperty->getDeclaringClass()->getName() == $classReflection->getName()) { $properties[] = PropertyGenerator::fromReflection($reflectionProperty); } } $cg->addProperties($properties); $constants = array(); foreach ($classReflection->getConstants() as $name => $value) { $constants[] = array('name' => $name, 'value' => $value); } $cg->addConstants($constants); $methods = array(); foreach ($classReflection->getMethods() as $reflectionMethod) { $className = $cg->getNamespaceName() ? $cg->getNamespaceName() . "\\" . $cg->getName() : $cg->getName(); if ($reflectionMethod->getDeclaringClass()->getName() == $className) { $methods[] = MethodGenerator::fromReflection($reflectionMethod); } } $cg->addMethods($methods); return $cg; }
/** * Retrieve complex type information from class public properties. * * @param string $class * @return array * @throws \InvalidArgumentException * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function _processComplexType($class) { $typeName = $this->translateTypeName($class); $this->_types[$typeName] = []; if ($this->isArrayType($class)) { $this->register($this->getArrayItemType($class)); } else { if (!(class_exists($class) || interface_exists($class))) { throw new \InvalidArgumentException(sprintf('Could not load the "%s" class as parameter type.', $class)); } $reflection = new ClassReflection($class); $docBlock = $reflection->getDocBlock(); $this->_types[$typeName]['documentation'] = $docBlock ? $this->getDescription($docBlock) : ''; /** @var \Zend\Code\Reflection\MethodReflection $methodReflection */ foreach ($reflection->getMethods(\ReflectionMethod::IS_PUBLIC) as $methodReflection) { if ($methodReflection->class === "Magento\\Framework\\Model\\AbstractModel") { continue; } $this->_processMethod($methodReflection, $typeName); } } return $this->_types[$typeName]; }
/** * Get a list of methods declared on extensible data interface. * * @return string[] */ protected function getExtensibleInterfaceMethods() { if ($this->extensibleInterfaceMethods === null) { $interfaceReflection = new ClassReflection('Magento\\Framework\\Api\\ExtensibleDataInterface'); $methodsReflection = $interfaceReflection->getMethods(); $this->extensibleInterfaceMethods = []; foreach ($methodsReflection as $methodReflection) { $this->extensibleInterfaceMethods[] = $methodReflection->getName(); } } return $this->extensibleInterfaceMethods; }
/** * _processActionableMethods() - process all methods that can be called on this provider. * */ protected function _processActionableMethods() { $specialtyRegex = '#(.*)(' . implode('|', $this->_specialties) . ')$#i'; $methods = $this->_providerReflection->getMethods(); $actionableMethods = array(); foreach ($methods as $method) { $methodName = $method->getName(); /** * the following will determine what methods are actually actionable * public, non-static, non-underscore prefixed, classes that dont * contain the name " */ if (!$method->getDeclaringClass()->isInstantiable() || !$method->isPublic() || $methodName[0] == '_' || $method->isStatic() || in_array($methodName, array('getContextClasses', 'getName'))) { continue; } /** * check to see if the method was a required method by a Zend\Tool\* interface */ foreach ($method->getDeclaringClass()->getInterfaces() as $methodDeclaringClassInterface) { if (strpos($methodDeclaringClassInterface->getName(), 'Zend\\Tool\\') === 0 && $methodDeclaringClassInterface->hasMethod($methodName)) { continue 2; } } $actionableName = ucfirst($methodName); if (substr($actionableName, -6) == 'Action') { $actionableName = substr($actionableName, 0, -6); } $actionableMethods[$methodName]['methodName'] = $methodName; $matches = null; if (preg_match($specialtyRegex, $actionableName, $matches)) { $actionableMethods[$methodName]['actionName'] = $matches[1]; $actionableMethods[$methodName]['specialty'] = $matches[2]; } else { $actionableMethods[$methodName]['actionName'] = $actionableName; $actionableMethods[$methodName]['specialty'] = '_Global'; } // get the action, and create non-existent actions when they dont exist (the true part below) $action = $this->_registry->getActionRepository()->getAction($actionableMethods[$methodName]['actionName']); if ($action == null) { $action = new \Zend\Tool\Framework\Action\Base($actionableMethods[$methodName]['actionName']); $this->_registry->getActionRepository()->addAction($action); } $actionableMethods[$methodName]['action'] = $action; if (!in_array($actionableMethods[$methodName]['action'], $this->_actions)) { $this->_actions[] = $actionableMethods[$methodName]['action']; } $parameterInfo = array(); $position = 1; foreach ($method->getParameters() as $parameter) { $currentParam = $parameter->getName(); $parameterInfo[$currentParam]['position'] = $position++; $parameterInfo[$currentParam]['optional'] = $parameter->isOptional(); $parameterInfo[$currentParam]['default'] = $parameter->isOptional() ? $parameter->getDefaultValue() : null; $parameterInfo[$currentParam]['name'] = $currentParam; $parameterInfo[$currentParam]['type'] = 'string'; $parameterInfo[$currentParam]['description'] = null; } $matches = null; if (($docComment = $method->getDocComment()) != '' && preg_match_all('/@param\\s+(\\w+)+\\s+(\\$\\S+)\\s+(.*?)(?=(?:\\*\\s*@)|(?:\\*\\/))/s', $docComment, $matches)) { for ($i = 0; $i <= count($matches[0]) - 1; $i++) { $currentParam = ltrim($matches[2][$i], '$'); if ($currentParam != '' && isset($parameterInfo[$currentParam])) { $parameterInfo[$currentParam]['type'] = $matches[1][$i]; $descriptionSource = $matches[3][$i]; if ($descriptionSource != '') { $parameterInfo[$currentParam]['description'] = trim($descriptionSource); } } } } $actionableMethods[$methodName]['parameterInfo'] = $parameterInfo; } $this->_actionableMethods = $actionableMethods; }
function registerRoutes() { // Auto-register routes. if (!isset($this->classLoader->getPrefixesPsr4()[$this->config->namespacePrefix . '\\'])) { throw new Exception(sprintf('Namespace prefix "%s" defined in the config was not found in the autoloader.', $this->config->namespacePrefix)); } $sourcePath = array_pop($this->classLoader->getPrefixesPsr4()[$this->config->namespacePrefix . '\\']); $routes = []; $app = $this->app; $formatNegotiator = $this->formatNegotiator; $serializer = $this->serializer; $config = $this->config; foreach ($this->getWebServiceClasses($this->config->namespacePrefix, $sourcePath) as $webServiceClass) { // Need to get methods and DTOs from class $classReflection = new ClassReflection($webServiceClass); $httpMethodNames = $this->config->httpMethodNames; $httpMethodReflections = array_filter($classReflection->getMethods(), function ($methodReflection) use($httpMethodNames) { return in_array($methodReflection->name, $httpMethodNames); }); // @todo add a check to make sure DTOs are unique. This might happen implicitly when registering routes. // Call for each http method/DTO in web service /** @var MethodReflection $httpMethodReflection */ foreach ($httpMethodReflections as $httpMethodReflection) { // This assumes that the first argument of the HTTP method is a DTO. $httpMethodReflectionPrototype = $httpMethodReflection->getPrototype(); $requestDtoClass = array_shift($httpMethodReflectionPrototype['arguments'])['type']; $requestDtoClassReflection = new ClassReflection($requestDtoClass); $requestDtoProperties = $requestDtoClassReflection->getProperties(); $returnDtoClass = $httpMethodReflection->getReturnType(); $returnDtoProperties = (new ClassReflection($returnDtoClass))->getProperties(); $requestMethod = $httpMethodReflectionPrototype['name']; $route = '/' . $this->config->baseUrl . '/' . $requestDtoClassReflection->getShortName(); $routes[] = new class($route, $requestDtoClass, $requestDtoProperties, $returnDtoClass, $returnDtoProperties) { public $path; public $requestDto; public $requestDtoParameters; public $returnDto; public $returnDtoProperties; public function __construct(string $path, string $requestDto, array $requestDtoParameters, string $returnDto, array $returnDtoProperties) { $this->path = $path; $this->requestDto = $requestDto; $this->requestDtoParameters = $requestDtoParameters; $this->returnDto = $returnDto; $this->returnDtoProperties = $returnDtoProperties; } }; $app->get($route, function () use($app, $formatNegotiator, $serializer, $config, $webServiceClass, $requestDtoClass, $requestMethod) { /** @var Request $httpRequest */ $httpRequest = $app['request']; // Convert request parameters to the request DTO. $params = $serializer->serialize($httpRequest->query->all(), 'json'); $requestDto = $serializer->deserialize($params, $requestDtoClass, 'json'); // Get the response DTO by calling the HTTP method of the web service class, with the request DTO. $responseDto = (new $webServiceClass())->{$requestMethod}($requestDto); // Content negotiation $format = $formatNegotiator->getBestFormat(implode(',', $httpRequest->getAcceptableContentTypes()), $config->contentNegotiation->priorities); return new Response($serializer->serialize($responseDto, $format), 200, array('Content-Type' => $app['request']->getMimeType($format))); }); } } /** * Register custom _routes meta route */ $app->get($config->baseUrl . '/_routes', function () use($app, $formatNegotiator, $serializer, $config, $routes) { $httpRequest = $app['request']; $format = $formatNegotiator->getBestFormat(implode(',', $httpRequest->getAcceptableContentTypes()), $config->contentNegotiation->priorities); $serializedData = $serializer->serialize($routes, $format); $responseCode = Response::HTTP_OK; if ($serializedData === false) { $serializedData = ''; $responseCode = Response::HTTP_INTERNAL_SERVER_ERROR; } return new Response($serializedData, $responseCode, array('Content-Type' => $app['request']->getMimeType($format))); }); }
/** * Copied from ClassGenerator::fromReflection and tweaked slightly * @param ClassReflection $classReflection * * @return ClassGenerator */ public function getGeneratorFromReflection(ClassReflection $classReflection) { // class generator $cg = new ClassGenerator($classReflection->getName()); $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $docblock = DocBlockGenerator::fromReflection($classReflection->getDocBlock()); $docblock->setIndentation(Generator::$indentation); $cg->setDocBlock($docblock); } $cg->setAbstract($classReflection->isAbstract()); // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } /* @var \Zend\Code\Reflection\ClassReflection $parentClass */ $parentClass = $classReflection->getParentClass(); if ($parentClass) { $cg->setExtendedClass('\\' . ltrim($parentClass->getName(), '\\')); $interfaces = array_diff($classReflection->getInterfaces(), $parentClass->getInterfaces()); } else { $interfaces = $classReflection->getInterfaces(); } $interfaceNames = array(); foreach ($interfaces as $interface) { /* @var \Zend\Code\Reflection\ClassReflection $interface */ $interfaceNames[] = $interface->getName(); } $cg->setImplementedInterfaces($interfaceNames); $properties = array(); foreach ($classReflection->getProperties() as $reflectionProperty) { if ($reflectionProperty->getDeclaringClass()->getName() == $classReflection->getName()) { $property = PropertyGenerator::fromReflection($reflectionProperty); $property->setIndentation(Generator::$indentation); $properties[] = $property; } } $cg->addProperties($properties); $methods = array(); foreach ($classReflection->getMethods() as $reflectionMethod) { $className = $cg->getNamespaceName() ? $cg->getNamespaceName() . "\\" . $cg->getName() : $cg->getName(); if ($reflectionMethod->getDeclaringClass()->getName() == $className) { $method = MethodGenerator::fromReflection($reflectionMethod); $method->setBody(preg_replace("/^\\s+/m", '', $method->getBody())); $method->setIndentation(Generator::$indentation); $methods[] = $method; } } $cg->addMethods($methods); return $cg; }