1<?php
2/**
3 * Doctrine_Ticket_749_TestCase
4 *
5 * @package     Doctrine
6 * @author      David Brewer <dbrewer@secondstory.com>
7 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
8 * @category    Object Relational Mapping
9 * @link        www.doctrine-project.org
10 * @since       1.0
11 * @version     $Revision$
12 *
13 * This test case demonstrates a problem with column aggregation inheritance
14 * in Doctrine 0.9. The high level summary is that it is possible to make
15 * it work in general -- if class B is a subclass of class A, you can select
16 * from class A and get back objects of class B.  However, those objects do
17 * not have the related objects of class B, and in fact an exception is
18 * thrown when you try to access those related objects.
19 *
20 * This test case should not probably be applied to trunk and possibly not
21 * to 0.10 branch.  I'm not sure it's even possible to fix in 0.9 but it is
22 * an issue that keeps arising for me so it seemed worth a test case.
23 */
24
25class Doctrine_Ticket_749_TestCase extends Doctrine_UnitTestCase
26{
27    public function prepareTables()
28    {
29        $this->tables = array('Parent749', 'Record749', 'RelatedRecord749');
30        parent::prepareTables();
31    }
32
33    public function prepareData()
34    {
35        $record = new Record749();
36        $record['title'] = 'Test Record 1';
37        $record['Related']['content'] = 'Test Content 1';
38        $record->save();
39
40        $record = new Record749();
41        $record['title'] = 'Test Record 2';
42        $record['Related']['content'] = 'Test Content 2';
43        $record->save();
44    }
45
46    public function testSelectDataFromSubclassAsCollection()
47    {
48        $records = Doctrine_Query::create()->query('FROM Record749 r ORDER BY r.title', array());
49
50        $this->verifyRecords($records);
51    }
52
53    public function testSelectDataFromParentClassAsCollection()
54    {
55
56        $records = Doctrine_Query::create()->query('FROM Parent749 p ORDER BY p.title', array());
57        $this->verifyRecords($records);
58    }
59
60    /**
61     * This method is used by both tests, as the collection of records should
62     * be identical for both of them if things are working properly.
63     */
64    private function verifyRecords ($records) {
65        $expected_values = array(
66            array('title'=>'Test Record 1', 'content'=>'Test Content 1'),
67            array('title'=>'Test Record 2', 'content'=>'Test Content 2'),
68        );
69
70        foreach ($records as $record) {
71            $this->assertTrue($record instanceof Record749);
72            $expected = array_shift($expected_values);
73            $this->assertEqual($record['title'], $expected['title']);
74            try {
75                $this->assertEqual($record['Related']['content'], $expected['content']);
76            } catch (Exception $e) {
77                $this->fail('Caught exception when trying to get related content: ' . $e->getMessage());
78            }
79        }
80    }
81}
82
83class Parent749 extends Doctrine_Record
84{
85  public function setTableDefinition()
86  {
87    $this->setTableName('mytable');
88    $this->hasColumn('id', 'integer', 4, array (
89      'primary' => true,
90      'autoincrement' => true,
91      'notnull' => true,
92    ));
93
94    $this->hasColumn('title', 'string', 255, array ());
95    $this->hasColumn('type', 'integer', 11, array ());
96
97    $this->setSubclasses(array('Record749' => array('type' => 1)));
98  }
99
100  public function setUp()
101  {
102  }
103}
104
105class Record749 extends Parent749
106{
107  public function setTableDefinition()
108  {
109    parent::setTableDefinition();
110    $this->setTableName('mytable');
111  }
112
113  public function setUp()
114  {
115    parent::setUp();
116    $this->hasOne('RelatedRecord749 as Related', array('local' => 'id',
117                                                    'foreign' => 'record_id'));
118  }
119}
120
121class RelatedRecord749 extends Doctrine_Record
122{
123  public function setTableDefinition()
124  {
125    $this->hasColumn('id', 'integer', 4, array (
126      'primary' => true,
127      'autoincrement' => true,
128      'notnull' => true,
129    ));
130
131    $this->hasColumn('content', 'string', 255, array ());
132    $this->hasColumn('record_id', 'integer', null, array ('unique' => true,));
133  }
134
135  public function setUp()
136  {
137    $this->hasOne('Record749 as Record', array('local' => 'record_id',
138                                  'foreign' => 'id',
139                                  'onDelete' => 'cascade'));
140  }
141
142}
143
144