/** * Generate view content * * @param string $moduleName * @param ClassReflection $loadedEntity */ protected function addContent($moduleName, ClassReflection $loadedEntity) { // prepare some params $moduleIdentifier = $this->filterCamelCaseToUnderscore($moduleName); $entityName = $loadedEntity->getShortName(); $entityParam = lcfirst($entityName); $formParam = lcfirst(str_replace('Entity', '', $loadedEntity->getShortName())) . 'DataForm'; $moduleRoute = $this->filterCamelCaseToDash($moduleName); // set action body $body = []; $body[] = 'use ' . $loadedEntity->getName() . ';'; $body[] = ''; $body[] = '/** @var ' . $entityName . ' $' . $entityParam . ' */'; $body[] = '$' . $entityParam . ' = $this->' . $entityParam . ';'; $body[] = ''; $body[] = '$this->h1(\'' . $moduleIdentifier . '_title_update\');'; $body[] = ''; $body[] = '$this->' . $formParam . '->setAttribute(\'action\', $this->url(\'' . $moduleRoute . '/update\', [\'id\' => $' . $entityParam . '->getIdentifier()]));'; $body[] = ''; $body[] = 'echo $this->bootstrapForm($this->' . $formParam . ');'; $body[] = '?>'; $body[] = '<p>'; $body[] = ' <a class="btn btn-primary" href="<?php echo $this->url(\'' . $moduleRoute . '\'); ?>">'; $body[] = ' <i class="fa fa-table"></i>'; $body[] = ' <?php echo $this->translate(\'' . $moduleIdentifier . '_action_index\'); ?>'; $body[] = ' </a>'; $body[] = '</p>'; $body = implode(AbstractGenerator::LINE_FEED, $body); // add method $this->setContent($body); }
/** * Generate view content * * @param string $moduleName * @param ClassReflection $loadedEntity */ protected function addContent($moduleName, ClassReflection $loadedEntity) { // prepare some params $moduleIdentifier = $this->filterCamelCaseToUnderscore($moduleName); $entityName = $loadedEntity->getShortName(); $entityParam = lcfirst($entityName); $formParam = lcfirst(str_replace('Entity', '', $loadedEntity->getShortName())) . 'DeleteForm'; $moduleRoute = $this->filterCamelCaseToDash($moduleName); $deleteMessage = $moduleRoute . '_message_' . $moduleRoute . '_deleting_possible'; // set action body $body = []; $body[] = 'use ' . $loadedEntity->getName() . ';'; $body[] = ''; $body[] = '/** @var ' . $entityName . ' $' . $entityParam . ' */'; $body[] = '$' . $entityParam . ' = $this->' . $entityParam . ';'; $body[] = ''; $body[] = '$this->h1(\'' . $moduleIdentifier . '_title_delete\');'; $body[] = ''; $body[] = '$this->' . $formParam . '->setAttribute(\'action\', $this->url(\'' . $moduleRoute . '/delete\', [\'id\' => $' . $entityParam . '->getIdentifier()]));'; $body[] = ''; $body[] = '?>'; $body[] = '<div class="well">'; $body[] = ' <table class="table">'; $body[] = ' <tbody>'; foreach ($loadedEntity->getProperties() as $property) { $methodName = 'get' . ucfirst($property->getName()); $body[] = ' <tr>'; $body[] = ' <th class="col-sm-2 text-right"><?php echo $this->translate(\'' . $moduleIdentifier . '_label_' . $this->filterCamelCaseToUnderscore($property->getName()) . '\'); ?></th>'; $body[] = ' <td class="col-sm-10"><?php echo $' . $entityParam . '->' . $methodName . '() ?></td>'; $body[] = ' </tr>'; } $body[] = ' <tr>'; $body[] = ' <th class="col-sm-2 text-right"> </th>'; $body[] = ' <td class="col-sm-10"><?php echo $this->form($this->' . $formParam . '); ?></td>'; $body[] = ' </tr>'; $body[] = ' </tbody>'; $body[] = ' </table>'; $body[] = '</div>'; $body[] = '<p>'; $body[] = ' <a class="btn btn-primary" href="<?php echo $this->url(\'' . $moduleRoute . '\'); ?>">'; $body[] = ' <i class="fa fa-table"></i>'; $body[] = ' <?php echo $this->translate(\'' . $moduleIdentifier . '_action_index\'); ?>'; $body[] = ' </a>'; $body[] = '</p>'; $body = implode(AbstractGenerator::LINE_FEED, $body); // add method $this->setContent($body); }
/** * @param ClassReflection $class * @param string $namespaceName * @param array $useArray * @return string */ private function getClassNameInContext(ClassReflection $class, $namespaceName, $useArray) { if (!$namespaceName) { return '\\' . $class->getName(); } return array_key_exists($class->getName(), $useArray) ? $useArray[$class->getName()] ?: $class->getShortName() : (0 === strpos($class->getName(), $namespaceName) ? substr($class->getName(), strlen($namespaceName) + 1) : '\\' . $class->getName()); }
/** * Generate code to cache from class reflection. * This is a total mess, I know. Just wanted to flesh out the logic. * * @todo Refactor into a class, clean up logic, DRY it up, maybe move * some of this into Zend\Code * @param ClassReflection $r * @return string */ protected static function getCacheCode(ClassReflection $r) { $useString = ''; $usesNames = array(); if (count($uses = $r->getDeclaringFile()->getUses())) { foreach ($uses as $use) { $usesNames[$use['use']] = $use['as']; $useString .= "use {$use['use']}"; if ($use['as']) { $useString .= " as {$use['as']}"; } $useString .= ";\n"; } } $declaration = ''; if ($r->isAbstract() && !$r->isInterface()) { $declaration .= 'abstract '; } if ($r->isFinal()) { $declaration .= 'final '; } if ($r->isInterface()) { $declaration .= 'interface '; } if (!$r->isInterface()) { $declaration .= 'class '; } $declaration .= $r->getShortName(); $parentName = false; if (($parent = $r->getParentClass()) && $r->getNamespaceName()) { $parentName = array_key_exists($parent->getName(), $usesNames) ? $usesNames[$parent->getName()] ?: $parent->getShortName() : (0 === strpos($parent->getName(), $r->getNamespaceName()) ? substr($parent->getName(), strlen($r->getNamespaceName()) + 1) : '\\' . $parent->getName()); } else { if ($parent && !$r->getNamespaceName()) { $parentName = '\\' . $parent->getName(); } } if ($parentName) { $declaration .= " extends {$parentName}"; } $interfaces = array_diff($r->getInterfaceNames(), $parent ? $parent->getInterfaceNames() : array()); if (count($interfaces)) { foreach ($interfaces as $interface) { $iReflection = new ClassReflection($interface); $interfaces = array_diff($interfaces, $iReflection->getInterfaceNames()); } $declaration .= $r->isInterface() ? ' extends ' : ' implements '; $declaration .= implode(', ', array_map(function ($interface) use($usesNames, $r) { $iReflection = new ClassReflection($interface); return array_key_exists($iReflection->getName(), $usesNames) ? $usesNames[$iReflection->getName()] ?: $iReflection->getShortName() : (0 === strpos($iReflection->getName(), $r->getNamespaceName()) ? substr($iReflection->getName(), strlen($r->getNamespaceName()) + 1) : '\\' . $iReflection->getName()); }, $interfaces)); } $classContents = $r->getContents(false); $classFileDir = dirname($r->getFileName()); $classContents = trim(str_replace('__DIR__', sprintf("'%s'", $classFileDir), $classContents)); $return = "\nnamespace " . $r->getNamespaceName() . " {\n" . $useString . $declaration . "\n" . $classContents . "\n}\n"; return $return; }
/** * Generate view content * * @param string $moduleName * @param ClassReflection $loadedEntity */ protected function addContent($moduleName, ClassReflection $loadedEntity) { // prepare some params $moduleIdentifier = $this->filterCamelCaseToUnderscore($moduleName); $entityName = $loadedEntity->getShortName(); $entityParam = lcfirst($entityName); $listParam = lcfirst(str_replace('Entity', '', $entityName)) . 'List'; $moduleRoute = $this->filterCamelCaseToDash($moduleName); // set action body $body = []; $body[] = 'use ' . $loadedEntity->getName() . ';'; $body[] = ''; $body[] = '$this->h1(\'' . $moduleIdentifier . '_title_index\');'; $body[] = '?>'; $body[] = '<table class="table table-bordered table-striped">'; $body[] = ' <thead>'; $body[] = ' <tr>'; foreach ($loadedEntity->getProperties() as $property) { $body[] = ' <th><?php echo $this->translate(\'' . $moduleIdentifier . '_label_' . $this->filterCamelCaseToUnderscore($property->getName()) . '\'); ?></th>'; } $body[] = ' <th width="95">'; $body[] = ' <a class="btn btn-default btn-xs" href="<?php echo $this->url(\'' . $moduleRoute . '/create\'); ?>" title="<?php echo $this->translate(\'' . $moduleIdentifier . '_action_create\'); ?>">'; $body[] = ' <i class="fa fa-plus"></i>'; $body[] = ' </a>'; $body[] = ' </th>'; $body[] = ' </tr>'; $body[] = ' </thead>'; $body[] = ' <tbody>'; $body[] = ' <?php /** @var ' . $entityName . ' $' . $entityParam . ' */ ?>'; $body[] = ' <?php foreach ($this->' . $listParam . ' as $' . $entityParam . '): ?>'; $body[] = ' <tr>'; foreach ($loadedEntity->getProperties() as $property) { $methodName = 'get' . ucfirst($property->getName()); $body[] = ' <td><?php echo $' . $entityParam . '->' . $methodName . '() ?></td>'; } $body[] = ' <td>'; $body[] = ' <a class="btn btn-default btn-xs" href="<?php echo $this->url(\'' . $moduleRoute . '/show\', [\'id\' => $' . $entityParam . '->getIdentifier()]); ?>" title="<?php echo $this->translate(\'' . $moduleIdentifier . '_action_show\'); ?>">'; $body[] = ' <i class="fa fa-search"></i>'; $body[] = ' </a>'; $body[] = ' <a class="btn btn-default btn-xs" href="<?php echo $this->url(\'' . $moduleRoute . '/update\', [\'id\' => $' . $entityParam . '->getIdentifier()]); ?>" title="<?php echo $this->translate(\'' . $moduleIdentifier . '_action_update\'); ?>">'; $body[] = ' <i class="fa fa-pencil"></i>'; $body[] = ' </a>'; $body[] = ' <a class="btn btn-default btn-xs" href="<?php echo $this->url(\'' . $moduleRoute . '/delete\', [\'id\' => $' . $entityParam . '->getIdentifier()]); ?>" title="<?php echo $this->translate(\'' . $moduleIdentifier . '_action_delete\'); ?>">'; $body[] = ' <i class="fa fa-trash"></i>'; $body[] = ' </a>'; $body[] = ' </td>'; $body[] = ' </tr>'; $body[] = ' <?php endforeach; ?>'; $body[] = ' </tbody>'; $body[] = '</table>'; $body = implode(AbstractGenerator::LINE_FEED, $body); // add method $this->setContent($body); }
/** * 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; }
public function getClassUseName(ClassReflection $currentClass, ClassReflection $useClass) { $useNames = $this->fileReflectionUseStatementService->getUseNames($currentClass->getDeclaringFile()); $fullUseClassName = $useClass->getName(); $classUseName = null; if (array_key_exists($fullUseClassName, $useNames)) { $classUseName = $useNames[$fullUseClassName] ?: $useClass->getShortName(); } else { if (0 === strpos($fullUseClassName, $currentClass->getNamespaceName())) { $classUseName = substr($fullUseClassName, strlen($currentClass->getNamespaceName()) + 1); } else { $classUseName = '\\' . $fullUseClassName; } } return $classUseName; }
/** * Generate view content * * @param string $moduleName * @param ClassReflection $loadedEntity */ protected function addContent($moduleName, ClassReflection $loadedEntity) { // prepare some params $moduleIdentifier = $this->filterCamelCaseToUnderscore($moduleName); $entityName = $loadedEntity->getShortName(); $entityParam = lcfirst($entityName); $moduleRoute = $this->filterCamelCaseToDash($moduleName); // set action body $body = []; $body[] = 'use ' . $loadedEntity->getName() . ';'; $body[] = ''; $body[] = '/** @var ' . $entityName . ' $' . $entityParam . ' */'; $body[] = '$' . $entityParam . ' = $this->' . $entityParam . ';'; $body[] = ''; $body[] = '$this->h1(\'' . $moduleIdentifier . '_title_show\');'; $body[] = '?>'; $body[] = '<table class="table table-bordered">'; $body[] = ' <tbody>'; foreach ($loadedEntity->getProperties() as $property) { $methodName = 'get' . ucfirst($property->getName()); $body[] = ' <tr>'; $body[] = ' <th><?php echo $this->translate(\'' . $moduleIdentifier . '_label_' . $this->filterCamelCaseToUnderscore($property->getName()) . '\'); ?></th>'; $body[] = ' <td><?php echo $' . $entityParam . '->' . $methodName . '() ?></td>'; $body[] = ' </tr>'; } $body[] = ' </tbody>'; $body[] = '</table>'; $body[] = '<p>'; $body[] = ' <a class="btn btn-primary" href="<?php echo $this->url(\'' . $moduleRoute . '\'); ?>">'; $body[] = ' <i class="fa fa-table"></i>'; $body[] = ' <?php echo $this->translate(\'' . $moduleIdentifier . '_action_index\'); ?>'; $body[] = ' </a>'; $body[] = '</p>'; $body = implode(AbstractGenerator::LINE_FEED, $body); // add method $this->setContent($body); }
/** * Create the Trait/Interface/Class definition * * @param Reflection\ClassReflection $class * #return string */ protected function buildClassDecleration(Reflection\ClassReflection $class) { $code = ''; if ($class->isTrait() === false && $class->isInterface() === false && $class->isAbstract()) { $code .= "abstract "; } if ($class->isFinal()) { $code .= "final "; } if ($class->isInterface()) { $code .= "interface "; } else { if ($class->isTrait()) { $code .= "trait "; } else { $code .= "class "; } } $code .= $class->getShortName(); return $code; }
/** * @param ClassReflection $classReflection * @param $parent * @param $usesNames * @return string */ protected function extractInterfaceStatement(ClassReflection $classReflection, $parent, $usesNames) { $parentInterfaceNames = $parent instanceof ClassReflection ? $parent->getInterfaceNames() : array(); $interfaceNames = array_diff($classReflection->getInterfaceNames(), $parentInterfaceNames); $interfaceStatement = ''; if (!count($interfaceNames)) { return $interfaceStatement; } foreach ($interfaceNames as $interface) { $iReflection = new ClassReflection($interface); $interfaceNames = array_diff($interfaceNames, $iReflection->getInterfaceNames()); } $interfaceStatement .= $classReflection->isInterface() ? ' extends ' : ' implements '; $interfaceStatement .= implode(', ', array_map(function ($interface) use($usesNames, $classReflection) { $iReflection = new ClassReflection($interface); return array_key_exists($iReflection->getName(), $usesNames) ? $usesNames[$iReflection->getName()] ?: $iReflection->getShortName() : (0 === strpos($iReflection->getName(), $classReflection->getNamespaceName()) ? substr($iReflection->getName(), strlen($classReflection->getNamespaceName()) + 1) : '\\' . $iReflection->getName()); }, $interfaceNames)); return $interfaceStatement; }
protected function findClassInImports(ClassReflection $reflection, $class) { foreach ($this->findAliasedImports($reflection) as $alias => $aliasedImport) { if ($alias === $class) { return $aliasedImport; } } foreach ($this->findImports($reflection) as $import) { $importReflection = new ClassReflection($import); if ($importReflection->getShortName() === $class) { return $import; } } }
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))); }); }