Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

entity generator - ignore trait properties and methods #632

Merged
merged 11 commits into from
Jul 7, 2013
34 changes: 34 additions & 0 deletions lib/Doctrine/ORM/Tools/EntityGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,13 @@ protected function hasProperty($property, ClassMetadataInfo $metadata)
}
}

// check traits for existing property
foreach ($this->getTraits($metadata) as $trait) {
if ($trait->hasProperty($property)) {
return true;
}
}

return (
isset($this->staticReflection[$metadata->name]) &&
in_array($property, $this->staticReflection[$metadata->name]['properties'])
Expand All @@ -732,12 +739,39 @@ protected function hasMethod($method, ClassMetadataInfo $metadata)
}
}

// check traits for existing method
foreach ($this->getTraits($metadata) as $trait) {
if ($trait->hasMethod($method)) {
return true;
}
}

return (
isset($this->staticReflection[$metadata->name]) &&
in_array($method, $this->staticReflection[$metadata->name]['methods'])
);
}

/**
* @param ClassMetadataInfo $metadata
*
* @return array
*/
protected function getTraits(ClassMetadataInfo $metadata)
{
if ($metadata->reflClass !== null || class_exists($metadata->name)) {
$reflClass = $metadata->reflClass === null
? new \ReflectionClass($metadata->name)
: $metadata->reflClass;

if (PHP_VERSION_ID >= 50400) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can move this check at the beginning of the method and return early

return $reflClass->getTraits();
}
}

return array();
}

/**
* @param ClassMetadataInfo $metadata
*
Expand Down
45 changes: 45 additions & 0 deletions tests/Doctrine/Tests/Models/DDC2372/DDC2372Address.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Doctrine\Tests\Models\DDC2372;

/** @Entity @Table(name="addresses") */
class DDC2372Address
{
/**
* @Id @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
private $id;
/** @Column(type="string", length=255) */
private $street;
/** @OneToOne(targetEntity="User", mappedBy="address") */
private $user;

public function getId()
{
return $this->id;
}

public function getStreet()
{
return $this->street;
}

public function setStreet($street)
{
$this->street = $street;
}

public function getUser()
{
return $this->user;
}

public function setUser(User $user)
{
if ($this->user !== $user) {
$this->user = $user;
$user->setAddress($this);
}
}
}
34 changes: 34 additions & 0 deletions tests/Doctrine/Tests/Models/DDC2372/DDC2372User.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Doctrine\Tests\Models\DDC2372;

use Doctrine\Tests\Models\DDC2372\Traits\DDC2372AddressTrait;

/** @Entity @Table(name="users") */
class DDC2372User
{
use DDC2372AddressTrait;

/**
* @Id @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
private $id;
/** @Column(type="string", length=50) */
private $name;

public function getId()
{
return $this->id;
}

public function getName()
{
return $this->name;
}

public function setName($name)
{
$this->name = $name;
}
}
25 changes: 25 additions & 0 deletions tests/Doctrine/Tests/Models/DDC2372/Traits/DDC2372AddressTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Doctrine\Tests\Models\DDC2372\Traits;

trait DDC2372AddressTrait
{
/**
* @OneToOne(targetEntity="Doctrine\Tests\Models\DDC2372\DDC2372Address", inversedBy="user")
* @JoinColumn(name="address_id", referencedColumnName="id")
*/
private $address;

public function getAddress()
{
return $this->address;
}

public function setAddress(Address $address)
{
if ($this->address !== $address) {
$this->address = $address;
$address->setUser($this);
}
}
}
58 changes: 44 additions & 14 deletions tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace Doctrine\Tests\ORM\Tools;

use Doctrine\ORM\Tools\SchemaTool,
Doctrine\ORM\Tools\EntityGenerator,
Doctrine\ORM\Tools\Export\ClassMetadataExporter,
Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\ORM\Tools\EntityGenerator;
use Doctrine\ORM\Tools\Export\ClassMetadataExporter;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\Mapping\ClassMetadataFactory;
use Doctrine\Tests\Models\DDC2372\DDC2372User;

require_once __DIR__ . '/../../TestInit.php';

Expand Down Expand Up @@ -282,7 +284,7 @@ public function testGenerateEntityWithSequenceGenerator()

$filename = $this->_tmpDir . DIRECTORY_SEPARATOR
. $this->_namespace . DIRECTORY_SEPARATOR . 'DDC1784Entity.php';

$this->assertFileExists($filename);
require_once $filename;

Expand Down Expand Up @@ -330,7 +332,7 @@ public function testGenerateEntityWithMultipleInverseJoinColumns()

$property = new \ReflectionProperty($metadata->name, 'centroCustos');
$docComment = $property->getDocComment();

//joinColumns
$this->assertContains('@JoinColumn(name="idorcamento", referencedColumnName="idorcamento"),', $docComment);
$this->assertContains('@JoinColumn(name="idunidade", referencedColumnName="idunidade")', $docComment);
Expand Down Expand Up @@ -436,7 +438,7 @@ public function testEntityTypeAlias(array $field)

$entity = new $metadata->name;
$reflClass = new \ReflectionClass($metadata->name);

$type = $field['phpType'];
$name = $field['fieldName'];
$value = $field['value'];
Expand All @@ -451,6 +453,34 @@ public function testEntityTypeAlias(array $field)
$this->assertEquals($value, $entity->{$getter}());
}

/**
* @group DDC-2372
*/
public function testTraitPropertiesAndMethodsAreNotDuplicated()
{
if (PHP_VERSION_ID >= 50400) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO better mark test skipped in other case

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed

$cmf = new ClassMetadataFactory();
$em = $this->_getTestEntityManager();
$cmf->setEntityManager($em);

$user = new DDC2372User();
$metadata = $cmf->getMetadataFor(get_class($user));
$metadata->name = $this->_namespace . "\DDC2372User";
$metadata->namespace = $this->_namespace;

$this->_generator->writeEntityClass($metadata, $this->_tmpDir);

$this->assertFileExists($this->_tmpDir . "/" . $this->_namespace . "/DDC2372User.php");
require $this->_tmpDir . "/" . $this->_namespace . "/DDC2372User.php";

$reflClass = new \ReflectionClass($metadata->name);

$this->assertSame($reflClass->hasProperty('address'), false);
$this->assertSame($reflClass->hasMethod('setAddress'), false);
$this->assertSame($reflClass->hasMethod('getAddress'), false);
}
}

/**
* @return array
*/
Expand All @@ -470,43 +500,43 @@ public function getEntityTypeAliasDataProvider()
'value' => new \DateTime
)),
array(array(
'fieldName' => 'date',
'fieldName' => 'date',
'phpType' => '\\DateTime',
'dbType' => 'date',
'value' => new \DateTime
)),
array(array(
'fieldName' => 'time',
'fieldName' => 'time',
'phpType' => '\DateTime',
'dbType' => 'time',
'value' => new \DateTime
)),
array(array(
'fieldName' => 'object',
'fieldName' => 'object',
'phpType' => '\stdClass',
'dbType' => 'object',
'value' => new \stdClass()
)),
array(array(
'fieldName' => 'bigint',
'fieldName' => 'bigint',
'phpType' => 'integer',
'dbType' => 'bigint',
'value' => 11
)),
array(array(
'fieldName' => 'smallint',
'fieldName' => 'smallint',
'phpType' => 'integer',
'dbType' => 'smallint',
'value' => 22
)),
array(array(
'fieldName' => 'text',
'fieldName' => 'text',
'phpType' => 'string',
'dbType' => 'text',
'value' => 'text'
)),
array(array(
'fieldName' => 'blob',
'fieldName' => 'blob',
'phpType' => 'string',
'dbType' => 'blob',
'value' => 'blob'
Expand Down