Exemple #1
0
 /**
  * @param \PhpParser\Node $node
  */
 public function leaveNode(\PhpParser\Node $node)
 {
     array_pop($this->contextStack);
     if ($this->isContainerNode(end($this->contextStack)) || count($this->contextStack) === 0) {
         // we are on the first level
         if ($node instanceof Node\Stmt\Class_) {
             if (count($this->contextStack) > 0) {
                 if (end($this->contextStack)->getType() == 'Stmt_Namespace') {
                     $currentNamespaceName = NodeConverter::getValueFromNode(end($this->contextStack));
                     $this->currentClassObject->setNamespaceName($currentNamespaceName);
                     $this->currentNamespace->addClass($this->currentClassObject);
                 }
             } else {
                 $this->fileObject->addClass($this->currentClassObject);
                 $this->currentClassObject = null;
                 $this->currentContainer = $this->fileObject;
             }
         } elseif ($node instanceof Node\Stmt\Namespace_) {
             if (null !== $this->currentNamespace) {
                 $this->fileObject->addNamespace($this->currentNamespace);
                 $this->currentNamespace = null;
                 $this->currentContainer = $this->fileObject;
             } else {
                 //TODO: find how this could happen
             }
         } elseif ($node instanceof Node\Stmt\TraitUse) {
             if ($this->currentClassObject) {
                 $this->currentClassObject->addUseTraitStatement($node);
             }
         } elseif ($node instanceof Node\Stmt\Use_) {
             $this->currentContainer->addAliasDeclaration(NodeConverter::convertUseAliasStatementNodeToArray($node));
         } elseif ($node instanceof Node\Stmt\ClassConst) {
             $constants = NodeConverter::convertClassConstantNodeToArray($node);
             foreach ($constants as $constant) {
                 $this->currentContainer->setConstant($constant['name'], $constant['value']);
             }
         } elseif ($node instanceof Node\Stmt\ClassMethod) {
             $this->onFirstLevel = true;
             $method = $this->classFactory->buildClassMethodObject($node);
             $this->currentClassObject->addMethod($method);
         } elseif ($node instanceof Node\Stmt\Property) {
             $property = $this->classFactory->buildPropertyObject($node);
             $this->currentClassObject->addProperty($property);
         } elseif ($node instanceof Node\Stmt\Function_) {
             $this->onFirstLevel = true;
             $function = $this->classFactory->buildFunctionObject($node);
             $this->currentContainer->addFunction($function);
         } elseif (!$node instanceof Node\Name) {
             // any other nodes (except the name node of the current container node)
             // go into statements container
             if ($this->currentContainer->getFirstClass() === false) {
                 $this->currentContainer->addPreClassStatements($node);
             } else {
                 $this->currentContainer->addPostClassStatements($node);
             }
         }
     }
 }
 /**
  * This method generates the class object, which is passed to the template
  * it keeps all methods and properties including user modified method bodies and
  * comments that are required to create a controller class file
  *
  * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject
  * @param boolean $mergeWithExistingClass
  *
  * @return \EBT\ExtensionBuilder\Domain\Model\File
  */
 public function generateControllerClassFileObject($domainObject, $controllerClassTemplatePath, $mergeWithExistingClass)
 {
     $this->classObject = NULL;
     $className = $domainObject->getName() . 'Controller';
     $this->templateFileObject = $this->parserService->parseFile($controllerClassTemplatePath);
     $this->templateClassObject = $this->templateFileObject->getFirstClass();
     if ($mergeWithExistingClass) {
         try {
             $this->classFileObject = $this->roundTripService->getControllerClassFile($domainObject);
             if (!is_null($this->classFileObject)) {
                 $this->classObject = $this->classFileObject->getFirstClass();
             }
         } catch (\Exception $e) {
             \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('Class ' . $className . ' could not be imported: ' . $e->getMessage(), 'extension_builder');
         }
     }
     if ($this->classObject == NULL) {
         $this->classFileObject = clone $this->templateFileObject;
         $this->classObject = clone $this->templateFileObject->getFirstClass();
         $this->classObject->resetAll();
         $this->classObject->setName($className);
         $this->classObject->setDescription($className);
         if (isset($this->settings['Controller']['parentClass'])) {
             $parentClass = $this->settings['Controller']['parentClass'];
         } else {
             $parentClass = '\\TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController';
         }
         $this->classObject->setParentClassName($parentClass);
     }
     if ($domainObject->isAggregateRoot()) {
         $repositoryName = \TYPO3\CMS\Core\Utility\GeneralUtility::lcfirst($domainObject->getName() . 'Repository');
         // now add the property to class Object (or update an existing class Object property)
         if (!$this->classObject->propertyExists($repositoryName)) {
             $classProperty = $this->templateClassObject->getProperty('domainObjectRepository');
             $classProperty->setName($repositoryName);
             $classProperty->setDescription($repositoryName);
             $classProperty->setTag('var', $domainObject->getFullyQualifiedDomainRepositoryClassName(), TRUE);
             $this->classObject->setProperty($classProperty);
         }
         if (!$this->classObject->getProperty($repositoryName)->isTaggedWith('inject') && !$this->classObject->methodExists('inject' . ucfirst($repositoryName))) {
             $this->classObject->getProperty($repositoryName)->setTag('inject');
         }
     }
     foreach ($domainObject->getActions() as $action) {
         $actionMethodName = $action->getName() . 'Action';
         if (!$this->classObject->methodExists($actionMethodName)) {
             $actionMethod = $this->buildActionMethod($action, $domainObject);
             $this->classObject->addMethod($actionMethod);
         }
     }
     $this->classFileObject->getNamespace()->setName($this->extension->getNamespaceName() . '\\Controller')->setClasses(array($this->classObject));
     return $this->classFileObject;
 }
Exemple #3
0
 /**
  * This method generates the class object, which is passed to the template
  * it keeps all methods and properties including user modified method bodies and
  * comments that are required to create a controller class file
  *
  * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject
  * @param \EBT\ExtensionBuilder\Domain\Model\File $existingClassFileObject
  *
  * @return \EBT\ExtensionBuilder\Domain\Model\File
  */
 public function generateControllerClassFileObject($domainObject, $controllerClassTemplatePath, $existingClassFileObject = null)
 {
     $this->classObject = null;
     $className = $domainObject->getName() . 'Controller';
     $this->templateFileObject = $this->parserService->parseFile($controllerClassTemplatePath);
     $this->templateClassObject = $this->templateFileObject->getFirstClass();
     if ($existingClassFileObject) {
         $this->classFileObject = $existingClassFileObject;
         $this->classObject = $existingClassFileObject->getFirstClass();
         if ($this->classFileObject->getNamespace() === false) {
             $nameSpace = new \EBT\ExtensionBuilder\Domain\Model\NamespaceObject('dummy');
             $this->classFileObject->addNamespace($nameSpace);
         }
     }
     if ($this->classObject == null) {
         $this->classFileObject = clone $this->templateFileObject;
         $this->classObject = clone $this->templateFileObject->getFirstClass();
         $this->classObject->resetAll();
         $this->classObject->setName($className);
         $this->classObject->setDescription($className);
         if (isset($this->settings['Controller']['parentClass'])) {
             $parentClass = $this->settings['Controller']['parentClass'];
         } else {
             $parentClass = '\\TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController';
         }
         $this->classObject->setParentClassName($parentClass);
     }
     if ($domainObject->isAggregateRoot()) {
         $repositoryName = \TYPO3\CMS\Core\Utility\GeneralUtility::lcfirst($domainObject->getName() . 'Repository');
         // now add the property to class Object (or update an existing class Object property)
         if (!$this->classObject->propertyExists($repositoryName)) {
             $classProperty = $this->templateClassObject->getProperty('domainObjectRepository');
             $classProperty->setName($repositoryName);
             $classProperty->setDescription($repositoryName);
             $classProperty->setTag('var', $domainObject->getFullyQualifiedDomainRepositoryClassName(), true);
             $this->classObject->setProperty($classProperty);
         }
         if (!$this->classObject->getProperty($repositoryName)->isTaggedWith('inject') && !$this->classObject->methodExists('inject' . ucfirst($repositoryName))) {
             $this->classObject->getProperty($repositoryName)->setTag('inject');
         }
     }
     foreach ($domainObject->getActions() as $action) {
         $actionMethodName = $action->getName() . 'Action';
         if (!$this->classObject->methodExists($actionMethodName)) {
             $actionMethod = $this->buildActionMethod($action, $domainObject);
             $this->classObject->addMethod($actionMethod);
         }
     }
     $this->classFileObject->getNamespace()->setName($this->extension->getNamespaceName() . '\\Controller')->setClasses(array($this->classObject));
     return $this->classFileObject;
 }
Exemple #4
0
 /**
  * update means renaming of method name, parameter and replacing
  * parameter names in method body
  *
  * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\AbstractProperty $oldProperty
  * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\AbstractProperty $newProperty
  * @param string $methodType get,set,add,remove,is
  *
  * @return void
  */
 protected function updateMethod($oldProperty, $newProperty, $methodType)
 {
     $oldMethodName = ClassBuilder::getMethodName($oldProperty, $methodType);
     // the method to be merged
     $mergedMethod = $this->classObject->getMethod($oldMethodName);
     if (!$mergedMethod) {
         // no previous version of the method exists
         return;
     }
     $newMethodName = ClassBuilder::getMethodName($newProperty, $methodType);
     $this->log('updateMethod:' . $oldMethodName . '=>' . $newMethodName, 'extension_builder');
     if ($oldProperty->getName() != $newProperty->getName()) {
         // rename the method
         $mergedMethod->setName($newMethodName);
         $oldMethodBody = $mergedMethod->getBodyStmts();
         $oldComment = $mergedMethod->getDocComment();
         $newMethodBody = $this->replacePropertyNameInMethodBody($oldProperty->getName(), $newProperty->getName(), $oldMethodBody);
         $mergedMethod->setBodyStmts($newMethodBody);
     }
     // update the method parameters
     $methodParameters = $mergedMethod->getParameters();
     if (!empty($methodParameters)) {
         $parameterTags = $mergedMethod->getTagValues('param');
         foreach ($methodParameters as $methodParameter) {
             $oldParameterName = $methodParameter->getName();
             if ($oldParameterName == ClassBuilder::getParameterName($oldProperty, $methodType)) {
                 $newParameterName = ClassBuilder::getParameterName($newProperty, $methodType);
                 $methodParameter->setName($newParameterName);
                 $newMethodBody = $this->replacePropertyNameInMethodBody($oldParameterName, $newParameterName, $mergedMethod->getBodyStmts());
                 $mergedMethod->setBodyStmts($newMethodBody);
             }
             $typeHint = $methodParameter->getTypeHint();
             if ($typeHint) {
                 if ($oldProperty->isRelation()) {
                     /** @var $oldProperty \EBT\ExtensionBuilder\Domain\Model\DomainObject\Relation\AbstractRelation */
                     if ($typeHint == $oldProperty->getForeignClassName()) {
                         $methodParameter->setTypeHint($this->updateExtensionKey($this->getForeignClassName($newProperty)));
                     }
                 }
             }
             $parameterTags[$methodParameter->getPosition()] = ClassBuilder::getParamTag($newProperty, $methodType);
             $mergedMethod->replaceParameter($methodParameter);
         }
         $mergedMethod->setTag('param', $parameterTags);
     }
     $returnTagValue = $mergedMethod->getTagValue('return');
     if ($returnTagValue != 'void') {
         $mergedMethod->setTag('return', $newProperty->getTypeForComment() . ' ' . $newProperty->getName());
     }
     // replace property names in description
     $mergedMethod->setDescription(str_replace($oldProperty->getName(), $newProperty->getName(), $mergedMethod->getDescription()));
     if ($oldProperty instanceof AbstractRelation && $newProperty instanceof AbstractRelation) {
         $mergedMethod->setDescription(str_replace($oldProperty->getForeignClassName(), $newProperty->getForeignClassName(), $mergedMethod->getDescription()));
     }
     $this->classObject->removeMethod($oldMethodName);
     $this->classObject->addMethod($mergedMethod);
 }