/**
  * This test creates an extension based on a JSON file, generated
  * with version 1.0 of the ExtensionBuilder and compares all
  * generated files with the originally created ones
  * This test should help, to find compatibility breaking changes
  *
  * @test
  */
 function generateExtensionFromVersion3Configuration()
 {
     $this->configurationManager = $this->getMock($this->buildAccessibleProxy('EBT\\ExtensionBuilder\\Configuration\\ConfigurationManager'), array('dummy'));
     $this->extensionSchemaBuilder = $this->objectManager->get('EBT\\ExtensionBuilder\\Service\\ExtensionSchemaBuilder');
     $testExtensionDir = $this->fixturesPath . 'TestExtensions/test_extension_v3/';
     $jsonFile = $testExtensionDir . \EBT\ExtensionBuilder\Configuration\ConfigurationManager::EXTENSION_BUILDER_SETTINGS_FILE;
     if (file_exists($jsonFile)) {
         // compatibility adaptions for configurations from older versions
         $extensionConfigurationJSON = json_decode(file_get_contents($jsonFile), TRUE);
         $extensionConfigurationJSON = $this->configurationManager->fixExtensionBuilderJSON($extensionConfigurationJSON, FALSE);
     } else {
         $extensionConfigurationJSON = array();
         $this->fail('JSON file not found');
     }
     $this->extension = $this->extensionSchemaBuilder->build($extensionConfigurationJSON);
     $this->fileGenerator->setSettings(array('codeTemplateRootPath' => PATH_typo3conf . 'ext/extension_builder/Resources/Private/CodeTemplates/Extbase/', 'extConf' => array('enableRoundtrip' => '0')));
     $newExtensionDir = vfsStream::url('testDir') . '/';
     $this->extension->setExtensionDir($newExtensionDir . 'test_extension/');
     $this->fileGenerator->build($this->extension);
     $referenceFiles = \TYPO3\CMS\Core\Utility\GeneralUtility::getAllFilesAndFoldersInPath(array(), $testExtensionDir);
     foreach ($referenceFiles as $referenceFile) {
         $createdFile = str_replace($testExtensionDir, $this->extension->getExtensionDir(), $referenceFile);
         if (!in_array(basename($createdFile), array('ExtensionBuilder.json'))) {
             $referenceFileContent = str_replace(array('2011-08-11T06:49:00Z', '2011-08-11', '###YEAR###', '2014'), array(date('Y-m-d\\TH:i:00\\Z'), date('Y-m-d'), date('Y'), date('Y')), file_get_contents($referenceFile));
             $this->assertFileExists($createdFile, 'File ' . $createdFile . ' was not created!');
             // do not compare files that contain a formatted DateTime, as it might have changed between file creation and this comparison
             if (strpos($referenceFile, 'xlf') === FALSE && strpos($referenceFile, 'yaml') === FALSE) {
                 $originalLines = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(LF, $referenceFileContent, TRUE);
                 $generatedLines = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(LF, file_get_contents($createdFile), TRUE);
                 $this->assertEquals($originalLines, $generatedLines, 'File ' . $createdFile . ' was not equal to original file.');
             }
         }
     }
 }
 public function setUp()
 {
     parent::setUp();
     $this->configurationManager = $this->getAccessibleMock('EBT\\ExtensionBuilder\\Configuration\\ConfigurationManager', array('dummy'));
     $this->extensionSchemaBuilder = $this->objectManager->get('EBT\\ExtensionBuilder\\Service\\ExtensionSchemaBuilder');
     $testExtensionDir = $this->fixturesPath . 'TestExtensions/test_extension/';
     $jsonFile = $testExtensionDir . \EBT\ExtensionBuilder\Configuration\ConfigurationManager::EXTENSION_BUILDER_SETTINGS_FILE;
     if (file_exists($jsonFile)) {
         // compatibility adaptions for configurations from older versions
         $extensionConfigurationJSON = json_decode(file_get_contents($jsonFile), TRUE);
         $extensionConfigurationJSON = $this->configurationManager->fixExtensionBuilderJSON($extensionConfigurationJSON, FALSE);
     } else {
         $extensionConfigurationJSON = array();
         $this->fail('JSON file not found: ' . $jsonFile);
     }
     $this->fixtureExtension = $this->extensionSchemaBuilder->build($extensionConfigurationJSON);
     $this->fixtureExtension->setExtensionDir($testExtensionDir);
     $this->roundTripService->_set('extension', $this->fixtureExtension);
     $this->roundTripService->_set('previousExtensionDirectory', $testExtensionDir);
     $this->roundTripService->_set('extensionDirectory', $testExtensionDir);
     $this->roundTripService->_set('previousDomainObjects', array($this->fixtureExtension->getDomainObjectByName('Main')->getUniqueIdentifier() => $this->fixtureExtension->getDomainObjectByName('Main')));
     $this->fileGenerator->setSettings(array('codeTemplateRootPath' => PATH_typo3conf . 'ext/extension_builder/Resources/Private/CodeTemplates/Extbase/', 'extConf' => array('enableRoundtrip' => '1')));
 }
 /**
  * @test
  */
 public function conversionExtractsWholeExtensionMetadataWithRelations()
 {
     $input = array('modules' => array(0 => array('value' => array('name' => 'Blog', 'objectsettings' => array('description' => 'A blog object', 'aggregateRoot' => false, 'type' => 'Entity'), 'propertyGroup' => array('properties' => array(0 => array('propertyName' => 'name', 'propertyType' => 'String'), 1 => array('propertyName' => 'description', 'propertyType' => 'String'))), 'relationGroup' => array('relations' => array(0 => array('relationName' => 'posts', 'relationType' => 'zeroToMany', 'propertyIsExcludeField' => 1))))), 1 => array('value' => array('name' => 'Post', 'objectsettings' => array('description' => 'A blog post', 'aggregateRoot' => false, 'type' => 'Entity'), 'propertyGroup' => array('properties' => array()), 'relationGroup' => array('relations' => array(0 => array('relationName' => 'comments', 'relationType' => 'zeroToMany', 'propertyIsExcludeField' => 1))))), 2 => array('value' => array('name' => 'Comment', 'objectsettings' => array('description' => '', 'aggregateRoot' => false, 'type' => 'Entity'), 'propertyGroup' => array('properties' => array()), 'relationGroup' => array('relations' => array())))), 'properties' => array('description' => 'Some description', 'extensionKey' => $this->extensionKey, 'name' => 'My ext name', 'emConf' => array('state' => 'beta')), 'wires' => array(0 => array('tgt' => array('moduleId' => 1, 'terminal' => 'SOURCES'), 'src' => array('moduleId' => 0, 'terminal' => 'relationWire_0')), 1 => array('tgt' => array('moduleId' => 2, 'terminal' => 'SOURCES'), 'src' => array('moduleId' => 1, 'terminal' => 'relationWire_0'))));
     $extension = new \EBT\ExtensionBuilder\Domain\Model\Extension();
     $extension->setName('My ext name');
     $extension->setState(\EBT\ExtensionBuilder\Domain\Model\Extension::STATE_BETA);
     $extension->setExtensionKey($this->extensionKey);
     $extension->setDescription('Some description');
     $extension->setExtensionDir('');
     $blog = new \EBT\ExtensionBuilder\Domain\Model\DomainObject();
     $blog->setName('Blog');
     $blog->setDescription('A blog object');
     $blog->setEntity(true);
     $blog->setAggregateRoot(false);
     $property = new \EBT\ExtensionBuilder\Domain\Model\DomainObject\StringProperty('name');
     $blog->addProperty($property);
     $property = new \EBT\ExtensionBuilder\Domain\Model\DomainObject\StringProperty('description');
     $blog->addProperty($property);
     $extension->addDomainObject($blog);
     $post = new \EBT\ExtensionBuilder\Domain\Model\DomainObject();
     $post->setName('Post');
     $post->setDescription('A blog post');
     $post->setEntity(true);
     $post->setAggregateRoot(false);
     $extension->addDomainObject($post);
     $comment = new \EBT\ExtensionBuilder\Domain\Model\DomainObject();
     $comment->setName('Comment');
     $comment->setDescription('');
     $comment->setEntity(true);
     $comment->setAggregateRoot(false);
     $extension->addDomainObject($comment);
     $relation = new \EBT\ExtensionBuilder\Domain\Model\DomainObject\Relation\ZeroToManyRelation('posts');
     $relation->setForeignModel($post);
     $relation->setExcludeField(1);
     $blog->addProperty($relation);
     $relation = new \EBT\ExtensionBuilder\Domain\Model\DomainObject\Relation\ZeroToManyRelation('comments');
     $relation->setForeignModel($comment);
     $relation->setExcludeField(1);
     $post->addProperty($relation);
     $actualExtension = $this->extensionSchemaBuilder->build($input);
     self::assertEquals($extension->getDomainObjects(), $actualExtension->getDomainObjects(), 'The extensions differ');
 }
 /**
  * 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;
 }