diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php index e48e8535b..3c0f9264f 100644 --- a/lib/Doctrine/ORM/Tools/EntityGenerator.php +++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php @@ -1168,17 +1168,18 @@ public function __construct() continue; } + $nullableField = $this->nullableFieldExpression($fieldMapping); + if (( ! isset($fieldMapping['id']) || ! $fieldMapping['id'] || $metadata->generatorType == ClassMetadataInfo::GENERATOR_TYPE_NONE ) && (! $metadata->isEmbeddedClass || ! $this->embeddablesImmutable) + && $code = $this->generateEntityStubMethod($metadata, 'set', $fieldMapping['fieldName'], $fieldMapping['type'], $nullableField) ) { - if ($code = $this->generateEntityStubMethod($metadata, 'set', $fieldMapping['fieldName'], $fieldMapping['type'])) { - $methods[] = $code; - } + $methods[] = $code; } - if ($code = $this->generateEntityStubMethod($metadata, 'get', $fieldMapping['fieldName'], $fieldMapping['type'])) { + if ($code = $this->generateEntityStubMethod($metadata, 'get', $fieldMapping['fieldName'], $fieldMapping['type'], $nullableField)) { $methods[] = $code; } } @@ -1205,7 +1206,7 @@ public function __construct() if ($code = $this->generateEntityStubMethod($metadata, 'set', $associationMapping['fieldName'], $associationMapping['targetEntity'], $nullable)) { $methods[] = $code; } - if ($code = $this->generateEntityStubMethod($metadata, 'get', $associationMapping['fieldName'], $associationMapping['targetEntity'])) { + if ($code = $this->generateEntityStubMethod($metadata, 'get', $associationMapping['fieldName'], $associationMapping['targetEntity'], $nullable)) { $methods[] = $code; } } elseif ($associationMapping['type'] & ClassMetadataInfo::TO_MANY) { @@ -1355,7 +1356,7 @@ public function __construct() * * @return string */ - protected function generateEntityStubMethod(ClassMetadataInfo $metadata, $type, $fieldName, $typeHint = null, $defaultValue = null) + protected function generateEntityStubMethod(ClassMetadataInfo $metadata, $type, $fieldName, $typeHint = null, $defaultValue = null) { $methodName = $type . Inflector::classify($fieldName); $variableName = Inflector::camelize($fieldName); @@ -1384,11 +1385,11 @@ public function __construct() $replacements = array( '' => ucfirst($type) . ' ' . $variableName . '.', '' => $methodTypeHint, - '' => $variableType, + '' => $variableType . (null !== $defaultValue ? ('|' . $defaultValue) : ''), '' => $variableName, '' => $methodName, '' => $fieldName, - '' => ($defaultValue !== null ) ? (' = '.$defaultValue) : '', + '' => ($defaultValue !== null ) ? (' = ' . $defaultValue) : '', '' => $this->getClassName($metadata) ); @@ -1627,7 +1628,9 @@ public function __construct() { $lines = array(); $lines[] = $this->spaces . '/**'; - $lines[] = $this->spaces . ' * @var ' . $this->getType($fieldMapping['type']); + $lines[] = $this->spaces . ' * @var ' + . $this->getType($fieldMapping['type']) + . ($this->nullableFieldExpression($fieldMapping) ? '|null' : ''); if ($this->generateAnnotations) { $lines[] = $this->spaces . ' *'; @@ -1809,6 +1812,20 @@ public function __construct() return static::$generatorStrategyMap[$type]; } + /** + * @param array $fieldMapping + * + * @return string|null + */ + private function nullableFieldExpression(array $fieldMapping) + { + if (isset($fieldMapping['nullable']) && true === $fieldMapping['nullable']) { + return 'null'; + } + + return null; + } + /** * Exports (nested) option elements. * diff --git a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php index 0cbae94d7..89c073fd2 100644 --- a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php @@ -368,8 +368,8 @@ class EntityGeneratorTest extends OrmTestCase $this->assertPhpDocReturnType('boolean', new \ReflectionMethod($book, 'removeComment')); $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')); + $this->assertPhpDocReturnType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor|null', new \ReflectionMethod($book, 'getAuthor')); + $this->assertPhpDocParamType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor|null', new \ReflectionMethod($book, 'setAuthor')); $expectedClassName = '\\' . $embeddedMetadata->name; $this->assertPhpDocVarType($expectedClassName, new \ReflectionProperty($book, 'isbn')); @@ -1080,17 +1080,25 @@ class */ private function assertPhpDocVarType($type, \ReflectionProperty $property) { - $this->assertEquals(1, preg_match('/@var\s+([^\s]+)/',$property->getDocComment(), $matches)); + $docComment = $property->getDocComment(); + $regex = '/@var\s+([\S]+)$/m'; + + $this->assertRegExp($regex, $docComment); + $this->assertEquals(1, preg_match($regex, $docComment, $matches)); $this->assertEquals($type, $matches[1]); } /** * @param string $type - * @param \ReflectionProperty $method + * @param \ReflectionMethod $method */ private function assertPhpDocReturnType($type, \ReflectionMethod $method) { - $this->assertEquals(1, preg_match('/@return\s+([^\s]+)/', $method->getDocComment(), $matches)); + $docComment = $method->getDocComment(); + $regex = '/@return\s+([\S]+)(\s+.*)$/m'; + + $this->assertRegExp($regex, $docComment); + $this->assertEquals(1, preg_match($regex, $docComment, $matches)); $this->assertEquals($type, $matches[1]); }