62 files changed, 4581 insertions, 0 deletions
diff --git a/backend/php/src/setup/data_initialization/additional_table_structures.sql b/backend/php/src/setup/data_initialization/additional_table_structures.sql new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/backend/php/src/setup/data_initialization/additional_table_structures.sql diff --git a/backend/php/src/setup/data_initialization/data_initialization.sql b/backend/php/src/setup/data_initialization/data_initialization.sql new file mode 100644 index 0000000..e69de29 --- a/dev/null +++ b/backend/php/src/setup/data_initialization/data_initialization.sql diff --git a/backend/php/src/setup/data_initialization/howto.txt b/backend/php/src/setup/data_initialization/howto.txt new file mode 100644 index 0000000..a6f0e24 --- a/dev/null +++ b/backend/php/src/setup/data_initialization/howto.txt @@ -0,0 +1,13 @@ +Hello there, + +To make use of the Data Initialization feature in POG Setup, put your insert statements in the data_initialization.sql file. (One per line). +Then, on step 1 of Setup, choose "Drop, recreate tables and reset data": + +This will + +1. Drop any tables that have the same name as the object(s) you have in the objects folder. +2. Recreate the tables and indexes(if needed) +3. Execute the insert statements in data_initialization.sql one by one. + +Regards, +The POG Team
\ No newline at end of file diff --git a/backend/php/src/setup/data_initialization/read_dump_lib.php b/backend/php/src/setup/data_initialization/read_dump_lib.php new file mode 100644 index 0000000..ed579ab --- a/dev/null +++ b/backend/php/src/setup/data_initialization/read_dump_lib.php @@ -0,0 +1,205 @@ +<?php +/* $Id: read_dump.lib.php,v 2.11 2006/01/17 17:02:30 cybot_tm Exp $ */ +// vim: expandtab sw=4 ts=4 sts=4: + +/** + * Removes comment lines and splits up large sql files into individual queries + * + * Last revision: September 23, 2001 - gandon + * + * @param array the splitted sql commands + * @param string the sql commands + * @param integer the MySQL release number (because certains php3 versions + * can't get the value of a constant from within a function) + * + * @return boolean always true + * + * @access public + */ +function PMA_splitSqlFile(&$ret, $sql, $release) +{ + // do not trim, see bug #1030644 + //$sql = trim($sql); + $sql = rtrim($sql, "\n\r"); + $sql_len = strlen($sql); + $char = ''; + $string_start = ''; + $in_string = FALSE; + $nothing = TRUE; + $time0 = time(); + + for ($i = 0; $i < $sql_len; ++$i) { + $char = $sql[$i]; + + // We are in a string, check for not escaped end of strings except for + // backquotes that can't be escaped + if ($in_string) { + for (;;) { + $i = strpos($sql, $string_start, $i); + // No end of string found -> add the current substring to the + // returned array + if (!$i) { + $ret[] = array('query' => $sql, 'empty' => $nothing); + return TRUE; + } + // Backquotes or no backslashes before quotes: it's indeed the + // end of the string -> exit the loop + elseif ($string_start == '`' || $sql[$i-1] != '\\') { + $string_start = ''; + $in_string = FALSE; + break; + } + // one or more Backslashes before the presumed end of string... + else { + // ... first checks for escaped backslashes + $j = 2; + $escaped_backslash = FALSE; + while ($i-$j > 0 && $sql[$i-$j] == '\\') { + $escaped_backslash = !$escaped_backslash; + $j++; + } + // ... if escaped backslashes: it's really the end of the + // string -> exit the loop + if ($escaped_backslash) { + $string_start = ''; + $in_string = FALSE; + break; + } + // ... else loop + else { + $i++; + } + } // end if...elseif...else + } // end for + } // end if (in string) + + // lets skip comments (/*, -- and #) + elseif (($char == '-' && $sql_len > $i + 2 && $sql[$i + 1] == '-' && $sql[$i + 2] <= ' ') || $char == '#' || ($char == '/' && $sql_len > $i + 1 && $sql[$i + 1] == '*')) { + $i = strpos($sql, $char == '/' ? '*/' : "\n", $i); + // didn't we hit end of string? + if ($i === FALSE) { + break; + } + if ($char == '/') { + $i++; + } + } + + // We are not in a string, first check for delimiter... + elseif ($char == ';') { + // if delimiter found, add the parsed part to the returned array + $ret[] = array('query' => substr($sql, 0, $i), 'empty' => $nothing); + $nothing = TRUE; + $sql = ltrim(substr($sql, min($i + 1, $sql_len))); + $sql_len = strlen($sql); + if ($sql_len) { + $i = -1; + } else { + // The submited statement(s) end(s) here + return TRUE; + } + } // end elseif (is delimiter) + + // ... then check for start of a string,... + elseif (($char == '"') || ($char == '\'') || ($char == '`')) { + $in_string = TRUE; + $nothing = FALSE; + $string_start = $char; + } // end elseif (is start of string) + + elseif ($nothing) { + $nothing = FALSE; + } + + // loic1: send a fake header each 30 sec. to bypass browser timeout + $time1 = time(); + if ($time1 >= $time0 + 30) { + $time0 = $time1; + header('X-pmaPing: Pong'); + } // end if + } // end for + + // add any rest to the returned array + if (!empty($sql) && preg_match('@[^[:space:]]+@', $sql)) { + $ret[] = array('query' => $sql, 'empty' => $nothing); + } + + return TRUE; +} // end of the 'PMA_splitSqlFile()' function + + +/** + * Reads (and decompresses) a (compressed) file into a string + * + * @param string the path to the file + * @param string the MIME type of the file, if empty MIME type is autodetected + * + * @global array the phpMyAdmin configuration + * + * @return string the content of the file or + * boolean FALSE in case of an error. + */ +function PMA_readFile($path, $mime = '') { + global $cfg; + + if (!file_exists($path)) { + return FALSE; + } + switch ($mime) { + case '': + $file = @fopen($path, 'rb'); + if (!$file) { + return FALSE; + } + $test = fread($file, 3); + fclose($file); + if ($test[0] == chr(31) && $test[1] == chr(139)) { + return PMA_readFile($path, 'application/x-gzip'); + } + if ($test == 'BZh') { + return PMA_readFile($path, 'application/x-bzip'); + } + return PMA_readFile($path, 'text/plain'); + case 'text/plain': + $file = @fopen($path, 'rb'); + if (!$file) { + return FALSE; + } + $content = fread($file, filesize($path)); + fclose($file); + break; + case 'application/x-gzip': + if ($cfg['GZipDump'] && @function_exists('gzopen')) { + $file = @gzopen($path, 'rb'); + if (!$file) { + return FALSE; + } + $content = ''; + while (!gzeof($file)) { + $content .= gzgetc($file); + } + gzclose($file); + } else { + return FALSE; + } + break; + case 'application/x-bzip': + if ($cfg['BZipDump'] && @function_exists('bzdecompress')) { + $file = @fopen($path, 'rb'); + if (!$file) { + return FALSE; + } + $content = fread($file, filesize($path)); + fclose($file); + $content = bzdecompress($content); + } else { + return FALSE; + } + break; + default: + return FALSE; + } + return $content; +} + +?> diff --git a/backend/php/src/setup/index.php b/backend/php/src/setup/index.php new file mode 100644 index 0000000..4087961 --- a/dev/null +++ b/backend/php/src/setup/index.php @@ -0,0 +1,717 @@ +<?php +/** +* @author Joel Wan & Mark Slemko. Designs by Jonathan Easton +* @link http://www.phpobjectgenerator.com +* @copyright Offered under the BSD license +* +* This setup file does the following: +* 1. Checks if configuration file is present +* 2. Checks if the data in the configuration file is correct +* 3. Checks if the database and table exist +* 4. Create table if not present +* 5. Tests 5 CRUD functions and determine if everything is OK for all objects within the current directory +* 6. When all tests pass, provides an interface to the database and a way to manage objects. +*/ +if (!isset($_SESSION)) +{ + session_start(); +} +if(file_exists("../configuration.php")) +{ + include_once("../configuration.php"); +} +include_once("setup_library/authentication.php"); +include_once("setup_library/setup_misc.php"); +include_once("data_initialization/read_dump_lib.php"); +if(!isset($_SESSION['diagnosticsSuccessful']) || (isset($_GET['step']) && $_GET['step']=="diagnostics")) +{ + $_SESSION['diagnosticsSuccessful'] = false; +} +?> +<?php include "setup_library/inc.header.php";?> +<?php +ini_set("max_execution_time", 0); +if(count($_POST) > 0 && $_SESSION['diagnosticsSuccessful']==false) +{ +?> +<form action="./index.php" method="POST"> +<div class="container"> +<div class="left"> + <div class="logo2"></div> + <div class="text"><div class="gold">POG setup diagnostics</div> + <br/>Setup performs unit tests on all your objects in the object directory and makes sure they're OK. <br/>This makes sure that your objects can talk to your database correctly. This can also be useful if you modify / customize the objects manually and want to make sure they still work once you're done. + <br/><br/>The diagnostics screen on the right shows the results of those tests. If all tests pass successfully, you can be assured that all objects are working correctly. + </div> +</div> +<div class="middle"> + <div id="tabs"> + <a href="./index.php?step=diagnostics"><img src="./setup_images/tab_setup.gif"/></a> + <img src="./setup_images/tab_separator.gif"/> + <img src="./setup_images/tab_diagnosticresults_on.gif"/> + <img src="./setup_images/tab_separator.gif"/> + <img src="./setup_images/tab_manageobjects.gif"/> + <img src="./setup_images/tab_separator.gif"/> + <img src="./setup_images/tab_manageplugins_off.gif"/> + + </div><div class="subtabs"> </div><a href="./index.php?step=diagnostics"><img src="./setup_images/setup_recheck.jpg" border="0"/></a><div class="middle2"> +<?php + $errors = 0; + AddTrace('Initializing POG Setup....OK!'); + if (isset($GLOBALS['configuration']['pdoDriver'])) + { + $errors++; + AddError('POG setup for PHP4/5 objects cannot be run with a PDO configuration file. Regenerate configuration.php'); + } + else + { + /** + * verify file structure status + */ + if(!file_exists("../objects/class.database.php")) + { + $errors++; + AddError('Database wrapper (class.database.php) is missing.'); + } + else + { + include "../objects/class.database.php"; + } + if(!file_exists("../objects/class.pog_base.php")) + { + $errors++; + AddError('POG Base class (class.pog_base.php) is missing.'); + } + else + { + include "../objects/class.pog_base.php"; + } + if (!file_exists("../configuration.php")) + { + $errors++; + AddError('Configuration file (configuration.php) is missing'); + } + if ($GLOBALS['configuration']['plugins_path'] == '') + { + $errors++; + AddError('Path to plugin folder has not been specified in configuration.php'); + } + else + { + if (!file_exists($GLOBALS['configuration']['plugins_path']."/plugin.base64.php")) + { + $errors++; + AddError('Base64 plugin file (plugins/plugin.base64.php) is missing'); + } + else + { + include_once($GLOBALS['configuration']['plugins_path']."/plugin.base64.php"); + } + } + + + + //load object names to be ignored + $ignoreObjects = file("../objects/ignore_objects.txt"); + foreach ($ignoreObjects as $key=>$ignoreObject){ + $ignoreObjects[$key] = trim($ignoreObject); + } + + $dir = opendir('../objects/'); + $objects = array(); + while(($file = readdir($dir)) !== false) + { + if(strlen($file) > 4 && substr(strtolower($file), strlen($file) - 4) === '.php' && !is_dir($file) && $file != "class.database.php" && $file != "class.pog_base.php") + { + $objects[] = $file; + include_once("../objects/{$file}"); + } + } + closedir($dir); + if (sizeof($objects) == 0) + { + $errors++; + AddError("[objects] folder does not contain any POG object."); + } + + if ($errors == 0) + { + $dir = opendir($GLOBALS['configuration']['plugins_path']); + $plugins = array(); + + while(($file = readdir($dir)) !== false) + { + if(file_exists($GLOBALS['configuration']['plugins_path']."/IPlugin.php")) + { + include_once($GLOBALS['configuration']['plugins_path']."/IPlugin.php"); + } + if(strlen($file) > 4 && substr(strtolower($file), strlen($file) - 4) === '.php' && !is_dir($file) && strtolower(substr($file, 0, 6)) == 'plugin') + { + include_once($GLOBALS['configuration']['plugins_path']."/{$file}"); + $pluginName = GetPluginName($file); + if ($pluginName != '') + { + $plugins[] = $file; + } + + } + } + closedir($dir); + } + + /** + * verify configuration info + */ + if ($errors == 0) + { + AddTrace('File Structure....OK!'); + if (!@mysql_connect ($GLOBALS['configuration']['host'].":".$GLOBALS['configuration']['port'], $GLOBALS['configuration']['user'], $GLOBALS['configuration']['pass'])) + { + $errors++; + AddError('Cannot connect to the specified database server. Edit configuration.php'); + } + if (isset($GLOBALS['configuration']['db_encoding']) && $GLOBALS['configuration']['db_encoding'] == 1 && !Base64::IsBase64FunctionInstalled()) + { + $errors++; + AddError('$configuration[db_encoding] needs to be set to 0 until you install the base64 plugin. Set db_encoding to 0 by editing configuration.php, run setup again and go to the "Manage Plugins" tab. Install the base64 plugin. Then you can set db_encoding = 1'); + } + if ($errors == 0) + { + if (!@mysql_select_db ($GLOBALS['configuration']['db'])) + { + $errors++; + AddError('Cannot find the specified database "'.$GLOBALS['configuration']['db'].'". Edit configuration.php'); + } + } + } + + /** + * verify storage status + */ + + if ($errors == 0) + { + AddTrace("Configuration Info....OK!\n"); + AddTrace("Storage Status"); + foreach($objects as $object) + { + $objectName = GetObjectName("../objects/".$object); + eval ('$instance = new '.$objectName.'();'); + if (TestStorageExists($objectName, "mysql")) + { + if (isset($_POST['pog_table']) && ($_POST['pog_table'] == "recreate" || $_POST['pog_table'] == "recreate_import")) + { + if (!TestDeleteStorage($instance)) + { + $errors++; + AddError("Dropping table '".strtolower($objectName)."' failed. Drop and recreate the table manually."); + } + else + { + if (!TestCreateStorage("../objects/".$object)) + { + $errors++; + AddError("Creating table [".strtolower($objectName)."] failed. Create the table manually using the generated SQL query in the object header."); + } + else + { + AddTrace("\tDropping & Recreating table [".strtolower($objectName)."]....OK!"); + } + } + } + else + { + if (!TestAlterStorage($instance)) + { + $errors++; + AddError("Aligning [$objectName] with table '".strtolower($objectName)."' failed. Alter the table manually so that object attributes and table columns match."); + } + else + { + AddTrace("\tAligning [$objectName] with table '".strtolower($objectName)."'....OK!"); + } + } + } + else + { + if (!TestCreateStorage("../objects/".$object)) + { + $errors++; + AddError("Creating table [".strtolower($objectName)."] failed. Create the table manually using the generated SQL query in the object header."); + } + else + { + AddTrace("\tCreating table [".strtolower($objectName)."]....OK!"); + } + } + } + } + + $objectNameList = array(); + + /** + * Initialize test data? + */ + if (isset($_POST['pog_table']) && $_POST['pog_table'] == 'recreate_import') + { + $initialData = file_get_contents('data_initialization/data_initialization.sql'); + PMA_splitSqlFile($statements, $initialData, 4); + if (sizeof($statements) > 0) + { + foreach ($statements as $statement) + { + if (!TestExecuteQuery($statement['query'])) + + { + $errors++; + AddError('Statement "'.$statement['query'].'" failed'); + } + } + } + $structure_changes = file_get_contents('data_initialization/additional_table_structures.sql'); + unset($statements); + PMA_splitSqlFile($statements, $structure_changes, 4); + if (sizeof($statements) > 0) + { + foreach ($statements as $statement) + { + if (!TestExecuteQuery($statement['query'])) + + { + $errors++; + AddError('Statement "'.$statement['query'].'" failed'); + } + } + } + } + + + /** + * verify object status + */ + $objectNameList = array(); + foreach($objects as $object) + { + $objectName = GetObjectName("../objects/".$object); + if (isset($objectName) && array_search($objectName, $ignoreObjects) ===false) + { + $objectNameList[] = $objectName; + } + } + + if ($errors == 0) + { + $pluginNameList = array(); + foreach($plugins as $plugin) + { + $pluginName = GetPluginName($plugin); + if ($pluginName != '') + { + $pluginNameList[] = $pluginName; + } + } + } + + + if ($errors == 0 && isset($_POST['pog_test']) && $_POST['pog_test'] == 'yes') + { + AddTrace("\nPOG Essentials"); + + $_SESSION['links'] = array(); + + $objectCount = 1; + foreach($objects as $object) + { + $objectName = GetObjectName("../objects/".$object); + if (isset($objectName) && array_search($objectName, $ignoreObjects) ===false) + { + eval('$instance = new '.$objectName.'();'); + AddTrace("\t[".$objectName."]"); + + $link = GetAtLink("../objects/".$object); + $_SESSION['links'][$objectName] = $link; + + if (!TestEssentials($instance)) + { + $errors++; + AddError("Object $objectName failed essential tests"); + } + if ($objectCount != sizeof($objects)) + { + AddTrace("\t***"); + } + } + $objectCount++; + } + } + + + if ($errors == 0 && isset($_POST['pog_test']) && $_POST['pog_test'] == 'yes') + { + AddTrace("\nPOG Relations PreRequisites"); + $objectCount = 1; + foreach ($objects as $object) + { + $objectName = GetObjectName("../objects/".$object); + if (isset($objectName) && array_search($objectName, $ignoreObjects) ===false) + { + eval('$instance = new '.$objectName.'();'); + AddTrace("\t[".$objectName."]"); + if (!TestRelationsPreRequisites($instance, $objectNameList, $objectName, $ignoreObjects)) + { + $errors++; + } + if ($objectCount != sizeof($objects)) + { + AddTrace("\t***"); + } + } + $objectCount++; + } + } + + + if ($errors == 0 && isset($_POST['pog_test']) && $_POST['pog_test'] == 'yes') + { + AddTrace("\nPOG Relations"); + $objectCount = 1; + foreach ($objects as $object) + { + $objectName = GetObjectName("../objects/".$object); + if (isset($objectName) && array_search($objectName, $ignoreObjects) ===false) + { + eval('$instance = new '.$objectName.'();'); + AddTrace("\t[".$objectName."]"); + if (!TestRelations($instance, $objectNameList, $ignoreObjects)) + { + $errors++; + AddError("Object $objectName failed relations tests"); + } + if ($objectCount != sizeof($objects)) + { + AddTrace("\t***"); + } + } + $objectCount++; + } + } + if ($errors == 0) + { + $_SESSION['diagnosticsSuccessful'] = true; + } + if(isset($_POST['pog_test']) && $_POST['pog_test'] == 'no') + { + AddTrace("\nUNIT TESTS NOT PERFORMED. FOUND $errors ERROR(S)"); + } + else + { + AddTrace("\nCHECKED ".count($objectNameList)." OBJECT(S). FOUND $errors ERROR(S)".($errors == 0 ? ". HURRAY!" : ":")); + } + AddTrace("---------------------------------------------------"); + if (isset($_SESSION['errorMessages'])) + { + $errorMessages = unserialize($_SESSION['errorMessages']); + } + $traceMessages = unserialize($_SESSION['traceMessages']); + $diagnostics = ''; + foreach ($traceMessages as $traceMessage) + { + $diagnostics .= "\n$traceMessage"; + } + if (isset($errorMessages)) + { + foreach ($errorMessages as $errorMessage) + { + $diagnostics .= "\n$errorMessage\n"; + } + } + $_SESSION['fileNames'] = serialize($objects); + $_SESSION['objectNameList'] = serialize($objectNameList); + if (isset($pluginNameList)) + { + $_SESSION['pluginNameList'] = serialize($pluginNameList); + } + } + echo "<textarea>".$diagnostics."</textarea><br/><br/><br/></div>"; + if ($_SESSION['diagnosticsSuccessful']) + { + echo '<input type="image" src="./setup_images/setup_proceed.gif" name="submit"/>'; + } + unset($_POST, $instanceId, $_SESSION['traceMessages'], $_SESSION['errorMessages']); +?> +</div></div> +</form> +<?php +} +else if($_SESSION['diagnosticsSuccessful'] == true && (!isset($_GET['plugins']) || $_GET['plugins'] != true) ) +{ + $pluginNameList = unserialize($_SESSION['pluginNameList']); +?> +<form action="./index.php" method="POST"> +<div class="container"> + <div class="left"> + <div class="logo3"></div> + <div class="text"><div class="gold">POG documentation summary</div> + <br/><br/>The following 3 documents summarize what POG is all about:<br/><br/> + 1. <a href="http://www.phpobjectgenerator.com/plog/file_download/15">POG Essentials</a><br/><br/> + 2. <a href="http://www.phpobjectgenerator.com/plog/file_download/21">POG Object Relations</a><br/><br/> + 3. <a href="http://www.phpobjectgenerator.com/plog/file_download/18">POG SOAP API</a> + </div><!--text--> + </div><!--left--> +<div class="middle33"> + <div id="tabs3"> + <a href="./index.php?step=diagnostics"><img src="./setup_images/tab_setup.gif"/></a> + <img src="./setup_images/tab_separator.gif"/> + <img src="./setup_images/tab_diagnosticresults.gif"/> + <img src="./setup_images/tab_separator.gif"/> + <a href="./index.php"><img src="./setup_images/tab_manageobjects_on.gif"/></a> + <img src="./setup_images/tab_separator.gif"/> +<?php + if (sizeof($pluginNameList) > 0) + { +?> + <a href="./index.php?plugins=true"><img src="./setup_images/tab_manageplugins_off.gif" border="0"/></a> +<?php + } +?> + </div><!--tabs3--><div class="subtabs"> +<?php + //provide interface to the database + include "./setup_library/xPandMenu.php"; + $root = new XMenu(); + if(file_exists("configuration.php")) + { + include "../configuration.php"; + } + if(file_exists("../objects/class.database.php")) + { + include "../objects/class.database.php"; + } + + $fileNames = unserialize($_SESSION['fileNames']); + foreach($fileNames as $filename) + { + include_once("../objects/{$filename}"); + } + $objectNameList = unserialize($_SESSION['objectNameList']); + if (isset($_GET['objectName'])) + { + $_SESSION['objectName'] = $_GET['objectName']; + } + $objectName = (isset($_SESSION['objectName'])?$_SESSION['objectName']:$objectNameList[0]); + + ?> + <div id="header"> + <ul> + <li id='inactive'>My Objects:</li> + <?php + if (!isset($_SESSION['objectName'])) + { + $_SESSION['objectName'] = $objectNameList[0]; + } + for($i=0; $i<count($objectNameList); $i++) + { + $name = $objectNameList[$i]; + eval('$instance = new '.$name.'();'); + if (!TestIsMapping($instance)) + { + echo "<li ".($_SESSION['objectName']==$objectNameList[$i]?"id='current'":'')."><a href='./index.php?objectName=".$objectNameList[$i]."'>".$objectNameList[$i]."</a></li>"; + //echo "<a href='./index.php?objectName=".$objectNameList[$i]."'".(isset($_SESSION['objectName']) && $_SESSION['objectName']==$objectNameList[$i]?"class='activetab'":(!isset($_SESSION['objectName'])&&$i==0?"class='activetab'":"inactivetab")).">".$objectNameList[$i]."</a> "; + } + } + ?> + </ul> + </div><!--header--> + </div><!--subtabs--> + <div class="toolbar"><a href="<?php echo $_SESSION['links'][$_SESSION['objectName']]?>" target="_blank" title="modify and regenerate object"><img src="./setup_images/setup_regenerate.jpg" border="0"/></a><a href="#" title="Delete all objects" onclick="if (confirm('Are you sure you want to delete all objects in this table? TPress OK to Delete.')){window.location='./?thrashall=true';}else{alert('Phew, nothing was deleted ;)');}"><img src='./setup_images/setup_deleteall.jpg' alt='delete all' border="0"/></a><a href="#" onclick="javascript:expandAll();return false;" title="expand all nodes"><img src='./setup_images/setup_expandall.jpg' alt='expand all' border="0"/></a><a href="#" onclick="javascript:collapseAll();return false;" title="collapse all nodes"><img src='./setup_images/setup_collapseall.jpg' alt='collapse all' border="0"/></a><a href="#" title="update all objects to newest POG version" onclick="if (confirm('Setup will now attempt to upgrade your objects by contacting the POG SOAP server. Would you like to continue?')){window.location='./setup_library/upgrade.php';}else{alert('Upgrade aborted');}"><img src='./setup_images/setup_updateall.jpg' alt='update all objects' border='0'/></a></div><div class="middle3"> + <?php + //is there an action to perform? + if (isset($_GET['thrashall'])) + { + eval('$instance = new '.$objectName.'();'); + $instanceId = strtolower(get_class($instance))."Id"; + $instanceList = $instance->GetList(array(array($instanceId, ">", "0"))); + foreach ($instanceList as $instance) + { + $instance->Delete(); + } + unset($_GET); + } + echo '<div id="container"></div>'; + $_SESSION['fileNames'] = serialize($fileNames); + $_SESSION['objectNameList'] = serialize($objectNameList); +?> +<b class="rbottom"><b class="r4"></b><b class="r3"></b><b class="r2"></b><b class="r1"></b></b> +</div><!--middle3--> +</div><!--middle33--> +</div><!--container--> +</form> +<?php +echo "<script>sndReq('GetList', '', '$objectName', '', '', '', '$objectName');</script>"; +} +else if ($_SESSION['diagnosticsSuccessful'] && $_GET['plugins']) +{ +?> +<form action="./index.php?plugins=true" method="POST"> + <div class="container"> + <div class="left"> + <div class="logo3"></div> + <div class="text"><div class="gold">POG documentation summary</div> + <br/><br/>The following 3 documents summarize what POG is all about:<br/><br/> + 1. <a href="http://www.phpobjectgenerator.com/plog/file_download/15">POG Essentials</a><br/><br/> + 2. <a href="http://www.phpobjectgenerator.com/plog/file_download/21" target="_blank">POG Object Relations</a><br/><br/> + 3. <a href="http://www.phpobjectgenerator.com/plog/file_download/18">POG SOAP API</a> + </div><!--text--> + </div><!--left--> +<div class="middle33"> + <div id="tabs3"> + <a href="./index.php?step=diagnostics"><img src="./setup_images/tab_setup.gif"/></a> + <img src="./setup_images/tab_separator.gif"/> + <img src="./setup_images/tab_diagnosticresults.gif"/> + <img src="./setup_images/tab_separator.gif"/> + <a href="./index.php"><img src="./setup_images/tab_manageobjects.gif"/></a> + <img src="./setup_images/tab_separator.gif"/> + <img src="./setup_images/tab_manageplugins_on.gif"/> + </div><!--tabs3--><div class="subtabs"> +<?php + //provide interface to the database + include "./setup_library/xPandMenu.php"; + $root = new XMenu(); + if(file_exists("configuration.php")) + { + include "../configuration.php"; + } + if(file_exists("../objects/class.database.php")) + { + include "../objects/class.database.php"; + } + include_once('../objects/class.pog_base.php'); + if(file_exists($GLOBALS['configuration']['plugins_path']."/IPlugin.php")) + { + include_once($GLOBALS['configuration']['plugins_path'].'/IPlugin.php'); + } + $pluginNameList = unserialize($_SESSION['pluginNameList']); + foreach($pluginNameList as $pluginName) + { + include_once($GLOBALS['configuration']['plugins_path']."/plugin.".$pluginName.".php"); + } + + ?> + <div id="header"> + <ul> + <li id='inactive'>My Plugins:</li> + <?php + if (isset($_GET['pluginName'])) + { + $_SESSION['pluginName'] = $_GET['pluginName']; + } + $pluginName = (isset($_SESSION['pluginName'])?$_SESSION['pluginName']:$pluginNameList[0]); + $_SESSION['pluginName'] = $pluginName; + for($i=0; $i<count($pluginNameList); $i++) + { + $name = $pluginNameList[$i]; + echo "<li ".($_SESSION['pluginName']==$pluginNameList[$i]?"id='current'":'')."><a href='./index.php?plugins=true&pluginName=".$pluginNameList[$i]."'>".$pluginNameList[$i]."</a></li>"; + } + $pluginInstance = new $_SESSION['pluginName']('', ''); + ?> + </ul> + </div><!--header--> + </div><!--subtabs--> + <div class="toolbar"><img src="setup_images/button_toolbar_left.gif"/> + <a href='http://plugins.phpobjectgenerator.com/?id=<?=get_class($pluginInstance)?>' target="_blank"><img src="setup_images/button_toolbar_homepage.gif" border='0'/></a> + <img src="setup_images/toolbar_separator.gif"/> + <?php + if ($pluginInstance->AuthorPage() != null) + { + ?> + <a href='<?php echo $pluginInstance->AuthorPage();?>' target="_blank"><img src="setup_images/button_toolbar_author.gif" border='0'/></a> + <img src="setup_images/toolbar_separator.gif"/> + <?php + } + ?> + <a href='http://plugins.phpobjectgenerator.com/?id=<?=get_class($pluginInstance)?>&help' target="_blank"><img src="setup_images/button_toolbar_help.gif" border='0'/></a> + </div><div class="middle3"> + <?php + echo '<div id="container"><div style="padding:30px;">'; + $pluginInstance->SetupRender(); + echo '</div></div>'; + $_SESSION['pluginNameList'] = serialize($pluginNameList); +?> +<b class="rbottom"><b class="r4"></b><b class="r3"></b><b class="r2"></b><b class="r1"></b></b> +</div><!--middle3--> +</div><!--middle33--> +</div><!--container--> +</form> +<?php +} +else +{ + unset($_SESSION['objectNameList'], $_SESSION['fileNames'], $_SESSION['links'], $_SESSION['pluginNameList']); + //welcome screen +?> +<form action="./index.php" method="POST"> +<div class="container"> + <div class="left"> + <div class="logo"></div> + <div class="text"><div class="gold">What is POG Setup?</div>POG Setup is an extension of the online Php Object Generator. It is meant to help the veteran POG user and the novice alike. + <br/><br/>POG Setup is a 3 step process which:<br/><br/> + 1. Creates tables for your generated objects.<br/><br/> + 2. Performs diagnostics tests on all objects within your 'objects' directory.<br/><br/> + 3. Provides a light interface to your object tables.</div> + </div> + <div class="middle"> + <div id="tabs"> + <img src="./setup_images/tab_setup_on.gif"/> + <img src="./setup_images/tab_separator.gif" height="20px" width="17px"/> + <img src="./setup_images/tab_diagnosticresults.gif" height="20px" width="137px"/> + <img src="./setup_images/tab_separator.gif" height="20px" width="17px"/> + <img src="./setup_images/tab_manageobjects.gif" height="20px" width="129px"/> + <img src="./setup_images/tab_separator.gif"/> + <img src="./setup_images/tab_manageplugins_off.gif"/> + </div> + <div id="nifty"> + <div style="height:500px"> + <img src="./setup_images/setup_welcome.jpg" height="47px" width="617px"/> + <div class="col1"><img src="./setup_images/pog_setup_closed.jpg"/><div class="gold">What is POG?</div>POG generates PHP objects with integrated CRUD methods to dramatically accelerate web application development in PHP. <br/> + <br/>POG allows developers to easily map object attributes onto columns of a database table without having to write SQL queries.</div> + <div class="col2"><img src="./setup_images/pog_setup_open.jpg"/><div class="gold">What is POG Setup?</div>You've generated one or more objects using Php Object Generator ... Now what?<br/> + <br/>POG SETUP is an answer to this question and takes the POG experience one step further. The Setup process automates <b>table creation</b>, <b>unit testing</b> and provides a light <b>scaffolding</b> environment.</div> + <div class="col3"> + <div class="gold">If you are ready to get POG'd up, click on thebutton below to proceed. Doing this will:</div><br/> + <table> + <tr> + <td>TABLES:</td> + <td> + <select class="ss" name="pog_table"> + <option value="align">Align tables with objects (default)</option> + <option value="recreate">Recreate tables</option> + <option value="recreate_import">Recreate tables and initialize data</option> + </select> + </td> + </tr> + <tr> + <td>TESTS:</td> + <td> + <select class="ss" name="pog_test"> + <option value="yes">Perform unit tests (default)</option> + <option value="no">Bypass unit tests</option> + </select> + </td> + </tr> + </table><br/> + <br/><input type="image" onclick="PleaseWait('');" src="./setup_images/setup_pogmeup.gif" name="submit"/> + <div align="center" id="pleasewait" style="display:none;"><img src="./setup_images/loading.gif"/></div> + </div> + </div> + <b class="rbottom"><b class="r4"></b><b class="r3"></b><b class="r2"></b><b class="r1"></b></b> + </div> + </div> +</div> +</form> +<?php +} +?> +<div class="footer"> +<?php include "setup_library/inc.footer.php";?> +</div> +</body> +</html> diff --git a/backend/php/src/setup/rpc.php b/backend/php/src/setup/rpc.php new file mode 100644 index 0000000..2e2d0c1 --- a/dev/null +++ b/backend/php/src/setup/rpc.php @@ -0,0 +1,227 @@ +<?php +include "./setup_library/xPandMenu.php"; +include "./setup_library/setup_misc.php"; +if(file_exists("../configuration.php")) +{ + include_once("../configuration.php"); +} + +if(file_exists("../objects/class.database.php")) +{ + include_once("../objects/class.database.php"); +} +include_once('../objects/class.pog_base.php'); + +$objectName = isset($_REQUEST['objectname']) ? $_REQUEST['objectname'] : ''; +$anchor = isset($_REQUEST['anchor']) ? $_REQUEST['anchor'] : ''; +$offset = isset($_REQUEST['offset']) ? $_REQUEST['offset'] : ''; +$limit = isset($_REQUEST['limit']) ? $_REQUEST['limit'] : ''; + + +//include all classes (possible relations) +$dir = opendir('../objects/'); +$objects = array(); +while(($file = readdir($dir)) !== false) +{ + if(strlen($file) > 4 && substr(strtolower($file), strlen($file) - 4) === '.php' && !is_dir($file) && $file != "class.database.php" && $file != "configuration.php" && $file != "setup.php" && $file != "class.pog_base.php") + { + $objects[] = $file; + } +} +closedir($dir); +foreach ($objects as $object) +{ + include_once("../objects/{$object}"); +} + +eval ('$instance = new '.$objectName.'();'); +$attributeList = array_keys(get_object_vars($instance)); +$noOfExternalAttributes = sizeof($attributeList) - 3; + +// get object id to perform action. required for Delete() and Update() +$objectId = isset($_REQUEST['objectid']) ? $_REQUEST['objectid'] : ''; + +// get the ids of all open nodes before action is performed +$openNodes = isset($_REQUEST['opennodes']) ? explode('-', $_REQUEST['opennodes']) : ''; + +// get action to perform +$action = $_GET['action']; + +$currentNode = -1; +if (isset($_GET['currentnode'])) +{ + // get the node id on which the action is performed. required for Delete() and Update() + $currentNode = $_GET['currentnode']; + $currentNodeParts = explode('Xnode', $currentNode); + if (isset($currentNodeParts[1])) + { + $currentNode = $currentNodeParts[1]; + } +} +$root = new XMenu(); + +if ($openNodes != '') +{ + foreach ($openNodes as $openNode) + { + $openNodeParts = explode('Xtree', $openNode); + $noParts = sizeof($openNodeParts); + + // all open nodes when action is initiated + if ($noParts > 0 && is_numeric($openNodeParts[$noParts - 1])) + { + // initialize all open nodes + $root->visibleNodes[] = $openNodeParts[$noParts - 1]; + } + } +} +// perform requested action +switch($action) +{ + case 'Add': + eval ('$instance = new '.$objectName.'();'); + $attributeList = array_keys(get_object_vars($instance)); + foreach($attributeList as $attribute) + { + if ($attribute != "pog_attribute_type" && $attribute!= "pog_query") + { + if (isset($instance->pog_attribute_type[$attribute])) + { + if (isset($_GET[$attribute])) + { + $instance->{$attribute} = $_GET[$attribute]; + } + } + } + } + if ($instance->Save()) + { + for ($i = 0; $i < sizeof($root->visibleNodes); $i++) + { + if ($root->visibleNodes[$i] > ($noOfExternalAttributes + 2)) + { + $root->visibleNodes[$i] += ($noOfExternalAttributes + 1); + } + } + } + RefreshTree($anchor, $root); + break; + case 'Refresh': + RefreshTree($objectName, $root, $offset, $limit); + break; + case 'GetList': + RefreshTree($anchor, $root, $offset, $limit); + break; + case 'DeleteDeep': + case 'Delete': + eval ('$instance = new '.$objectName.'();'); + $instance->Get($objectId); + $instance->Delete(($action == 'DeleteDeep')); + for ($i = 0; $i < sizeof($root->visibleNodes); $i++) + { + if ($root->visibleNodes[$i] > ($noOfExternalAttributes + 2)) + { + if (intval($root->visibleNodes[$i]) == intval($openNodeParts[$noParts - 1])) + { + $root->visibleNodes[$i] = null; + } + else if ($root->visibleNodes[$i] > $currentNode) + { + $root->visibleNodes[$i] -= ($noOfExternalAttributes + 1); + } + } + } + RefreshTree($anchor, $root); + break; + case 'Update': + eval ('$instance = new '.$objectName.'();'); + $instance->Get($objectId); + $attributeList = array_keys(get_object_vars($instance)); + foreach($attributeList as $attribute) + { + if ($attribute != "pog_attribute_type" && $attribute!= "pog_query") + { + if (isset($instance->pog_attribute_type[$attribute])) + { + if (isset($_GET[$attribute])) + { + $instance->{$attribute} = $_GET[$attribute]; + } + } + } + } + $instance->Save(); + RefreshTree($anchor, $root); + break; + } + + /** + * Refreshes the tree after an operation while preserving node statuses + * + * @param unknown_type $objectName + * @param unknown_type $root + */ + function RefreshTree($objectName, $root, $offset = '', $limit = '') + { + if ($limit == '') + { + $offset = 0; + $limit = 50; + } + $sqlLimit = "$offset, $limit"; + + $js = "new Array("; + eval ('$instance = new '.$objectName.'();'); + $recCount = GetNumberOfRecords(strtolower($objectName)); + $attributeList = array_keys(get_object_vars($instance)); + $instanceList = $instance->GetList(array(array(strtolower($objectName)."Id",">",0)), strtolower($objectName)."Id", false, $sqlLimit); + $x = 0; + $masterNode = &$root->addItem(new XNode("<span style='color:#998D05'>".$objectName."</span> <span style='font-weight:normal'>{Dimensions:[".sizeof($instanceList)."]}</span>", false, "setup_images/folderclose.gif","setup_images/folderopen.gif")); + $node = &$masterNode->addItem(new XNode("<span style='color:#998D05'>ADD RECORD</span>", false,"setup_images/folderclose.gif","setup_images/folderopen.gif")); + foreach($attributeList as $attribute) + { + if ($attribute != "pog_attribute_type" && $attribute!= "pog_query") + { + if ($x != 0 && isset($instance->pog_attribute_type[$attribute])) + { + $js .= '"'.$attribute.'",'; + $thisValue = ConvertAttributeToHtml($attribute, $instance->pog_attribute_type[$attribute]['db_attributes'], $instance->{$attribute}, $instance->{$attributeList[0]}); + $subnode = &$node->addItem(new XNode("<br/><span style='color:#998D05'>".$attribute."</span> <span style='font-weight:normal;color:#ADA8B2;'>{".$instance->pog_attribute_type[$attribute]['db_attributes'][1]."}</span><br/>".$thisValue."<br/>", false,'',"setup_images/folderopen.gif")); + } + } + $x++; + } + $js = trim($js, ","); + $js .= ")"; + $subnode = &$node->addItem(new XNode("<br/><a href='#' onclick='javascript:sndReq(\"Add\", getOpenNodes(), \"$objectName\", \"".$instance->{strtolower($objectName).'Id'}."\", this.parentNode.parentNode.parentNode.parentNode.id, $js, \"$objectName\");return false;'><img src='./setup_images/button_add.gif' border='0'/></a>", false,'',"folderopen.gif")); + + if ($instanceList != null) + { + foreach($instanceList as $instance) + { + ConvertObjectToNode($instance, $masterNode, $js, $objectName); + } + } + + $menu_html_code = $root->generateTree(); + $menu_html_code .= "<div class='nav'>"; + $pre = "<div class='nav'>"; + if ($offset != '' && $offset != 0) + { + $pre .= "‹‹<a href='#' onclick='javascript:refTree(".($offset-$limit).", $limit, \"$objectName\");return false;'>Newer</a> | "; + $menu_html_code.= "‹‹<a href='#' onclick='javascript:refTree(".($offset-$limit).", $limit, \"$objectName\");return false;'>Newer</a> | "; + } + $pre .= "<b>".($recCount-$offset-$limit < 0 ? 0 : $recCount-$offset-$limit)." - ".($recCount-$offset)." of $recCount </b>"; + $menu_html_code .= "<b>".($recCount-$offset-$limit < 0 ? 0 : $recCount-$offset-$limit)." - ".($recCount-$offset)." of $recCount </b>"; + + if ($offset <= $recCount - $limit) + { + $pre .= "| <a href='#' onclick='javascript:refTree(".($offset+$limit).", $limit, \"$objectName\");return false;'>Older</a>››"; + $menu_html_code.= "| <a href='#' onclick='javascript:refTree(".($offset+$limit).", $limit, \"$objectName\");return false;'>Older</a>››"; + } + $menu_html_code .= "</div>"; + $pre .= "</div>"; + $table = "<div id='container'><br/><br/>".$pre.$menu_html_code."</div>"; + echo $table; + } +?> diff --git a/backend/php/src/setup/setup.css b/backend/php/src/setup/setup.css new file mode 100644 index 0000000..3c59e53 --- a/dev/null +++ b/backend/php/src/setup/setup.css @@ -0,0 +1,77 @@ +.container {background:url('./setup_images/gradient_container.gif') top left repeat-x} +.logo {width:234px;height:191px;position:relative;float:left;background:url('./setup_images/setup_logo1.jpg') top left no-repeat} +.logo2 {width:234px;height:191px;position:relative;float:left;background:url('./setup_images/setup_logo2.jpg') top left no-repeat} +.logo3 {width:234px;height:191px;position:relative;float:left;background:url('./setup_images/setup_logo3.jpg') top left no-repeat} +.bottom3 {float:left;display:inline;position:relative;width:100%;background:url('./setup_images/setup_bottom3tile.jpg') top left repeat-x} +.toolbar {float:left;display:inline;width:100%;height:42px;background-color:#444;background:url('./setup_images/setup_toolbargradient.jpg') top left repeat-x} +body {margin:0 auto;padding:0;color:#828282;background:#fff;font:normal 10px Verdana} +.activetab {font-weight:bold;color:#7B7F0E;background:#ccc} +.error {background:#f00} +.warning {background:#0cf} +.succeed {background:#0f0} +.header {width:90%;height:90px;padding:15px 0 0 15px} +.footer {width:90%;padding-left:15px;vertical-align:middle;height:35px} +.footer img {vertical-align:middle;height:35px} +.toolbar img {display:inline} +.bottom3 img {display:inline} +.left {width:234px;height:550px;z-Index:9;position:absolute;} +.text {width:194px;height:319px;line-height:15px;position:relative;float:left;padding:22px} +.gold {color:#998D05;font-weight:bold;display:block;} +.middle {width:617px;padding-left:234px;height:596px;color:#404855} +.middle2 {float:left;position:relative;padding:20px 0 0 22px;width:594px;background:#E7E9EE} +.middle33 {height:596px;position:relative;padding-left:234px;color:#404855} +.middle3 {float:left;position:relative;width:100%;background:#E7E9EE} +.subtabs {padding-top:35px;float:left;position:relative} +#tabs {width:617px;height:20px;float:left} +#tabs3 {width:100%;height:20px;float:left} +#tabs img,#tabs3 img {float:left;border:none} +.middle img,.middle input,.middle2 img,.middle2 input {display:inline;margin:0;padding:0} +a {text-decoration:none;color:#7F7714} +input.i {position:relative;padding:2px 3px;width:200px;color:#5A4F64;font-size:9px;vertical-align:middle;border-top:1px solid #404040;border-left:1px solid #404040;border-right:1px solid #D1D0CC;border-bottom:1px solid #D1D0CC; background-color:#F7F7F7;} +textarea {width:575px;height:325px;font-size:12px;border-top:1px solid #404040;border-left:1px solid #404040;border-right:1px solid #D1D0CC;border-bottom:1px solid #D1D0CC} +textarea.t {width:450px;height:50px;font-size:12px;border-top:1px solid #404040; color:#5A4F64; border-left:1px solid #404040;border-right:1px solid #D1D0CC;border-bottom:1px solid #D1D0CC; background-color:#F7F7F7;} +select.s, input.c {border-top:1px solid #404040; color:#5A4F64; border-left:1px solid #404040;border-right:1px solid #D1D0CC;border-bottom:1px solid #D1D0CC; background-color:#F7F7F7;} +.ss{font-size:95%;} +table {position:relative;display:inline;background:#E8E9EE} +td {height:25px} +.id {font-weight:bold;padding-left:5px} +div#nifty {background:#E7E9EE;margin-top:40px;position:relative;float:left;width:617px} +div.nifty{margin-top:0;background:#E7E9EE} +b.rtop,b.rbottom {display:block;background:#FFF} +b.rtop b {display:block;height:1px;overflow:hidden;background:#FFF} +b.rbottom b {display:block;height:1px;overflow:hidden;background:#E7E9EE} +b.r1 {margin:0 5px} +b.r2 {margin:0 3px} +b.r3 {margin:0 2px} +b.rtop b.r4,b.rbottom b.r4 {margin:0 1px;height:2px} +.col1,.col2 {padding-left:15px;padding-right:15px;margin-left:10px;line-height:14px;color:#848484;position:relative;width:250px;height:270px;display:inline;float:left} +.col3 {width:300px;padding-left:150px;padding-right:150px;height:190px;display:block;float:left color:#848484} +#header {float:left;width:100%;line-height:normal;} +#header ul {margin:0;padding:8px 10px 0;list-style:none;color:#818183} +#header li {float:left;background:url("norm_right.gif") no-repeat right top;margin-right:5px;padding:0} +#header a {display:block;background:url("norm_left.gif") no-repeat left top;padding:3px 8px 2px;color:#B1B97D} +#header #current {background-image:url("./setup_images/tab_activeobjectright.gif")} +#header #current a {background-image:url("./setup_images/tab_activeobjectleft.gif");padding:3px 8px 2px;font-weight:bold;color:#867C1D} +#header #inactive {padding:3px 3px 2px 5px;font-weight:bold} +a.deleteDeep:hover +{ +text-decoration:none; +background-color:#9a1818; +color:#fff; +} +a.deleteShallow:hover +{ +text-decoration:none; +background-color:#f3e508; +color:#000; +} +a.deleteCancel:hover +{ +text-decoration:none; +background-color:#bee8b6; +color:#000; +} +.nav +{ +padding-left:80px; +}
\ No newline at end of file diff --git a/backend/php/src/setup/setup_images/background_id.gif b/backend/php/src/setup/setup_images/background_id.gif Binary files differnew file mode 100644 index 0000000..363cc1c --- a/dev/null +++ b/backend/php/src/setup/setup_images/background_id.gif diff --git a/backend/php/src/setup/setup_images/button_add.gif b/backend/php/src/setup/setup_images/button_add.gif Binary files differnew file mode 100644 index 0000000..2b9fc72 --- a/dev/null +++ b/backend/php/src/setup/setup_images/button_add.gif diff --git a/backend/php/src/setup/setup_images/button_delete.gif b/backend/php/src/setup/setup_images/button_delete.gif Binary files differnew file mode 100644 index 0000000..31cc30f --- a/dev/null +++ b/backend/php/src/setup/setup_images/button_delete.gif diff --git a/backend/php/src/setup/setup_images/button_toolbar_author.gif b/backend/php/src/setup/setup_images/button_toolbar_author.gif Binary files differnew file mode 100644 index 0000000..b7f9f2b --- a/dev/null +++ b/backend/php/src/setup/setup_images/button_toolbar_author.gif diff --git a/backend/php/src/setup/setup_images/button_toolbar_help.gif b/backend/php/src/setup/setup_images/button_toolbar_help.gif Binary files differnew file mode 100644 index 0000000..324f1d4 --- a/dev/null +++ b/backend/php/src/setup/setup_images/button_toolbar_help.gif diff --git a/backend/php/src/setup/setup_images/button_toolbar_homepage.gif b/backend/php/src/setup/setup_images/button_toolbar_homepage.gif Binary files differnew file mode 100644 index 0000000..274f235 --- a/dev/null +++ b/backend/php/src/setup/setup_images/button_toolbar_homepage.gif diff --git a/backend/php/src/setup/setup_images/button_toolbar_left.gif b/backend/php/src/setup/setup_images/button_toolbar_left.gif Binary files differnew file mode 100644 index 0000000..a0bbc5f --- a/dev/null +++ b/backend/php/src/setup/setup_images/button_toolbar_left.gif diff --git a/backend/php/src/setup/setup_images/button_update.gif b/backend/php/src/setup/setup_images/button_update.gif Binary files differnew file mode 100644 index 0000000..1ee086f --- a/dev/null +++ b/backend/php/src/setup/setup_images/button_update.gif diff --git a/backend/php/src/setup/setup_images/folderclose.gif b/backend/php/src/setup/setup_images/folderclose.gif Binary files differnew file mode 100644 index 0000000..112a784 --- a/dev/null +++ b/backend/php/src/setup/setup_images/folderclose.gif diff --git a/backend/php/src/setup/setup_images/folderopen.gif b/backend/php/src/setup/setup_images/folderopen.gif Binary files differnew file mode 100644 index 0000000..443dd4e --- a/dev/null +++ b/backend/php/src/setup/setup_images/folderopen.gif diff --git a/backend/php/src/setup/setup_images/generate.jpg b/backend/php/src/setup/setup_images/generate.jpg Binary files differnew file mode 100644 index 0000000..8eb8e71 --- a/dev/null +++ b/backend/php/src/setup/setup_images/generate.jpg diff --git a/backend/php/src/setup/setup_images/gradient_container.gif b/backend/php/src/setup/setup_images/gradient_container.gif Binary files differnew file mode 100644 index 0000000..a6430f8 --- a/dev/null +++ b/backend/php/src/setup/setup_images/gradient_container.gif diff --git a/backend/php/src/setup/setup_images/loading.gif b/backend/php/src/setup/setup_images/loading.gif Binary files differnew file mode 100644 index 0000000..bf510da --- a/dev/null +++ b/backend/php/src/setup/setup_images/loading.gif diff --git a/backend/php/src/setup/setup_images/mini_pog.jpg b/backend/php/src/setup/setup_images/mini_pog.jpg Binary files differnew file mode 100644 index 0000000..3cbf683 --- a/dev/null +++ b/backend/php/src/setup/setup_images/mini_pog.jpg diff --git a/backend/php/src/setup/setup_images/pog_setup_closed.jpg b/backend/php/src/setup/setup_images/pog_setup_closed.jpg Binary files differnew file mode 100644 index 0000000..e493506 --- a/dev/null +++ b/backend/php/src/setup/setup_images/pog_setup_closed.jpg diff --git a/backend/php/src/setup/setup_images/pog_setup_open.jpg b/backend/php/src/setup/setup_images/pog_setup_open.jpg Binary files differnew file mode 100644 index 0000000..4417e8c --- a/dev/null +++ b/backend/php/src/setup/setup_images/pog_setup_open.jpg diff --git a/backend/php/src/setup/setup_images/setup_attachtables.jpg b/backend/php/src/setup/setup_images/setup_attachtables.jpg Binary files differnew file mode 100644 index 0000000..0ffeafa --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_attachtables.jpg diff --git a/backend/php/src/setup/setup_images/setup_bottom3.jpg b/backend/php/src/setup/setup_images/setup_bottom3.jpg Binary files differnew file mode 100644 index 0000000..798d96d --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_bottom3.jpg diff --git a/backend/php/src/setup/setup_images/setup_bottom3tile.jpg b/backend/php/src/setup/setup_images/setup_bottom3tile.jpg Binary files differnew file mode 100644 index 0000000..abbe75d --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_bottom3tile.jpg diff --git a/backend/php/src/setup/setup_images/setup_collapseall.jpg b/backend/php/src/setup/setup_images/setup_collapseall.jpg Binary files differnew file mode 100644 index 0000000..5a316c4 --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_collapseall.jpg diff --git a/backend/php/src/setup/setup_images/setup_deleteall.jpg b/backend/php/src/setup/setup_images/setup_deleteall.jpg Binary files differnew file mode 100644 index 0000000..f884e74 --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_deleteall.jpg diff --git a/backend/php/src/setup/setup_images/setup_expandall.jpg b/backend/php/src/setup/setup_images/setup_expandall.jpg Binary files differnew file mode 100644 index 0000000..52751dd --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_expandall.jpg diff --git a/backend/php/src/setup/setup_images/setup_footer.jpg b/backend/php/src/setup/setup_images/setup_footer.jpg Binary files differnew file mode 100644 index 0000000..4b57b24 --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_footer.jpg diff --git a/backend/php/src/setup/setup_images/setup_generateform.jpg b/backend/php/src/setup/setup_images/setup_generateform.jpg Binary files differnew file mode 100644 index 0000000..1da8733 --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_generateform.jpg diff --git a/backend/php/src/setup/setup_images/setup_logo1.jpg b/backend/php/src/setup/setup_images/setup_logo1.jpg Binary files differnew file mode 100644 index 0000000..6530570 --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_logo1.jpg diff --git a/backend/php/src/setup/setup_images/setup_logo2.jpg b/backend/php/src/setup/setup_images/setup_logo2.jpg Binary files differnew file mode 100644 index 0000000..7d05645 --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_logo2.jpg diff --git a/backend/php/src/setup/setup_images/setup_logo3.jpg b/backend/php/src/setup/setup_images/setup_logo3.jpg Binary files differnew file mode 100644 index 0000000..8d97149 --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_logo3.jpg diff --git a/backend/php/src/setup/setup_images/setup_pogmeup.gif b/backend/php/src/setup/setup_images/setup_pogmeup.gif Binary files differnew file mode 100644 index 0000000..ab95cb7 --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_pogmeup.gif diff --git a/backend/php/src/setup/setup_images/setup_proceed.gif b/backend/php/src/setup/setup_images/setup_proceed.gif Binary files differnew file mode 100644 index 0000000..878b1c2 --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_proceed.gif diff --git a/backend/php/src/setup/setup_images/setup_recheck.jpg b/backend/php/src/setup/setup_images/setup_recheck.jpg Binary files differnew file mode 100644 index 0000000..0b0bcb7 --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_recheck.jpg diff --git a/backend/php/src/setup/setup_images/setup_regenerate.jpg b/backend/php/src/setup/setup_images/setup_regenerate.jpg Binary files differnew file mode 100644 index 0000000..878d6bc --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_regenerate.jpg diff --git a/backend/php/src/setup/setup_images/setup_toolbargradient.jpg b/backend/php/src/setup/setup_images/setup_toolbargradient.jpg Binary files differnew file mode 100644 index 0000000..1a9fede --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_toolbargradient.jpg diff --git a/backend/php/src/setup/setup_images/setup_updateall.jpg b/backend/php/src/setup/setup_images/setup_updateall.jpg Binary files differnew file mode 100644 index 0000000..2b8be24 --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_updateall.jpg diff --git a/backend/php/src/setup/setup_images/setup_welcome.jpg b/backend/php/src/setup/setup_images/setup_welcome.jpg Binary files differnew file mode 100644 index 0000000..59a03e4 --- a/dev/null +++ b/backend/php/src/setup/setup_images/setup_welcome.jpg diff --git a/backend/php/src/setup/setup_images/tab_activeobjectleft.gif b/backend/php/src/setup/setup_images/tab_activeobjectleft.gif Binary files differnew file mode 100644 index 0000000..c80504a --- a/dev/null +++ b/backend/php/src/setup/setup_images/tab_activeobjectleft.gif diff --git a/backend/php/src/setup/setup_images/tab_activeobjectright.gif b/backend/php/src/setup/setup_images/tab_activeobjectright.gif Binary files differnew file mode 100644 index 0000000..646f0b0 --- a/dev/null +++ b/backend/php/src/setup/setup_images/tab_activeobjectright.gif diff --git a/backend/php/src/setup/setup_images/tab_diagnosticresults.gif b/backend/php/src/setup/setup_images/tab_diagnosticresults.gif Binary files differnew file mode 100644 index 0000000..f0e9a5b --- a/dev/null +++ b/backend/php/src/setup/setup_images/tab_diagnosticresults.gif diff --git a/backend/php/src/setup/setup_images/tab_diagnosticresults_on.gif b/backend/php/src/setup/setup_images/tab_diagnosticresults_on.gif Binary files differnew file mode 100644 index 0000000..e2b8002 --- a/dev/null +++ b/backend/php/src/setup/setup_images/tab_diagnosticresults_on.gif diff --git a/backend/php/src/setup/setup_images/tab_manageobjects.gif b/backend/php/src/setup/setup_images/tab_manageobjects.gif Binary files differnew file mode 100644 index 0000000..06b72b2 --- a/dev/null +++ b/backend/php/src/setup/setup_images/tab_manageobjects.gif diff --git a/backend/php/src/setup/setup_images/tab_manageobjects_on.gif b/backend/php/src/setup/setup_images/tab_manageobjects_on.gif Binary files differnew file mode 100644 index 0000000..55006a3 --- a/dev/null +++ b/backend/php/src/setup/setup_images/tab_manageobjects_on.gif diff --git a/backend/php/src/setup/setup_images/tab_manageplugins_off.gif b/backend/php/src/setup/setup_images/tab_manageplugins_off.gif Binary files differnew file mode 100644 index 0000000..d55f605 --- a/dev/null +++ b/backend/php/src/setup/setup_images/tab_manageplugins_off.gif diff --git a/backend/php/src/setup/setup_images/tab_manageplugins_on.gif b/backend/php/src/setup/setup_images/tab_manageplugins_on.gif Binary files differnew file mode 100644 index 0000000..1b26ee0 --- a/dev/null +++ b/backend/php/src/setup/setup_images/tab_manageplugins_on.gif diff --git a/backend/php/src/setup/setup_images/tab_separator.gif b/backend/php/src/setup/setup_images/tab_separator.gif Binary files differnew file mode 100644 index 0000000..76bb9cf --- a/dev/null +++ b/backend/php/src/setup/setup_images/tab_separator.gif diff --git a/backend/php/src/setup/setup_images/tab_setup.gif b/backend/php/src/setup/setup_images/tab_setup.gif Binary files differnew file mode 100644 index 0000000..a4a5a75 --- a/dev/null +++ b/backend/php/src/setup/setup_images/tab_setup.gif diff --git a/backend/php/src/setup/setup_images/tab_setup_on.gif b/backend/php/src/setup/setup_images/tab_setup_on.gif Binary files differnew file mode 100644 index 0000000..c3d4a41 --- a/dev/null +++ b/backend/php/src/setup/setup_images/tab_setup_on.gif diff --git a/backend/php/src/setup/setup_images/toolbar_separator.gif b/backend/php/src/setup/setup_images/toolbar_separator.gif Binary files differnew file mode 100644 index 0000000..e061b56 --- a/dev/null +++ b/backend/php/src/setup/setup_images/toolbar_separator.gif diff --git a/backend/php/src/setup/setup_library/authentication.php b/backend/php/src/setup/setup_library/authentication.php new file mode 100644 index 0000000..6a6954a --- a/dev/null +++ b/backend/php/src/setup/setup_library/authentication.php @@ -0,0 +1,30 @@ +<?php +if (sizeof($_POST) > 0 && $GLOBALS['configuration']['setup_password'] != "" && (!isset($_SESSION['authenticated']) || !$_SESSION['authenticated'])) +{ + if ($_POST['setup_password'] == $GLOBALS['configuration']['setup_password']) + { + $_SESSION['authenticated'] = true; + } + $_POST = null; +} +if ((!isset($_SESSION['authenticated']) || !$_SESSION['authenticated']) && $GLOBALS['configuration']['setup_password'] != "") +{ +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<title>Php Object Generator Setup <?=$GLOBALS['configuration']['versionNumber'].$GLOBALS['configuration']['revisionNumber']?></title> +<link rel="stylesheet" href="./setup.css" type="text/css" /> +<link rel="stylesheet" type="text/css" href="./setup_library/xPandMenu.css"/> +<div align="center"> +<form action="./index.php" method="POST"><br/> +<img src="setup_images/mini_pog.jpg"/><br/><br/> +<input name="setup_password" type="password" class="i"/> +<br/><br/><input type="image" src="setup_images/generate.jpg" name="submit"/> +</form> +</div> +</html> +<?php +exit; +} +?>
\ No newline at end of file diff --git a/backend/php/src/setup/setup_library/class.zipfile.php b/backend/php/src/setup/setup_library/class.zipfile.php new file mode 100644 index 0000000..4bbe779 --- a/dev/null +++ b/backend/php/src/setup/setup_library/class.zipfile.php @@ -0,0 +1,212 @@ +<?php + +/** + * Class to dynamically create a zip file (archive) + * + * @author Rochak Chauhan. Extended by Joel Wan & Mark Slemko + */ + +class createZip { + var $compressedData = array(); + var $centralDirectory = array(); // central directory + var $endOfCentralDirectory = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record + var $oldOffset = 0; + + /** + * Function to create the directory where the file(s) will be unzipped + * + * @param $directoryName string + * + */ + + function addDirectory($directoryName) { + $directoryName = str_replace("\\", "/", $directoryName); + + $feedArrayRow = "\x50\x4b\x03\x04"; + $feedArrayRow .= "\x0a\x00"; + $feedArrayRow .= "\x00\x00"; + $feedArrayRow .= "\x00\x00"; + $feedArrayRow .= "\x00\x00\x00\x00"; + + $feedArrayRow .= pack("V",0); + $feedArrayRow .= pack("V",0); + $feedArrayRow .= pack("V",0); + $feedArrayRow .= pack("v", strlen($directoryName) ); + $feedArrayRow .= pack("v", 0 ); + $feedArrayRow .= $directoryName; + + $feedArrayRow .= pack("V",0); + $feedArrayRow .= pack("V",0); + $feedArrayRow .= pack("V",0); + + $this -> compressedData[] = $feedArrayRow; + + $newOffset = strlen(implode("", $this->compressedData)); + + $addCentralRecord = "\x50\x4b\x01\x02"; + $addCentralRecord .="\x00\x00"; + $addCentralRecord .="\x0a\x00"; + $addCentralRecord .="\x00\x00"; + $addCentralRecord .="\x00\x00"; + $addCentralRecord .="\x00\x00\x00\x00"; + $addCentralRecord .= pack("V",0); + $addCentralRecord .= pack("V",0); + $addCentralRecord .= pack("V",0); + $addCentralRecord .= pack("v", strlen($directoryName) ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("v", 0 ); + $ext = "\x00\x00\x10\x00"; + $ext = "\xff\xff\xff\xff"; + $addCentralRecord .= pack("V", 16 ); + + $addCentralRecord .= pack("V", $this -> oldOffset ); + $this -> oldOffset = $newOffset; + + $addCentralRecord .= $directoryName; + + $this -> centralDirectory[] = $addCentralRecord; + } + + /** + * Function to add file(s) to the specified directory in the archive + * + * @param $directoryName string + * + */ + + function addFile($data, $directoryName) { + + $directoryName = str_replace("\\", "/", $directoryName); + + $feedArrayRow = "\x50\x4b\x03\x04"; + $feedArrayRow .= "\x14\x00"; + $feedArrayRow .= "\x00\x00"; + $feedArrayRow .= "\x08\x00"; + $feedArrayRow .= "\x00\x00\x00\x00"; + + $uncompressedLength = strlen($data); + $compression = crc32($data); + $gzCompressedData = gzcompress($data); + $gzCompressedData = substr( substr($gzCompressedData, 0, strlen($gzCompressedData) - 4), 2); + $compressedLength = strlen($gzCompressedData); + $feedArrayRow .= pack("V",$compression); + $feedArrayRow .= pack("V",$compressedLength); + $feedArrayRow .= pack("V",$uncompressedLength); + $feedArrayRow .= pack("v", strlen($directoryName) ); + $feedArrayRow .= pack("v", 0 ); + $feedArrayRow .= $directoryName; + + $feedArrayRow .= $gzCompressedData; + + $feedArrayRow .= pack("V",$compression); + $feedArrayRow .= pack("V",$compressedLength); + $feedArrayRow .= pack("V",$uncompressedLength); + + $this -> compressedData[] = $feedArrayRow; + + $newOffset = strlen(implode("", $this->compressedData)); + + $addCentralRecord = "\x50\x4b\x01\x02"; + $addCentralRecord .="\x00\x00"; + $addCentralRecord .="\x14\x00"; + $addCentralRecord .="\x00\x00"; + $addCentralRecord .="\x08\x00"; + $addCentralRecord .="\x00\x00\x00\x00"; + $addCentralRecord .= pack("V",$compression); + $addCentralRecord .= pack("V",$compressedLength); + $addCentralRecord .= pack("V",$uncompressedLength); + $addCentralRecord .= pack("v", strlen($directoryName) ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("v", 0 ); + $addCentralRecord .= pack("V", 32 ); + + $addCentralRecord .= pack("V", $this -> oldOffset ); + $this -> oldOffset = $newOffset; + + $addCentralRecord .= $directoryName; + + $this -> centralDirectory[] = $addCentralRecord; + } + + /** + * Fucntion to return the zip file + * + * @return zipfile (archive) + */ + + function getZippedfile() { + + $data = implode("", $this -> compressedData); + $controlDirectory = implode("", $this -> centralDirectory); + + return + $data. + $controlDirectory. + $this -> endOfCentralDirectory. + pack("v", sizeof($this -> centralDirectory)). + pack("v", sizeof($this -> centralDirectory)). + pack("V", strlen($controlDirectory)). + pack("V", strlen($data)). + "\x00\x00"; + } + + /** + * + * Function to force the download of the archive as soon as it is created + * + * @param archiveName string - name of the created archive file + */ + + function forceDownload($archiveName) { + $headerInfo = ''; + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); + header("Cache-Control: private",false); + header("Content-Type: application/zip"); + header("Content-Disposition: attachment; filename=".basename($archiveName).";" ); + header("Content-Transfer-Encoding: binary"); + echo $this->getZippedfile(); + + } + + /** + * Generates zip file from POG package. + * + * @param multi-d array $package + * @param array $paths + */ + function addPOGPackage($package, $paths=array()) + { + + $i = 0; + foreach ($package as $key=>$value) + { + $path = ''; + foreach ($paths as $p) + { + $path .= (($path == '') ? $p : "/$p"); + } + if (strpos($key, ".") == false) + { + $paths[] = $key; + $this->addDirectory((($path == '') ? "$key/" : "$path/$key/")); + $this->addPOGPackage($package[$key], &$paths); + } + else + { + $this->addFile(base64_decode($value), (($path == '') ? $key : "$path/$key")); + } + if ($i == (sizeof($package)-1)) + { + array_pop($paths); + } + $i++; + } + } +} +?>
\ No newline at end of file diff --git a/backend/php/src/setup/setup_library/inc.footer.php b/backend/php/src/setup/setup_library/inc.footer.php new file mode 100644 index 0000000..d00549d --- a/dev/null +++ b/backend/php/src/setup/setup_library/inc.footer.php @@ -0,0 +1,6 @@ +<img src="./setup_images/setup_footer.jpg"/> +<a href="http://www.phpobjectgenerator.com" title="Php Object Generator Homepage">PHP Object Generator</a> | +<a href="http://www.phpobjectgenerator.com/plog" title="Php Weblog">POG Weblog</a> | +<a href="http://groups.google.com/group/Php-Object-Generator" title="POG Google Group">Google group</a> | +<a href="http://www.phpobjectgenerator.com/plog/tutorials" title="POG Tutorials">Tutorials</a> | +<a href="mailto:pogguys@phpobjectgenerator.com" title="Contact the POG authors">Contact us</a>
\ No newline at end of file diff --git a/backend/php/src/setup/setup_library/inc.header.php b/backend/php/src/setup/setup_library/inc.header.php new file mode 100644 index 0000000..e53b36d --- a/dev/null +++ b/backend/php/src/setup/setup_library/inc.header.php @@ -0,0 +1,36 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<title>Php Object Generator Setup <?=$GLOBALS['configuration']['versionNumber'].$GLOBALS['configuration']['revisionNumber']?></title> +<link rel="stylesheet" type="text/css" href="./setup_library/xPandMenu.css"/> +<link rel="stylesheet" href="./setup.css" type="text/css" /> +<script src="./setup_library/xPandMenu.js"></script> +</head> +<body> +<div class="header"> +<script type="text/javascript"><!-- +google_ad_client = "pub-7832108692498114"; +google_alternate_color = "FFFFFF"; +google_ad_width = 728; +google_ad_height = 90; +google_ad_format = "728x90_as"; +google_ad_type = "text"; +google_ad_channel ="1767526614"; +google_color_border = "FFFFFF"; +google_color_bg = "FFFFFF"; +google_color_link = "716500"; +google_color_url = "B8B8B8"; +google_color_text = "CCC078"; +//--></script> +<script type="text/javascript" + src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> +</script> +<script type="text/javascript"><!-- +function PleaseWait(id) +{ + var div = document.getElementById("pleasewait"+id); + div.style.display = "block"; + return false; +} +//--></script> +</div>
\ No newline at end of file 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 @@ +<?php + + + /** + * Specifies what test data is used during unit testing (step 2 of the setup process) + * Todo: Can be improved but satisfatory for now + * @return array + */ + function InitializeTestValues($pog_attribute_type) + { + $DATETIME = '1997-12-15 23:50:26'; + $DATE = '1997-12-15'; + $TIMESTAMP = '1997-12-15 23:50:26'; + $TIME = '23:50:26'; + $YEAR = '1997'; + $DECIMAL = + $DOUBLE = + $FLOAT = + $BIGINT = + $INT = '12345678'; + $SMALLINT = '1234'; + $MEDIUMINT = '12345'; + $TINYINT = '1'; + $CHAR = 'L'; + $VARCHAR = + $TEXT = + $TINYBLOB = + $TINYTEXT = + $BLOB = + $MEDIUMBLOB = + $MEDIUMTEXT = + $LONGBLOB = + $BINARY= + $LONGTEXT = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry'; + $attribute_testValues = array(); + array_shift($pog_attribute_type); //get rid of objectid + foreach ($pog_attribute_type as $attribute => $property) + { + if (isset($property['db_attributes'][2])) + //length is specified, for e.g. if attribute = VARCHAR(255), $property[2]=255 + { + $limit = explode(',', $property['db_attributes'][2]); + //field is limited + if (intval($limit[0]) > 0) + { + if (isset($limit[1]) && intval($limit[1]) > 0) + { + //decimal, enum, set + $attribute_testValues[$attribute] = substr(${$property['db_attributes'][1]}, 0, ceil($limit[0]*0.6)).".".substr(${$property['db_attributes'][1]}, 0, $limit[1]); + } + else + { + $attribute_testValues[$attribute] = substr(${$property['db_attributes'][1]}, 0, ceil($limit[0] * 0.6)); + } + } + } + else + //length not specified, but we still need to account for default mysql behavior + //for eg, FLOAT(X), if X isn't specified, mysql defaults to (10,2). + { + if ($property['db_attributes'][1] == "FLOAT" || $property['db_attributes'][1] == "DOUBLE") + { + $attribute_testValues[$attribute] = "1234.56"; + } + else if ($property['db_attributes'][1] != "HASMANY" && $property['db_attributes'][1] != "BELONGSTO" && $property['db_attributes'][1] != "JOIN") + { + $attribute_testValues[$attribute] = ${$property['db_attributes'][1]}; + } + } + } + return $attribute_testValues; + } + + /** + * Specifies how object attributes are rendered during scaffolding (step 3 of the setup process) + * Todo: Can be improved but satisfactory for now + * @param string $attributeName + * @param string $attributeType + * @param string $attributeValue + * @param int $objectId + * @return string $html + */ + function ConvertAttributeToHtml($attributeName, $attributeProperties, $attributeValue='', $objectId='') + { + switch ($attributeProperties[1]) + { + case "ENUM": + $enumParts = explode(',', $attributeProperties[2]); + $html = "<select id='".($objectId != ''?$attributeName."_".$objectId:$attributeName)."' class='s'>"; + foreach ($enumParts as $enumPart) + { + if ($attributeValue == trim($enumPart, "\' ")) + { + $html .= "<option value='".trim($enumPart, "\' ")."' selected>".trim($enumPart, "\' ")."</option>"; + } + else + { + $html .= "<option value='".trim($enumPart, "\' ")."'>".trim($enumPart, "\' ")."</option>"; + } + } + $html .= "</select>"; + break; + case "HASMANY": + case "JOIN": + case "BELONGSTO": + $html = $attributeValue; + break; + case "MEDIUMBLOB": + $html = "sorry. cannot render attribute of type LONGBLOB"; + break; + case "LONGBLOB": + $html = "sorry. cannot render attribute of type LONGBLOB"; + break; + case "TEXT": + case "LONGTEXT": + case "BINARY": + case "MEDIUMTEXT": + case "TINYTEXT": + case "VARCHAR": + case "TINYBLOB": + case "BLOB": + $html = "<textarea class='t' id='".($objectId != ''?$attributeName."_".$objectId:$attributeName)."'>".($attributeValue != ''?$attributeValue:'')."</textarea>"; + break; + case "DATETIME": + case "DATE": + case "TIMESTAMP": + case "TIME": + case "YEAR": + case "DECIMAL": + case "DOUBLE": + case "FLOAT": + case "BIGINT": + case "INT": + case "YEAR": + case "SMALLINT": + case "MEDIUMINT": + case "TINYINT": + case "CHAR": + $html = "<input class='i' id='".($objectId != ''?$attributeName."_".$objectId:$attributeName)."' value='".($attributeValue != ''?$attributeValue:'')."' type='text' />"; + break; + default: + $html = substr($attributeValue, 0, 500); + if (strlen($attributeValue) > 500) + { + $html .= "..."; + } + break; + } + return $html; + } + + /** + * Renders an object as an Xtree Node + * + * @param unknown_type $child + */ + function ConvertObjectToNode(&$instance, &$masterNode, $js, $anchor, $once = false) + { + $attributeList = array_keys(get_object_vars($instance)); + $objectName = $className = get_class($instance); + $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")); + + //regular attributes + foreach($attributeList as $attribute) + { + if ($attribute != "pog_attribute_type" && $attribute!= "pog_query" ) + { + if (isset($instance->pog_attribute_type[$attribute])) + { + $thisValue = ConvertAttributeToHtml($attribute, $instance->pog_attribute_type[$attribute]['db_attributes'], $instance->{$attribute}, $instance->{$attributeList[0]}); + $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")); + } + } + } + + //parents, children and mapping + foreach ($instance->pog_attribute_type as $attribute_name => $attrubute_type) + { + if ($attrubute_type['db_attributes'][1] == "HASMANY" || $attrubute_type['db_attributes'][1] == "BELONGSTO" || $attrubute_type['db_attributes'][1] == "JOIN") + { + if ($attrubute_type['db_attributes'][1] == "BELONGSTO") + { + eval ('$value = $instance->'.strtolower($attribute_name).'Id;'); + $thisValue = ConvertAttributeToHtml($attribute_name, $attrubute_type['db_attributes'], $value, ''); + $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")); + } + else + { + $value = ''; + eval('$siblingList = $instance->Get'.ucfirst(strtolower($attribute_name)).'List();'); + if (sizeof($siblingList) > 0) + { + $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)); + $child = $siblingList[0]; + $js2 = "new Array("; + $attributeList = array_keys(get_object_vars($child)); + $x=0; + foreach($attributeList as $attribute) + { + if ($attribute != "pog_attribute_type" && $attribute!= "pog_query") + { + if ($x != 0 && isset($child->pog_attribute_type[$attribute])) + { + $js2 .= '"'.$attribute.'",'; + } + } + $x++; + } + $js2 = trim($js2, ","); + $js2 .= ")"; + + if (!$once) + { + foreach ($siblingList as $child) + { + /*$value .= $child->{strtolower($attribute_name)."Id"} . ",";*/ + if ($attrubute_type['db_attributes'][1] == "JOIN") + { + ConvertObjectToNode($child, $myNode, $js2, $anchor, true); + } + else + { + ConvertObjectToNode($child, $myNode, $js2, $anchor); + } + } + } + } + else + { + $node->addItem(new XNode("<span style='color:#4d4a4a'>[".$attribute_name."List]{Dimensions:[0]}</span><br/><br/>", false, '',"setup_images/folderopen.gif")); + } + } + } + } + $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")); + } + + + /** + * Populates object attributes with test values + * + * @param unknown_type $object + * @return unknown + */ + function PopulateTestValues(&$object) + { + $attributeList = array_keys(get_object_vars($object)); + $type_value = InitializeTestValues($object->pog_attribute_type); + + $objectName = get_class($object); + foreach($attributeList as $attribute) + { + if (isset($object->pog_attribute_type[$attribute])) + { + if (isset($type_value[$attribute])) + { + $object->{$attribute} = $type_value[$attribute]; + } + else if ($object->pog_attribute_type[$attribute]['db_attributes'][0] != "OBJECT") + { + $object->{$attribute} = "1"; + } + } + } + eval ("\$object -> ".strtolower($objectName)."Id = '';"); + return $object; + } + + /** + * Extracts @link from object file + * + * @param unknown_type $objectFilePath + * @return unknown + */ + function GetAtLink($objectFilePath) + { + $link = ''; + $content = file_get_contents($objectFilePath); + $contentParts = split("<b>",$content); + if (isset($contentParts[1])) + { + $contentParts2 = split("</b>",$contentParts[1]); + } + if (isset($contentParts2[0])) + { + $className = trim($contentParts2[0]); + } + if (isset($className)) + { + $linkParts1 = split("\*\/", $contentParts[1]); + $linkParts2 = split("\@link", $linkParts1[0]); + if (isset($linkParts2[1])) + { + $link = $linkParts2[1]; + } + if (isset($GLOBALS['configuration']['homepage']) && isset($link)) + { + $linkParts = explode('?', $link); + if (isset($linkParts[1])) + { + $link = $GLOBALS['configuration']['homepage'].'/?'.$linkParts[1]; + } + } + } + return $link; + } + + /** + * Extracts object name from object file. Do not rely on filename. + * + * @param unknown_type $objectFilePath + */ + function GetObjectName($objectFilePath) + { + $content = file_get_contents($objectFilePath); + $contentParts = split("<b>",$content); + if (isset($contentParts[1])) + { + $contentParts2 = split("</b>",$contentParts[1]); + } + if (isset($contentParts2[0])) + { + $className = trim($contentParts2[0]); + } + return $className; + } + + /** + * Gets plugin name based on filename + * + * @param unknown_type $fileName + * @return unknown + */ + function GetPluginName($fileName) + { + $fileNameParts = explode('.', $fileName); + if (strtolower($fileName) != "iplugin.php" && strtolower($fileNameParts[0]) == 'plugin' && strtolower($fileNameParts[2]) == 'php') + { + return $fileNameParts[1]; + } + return ''; + } + + /** + * Adds message to error queue + * + * @param unknown_type $error + */ + function AddError($error) + { + if (isset($_SESSION['errorMessages'])) + { + $errorMessages = unserialize($_SESSION['errorMessages']); + if (array_search($error, $errorMessages) === false) + { + $errorMessages[] = $error; + } + } + else + { + $errorMessages = array(); + $errorMessages[] = $error; + } + $_SESSION['errorMessages'] = serialize($errorMessages); + } + + /** + * Add message to tracing queue + * + * @param unknown_type $trace + */ + function AddTrace($trace) + { + if (isset($_SESSION['traceMessages'])) + { + $traceMessages = unserialize($_SESSION['traceMessages']); + $traceMessages[] = $trace; + } + else + { + $traceMessages = array(); + $traceMessages[] = $trace; + } + $_SESSION['traceMessages'] = serialize($traceMessages); + } + + /** + * Unit tests + */ + + /** + * Test the base 5 CRUD methods + * + * @param unknown_type $instance + * @return unknown + */ + function TestEssentials($instance, $optimizeAsWell = true) + { + if(TestIsMapping($instance)) + { + return true; + } + $errors = 0; + if (!TestSave($instance)) + { + $errors++; + } + if (!TestSaveNew($instance)) + { + $errors++; + } + if (!TestDelete($instance)) + { + $errors++; + } + if (!TestGetList($instance)) + { + $errors++; + } + if (!TestDeleteList($instance)) + { + $errors++; + } + if ($optimizeAsWell) + { + if (!TestOptimizeStorage(strtolower(get_class($instance)))) + { + $errors++; + } + } + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Enter description here... + * + * @param unknown_type $instance + * @return unknown + */ + function TestRelationsPreRequisites($instance, $allObjectsList, $thisObjectName, $ignoreObjects) + { + if(TestIsMapping($instance)) + { + AddTrace("\tIs Mapping (OK)"); + return true; + } + if (TestIsSingle($instance)) + { + AddTrace("\tIs single (OK)"); + return true; + } + else + { + if (!TestParentChildLink($instance, $allObjectsList, $thisObjectName, $ignoreObjects) || !TestAssociationLink($instance, $allObjectsList, $thisObjectName, $ignoreObjects)) + { + return false; + } + else + { + AddTrace("\tIs properly connected (OK)"); + return true; + } + } + } + + /** + * Test the optional object relations methods + * + * @param unknown_type $instance + * @return unknown + */ + function TestRelations($instance, $ignoreObjects) + { + $errors=0; + if (TestIsParent($instance)) + { + if (!TestAddChild($instance, true, $ignoreObjects)) + { + $errors++; + } + if (!TestGetChildrenList($instance, true, $ignoreObjects)) + { + $errors++; + } + if (!TestDeleteDeep_Child($instance, true, $ignoreObjects)) + { + $errors++; + } + if (!TestSaveDeep_Child($instance, true, $ignoreObjects)) + { + $errors++; + } + if (!TestSetChildrenList($instance, true, $ignoreObjects)) + { + $errors++; + } + } + if (TestIsChild($instance)) + { + if (!TestSetParent($instance, true, $ignoreObjects)) + { + $errors++; + } + if (!TestGetParent($instance, true, $ignoreObjects)) + { + $errors++; + } + } + if (TestIsSibling($instance)) + { + if (!TestAddSibling($instance, true, $ignoreObjects)) + { + $errors++; + } + if (!TestGetSiblingList($instance, true, $ignoreObjects)) + { + $errors++; + } + if (!TestSaveDeep_Sibling($instance, true, $ignoreObjects)) + { + $errors++; + } + if (!TestDeleteDeep_Sibling($instance, true, $ignoreObjects)) + { + $errors++; + } + if (!TestSetSiblingList($instance, true, $ignoreObjects)) + { + $errors++; + } + } + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Tests whether object table already exists + * + */ + function TestStorageExists($objectName, $databaseType = "mysql") + { + switch ($databaseType) + { + case "mysql": + $query = "show tables like '".strtolower($objectName)."'"; + break; + case "sqlite": + $query = "select name FROM sqlite_master WHERE type='table' and name='".strtolower($objectName)."'"; + break; + case "pgsql": + $query = "select table_name FROM information_schema.tables WHERE table_schema = 'public' and table_name='".strtolower($objectName)."'"; + break; + case "odbc": + //assume mssql + $query = "select * from information_schema.tables where table_type = 'BASE TABLE' and table_name='".strtolower($objectName)."'"; + break; + case "firebird": + 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."); + return true; + break; + } + + $connection = Database::Connect(); + $rows = Database::Query($query, $connection); + if ($rows > 0) + { + return true; + } + return false; + } + + /** + * Creates the table to store objects + * + */ + function TestCreateStorage($objectFilePath, $databaseType = "mysql") + { + if ($databaseType == "firebird") + { + 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."); + return true; + } + + $objectName = GetObjectName($objectFilePath); + + //extract sql + $content = file_get_contents($objectFilePath); + $contentParts = split("<b>",$content); + if (isset($contentParts[1])) + { + $contentParts2 = split("</b>",$contentParts[1]); + } + if (isset($contentParts2[0])) + { + $className = trim($contentParts2[0]); + } + if (isset($className)) + { + $sqlParts = split(";",$contentParts[0]); + $sqlPart = split("CREATE",$sqlParts[0]); + $sql = "CREATE ".$sqlPart[1].";"; + + //execute sql + $connection = Database::Connect(); + if (Database::NonQuery($sql, $connection) !== false) + { + return true; + } + } + AddError("Query failed: $sql"); + return false; + } + + /** + * Drops the table for the corresponding object + * + */ + function TestDeleteStorage($object, $databaseType = "mysql") + { + $tableName = strtolower(get_class($object)); + $connection = Database::Connect(); + if (Database::NonQuery('drop table `'.strtolower($tableName).'`', $connection) !== false) + { + return true; + } + return false; + } + + /** + * Executes an arbitrary query + * + * @param unknown_type $query + */ + function TestExecuteQuery($query) + { + $connection = Database::Connect(); + if ($query == "") + { + return true; + } + if (Database::NonQuery($query, $connection) !== false) + { + return true; + } + return false; + } + + /** + * Enter description here... + * + * @param unknown_type $object + * @return unknown + */ + function TestAlterStorage($object, $databaseType = "mysql") + { + if ($databaseType != "mysql") + { + 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."); + return true; + } + + //find object attributes/table columns mismatch + $tableName = strtolower(get_class($object)); + $columns = array(); + + $query = "describe `$tableName` "; + $connection = Database::Connect(); + $cursor = Database::Reader($query, $connection); + if ($cursor !== false) + { + while ($row = Database::Read($cursor)) + { + $columns[$row["Field"]] = $row["Type"]; + } + + $attribute_types = $object -> pog_attribute_type; + $lowerAttributes = array(); + foreach (array_keys($attribute_types) as $key) + { + $lowerAttributes[strtolower($key)] = $attribute_types[$key]; + } + + //columns to remove + $columnsToRemove = array_diff(array_keys($columns), array_keys($lowerAttributes)); + + //columns to add + $columnsToAdd = array_diff(array_keys($lowerAttributes), array_keys($columns)); + + //columns whose type has changed + $otherColumns = array_intersect(array_keys($lowerAttributes), array_keys($columns)); + + $columnsToModify = array(); + foreach ($otherColumns as $otherColumn) + { + $type = strtolower($lowerAttributes[$otherColumn]['db_attributes'][1]); + if ($type == 'enum' || $type == 'set') + { + $enumPartsObj = explode(',', strtolower($lowerAttributes[$otherColumn]['db_attributes'][2])); + $parts = explode('(',$columns[$otherColumn]); + $parts2 = explode(')',$parts[1]); + $enumpartsDb = explode(',', strtolower(trim($parts2[0]))); + foreach ($enumPartsObj as $ep) + { + if (array_search(trim($ep), $enumpartsDb) === false) + { + $type .= "(".$lowerAttributes[$otherColumn]['db_attributes'][2].")"; + $columnsToModify[$otherColumn] = $type; + break; + } + } + } + else + { + if (isset($lowerAttributes[$otherColumn]['db_attributes'][2])) + { + $type .= "(".$lowerAttributes[$otherColumn]['db_attributes'][2].")"; + } + if (strpos(strtolower($columns[$otherColumn]), $type) === false && $type != "hasmany" && $type != "join") + { + if ($type == "belongsto") + { + $columnsToModify[strtolower($otherColumn)] = "int"; + } + else + { + $columnsToModify[$otherColumn] = $type; + } + } + } + } + + $columnsToRemove2 = array(); + foreach ($columnsToRemove as $c) + { + $columnsToRemove2[] = strtolower($c); + } + + $columnsToRemove = $columnsToRemove2; + + $columnsToAdd2 = array(); + foreach ($columnsToAdd as $c) + { + if ($lowerAttributes[$c]['db_attributes'][1] != "HASMANY" && $lowerAttributes[$c]['db_attributes'][1] != "JOIN") + { + if ($lowerAttributes[$c]['db_attributes'][1] == "BELONGSTO") + { + $colMarkedForDeletion = array_search(strtolower($c)."id", $columnsToRemove); + if ($colMarkedForDeletion === false) //this is clumsy, until we think of something better + { + $columnsToAdd2[] = strtolower($c)."id int"; + } + else + { + //remove entry from columnsToRemove since they are the same. Will lose data if dropped & recreated + array_splice($columnsToRemove, $colMarkedForDeletion, 1); + } + } + else + { + $columnsToAdd2[] = $c; + } + } + } + + $common = array(); + $common = array_intersect($columnsToAdd2, $columnsToRemove); + + $columnsToAdd = array(); + foreach ($columnsToAdd2 as $col) + { + if (array_search($col, $common) === false) + { + $columnsToAdd[] = $col; + } + } + $columnsToRemove2 = array(); + foreach ($columnsToRemove as $col) + { + if (array_search($col, $common) === false) + { + $columnsToRemove2[] = $col; + } + } + + + if (sizeof($columnsToAdd) == 0 && sizeof($columnsToRemove2) == 0 && sizeof($columnsToModify) == 0) + { + return true; + } + + //construct query + $query = "alter table `$tableName` "; + + foreach ($columnsToRemove2 as $remove) + { + $query .= "drop column `$remove`,"; + } + + foreach ($columnsToAdd as $add) + { + $columnType = ''; + if (isset($lowerAttributes[$add])) + { + $columnType = strtolower($lowerAttributes[$add]['db_attributes'][1]); + } + if (isset($lowerAttributes[$add]['db_attributes'][2])) + { + $columnType .= "(".$lowerAttributes[$add]['db_attributes'][2].")"; + } + if ($columnType != '') + { + $query .= "add column `$add` $columnType,"; + } + else + { + $query .= "add column $add,"; + } + } + + + foreach (array_keys($columnsToModify) as $modify) + { + $query .= "modify `$modify` ".$columnsToModify[$modify].","; + } + $query = trim($query, ','); + //execute query + + if (Database::NonQuery($query, $connection) !== false) + { + return true; + } + } + AddError("Query failed: $query"); + return false; + } + + /** + * Optimizes the table by running mysql optimize + * + * @param unknown_type $objectName + * @return unknown + */ + function TestOptimizeStorage($objectName) + { + $connection = Database::Connect(); + if (Database::NonQuery("optimize table `".strtolower($objectName)."`", $connection) !== false) + { + AddTrace("\tOptimizing....OK!"); + return true; + } + return false; + } + + /** + * Unit test for Save() + * + */ + function TestSave($object, $trace=true) + { + $className = get_class($object); + $object = PopulateTestValues($object); + $objectId = false; + $object->{strtolower($className)."Id"} = ""; + $objectId = $object->Save(false); + + if(!$objectId) + { + if ($trace) + { + AddTrace("\tSave() failed"); + AddError("Query failed: ".$object->pog_query); + } + return false; + } + //cleanup test data + $query = "delete from `".strtolower($className)."` where ".strtolower($className)."id = '".$objectId."';"; + $connection = Database::Connect(); + Database::NonQuery($query, $connection); + if ($trace) + { + AddTrace("\tSave()....OK!"); + } + return true; + } + + /** + * Unit test for SaveNew() + * + */ + function TestSaveNew($object, $trace = true) + { + $className = get_class($object); + if(!TestSave($object, false)) + { + if ($trace) + { + AddTrace("\tSaveNew() ignored"); + } + return false; + } + $objectId = $object->SaveNew(false); + if ($objectId) + { + $query = "delete from `".strtolower($className)."` where ".strtolower($className)."Id = '".$objectId."';"; + $connection = Database::Connect(); + Database::NonQuery($query, $connection); + if ($trace) + { + AddTrace("\tSaveNew()....OK!"); + } + return true; + } + if ($trace) + { + AddTrace("\tSaveNew() failed"); + AddError("Query failed: ".$object->pog_query); + } + return false; + } + + /** + * Unit test for GetList(). Implicitly tests Get() + * + */ + function TestGetList($object, $trace = true) + { + if ($trace) + { + AddTrace("\tGetList()"); + } + $errors = 0; + if (TestSave($object,false) && TestSaveNew($object, false) && TestDelete($object, false)) + { + $className = get_class($object); + $objectList = $object->GetList(array(array(strtolower($className)."Id", ">", 0))); + $oldCount = count($objectList); + $object = PopulateTestValues($object); + $objectId = false; + $object->{strtolower($className)."Id"} = 0; + $objectId = $object->Save(false); + $objectId2 = $object->SaveNew(false); + $objectId3 = $object->SaveNew(false); + + + //Test Multiple Conditions + $objectList = $object->GetList(array(array(strtolower($className)."Id", ">=",$objectId), array(strtolower($className)."Id", "<=", $objectId+2)), strtolower($className)."Id", false, 2); + if (sizeof($objectList) != 2) + { + //Test Limit + if ($trace) + { + AddTrace("\t\tLimit failed"); + AddError('ERROR: GetList() :sizeof(list) != \$limit\n'); + AddError("Query failed: ".$object->pog_query); + } + $errors++; + } + else + { + if ($trace) + { + AddTrace("\t\tLimit....OK!"); + } + } + if ($objectList[1]->{strtolower($className)."Id"} > $objectList[0]->{strtolower($className)."Id"}) + { + //Test Sorting + if ($trace) + { + AddTrace("\t\tSorting failed"); + AddError("ERROR: GetList() :list is not properly sorted"); + AddError("Query failed: ".$object->pog_query); + } + $errors++; + } + else + { + if ($trace) + { + AddTrace("\t\tSorting....OK!"); + } + } + if ($errors == 0) + { + $objectList = $object->GetList(array(array(strtolower($className)."Id", ">=",$objectId), array(strtolower($className)."Id", "<=", $objectId+2)), strtolower($className)."Id", false, 3); + foreach ($objectList as $object) + { + $attributeList = array_keys(get_object_vars($object)); + foreach ($attributeList as $attribute) + { + if (isset($object->pog_attribute_type[$attribute])) + { + if (isset($type_value[$attribute])) + { + if ($object->{$attribute} != $type_value[$attribute]) + { + if($trace) + { + 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]."`"); + } + } + } + } + } + $object->Delete(); + } + return true; + } + else + { + if ($trace) + { + AddTrace("\tGetList() failed"); + AddError("Query failed: ".$object->pog_query); + } + return false; + } + } + if ($trace) + { + AddTrace("\tGetList() ignored"); + } + return false; + } + + /** + * Unit test for Delete() + * + */ + function TestDelete($object, $trace = true) + { + if(!TestSave($object, false)) + { + if ($trace) + { + AddTrace("\tDelete() ignored"); + } + return false; + } + $object = PopulateTestValues($object); + $object->Save(false); + if ($object->Delete(false)) + { + if ($trace) + { + AddTrace("\tDelete()....OK!"); + } + return true; + } + if ($trace) + { + AddTrace("\tDelete() failed"); + AddError("Query failed: ".$object->pog_query); + } + return false; + } + + /** + * Unit Test for DeleteList() + * + * @param unknown_type $object + * @param unknown_type $trace + */ + function TestDeleteList($object, $trace = true) + { + $className = get_class($object); + if(!TestSave($object, false) || !TestGetList($object, false)) + { + if ($trace) + { + AddTrace("\tDeleteList() ignored"); + } + return false; + } + + $object = PopulateTestValues($object); + + $originalCount = GetNumberOfRecords($className); + + $objectId = false; + $object->{strtolower($className)."Id"} = 0; + $objectId = $object->Save(false); + $objectId2 = $object->SaveNew(false); + $objectId3 = $object->SaveNew(false); + + $className = get_class($object); + $object->DeleteList(array(array(strtolower($className)."Id", "=", $objectId), array("or"), array(strtolower($className)."Id", "=", $objectId2), array("or"), array(strtolower($className)."Id", "=", $objectId3))); + + $newCount = GetNumberOfRecords($className); + + if ($newCount == $originalCount) + { + if ($trace) + { + AddTrace("\tDeleteList()....OK!"); + } + return true; + } + + if ($trace) + { + AddTrace("\tDeleteList() failed"); + AddError("Query failed: ".$object->pog_query); + } + return false; + } + + /** + * Tests whether the object is connected at all + * + * @param unknown_type $object + * @param unknown_type $allObjectsList + */ + function TestIsSingle($object) + { + $attribute_types = $object->pog_attribute_type; + + //get all child classes + $childrenList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "HASMANY") + { + $childrenList[] = $key; + } + } + + //get all parent classes + $parentsList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "BELONGSTO") + { + $parentsList[] = $key; + } + } + + //get all associations + $associationsList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "JOIN") + { + $associationsList[] = $key; + } + } + + if (sizeof($childrenList) == 0 && sizeof($parentsList) == 0 && sizeof($associationsList) == 0) + { + return true; + } + return false; + } + + /** + * Tests that all parents have children and vice-versa + * + * @param unknown_type $object + * @param unknown_type $allObjectsList + * @param unknown_type $thisObjectName + * @return unknown + */ + function TestParentChildLink($object, $allObjectsList, $thisObjectName = '', $ignoreObjects) + { + $attribute_types = $object->pog_attribute_type; + + //get all child classes + $childrenList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "HASMANY") + { + $childrenList[] = $key; + } + } + + //get all parent classes + $parentsList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "BELONGSTO") + { + $parentsList[] = $key; + } + } + + $errors = 0; + foreach ($childrenList as $child) + { + if (array_search($child, $allObjectsList) === false) + { + $errors++; + AddError("$thisObjectName refers to $child as {Child}, which couldn't be found. Generate the $child object with reference to $thisObjectName as {Parent}"); + } + else + { + //test that child refers to this object as parent + eval ("\$childInstance = new $child();"); + $childAttributes = array_keys($childInstance->pog_attribute_type); + if (array_search($thisObjectName, $childAttributes) === false) + { + $errors++; + AddError("$thisObjectName refers to $child as {Child}, but $child does not refer to $thisObjectName as {Parent}. Relations need to be reciprocal."); + } + } + } + + foreach ($parentsList as $parent) + { + if (array_search($parent, $allObjectsList) === false) + { + $errors++; + AddError("$thisObjectName refers to $parent as parent, which couldn't be found. Generate the $parent object with reference to $thisObjectName as {Child}"); + } + else + { + //test that parent refers to this object as child + eval ("\$parentInstance = new $parent();"); + $parentAttributes = array_keys($parentInstance->pog_attribute_type); + if (array_search($thisObjectName, $parentAttributes) === false) + { + $errors++; + AddError("$thisObjectName refers to $parent as {Parent}, but $parent does not refer to $thisObjectName as {Child}. Relations need to be reciprocal."); + } + } + } + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Tests that all Joins have reciprocal links + * + * @param unknown_type $object + * @param unknown_type $allObjectsList + * @param unknown_type $thisObjectName + */ + function TestAssociationLink($object, $allObjectsList, $thisObjectName = '', $ignoreObjects) + { + $attribute_types = $object->pog_attribute_type; + + //get all join classes + $associationsList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "JOIN") + { + $associationsList[] = $key; + } + } + + $errors = 0; + foreach ($associationsList as $association) + { + if (array_search($association, $allObjectsList) === false) + { + $errors++; + AddError("$thisObjectName refers to $association as {SIBLING}, which couldn't be found. Generate the $association object with reference to $thisObjectName as {SIBLING}"); + } + else + { + //test that association refers to this object as map + eval ("\$associationInstance = new $association();"); + $associationAttributes = array_keys($associationInstance->pog_attribute_type); + if (array_search($thisObjectName, $associationAttributes) === false) + { + $errors++; + AddError("$thisObjectName refers to $association as {SIBLING}, but $association does not refer to $thisObjectName as {SIBLING}. Relations need to be reciprocal."); + } + } + } + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Unit test to see if object is a parent + * + * @param unknown_type $object + */ + function TestIsParent($object) + { + $attribute_types = $object->pog_attribute_type; + foreach ($attribute_types as $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "HASMANY") + { + return true; + } + } + return false; + } + + /** + * Unit test to see if object is child + * + * @param unknown_type $object + */ + function TestIsChild($object) + { + $attribute_types = $object->pog_attribute_type; + foreach ($attribute_types as $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "BELONGSTO") + { + return true; + } + } + return false; + } + + /** + * Unit test to see if object is Sibling + * + * @param unknown_type $object + * @return unknown + */ + function TestIsSibling($object) + { + $attribute_types = $object->pog_attribute_type; + foreach ($attribute_types as $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "JOIN") + { + return true; + } + } + return false; + } + + /** + * Unit test to see if object is a Mapping object + * + * @param unknown_type $object + */ + function TestIsMapping($object) + { + $funcs = get_class_methods(get_class($object)); + foreach ($funcs as $func) + { + if (strtolower($func) == "addmapping") + { + return true; + } + } + return false; + } + + /** + * Unit test for Save($deep) + * + * @param unknown_type $object + */ + function TestSaveDeep_Child($object, $trace = true, $ignoreObjects) + { + $thisObjectName = get_class($object); + if (!TestAddChild($object, false, $ignoreObjects)) + { + if ($trace) + { + AddTrace("\tSave(deep) ignored"); + AddError("Save(deep) ignored since AddChild could not be performed"); + } + return false; + } + if (!TestGetChildrenList($object, false, $ignoreObjects)) + { + if ($trace) + { + AddTrace("\tSave(deep) ignored"); + AddError("Save(deep) ignored since GetChildrenList could not be performed"); + } + return false; + } + if (!TestDeleteDeep_Child($object, false, $ignoreObjects)) + { + if ($trace) + { + AddTrace("\tSave(deep) ignored"); + AddError("Save(deep) ignored since Delete(deep) could not be performed"); + } + return false; + } + + //get all child classes + $childrenList = array(); + eval("\$object = new $thisObjectName();"); + $object = PopulateTestValues($object); + $attribute_types = $object->pog_attribute_type; + + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "HASMANY") + { + $childrenList[] = $key; + } + } + + $errors = 0; + foreach ($childrenList as $child) + { + //instantiate + eval("\$childInstance = new $child();"); + $childInstance = PopulateTestValues($childInstance); + + //add children + eval ("\$object -> Add$child(\$childInstance);"); + } + + //test + if (!$object->Save(true)) + { + $errors++; + return false; + } + + foreach ($childrenList as $child) + { + //instantiate + eval("\$childArray = \$object->Get".$child."List();"); + if (sizeof($childArray) == 0) + { + if ($trace) + { + AddTrace("\tSave($child) failed"); + + } + $errors++; + } + else + { + if ($trace) + { + AddTrace("\tSave($child)....OK!"); + } + } + } + + //cleanup + $object->Delete(true); + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Unit test for Save($deep) + * + * @param unknown_type $object + * @return unknown + */ + function TestSaveDeep_Sibling($object, $trace = true, $ignoreObjects) + { + $thisObjectName = get_class($object); + if (!TestAddSibling($object, false, $ignoreObjects)) + { + if ($trace) + { + AddTrace("\tSave(deep) ignored"); + AddError("Save(deep) ignored since AddSibling could not be performed"); + } + return false; + } + if (!TestGetSiblingList($object, false, $ignoreObjects)) + { + if ($trace) + { + AddTrace("\tSave(deep) ignored"); + AddError("Save(deep) ignored since GetSiblingList could not be performed"); + } + return false; + } + + //get all sibling classes + $siblingList = array(); + eval("\$object = new $thisObjectName();"); + $object = PopulateTestValues($object); + $attribute_types = $object->pog_attribute_type; + + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "JOIN") + { + $siblingList[] = $key; + } + } + + $errors = 0; + + $siblingStore = array(); + + foreach ($siblingList as $sibling) + { + //instantiate + eval("\$siblingInstance = new $sibling();"); + $siblingStore[] = $siblingInstance; + $siblingInstance = PopulateTestValues($siblingInstance); + + //add children + eval ("\$object -> Add$sibling(\$siblingInstance);"); + } + + //test + if (!$object->Save(true)) + { + $errors++; + return false; + } + + foreach ($siblingList as $sibling) + { + //instantiate + eval("\$siblingArray = \$object->Get".$sibling."List();"); + if (sizeof($siblingArray) == 0) + { + if ($trace) + { + AddTrace("\tSave($sibling) failed"); + } + $errors++; + } + else + { + if ($trace) + { + AddTrace("\tSave($sibling)....OK!"); + } + } + } + + //cleanup + $object->Delete(); + foreach($siblingStore as $stored) + { + $stored->Delete(); + } + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Unit test for Delete($deep) + * + * @param unknown_type $object + */ + function TestDeleteDeep_Child($object, $trace = true, $ignoreObjects) + { + $thisObjectName = get_class($object); + $attribute_types = $object->pog_attribute_type; + + if (!TestSetParent($object, false, $ignoreObjects)) + { + AddTrace("\tDelete(deep) ignored"); + return false; + } + //get all child classes + $childrenList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "HASMANY") + { + $childrenList[] = $key; + } + } + + $errors = 0; + + $object = PopulateTestValues($object); + $objectId = $object->Save(false); + + + $childrenStore = array(); + foreach ($childrenList as $child) + { + //instantiate + eval("\$childInstance = new $child();"); + $childInstance = PopulateTestValues($childInstance); + eval("\$childInstance -> Set".$thisObjectName."(\$object);"); + $childInstance -> Save(); + $childrenStore[] = &$childInstance; + } + + //test + if (!$object->Delete(true)) + { + $errors++; + } + + foreach ($childrenList as $child) + { + eval("\$childInstance = new $child();"); + $parentList = $childInstance->GetList(array(array(strtolower($thisObjectName)."Id", "=", $objectId))); + if (sizeof($parentList) > 0) + { + if ($trace) + { + AddTrace("\tDelete($child) failed"); + $errors++; + } + } + else + { + if ($trace) + { + AddTrace("\tDelete($child)....OK!"); + } + } + } + + //cleanup + foreach ($childrenStore as $child); + { + $child->Delete(); + } + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Unit test for Delete($deep) + * + * @param unknown_type $object + * @param unknown_type $trace + */ + function TestDeleteDeep_Sibling($object, $trace = true, $ignoreObjects) + { + $thisObjectName = get_class($object); + $attribute_types = $object->pog_attribute_type; + + if (!TestAddSibling($object, false, $ignoreObjects) || !TestSaveDeep_Sibling($object, false, $ignoreObjects)) + { + AddTrace("\tDelete(deep) ignored"); + return false; + } + //get all sibling classes + $siblingList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "JOIN") + { + $siblingList[] = $key; + } + } + + $errors = 0; + + $object = PopulateTestValues($object); + $object->Save(false); + + $siblingStore = array(); + foreach ($siblingList as $sibling) + { + //instantiate + eval("\$siblingInstance = new $sibling();"); + $siblingInstance = PopulateTestValues($siblingInstance); + eval("\$siblingInstance->Add".$thisObjectName."(\$object);"); + $siblingId = $siblingInstance->Save(); + $siblingStore[] = $siblingId; + } + + //test + if (!$object->Delete(false, true)) + { + $errors++; + } + + $x = 0; + foreach ($siblingList as $sibling) + { + eval("\$siblingInstance = new $sibling();"); + $siblingLeft = $siblingInstance->GetList(array(array(strtolower($sibling)."Id", "=", $siblingStore[$x]))); + if (sizeof($siblingLeft) > 0) + { + if ($trace) + { + AddTrace("\tDelete($sibling) failed"); + $errors++; + } + } + else + { + if ($trace) + { + AddTrace("\tDelete($sibling)....OK!"); + } + } + $x++; + } + + + //cleanup + $object->Delete(); + $x = 0; + foreach ($siblingList as $sibling) + { + eval("\$siblingInstance = new $sibling();"); + if (isset($siblingStore[$x]) && $siblingStore[$x] != '') + { + eval ("\$siblingInstance->".strtolower($sibling)."Id = ".$siblingStore[$x].";"); + $siblingInstance->Delete(); + } + $x++; + } + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Unit test for SetParent() + * + * @param unknown_type $object + */ + function TestSetParent($object, $trace = true, $ignoreObjects) + { + $thisObjectName = get_class($object); + $attribute_types = $object->pog_attribute_type; + + //get all parent classes + $parentList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "BELONGSTO") + { + $parentList[] = $key; + } + } + + $errors = 0; + foreach ($parentList as $parent) + { + //instantiate + eval("\$parentInstance = new $parent();"); + + //save + $parentInstance = PopulateTestValues($parentInstance); + $parentInstance -> Save(false); + + //set parent + eval ("\$object -> Set$parent(\$parentInstance);"); + + eval ("\$objectId = \$object->".strtolower($parent)."Id;"); + + eval ("\$parentId = \$parentInstance->".strtolower($parent)."Id;"); + + if ($objectId != $parentId) + { + if ($trace) + { + AddTrace("\tSet$parent() failed"); + AddError("Could not set $parent as {Parent} of $thisObjectName"); + } + $errors++; + } + else + { + if ($trace) + { + AddTrace("\tSet$parent()....OK!"); + } + } + //cleanup (delete parent) + $parentInstance -> Delete(false); + eval ("\$object->".strtolower($parent)."Id = '';"); + } + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Unit test for GetParent() + * + * @param unknown_type $object + */ + function TestGetParent($object, $ignoreObjects) + { + $thisObjectName = get_class($object); + eval ("\$object = new $thisObjectName();"); + + $attribute_types = $object->pog_attribute_type; + + //get all parent classes + $parentList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "BELONGSTO") + { + $parentList[] = $key; + } + } + + $errors = 0; + + foreach ($parentList as $parent) + { + /*if (TestSetParent($object, false)) + {*/ + //instantiate + eval("\$parentInstance = new $parent();"); + + //save + $parentInstance = PopulateTestValues($parentInstance); + $parentInstance -> Save(false); + + + //set parent + eval ("\$object -> Set$parent(\$parentInstance);"); + + eval("\$myParent = \$object->Get$parent();"); + + eval ("\$objectId = \$object->".strtolower($parent)."Id;"); + + eval ("\$parentId = \$myParent->".strtolower($parent)."Id;"); + + if ($objectId != $parentId) + { + AddTrace("\tGet$parent() failed"); + AddError("Could not retrieve parent object $parent"); + $errors++; + } + else + { + AddTrace("\tGet$parent()....OK!"); + } + + //cleanup (delete parent) + $parentInstance -> Delete(false); + /*} + else + { + AddTrace("\tGet$parent() ignored"); + }*/ + } + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Unit test for AddChild() + * + * @param unknown_type $object + */ + function TestAddChild($object, $trace = true, $ignoreObjects) + { + $thisObjectName = get_class($object); + eval ("\$object = new $thisObjectName();"); + $attribute_types = $object->pog_attribute_type; + + $object = PopulateTestValues($object); + + //get all child classes + $childrenList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "HASMANY") + { + $childrenList[] = $key; + } + } + + $errors = 0; + foreach ($childrenList as $child) + { + //instantiate + eval ("\$childInstance = new $child();"); + $childInstance = PopulateTestValues($childInstance); + + //instantiate other + eval("\$childInstance2 = new $child();"); + $childInstance2 = PopulateTestValues($childInstance2); + + //add children + eval ("\$object -> Add$child(\$childInstance);"); + eval ("\$object -> Add$child(\$childInstance2);"); + + //verify that children were added + + eval ("\$children = \$object->".strtolower($child)."List;"); + + if (sizeof($children) != 2) + { + if ($trace) + { + AddTrace("\tAdd$child() failed"); + AddError("Could not add child object $child"); + } + $errors++; + } + else + { + if ($trace) + { + AddTrace("\tAdd$child()....OK!"); + } + } + } + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Unit test for GetChildrenList() + * + * @param unknown_type $object + */ + function TestGetChildrenList($object, $trace = true, $ignoreObjects) + { + $thisObjectName = get_class($object); + eval ("\$object = new $thisObjectName();"); + $attribute_types = $object->pog_attribute_type; + $errors = 0; + + //get all child classes + $childrenList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "HASMANY") + { + $childrenList[] = $key; + } + } + + //save shallow + $object = PopulateTestValues($object); + $object->Save(false); + + + foreach ($childrenList as $child) + { + //instantiate + eval("\$childInstance = new $child();"); + $childInstance = PopulateTestValues($childInstance); + + if (!TestSetParent($childInstance, false, $ignoreObjects)) + { + AddTrace("\tGetChildrenList() ignored"); + return false; + } + eval("\$childInstance->Set".$thisObjectName."(\$object);"); + + $childInstance->Save(); + + + + //try getting all children + eval ("\$children = \$object -> Get".$child."List();"); + if (sizeof($children) != 1) + { + AddTrace("\tGet".$child."List() failed"); + AddError("Could not get children list"); + $errors++; + } + + //cleanup + $childInstance->Delete(); + + if ($errors == 0 && $trace) + { + AddTrace("\tGet".$child."List()....OK!"); + } + } + + $object->Delete(false); + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Unit Test for SetChildrenList + * + * @param unknown_type $object + * @param unknown_type $trace + * @return unknown + */ + function TestSetChildrenList($object, $trace = true, $ignoreObjects) + { + $thisObjectName = get_class($object); + if (!TestSaveDeep_Child($object, false, $ignoreObjects)) + { + AddTrace("\tSetChildrenList(deep) ignored"); + AddError("SetChildrenList ignored since SaveDeep could not be performed"); + return false; + } + + //get all child classes + $childrenList = array(); + eval("\$object = new $thisObjectName();"); + $object = PopulateTestValues($object); + $attribute_types = $object->pog_attribute_type; + + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "HASMANY") + { + $childrenList[] = $key; + } + } + + $errors = 0; + foreach ($childrenList as $child) + { + //instantiate + $childInstanceList = array(); + eval("\$childInstance = new $child();"); + eval("\$childInstance2 = new $child();"); + $childInstance = PopulateTestValues($childInstance); + $childInstance2 = PopulateTestValues($childInstance2); + + //add children to array + $childInstanceList[] = $childInstance; + $childInstanceList[] = $childInstance2; + + eval ("\$object -> Set".$child."List(\$childInstanceList);"); + } + + //test + if (!$object->Save(true)) + { + $errors++; + return false; + } + + foreach ($childrenList as $child) + { + //instantiate + eval("\$childArray = \$object->Get".$child."List();"); + if (sizeof($childArray) == 0) + { + AddTrace("\tSet($child)List failed"); + $errors++; + } + else + { + AddTrace("\tSet($child)List....OK!"); + } + } + + //cleanup + $object->Delete(true); + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Unit Test for AddSibling() + * + * @param unknown_type $object + * @param unknown_type $trace + * @return unknown + */ + function TestAddSibling($object, $trace = true, $ignoreObjects) + { + $thisObjectName = get_class($object); + eval ("\$object = new $thisObjectName();"); + $attribute_types = $object->pog_attribute_type; + + $object = PopulateTestValues($object); + + //get all sibling classes + $siblingList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "JOIN") + { + $siblingList[] = $key; + } + } + + $errors = 0; + foreach ($siblingList as $sibling) + { + //instantiate + eval ("\$siblingInstance = new $sibling();"); + $siblingInstance = PopulateTestValues($siblingInstance); + + //instantiate other + eval("\$siblingInstance2 = new $sibling();"); + $siblingInstance2 = PopulateTestValues($siblingInstance2); + + //add sibling + eval ("\$object -> Add$sibling(\$siblingInstance);"); + eval ("\$object -> Add$sibling(\$siblingInstance2);"); + + //verify that slbings were added + eval ("\$siblings = \$object->".strtolower($sibling)."List;"); + + if (sizeof($siblings) != 2) + { + if ($trace) + { + AddTrace("\tAdd$sibling() failed"); + AddError("Could not add sibling object $sibling"); + } + $errors++; + } + else + { + if ($trace) + { + AddTrace("\tAdd$sibling()....OK!"); + } + } + } + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Unit test for GetSiblingList() + * + * @param unknown_type $object + * @param unknown_type $trace + * @return unknown + */ + function TestGetSiblingList($object, $trace = true, $ignoreObjects) + { + $thisObjectName = get_class($object); + eval ("\$object = new $thisObjectName();"); + $attribute_types = $object->pog_attribute_type; + $errors = 0; + + //get all sibling classes + $siblingList = array(); + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "JOIN") + { + $siblingList[] = $key; + } + } + + $object = PopulateTestValues($object); + + $siblingsStore = array(); + + foreach ($siblingList as $sibling) + { + //instantiate + eval("\$siblingInstance = new $sibling();"); + $siblingsStore[] = $siblingInstance; + $siblingInstance = PopulateTestValues($siblingInstance); + + if (!TestAddSibling($siblingInstance, false, $ignoreObjects)) + { + if ($trace) + { + AddTrace("\tGetSiblingList() ignored"); + } + return false; + } + eval("\$object->Add".$sibling."(\$siblingInstance);"); + + } + + $object->Save(); + + foreach ($siblingList as $sibling) + { + + //try getting all siblings + eval ("\$siblings = \$object -> Get".$sibling."List();"); + if (sizeof($siblings) != 1) + { + if ($trace) + { + AddTrace("\tGet".$sibling."List() failed"); + AddError("Could not get sibling list"); + } + $errors++; + } + else if ($trace) + { + AddTrace("\tGet".$sibling."List()....OK!"); + } + } + + foreach ($siblingsStore as $stored) + { + $stored->Delete(); + } + + $object->Delete(false); + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Unit test for SetSiblingList() + * + * @param unknown_type $object + * @param unknown_type $trace + */ + function TestSetSiblingList($object, $trace = true, $ignoreObjects) + { + $thisObjectName = get_class($object); + if (!TestSaveDeep_Sibling($object, false, $ignoreObjects)) + { + AddTrace("\tSetSiblingList(deep) ignored"); + AddError("SetSiblingList ignored since SaveDeep could not be performed"); + return false; + } + + //get all sibling classes + $siblingList = array(); + eval("\$object = new $thisObjectName();"); + $object = PopulateTestValues($object); + $attribute_types = $object->pog_attribute_type; + + foreach ($attribute_types as $key => $attribute_array) + { + if ($attribute_array['db_attributes'][1] == "JOIN") + { + $siblingList[] = $key; + } + } + + $errors = 0; + foreach ($siblingList as $sibling) + { + //instantiate + $siblingInstanceList = array(); + eval("\$siblingInstance = new $sibling();"); + eval("\$siblingInstance2 = new $sibling();"); + $siblingInstance = PopulateTestValues($siblingInstance); + $siblingInstance2 = PopulateTestValues($siblingInstance2); + + //add sibling to array + $siblingInstanceList[] = $siblingInstance; + $siblingInstanceList[] = $siblingInstance2; + + eval ("\$object -> Set".$sibling."List(\$siblingInstanceList);"); + } + + //test + if (!$object->Save(true)) + { + $errors++; + return false; + } + + foreach ($siblingList as $sibling) + { + //instantiate + eval("\$siblingArray = \$object->Get".$sibling."List();"); + if (sizeof($siblingArray) == 0) + { + if ($trace) + { + AddTrace("\tSet($sibling)List failed"); + } + $errors++; + } + else if ($trace) + { + AddTrace("\tSet($sibling)List....OK!"); + } + } + + //cleanup + $object->Delete(false, true); + + if ($errors == 0) + { + return true; + } + return false; + } + + /** + * Creates the mapping name + * + * @param unknown_type $objectName1 + * @param unknown_type $objectName2 + * @return unknown + */ + function MappingName($objectName1, $objectName2) + { + $array = array($objectName1, $objectName2); + sort($array); + return implode($array)."Map"; + } + + /** + * Gets total no. of records; + */ + function GetNumberOfRecords($objectName) + { + $sql = 'select count(*) from `'.strtolower($objectName)."`"; + $connection = Database::Connect(); + $cursor = Database::Reader($sql, $connection); + if ($cursor !== false) + { + while($row = Database::Read($cursor)) + { + return $row['count(*)']; + } + } + return 0; + } +?>
\ No newline at end of file diff --git a/backend/php/src/setup/setup_library/upgrade.php b/backend/php/src/setup/setup_library/upgrade.php new file mode 100644 index 0000000..122da58 --- a/dev/null +++ b/backend/php/src/setup/setup_library/upgrade.php @@ -0,0 +1,140 @@ +<?php +/** +* @author Joel Wan & Mark Slemko. Designs by Jonathan Easton +* @link http://www.phpobjectgenerator.com +* @copyright Offered under the BSD license +* +* This upgrade file does the following: +* 1. Checks if there is a new version of POG +* 2. If there is, it reads generates newer versions of all objects in the object directory, +* zip then and present them to the user to 'download' +*/ +ini_set("max_execution_time", 0); +include_once "../../configuration.php"; +include_once "class.zipfile.php"; +include_once "setup_misc.php"; + + /** + * Connects to POG SOAP server defined in configuration.php and + * generates new versions of all objects detected in /objects/ dir. + * All upgraded objects are then zipped and presented to user. + * + * @param string $path + */ + function UpdateAllObjects($path) + { + $dir = opendir($path); + $objects = array(); + while(($file = readdir($dir)) !== false) + { + if(strlen($file) > 4 && substr(strtolower($file), strlen($file) - 4) === '.php' && !is_dir($file) && $file != "class.database.php" && $file != "configuration.php" && $file != "setup.php" && $file != "class.pog_base.php") + { + $objects[] = $file; + } + } + closedir($dir); + $i = 0; + foreach($objects as $object) + { + $content = file_get_contents($path."/".$object); + $contentParts = split("<b>",$content); + if (isset($contentParts[1])) + { + $contentParts2 = split("</b>",$contentParts[1]); + } + if (isset($contentParts2[0])) + { + $className = trim($contentParts2[0]); + } + if (isset($className)) + { + eval ('include_once("../../objects/class.'.strtolower($className).'.php");'); + $instance = new $className(); + if (!TestIsMapping($instance)) + { + $objectNameList[] = $className; + + $linkParts1 = split("\*\/", $contentParts[1]); + $linkParts2 = split("\@link", $linkParts1[0]); + $link = $linkParts2[1]; + $options = false; + if ($GLOBALS['configuration']['proxy_host'] != false && + $GLOBALS['configuration']['proxy_port'] != false && + $GLOBALS['configuration']['proxy_username'] != false && + $GLOBALS['configuration']['proxy_password'] != false) + { + $options = array( + 'proxy_host' => $GLOBALS['configuration']['proxy_host'], + 'proxy_port' => $GLOBALS['configuration']['proxy_port'], + 'proxy_login' => $GLOBALS['configuration']['proxy_username'], + 'proxy_password' => $GLOBALS['configuration']['proxy_password'] + ); + } + $client = new SoapClient( + $GLOBALS['configuration']['soap'], + $options) ; + if ($i == 0) + { + $package = unserialize($client->GeneratePackageFromLink($link)); + } + else + { + $objectString = $client->GenerateObjectFromLink($link); + $package["objects"]["class.".strtolower($className).".php"] = $objectString; + } + } + } + $i++; + } + + + //upgrade mapping classes if any + foreach ($objectNameList as $objectName) + { + $instance = new $objectName(); + foreach ($instance->pog_attribute_type as $key => $attribute_type) + { + if ($attribute_type['db_attributes'][1] == "JOIN") + { + $mappingString = $client->GenerateMapping($objectName, $key, (isset($GLOBALS['configuration']['pdoDriver']) ? 'php5.1' :'php5'), (isset($GLOBALS['configuration']['pdoDriver']) ? 'pdo' :'pog'), (isset($GLOBALS['configuration']['pdoDriver']) ? 'mysql' :'')); + $package["objects"]['class.'.strtolower(MappingName($objectName, $key)).'.php'] = $mappingString; + } + } + } + + $zipfile = new createZip(); + $zipfile -> addPOGPackage($package); + $zipfile -> forceDownload("pog.".time().".zip"); + } + + /** + * Checks if POG generator has been updated + * + * @return unknown + */ + function UpdateAvailable() + { + $client = new SoapClient($GLOBALS['configuration']['soap']); + $generatorVersion = base64_decode($client -> GetGeneratorVersion()); + if ($generatorVersion != $GLOBALS['configuration']['versionNumber'].$GLOBALS['configuration']['revisionNumber']) + { + return true; + } + else + { + return false; + } + } + + if (UpdateAvailable()) + { + UpdateAllObjects("../../objects/"); + } + else + { + echo "<script> + alert('All POG objects are already up to date'); + window.close(); + </script>"; + } +?>
\ No newline at end of file diff --git a/backend/php/src/setup/setup_library/xPandMenu.css b/backend/php/src/setup/setup_library/xPandMenu.css new file mode 100644 index 0000000..744debe --- a/dev/null +++ b/backend/php/src/setup/setup_library/xPandMenu.css @@ -0,0 +1,55 @@ +#container { + width:500px; + background-color:#E7E9EE; +} +.Xtree, .XtreeRoot { + list-style-type:none; + margin:15px 20px; +} +.Xtree { + /* Indentation of a sub-item compared to its parent */ + padding-left:25px; + margin-left:3px; + border-left:1px dotted #998D05; + width:100%; +} +.Xnode { + /* Top and bottom space for a node item */ + margin-top:-3px;margin-bottom:3px; + /* Height of the node item */ + height:20px; + /* Node background color */ + background:#E7E9EE; + /* Font specifications for a node */ + font-weight:bold; + font-size:10px; + cursor:pointer; + vertical-align:middle; + width:100%; +} +.Xnode img{ vertical-align:middle; } +.Xleaf { + /* Top and bottom space for a leaf item */ + margin-top:-10px;margin-bottom:1px; + /* Height of the leag item */ + /* Leaf background color */ + /* Font specifications for a leaf */ + font-weight:normal; + font-size:10px; + padding:2px; +} +.Xnode a { + text-decoration:none; +} +.Xnode a:hover { + color:red; + text-decoration:underline; +} +.Xleaf a { + text-decoration:none; +} +.Xleaf a:hover { + color:red; + text-decoration:none; + background:#eee; +}
\ No newline at end of file diff --git a/backend/php/src/setup/setup_library/xPandMenu.js b/backend/php/src/setup/setup_library/xPandMenu.js new file mode 100644 index 0000000..7f9a632 --- a/dev/null +++ b/backend/php/src/setup/setup_library/xPandMenu.js @@ -0,0 +1,273 @@ +/******************************** +* xPandMenu MULTI-LEVEL class +********************************* +* Javascript file +********************************* +* Patrick Brosset +* patrickbrosset@gmail.com +********************************* +* 02/2005 +*********************************/ + + +// Show / hide a sub-menu +function xMenuShowHide(obj) +{ + + if(obj.style.display == 'none'){ + obj.style.display = 'block'; + }else{ + obj.style.display = 'none'; + } + +} + + +// Toggle expanded / collapsed versions of items' images +function xSwapImg(imgDiv,srcImg,srcAltImg){ + + /* Update by Christian Vallee <cv@valtechnologie.com> + ==> No need to specify absolute URL for images anymore, this feature will find it on its own */ + + // looking for the images' root URL based on the current image + var str = imgDiv.src; + var pos = str.search(srcImg); + // if the URL root wasn't found using the first image, try with the alternative one + if ( pos == -1 ) { pos = str.search(srcAltImg); } + // extracting the URL root + var root = str.substring(0,pos); + // adding the root the image path supplied + srcImg = root.concat(srcImg); + srcAltImg = root.concat(srcAltImg); + + /* End Update */ + + if(imgDiv.src == srcImg){ + imgDiv.src = srcAltImg; + }else{ + imgDiv.src = srcImg; + } + +} + + +// Restore the menu state when the page loads +function xRestoreState() +{ + //restore list state + var name = "xMenuState"; + var start = document.cookie.indexOf(name+"="); + if(start != -1) + { + var len = start+name.length+1; + if ((!start) && (name != document.cookie.substring(0,name.length))) return null; + if (start == -1) return null; + var end = document.cookie.indexOf(";",len); + if (end == -1) end = document.cookie.length; + var value = unescape(document.cookie.substring(len,end)); + var values = value.split("|"); + for(i=0;i<values.length-1;i++) + { + var couple = values[i].split(":"); + document.getElementById(couple[0]).style.display = couple[1]; + } + } + //restore img state + name = "xMenuStateImg"; + start = document.cookie.indexOf(name+"="); + if(start != -1) + { + var len = start+name.length+1; + if ((!start) && (name != document.cookie.substring(0,name.length))) return null; + if (start == -1) return null; + var end = document.cookie.indexOf(";",len); + if (end == -1) end = document.cookie.length; + var value = unescape(document.cookie.substring(len,end)); + var values = value.split("[]"); + for(i=0;i<values.length-1;i++) + { + var couple = values[i].split(">>"); + var imgs = couple[1].split(","); + for(var il in imgs) + { + document.getElementById(imgs[il]).src = couple[0]; + } + } + } +} + +//Get the ids of all open nodes +function getOpenNodes() +{ + value = new Array(); + var myLists = document.getElementsByTagName("UL"); + for(i=0;i<myLists.length;i++) + { + if(myLists[i].className == "Xtree" && myLists[i].style.display == "block") value += myLists[i].id + "-"; + } + return value; +} + +// Save the menu state when the page unloads +function xSaveState() +{ + //Save list state + var value = ""; + var myLists = document.getElementsByTagName("UL"); + for(i=0;i<myLists.length;i++) + { + if(myLists[i].className == "Xtree") value += myLists[i].id + ":" + myLists[i].style.display + "|"; + } + document.cookie = "xMenuState=" + escape(value) + ";"; + //save img state + value = new Array(); + myLists = document.getElementsByTagName("IMG"); + for(i=0;i<myLists.length;i++) + { + if(myLists[i].id.substring(0,4) == "Ximg") + { + if(value[myLists[i].src]){value[myLists[i].src] += "," + myLists[i].id;} + else{value[myLists[i].src] = myLists[i].id;} + } + } + var str = ""; + for(var imgPath in value) + { + str += imgPath + ">>" + value[imgPath] + "[]"; + } + var cook = str.substring(0,str.length-2); + document.cookie = "xMenuStateImg=" + escape(cook) + ";"; +} + +function createRequestObject() +{ + var ro; + if (window.XMLHttpRequest) + { + ro = new XMLHttpRequest(); + } + else + { + ro = new ActiveXObject('MSXML2.XMLHTTP.3.0'); + } + return ro; +} + +var http = createRequestObject(); + +function refTree(offset, limit, objectName) +{ + http = createRequestObject(); + var req = './rpc.php?action=Refresh&offset='+offset+'&limit='+limit+'&objectname='+objectName; + http.open('get', req); + http.onreadystatechange = handleResponse; + http.send(null); +} + +function sndReq(action, openNodes, objectName, objectId, currentNode, attributes, anchor) +{ + + + http = createRequestObject(); + var req = './rpc.php?action='+action+'&opennodes='+openNodes+'&objectname='+objectName+'&objectid='+objectId+'¤tnode='+currentNode+'&anchor='+anchor; + if (action == "Add") + { + for (i=0; i<attributes.length; i++) + { + thisId = attributes[i]; + var thisInput = document.getElementById(thisId); + if (thisInput != null) + { + if (thisInput.type == "checkbox") + { + if (thisInput.checked) + { + req += "&" + thisId + "=" + thisInput.value; + } + } + else + { + req += "&" + thisId + "=" + thisInput.value; + } + } + } + } + else if (action == "Update") + { + for (i=0; i<attributes.length; i++) + { + thisId = attributes[i]; + var thisInput = document.getElementById(thisId+"_"+objectId); + if (thisInput.type == "checkbox") + { + if (thisInput.checked) + { + req += "&" + thisId + "=" + thisInput.value; + } + } + else + { + req += "&" + thisId + "=" + thisInput.value; + } + } + } + http.open('get', req); + http.onreadystatechange = handleResponse; + http.send(null); +} + +function handleResponse() +{ + if(http.readyState == 4) + { + var response = http.responseText; + document.getElementById('container').innerHTML = response; + } +} + +function expandAll() +{ + var myLists = document.getElementsByTagName("UL"); + for(i=0;i<myLists.length;i++) + { + if(myLists[i].className == "Xtree" && myLists[i].style.display == "none") myLists[i].style.display = "block"; + } + myLists = document.getElementsByTagName("IMG"); + for(i=0;i<myLists.length;i++) + { + if(myLists[i].id.substring(0,4) == "Ximg") + { + myLists[i].src = "setup_images/folderopen.gif"; + } + } +} + +function collapseAll() +{ + var myLists = document.getElementsByTagName("UL"); + for(i=0;i<myLists.length;i++) + { + if(myLists[i].className == "Xtree" && myLists[i].style.display == "block") myLists[i].style.display = "none"; + } + myLists = document.getElementsByTagName("IMG"); + for(i=0;i<myLists.length;i++) + { + if(myLists[i].id.substring(0,4) == "Ximg") + { + myLists[i].src = "setup_images/folderclose.gif"; + } + } +} + +function ToggleElementVisibility(elementId) +{ + var element = document.getElementById(elementId); + if (element.style.display != 'none') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'inline'; + } +}
\ No newline at end of file diff --git a/backend/php/src/setup/setup_library/xPandMenu.php b/backend/php/src/setup/setup_library/xPandMenu.php new file mode 100644 index 0000000..d9c7d07 --- a/dev/null +++ b/backend/php/src/setup/setup_library/xPandMenu.php @@ -0,0 +1,233 @@ +<?php + +/******************************** +* xPandMenu MULTI-LEVEL class +********************************* +* Creates a tree-view menu. +* The menu can be as deep as needed +* The menu items are organised in HTML unordered lists +* Container nodes can be expanded/collapsed thanks to Javascript actions +********************************* +* Patrick Brosset +* patrickbrosset@gmail.com +********************************* +* 02/2005 +*********************************/ + + + +// Path to default image files (directories and documents icons) -- (use absolute URL) +define('NODE_DEFAULT_IMG','http://project.zoe.co.nz/patrick/xpand/multi/images/folder_win.gif'); +define('LEAF_DEFAULT_IMG','http://project.zoe.co.nz/patrick/xpand/multi/images/document_win.gif'); +define('NODE_DEFAULT_ALT_IMG','http://project.zoe.co.nz/patrick/xpand/multi/images/folder_win_o.gif'); +define('LEAF_DEFAULT_ALT_IMG','http://project.zoe.co.nz/patrick/xpand/multi/images/document_win_o.gif'); + +// Reference to the File class for saving and loading the generated menu +//include_once 'File.php'; + + + +// Xmenu class +class XMenu +{ + + + // Sub-nodes contained in this menu (references to Xnode objects) + var $items = array(); + + // Keeps track of the HTML code indent to use (formatting of UL and LI) + var $indent; + + // Is it the first node ? + var $first; + + // Used for assigning unique IDs to HTML elements (for the javascript function) + var $treeCount; + + // Same for images + var $imgCount; + + // Contains the generated HTML code + var $output; + + // Contains the nodes to expand when generating tree + var $visibleNodes = array("1"); + + + + // Constructor + function XMenu() + { + $this->indent = 0; + $this->first = true; + $this->treeCount = 0; + $this->imgCount = 0; + $this->output = ""; + } + + + + // addItem, adds a child to this menu + // Takes a XNode object reference as argument + function &addItem(&$node) + { + $this->items[] = &$node; + return $this->items[count($this->items) - 1]; + } + + + + // generateTree, generates the HTML code (UL list) for the dynamic tree-view + function generateTree($root = false) + { + if(!$root) $root = $this; + + if($this->first){ + $this->output .= $this->codeIndent()."<ul id=\"XRoot\" class=\"XtreeRoot\">\n"; + $this->first = false; + }else{ + if (array_search($this->treeCount, $this->visibleNodes) !== false) + { + $this->output .= $this->codeIndent()."<ul id=\"Xtree".$this->treeCount."\" class=\"Xtree\" style=\"display:block;\">\n"; + } + else + { + $this->output .= $this->codeIndent()."<ul id=\"Xtree".$this->treeCount."\" class=\"Xtree\" style=\"display:none;\">\n"; + } + } + $this->treeCount ++; + foreach($root->items as $myChild){ + $this->imgCount ++; + if($myChild->img){ + if($myChild->alt_img){ + $img_js = "xSwapImg(document.getElementById('Ximg".$this->imgCount."'),'".$myChild->img."','".$myChild->alt_img."');"; + }else{ + $img_js = ""; + } + if (array_search($this->treeCount, $this->visibleNodes) !== false) + { + $img = "<img onClick=\"".$img_js."xMenuShowHide(document.getElementById('Xtree".$this->treeCount."'));\" id=\"Ximg".$this->imgCount."\" src=\"".$myChild->alt_img."\" border=\"0\"> "; + } + else + { + $img = "<img onClick=\"".$img_js."xMenuShowHide(document.getElementById('Xtree".$this->treeCount."'));\" id=\"Ximg".$this->imgCount."\" src=\"".$myChild->img."\" border=\"0\"> "; + } + }else{ + $img = "";$img_js = ""; + } + if($myChild->link){ + $href_open = "<a href=\"".$myChild->link."\">"; + $href_close = "</a>"; + }else{ + $href_open = ""; + $href_close = ""; + } + if(count($myChild->items) != 0){ + $this->output .= $this->codeIndent()."<li class=\"Xnode\" id=\"Xnode".$this->treeCount."\"><div>".$href_open.$img.$myChild->name.$href_close."</div></li>\n"; + $this->indent ++; + $this->generateTree($myChild); + }else{ + $this->output .= $this->codeIndent()."<li class=\"Xleaf\"><div onClick=\"".$img_js."\">".$href_open.$img.$myChild->name.$href_close."</div></li>\n"; + } + } + $this->output .= $this->codeIndent()."</ul>\n"; + $this->indent --; + + return $this->output; + } + + + + // saveTree and restoreTree - thanks to Niels Fanoe (niels.f@noee.dk) for giving me the idea + + // saveTree, save the generated HTML code to a file for future use without generating again + function saveTree($filename = "xMenuCache.html") + { + $file = new File(); + $file->write($this->output,$filename); + $file->printError(); + return $filename; + } + + + + // restoreTree, returns the previously generated HTML code stored in a file + // Call this method STATICALLY for easier use: XMenu::restoreTree("xPandMenuCode.html"); + function restoreTree($filename = "xMenuCache.html") + { + $file = new File(); + $menu = $file->read($filename); + $error = $file->getError(); + if(!empty($error)) return false; + else return $menu; + } + + + + // codeIndent, only used to create a nice and readable HTML code (indents the UL and LI tags) + function codeIndent() + { + $str = ""; + for($i=0;$i<$this->indent;$i++){ + $str .= " "; + } + return $str; + } + + +} + + + + +// XNode class: A node item in the menu +class XNode +{ + + + // Name assigned to this node (Text shown on the item) + var $name; + + // Link for the item (if any) + var $link; + + // Sub-items of this node + var $items = array(); + + // Absolute URL of this node's icon + var $img; + + // Absolute URL of this node's icon (alternate, used for expanded and collapsed states) + var $alt_img; + + + + // constructor + // $name: text shown for this item + // $link: where does this item links to when clicked (optional) + // $img and $alt_img: images displayed next to this item (absolute paths to images must be used) + function XNode($name,$link = false,$img = LEAF_DEFAULT_IMG,$alt_img = LEAF_DEFAULT_ALT_IMG) + { + $this->name = $name; + $this->link = $link; + $this->img = $img; + $this->alt_img = $alt_img; + } + + + + // addItem, adds a subnode under this node + // Takes a XNode object reference as argument + function &addItem(&$node) + { + if($this->img == LEAF_DEFAULT_IMG){$this->img = NODE_DEFAULT_IMG;} + if($this->alt_img == LEAF_DEFAULT_ALT_IMG){$this->alt_img = NODE_DEFAULT_ALT_IMG;} + $this->items[] = &$node; + return $this->items[count($this->items) - 1]; + } + + + +} + +?>
\ No newline at end of file |