summaryrefslogtreecommitdiff
path: root/backend/php/src/setup/setup_library/setup_misc.php
Unidiff
Diffstat (limited to 'backend/php/src/setup/setup_library/setup_misc.php') (more/less context) (ignore whitespace changes)
-rw-r--r--backend/php/src/setup/setup_library/setup_misc.php2357
1 files changed, 2357 insertions, 0 deletions
diff --git a/backend/php/src/setup/setup_library/setup_misc.php b/backend/php/src/setup/setup_library/setup_misc.php
new file mode 100644
index 0000000..f0e4f0e
--- a/dev/null
+++ b/backend/php/src/setup/setup_library/setup_misc.php
@@ -0,0 +1,2357 @@
1<?php
2
3
4 /**
5 * Specifies what test data is used during unit testing (step 2 of the setup process)
6 * Todo: Can be improved but satisfatory for now
7 * @return array
8 */
9 function InitializeTestValues($pog_attribute_type)
10 {
11 $DATETIME = '1997-12-15 23:50:26';
12 $DATE = '1997-12-15';
13 $TIMESTAMP = '1997-12-15 23:50:26';
14 $TIME = '23:50:26';
15 $YEAR = '1997';
16 $DECIMAL =
17 $DOUBLE =
18 $FLOAT =
19 $BIGINT =
20 $INT = '12345678';
21 $SMALLINT = '1234';
22 $MEDIUMINT = '12345';
23 $TINYINT = '1';
24 $CHAR = 'L';
25 $VARCHAR =
26 $TEXT =
27 $TINYBLOB =
28 $TINYTEXT =
29 $BLOB =
30 $MEDIUMBLOB =
31 $MEDIUMTEXT =
32 $LONGBLOB =
33 $BINARY=
34 $LONGTEXT = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry';
35 $attribute_testValues = array();
36 array_shift($pog_attribute_type); //get rid of objectid
37 foreach ($pog_attribute_type as $attribute => $property)
38 {
39 if (isset($property['db_attributes'][2]))
40 //length is specified, for e.g. if attribute = VARCHAR(255), $property[2]=255
41 {
42 $limit = explode(',', $property['db_attributes'][2]);
43 //field is limited
44 if (intval($limit[0]) > 0)
45 {
46 if (isset($limit[1]) && intval($limit[1]) > 0)
47 {
48 //decimal, enum, set
49 $attribute_testValues[$attribute] = substr(${$property['db_attributes'][1]}, 0, ceil($limit[0]*0.6)).".".substr(${$property['db_attributes'][1]}, 0, $limit[1]);
50 }
51 else
52 {
53 $attribute_testValues[$attribute] = substr(${$property['db_attributes'][1]}, 0, ceil($limit[0] * 0.6));
54 }
55 }
56 }
57 else
58 //length not specified, but we still need to account for default mysql behavior
59 //for eg, FLOAT(X), if X isn't specified, mysql defaults to (10,2).
60 {
61 if ($property['db_attributes'][1] == "FLOAT" || $property['db_attributes'][1] == "DOUBLE")
62 {
63 $attribute_testValues[$attribute] = "1234.56";
64 }
65 else if ($property['db_attributes'][1] != "HASMANY" && $property['db_attributes'][1] != "BELONGSTO" && $property['db_attributes'][1] != "JOIN")
66 {
67 $attribute_testValues[$attribute] = ${$property['db_attributes'][1]};
68 }
69 }
70 }
71 return $attribute_testValues;
72 }
73
74 /**
75 * Specifies how object attributes are rendered during scaffolding (step 3 of the setup process)
76 * Todo: Can be improved but satisfactory for now
77 * @param string $attributeName
78 * @param string $attributeType
79 * @param string $attributeValue
80 * @param int $objectId
81 * @return string $html
82 */
83 function ConvertAttributeToHtml($attributeName, $attributeProperties, $attributeValue='', $objectId='')
84 {
85 switch ($attributeProperties[1])
86 {
87 case "ENUM":
88 $enumParts = explode(',', $attributeProperties[2]);
89 $html = "<select id='".($objectId != ''?$attributeName."_".$objectId:$attributeName)."' class='s'>";
90 foreach ($enumParts as $enumPart)
91 {
92 if ($attributeValue == trim($enumPart, "\' "))
93 {
94 $html .= "<option value='".trim($enumPart, "\' ")."' selected>".trim($enumPart, "\' ")."</option>";
95 }
96 else
97 {
98 $html .= "<option value='".trim($enumPart, "\' ")."'>".trim($enumPart, "\' ")."</option>";
99 }
100 }
101 $html .= "</select>";
102 break;
103 case "HASMANY":
104 case "JOIN":
105 case "BELONGSTO":
106 $html = $attributeValue;
107 break;
108 case "MEDIUMBLOB":
109 $html = "sorry. cannot render attribute of type LONGBLOB";
110 break;
111 case "LONGBLOB":
112 $html = "sorry. cannot render attribute of type LONGBLOB";
113 break;
114 case "TEXT":
115 case "LONGTEXT":
116 case "BINARY":
117 case "MEDIUMTEXT":
118 case "TINYTEXT":
119 case "VARCHAR":
120 case "TINYBLOB":
121 case "BLOB":
122 $html = "<textarea class='t' id='".($objectId != ''?$attributeName."_".$objectId:$attributeName)."'>".($attributeValue != ''?$attributeValue:'')."</textarea>";
123 break;
124 case "DATETIME":
125 case "DATE":
126 case "TIMESTAMP":
127 case "TIME":
128 case "YEAR":
129 case "DECIMAL":
130 case "DOUBLE":
131 case "FLOAT":
132 case "BIGINT":
133 case "INT":
134 case "YEAR":
135 case "SMALLINT":
136 case "MEDIUMINT":
137 case "TINYINT":
138 case "CHAR":
139 $html = "<input class='i' id='".($objectId != ''?$attributeName."_".$objectId:$attributeName)."' value='".($attributeValue != ''?$attributeValue:'')."' type='text' />";
140 break;
141 default:
142 $html = substr($attributeValue, 0, 500);
143 if (strlen($attributeValue) > 500)
144 {
145 $html .= "...";
146 }
147 break;
148 }
149 return $html;
150 }
151
152 /**
153 * Renders an object as an Xtree Node
154 *
155 * @param unknown_type $child
156 */
157 function ConvertObjectToNode(&$instance, &$masterNode, $js, $anchor, $once = false)
158 {
159 $attributeList = array_keys(get_object_vars($instance));
160 $objectName = $className = get_class($instance);
161 $node = &$masterNode->addItem(new XNode("<span style='color:#0BAA9D'>[".$instance->{strtolower($className)."Id"}."]</span> <a href='#' onclick='ToggleElementVisibility(\"deleteConfirm_".$instance->{strtolower($objectName).'Id'}."\");return false;'><img src=\"./setup_images/button_delete.gif\" border=\"0\"/></a> <span id='deleteConfirm_".$instance->{strtolower($objectName).'Id'}."' style='display:none;width:250px;'><a href='#' class='deleteDeep' onclick='javascript:sndReq(\"DeleteDeep\", getOpenNodes(), \"$objectName\", \"".$instance->{strtolower($objectName).'Id'}."\", this.parentNode.parentNode.parentNode.parentNode.id, $js, \"$anchor\");return false;'>Delete(deep)</a> | <a href='#' class='deleteShallow' onclick='javascript:sndReq(\"Delete\", getOpenNodes(), \"$objectName\", \"".$instance->{strtolower($objectName).'Id'}."\", this.parentNode.parentNode.parentNode.parentNode.id, $js, \"$anchor\");return false;'>Delete(shallow)</a> | <a href='#' class='deleteCancel' onclick='ToggleElementVisibility(\"deleteConfirm_".$instance->{strtolower($objectName).'Id'}."\");return false;'>Cancel</a></span>", false,"setup_images/folderclose.gif","setup_images/folderopen.gif"));
162
163 //regular attributes
164 foreach($attributeList as $attribute)
165 {
166 if ($attribute != "pog_attribute_type" && $attribute!= "pog_query" )
167 {
168 if (isset($instance->pog_attribute_type[$attribute]))
169 {
170 $thisValue = ConvertAttributeToHtml($attribute, $instance->pog_attribute_type[$attribute]['db_attributes'], $instance->{$attribute}, $instance->{$attributeList[0]});
171 $subnode = &$node->addItem(new XNode("<br/>".$attribute."<span style='font-weight:normal;color:#ADA8B2;'>{".$instance->pog_attribute_type[$attribute]['db_attributes'][1]."}</span><br/>".str_replace("\0", "", $thisValue)."<br/><br/>", false,'',"setup_images/folderopen.gif"));
172 }
173 }
174 }
175
176 //parents, children and mapping
177 foreach ($instance->pog_attribute_type as $attribute_name => $attrubute_type)
178 {
179 if ($attrubute_type['db_attributes'][1] == "HASMANY" || $attrubute_type['db_attributes'][1] == "BELONGSTO" || $attrubute_type['db_attributes'][1] == "JOIN")
180 {
181 if ($attrubute_type['db_attributes'][1] == "BELONGSTO")
182 {
183 eval ('$value = $instance->'.strtolower($attribute_name).'Id;');
184 $thisValue = ConvertAttributeToHtml($attribute_name, $attrubute_type['db_attributes'], $value, '');
185 $subnode = &$node->addItem(new XNode("<br/>".$attribute_name."<span style='font-weight:normal;color:#ADA8B2;'>{".($attrubute_type['db_attributes'][1] == "HASMANY" ? "CHILD" : "PARENT")."}</span><br/>".$thisValue."<br/><br/>", false,'',"setup_images/folderopen.gif"));
186 }
187 else
188 {
189 $value = '';
190 eval('$siblingList = $instance->Get'.ucfirst(strtolower($attribute_name)).'List();');
191 if (sizeof($siblingList) > 0)
192 {
193 $myNode = &$node->addItem(new XNode("<span style='color:#4d4a4a'>[".$attribute_name."List]{Dimensions:[".sizeof($siblingList)."]}</span>", false, "setup_images/folderclose.gif","setup_images/folderopen.gif", true));
194 $child = $siblingList[0];
195 $js2 = "new Array(";
196 $attributeList = array_keys(get_object_vars($child));
197 $x=0;
198 foreach($attributeList as $attribute)
199 {
200 if ($attribute != "pog_attribute_type" && $attribute!= "pog_query")
201 {
202 if ($x != 0 && isset($child->pog_attribute_type[$attribute]))
203 {
204 $js2 .= '"'.$attribute.'",';
205 }
206 }
207 $x++;
208 }
209 $js2 = trim($js2, ",");
210 $js2 .= ")";
211
212 if (!$once)
213 {
214 foreach ($siblingList as $child)
215 {
216 /*$value .= $child->{strtolower($attribute_name)."Id"} . ",";*/
217 if ($attrubute_type['db_attributes'][1] == "JOIN")
218 {
219 ConvertObjectToNode($child, $myNode, $js2, $anchor, true);
220 }
221 else
222 {
223 ConvertObjectToNode($child, $myNode, $js2, $anchor);
224 }
225 }
226 }
227 }
228 else
229 {
230 $node->addItem(new XNode("<span style='color:#4d4a4a'>[".$attribute_name."List]{Dimensions:[0]}</span><br/><br/>", false, '',"setup_images/folderopen.gif"));
231 }
232 }
233 }
234 }
235 $subnode = &$node->addItem(new XNode("<br/><a style='float:left;' href='#' onclick='javascript:PleaseWait(\"".$instance->{strtolower($objectName).'Id'}."\"); sndReq(\"Update\", getOpenNodes(), \"$objectName\", \"".$instance->{strtolower($objectName).'Id'}."\", this.parentNode.parentNode.parentNode.parentNode.id, $js, \"$anchor\");return false;'><img src='./setup_images/button_update.gif' border='0'/></a><span id='pleasewait".$instance->{strtolower($objectName).'Id'}."' style='float:left;display:none;'><img src='./setup_images/loading.gif' style='float:left;'/></span><br/>", false,'',"folderopen.gif"));
236 }
237
238
239 /**
240 * Populates object attributes with test values
241 *
242 * @param unknown_type $object
243 * @return unknown
244 */
245 function PopulateTestValues(&$object)
246 {
247 $attributeList = array_keys(get_object_vars($object));
248 $type_value = InitializeTestValues($object->pog_attribute_type);
249
250 $objectName = get_class($object);
251 foreach($attributeList as $attribute)
252 {
253 if (isset($object->pog_attribute_type[$attribute]))
254 {
255 if (isset($type_value[$attribute]))
256 {
257 $object->{$attribute} = $type_value[$attribute];
258 }
259 else if ($object->pog_attribute_type[$attribute]['db_attributes'][0] != "OBJECT")
260 {
261 $object->{$attribute} = "1";
262 }
263 }
264 }
265 eval ("\$object -> ".strtolower($objectName)."Id = '';");
266 return $object;
267 }
268
269 /**
270 * Extracts @link from object file
271 *
272 * @param unknown_type $objectFilePath
273 * @return unknown
274 */
275 function GetAtLink($objectFilePath)
276 {
277 $link = '';
278 $content = file_get_contents($objectFilePath);
279 $contentParts = split("<b>",$content);
280 if (isset($contentParts[1]))
281 {
282 $contentParts2 = split("</b>",$contentParts[1]);
283 }
284 if (isset($contentParts2[0]))
285 {
286 $className = trim($contentParts2[0]);
287 }
288 if (isset($className))
289 {
290 $linkParts1 = split("\*\/", $contentParts[1]);
291 $linkParts2 = split("\@link", $linkParts1[0]);
292 if (isset($linkParts2[1]))
293 {
294 $link = $linkParts2[1];
295 }
296 if (isset($GLOBALS['configuration']['homepage']) && isset($link))
297 {
298 $linkParts = explode('?', $link);
299 if (isset($linkParts[1]))
300 {
301 $link = $GLOBALS['configuration']['homepage'].'/?'.$linkParts[1];
302 }
303 }
304 }
305 return $link;
306 }
307
308 /**
309 * Extracts object name from object file. Do not rely on filename.
310 *
311 * @param unknown_type $objectFilePath
312 */
313 function GetObjectName($objectFilePath)
314 {
315 $content = file_get_contents($objectFilePath);
316 $contentParts = split("<b>",$content);
317 if (isset($contentParts[1]))
318 {
319 $contentParts2 = split("</b>",$contentParts[1]);
320 }
321 if (isset($contentParts2[0]))
322 {
323 $className = trim($contentParts2[0]);
324 }
325 return $className;
326 }
327
328 /**
329 * Gets plugin name based on filename
330 *
331 * @param unknown_type $fileName
332 * @return unknown
333 */
334 function GetPluginName($fileName)
335 {
336 $fileNameParts = explode('.', $fileName);
337 if (strtolower($fileName) != "iplugin.php" && strtolower($fileNameParts[0]) == 'plugin' && strtolower($fileNameParts[2]) == 'php')
338 {
339 return $fileNameParts[1];
340 }
341 return '';
342 }
343
344 /**
345 * Adds message to error queue
346 *
347 * @param unknown_type $error
348 */
349 function AddError($error)
350 {
351 if (isset($_SESSION['errorMessages']))
352 {
353 $errorMessages = unserialize($_SESSION['errorMessages']);
354 if (array_search($error, $errorMessages) === false)
355 {
356 $errorMessages[] = $error;
357 }
358 }
359 else
360 {
361 $errorMessages = array();
362 $errorMessages[] = $error;
363 }
364 $_SESSION['errorMessages'] = serialize($errorMessages);
365 }
366
367 /**
368 * Add message to tracing queue
369 *
370 * @param unknown_type $trace
371 */
372 function AddTrace($trace)
373 {
374 if (isset($_SESSION['traceMessages']))
375 {
376 $traceMessages = unserialize($_SESSION['traceMessages']);
377 $traceMessages[] = $trace;
378 }
379 else
380 {
381 $traceMessages = array();
382 $traceMessages[] = $trace;
383 }
384 $_SESSION['traceMessages'] = serialize($traceMessages);
385 }
386
387 /**
388 * Unit tests
389 */
390
391 /**
392 * Test the base 5 CRUD methods
393 *
394 * @param unknown_type $instance
395 * @return unknown
396 */
397 function TestEssentials($instance, $optimizeAsWell = true)
398 {
399 if(TestIsMapping($instance))
400 {
401 return true;
402 }
403 $errors = 0;
404 if (!TestSave($instance))
405 {
406 $errors++;
407 }
408 if (!TestSaveNew($instance))
409 {
410 $errors++;
411 }
412 if (!TestDelete($instance))
413 {
414 $errors++;
415 }
416 if (!TestGetList($instance))
417 {
418 $errors++;
419 }
420 if (!TestDeleteList($instance))
421 {
422 $errors++;
423 }
424 if ($optimizeAsWell)
425 {
426 if (!TestOptimizeStorage(strtolower(get_class($instance))))
427 {
428 $errors++;
429 }
430 }
431
432 if ($errors == 0)
433 {
434 return true;
435 }
436 return false;
437 }
438
439 /**
440 * Enter description here...
441 *
442 * @param unknown_type $instance
443 * @return unknown
444 */
445 function TestRelationsPreRequisites($instance, $allObjectsList, $thisObjectName, $ignoreObjects)
446 {
447 if(TestIsMapping($instance))
448 {
449 AddTrace("\tIs Mapping (OK)");
450 return true;
451 }
452 if (TestIsSingle($instance))
453 {
454 AddTrace("\tIs single (OK)");
455 return true;
456 }
457 else
458 {
459 if (!TestParentChildLink($instance, $allObjectsList, $thisObjectName, $ignoreObjects) || !TestAssociationLink($instance, $allObjectsList, $thisObjectName, $ignoreObjects))
460 {
461 return false;
462 }
463 else
464 {
465 AddTrace("\tIs properly connected (OK)");
466 return true;
467 }
468 }
469 }
470
471 /**
472 * Test the optional object relations methods
473 *
474 * @param unknown_type $instance
475 * @return unknown
476 */
477 function TestRelations($instance, $ignoreObjects)
478 {
479 $errors=0;
480 if (TestIsParent($instance))
481 {
482 if (!TestAddChild($instance, true, $ignoreObjects))
483 {
484 $errors++;
485 }
486 if (!TestGetChildrenList($instance, true, $ignoreObjects))
487 {
488 $errors++;
489 }
490 if (!TestDeleteDeep_Child($instance, true, $ignoreObjects))
491 {
492 $errors++;
493 }
494 if (!TestSaveDeep_Child($instance, true, $ignoreObjects))
495 {
496 $errors++;
497 }
498 if (!TestSetChildrenList($instance, true, $ignoreObjects))
499 {
500 $errors++;
501 }
502 }
503 if (TestIsChild($instance))
504 {
505 if (!TestSetParent($instance, true, $ignoreObjects))
506 {
507 $errors++;
508 }
509 if (!TestGetParent($instance, true, $ignoreObjects))
510 {
511 $errors++;
512 }
513 }
514 if (TestIsSibling($instance))
515 {
516 if (!TestAddSibling($instance, true, $ignoreObjects))
517 {
518 $errors++;
519 }
520 if (!TestGetSiblingList($instance, true, $ignoreObjects))
521 {
522 $errors++;
523 }
524 if (!TestSaveDeep_Sibling($instance, true, $ignoreObjects))
525 {
526 $errors++;
527 }
528 if (!TestDeleteDeep_Sibling($instance, true, $ignoreObjects))
529 {
530 $errors++;
531 }
532 if (!TestSetSiblingList($instance, true, $ignoreObjects))
533 {
534 $errors++;
535 }
536 }
537 if ($errors == 0)
538 {
539 return true;
540 }
541 return false;
542 }
543
544 /**
545 * Tests whether object table already exists
546 *
547 */
548 function TestStorageExists($objectName, $databaseType = "mysql")
549 {
550 switch ($databaseType)
551 {
552 case "mysql":
553 $query = "show tables like '".strtolower($objectName)."'";
554 break;
555 case "sqlite":
556 $query = "select name FROM sqlite_master WHERE type='table' and name='".strtolower($objectName)."'";
557 break;
558 case "pgsql":
559 $query = "select table_name FROM information_schema.tables WHERE table_schema = 'public' and table_name='".strtolower($objectName)."'";
560 break;
561 case "odbc":
562 //assume mssql
563 $query = "select * from information_schema.tables where table_type = 'BASE TABLE' and table_name='".strtolower($objectName)."'";
564 break;
565 case "firebird":
566 AddError("POG Setup doesn't support automatic table detection for Firebird databases yet. Therefore, your objects/tables may be misaligned. If POG Essential tests failed, this may very well be the case. Create the tables manually and re-run setup.");
567 return true;
568 break;
569 }
570
571 $connection = Database::Connect();
572 $rows = Database::Query($query, $connection);
573 if ($rows > 0)
574 {
575 return true;
576 }
577 return false;
578 }
579
580 /**
581 * Creates the table to store objects
582 *
583 */
584 function TestCreateStorage($objectFilePath, $databaseType = "mysql")
585 {
586 if ($databaseType == "firebird")
587 {
588 AddError("POG Setup doesn't support automatic table creation for Firebird databases yet. Therefore, your objects/tables may be misaligned. If POG Essential tests failed, this may very well be the case. Create the tables manually and re-run setup.");
589 return true;
590 }
591
592 $objectName = GetObjectName($objectFilePath);
593
594 //extract sql
595 $content = file_get_contents($objectFilePath);
596 $contentParts = split("<b>",$content);
597 if (isset($contentParts[1]))
598 {
599 $contentParts2 = split("</b>",$contentParts[1]);
600 }
601 if (isset($contentParts2[0]))
602 {
603 $className = trim($contentParts2[0]);
604 }
605 if (isset($className))
606 {
607 $sqlParts = split(";",$contentParts[0]);
608 $sqlPart = split("CREATE",$sqlParts[0]);
609 $sql = "CREATE ".$sqlPart[1].";";
610
611 //execute sql
612 $connection = Database::Connect();
613 if (Database::NonQuery($sql, $connection) !== false)
614 {
615 return true;
616 }
617 }
618 AddError("Query failed: $sql");
619 return false;
620 }
621
622 /**
623 * Drops the table for the corresponding object
624 *
625 */
626 function TestDeleteStorage($object, $databaseType = "mysql")
627 {
628 $tableName = strtolower(get_class($object));
629 $connection = Database::Connect();
630 if (Database::NonQuery('drop table `'.strtolower($tableName).'`', $connection) !== false)
631 {
632 return true;
633 }
634 return false;
635 }
636
637 /**
638 * Executes an arbitrary query
639 *
640 * @param unknown_type $query
641 */
642 function TestExecuteQuery($query)
643 {
644 $connection = Database::Connect();
645 if ($query == "")
646 {
647 return true;
648 }
649 if (Database::NonQuery($query, $connection) !== false)
650 {
651 return true;
652 }
653 return false;
654 }
655
656 /**
657 * Enter description here...
658 *
659 * @param unknown_type $object
660 * @return unknown
661 */
662 function TestAlterStorage($object, $databaseType = "mysql")
663 {
664 if ($databaseType != "mysql")
665 {
666 AddTrace("POG Setup doesn't support table automatic alteration for non-MySQL databases yet. Therefore, your objects/tables may be misaligned. If POG Essential tests failed, this may very well be the case. Drop and recreate the tables and re-run setup.");
667 return true;
668 }
669
670 //find object attributes/table columns mismatch
671 $tableName = strtolower(get_class($object));
672 $columns = array();
673
674 $query = "describe `$tableName` ";
675 $connection = Database::Connect();
676 $cursor = Database::Reader($query, $connection);
677 if ($cursor !== false)
678 {
679 while ($row = Database::Read($cursor))
680 {
681 $columns[$row["Field"]] = $row["Type"];
682 }
683
684 $attribute_types = $object -> pog_attribute_type;
685 $lowerAttributes = array();
686 foreach (array_keys($attribute_types) as $key)
687 {
688 $lowerAttributes[strtolower($key)] = $attribute_types[$key];
689 }
690
691 //columns to remove
692 $columnsToRemove = array_diff(array_keys($columns), array_keys($lowerAttributes));
693
694 //columns to add
695 $columnsToAdd = array_diff(array_keys($lowerAttributes), array_keys($columns));
696
697 //columns whose type has changed
698 $otherColumns = array_intersect(array_keys($lowerAttributes), array_keys($columns));
699
700 $columnsToModify = array();
701 foreach ($otherColumns as $otherColumn)
702 {
703 $type = strtolower($lowerAttributes[$otherColumn]['db_attributes'][1]);
704 if ($type == 'enum' || $type == 'set')
705 {
706 $enumPartsObj = explode(',', strtolower($lowerAttributes[$otherColumn]['db_attributes'][2]));
707 $parts = explode('(',$columns[$otherColumn]);
708 $parts2 = explode(')',$parts[1]);
709 $enumpartsDb = explode(',', strtolower(trim($parts2[0])));
710 foreach ($enumPartsObj as $ep)
711 {
712 if (array_search(trim($ep), $enumpartsDb) === false)
713 {
714 $type .= "(".$lowerAttributes[$otherColumn]['db_attributes'][2].")";
715 $columnsToModify[$otherColumn] = $type;
716 break;
717 }
718 }
719 }
720 else
721 {
722 if (isset($lowerAttributes[$otherColumn]['db_attributes'][2]))
723 {
724 $type .= "(".$lowerAttributes[$otherColumn]['db_attributes'][2].")";
725 }
726 if (strpos(strtolower($columns[$otherColumn]), $type) === false && $type != "hasmany" && $type != "join")
727 {
728 if ($type == "belongsto")
729 {
730 $columnsToModify[strtolower($otherColumn)] = "int";
731 }
732 else
733 {
734 $columnsToModify[$otherColumn] = $type;
735 }
736 }
737 }
738 }
739
740 $columnsToRemove2 = array();
741 foreach ($columnsToRemove as $c)
742 {
743 $columnsToRemove2[] = strtolower($c);
744 }
745
746 $columnsToRemove = $columnsToRemove2;
747
748 $columnsToAdd2 = array();
749 foreach ($columnsToAdd as $c)
750 {
751 if ($lowerAttributes[$c]['db_attributes'][1] != "HASMANY" && $lowerAttributes[$c]['db_attributes'][1] != "JOIN")
752 {
753 if ($lowerAttributes[$c]['db_attributes'][1] == "BELONGSTO")
754 {
755 $colMarkedForDeletion = array_search(strtolower($c)."id", $columnsToRemove);
756 if ($colMarkedForDeletion === false) //this is clumsy, until we think of something better
757 {
758 $columnsToAdd2[] = strtolower($c)."id int";
759 }
760 else
761 {
762 //remove entry from columnsToRemove since they are the same. Will lose data if dropped & recreated
763 array_splice($columnsToRemove, $colMarkedForDeletion, 1);
764 }
765 }
766 else
767 {
768 $columnsToAdd2[] = $c;
769 }
770 }
771 }
772
773 $common = array();
774 $common = array_intersect($columnsToAdd2, $columnsToRemove);
775
776 $columnsToAdd = array();
777 foreach ($columnsToAdd2 as $col)
778 {
779 if (array_search($col, $common) === false)
780 {
781 $columnsToAdd[] = $col;
782 }
783 }
784 $columnsToRemove2 = array();
785 foreach ($columnsToRemove as $col)
786 {
787 if (array_search($col, $common) === false)
788 {
789 $columnsToRemove2[] = $col;
790 }
791 }
792
793
794 if (sizeof($columnsToAdd) == 0 && sizeof($columnsToRemove2) == 0 && sizeof($columnsToModify) == 0)
795 {
796 return true;
797 }
798
799 //construct query
800 $query = "alter table `$tableName` ";
801
802 foreach ($columnsToRemove2 as $remove)
803 {
804 $query .= "drop column `$remove`,";
805 }
806
807 foreach ($columnsToAdd as $add)
808 {
809 $columnType = '';
810 if (isset($lowerAttributes[$add]))
811 {
812 $columnType = strtolower($lowerAttributes[$add]['db_attributes'][1]);
813 }
814 if (isset($lowerAttributes[$add]['db_attributes'][2]))
815 {
816 $columnType .= "(".$lowerAttributes[$add]['db_attributes'][2].")";
817 }
818 if ($columnType != '')
819 {
820 $query .= "add column `$add` $columnType,";
821 }
822 else
823 {
824 $query .= "add column $add,";
825 }
826 }
827
828
829 foreach (array_keys($columnsToModify) as $modify)
830 {
831 $query .= "modify `$modify` ".$columnsToModify[$modify].",";
832 }
833 $query = trim($query, ',');
834 //execute query
835
836 if (Database::NonQuery($query, $connection) !== false)
837 {
838 return true;
839 }
840 }
841 AddError("Query failed: $query");
842 return false;
843 }
844
845 /**
846 * Optimizes the table by running mysql optimize
847 *
848 * @param unknown_type $objectName
849 * @return unknown
850 */
851 function TestOptimizeStorage($objectName)
852 {
853 $connection = Database::Connect();
854 if (Database::NonQuery("optimize table `".strtolower($objectName)."`", $connection) !== false)
855 {
856 AddTrace("\tOptimizing....OK!");
857 return true;
858 }
859 return false;
860 }
861
862 /**
863 * Unit test for Save()
864 *
865 */
866 function TestSave($object, $trace=true)
867 {
868 $className = get_class($object);
869 $object = PopulateTestValues($object);
870 $objectId = false;
871 $object->{strtolower($className)."Id"} = "";
872 $objectId = $object->Save(false);
873
874 if(!$objectId)
875 {
876 if ($trace)
877 {
878 AddTrace("\tSave() failed");
879 AddError("Query failed: ".$object->pog_query);
880 }
881 return false;
882 }
883 //cleanup test data
884 $query = "delete from `".strtolower($className)."` where ".strtolower($className)."id = '".$objectId."';";
885 $connection = Database::Connect();
886 Database::NonQuery($query, $connection);
887 if ($trace)
888 {
889 AddTrace("\tSave()....OK!");
890 }
891 return true;
892 }
893
894 /**
895 * Unit test for SaveNew()
896 *
897 */
898 function TestSaveNew($object, $trace = true)
899 {
900 $className = get_class($object);
901 if(!TestSave($object, false))
902 {
903 if ($trace)
904 {
905 AddTrace("\tSaveNew() ignored");
906 }
907 return false;
908 }
909 $objectId = $object->SaveNew(false);
910 if ($objectId)
911 {
912 $query = "delete from `".strtolower($className)."` where ".strtolower($className)."Id = '".$objectId."';";
913 $connection = Database::Connect();
914 Database::NonQuery($query, $connection);
915 if ($trace)
916 {
917 AddTrace("\tSaveNew()....OK!");
918 }
919 return true;
920 }
921 if ($trace)
922 {
923 AddTrace("\tSaveNew() failed");
924 AddError("Query failed: ".$object->pog_query);
925 }
926 return false;
927 }
928
929 /**
930 * Unit test for GetList(). Implicitly tests Get()
931 *
932 */
933 function TestGetList($object, $trace = true)
934 {
935 if ($trace)
936 {
937 AddTrace("\tGetList()");
938 }
939 $errors = 0;
940 if (TestSave($object,false) && TestSaveNew($object, false) && TestDelete($object, false))
941 {
942 $className = get_class($object);
943 $objectList = $object->GetList(array(array(strtolower($className)."Id", ">", 0)));
944 $oldCount = count($objectList);
945 $object = PopulateTestValues($object);
946 $objectId = false;
947 $object->{strtolower($className)."Id"} = 0;
948 $objectId = $object->Save(false);
949 $objectId2 = $object->SaveNew(false);
950 $objectId3 = $object->SaveNew(false);
951
952
953 //Test Multiple Conditions
954 $objectList = $object->GetList(array(array(strtolower($className)."Id", ">=",$objectId), array(strtolower($className)."Id", "<=", $objectId+2)), strtolower($className)."Id", false, 2);
955 if (sizeof($objectList) != 2)
956 {
957 //Test Limit
958 if ($trace)
959 {
960 AddTrace("\t\tLimit failed");
961 AddError('ERROR: GetList() :sizeof(list) != \$limit\n');
962 AddError("Query failed: ".$object->pog_query);
963 }
964 $errors++;
965 }
966 else
967 {
968 if ($trace)
969 {
970 AddTrace("\t\tLimit....OK!");
971 }
972 }
973 if ($objectList[1]->{strtolower($className)."Id"} > $objectList[0]->{strtolower($className)."Id"})
974 {
975 //Test Sorting
976 if ($trace)
977 {
978 AddTrace("\t\tSorting failed");
979 AddError("ERROR: GetList() :list is not properly sorted");
980 AddError("Query failed: ".$object->pog_query);
981 }
982 $errors++;
983 }
984 else
985 {
986 if ($trace)
987 {
988 AddTrace("\t\tSorting....OK!");
989 }
990 }
991 if ($errors == 0)
992 {
993 $objectList = $object->GetList(array(array(strtolower($className)."Id", ">=",$objectId), array(strtolower($className)."Id", "<=", $objectId+2)), strtolower($className)."Id", false, 3);
994 foreach ($objectList as $object)
995 {
996 $attributeList = array_keys(get_object_vars($object));
997 foreach ($attributeList as $attribute)
998 {
999 if (isset($object->pog_attribute_type[$attribute]))
1000 {
1001 if (isset($type_value[$attribute]))
1002 {
1003 if ($object->{$attribute} != $type_value[$attribute])
1004 {
1005 if($trace)
1006 {
1007 AddError("WARNING: Failed to retrieve attribute `$attribute`. Expecting `".$type_value[$attribute]."`; found `".$object->{$attribute}."`. Check that column `$attribute` in the `$className` table is of type `".$object->pog_attribute_type[$attribute]['db_attributes'][1]."`");
1008 }
1009 }
1010 }
1011 }
1012 }
1013 $object->Delete();
1014 }
1015 return true;
1016 }
1017 else
1018 {
1019 if ($trace)
1020 {
1021 AddTrace("\tGetList() failed");
1022 AddError("Query failed: ".$object->pog_query);
1023 }
1024 return false;
1025 }
1026 }
1027 if ($trace)
1028 {
1029 AddTrace("\tGetList() ignored");
1030 }
1031 return false;
1032 }
1033
1034 /**
1035 * Unit test for Delete()
1036 *
1037 */
1038 function TestDelete($object, $trace = true)
1039 {
1040 if(!TestSave($object, false))
1041 {
1042 if ($trace)
1043 {
1044 AddTrace("\tDelete() ignored");
1045 }
1046 return false;
1047 }
1048 $object = PopulateTestValues($object);
1049 $object->Save(false);
1050 if ($object->Delete(false))
1051 {
1052 if ($trace)
1053 {
1054 AddTrace("\tDelete()....OK!");
1055 }
1056 return true;
1057 }
1058 if ($trace)
1059 {
1060 AddTrace("\tDelete() failed");
1061 AddError("Query failed: ".$object->pog_query);
1062 }
1063 return false;
1064 }
1065
1066 /**
1067 * Unit Test for DeleteList()
1068 *
1069 * @param unknown_type $object
1070 * @param unknown_type $trace
1071 */
1072 function TestDeleteList($object, $trace = true)
1073 {
1074 $className = get_class($object);
1075 if(!TestSave($object, false) || !TestGetList($object, false))
1076 {
1077 if ($trace)
1078 {
1079 AddTrace("\tDeleteList() ignored");
1080 }
1081 return false;
1082 }
1083
1084 $object = PopulateTestValues($object);
1085
1086 $originalCount = GetNumberOfRecords($className);
1087
1088 $objectId = false;
1089 $object->{strtolower($className)."Id"} = 0;
1090 $objectId = $object->Save(false);
1091 $objectId2 = $object->SaveNew(false);
1092 $objectId3 = $object->SaveNew(false);
1093
1094 $className = get_class($object);
1095 $object->DeleteList(array(array(strtolower($className)."Id", "=", $objectId), array("or"), array(strtolower($className)."Id", "=", $objectId2), array("or"), array(strtolower($className)."Id", "=", $objectId3)));
1096
1097 $newCount = GetNumberOfRecords($className);
1098
1099 if ($newCount == $originalCount)
1100 {
1101 if ($trace)
1102 {
1103 AddTrace("\tDeleteList()....OK!");
1104 }
1105 return true;
1106 }
1107
1108 if ($trace)
1109 {
1110 AddTrace("\tDeleteList() failed");
1111 AddError("Query failed: ".$object->pog_query);
1112 }
1113 return false;
1114 }
1115
1116 /**
1117 * Tests whether the object is connected at all
1118 *
1119 * @param unknown_type $object
1120 * @param unknown_type $allObjectsList
1121 */
1122 function TestIsSingle($object)
1123 {
1124 $attribute_types = $object->pog_attribute_type;
1125
1126 //get all child classes
1127 $childrenList = array();
1128 foreach ($attribute_types as $key => $attribute_array)
1129 {
1130 if ($attribute_array['db_attributes'][1] == "HASMANY")
1131 {
1132 $childrenList[] = $key;
1133 }
1134 }
1135
1136 //get all parent classes
1137 $parentsList = array();
1138 foreach ($attribute_types as $key => $attribute_array)
1139 {
1140 if ($attribute_array['db_attributes'][1] == "BELONGSTO")
1141 {
1142 $parentsList[] = $key;
1143 }
1144 }
1145
1146 //get all associations
1147 $associationsList = array();
1148 foreach ($attribute_types as $key => $attribute_array)
1149 {
1150 if ($attribute_array['db_attributes'][1] == "JOIN")
1151 {
1152 $associationsList[] = $key;
1153 }
1154 }
1155
1156 if (sizeof($childrenList) == 0 && sizeof($parentsList) == 0 && sizeof($associationsList) == 0)
1157 {
1158 return true;
1159 }
1160 return false;
1161 }
1162
1163 /**
1164 * Tests that all parents have children and vice-versa
1165 *
1166 * @param unknown_type $object
1167 * @param unknown_type $allObjectsList
1168 * @param unknown_type $thisObjectName
1169 * @return unknown
1170 */
1171 function TestParentChildLink($object, $allObjectsList, $thisObjectName = '', $ignoreObjects)
1172 {
1173 $attribute_types = $object->pog_attribute_type;
1174
1175 //get all child classes
1176 $childrenList = array();
1177 foreach ($attribute_types as $key => $attribute_array)
1178 {
1179 if ($attribute_array['db_attributes'][1] == "HASMANY")
1180 {
1181 $childrenList[] = $key;
1182 }
1183 }
1184
1185 //get all parent classes
1186 $parentsList = array();
1187 foreach ($attribute_types as $key => $attribute_array)
1188 {
1189 if ($attribute_array['db_attributes'][1] == "BELONGSTO")
1190 {
1191 $parentsList[] = $key;
1192 }
1193 }
1194
1195 $errors = 0;
1196 foreach ($childrenList as $child)
1197 {
1198 if (array_search($child, $allObjectsList) === false)
1199 {
1200 $errors++;
1201 AddError("$thisObjectName refers to $child as {Child}, which couldn't be found. Generate the $child object with reference to $thisObjectName as {Parent}");
1202 }
1203 else
1204 {
1205 //test that child refers to this object as parent
1206 eval ("\$childInstance = new $child();");
1207 $childAttributes = array_keys($childInstance->pog_attribute_type);
1208 if (array_search($thisObjectName, $childAttributes) === false)
1209 {
1210 $errors++;
1211 AddError("$thisObjectName refers to $child as {Child}, but $child does not refer to $thisObjectName as {Parent}. Relations need to be reciprocal.");
1212 }
1213 }
1214 }
1215
1216 foreach ($parentsList as $parent)
1217 {
1218 if (array_search($parent, $allObjectsList) === false)
1219 {
1220 $errors++;
1221 AddError("$thisObjectName refers to $parent as parent, which couldn't be found. Generate the $parent object with reference to $thisObjectName as {Child}");
1222 }
1223 else
1224 {
1225 //test that parent refers to this object as child
1226 eval ("\$parentInstance = new $parent();");
1227 $parentAttributes = array_keys($parentInstance->pog_attribute_type);
1228 if (array_search($thisObjectName, $parentAttributes) === false)
1229 {
1230 $errors++;
1231 AddError("$thisObjectName refers to $parent as {Parent}, but $parent does not refer to $thisObjectName as {Child}. Relations need to be reciprocal.");
1232 }
1233 }
1234 }
1235
1236 if ($errors == 0)
1237 {
1238 return true;
1239 }
1240 return false;
1241 }
1242
1243 /**
1244 * Tests that all Joins have reciprocal links
1245 *
1246 * @param unknown_type $object
1247 * @param unknown_type $allObjectsList
1248 * @param unknown_type $thisObjectName
1249 */
1250 function TestAssociationLink($object, $allObjectsList, $thisObjectName = '', $ignoreObjects)
1251 {
1252 $attribute_types = $object->pog_attribute_type;
1253
1254 //get all join classes
1255 $associationsList = array();
1256 foreach ($attribute_types as $key => $attribute_array)
1257 {
1258 if ($attribute_array['db_attributes'][1] == "JOIN")
1259 {
1260 $associationsList[] = $key;
1261 }
1262 }
1263
1264 $errors = 0;
1265 foreach ($associationsList as $association)
1266 {
1267 if (array_search($association, $allObjectsList) === false)
1268 {
1269 $errors++;
1270 AddError("$thisObjectName refers to $association as {SIBLING}, which couldn't be found. Generate the $association object with reference to $thisObjectName as {SIBLING}");
1271 }
1272 else
1273 {
1274 //test that association refers to this object as map
1275 eval ("\$associationInstance = new $association();");
1276 $associationAttributes = array_keys($associationInstance->pog_attribute_type);
1277 if (array_search($thisObjectName, $associationAttributes) === false)
1278 {
1279 $errors++;
1280 AddError("$thisObjectName refers to $association as {SIBLING}, but $association does not refer to $thisObjectName as {SIBLING}. Relations need to be reciprocal.");
1281 }
1282 }
1283 }
1284
1285 if ($errors == 0)
1286 {
1287 return true;
1288 }
1289 return false;
1290 }
1291
1292 /**
1293 * Unit test to see if object is a parent
1294 *
1295 * @param unknown_type $object
1296 */
1297 function TestIsParent($object)
1298 {
1299 $attribute_types = $object->pog_attribute_type;
1300 foreach ($attribute_types as $attribute_array)
1301 {
1302 if ($attribute_array['db_attributes'][1] == "HASMANY")
1303 {
1304 return true;
1305 }
1306 }
1307 return false;
1308 }
1309
1310 /**
1311 * Unit test to see if object is child
1312 *
1313 * @param unknown_type $object
1314 */
1315 function TestIsChild($object)
1316 {
1317 $attribute_types = $object->pog_attribute_type;
1318 foreach ($attribute_types as $attribute_array)
1319 {
1320 if ($attribute_array['db_attributes'][1] == "BELONGSTO")
1321 {
1322 return true;
1323 }
1324 }
1325 return false;
1326 }
1327
1328 /**
1329 * Unit test to see if object is Sibling
1330 *
1331 * @param unknown_type $object
1332 * @return unknown
1333 */
1334 function TestIsSibling($object)
1335 {
1336 $attribute_types = $object->pog_attribute_type;
1337 foreach ($attribute_types as $attribute_array)
1338 {
1339 if ($attribute_array['db_attributes'][1] == "JOIN")
1340 {
1341 return true;
1342 }
1343 }
1344 return false;
1345 }
1346
1347 /**
1348 * Unit test to see if object is a Mapping object
1349 *
1350 * @param unknown_type $object
1351 */
1352 function TestIsMapping($object)
1353 {
1354 $funcs = get_class_methods(get_class($object));
1355 foreach ($funcs as $func)
1356 {
1357 if (strtolower($func) == "addmapping")
1358 {
1359 return true;
1360 }
1361 }
1362 return false;
1363 }
1364
1365 /**
1366 * Unit test for Save($deep)
1367 *
1368 * @param unknown_type $object
1369 */
1370 function TestSaveDeep_Child($object, $trace = true, $ignoreObjects)
1371 {
1372 $thisObjectName = get_class($object);
1373 if (!TestAddChild($object, false, $ignoreObjects))
1374 {
1375 if ($trace)
1376 {
1377 AddTrace("\tSave(deep) ignored");
1378 AddError("Save(deep) ignored since AddChild could not be performed");
1379 }
1380 return false;
1381 }
1382 if (!TestGetChildrenList($object, false, $ignoreObjects))
1383 {
1384 if ($trace)
1385 {
1386 AddTrace("\tSave(deep) ignored");
1387 AddError("Save(deep) ignored since GetChildrenList could not be performed");
1388 }
1389 return false;
1390 }
1391 if (!TestDeleteDeep_Child($object, false, $ignoreObjects))
1392 {
1393 if ($trace)
1394 {
1395 AddTrace("\tSave(deep) ignored");
1396 AddError("Save(deep) ignored since Delete(deep) could not be performed");
1397 }
1398 return false;
1399 }
1400
1401 //get all child classes
1402 $childrenList = array();
1403 eval("\$object = new $thisObjectName();");
1404 $object = PopulateTestValues($object);
1405 $attribute_types = $object->pog_attribute_type;
1406
1407 foreach ($attribute_types as $key => $attribute_array)
1408 {
1409 if ($attribute_array['db_attributes'][1] == "HASMANY")
1410 {
1411 $childrenList[] = $key;
1412 }
1413 }
1414
1415 $errors = 0;
1416 foreach ($childrenList as $child)
1417 {
1418 //instantiate
1419 eval("\$childInstance = new $child();");
1420 $childInstance = PopulateTestValues($childInstance);
1421
1422 //add children
1423 eval ("\$object -> Add$child(\$childInstance);");
1424 }
1425
1426 //test
1427 if (!$object->Save(true))
1428 {
1429 $errors++;
1430 return false;
1431 }
1432
1433 foreach ($childrenList as $child)
1434 {
1435 //instantiate
1436 eval("\$childArray = \$object->Get".$child."List();");
1437 if (sizeof($childArray) == 0)
1438 {
1439 if ($trace)
1440 {
1441 AddTrace("\tSave($child) failed");
1442
1443 }
1444 $errors++;
1445 }
1446 else
1447 {
1448 if ($trace)
1449 {
1450 AddTrace("\tSave($child)....OK!");
1451 }
1452 }
1453 }
1454
1455 //cleanup
1456 $object->Delete(true);
1457
1458 if ($errors == 0)
1459 {
1460 return true;
1461 }
1462 return false;
1463 }
1464
1465 /**
1466 * Unit test for Save($deep)
1467 *
1468 * @param unknown_type $object
1469 * @return unknown
1470 */
1471 function TestSaveDeep_Sibling($object, $trace = true, $ignoreObjects)
1472 {
1473 $thisObjectName = get_class($object);
1474 if (!TestAddSibling($object, false, $ignoreObjects))
1475 {
1476 if ($trace)
1477 {
1478 AddTrace("\tSave(deep) ignored");
1479 AddError("Save(deep) ignored since AddSibling could not be performed");
1480 }
1481 return false;
1482 }
1483 if (!TestGetSiblingList($object, false, $ignoreObjects))
1484 {
1485 if ($trace)
1486 {
1487 AddTrace("\tSave(deep) ignored");
1488 AddError("Save(deep) ignored since GetSiblingList could not be performed");
1489 }
1490 return false;
1491 }
1492
1493 //get all sibling classes
1494 $siblingList = array();
1495 eval("\$object = new $thisObjectName();");
1496 $object = PopulateTestValues($object);
1497 $attribute_types = $object->pog_attribute_type;
1498
1499 foreach ($attribute_types as $key => $attribute_array)
1500 {
1501 if ($attribute_array['db_attributes'][1] == "JOIN")
1502 {
1503 $siblingList[] = $key;
1504 }
1505 }
1506
1507 $errors = 0;
1508
1509 $siblingStore = array();
1510
1511 foreach ($siblingList as $sibling)
1512 {
1513 //instantiate
1514 eval("\$siblingInstance = new $sibling();");
1515 $siblingStore[] = $siblingInstance;
1516 $siblingInstance = PopulateTestValues($siblingInstance);
1517
1518 //add children
1519 eval ("\$object -> Add$sibling(\$siblingInstance);");
1520 }
1521
1522 //test
1523 if (!$object->Save(true))
1524 {
1525 $errors++;
1526 return false;
1527 }
1528
1529 foreach ($siblingList as $sibling)
1530 {
1531 //instantiate
1532 eval("\$siblingArray = \$object->Get".$sibling."List();");
1533 if (sizeof($siblingArray) == 0)
1534 {
1535 if ($trace)
1536 {
1537 AddTrace("\tSave($sibling) failed");
1538 }
1539 $errors++;
1540 }
1541 else
1542 {
1543 if ($trace)
1544 {
1545 AddTrace("\tSave($sibling)....OK!");
1546 }
1547 }
1548 }
1549
1550 //cleanup
1551 $object->Delete();
1552 foreach($siblingStore as $stored)
1553 {
1554 $stored->Delete();
1555 }
1556
1557 if ($errors == 0)
1558 {
1559 return true;
1560 }
1561 return false;
1562 }
1563
1564 /**
1565 * Unit test for Delete($deep)
1566 *
1567 * @param unknown_type $object
1568 */
1569 function TestDeleteDeep_Child($object, $trace = true, $ignoreObjects)
1570 {
1571 $thisObjectName = get_class($object);
1572 $attribute_types = $object->pog_attribute_type;
1573
1574 if (!TestSetParent($object, false, $ignoreObjects))
1575 {
1576 AddTrace("\tDelete(deep) ignored");
1577 return false;
1578 }
1579 //get all child classes
1580 $childrenList = array();
1581 foreach ($attribute_types as $key => $attribute_array)
1582 {
1583 if ($attribute_array['db_attributes'][1] == "HASMANY")
1584 {
1585 $childrenList[] = $key;
1586 }
1587 }
1588
1589 $errors = 0;
1590
1591 $object = PopulateTestValues($object);
1592 $objectId = $object->Save(false);
1593
1594
1595 $childrenStore = array();
1596 foreach ($childrenList as $child)
1597 {
1598 //instantiate
1599 eval("\$childInstance = new $child();");
1600 $childInstance = PopulateTestValues($childInstance);
1601 eval("\$childInstance -> Set".$thisObjectName."(\$object);");
1602 $childInstance -> Save();
1603 $childrenStore[] = &$childInstance;
1604 }
1605
1606 //test
1607 if (!$object->Delete(true))
1608 {
1609 $errors++;
1610 }
1611
1612 foreach ($childrenList as $child)
1613 {
1614 eval("\$childInstance = new $child();");
1615 $parentList = $childInstance->GetList(array(array(strtolower($thisObjectName)."Id", "=", $objectId)));
1616 if (sizeof($parentList) > 0)
1617 {
1618 if ($trace)
1619 {
1620 AddTrace("\tDelete($child) failed");
1621 $errors++;
1622 }
1623 }
1624 else
1625 {
1626 if ($trace)
1627 {
1628 AddTrace("\tDelete($child)....OK!");
1629 }
1630 }
1631 }
1632
1633 //cleanup
1634 foreach ($childrenStore as $child);
1635 {
1636 $child->Delete();
1637 }
1638
1639 if ($errors == 0)
1640 {
1641 return true;
1642 }
1643 return false;
1644 }
1645
1646 /**
1647 * Unit test for Delete($deep)
1648 *
1649 * @param unknown_type $object
1650 * @param unknown_type $trace
1651 */
1652 function TestDeleteDeep_Sibling($object, $trace = true, $ignoreObjects)
1653 {
1654 $thisObjectName = get_class($object);
1655 $attribute_types = $object->pog_attribute_type;
1656
1657 if (!TestAddSibling($object, false, $ignoreObjects) || !TestSaveDeep_Sibling($object, false, $ignoreObjects))
1658 {
1659 AddTrace("\tDelete(deep) ignored");
1660 return false;
1661 }
1662 //get all sibling classes
1663 $siblingList = array();
1664 foreach ($attribute_types as $key => $attribute_array)
1665 {
1666 if ($attribute_array['db_attributes'][1] == "JOIN")
1667 {
1668 $siblingList[] = $key;
1669 }
1670 }
1671
1672 $errors = 0;
1673
1674 $object = PopulateTestValues($object);
1675 $object->Save(false);
1676
1677 $siblingStore = array();
1678 foreach ($siblingList as $sibling)
1679 {
1680 //instantiate
1681 eval("\$siblingInstance = new $sibling();");
1682 $siblingInstance = PopulateTestValues($siblingInstance);
1683 eval("\$siblingInstance->Add".$thisObjectName."(\$object);");
1684 $siblingId = $siblingInstance->Save();
1685 $siblingStore[] = $siblingId;
1686 }
1687
1688 //test
1689 if (!$object->Delete(false, true))
1690 {
1691 $errors++;
1692 }
1693
1694 $x = 0;
1695 foreach ($siblingList as $sibling)
1696 {
1697 eval("\$siblingInstance = new $sibling();");
1698 $siblingLeft = $siblingInstance->GetList(array(array(strtolower($sibling)."Id", "=", $siblingStore[$x])));
1699 if (sizeof($siblingLeft) > 0)
1700 {
1701 if ($trace)
1702 {
1703 AddTrace("\tDelete($sibling) failed");
1704 $errors++;
1705 }
1706 }
1707 else
1708 {
1709 if ($trace)
1710 {
1711 AddTrace("\tDelete($sibling)....OK!");
1712 }
1713 }
1714 $x++;
1715 }
1716
1717
1718 //cleanup
1719 $object->Delete();
1720 $x = 0;
1721 foreach ($siblingList as $sibling)
1722 {
1723 eval("\$siblingInstance = new $sibling();");
1724 if (isset($siblingStore[$x]) && $siblingStore[$x] != '')
1725 {
1726 eval ("\$siblingInstance->".strtolower($sibling)."Id = ".$siblingStore[$x].";");
1727 $siblingInstance->Delete();
1728 }
1729 $x++;
1730 }
1731
1732 if ($errors == 0)
1733 {
1734 return true;
1735 }
1736 return false;
1737 }
1738
1739 /**
1740 * Unit test for SetParent()
1741 *
1742 * @param unknown_type $object
1743 */
1744 function TestSetParent($object, $trace = true, $ignoreObjects)
1745 {
1746 $thisObjectName = get_class($object);
1747 $attribute_types = $object->pog_attribute_type;
1748
1749 //get all parent classes
1750 $parentList = array();
1751 foreach ($attribute_types as $key => $attribute_array)
1752 {
1753 if ($attribute_array['db_attributes'][1] == "BELONGSTO")
1754 {
1755 $parentList[] = $key;
1756 }
1757 }
1758
1759 $errors = 0;
1760 foreach ($parentList as $parent)
1761 {
1762 //instantiate
1763 eval("\$parentInstance = new $parent();");
1764
1765 //save
1766 $parentInstance = PopulateTestValues($parentInstance);
1767 $parentInstance -> Save(false);
1768
1769 //set parent
1770 eval ("\$object -> Set$parent(\$parentInstance);");
1771
1772 eval ("\$objectId = \$object->".strtolower($parent)."Id;");
1773
1774 eval ("\$parentId = \$parentInstance->".strtolower($parent)."Id;");
1775
1776 if ($objectId != $parentId)
1777 {
1778 if ($trace)
1779 {
1780 AddTrace("\tSet$parent() failed");
1781 AddError("Could not set $parent as {Parent} of $thisObjectName");
1782 }
1783 $errors++;
1784 }
1785 else
1786 {
1787 if ($trace)
1788 {
1789 AddTrace("\tSet$parent()....OK!");
1790 }
1791 }
1792 //cleanup (delete parent)
1793 $parentInstance -> Delete(false);
1794 eval ("\$object->".strtolower($parent)."Id = '';");
1795 }
1796
1797 if ($errors == 0)
1798 {
1799 return true;
1800 }
1801 return false;
1802 }
1803
1804 /**
1805 * Unit test for GetParent()
1806 *
1807 * @param unknown_type $object
1808 */
1809 function TestGetParent($object, $ignoreObjects)
1810 {
1811 $thisObjectName = get_class($object);
1812 eval ("\$object = new $thisObjectName();");
1813
1814 $attribute_types = $object->pog_attribute_type;
1815
1816 //get all parent classes
1817 $parentList = array();
1818 foreach ($attribute_types as $key => $attribute_array)
1819 {
1820 if ($attribute_array['db_attributes'][1] == "BELONGSTO")
1821 {
1822 $parentList[] = $key;
1823 }
1824 }
1825
1826 $errors = 0;
1827
1828 foreach ($parentList as $parent)
1829 {
1830 /*if (TestSetParent($object, false))
1831 {*/
1832 //instantiate
1833 eval("\$parentInstance = new $parent();");
1834
1835 //save
1836 $parentInstance = PopulateTestValues($parentInstance);
1837 $parentInstance -> Save(false);
1838
1839
1840 //set parent
1841 eval ("\$object -> Set$parent(\$parentInstance);");
1842
1843 eval("\$myParent = \$object->Get$parent();");
1844
1845 eval ("\$objectId = \$object->".strtolower($parent)."Id;");
1846
1847 eval ("\$parentId = \$myParent->".strtolower($parent)."Id;");
1848
1849 if ($objectId != $parentId)
1850 {
1851 AddTrace("\tGet$parent() failed");
1852 AddError("Could not retrieve parent object $parent");
1853 $errors++;
1854 }
1855 else
1856 {
1857 AddTrace("\tGet$parent()....OK!");
1858 }
1859
1860 //cleanup (delete parent)
1861 $parentInstance -> Delete(false);
1862 /*}
1863 else
1864 {
1865 AddTrace("\tGet$parent() ignored");
1866 }*/
1867 }
1868 if ($errors == 0)
1869 {
1870 return true;
1871 }
1872 return false;
1873 }
1874
1875 /**
1876 * Unit test for AddChild()
1877 *
1878 * @param unknown_type $object
1879 */
1880 function TestAddChild($object, $trace = true, $ignoreObjects)
1881 {
1882 $thisObjectName = get_class($object);
1883 eval ("\$object = new $thisObjectName();");
1884 $attribute_types = $object->pog_attribute_type;
1885
1886 $object = PopulateTestValues($object);
1887
1888 //get all child classes
1889 $childrenList = array();
1890 foreach ($attribute_types as $key => $attribute_array)
1891 {
1892 if ($attribute_array['db_attributes'][1] == "HASMANY")
1893 {
1894 $childrenList[] = $key;
1895 }
1896 }
1897
1898 $errors = 0;
1899 foreach ($childrenList as $child)
1900 {
1901 //instantiate
1902 eval ("\$childInstance = new $child();");
1903 $childInstance = PopulateTestValues($childInstance);
1904
1905 //instantiate other
1906 eval("\$childInstance2 = new $child();");
1907 $childInstance2 = PopulateTestValues($childInstance2);
1908
1909 //add children
1910 eval ("\$object -> Add$child(\$childInstance);");
1911 eval ("\$object -> Add$child(\$childInstance2);");
1912
1913 //verify that children were added
1914
1915 eval ("\$children = \$object->".strtolower($child)."List;");
1916
1917 if (sizeof($children) != 2)
1918 {
1919 if ($trace)
1920 {
1921 AddTrace("\tAdd$child() failed");
1922 AddError("Could not add child object $child");
1923 }
1924 $errors++;
1925 }
1926 else
1927 {
1928 if ($trace)
1929 {
1930 AddTrace("\tAdd$child()....OK!");
1931 }
1932 }
1933 }
1934
1935 if ($errors == 0)
1936 {
1937 return true;
1938 }
1939 return false;
1940 }
1941
1942 /**
1943 * Unit test for GetChildrenList()
1944 *
1945 * @param unknown_type $object
1946 */
1947 function TestGetChildrenList($object, $trace = true, $ignoreObjects)
1948 {
1949 $thisObjectName = get_class($object);
1950 eval ("\$object = new $thisObjectName();");
1951 $attribute_types = $object->pog_attribute_type;
1952 $errors = 0;
1953
1954 //get all child classes
1955 $childrenList = array();
1956 foreach ($attribute_types as $key => $attribute_array)
1957 {
1958 if ($attribute_array['db_attributes'][1] == "HASMANY")
1959 {
1960 $childrenList[] = $key;
1961 }
1962 }
1963
1964 //save shallow
1965 $object = PopulateTestValues($object);
1966 $object->Save(false);
1967
1968
1969 foreach ($childrenList as $child)
1970 {
1971 //instantiate
1972 eval("\$childInstance = new $child();");
1973 $childInstance = PopulateTestValues($childInstance);
1974
1975 if (!TestSetParent($childInstance, false, $ignoreObjects))
1976 {
1977 AddTrace("\tGetChildrenList() ignored");
1978 return false;
1979 }
1980 eval("\$childInstance->Set".$thisObjectName."(\$object);");
1981
1982 $childInstance->Save();
1983
1984
1985
1986 //try getting all children
1987 eval ("\$children = \$object -> Get".$child."List();");
1988 if (sizeof($children) != 1)
1989 {
1990 AddTrace("\tGet".$child."List() failed");
1991 AddError("Could not get children list");
1992 $errors++;
1993 }
1994
1995 //cleanup
1996 $childInstance->Delete();
1997
1998 if ($errors == 0 && $trace)
1999 {
2000 AddTrace("\tGet".$child."List()....OK!");
2001 }
2002 }
2003
2004 $object->Delete(false);
2005
2006 if ($errors == 0)
2007 {
2008 return true;
2009 }
2010 return false;
2011 }
2012
2013 /**
2014 * Unit Test for SetChildrenList
2015 *
2016 * @param unknown_type $object
2017 * @param unknown_type $trace
2018 * @return unknown
2019 */
2020 function TestSetChildrenList($object, $trace = true, $ignoreObjects)
2021 {
2022 $thisObjectName = get_class($object);
2023 if (!TestSaveDeep_Child($object, false, $ignoreObjects))
2024 {
2025 AddTrace("\tSetChildrenList(deep) ignored");
2026 AddError("SetChildrenList ignored since SaveDeep could not be performed");
2027 return false;
2028 }
2029
2030 //get all child classes
2031 $childrenList = array();
2032 eval("\$object = new $thisObjectName();");
2033 $object = PopulateTestValues($object);
2034 $attribute_types = $object->pog_attribute_type;
2035
2036 foreach ($attribute_types as $key => $attribute_array)
2037 {
2038 if ($attribute_array['db_attributes'][1] == "HASMANY")
2039 {
2040 $childrenList[] = $key;
2041 }
2042 }
2043
2044 $errors = 0;
2045 foreach ($childrenList as $child)
2046 {
2047 //instantiate
2048 $childInstanceList = array();
2049 eval("\$childInstance = new $child();");
2050 eval("\$childInstance2 = new $child();");
2051 $childInstance = PopulateTestValues($childInstance);
2052 $childInstance2 = PopulateTestValues($childInstance2);
2053
2054 //add children to array
2055 $childInstanceList[] = $childInstance;
2056 $childInstanceList[] = $childInstance2;
2057
2058 eval ("\$object -> Set".$child."List(\$childInstanceList);");
2059 }
2060
2061 //test
2062 if (!$object->Save(true))
2063 {
2064 $errors++;
2065 return false;
2066 }
2067
2068 foreach ($childrenList as $child)
2069 {
2070 //instantiate
2071 eval("\$childArray = \$object->Get".$child."List();");
2072 if (sizeof($childArray) == 0)
2073 {
2074 AddTrace("\tSet($child)List failed");
2075 $errors++;
2076 }
2077 else
2078 {
2079 AddTrace("\tSet($child)List....OK!");
2080 }
2081 }
2082
2083 //cleanup
2084 $object->Delete(true);
2085
2086 if ($errors == 0)
2087 {
2088 return true;
2089 }
2090 return false;
2091 }
2092
2093 /**
2094 * Unit Test for AddSibling()
2095 *
2096 * @param unknown_type $object
2097 * @param unknown_type $trace
2098 * @return unknown
2099 */
2100 function TestAddSibling($object, $trace = true, $ignoreObjects)
2101 {
2102 $thisObjectName = get_class($object);
2103 eval ("\$object = new $thisObjectName();");
2104 $attribute_types = $object->pog_attribute_type;
2105
2106 $object = PopulateTestValues($object);
2107
2108 //get all sibling classes
2109 $siblingList = array();
2110 foreach ($attribute_types as $key => $attribute_array)
2111 {
2112 if ($attribute_array['db_attributes'][1] == "JOIN")
2113 {
2114 $siblingList[] = $key;
2115 }
2116 }
2117
2118 $errors = 0;
2119 foreach ($siblingList as $sibling)
2120 {
2121 //instantiate
2122 eval ("\$siblingInstance = new $sibling();");
2123 $siblingInstance = PopulateTestValues($siblingInstance);
2124
2125 //instantiate other
2126 eval("\$siblingInstance2 = new $sibling();");
2127 $siblingInstance2 = PopulateTestValues($siblingInstance2);
2128
2129 //add sibling
2130 eval ("\$object -> Add$sibling(\$siblingInstance);");
2131 eval ("\$object -> Add$sibling(\$siblingInstance2);");
2132
2133 //verify that slbings were added
2134 eval ("\$siblings = \$object->".strtolower($sibling)."List;");
2135
2136 if (sizeof($siblings) != 2)
2137 {
2138 if ($trace)
2139 {
2140 AddTrace("\tAdd$sibling() failed");
2141 AddError("Could not add sibling object $sibling");
2142 }
2143 $errors++;
2144 }
2145 else
2146 {
2147 if ($trace)
2148 {
2149 AddTrace("\tAdd$sibling()....OK!");
2150 }
2151 }
2152 }
2153
2154 if ($errors == 0)
2155 {
2156 return true;
2157 }
2158 return false;
2159 }
2160
2161 /**
2162 * Unit test for GetSiblingList()
2163 *
2164 * @param unknown_type $object
2165 * @param unknown_type $trace
2166 * @return unknown
2167 */
2168 function TestGetSiblingList($object, $trace = true, $ignoreObjects)
2169 {
2170 $thisObjectName = get_class($object);
2171 eval ("\$object = new $thisObjectName();");
2172 $attribute_types = $object->pog_attribute_type;
2173 $errors = 0;
2174
2175 //get all sibling classes
2176 $siblingList = array();
2177 foreach ($attribute_types as $key => $attribute_array)
2178 {
2179 if ($attribute_array['db_attributes'][1] == "JOIN")
2180 {
2181 $siblingList[] = $key;
2182 }
2183 }
2184
2185 $object = PopulateTestValues($object);
2186
2187 $siblingsStore = array();
2188
2189 foreach ($siblingList as $sibling)
2190 {
2191 //instantiate
2192 eval("\$siblingInstance = new $sibling();");
2193 $siblingsStore[] = $siblingInstance;
2194 $siblingInstance = PopulateTestValues($siblingInstance);
2195
2196 if (!TestAddSibling($siblingInstance, false, $ignoreObjects))
2197 {
2198 if ($trace)
2199 {
2200 AddTrace("\tGetSiblingList() ignored");
2201 }
2202 return false;
2203 }
2204 eval("\$object->Add".$sibling."(\$siblingInstance);");
2205
2206 }
2207
2208 $object->Save();
2209
2210 foreach ($siblingList as $sibling)
2211 {
2212
2213 //try getting all siblings
2214 eval ("\$siblings = \$object -> Get".$sibling."List();");
2215 if (sizeof($siblings) != 1)
2216 {
2217 if ($trace)
2218 {
2219 AddTrace("\tGet".$sibling."List() failed");
2220 AddError("Could not get sibling list");
2221 }
2222 $errors++;
2223 }
2224 else if ($trace)
2225 {
2226 AddTrace("\tGet".$sibling."List()....OK!");
2227 }
2228 }
2229
2230 foreach ($siblingsStore as $stored)
2231 {
2232 $stored->Delete();
2233 }
2234
2235 $object->Delete(false);
2236
2237 if ($errors == 0)
2238 {
2239 return true;
2240 }
2241 return false;
2242 }
2243
2244 /**
2245 * Unit test for SetSiblingList()
2246 *
2247 * @param unknown_type $object
2248 * @param unknown_type $trace
2249 */
2250 function TestSetSiblingList($object, $trace = true, $ignoreObjects)
2251 {
2252 $thisObjectName = get_class($object);
2253 if (!TestSaveDeep_Sibling($object, false, $ignoreObjects))
2254 {
2255 AddTrace("\tSetSiblingList(deep) ignored");
2256 AddError("SetSiblingList ignored since SaveDeep could not be performed");
2257 return false;
2258 }
2259
2260 //get all sibling classes
2261 $siblingList = array();
2262 eval("\$object = new $thisObjectName();");
2263 $object = PopulateTestValues($object);
2264 $attribute_types = $object->pog_attribute_type;
2265
2266 foreach ($attribute_types as $key => $attribute_array)
2267 {
2268 if ($attribute_array['db_attributes'][1] == "JOIN")
2269 {
2270 $siblingList[] = $key;
2271 }
2272 }
2273
2274 $errors = 0;
2275 foreach ($siblingList as $sibling)
2276 {
2277 //instantiate
2278 $siblingInstanceList = array();
2279 eval("\$siblingInstance = new $sibling();");
2280 eval("\$siblingInstance2 = new $sibling();");
2281 $siblingInstance = PopulateTestValues($siblingInstance);
2282 $siblingInstance2 = PopulateTestValues($siblingInstance2);
2283
2284 //add sibling to array
2285 $siblingInstanceList[] = $siblingInstance;
2286 $siblingInstanceList[] = $siblingInstance2;
2287
2288 eval ("\$object -> Set".$sibling."List(\$siblingInstanceList);");
2289 }
2290
2291 //test
2292 if (!$object->Save(true))
2293 {
2294 $errors++;
2295 return false;
2296 }
2297
2298 foreach ($siblingList as $sibling)
2299 {
2300 //instantiate
2301 eval("\$siblingArray = \$object->Get".$sibling."List();");
2302 if (sizeof($siblingArray) == 0)
2303 {
2304 if ($trace)
2305 {
2306 AddTrace("\tSet($sibling)List failed");
2307 }
2308 $errors++;
2309 }
2310 else if ($trace)
2311 {
2312 AddTrace("\tSet($sibling)List....OK!");
2313 }
2314 }
2315
2316 //cleanup
2317 $object->Delete(false, true);
2318
2319 if ($errors == 0)
2320 {
2321 return true;
2322 }
2323 return false;
2324 }
2325
2326 /**
2327 * Creates the mapping name
2328 *
2329 * @param unknown_type $objectName1
2330 * @param unknown_type $objectName2
2331 * @return unknown
2332 */
2333 function MappingName($objectName1, $objectName2)
2334 {
2335 $array = array($objectName1, $objectName2);
2336 sort($array);
2337 return implode($array)."Map";
2338 }
2339
2340 /**
2341 * Gets total no. of records;
2342 */
2343 function GetNumberOfRecords($objectName)
2344 {
2345 $sql = 'select count(*) from `'.strtolower($objectName)."`";
2346 $connection = Database::Connect();
2347 $cursor = Database::Reader($sql, $connection);
2348 if ($cursor !== false)
2349 {
2350 while($row = Database::Read($cursor))
2351 {
2352 return $row['count(*)'];
2353 }
2354 }
2355 return 0;
2356 }
2357?> \ No newline at end of file