<?php

namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\ORM\UnitOfWork;

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

/**
 * @group DDC-1390
 */
class DDC1390Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
    protected function setUp()
    {
        parent::setUp();

        $classes = array(
            $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1390RelatedBase'),
            $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1390Related'),
            $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1390Entity'),
        );

        try {
            $this->_schemaTool->createSchema($classes);
        } catch(\Exception $ignored) {

        }
    }

    public function testIssue()
    {
        $related = new DDC1390Related;
        $entity = new DDC1390Entity;
        $entity->related = $related;
        $related->entity = $entity;

        $this->_em->persist($entity);
        $this->_em->flush();
        $this->_em->clear();

        //$entity = $this->_em->getReference(__NAMESPACE__ . "\DDC1390Entity", $entity->dbId); //proxy or not makes no difference

        $dql = "SELECT a FROM " . __NAMESPACE__ . "\DDC1390Entity a WHERE a.dbId = ?1";
        $entity = $this->_em->createQuery($dql)->setParameter(1, $entity->dbId)->getSingleResult();

        $this->assertNotNull($entity->related);
        $this->assertEquals($related->dbId, $entity->related->dbId);
    }
}

/**
 * @Entity
 * @InheritanceType("JOINED")
 * @DiscriminatorMap({"a" = "DDC1390Related"})
 */
abstract class DDC1390RelatedBase extends DDC1390Object
{

}

/**
 * @Entity
 */
class DDC1390Related extends DDC1390RelatedBase
{
   /**
    * @OneToOne(targetEntity="DDC1390Entity", mappedBy="related")
    */
   protected $entity;
}

/**
 * @Entity
 */
class DDC1390Entity extends DDC1390Object
{
   /**
    * @OneToOne(targetEntity="DDC1390Related", inversedBy="entity", cascade={"persist", "remove", "detach"})
    * @JoinColumn(name="related_dbId", referencedColumnName="dbId")
    */
   protected $related;
}

/**
 * @MappedSuperclass
 */
abstract class DDC1390Object
{
    /**
     * @Id @GeneratedValue @Column(type="integer")
     * @var int
     */
    protected $dbId;

    public function & __get($name)
    {
        $referenceHolderVar = $this->$name;
        return $referenceHolderVar;
    }

    public function __set($name, $value)
    {
        $this->$name = $value;
    }

}