public function exportJson() { $metadata = $this->cmf->getAllMetadata(); $metadata = MetadataFilter::filter($metadata, $this->filter); if ($metadata) { $filename = $this->path . '/' . $this->extensionKey . '/' . self::PROJECT_FILE_NAME; if (!is_dir($dir = dirname($filename))) { mkdir($dir, 0777, true); } $configuration = new ExtensionBuilderConfiguration(); if (is_readable($filename)) { if ($this->overwriteExistingFiles && $this->roundTripExistingFiles) { $this->logs[] = sprintf('File "<info>%s</info>" already exists, you selected both override (force) and round-trip - please choose one.', $filename); return 1; } if (!$this->overwriteExistingFiles && !$this->roundTripExistingFiles) { $this->logs[] = sprintf('File "<info>%s</info>" already exists, use --force to override or --round-trip it.', $filename); return 1; } if ($this->roundTripExistingFiles) { $roundtripContents = json_decode(file_get_contents($filename), true); $configuration->setProperties($this->mapArrayToClass($roundtripContents['properties'], new Properties())); $configuration->setLog($this->mapArrayToClass($roundtripContents['log'], new Log())); } } $configuration->getProperties()->setExtensionKey($this->extensionKey); $configuration->getLog()->setLastModified(date('Y-m-d H:i')); //in this array we store the target entites for all relations to create wires later on $relationTargetsByModuleByRelation = array(); $moduleIndex = 0; $posX = 50; $posY = 50; foreach ($metadata as $metadata) { if ($moduleIndex) { if (0 == $moduleIndex % 5) { $posX = 50; $posY += 200; } else { $posX += 300; } } $className = $metadata->name; //remove namespaces, e.g. when importing entities if (class_exists($className)) { $reflection = new \ReflectionClass($className); $className = $reflection->getShortName(); } $this->logs[] = sprintf('Processing table "<info>%s</info>"', $className); $module = new Module(); $module->getValue()->setName($className); $module->getConfig()->setPosition(array($posX, $posY)); $module->getValue()->getObjectsettings()->setUid($this->getRandomUid()); $module->getValue()->getObjectsettings()->setType(ObjectSettings::OBJECT_TYPE_ENTITY); //export properties foreach ($metadata->fieldMappings as $fieldMapping) { $property = new Property(); $property->setPropertyName($fieldMapping['fieldName']); $property->setPropertyType($this->getPropertyType($fieldMapping['type'])); $property->setUid($this->getRandomUid()); $module->getValue()->getPropertyGroup()->addProperty($property); } //export relations $relationIndex = 0; foreach ($metadata->associationMappings as $associationMapping) { $relationNameSingular = $associationMapping['fieldName']; $relationNamePlural = Inflector::pluralize(Inflector::singularize($associationMapping['fieldName'])); $relation = new Relation(); $relationType = null; $relationName = ''; switch ($associationMapping['type']) { case ClassMetadataInfo::ONE_TO_MANY: $relationType = Relation::ONE_TO_MANY; $relationName = $relationNamePlural; break; case ClassMetadataInfo::MANY_TO_ONE: $relationType = Relation::MANY_TO_ONE; $relationName = $relationNameSingular; break; case ClassMetadataInfo::ONE_TO_ONE: $relationType = Relation::ONE_TO_ONE; $relationName = $relationNameSingular; break; case ClassMetadataInfo::MANY_TO_MANY: $relationType = Relation::MANY_TO_MANY; $relationName = $relationNamePlural; break; } $relation->setRelationName($relationName); $relation->setRelationType($relationType); $relationName = $relationNameSingular; $module->getValue()->getRelationGroup()->addRelation($relation); $targetClassName = $associationMapping['targetEntity']; //remove namespaces, e.g. when importing entities if (class_exists($targetClassName)) { $reflection = new \ReflectionClass($targetClassName); $targetClassName = $reflection->getShortName(); } $relationTargetsByModuleByRelation[$moduleIndex][$relationIndex] = $targetClassName; $relationIndex++; $this->logs[] = sprintf('Added relation "<comment>%s</comment>": "<info>%s</info>" -> "<info>%s</info>"', $relationName, $className, $targetClassName); } $configuration->addModule($module); $moduleIndex++; } // now we have all the modules, we can create wires $moduleIndex = 0; foreach ($configuration->getModules() as $key => $module) { $relationIndex = 0; if (!empty($module->getValue()->getRelationGroup()->getRelations())) { foreach ($module->getValue()->getRelationGroup()->getRelations() as $relation) { /* @var $relation Relation */ // now add the corresponding wire for the relation $wire = new Wire(); $targetEntity = $relationTargetsByModuleByRelation[$moduleIndex][$relationIndex]; $targetModule = $configuration->getModuleByName($targetEntity); if ($targetModule) { $targetModuleId = array_search($targetModule, $configuration->getModules()); $src = new Node(); $src->setModuleId($key); $src->setTerminal(Node::TERMINAL_SRC . $relationIndex); $src->setUid($relation->getUid()); $tgt = new Node(); $tgt->setModuleId($targetModuleId); $tgt->setTerminal(Node::TERMINAL_TGT); $tgt->setUid($targetModule->getValue()->getObjectsettings()->getUid()); $wire->setSrc($src); $wire->setTgt($tgt); $configuration->addWire($wire); $this->logs[] = sprintf('Added wire "<comment>%s</comment>": "<info>%s</info>" -> "<info>%s</info>"', $relation->getRelationName(), $module->getValue()->getName(), $targetEntity); } $relationIndex++; } } $moduleIndex++; } file_put_contents($filename, json_encode($configuration, JSON_PRETTY_PRINT)); $this->logs[] = 'Exported database schema to ' . $filename; return true; } else { $this->logs[] = 'Database does not have any mapping information.'; return false; } }
public function exportJson() { // set metadata, mkdir, set filename and configuration $this->prepare(); if (!empty($this->metadata)) { $extbaseConfig = new ExtensionBuilderConfiguration(); $roundtripCache = array(); if (is_readable($this->filename)) { if ($this->overwriteExistingFiles && $this->roundTripExistingFiles) { $this->logs[] = sprintf('File "<info>%s</info>" already exists, you selected both override (force) and round-trip - please choose one.', $this->filename); return 1; } if (!$this->overwriteExistingFiles && !$this->roundTripExistingFiles) { $this->logs[] = sprintf('File "<info>%s</info>" already exists, use --force to override or --round-trip it.', $this->filename); return 1; } if ($this->roundTripExistingFiles) { $roundtripContents = json_decode(file_get_contents($this->filename), true); $extbaseConfig->setProperties($this->mapArrayToClass($roundtripContents['properties'], new Properties())); $extbaseConfig->setLog($this->mapArrayToClass($roundtripContents['log'], new Log())); // $roundtripCache[] foreach ($roundtripContents['modules'] as $moduleArray) { $module = $this->mapArrayToClass($moduleArray, new Module()); /* @var $module \EdRush\Extbaser\VO\ExtensionBuilderConfiguration\Module */ if (isset($module->value) && isset($module->value['name'])) { $roundtripCache['actionGroups'][$module->value['name']] = $module->getValue()['actionGroup']; } } } } $extensionKey = $this->extensionKey; if (is_null($extensionKey)) { // support limbo directory separators // e.g. on Windows git bash uses "/", but php's DIRECTORY_SEPARATOR is "\" $directorySeparators = array("\\", "/"); $path = str_replace($directorySeparators, DIRECTORY_SEPARATOR, $this->path); $extensionKey = array_pop(explode(DIRECTORY_SEPARATOR, $path)); } $extbaseConfig->getProperties()->setExtensionKey($extensionKey); $extbaseConfig->getLog()->setLastModified(date('Y-m-d H:i')); //in this array we store the target entites for all relations to create wires later on $relationTargetsByModuleByRelation = array(); $moduleIndex = 0; $posX = 50; $posY = 50; foreach ($this->metadata as $metadata) { /* @var $metadata \Doctrine\ORM\Mapping\ClassMetadata */ $className = $metadata->name; $tableName = $metadata->getTableName(); //remove namespaces, e.g. when importing entities if (class_exists($className)) { $reflection = new \ReflectionClass($className); $className = $reflection->getShortName(); } $ignore = false; if (isset($this->configuration['ignore_tables'])) { foreach ($this->configuration['ignore_tables'] as $ignoreTableName) { if (fnmatch($ignoreTableName, $tableName)) { $ignore = true; } } } if ($ignore) { continue; } $this->logs[] = ''; $this->logs[] = sprintf('Processing table "<info>%s</info>"...', $tableName); if ($moduleIndex) { if (0 == $moduleIndex % 5) { $posX = 50; $posY += 200; } else { $posX += 300; } } $module = new Module(); $module->getValue()->setName($className); $module->getConfig()->setPosition(array($posX, $posY)); $module->getValue()->getObjectsettings()->setUid($this->getRandomUid()); $module->getValue()->getObjectsettings()->setType(ObjectSettings::OBJECT_TYPE_ENTITY); if (isset($roundtripCache['actionGroups']) && isset($roundtripCache['actionGroups'][$className])) { foreach ($roundtripCache['actionGroups'][$className] as $key => $value) { $module->getValue()->getActionGroup()->{$key} = $value; } } //export properties foreach ($metadata->fieldMappings as $fieldMapping) { $property = new Property(); $property->setPropertyName($fieldMapping['fieldName']); $property->setPropertyType($this->getPropertyType($fieldMapping['type'])); $property->setUid($this->getRandomUid()); $module->getValue()->getPropertyGroup()->addProperty($property); } //export relations $relationIndex = 0; foreach ($metadata->associationMappings as $associationMapping) { $targetClassName = $associationMapping['targetEntity']; //remove namespaces, e.g. when importing entities if (class_exists($targetClassName)) { $reflection = new \ReflectionClass($targetClassName); $targetClassName = $reflection->getShortName(); } $relationNameSingular = $associationMapping['fieldName']; $relationNamePlural = Inflector::pluralize(Inflector::singularize($associationMapping['fieldName'])); $relationNameSingularMappedBy = Inflector::singularize(strtolower($targetClassName)); $relationNamePluralMappedBy = Inflector::pluralize(strtolower($targetClassName)); $relation = new Relation(); $relationType = null; $relationName = ''; switch ($associationMapping['type']) { case ClassMetadataInfo::ONE_TO_MANY: $relationType = Relation::ONE_TO_MANY; $relationName = $relationNamePlural; break; case ClassMetadataInfo::MANY_TO_ONE: $relationType = Relation::MANY_TO_ONE; $relationName = $relationNameSingular; break; case ClassMetadataInfo::ONE_TO_ONE: $relationType = Relation::ONE_TO_ONE; $relationName = $relationNameSingular; break; case ClassMetadataInfo::MANY_TO_MANY: $relationType = Relation::MANY_TO_MANY; if ($relationNameSingularMappedBy == $tableName) { $relationName = $relationNamePlural; } else { $relationName = $relationNamePluralMappedBy; } break; } $relation->setRelationName($relationName); $relation->setRelationType($relationType); // add the relation to the module $module->getValue()->getRelationGroup()->addRelation($relation); $relationTargetsByModuleByRelation[$moduleIndex][$relationIndex] = $targetClassName; $relationIndex++; $this->logs[] = sprintf('Added relation "<comment>%s</comment>": "<info>%s</info>" -> "<info>%s</info>"', $relationName, $className, $targetClassName); } $extbaseConfig->addModule($module); $moduleIndex++; } // now we have all the modules, we can create wires $moduleIndex = 0; foreach ($extbaseConfig->getModules() as $key => $module) { $relationIndex = 0; if (!empty($module->getValue()->getRelationGroup()->getRelations())) { foreach ($module->getValue()->getRelationGroup()->getRelations() as $relation) { /* @var $relation Relation */ // now add the corresponding wire for the relation $wire = new Wire(); $targetEntity = $relationTargetsByModuleByRelation[$moduleIndex][$relationIndex]; $targetModule = $extbaseConfig->getModuleByName($targetEntity); if ($targetModule) { $targetModuleId = array_search($targetModule, $extbaseConfig->getModules()); $src = new Node(); $src->setModuleId($key); $src->setTerminal(Node::TERMINAL_SRC . $relationIndex); $src->setUid($relation->getUid()); $tgt = new Node(); $tgt->setModuleId($targetModuleId); $tgt->setTerminal(Node::TERMINAL_TGT); $tgt->setUid($targetModule->getValue()->getObjectsettings()->getUid()); $wire->setSrc($src); $wire->setTgt($tgt); $extbaseConfig->addWire($wire); $this->logs[] = sprintf('Added wire "<comment>%s</comment>": "<info>%s</info>" -> "<info>%s</info>"', $relation->getRelationName(), $module->getValue()->getName(), $targetEntity); } $relationIndex++; } } $moduleIndex++; } file_put_contents($this->filename, json_encode($extbaseConfig, JSON_PRETTY_PRINT)); $this->logs[] = 'Exported database schema to ' . $this->filename; return true; } else { $this->logs[] = 'Database does not have any mapping information.'; return false; } }