/** * Do some stuff on file * * @param array $configuration * @param FileContainer $fileContainer * @throws \Exception */ public function generate(array $configuration, FileContainer $fileContainer) { $this->configuration = $configuration; foreach ($configuration['entities'] as $entityName => $config) { $fqcn = $this->createEntityFqcn($this->configuration, $entityName); $entityFile = new ClassFileDefinition($entityName, $config, $fqcn); // Parent if (null !== $config['parent']) { if (false === array_key_exists($config['parent'], $this->configuration['entities'])) { throw new \Exception(sprintf('Entity %s has for parent %s, but this entity is not defined in config file', $entityName, $config['parent'])); } $entityFile->setParent($this->createEntityFqcn($this->configuration, $config['parent'])); } // Abstract if (true === $config['abstract']) { $entityFile->setPrefix(ClassPrefix::ABSTRACT_PREFIX()); } //Properties $construct = $this->getConstructor($entityFile); foreach ($config['properties'] as $propertyName => $propertyConfig) { $property = $this->createProperty($propertyName, $propertyConfig); $property->setVisibility(new Visibility($this->configuration['global']['fieldVisibility'])); $entityFile->addProperty($property); if ($property->getDefaultValue() instanceof ObjectValue) { $construct->addLine(sprintf('$this->%s = %s;', $property->getName()->toLowerCamelCase(), $property->getDefaultValue()->getPhpFormatedValue())); } } if (0 !== count($construct->getLines())) { $entityFile->addMethod($construct); } //Create $fileContainer->addFile($entityFile, [Tag::ENTITY()]); } }
/** * @param array $configuration * @param ClassFileDefinition $entityFile * @return bool */ protected function entityHasChild(array $configuration, ClassFileDefinition $entityFile) { foreach ($configuration['entities'] as $entityName => $config) { if (true === array_key_exists('parent', $config) && $entityFile->getSourceName() === $config['parent']) { return true; } } return false; }
protected function initializeProperty(ClassFileDefinition $file, PropertyDefinition $property) { $fqcn = new FullyQualifiedClassName('Doctrine\\Common\\Collections\\ArrayCollection'); $file->addUse($fqcn->getFullQualifiedClassName()); $arrayCollection = new ObjectValue($fqcn); $property->setDefaultValue($arrayCollection); $construct = $this->getConstructor($file); $construct->addLine(sprintf('$this->%s = %s;', $property->getName()->toLowerCamelCase(), $arrayCollection->getPhpFormatedValue())); }
/** * Do some stuff on file. * * @param array $configuration * @param FileContainer $fileContainer * * @return void */ public function generate(array $configuration, FileContainer $fileContainer) { foreach ($configuration['enums'] as $enumName => $enumConfiguration) { $fqcn = $this->createEnumFqcn($configuration, $enumName); $file = new ClassFileDefinition($enumName, $enumConfiguration, $fqcn); $file->setParent(new FullyQualifiedClassName('MyCLabs\\Enum\\Enum')); $file->setPrefix(ClassPrefix::FINAL_PREFIX()); foreach ($enumConfiguration['items'] as $item) { $file->addConstant(new ConstantDefinition(new PhpVariableName($item), new StringValue($item))); } $fileContainer->addFile($file, [Tag::ENUM]); } }
/** * @param array $configuration * @param FileContainer $fileContainer * @throws \Exception */ public function generate(array $configuration, FileContainer $fileContainer) { /** @var ClassFileDefinition[] $entityFiles */ $entityFiles = $fileContainer->getFilesByTag(Tag::ENTITY()); foreach ($entityFiles as $entityFile) { if ($entityFile->getPrefix() === ClassPrefix::ABSTRACT_PREFIX) { continue; } $repositoryFqcn = $this->createRepositoryFqcn($configuration, $entityFile->getFullyQualifiedClassName()->getName()); $annotations = $entityFile->getAnnotations(); foreach ($annotations as $key => $annotation) { if (false !== strpos($annotation, '@ORM\\Entity')) { unset($annotations[$key]); } } $annotations[] = sprintf('@ORM\\Entity(repositoryClass="%s")', $repositoryFqcn->getFullQualifiedClassName()); $entityFile->setAnnotations($annotations); $repositoryFile = new ClassFileDefinition($entityFile->getSourceName(), $entityFile->getSourceConfiguration(), $repositoryFqcn); $repositoryFile->setParent(new FullyQualifiedClassName('Doctrine\\ORM\\EntityRepository')); $fileContainer->addFile($repositoryFile, [Tag::REPOSITORY()]); } }
/** * @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()]); } }
private function generateRelationAnnotation(ClassFileDefinition $entityFile, PropertyDefinition $property) { $definition = $property->getSourceConfiguration(); $cardinality = $this->getCardinality($this->configuration, $property); switch ($cardinality) { //One to One case Cardinality::CARDINALITY_0_1: case Cardinality::CARDINALITY_1_0: case Cardinality::CARDINALITY_1_1: $annotationName = 'OneToOne'; break; //One To Many //One To Many case Cardinality::CARDINALITY_0_N: case Cardinality::CARDINALITY_1_N: $annotationName = 'OneToMany'; break; //Many To One //Many To One case Cardinality::CARDINALITY_N_0: case Cardinality::CARDINALITY_N_1: $annotationName = 'ManyToOne'; break; //Many to Many //Many to Many case Cardinality::CARDINALITY_N_N: $annotationName = 'ManyToMany'; break; default: throw new \Exception(sprintf('%s is not a valid cardinality', $cardinality)); } $relationConfiguration = ['targetEntity' => '"' . $this->createEntityFqcn($this->configuration, $definition['entity'])->getFullQualifiedClassName() . '"']; $reversePropertyName = $this->getReversePropertyName($this->configuration, $property); if ("ManyToOne" === $annotationName && null !== $reversePropertyName && true === array_key_exists('inverse', $definition)) { throw new \Exception('Doctrine do not accept Inversed relation ManyToOne, Switch Cardinality to OneToMany'); } if ("OneToMany" === $annotationName && null === $reversePropertyName) { throw new \Exception('Doctrine do not accept OneToMany, without reverse side'); } if (null !== $reversePropertyName) { if (true === array_key_exists('inverse', $definition)) { $relationConfiguration['mappedBy'] = '"' . $reversePropertyName->toLowerCamelCase() . '"'; } else { $relationConfiguration['inversedBy'] = '"' . $reversePropertyName->toLowerCamelCase() . '"'; } } $formattedConf = []; foreach ($relationConfiguration as $key => $value) { $formattedConf[] = sprintf('%s=%s', $key, $value); } $property->addAnnotation(sprintf('@ORM\\%s(%s)', $annotationName, implode(', ', $formattedConf))); $inverseJoinColumns = $this->generateJoinColumn($definition['entity'], $property, $cardinality); if ($cardinality == Cardinality::CARDINALITY_N_N) { $entityName = $entityFile->getSourceName(); $joinTableName = new PhpVariableName($entityName . '_' . $definition['entity']); $joinColumns = $this->generateJoinColumn($entityName, $property, $cardinality); $joinTableTemplate = <<<'ANNOT' @ORM\JoinTable(name="%s", * joinColumns={%s}, * inverseJoinColumns={%s} * ) ANNOT; $property->addAnnotation(sprintf($joinTableTemplate, $joinTableName->toLowerSnakeCase(), implode(', ', $joinColumns), implode(', ', $inverseJoinColumns))); } else { if (1 === count($inverseJoinColumns)) { $property->addAnnotation(reset($inverseJoinColumns)); } elseif (1 < count($inverseJoinColumns)) { $property->addAnnotation(sprintf('@ORM\\JoinColumns({%s})', implode(', ', $inverseJoinColumns))); } } }