/** * 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; }
protected function setUp($settingFile = '') { if (!class_exists('PHPParser_Parser')) { \EBT\ExtensionBuilder\Parser\AutoLoader::register(); } if (!class_exists('PHPParser_Parser')) { die('Parser not found!!'); } $this->fixturesPath = PATH_typo3conf . 'ext/extension_builder/Tests/Fixtures/'; $this->extension = $this->getMock('EBT\\ExtensionBuilder\\Domain\\Model\\Extension', array('getExtensionDir')); $extensionKey = 'dummy'; vfsStream::setup('testDir'); $dummyExtensionDir = vfsStream::url('testDir') . '/'; $this->extension->setVendorName('EBT'); $this->extension->setExtensionKey($extensionKey); $this->extension->expects($this->any())->method('getExtensionDir')->will($this->returnValue($dummyExtensionDir)); if (is_dir($dummyExtensionDir)) { GeneralUtility::mkdir($dummyExtensionDir, TRUE); } $yamlParser = new \EBT\ExtensionBuilder\Utility\SpycYAMLParser(); $settings = $yamlParser->YAMLLoadString(file_get_contents($this->fixturesPath . 'Settings/settings1.yaml')); $this->extension->setSettings($settings); $configurationManager = GeneralUtility::makeInstance('EBT\\ExtensionBuilder\\Configuration\\ConfigurationManager'); $this->roundTripService = $this->getMock($this->buildAccessibleProxy('EBT\\ExtensionBuilder\\Service\\RoundTrip'), array('dummy')); $this->classBuilder = GeneralUtility::makeInstance('EBT\\ExtensionBuilder\\Service\\ClassBuilder'); $this->classBuilder->injectConfigurationManager($configurationManager); $this->roundTripService->injectClassBuilder($this->classBuilder); $this->roundTripService->injectConfigurationManager($configurationManager); $this->templateParser = $this->getMock($this->buildAccessibleProxy('TYPO3\\CMS\\Fluid\\Core\\Parser\\TemplateParser'), array('dummy')); $this->fileGenerator = $this->getMock($this->buildAccessibleProxy('EBT\\ExtensionBuilder\\Service\\FileGenerator'), array('dummy')); $objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); $this->objectManager = clone $objectManager; $this->parserService = new \EBT\ExtensionBuilder\Service\Parser(new \PHPParser_Lexer()); $this->printerService = new \EBT\ExtensionBuilder\Service\Printer(); $this->printerService->injectNodeFactory(new \EBT\ExtensionBuilder\Parser\NodeFactory()); $localizationService = $this->objectManager->get('EBT\\ExtensionBuilder\\Service\\LocalizationService'); $this->fileGenerator->injectObjectManager($this->objectManager); $this->fileGenerator->injectPrinterService($this->printerService); $this->fileGenerator->injectLocalizationService($localizationService); $this->roundTripService->injectParserService($this->parserService); $this->roundTripService->initialize($this->extension); $this->classBuilder->injectRoundtripService($this->roundTripService); $this->classBuilder->injectParserService($this->parserService); $this->classBuilder->injectPrinterService($this->printerService); $this->classBuilder->injectClassFactory(new \EBT\ExtensionBuilder\Parser\ClassFactory()); $this->classBuilder->initialize($this->fileGenerator, $this->extension, TRUE); $this->fileGenerator->injectClassBuilder($this->classBuilder); $this->codeTemplateRootPath = PATH_typo3conf . 'ext/extension_builder/Resources/Private/CodeTemplates/Extbase/'; $this->modelClassTemplatePath = $this->codeTemplateRootPath . 'Classes/Domain/Model/Model.phpt'; $this->fileGenerator->setSettings(array('codeTemplateRootPath' => $this->codeTemplateRootPath, 'extConf' => array('enableRoundtrip' => '1'))); $this->fileGenerator->_set('codeTemplateRootPath', PATH_typo3conf . 'ext/extension_builder/Resources/Private/CodeTemplates/Extbase/'); $this->fileGenerator->_set('enableRoundtrip', true); $this->fileGenerator->_set('extension', $this->extension); }
/** * Generates the code for the repository class * Either from domainRepository template or from class partial * * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject * @param bool $mergeWithExistingClass * * @return string */ public function generateDomainRepositoryCode(\EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject) { $repositoryTemplateClassPath = $this->codeTemplateRootPath . 'Classes/Domain/Repository/Repository.phpt'; $existingClassFileObject = null; if ($this->roundTripEnabled) { $existingClassFileObject = $this->roundTripService->getRepositoryClassFile($domainObject); } $repositoryClassFileObject = $this->classBuilder->generateRepositoryClassFileObject($domainObject, $repositoryTemplateClassPath, $existingClassFileObject); if ($repositoryClassFileObject) { $this->addLicenseHeader($repositoryClassFileObject->getFirstClass()); return $this->printerService->renderFileObject($repositoryClassFileObject, true); } else { throw new \Exception('Class file for repository could not be generated'); } }
public function setUp() { parent::setUp(); $this->objectManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class); if (!class_exists('PhpParser\\Parser')) { throw new UnknownClassException('PhpParser not found!!'); } $this->fixturesPath = __DIR__ . '/Fixtures/'; $testTargetDir = 'testDir'; vfsStream::setup($testTargetDir); $dummyExtensionDir = vfsStream::url($testTargetDir) . '/'; $yamlParser = new \EBT\ExtensionBuilder\Utility\SpycYAMLParser(); $settings = $yamlParser->YAMLLoadString(file_get_contents($this->fixturesPath . 'Settings/settings1.yaml')); $this->extension = $this->getMock(\EBT\ExtensionBuilder\Domain\Model\Extension::class, array('getExtensionDir')); $this->extension->setVendorName('EBT'); $this->extension->setExtensionKey('dummy'); $this->extension->expects($this->any())->method('getExtensionDir')->will($this->returnValue($dummyExtensionDir)); if (is_dir($dummyExtensionDir)) { GeneralUtility::mkdir($dummyExtensionDir, TRUE); } $this->extension->setSettings($settings); // get instances to inject in Mocks $configurationManager = $this->objectManager->get(\EBT\ExtensionBuilder\Configuration\ConfigurationManager::class); $this->parserService = new \EBT\ExtensionBuilder\Service\Parser(new \PhpParser\Lexer()); $this->printerService = $this->objectManager->get(\EBT\ExtensionBuilder\Service\Printer::class); $localizationService = $this->objectManager->get(\EBT\ExtensionBuilder\Service\LocalizationService::class); $this->classBuilder = $this->objectManager->get(\EBT\ExtensionBuilder\Service\ClassBuilder::class); $this->classBuilder->initialize($this->extension); $this->roundTripService = $this->getAccessibleMock(\EBT\ExtensionBuilder\Service\RoundTrip::class, array('dummy')); $this->inject($this->roundTripService, 'configurationManager', $configurationManager); $this->inject($this->roundTripService, 'parserService', $this->parserService); $this->roundTripService->initialize($this->extension); $this->fileGenerator = $this->getAccessibleMock(\EBT\ExtensionBuilder\Service\FileGenerator::class, array('dummy')); $this->inject($this->fileGenerator, 'objectManager', $this->objectManager); $this->inject($this->fileGenerator, 'printerService', $this->printerService); $this->inject($this->fileGenerator, 'localizationService', $localizationService); $this->inject($this->fileGenerator, 'classBuilder', $this->classBuilder); $this->inject($this->fileGenerator, 'roundTripService', $this->roundTripService); $this->codeTemplateRootPath = PATH_typo3conf . 'ext/extension_builder/Resources/Private/CodeTemplates/Extbase/'; $this->modelClassTemplatePath = $this->codeTemplateRootPath . 'Classes/Domain/Model/Model.phpt'; $this->fileGenerator->setSettings(array('codeTemplateRootPath' => $this->codeTemplateRootPath, 'extConf' => array('enableRoundtrip' => '1'))); $this->fileGenerator->_set('codeTemplateRootPath', __DIR__ . '/../Resources/Private/CodeTemplates/Extbase/'); $this->fileGenerator->_set('enableRoundtrip', true); $this->fileGenerator->_set('extension', $this->extension); }
/** * wrapper for GeneralUtility::mkdir_deep * checks for overwrite settings * * @param string $directory base path * @param string $deepDirectory */ protected function mkdir_deep($directory, $deepDirectory) { if (!$this->roundTripEnabled) { GeneralUtility::mkdir_deep($directory, $deepDirectory); } else { $subDirectories = explode('/', $deepDirectory); $tmpBasePath = $directory; foreach ($subDirectories as $subDirectory) { $overWriteMode = RoundTrip::getOverWriteSettingForPath($tmpBasePath . $subDirectory, $this->extension); //throw new \Exception($directory . $subDirectory . '/' . $overWriteMode); if ($overWriteMode === -1) { // skip creation return; } if (!is_dir($deepDirectory) || $this->roundTripEnabled && $overWriteMode < 2) { GeneralUtility::mkdir_deep($tmpBasePath, $subDirectory); } $tmpBasePath .= $subDirectory . '/'; } } }
/** * Generate the code files according to the transferred JSON configuration. * * @throws \Exception * @return array (status => message) */ protected function rpcActionSave() { try { $extensionBuildConfiguration = $this->configurationManager->getConfigurationFromModeler(); GeneralUtility::devLog('Modeler Configuration', 'extension_builder', 0, $extensionBuildConfiguration); $validationConfigurationResult = $this->extensionValidator->validateConfigurationFormat($extensionBuildConfiguration); if (!empty($validationConfigurationResult['warnings'])) { $confirmationRequired = $this->handleValidationWarnings($validationConfigurationResult['warnings']); if (!empty($confirmationRequired)) { return $confirmationRequired; } } if (!empty($validationConfigurationResult['errors'])) { $errorMessage = ''; /** @var $exception \Exception */ foreach ($validationConfigurationResult['errors'] as $exception) { $errorMessage .= '<br />' . $exception->getMessage(); } throw new \Exception($errorMessage); } $extension = $this->extensionSchemaBuilder->build($extensionBuildConfiguration); } catch (\Exception $e) { throw $e; } // Validate the extension $validationResult = $this->extensionValidator->isValid($extension); if (!empty($validationResult['errors'])) { $errorMessage = ''; /** @var $exception \Exception */ foreach ($validationResult['errors'] as $exception) { $errorMessage .= '<br />' . $exception->getMessage(); } throw new \Exception($errorMessage); } if (!empty($validationResult['warnings'])) { $confirmationRequired = $this->handleValidationWarnings($validationResult['warnings']); if (!empty($confirmationRequired)) { return $confirmationRequired; } } $extensionDirectory = $extension->getExtensionDir(); if (!is_dir($extensionDirectory)) { GeneralUtility::mkdir($extensionDirectory); } else { if ($this->settings['extConf']['backupExtension'] == 1) { try { RoundTrip::backupExtension($extension, $this->settings['extConf']['backupDir']); } catch (\Exception $e) { throw $e; } } $extensionSettings = $this->configurationManager->getExtensionSettings($extension->getExtensionKey()); if ($this->settings['extConf']['enableRoundtrip'] == 1) { if (empty($extensionSettings)) { // no config file in an existing extension! // this would result in a total overwrite so we create one and give a warning $this->configurationManager->createInitialSettingsFile($extension, $this->settings['codeTemplateRootPath']); return array('warning' => "<span class='error'>Roundtrip is enabled but no configuration file was found.</span><br />This might happen if you use the extension builder the first time for this extension. <br />A settings file was generated in <br /><b>typo3conf/ext/" . $extension->getExtensionKey() . '/Configuration/ExtensionBuilder/settings.yaml.</b><br />Configure the overwrite settings, then save again.'); } try { RoundTrip::prepareExtensionForRoundtrip($extension); } catch (\Exception $e) { throw $e; } } else { if (!is_array($extensionSettings['ignoreWarnings']) || !in_array(\EBT\ExtensionBuilder\Domain\Validator\ExtensionValidator::EXTENSION_DIR_EXISTS, $extensionSettings['ignoreWarnings'])) { $confirmationRequired = $this->handleValidationWarnings(array(new \EBT\ExtensionBuilder\Domain\Exception\ExtensionException("This action will overwrite previously saved content!\n(Enable the roundtrip feature to avoid this warning).", \EBT\ExtensionBuilder\Domain\Validator\ExtensionValidator::EXTENSION_DIR_EXISTS))); if (!empty($confirmationRequired)) { return $confirmationRequired; } } } } try { $this->fileGenerator->build($extension); $this->extensionInstallationStatus->setExtension($extension); $message = '<p>The Extension was saved</p>' . $this->extensionInstallationStatus->getStatusMessage(); if ($extension->getNeedsUploadFolder()) { $message .= '<br />Notice: File upload is not yet implemented.'; } $result = array('success' => $message); if ($this->extensionInstallationStatus->isDbUpdateNeeded()) { $result['confirmUpdate'] = true; } } catch (\Exception $e) { throw $e; } $this->extensionRepository->saveExtensionConfiguration($extension); return $result; }