/** * @param \EBT\ExtensionBuilder\Domain\Model\File $fileObject * @return array */ public function getFileStatements(\EBT\ExtensionBuilder\Domain\Model\File $fileObject) { $stmts = array(); if ($fileObject->hasNamespaces()) { foreach ($fileObject->getNamespaces() as $namespace) { $stmts[] = $this->buildNamespaceNode($namespace); foreach ($namespace->getAliasDeclarations() as $aliasDeclaration) { $stmts[] = $this->buildUseStatementNode($aliasDeclaration['name'], $aliasDeclaration['alias']); } $stmts = array_merge($stmts, $this->getContainerStatements($namespace)); } } else { $stmts = array_merge($stmts, $this->getContainerStatements($fileObject)); } return $stmts; }
/** * This method generates the repository class object, * which is passed to the template * it keeps all methods and properties including * user modified method bodies and comments * needed to create a repository class file * * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject * @param boolean $mergeWithExistingClass * * @return \EBT\ExtensionBuilder\Domain\Model\File */ public function generateRepositoryClassFileObject($domainObject, $repositoryTemplateClassPath, $mergeWithExistingClass) { $this->classObject = NULL; $className = $domainObject->getName() . 'Repository'; $this->templateFileObject = $this->parserService->parseFile($repositoryTemplateClassPath); $this->templateClassObject = $this->templateFileObject->getFirstClass(); if ($mergeWithExistingClass) { try { $this->classFileObject = $this->roundTripService->getRepositoryClassFile($domainObject); if ($this->classFileObject instanceof Model\File) { $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->templateClassObject; $this->classObject->resetAll(); $this->classObject->setName($className); $this->classObject->setNamespaceName($this->extension->getNamespaceName() . '\\Domain\\Repository'); $this->classObject->setDescription('The repository for ' . Inflector::pluralize($domainObject->getName())); if (isset($this->settings['Repository']['parentClass'])) { $parentClass = $this->settings['Repository']['parentClass']; } else { $parentClass = '\\TYPO3\\CMS\\Extbase\\Persistence\\Repository'; } $this->classObject->setParentClassName($parentClass); } $this->classFileObject->getNamespace()->setName($this->extension->getNamespaceName() . '\\Domain\\Repository')->setClasses(array($this->classObject)); return $this->classFileObject; }
/** * @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); } } } }
/** * includes the generated file and compares the reflection class * with the class object * * @param \EBT\ExtensionBuilder\Domain\Model\File $classFileObject * @param string $pathToGeneratedFile * @return \ReflectionClass */ protected function compareClasses($classFileObject, $pathToGeneratedFile) { $this->assertTrue(file_exists($pathToGeneratedFile), $pathToGeneratedFile . 'not exists'); $classObject = $classFileObject->getFirstClass(); $this->assertTrue($classObject instanceof \EBT\ExtensionBuilder\Domain\Model\ClassObject\ClassObject); $className = $classObject->getQualifiedName(); if (!class_exists($className)) { require_once $pathToGeneratedFile; } $this->assertTrue(class_exists($className), 'Class "' . $className . '" does not exist! Tried ' . $pathToGeneratedFile); $reflectedClass = new \ReflectionClass($className); $this->assertEquals(count($reflectedClass->getMethods()), count($classObject->getMethods()), 'Method count does not match'); $this->assertEquals(count($reflectedClass->getProperties()), count($classObject->getProperties())); $this->assertEquals(count($reflectedClass->getConstants()), count($classObject->getConstants())); if (strlen($classObject->getNamespaceName()) > 0) { $this->assertEquals($reflectedClass->getNamespaceName(), $classObject->getNamespaceName()); } return $reflectedClass; }
/** * This method generates the repository class object, * which is passed to the template * it keeps all methods and properties including * user modified method bodies and comments * needed to create a repository class file * * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject * @param \EBT\ExtensionBuilder\Domain\Model\File $existingClassFileObject * * @return \EBT\ExtensionBuilder\Domain\Model\File */ public function generateRepositoryClassFileObject($domainObject, $repositoryTemplateClassPath, $existingClassFileObject = null) { $this->classObject = null; $className = $domainObject->getName() . 'Repository'; $this->templateFileObject = $this->parserService->parseFile($repositoryTemplateClassPath); $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->templateClassObject; $this->classObject->resetAll(); $this->classObject->setName($className); $this->classObject->setDescription('The repository for ' . Inflector::pluralize($domainObject->getName())); if (isset($this->settings['Repository']['parentClass'])) { $parentClass = $this->settings['Repository']['parentClass']; } else { $parentClass = '\\TYPO3\\CMS\\Extbase\\Persistence\\Repository'; } $this->classObject->setParentClassName($parentClass); } if ($domainObject->getSorting() && is_null($this->classObject->getProperty('defaultOrderings'))) { $defaultOrderings = $this->templateClassObject->getProperty('defaultOrderings'); $this->classObject->addProperty($defaultOrderings); } $this->classFileObject->getNamespace()->setName($this->extension->getNamespaceName() . '\\Domain\\Repository')->setClasses(array($this->classObject)); return $this->classFileObject; }
/** * * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $currentDomainObject * * @return \EBT\ExtensionBuilder\Domain\Model\ClassObject\ClassObject|null */ public function getRepositoryClassFile(Model\DomainObject $currentDomainObject) { $extensionDir = $this->previousExtensionDirectory; if (isset($this->previousDomainObjects[$currentDomainObject->getUniqueIdentifier()])) { $oldDomainObject = $this->previousDomainObjects[$currentDomainObject->getUniqueIdentifier()]; $fileName = FileGenerator::getFolderForClassFile($extensionDir, 'Repository', false); $fileName .= $oldDomainObject->getName() . 'Repository.php'; if (file_exists($fileName)) { $this->classFileObject = $this->parserService->parseFile($fileName); $this->classObject = $this->classFileObject->getFirstClass(); $this->classObject->setName($currentDomainObject->getName() . 'Repository'); if ($oldDomainObject->getName() != $currentDomainObject->getName() || $this->extensionRenamed) { $newClassName = $currentDomainObject->getDomainRepositoryClassName(); $this->classObject->setName($newClassName); $this->cleanUp(FileGenerator::getFolderForClassFile($extensionDir, 'Repository'), $oldDomainObject->getName() . 'Repository.php'); } return $this->classFileObject; } else { GeneralUtility::devLog('class file didn\'t exist:' . $fileName, 'extension_builder', 2); } } else { $fileName = FileGenerator::getFolderForClassFile($extensionDir, 'Repository', false); $fileName .= $currentDomainObject->getName() . 'Repository.php'; if (file_exists($fileName)) { $this->classFileObject = $this->parserService->parseFile($fileName); $this->classObject = $this->classFileObject->getFirstClass(); $this->classObject->setFileName($fileName); $this->classObject->setFileName($fileName); $this->log('existing Repository class:' . $fileName, 0, (array) $this->classObject); return $this->classFileObject; } } $this->log('No existing Repository class:' . $currentDomainObject->getName(), 2); return null; }