Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save StalkAlex/52ce9deb14056e7fe5f1fb49fd49f927 to your computer and use it in GitHub Desktop.
Save StalkAlex/52ce9deb14056e7fe5f1fb49fd49f927 to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
namespace App\Command;
use Spatie\ArrayToXml\ArrayToXml;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Yaml;
/**
* Temp command for converting mappings.
* Requirements:
* - composer require spatie/array-to-xml
*/
final class ConvertMappingsCommand extends Command
{
private const MAPPING_DIR = __DIR__ . '../../config/mapping/doctrine/';
protected function configure()
{
$this->setName('temp:convert-mappings');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$errors = 0;
$finder = new Finder();
$finder
->files()
->in(self::MAPPING_DIR)
->name('*.mongodb.yml');
foreach ($finder as $file) {
echo 'processing '.$file->getFilename()."\n";
try {
$data = Yaml::parse($file->getContents());
$this->saveXml(
$this->createXml(
$this->convertData($data)
),
$file
);
} catch (ParseException $exception) {
$output->writeln(\sprintf('<error>Unable to parse the YAML for file %s</error>', $file->getRealPath()));
++$errors;
}
}
return (0 === $errors) ? 0 : 1;
}
private function convertData(array $data): array
{
$result = [];
$documentName = \array_key_first($data);
$document = $data[$documentName];
$rootAttributes = [
'name' => $documentName,
];
$attributes = [
'collection',
'repositoryClass',
'changeTrackingPolicy',
'inheritanceType',
];
foreach ($attributes as $attribute) {
if (isset($document[$attribute])) {
$rootAttributes[$this->decamelize($attribute)] = $document[$attribute];
}
}
switch ($document['type'] ?? 'document') {
case 'document':
$type = 'document';
break;
case 'embeddedDocument':
$type = 'embedded-document';
break;
default:
throw new \Exception(\sprintf('Unsupported document type %s', $document['type']));
}
$result[$type] = [
'_attributes' => $rootAttributes,
];
if (isset($document['discriminatorField'])) {
if (\is_array($document['discriminatorField'])) {
throw new \Exception('discriminatorField is array');
}
$result[$type]['discriminator-field'] = [
'_attributes' => [
'name' => $document['discriminatorField'],
],
];
}
if (isset($document['discriminatorMap'])) {
$maps = [];
foreach ($document['discriminatorMap'] as $value => $className) {
if (\is_array($className)) {
throw new \Exception('discriminatorMap classname is array');
}
$maps[] = [
'_attributes' => [
'value' => $value,
'class' => $className,
],
];
}
$result[$type]['discriminator-map']['discriminator-mapping'] = $maps;
}
if (isset($document['fields'])) {
$fields = [];
foreach ($document['fields'] ?? [] as $name => $props) {
$field = [
'_attributes' => [
'field-name' => $name,
],
];
foreach ($props ?? [] as $key => $value) {
$elementName = $this->decamelize($key);
if (\is_string($value)) {
$field['_attributes'][$elementName] = $value;
} elseif (\is_bool($value)) {
$field['_attributes'][$elementName] = $value ? 'true' : 'false';
} else {
throw new \Exception(\sprintf('Unknown value %s for field %s', \print_r($value, true), $key));
}
}
$fields[] = $field;
}
$result[$type]['field'] = $fields;
}
if (isset($document['referenceOne'])) {
$fields = [];
foreach ($document['referenceOne'] ?? [] as $name => $props) {
$field = [
'_attributes' => [
'field' => $name,
],
];
foreach ($props ?? [] as $key => $value) {
$elementName = $this->decamelize($key);
if (\is_string($value)) {
$field['_attributes'][$elementName] = $value;
} elseif (\is_bool($value)) {
$field['_attributes'][$elementName] = $value ? 'true' : 'false';
} else {
throw new \Exception(\sprintf('Unsupported value %s for field %s', \print_r($value, true), $key));
}
}
$fields[] = $field;
}
$result[$type]['reference-one'] = $fields;
}
if (isset($document['referenceMany'])) {
$fields = [];
foreach ($document['referenceMany'] ?? [] as $name => $props) {
$field = [
'_attributes' => [
'field' => $name,
],
];
foreach ($props ?? [] as $key => $value) {
$elementName = $this->decamelize($key);
if (\is_string($value)) {
$field['_attributes'][$elementName] = $value;
} elseif (\is_bool($value)) {
$field['_attributes'][$elementName] = $value ? 'true' : 'false';
} else {
throw new \Exception(\sprintf('Unsupported value %s for field %s', \print_r($value, true), $key));
}
}
$fields[] = $field;
}
$result[$type]['reference-many'] = $fields;
}
if (isset($document['embedOne'])) {
$fields = [];
foreach ($document['embedOne'] ?? [] as $name => $props) {
$field = [
'_attributes' => [
'field' => $name,
],
];
foreach ($props ?? [] as $key => $value) {
$elementName = $this->decamelize($key);
if (\is_string($value)) {
$field['_attributes'][$elementName] = $value;
} elseif (\is_bool($value)) {
$field['_attributes'][$elementName] = $value ? 'true' : 'false';
} else {
throw new \Exception(\sprintf('Unsupported value %s for field %s', \print_r($value, true), $key));
}
}
$fields[] = $field;
}
$result[$type]['embed-one'] = $fields;
}
if (isset($document['embedMany'])) {
$fields = [];
foreach ($document['embedMany'] ?? [] as $name => $props) {
$field = [
'_attributes' => [
'field' => $name,
],
];
foreach ($props ?? [] as $key => $value) {
$elementName = $this->decamelize($key);
if (\is_string($value)) {
$field['_attributes'][$elementName] = $value;
} elseif (\is_bool($value)) {
$field['_attributes'][$elementName] = $value ? 'true' : 'false';
} else {
throw new \Exception(\sprintf('Unsupported value %s for field %s', \print_r($value, true), $key));
}
}
$fields[] = $field;
}
$result[$type]['embed-many'] = $fields;
}
if (isset($document['indexes'])) {
$indexes = [];
foreach ($document['indexes'] ?? [] as $indexName => $props) {
$options = [];
$keys = [];
foreach ($props['options'] ?? [] as $name => $value) {
$options[] = [
'_attributes' => [
'name' => $name,
'value' => $value,
],
];
}
foreach ($props['keys'] ?? [] as $name => $order) {
$keys[] = [
'_attributes' => [
'name' => $name,
'order' => $order,
],
];
}
$indexes[] = [
'_attributes' => [
'name' => $indexName,
],
'key' => $keys,
];
}
if (\count($indexes)) {
$result[$type]['indexes']['index'] = $indexes;
}
}
if (isset($document['lifecycleCallbacks'])) {
$events = [];
foreach ($document['lifecycleCallbacks'] ?? [] as $event => $methods) {
foreach ($methods as $method) {
$events[] = [
'_attributes' => [
'type' => $event,
'method' => $method,
],
];
}
}
if (\count($events)) {
$result[$type]['lifecycle-callbacks']['lifecycle-callback'] = $events;
}
}
return $result;
}
private function createXml(array $data): string
{
$rootItem = [
'rootElementName' => 'doctrine-mongo-mapping',
'_attributes' => [
'xmlns' => 'http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping',
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation' => 'http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping
http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd',
],
];
// Convert array to XML file
$converter = new ArrayToXml($data, $rootItem, true, 'UTF-8', '1.0');
// Turn XML indenting on
$converter->toDom()->formatOutput = true;
// Return XML-document as string
return $converter->toXml();
}
private function saveXml(string $xml, \SplFileInfo $file): void
{
$newfilename = \str_replace('.yml', '.xml', $file->getFilename());
\file_put_contents(\getcwd().'/xml/'.$newfilename, $xml);
}
private function decamelize(string $string): string
{
return \strtolower(\preg_replace(['/([a-z\d])([A-Z])/', '/([^-])([A-Z][a-z])/'], '$1-$2', $string));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment