All Data Structures Functions Variables Pages
RedBeanModelMulitpleSameModelRelationsTest.php
1 <?php
2  /*********************************************************************************
3  * Zurmo is a customer relationship management program developed by
4  * Zurmo, Inc. Copyright (C) 2017 Zurmo Inc.
5  *
6  * Zurmo is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  *
13  * Zurmo is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  *
23  * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive
24  * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.
25  *
26  * The interactive user interfaces in original and modified versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  *
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the Zurmo
32  * logo and Zurmo copyright notice. If the display of the logo is not reasonably
33  * feasible for technical reasons, the Appropriate Legal Notices must display the words
34  * "Copyright Zurmo Inc. 2017. All rights reserved".
35  ********************************************************************************/
36 
43  {
44  public static function getDependentTestModelClassNames()
45  {
46  return array('P', 'PP', 'PPP', 'PPPP');
47  }
48 
49  public function testMultipleHasOnesToTheSameModel()
50  {
51  $pp1 = new PP();
52  $pp1->name = 'pp1';
53  $pp1->save();
54  $this->assertTrue($pp1->save());
55  $pp2 = new PP();
56  $pp2->name = 'pp2';
57  $this->assertTrue($pp2->save());
58  $pp3 = new PP();
59  $pp3->name = 'pp3';
60  $this->assertTrue($pp3->save());
61 
62  $p = new P();
63  $p->name = 'name';
64  $p->pp = $pp1;
65  $p->pp1 = $pp2;
66  $p->pp2 = $pp3;
67  $this->assertTrue($p->save());
68 
69  //Retrieve row to make sure columns are coppect
70  $row = ZurmoRedBean::getRow('select * from p');
71  $this->assertTrue(isset($row['id']) && $row['id'] = $p->id);
72  $this->assertTrue(isset($row['pp_id']) && $row['pp_id'] = $pp1->id);
73  $this->assertTrue(isset($row['pp1link_pp_id']) && $row['pp1link_pp_id'] = $pp2->id);
74  $this->assertTrue(isset($row['pp2link_pp_id']) && $row['pp2link_pp_id'] = $pp3->id);
75  $this->assertCount(5, $row);
76 
77  $row = ZurmoRedBean::getRow('select * from pp');
78  $this->assertTrue(isset($row['id']) && $row['id'] = $pp1->id);
79  $this->assertTrue(isset($row['name']) && $row['name'] = 'pp1');
80  $this->assertCount(2, $row);
81  }
82 
83  public function testMultipleHasManysToTheSameModel()
84  {
85  $ppp1 = new PPP();
86  $ppp1->name = 'ppp1';
87  $ppp1->save();
88  $this->assertTrue($ppp1->save());
89  $ppp2 = new PPP();
90  $ppp2->name = 'ppp2';
91  $this->assertTrue($ppp2->save());
92  $ppp3 = new PPP();
93  $ppp3->name = 'ppp3';
94  $this->assertTrue($ppp3->save());
95 
96  $p = new P();
97  $p->name = 'name2';
98  $p->ppp->add ($ppp1);
99  $p->ppp1->add($ppp2);
100  $p->ppp2->add($ppp3);
101  $this->assertTrue($p->save());
102 
103  //Retrieve row to make sure columns are correct
104  $row = ZurmoRedBean::getRow('select * from p where id =' . $p->id);
105  $this->assertTrue(isset($row['id']) && $row['id'] = $p->id);
106  $this->assertEquals(null, $row['pp_id']);
107  $this->assertEquals(null, $row['pp1link_pp_id']);
108  $this->assertEquals(null, $row['pp2link_pp_id']);
109  $this->assertCount(5, $row);
110 
111  $row = ZurmoRedBean::getRow('select * from ppp where id =' . $ppp1->id);
112  $this->assertTrue(isset($row['id']) && $row['id'] = $ppp1->id);
113  $this->assertTrue(isset($row['name']) && $row['name'] = 'ppp1');
114  $this->assertTrue(isset($row['p_id']) && $row['p_id'] = $p->id);
115  $this->assertEquals(null, $row['ppp1link_p_id']);
116  $this->assertEquals(null, $row['ppp2link_p_id']);
117  $this->assertCount(5, $row);
118 
119  $row = ZurmoRedBean::getRow('select * from ppp where id =' . $ppp2->id);
120  $this->assertTrue(isset($row['id']) && $row['id'] = $ppp2->id);
121  $this->assertTrue(isset($row['name']) && $row['name'] = 'ppp2');
122  $this->assertEquals(null, $row['p_id']);
123  $this->assertTrue(isset($row['ppp1link_p_id']) && $row['ppp1link_p_id'] = $p->id);
124  $this->assertEquals(null, $row['ppp2link_p_id']);
125  $this->assertCount(5, $row);
126 
127  $row = ZurmoRedBean::getRow('select * from ppp where id =' . $ppp3->id);
128  $this->assertTrue(isset($row['id']) && $row['id'] = $ppp3->id);
129  $this->assertTrue(isset($row['name']) && $row['name'] = 'ppp3');
130  $this->assertEquals(null, $row['p_id']);
131  $this->assertEquals(null, $row['ppp1link_p_id']);
132  $this->assertTrue(isset($row['ppp2link_p_id']) && $row['ppp2link_p_id'] = $p->id);
133  $this->assertCount(5, $row);
134 
135  $pId = $p->id;
136  $ppp1Id = $ppp1->id;
137  $ppp2Id = $ppp2->id;
138  $ppp3Id = $ppp3->id;
139  $p->forget();
140  $ppp1->forget();
141  $ppp2->forget();
142  $ppp3->forget();
143 
144  $p = P::getById($pId);
145  $this->assertEquals(1, $p->ppp->count());
146  $this->assertEquals(1, $p->ppp1->count());
147  $this->assertEquals(1, $p->ppp2->count());
148  $this->assertEquals($ppp1Id, $p->ppp[0]->id);
149  $this->assertEquals($ppp2Id, $p->ppp1[0]->id);
150  $this->assertEquals($ppp3Id, $p->ppp2[0]->id);
151 
152  //Unlink relationships to make sure they are removed properly
153  $p->ppp->remove(PPP::getById($ppp1Id));
154  $p->ppp1->remove(PPP::getById($ppp2Id));
155  $p->ppp2->remove(PPP::getById($ppp3Id));
156  $saved = $p->save();
157  $this->assertTrue($saved);
158 
159  //test rows are empty..
160  $row = ZurmoRedBean::getRow('select * from ppp where id =' . $ppp1->id);
161  $this->assertTrue(isset($row['id']) && $row['id'] = $ppp1->id);
162  $this->assertTrue(isset($row['name']) && $row['name'] = 'ppp1');
163  $this->assertEquals(null, $row['p_id']);
164  $this->assertEquals(null, $row['ppp1link_p_id']);
165  $this->assertEquals(null, $row['ppp2link_p_id']);
166 
167  $row = ZurmoRedBean::getRow('select * from ppp where id =' . $ppp2->id);
168  $this->assertTrue(isset($row['id']) && $row['id'] = $ppp2->id);
169  $this->assertTrue(isset($row['name']) && $row['name'] = 'ppp2');
170  $this->assertEquals(null, $row['p_id']);
171  $this->assertEquals(null, $row['ppp1link_p_id']);
172  $this->assertEquals(null, $row['ppp2link_p_id']);
173 
174  $row = ZurmoRedBean::getRow('select * from ppp where id =' . $ppp3->id);
175  $this->assertTrue(isset($row['id']) && $row['id'] = $ppp3->id);
176  $this->assertTrue(isset($row['name']) && $row['name'] = 'ppp3');
177  $this->assertEquals(null, $row['p_id']);
178  $this->assertEquals(null, $row['ppp1link_p_id']);
179  $this->assertEquals(null, $row['ppp2link_p_id']);
180  }
181 
182  public function testAssumptiveLinkWithARelationNameThatIsNotTheModelClassName()
183  {
184  $pp1 = new PP();
185  $pp1->name = 'pp1';
186  $pp1->save();
187  $this->assertTrue($pp1->save());
188  $pp2 = new PP();
189  $pp2->name = 'pp2';
190  $this->assertTrue($pp2->save());
191 
192  $pppp = new PPPP();
193  $pppp->name = 'name1';
194  $pppp->pp = $pp1;
195  $pppp->pp1 = $pp2;
196  $this->assertTrue($pppp->save());
197 
198  //Retrieve row to make sure columns are correct
199  $row = ZurmoRedBean::getRow('select * from pppp where id =' . $pppp->id);
200  $this->assertTrue(isset($row['id']) && $row['id'] = $pppp->id);
201  $this->assertEquals($pp1->id, $row['pp_id']);
202  $this->assertEquals($pp2->id, $row['pp1link_pp_id']);
203  $this->assertCount(4, $row);
204  }
205 
212  {
214  $searchAttributeData = array();
215  $searchAttributeData['clauses'] = array(
216  1 => array(
217  'attributeName' => 'pp',
218  'relatedModelData' => array(
219  'attributeName' => 'name',
220  'operatorType' => 'equals',
221  'value' => 'somevalue',
222  ),
223  ),
224  2 => array(
225  'attributeName' => 'pp1',
226  'relatedModelData' => array(
227  'attributeName' => 'name',
228  'operatorType' => 'equals',
229  'value' => 'somevalue2',
230  ),
231  ),
232  );
233  $searchAttributeData['structure'] = '1 and 2';
234  //Build the query 'where' and 'joins'. Confirm they are as expected
235  $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('PPPP');
236  $where = ModelDataProviderUtil::makeWhere('PPPP', $searchAttributeData, $joinTablesAdapter);
237  $compareWhere = "({$quote}pp{$quote}.{$quote}name{$quote} = 'somevalue') and ";
238  $compareWhere .= "({$quote}pp1{$quote}.{$quote}name{$quote} = 'somevalue2')";
239  $this->assertEquals($compareWhere, $where);
240  $this->assertEquals(0, $joinTablesAdapter->getFromTableJoinCount());
241  $this->assertEquals(2, $joinTablesAdapter->getLeftTableJoinCount());
242  $leftTables = $joinTablesAdapter->getLeftTablesAndAliases();
243  $this->assertEquals('pp', $leftTables[0]['tableName']);
244  $this->assertEquals('pp', $leftTables[1]['tableName']);
245 
246  //Only stringing hasOne relations together so it makes sense not to need distinct
247  $this->assertFalse($joinTablesAdapter->getSelectDistinct());
248 
249  //Now test that the subsetSQL query produced is correct.
250  $subsetSql = AAA::makeSubsetOrCountSqlQuery('pppp', $joinTablesAdapter, 1, 5, $where,
251  null, false, $joinTablesAdapter->getSelectDistinct());
252  $compareSubsetSql = "select {$quote}pppp{$quote}.{$quote}id{$quote} id ";
253  $compareSubsetSql .= "from {$quote}pppp{$quote} ";
254  $compareSubsetSql .= "left join {$quote}pp{$quote} on ";
255  $compareSubsetSql .= "{$quote}pp{$quote}.{$quote}id{$quote} = {$quote}pppp{$quote}.{$quote}pp_id{$quote} ";
256  $compareSubsetSql .= "left join {$quote}pp{$quote} pp1 on ";
257  $compareSubsetSql .= "{$quote}pp1{$quote}.{$quote}id{$quote} = {$quote}pppp{$quote}.{$quote}pp1link_pp_id{$quote} ";
258  $compareSubsetSql .= "where " . $compareWhere . ' ';
259  $compareSubsetSql .= 'limit 5 offset 1';
260  $this->assertEquals($compareSubsetSql, $subsetSql);
261  //Make sure the sql runs properly.
262  $data = PPPP::getSubset($joinTablesAdapter, 0, 5, $where, null, null, $joinTablesAdapter->getSelectDistinct());
263  }
264 
265  public function testMultipleManyManysToTheSameModel()
266  {
267  $pp1 = new PP();
268  $pp1->name = 'pp1a';
269  $pp1->save();
270  $this->assertTrue($pp1->save());
271  $pp1Id = $pp1->id;
272  $pp2 = new PP();
273  $pp2->name = 'pp2a';
274  $this->assertTrue($pp2->save());
275  $pp2Id = $pp2->id;
276 
277  $p = new P();
278  $p->name = 'manyNames';
279  $p->ppManyAssumptive->add($pp1);
280  $p->ppManySpecific->add($pp2);
281  $this->assertTrue($p->save());
282  $pId = $p->id;
283 
284  //Retrieve row to make sure columns are coppect
285  $row = ZurmoRedBean::getRow('select * from p');
286  $this->assertCount(5, $row);
287 
288  $this->assertEquals(1, ZurmoRedBean::count('p_pp'));
289  $row = ZurmoRedBean::getRow('select * from p_pp');
290  $this->assertTrue(isset($row['p_id']) && $row['p_id'] = $p->id);
291  $this->assertTrue(isset($row['pp_id']) && $row['pp_id'] = $pp1->id);
292  $this->assertCount(3, $row);
293 
294  $this->assertEquals(1, ZurmoRedBean::count('ppmanyspecificlink_p_pp'));
295  $row = ZurmoRedBean::getRow('select * from ppmanyspecificlink_p_pp');
296  $this->assertTrue(isset($row['p_id']) && $row['p_id'] = $p->id);
297  $this->assertTrue(isset($row['pp_id']) && $row['pp_id'] = $pp2->id);
298  $this->assertCount(3, $row);
299 
300  //Unlink and make sure the tables are cleared
301  $p->forget();
302  $pp1->forget();
303  $pp2->forget();
304 
305  $p = P::getById($pId);
306  $this->assertEquals(1, $p->ppManyAssumptive->count());
307  $this->assertEquals(1, $p->ppManySpecific->count());
308  $p->ppManyAssumptive->removeAll();
309  $p->ppManySpecific->removeAll();
310  $this->assertTrue($p->save());
311 
312  $this->assertEquals(0, ZurmoRedBean::count('p_pp'));
313  $this->assertEquals(0, ZurmoRedBean::count('ppmanyspecificlink_p_pp'));
314  }
315 
316  public function testMultipleManyManysToTheSameModelSearchQueryFormsCorrectly()
317  {
319  $searchAttributeData = array();
320  $searchAttributeData['clauses'] = array(
321  1 => array(
322  'attributeName' => 'ppManyAssumptive',
323  'relatedModelData' => array(
324  'attributeName' => 'name',
325  'operatorType' => 'equals',
326  'value' => 'somevalue',
327  ),
328  ),
329  2 => array(
330  'attributeName' => 'ppManySpecific',
331  'relatedModelData' => array(
332  'attributeName' => 'name',
333  'operatorType' => 'equals',
334  'value' => 'somevalue2',
335  ),
336  ),
337  );
338  $searchAttributeData['structure'] = '1 and 2';
339  //Build the query 'where' and 'joins'. Confirm they are as expected
340  $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('P');
341  $where = ModelDataProviderUtil::makeWhere('P', $searchAttributeData, $joinTablesAdapter);
342  $compareWhere = "({$quote}pp{$quote}.{$quote}name{$quote} = 'somevalue') and ";
343  $compareWhere .= "({$quote}pp1{$quote}.{$quote}name{$quote} = 'somevalue2')";
344  $this->assertEquals($compareWhere, $where);
345  $this->assertEquals(0, $joinTablesAdapter->getFromTableJoinCount());
346  $this->assertEquals(4, $joinTablesAdapter->getLeftTableJoinCount());
347  $leftTables = $joinTablesAdapter->getLeftTablesAndAliases();
348  $this->assertEquals('p_pp', $leftTables[0]['tableName']);
349  $this->assertEquals('pp', $leftTables[1]['tableName']);
350  $this->assertEquals('ppmanyspecificlink_p_pp', $leftTables[2]['tableName']);
351  $this->assertEquals('pp', $leftTables[3]['tableName']);
352 
353  //Distinct because MANY_MANY relationships
354  $this->assertTrue($joinTablesAdapter->getSelectDistinct());
355 
356  //Now test that the subsetSQL query produced is correct.
357  $subsetSql = AAA::makeSubsetOrCountSqlQuery('p', $joinTablesAdapter, 1, 5, $where,
358  null, false, $joinTablesAdapter->getSelectDistinct());
359  $compareSubsetSql = "select distinct {$quote}p{$quote}.{$quote}id{$quote} id ";
360  $compareSubsetSql .= "from {$quote}p{$quote} ";
361  $compareSubsetSql .= "left join {$quote}p_pp{$quote} on ";
362  $compareSubsetSql .= "{$quote}p_pp{$quote}.{$quote}p_id{$quote} = {$quote}p{$quote}.{$quote}id{$quote} ";
363  $compareSubsetSql .= "left join {$quote}pp{$quote} on ";
364  $compareSubsetSql .= "{$quote}pp{$quote}.{$quote}id{$quote} = {$quote}p_pp{$quote}.{$quote}pp_id{$quote} ";
365  $compareSubsetSql .= "left join {$quote}ppmanyspecificlink_p_pp{$quote} on ";
366  $compareSubsetSql .= "{$quote}ppmanyspecificlink_p_pp{$quote}.{$quote}p_id{$quote} = {$quote}p{$quote}.{$quote}id{$quote} ";
367  $compareSubsetSql .= "left join {$quote}pp{$quote} pp1 on ";
368  $compareSubsetSql .= "{$quote}pp1{$quote}.{$quote}id{$quote} = {$quote}ppmanyspecificlink_p_pp{$quote}.{$quote}pp_id{$quote} ";
369  $compareSubsetSql .= "where " . $compareWhere . ' ';
370  $compareSubsetSql .= 'limit 5 offset 1';
371  $this->assertEquals($compareSubsetSql, $subsetSql);
372  //Make sure the sql runs properly.
373  $data = P::getSubset($joinTablesAdapter, 0, 5, $where, null, null, $joinTablesAdapter->getSelectDistinct());
374  }
375 
376  public function testMultipleBelongsToTheSameModel()
377  {
378  //HAS_MANY_BELONGS_TO
379  //Todo: later - either remove it or add specific link support. Not sure it is needed anymore since we can
380  //define the link type.
381  }
382 
383  public function testAreRelationsValidWithOnlyOneAssumptiveLinkAgainstASingleModel()
384  {
385  //Todo later: Need to make some validity checker that works when debug is on during RedBean hit/cache setup
386  //that makes sure you don't have more than one assumptive link to the same model.
387  }
388 
389  public function testMoveThisSomewhereElse()
390  {
391  //Todo later:
392  //RedBeanModel::LINK_TYPE_POLYMORPHIC;
393  //Currently there is no way to query from the other side of a polymorphic relationship. Currently that
394  //use case is limited or non-existent. Add as needed.
395  }
396 
397  public function testHasOneBelongsToSupportsSpecificLinks()
398  {
399  //Todo later:
400  //We don't have any real usage of HAS_ONE_BELONGS_TO yet. So until we need to support specific links
401  //this is on hold.
402  }
403  }
404 ?>
Definition: PP.php:37
Definition: PPP.php:37
static getSubset(RedBeanModelJoinTablesQueryAdapter $joinTablesAdapter=null, $offset=null, $count=null, $where=null, $orderBy=null, $modelClassName=null, $selectDistinct=false)
static makeSubsetOrCountSqlQuery($tableName, RedBeanModelJoinTablesQueryAdapter $joinTablesAdapter, $offset=null, $count=null, $where=null, $orderBy=null, $selectCount=false, $selectDistinct=false, array $quotedExtraSelectColumnNameAndAliases=array())
static makeWhere($modelClassName, array $metadata, $joinTablesAdapter, $onTableAliasName=null)
Definition: P.php:37
static getById($id, $modelClassName=null)
Definition: PPPP.php:37
Generated on Fri Feb 21 2020 07:10:29