/** * @param array $configuration * @param FileContainer $fileContainer * @throws \Exception */ public function generate(array $configuration, FileContainer $fileContainer) { $this->configuration = $configuration; foreach ($configuration['entities'] as $entityName => $config) { if (true === $config['abstract']) { continue; } $relatedEntity = $this->createEntityFqcn($configuration, $entityName); $repositoryFile = new ClassFileDefinition($entityName, $config, $relatedEntity); $method = new MethodDefinition(new PhpVariableName('initMetadata'), [new ParameterDefinition(new ObjectType(new FullyQualifiedClassName('CCMBenchmark\\Ting\\Serializer\\SerializerFactoryInterface')), new PhpVariableName('serializerFactory')), new ParameterDefinition(new ArrayType(), new PhpVariableName('options'), new ArrayValue([]))]); $method->addLine(sprintf(' $metadata = new Metadata($serializerFactory); $metadata->setEntity(%s::class); $metadata->setConnectionName($options[\'connection\']); $metadata->setDatabase($options[\'database\']); $metadata->setTable(\'%s\'); ', $relatedEntity->getName(), $relatedEntity->getClassName()->toLowerSnakeCase())); foreach ($config['properties'] as $propertyName => $propertyConfig) { if ('relation' === $propertyConfig['type']) { continue; } $propertyName = new PhpVariableName($propertyName); $fieldDefinition = ['primary' => $propertyConfig['primary'], 'autoincrement' => $propertyConfig['autoincrement'], 'fieldName' => $propertyName->toLowerCamelCase(), 'columnName' => $propertyName->toLowerSnakeCase(), 'type' => $this->transformTypeToValidTingType($propertyConfig['type'])]; if ('enum' === $propertyConfig['type']) { $fieldDefinition['serializer'] = null; //todo: add a good serializer for each enumerator type } $fieldArray = array_diff_key($fieldDefinition, $this->getDefaultFieldConfiguration()); $dataValue = $this->dataValueFactory->getDataValueFromValue($fieldArray); $method->addLine(sprintf('$metadata->addField(%s);', $dataValue->getPhpFormatedValue())); } $repositoryFile->setParent(new FullyQualifiedClassName('CCMBenchmark\\Ting\\Repository\\Repository'))->addInterface(new FullyQualifiedClassName('CCMBenchmark\\Ting\\Repository\\MetadataInitializer'))->addUse($relatedEntity->getFullQualifiedClassName())->addMethod($method); //Create $fileContainer->addFile($repositoryFile, [Tag::REPOSITORY()]); } }
/** * @param $propertyName * @param $propertyConfig * @return PropertyDefinition * @throws \Exception */ private function createProperty($propertyName, $propertyConfig) { $defaultValue = null; switch ($propertyConfig['type']) { case "relation": if (false === array_key_exists('entity', $propertyConfig)) { throw new \Exception(sprintf('property[type: Relation] %s must define "entity" key', $propertyName)); } $fqcn = $this->createEntityFqcn($this->configuration, $propertyConfig['entity']); if (true === array_key_exists('inverse', $propertyConfig)) { //Inversed side if (false === array_key_exists($propertyConfig['entity'], $this->configuration['entities'])) { throw new \Exception(sprintf('property[type: Relation] %s is inversed by %s but this entity does not exist ', $propertyName, $propertyConfig['entity'])); } if (false === array_key_exists($propertyConfig['inverse'], $this->configuration['entities'][$propertyConfig['entity']]['properties'])) { throw new \Exception(sprintf('property %s as %s for inverse property, but this property does not exist ', $propertyName, $propertyConfig['inverse'])); } $inversedProperty = $this->configuration['entities'][$propertyConfig['entity']]['properties'][$propertyConfig['inverse']]; if (false === array_key_exists('cardinality', $inversedProperty)) { throw new \Exception(sprintf('property[type: Relation] %s must define "cardinality" key', $propertyConfig['entity'])); } /** @var Cardinality $cardinality */ $cardinality = new Cardinality($inversedProperty['cardinality']); $type = new ObjectType($fqcn); if (true === $cardinality->hasSourceMany()) { $type = new ArrayType($type); } } else { //Relation Side $type = new ObjectType($fqcn); if (false === array_key_exists('cardinality', $propertyConfig)) { throw new \Exception(sprintf('property[type: Relation] %s must define "cardinality" key', $propertyName)); } /** @var Cardinality $cardinality */ $cardinality = new Cardinality($propertyConfig['cardinality']); if (true === $cardinality->hasTargetMany()) { $type = new ArrayType($type); } } break; case "enum": $fqcn = $this->createEnumFqcn($this->configuration, $propertyConfig['enum']); $type = new ObjectType($fqcn); if (true === array_key_exists('default', $propertyConfig)) { $defaultValue = new ObjectValue($fqcn, [new StringValue($propertyConfig['default'])]); } break; case "enum[]": $fqcn = $this->createEnumFqcn($this->configuration, $propertyConfig['enum']); $type = new ArrayType(new ObjectType($fqcn)); $defaultValue = new ArrayValue([]); break; default: $type = $this->typeFactory->getTypeFromName($propertyConfig['type']); if (true === array_key_exists('default', $propertyConfig)) { $defaultValue = $this->valueFactory->createValue($type, $propertyConfig['default']); } } $name = new PhpVariableName($propertyName); $property = new PropertyDefinition($propertyName, $propertyConfig, $type, $name, $defaultValue); return $property; }