Merge pull request #1135 from deeky666/DDC-3304
[DDC-3304] Add support for embeddables in entity generator
This commit is contained in:
commit
f12c311a79
@ -139,6 +139,13 @@ class EntityGenerator
|
||||
*/
|
||||
protected $fieldVisibility = 'private';
|
||||
|
||||
/**
|
||||
* Whether or not to make generated embeddables immutable.
|
||||
*
|
||||
* @var boolean.
|
||||
*/
|
||||
protected $embeddablesImmutable = false;
|
||||
|
||||
/**
|
||||
* Hash-map for handle types.
|
||||
*
|
||||
@ -299,6 +306,21 @@ public function __construct()
|
||||
{
|
||||
<spaces><collections>
|
||||
}
|
||||
';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected static $embeddableConstructorMethodTemplate =
|
||||
'/**
|
||||
* Constructor
|
||||
*
|
||||
* <paramTags>
|
||||
*/
|
||||
public function __construct(<params>)
|
||||
{
|
||||
<spaces><fields>
|
||||
}
|
||||
';
|
||||
|
||||
/**
|
||||
@ -485,6 +507,16 @@ public function __construct()
|
||||
$this->fieldVisibility = $visibility;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not to generate immutable embeddables.
|
||||
*
|
||||
* @param boolean $embeddablesImmutable
|
||||
*/
|
||||
public function setEmbeddablesImmutable($embeddablesImmutable)
|
||||
{
|
||||
$this->embeddablesImmutable = (boolean) $embeddablesImmutable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an annotation prefix.
|
||||
*
|
||||
@ -599,6 +631,7 @@ public function __construct()
|
||||
protected function generateEntityBody(ClassMetadataInfo $metadata)
|
||||
{
|
||||
$fieldMappingProperties = $this->generateEntityFieldMappingProperties($metadata);
|
||||
$embeddedProperties = $this->generateEntityEmbeddedProperties($metadata);
|
||||
$associationMappingProperties = $this->generateEntityAssociationMappingProperties($metadata);
|
||||
$stubMethods = $this->generateEntityStubMethods ? $this->generateEntityStubMethods($metadata) : null;
|
||||
$lifecycleCallbackMethods = $this->generateEntityLifecycleCallbackMethods($metadata);
|
||||
@ -609,6 +642,10 @@ public function __construct()
|
||||
$code[] = $fieldMappingProperties;
|
||||
}
|
||||
|
||||
if ($embeddedProperties) {
|
||||
$code[] = $embeddedProperties;
|
||||
}
|
||||
|
||||
if ($associationMappingProperties) {
|
||||
$code[] = $associationMappingProperties;
|
||||
}
|
||||
@ -637,6 +674,10 @@ public function __construct()
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($metadata->isEmbeddedClass && $this->embeddablesImmutable) {
|
||||
return $this->generateEmbeddableConstructor($metadata);
|
||||
}
|
||||
|
||||
$collections = array();
|
||||
|
||||
foreach ($metadata->associationMappings as $mapping) {
|
||||
@ -652,6 +693,100 @@ public function __construct()
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMetadataInfo $metadata
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateEmbeddableConstructor(ClassMetadataInfo $metadata)
|
||||
{
|
||||
$paramTypes = array();
|
||||
$paramVariables = array();
|
||||
$params = array();
|
||||
$fields = array();
|
||||
|
||||
// Resort fields to put optional fields at the end of the method signature.
|
||||
$requiredFields = array();
|
||||
$optionalFields = array();
|
||||
|
||||
foreach ($metadata->fieldMappings as $fieldMapping) {
|
||||
if (empty($fieldMapping['nullable'])) {
|
||||
$requiredFields[] = $fieldMapping;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$optionalFields[] = $fieldMapping;
|
||||
}
|
||||
|
||||
$fieldMappings = array_merge($requiredFields, $optionalFields);
|
||||
|
||||
foreach ($metadata->embeddedClasses as $fieldName => $embeddedClass) {
|
||||
$paramType = '\\' . ltrim($embeddedClass['class'], '\\');
|
||||
$paramVariable = '$' . $fieldName;
|
||||
|
||||
$paramTypes[] = $paramType;
|
||||
$paramVariables[] = $paramVariable;
|
||||
$params[] = $paramType . ' ' . $paramVariable;
|
||||
$fields[] = '$this->' . $fieldName . ' = ' . $paramVariable . ';';
|
||||
}
|
||||
|
||||
foreach ($fieldMappings as $fieldMapping) {
|
||||
if (isset($fieldMapping['declaredField']) &&
|
||||
isset($metadata->embeddedClasses[$fieldMapping['declaredField']])
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$paramTypes[] = $this->getType($fieldMapping['type']) . (!empty($fieldMapping['nullable']) ? '|null' : '');
|
||||
$param = '$' . $fieldMapping['fieldName'];
|
||||
$paramVariables[] = $param;
|
||||
|
||||
if ($fieldMapping['type'] === 'datetime') {
|
||||
$param = $this->getType($fieldMapping['type']) . ' ' . $param;
|
||||
}
|
||||
|
||||
if (!empty($fieldMapping['nullable'])) {
|
||||
$param .= ' = null';
|
||||
}
|
||||
|
||||
$params[] = $param;
|
||||
|
||||
$fields[] = '$this->' . $fieldMapping['fieldName'] . ' = $' . $fieldMapping['fieldName'] . ';';
|
||||
}
|
||||
|
||||
$maxParamTypeLength = max(array_map('strlen', $paramTypes));
|
||||
$paramTags = array_map(
|
||||
function ($type, $variable) use ($maxParamTypeLength) {
|
||||
return '@param ' . $type . str_repeat(' ', $maxParamTypeLength - strlen($type) + 1) . $variable;
|
||||
},
|
||||
$paramTypes,
|
||||
$paramVariables
|
||||
);
|
||||
|
||||
// Generate multi line constructor if the signature exceeds 120 characters.
|
||||
if (array_sum(array_map('strlen', $params)) + count($params) * 2 + 29 > 120) {
|
||||
$delimiter = "\n" . $this->spaces;
|
||||
$params = $delimiter . implode(',' . $delimiter, $params) . "\n";
|
||||
} else {
|
||||
$params = implode(', ', $params);
|
||||
}
|
||||
|
||||
$replacements = array(
|
||||
'<paramTags>' => implode("\n * ", $paramTags),
|
||||
'<params>' => $params,
|
||||
'<fields>' => implode("\n" . $this->spaces, $fields),
|
||||
);
|
||||
|
||||
$constructor = str_replace(
|
||||
array_keys($replacements),
|
||||
array_values($replacements),
|
||||
static::$embeddableConstructorMethodTemplate
|
||||
);
|
||||
|
||||
return $this->prefixCodeWithSpaces($constructor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo this won't work if there is a namespace in brackets and a class outside of it.
|
||||
*
|
||||
@ -866,7 +1001,8 @@ public function __construct()
|
||||
'generateTableAnnotation',
|
||||
'generateInheritanceAnnotation',
|
||||
'generateDiscriminatorColumnAnnotation',
|
||||
'generateDiscriminatorMapAnnotation'
|
||||
'generateDiscriminatorMapAnnotation',
|
||||
'generateEntityAnnotation',
|
||||
);
|
||||
|
||||
foreach ($methods as $method) {
|
||||
@ -875,14 +1011,6 @@ public function __construct()
|
||||
}
|
||||
}
|
||||
|
||||
$customRepository = $metadata->customRepositoryClassName
|
||||
? '(repositoryClass="' . $metadata->customRepositoryClassName . '")'
|
||||
: '';
|
||||
|
||||
$lines[] = ' * @' . $this->annotationsPrefix
|
||||
. ($metadata->isMappedSuperclass ? 'MappedSuperclass' : 'Entity')
|
||||
. $customRepository;
|
||||
|
||||
if (isset($metadata->lifecycleCallbacks) && $metadata->lifecycleCallbacks) {
|
||||
$lines[] = ' * @' . $this->annotationsPrefix . 'HasLifecycleCallbacks';
|
||||
}
|
||||
@ -893,6 +1021,26 @@ public function __construct()
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMetadataInfo $metadata
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateEntityAnnotation(ClassMetadataInfo $metadata)
|
||||
{
|
||||
$prefix = '@' . $this->annotationsPrefix;
|
||||
|
||||
if ($metadata->isEmbeddedClass) {
|
||||
return $prefix . 'Embeddable';
|
||||
}
|
||||
|
||||
$customRepository = $metadata->customRepositoryClassName
|
||||
? '(repositoryClass="' . $metadata->customRepositoryClassName . '")'
|
||||
: '';
|
||||
|
||||
return $prefix . ($metadata->isMappedSuperclass ? 'MappedSuperclass' : 'Entity') . $customRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMetadataInfo $metadata
|
||||
*
|
||||
@ -900,6 +1048,10 @@ public function __construct()
|
||||
*/
|
||||
protected function generateTableAnnotation($metadata)
|
||||
{
|
||||
if ($metadata->isEmbeddedClass) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$table = array();
|
||||
|
||||
if (isset($metadata->table['schema'])) {
|
||||
@ -1003,7 +1155,17 @@ public function __construct()
|
||||
$methods = array();
|
||||
|
||||
foreach ($metadata->fieldMappings as $fieldMapping) {
|
||||
if ( ! isset($fieldMapping['id']) || ! $fieldMapping['id'] || $metadata->generatorType == ClassMetadataInfo::GENERATOR_TYPE_NONE) {
|
||||
if (isset($fieldMapping['declaredField']) &&
|
||||
isset($metadata->embeddedClasses[$fieldMapping['declaredField']])
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (( ! isset($fieldMapping['id']) ||
|
||||
! $fieldMapping['id'] ||
|
||||
$metadata->generatorType == ClassMetadataInfo::GENERATOR_TYPE_NONE
|
||||
) && (! $metadata->isEmbeddedClass || ! $this->embeddablesImmutable)
|
||||
) {
|
||||
if ($code = $this->generateEntityStubMethod($metadata, 'set', $fieldMapping['fieldName'], $fieldMapping['type'])) {
|
||||
$methods[] = $code;
|
||||
}
|
||||
@ -1014,6 +1176,22 @@ public function __construct()
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($metadata->embeddedClasses as $fieldName => $embeddedClass) {
|
||||
if (isset($embeddedClass['declaredField'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! $metadata->isEmbeddedClass || ! $this->embeddablesImmutable) {
|
||||
if ($code = $this->generateEntityStubMethod($metadata, 'set', $fieldName, $embeddedClass['class'])) {
|
||||
$methods[] = $code;
|
||||
}
|
||||
}
|
||||
|
||||
if ($code = $this->generateEntityStubMethod($metadata, 'get', $fieldName, $embeddedClass['class'])) {
|
||||
$methods[] = $code;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($metadata->associationMappings as $associationMapping) {
|
||||
if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) {
|
||||
$nullable = $this->isAssociationIsNullable($associationMapping) ? 'null' : null;
|
||||
@ -1123,7 +1301,12 @@ public function __construct()
|
||||
|
||||
foreach ($metadata->fieldMappings as $fieldMapping) {
|
||||
if ($this->hasProperty($fieldMapping['fieldName'], $metadata) ||
|
||||
$metadata->isInheritedField($fieldMapping['fieldName'])) {
|
||||
$metadata->isInheritedField($fieldMapping['fieldName']) ||
|
||||
(
|
||||
isset($fieldMapping['declaredField']) &&
|
||||
isset($metadata->embeddedClasses[$fieldMapping['declaredField']])
|
||||
)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1135,6 +1318,27 @@ public function __construct()
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMetadataInfo $metadata
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateEntityEmbeddedProperties(ClassMetadataInfo $metadata)
|
||||
{
|
||||
$lines = array();
|
||||
|
||||
foreach ($metadata->embeddedClasses as $fieldName => $embeddedClass) {
|
||||
if (isset($embeddedClass['declaredField']) || $this->hasProperty($fieldName, $metadata)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$lines[] = $this->generateEmbeddedPropertyDocBlock($embeddedClass);
|
||||
$lines[] = $this->spaces . $this->fieldVisibility . ' $' . $fieldName . ";\n";
|
||||
}
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMetadataInfo $metadata
|
||||
* @param string $type
|
||||
@ -1496,6 +1700,35 @@ public function __construct()
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $embeddedClass
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateEmbeddedPropertyDocBlock(array $embeddedClass)
|
||||
{
|
||||
$lines = array();
|
||||
$lines[] = $this->spaces . '/**';
|
||||
$lines[] = $this->spaces . ' * @var \\' . ltrim($embeddedClass['class'], '\\');
|
||||
|
||||
if ($this->generateAnnotations) {
|
||||
$lines[] = $this->spaces . ' *';
|
||||
|
||||
$embedded = array('class="' . $embeddedClass['class'] . '"');
|
||||
|
||||
if (isset($fieldMapping['columnPrefix'])) {
|
||||
$embedded[] = 'columnPrefix=' . var_export($embeddedClass['columnPrefix'], true);
|
||||
}
|
||||
|
||||
$lines[] = $this->spaces . ' * @' .
|
||||
$this->annotationsPrefix . 'Embedded(' . implode(', ', $embedded) . ')';
|
||||
}
|
||||
|
||||
$lines[] = $this->spaces . ' */';
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
* @param int $num
|
||||
|
@ -49,7 +49,12 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
rmdir($this->_tmpDir . '/' . $this->_namespace);
|
||||
}
|
||||
|
||||
public function generateBookEntityFixture()
|
||||
/**
|
||||
* @param ClassMetadataInfo[] $embeddedClasses
|
||||
*
|
||||
* @return ClassMetadataInfo
|
||||
*/
|
||||
public function generateBookEntityFixture(array $embeddedClasses = array())
|
||||
{
|
||||
$metadata = new ClassMetadataInfo($this->_namespace . '\EntityGeneratorBook');
|
||||
$metadata->namespace = $this->_namespace;
|
||||
@ -79,6 +84,11 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
$metadata->addLifecycleCallback('willBeRemoved', 'preRemove');
|
||||
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
|
||||
|
||||
foreach ($embeddedClasses as $fieldName => $embeddedClass) {
|
||||
$this->mapNestedEmbedded($fieldName, $metadata, $embeddedClass);
|
||||
$this->mapEmbedded($fieldName, $metadata, $embeddedClass);
|
||||
}
|
||||
|
||||
$this->_generator->writeEntityClass($metadata, $this->_tmpDir);
|
||||
|
||||
return $metadata;
|
||||
@ -102,22 +112,117 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ClassMetadataInfo
|
||||
*/
|
||||
private function generateIsbnEmbeddableFixture(array $embeddedClasses = array())
|
||||
{
|
||||
$metadata = new ClassMetadataInfo($this->_namespace . '\EntityGeneratorIsbn');
|
||||
$metadata->namespace = $this->_namespace;
|
||||
$metadata->isEmbeddedClass = true;
|
||||
$metadata->mapField(array('fieldName' => 'prefix', 'type' => 'integer'));
|
||||
$metadata->mapField(array('fieldName' => 'groupNumber', 'type' => 'integer'));
|
||||
$metadata->mapField(array('fieldName' => 'publisherNumber', 'type' => 'integer'));
|
||||
$metadata->mapField(array('fieldName' => 'titleNumber', 'type' => 'integer'));
|
||||
$metadata->mapField(array('fieldName' => 'checkDigit', 'type' => 'integer'));
|
||||
|
||||
foreach ($embeddedClasses as $fieldName => $embeddedClass) {
|
||||
$this->mapEmbedded($fieldName, $metadata, $embeddedClass);
|
||||
}
|
||||
|
||||
$this->_generator->writeEntityClass($metadata, $this->_tmpDir);
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ClassMetadataInfo
|
||||
*/
|
||||
private function generateTestEmbeddableFixture()
|
||||
{
|
||||
$metadata = new ClassMetadataInfo($this->_namespace . '\EntityGeneratorTestEmbeddable');
|
||||
$metadata->namespace = $this->_namespace;
|
||||
$metadata->isEmbeddedClass = true;
|
||||
$metadata->mapField(array('fieldName' => 'field1', 'type' => 'integer'));
|
||||
$metadata->mapField(array('fieldName' => 'field2', 'type' => 'integer', 'nullable' => true));
|
||||
$metadata->mapField(array('fieldName' => 'field3', 'type' => 'datetime'));
|
||||
$metadata->mapField(array('fieldName' => 'field4', 'type' => 'datetime', 'nullable' => true));
|
||||
|
||||
$this->_generator->writeEntityClass($metadata, $this->_tmpDir);
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fieldName
|
||||
* @param ClassMetadataInfo $classMetadata
|
||||
* @param ClassMetadataInfo $embeddableMetadata
|
||||
* @param string|null $columnPrefix
|
||||
*/
|
||||
private function mapEmbedded(
|
||||
$fieldName,
|
||||
ClassMetadataInfo $classMetadata,
|
||||
ClassMetadataInfo $embeddableMetadata,
|
||||
$columnPrefix = false
|
||||
) {
|
||||
$classMetadata->mapEmbedded(
|
||||
array('fieldName' => $fieldName, 'class' => $embeddableMetadata->name, 'columnPrefix' => $columnPrefix)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fieldName
|
||||
* @param ClassMetadataInfo $classMetadata
|
||||
* @param ClassMetadataInfo $embeddableMetadata
|
||||
*/
|
||||
private function mapNestedEmbedded(
|
||||
$fieldName,
|
||||
ClassMetadataInfo $classMetadata,
|
||||
ClassMetadataInfo $embeddableMetadata
|
||||
) {
|
||||
foreach ($embeddableMetadata->embeddedClasses as $property => $embeddableClass) {
|
||||
$classMetadata->mapEmbedded(array(
|
||||
'fieldName' => $fieldName . '.' . $property,
|
||||
'class' => $embeddableClass['class'],
|
||||
'columnPrefix' => $embeddableClass['columnPrefix'],
|
||||
'declaredField' => $embeddableClass['declaredField']
|
||||
? $fieldName . '.' . $embeddableClass['declaredField']
|
||||
: $fieldName,
|
||||
'originalField' => $embeddableClass['originalField'] ?: $property,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMetadataInfo $metadata
|
||||
*/
|
||||
private function loadEntityClass(ClassMetadataInfo $metadata)
|
||||
{
|
||||
$className = basename(str_replace('\\', '/', $metadata->name));
|
||||
$path = $this->_tmpDir . '/' . $this->_namespace . '/' . $className . '.php';
|
||||
|
||||
$this->assertFileExists($path);
|
||||
|
||||
require_once $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMetadataInfo $metadata
|
||||
* @return EntityGeneratorBook
|
||||
*
|
||||
* @return mixed An instance of the given metadata's class.
|
||||
*/
|
||||
public function newInstance($metadata)
|
||||
{
|
||||
$path = $this->_tmpDir . '/'. $this->_namespace . '/EntityGeneratorBook.php';
|
||||
$this->assertFileExists($path);
|
||||
require_once $path;
|
||||
$this->loadEntityClass($metadata);
|
||||
|
||||
return new $metadata->name;
|
||||
}
|
||||
|
||||
public function testGeneratedEntityClass()
|
||||
{
|
||||
$metadata = $this->generateBookEntityFixture();
|
||||
$testMetadata = $this->generateTestEmbeddableFixture();
|
||||
$isbnMetadata = $this->generateIsbnEmbeddableFixture(array('test' => $testMetadata));
|
||||
$metadata = $this->generateBookEntityFixture(array('isbn' => $isbnMetadata));
|
||||
|
||||
$book = $this->newInstance($metadata);
|
||||
$this->assertTrue(class_exists($metadata->name), "Class does not exist.");
|
||||
@ -125,11 +230,20 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getId'), "EntityGeneratorBook::getId() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'setName'), "EntityGeneratorBook::setName() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getName'), "EntityGeneratorBook::getName() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'setStatus'), "EntityGeneratorBook::setStatus() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getStatus'), "EntityGeneratorBook::getStatus() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'setAuthor'), "EntityGeneratorBook::setAuthor() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getAuthor'), "EntityGeneratorBook::getAuthor() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getComments'), "EntityGeneratorBook::getComments() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'addComment'), "EntityGeneratorBook::addComment() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'removeComment'), "EntityGeneratorBook::removeComment() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'setIsbn'), "EntityGeneratorBook::setIsbn() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getIsbn'), "EntityGeneratorBook::getIsbn() missing.");
|
||||
|
||||
$reflClass = new \ReflectionClass($metadata->name);
|
||||
|
||||
$this->assertCount(6, $reflClass->getProperties());
|
||||
$this->assertCount(15, $reflClass->getMethods());
|
||||
|
||||
$this->assertEquals('published', $book->getStatus());
|
||||
|
||||
@ -154,13 +268,27 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
$this->assertEquals(new \Doctrine\Common\Collections\ArrayCollection(array($comment)), $book->getComments());
|
||||
$book->removeComment($comment);
|
||||
$this->assertEquals(new \Doctrine\Common\Collections\ArrayCollection(array()), $book->getComments());
|
||||
|
||||
$this->newInstance($isbnMetadata);
|
||||
$isbn = new $isbnMetadata->name();
|
||||
|
||||
$book->setIsbn($isbn);
|
||||
$this->assertSame($isbn, $book->getIsbn());
|
||||
|
||||
$reflMethod = new \ReflectionMethod($metadata->name, 'setIsbn');
|
||||
$reflParameters = $reflMethod->getParameters();
|
||||
$this->assertEquals($isbnMetadata->name, $reflParameters[0]->getClass()->name);
|
||||
}
|
||||
|
||||
public function testEntityUpdatingWorks()
|
||||
{
|
||||
$metadata = $this->generateBookEntityFixture();
|
||||
$metadata = $this->generateBookEntityFixture(array('isbn' => $this->generateIsbnEmbeddableFixture()));
|
||||
|
||||
$metadata->mapField(array('fieldName' => 'test', 'type' => 'string'));
|
||||
|
||||
$testEmbeddableMetadata = $this->generateTestEmbeddableFixture();
|
||||
$this->mapEmbedded('testEmbedded', $metadata, $testEmbeddableMetadata);
|
||||
|
||||
$this->_generator->writeEntityClass($metadata, $this->_tmpDir);
|
||||
|
||||
$this->assertFileExists($this->_tmpDir . "/" . $this->_namespace . "/EntityGeneratorBook.php~");
|
||||
@ -171,13 +299,26 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
$this->assertTrue($reflClass->hasProperty('name'), "Regenerating keeps property 'name'.");
|
||||
$this->assertTrue($reflClass->hasProperty('status'), "Regenerating keeps property 'status'.");
|
||||
$this->assertTrue($reflClass->hasProperty('id'), "Regenerating keeps property 'id'.");
|
||||
$this->assertTrue($reflClass->hasProperty('isbn'), "Regenerating keeps property 'isbn'.");
|
||||
|
||||
$this->assertTrue($reflClass->hasProperty('test'), "Check for property test failed.");
|
||||
$this->assertTrue($reflClass->getProperty('test')->isProtected(), "Check for protected property test failed.");
|
||||
$this->assertTrue($reflClass->hasProperty('testEmbedded'), "Check for property testEmbedded failed.");
|
||||
$this->assertTrue($reflClass->getProperty('testEmbedded')->isProtected(), "Check for protected property testEmbedded failed.");
|
||||
$this->assertTrue($reflClass->hasMethod('getTest'), "Check for method 'getTest' failed.");
|
||||
$this->assertTrue($reflClass->getMethod('getTest')->isPublic(), "Check for public visibility of method 'getTest' failed.");
|
||||
$this->assertTrue($reflClass->hasMethod('setTest'), "Check for method 'getTest' failed.");
|
||||
$this->assertTrue($reflClass->getMethod('getTest')->isPublic(), "Check for public visibility of method 'getTest' failed.");
|
||||
$this->assertTrue($reflClass->hasMethod('setTest'), "Check for method 'setTest' failed.");
|
||||
$this->assertTrue($reflClass->getMethod('setTest')->isPublic(), "Check for public visibility of method 'setTest' failed.");
|
||||
$this->assertTrue($reflClass->hasMethod('getTestEmbedded'), "Check for method 'getTestEmbedded' failed.");
|
||||
$this->assertTrue(
|
||||
$reflClass->getMethod('getTestEmbedded')->isPublic(),
|
||||
"Check for public visibility of method 'getTestEmbedded' failed."
|
||||
);
|
||||
$this->assertTrue($reflClass->hasMethod('setTestEmbedded'), "Check for method 'setTestEmbedded' failed.");
|
||||
$this->assertTrue(
|
||||
$reflClass->getMethod('setTestEmbedded')->isPublic(),
|
||||
"Check for public visibility of method 'setTestEmbedded' failed."
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -185,10 +326,12 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
*/
|
||||
public function testDoesNotRegenerateExistingMethodsWithDifferentCase()
|
||||
{
|
||||
$metadata = $this->generateBookEntityFixture();
|
||||
$metadata = $this->generateBookEntityFixture(array('isbn' => $this->generateIsbnEmbeddableFixture()));
|
||||
|
||||
// Workaround to change existing fields case (just to simulate the use case)
|
||||
$metadata->fieldMappings['status']['fieldName'] = 'STATUS';
|
||||
$metadata->embeddedClasses['ISBN'] = $metadata->embeddedClasses['isbn'];
|
||||
unset($metadata->embeddedClasses['isbn']);
|
||||
|
||||
// Should not throw a PHP fatal error
|
||||
$this->_generator->writeEntityClass($metadata, $this->_tmpDir);
|
||||
@ -200,8 +343,12 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
|
||||
$this->assertTrue($reflClass->hasProperty('status'));
|
||||
$this->assertTrue($reflClass->hasProperty('STATUS'));
|
||||
$this->assertTrue($reflClass->hasProperty('isbn'));
|
||||
$this->assertTrue($reflClass->hasProperty('ISBN'));
|
||||
$this->assertTrue($reflClass->hasMethod('getStatus'));
|
||||
$this->assertTrue($reflClass->hasMethod('setStatus'));
|
||||
$this->assertTrue($reflClass->hasMethod('getIsbn'));
|
||||
$this->assertTrue($reflClass->hasMethod('setIsbn'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -209,8 +356,9 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
*/
|
||||
public function testMethodDocBlockShouldStartWithBackSlash()
|
||||
{
|
||||
$metadata = $this->generateBookEntityFixture();
|
||||
$book = $this->newInstance($metadata);
|
||||
$embeddedMetadata = $this->generateIsbnEmbeddableFixture();
|
||||
$metadata = $this->generateBookEntityFixture(array('isbn' => $embeddedMetadata));
|
||||
$book = $this->newInstance($metadata);
|
||||
|
||||
$this->assertPhpDocVarType('\Doctrine\Common\Collections\Collection', new \ReflectionProperty($book, 'comments'));
|
||||
$this->assertPhpDocReturnType('\Doctrine\Common\Collections\Collection', new \ReflectionMethod($book, 'getComments'));
|
||||
@ -220,6 +368,11 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
$this->assertPhpDocVarType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor', new \ReflectionProperty($book, 'author'));
|
||||
$this->assertPhpDocReturnType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor', new \ReflectionMethod($book, 'getAuthor'));
|
||||
$this->assertPhpDocParamType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor', new \ReflectionMethod($book, 'setAuthor'));
|
||||
|
||||
$expectedClassName = '\\' . $embeddedMetadata->name;
|
||||
$this->assertPhpDocVarType($expectedClassName, new \ReflectionProperty($book, 'isbn'));
|
||||
$this->assertPhpDocReturnType($expectedClassName, new \ReflectionMethod($book, 'getIsbn'));
|
||||
$this->assertPhpDocParamType($expectedClassName, new \ReflectionMethod($book, 'setIsbn'));
|
||||
}
|
||||
|
||||
public function testEntityExtendsStdClass()
|
||||
@ -229,6 +382,10 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
|
||||
$book = $this->newInstance($metadata);
|
||||
$this->assertInstanceOf('stdClass', $book);
|
||||
|
||||
$metadata = $this->generateIsbnEmbeddableFixture();
|
||||
$isbn = $this->newInstance($metadata);
|
||||
$this->assertInstanceOf('stdClass', $isbn);
|
||||
}
|
||||
|
||||
public function testLifecycleCallbacks()
|
||||
@ -244,12 +401,15 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
|
||||
public function testLoadMetadata()
|
||||
{
|
||||
$metadata = $this->generateBookEntityFixture();
|
||||
$embeddedMetadata = $this->generateIsbnEmbeddableFixture();
|
||||
$metadata = $this->generateBookEntityFixture(array('isbn' => $embeddedMetadata));
|
||||
|
||||
$book = $this->newInstance($metadata);
|
||||
|
||||
$reflectionService = new RuntimeReflectionService();
|
||||
|
||||
$cm = new ClassMetadata($metadata->name);
|
||||
$cm->initializeReflection(new RuntimeReflectionService);
|
||||
$cm->initializeReflection($reflectionService);
|
||||
|
||||
$driver = $this->createAnnotationDriver();
|
||||
$driver->loadMetadataForClass($cm->name, $cm);
|
||||
@ -260,22 +420,38 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
$this->assertEquals($cm->identifier, $metadata->identifier);
|
||||
$this->assertEquals($cm->idGenerator, $metadata->idGenerator);
|
||||
$this->assertEquals($cm->customRepositoryClassName, $metadata->customRepositoryClassName);
|
||||
$this->assertEquals($cm->embeddedClasses, $metadata->embeddedClasses);
|
||||
$this->assertEquals($cm->isEmbeddedClass, $metadata->isEmbeddedClass);
|
||||
|
||||
$this->assertEquals(ClassMetadataInfo::FETCH_EXTRA_LAZY, $cm->associationMappings['comments']['fetch']);
|
||||
|
||||
$isbn = $this->newInstance($embeddedMetadata);
|
||||
|
||||
$cm = new ClassMetadata($embeddedMetadata->name);
|
||||
$cm->initializeReflection($reflectionService);
|
||||
|
||||
$driver->loadMetadataForClass($cm->name, $cm);
|
||||
|
||||
$this->assertEquals($cm->columnNames, $embeddedMetadata->columnNames);
|
||||
$this->assertEquals($cm->embeddedClasses, $embeddedMetadata->embeddedClasses);
|
||||
$this->assertEquals($cm->isEmbeddedClass, $embeddedMetadata->isEmbeddedClass);
|
||||
}
|
||||
|
||||
public function testLoadPrefixedMetadata()
|
||||
{
|
||||
$this->_generator->setAnnotationPrefix('ORM\\');
|
||||
$metadata = $this->generateBookEntityFixture();
|
||||
$embeddedMetadata = $this->generateIsbnEmbeddableFixture();
|
||||
$metadata = $this->generateBookEntityFixture(array('isbn' => $embeddedMetadata));
|
||||
|
||||
$reader = new AnnotationReader();
|
||||
$driver = new AnnotationDriver($reader, array());
|
||||
|
||||
$book = $this->newInstance($metadata);
|
||||
|
||||
$reflectionService = new RuntimeReflectionService();
|
||||
|
||||
$cm = new ClassMetadata($metadata->name);
|
||||
$cm->initializeReflection(new RuntimeReflectionService);
|
||||
$cm->initializeReflection($reflectionService);
|
||||
|
||||
$driver->loadMetadataForClass($cm->name, $cm);
|
||||
|
||||
@ -285,6 +461,17 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
$this->assertEquals($cm->identifier, $metadata->identifier);
|
||||
$this->assertEquals($cm->idGenerator, $metadata->idGenerator);
|
||||
$this->assertEquals($cm->customRepositoryClassName, $metadata->customRepositoryClassName);
|
||||
|
||||
$isbn = $this->newInstance($embeddedMetadata);
|
||||
|
||||
$cm = new ClassMetadata($embeddedMetadata->name);
|
||||
$cm->initializeReflection($reflectionService);
|
||||
|
||||
$driver->loadMetadataForClass($cm->name, $cm);
|
||||
|
||||
$this->assertEquals($cm->columnNames, $embeddedMetadata->columnNames);
|
||||
$this->assertEquals($cm->embeddedClasses, $embeddedMetadata->embeddedClasses);
|
||||
$this->assertEquals($cm->isEmbeddedClass, $embeddedMetadata->isEmbeddedClass);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -644,7 +831,120 @@ class EntityGeneratorTest extends OrmTestCase
|
||||
$this->assertFalse($rc3->hasMethod('getCreatedAt'));
|
||||
$this->assertFalse($rc3->hasMethod('setCreatedAt'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @group DDC-3304
|
||||
*/
|
||||
public function testGeneratedMutableEmbeddablesClass()
|
||||
{
|
||||
$embeddedMetadata = $this->generateTestEmbeddableFixture();
|
||||
$metadata = $this->generateIsbnEmbeddableFixture(array('test' => $embeddedMetadata));
|
||||
|
||||
$isbn = $this->newInstance($metadata);
|
||||
|
||||
$this->assertTrue(class_exists($metadata->name), "Class does not exist.");
|
||||
$this->assertFalse(method_exists($metadata->name, '__construct'), "EntityGeneratorIsbn::__construct present.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'getPrefix'), "EntityGeneratorIsbn::getPrefix() missing.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'setPrefix'), "EntityGeneratorIsbn::setPrefix() missing.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'getGroupNumber'), "EntityGeneratorIsbn::getGroupNumber() missing.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'setGroupNumber'), "EntityGeneratorIsbn::setGroupNumber() missing.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'getPublisherNumber'), "EntityGeneratorIsbn::getPublisherNumber() missing.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'setPublisherNumber'), "EntityGeneratorIsbn::setPublisherNumber() missing.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'getTitleNumber'), "EntityGeneratorIsbn::getTitleNumber() missing.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'setTitleNumber'), "EntityGeneratorIsbn::setTitleNumber() missing.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'getCheckDigit'), "EntityGeneratorIsbn::getCheckDigit() missing.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'setCheckDigit'), "EntityGeneratorIsbn::setCheckDigit() missing.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'getTest'), "EntityGeneratorIsbn::getTest() missing.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'setTest'), "EntityGeneratorIsbn::setTest() missing.");
|
||||
|
||||
$isbn->setPrefix(978);
|
||||
$this->assertSame(978, $isbn->getPrefix());
|
||||
|
||||
$this->newInstance($embeddedMetadata);
|
||||
$test = new $embeddedMetadata->name();
|
||||
|
||||
$isbn->setTest($test);
|
||||
$this->assertSame($test, $isbn->getTest());
|
||||
|
||||
$reflMethod = new \ReflectionMethod($metadata->name, 'setTest');
|
||||
$reflParameters = $reflMethod->getParameters();
|
||||
$this->assertEquals($embeddedMetadata->name, $reflParameters[0]->getClass()->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-3304
|
||||
*/
|
||||
public function testGeneratedImmutableEmbeddablesClass()
|
||||
{
|
||||
$this->_generator->setEmbeddablesImmutable(true);
|
||||
$embeddedMetadata = $this->generateTestEmbeddableFixture();
|
||||
$metadata = $this->generateIsbnEmbeddableFixture(array('test' => $embeddedMetadata));
|
||||
|
||||
$this->loadEntityClass($embeddedMetadata);
|
||||
$this->loadEntityClass($metadata);
|
||||
|
||||
$this->assertTrue(class_exists($metadata->name), "Class does not exist.");
|
||||
$this->assertTrue(method_exists($metadata->name, '__construct'), "EntityGeneratorIsbn::__construct missing.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'getPrefix'), "EntityGeneratorIsbn::getPrefix() missing.");
|
||||
$this->assertFalse(method_exists($metadata->name, 'setPrefix'), "EntityGeneratorIsbn::setPrefix() present.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'getGroupNumber'), "EntityGeneratorIsbn::getGroupNumber() missing.");
|
||||
$this->assertFalse(method_exists($metadata->name, 'setGroupNumber'), "EntityGeneratorIsbn::setGroupNumber() present.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'getPublisherNumber'), "EntityGeneratorIsbn::getPublisherNumber() missing.");
|
||||
$this->assertFalse(method_exists($metadata->name, 'setPublisherNumber'), "EntityGeneratorIsbn::setPublisherNumber() present.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'getTitleNumber'), "EntityGeneratorIsbn::getTitleNumber() missing.");
|
||||
$this->assertFalse(method_exists($metadata->name, 'setTitleNumber'), "EntityGeneratorIsbn::setTitleNumber() present.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'getCheckDigit'), "EntityGeneratorIsbn::getCheckDigit() missing.");
|
||||
$this->assertFalse(method_exists($metadata->name, 'setCheckDigit'), "EntityGeneratorIsbn::setCheckDigit() present.");
|
||||
$this->assertTrue(method_exists($metadata->name, 'getTest'), "EntityGeneratorIsbn::getTest() missing.");
|
||||
$this->assertFalse(method_exists($metadata->name, 'setTest'), "EntityGeneratorIsbn::setTest() present.");
|
||||
|
||||
$test = new $embeddedMetadata->name(1, new \DateTime());
|
||||
$isbn = new $metadata->name($test, 978, 3, 12, 732320, 83);
|
||||
|
||||
$reflMethod = new \ReflectionMethod($isbn, '__construct');
|
||||
$reflParameters = $reflMethod->getParameters();
|
||||
|
||||
$this->assertCount(6, $reflParameters);
|
||||
|
||||
$this->assertSame($embeddedMetadata->name, $reflParameters[0]->getClass()->name);
|
||||
$this->assertSame('test', $reflParameters[0]->getName());
|
||||
$this->assertFalse($reflParameters[0]->isOptional());
|
||||
|
||||
$this->assertSame('prefix', $reflParameters[1]->getName());
|
||||
$this->assertFalse($reflParameters[1]->isOptional());
|
||||
|
||||
$this->assertSame('groupNumber', $reflParameters[2]->getName());
|
||||
$this->assertFalse($reflParameters[2]->isOptional());
|
||||
|
||||
$this->assertSame('publisherNumber', $reflParameters[3]->getName());
|
||||
$this->assertFalse($reflParameters[3]->isOptional());
|
||||
|
||||
$this->assertSame('titleNumber', $reflParameters[4]->getName());
|
||||
$this->assertFalse($reflParameters[4]->isOptional());
|
||||
|
||||
$this->assertSame('checkDigit', $reflParameters[5]->getName());
|
||||
$this->assertFalse($reflParameters[5]->isOptional());
|
||||
|
||||
$reflMethod = new \ReflectionMethod($test, '__construct');
|
||||
$reflParameters = $reflMethod->getParameters();
|
||||
|
||||
$this->assertCount(4, $reflParameters);
|
||||
|
||||
$this->assertSame('field1', $reflParameters[0]->getName());
|
||||
$this->assertFalse($reflParameters[0]->isOptional());
|
||||
|
||||
$this->assertSame('DateTime', $reflParameters[1]->getClass()->name);
|
||||
$this->assertSame('field3', $reflParameters[1]->getName());
|
||||
$this->assertFalse($reflParameters[1]->isOptional());
|
||||
|
||||
$this->assertSame('field2', $reflParameters[2]->getName());
|
||||
$this->assertTrue($reflParameters[2]->isOptional());
|
||||
|
||||
$this->assertSame('DateTime', $reflParameters[3]->getClass()->name);
|
||||
$this->assertSame('field4', $reflParameters[3]->getName());
|
||||
$this->assertTrue($reflParameters[3]->isOptional());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user