summaryrefslogtreecommitdiff
path: root/backend
authorGiulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
committer Giulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
commitef68436ac04da078ffdcacd7e1f785473a303d45 (patch) (side-by-side diff)
treec403752d66a2c4775f00affd4fa8431b29c5b68c /backend
parent597ecfbc0249d83e1b856cbd558340c01237a360 (diff)
downloadclipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.zip
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.gz
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.bz2
First version of the newly restructured repository
Diffstat (limited to 'backend') (more/less context) (ignore whitespace changes)
-rw-r--r--backend/php/properties/php.properties.json4
-rw-r--r--backend/php/src/configuration.php36
-rw-r--r--backend/php/src/dump.php103
-rw-r--r--backend/php/src/index.php744
-rw-r--r--backend/php/src/json/JSON.php806
-rw-r--r--backend/php/src/objects/class.database.php79
-rw-r--r--backend/php/src/objects/class.onetimepassword.php400
-rw-r--r--backend/php/src/objects/class.onetimepasswordstatus.php368
-rw-r--r--backend/php/src/objects/class.pog_base.php143
-rw-r--r--backend/php/src/objects/class.record.php436
-rw-r--r--backend/php/src/objects/class.recordversion.php381
-rw-r--r--backend/php/src/objects/class.user.php502
-rw-r--r--backend/php/src/objects/ignore_objects.txt0
-rw-r--r--backend/php/src/plugins/IPlugin.php48
-rw-r--r--backend/php/src/plugins/base64_install.sql172
-rw-r--r--backend/php/src/plugins/base64_uninstall.sql20
-rw-r--r--backend/php/src/plugins/plugin.base64.php128
-rw-r--r--backend/php/src/setup/data_initialization/additional_table_structures.sql0
-rw-r--r--backend/php/src/setup/data_initialization/data_initialization.sql0
-rw-r--r--backend/php/src/setup/data_initialization/howto.txt13
-rw-r--r--backend/php/src/setup/data_initialization/read_dump_lib.php205
-rw-r--r--backend/php/src/setup/index.php717
-rw-r--r--backend/php/src/setup/rpc.php227
-rw-r--r--backend/php/src/setup/setup.css77
-rw-r--r--backend/php/src/setup/setup_images/background_id.gifbin0 -> 359 bytes
-rw-r--r--backend/php/src/setup/setup_images/button_add.gifbin0 -> 167 bytes
-rw-r--r--backend/php/src/setup/setup_images/button_delete.gifbin0 -> 281 bytes
-rw-r--r--backend/php/src/setup/setup_images/button_toolbar_author.gifbin0 -> 2037 bytes
-rw-r--r--backend/php/src/setup/setup_images/button_toolbar_help.gifbin0 -> 1910 bytes
-rw-r--r--backend/php/src/setup/setup_images/button_toolbar_homepage.gifbin0 -> 1939 bytes
-rw-r--r--backend/php/src/setup/setup_images/button_toolbar_left.gifbin0 -> 636 bytes
-rw-r--r--backend/php/src/setup/setup_images/button_update.gifbin0 -> 273 bytes
-rw-r--r--backend/php/src/setup/setup_images/folderclose.gifbin0 -> 62 bytes
-rw-r--r--backend/php/src/setup/setup_images/folderopen.gifbin0 -> 61 bytes
-rw-r--r--backend/php/src/setup/setup_images/generate.jpgbin0 -> 1678 bytes
-rw-r--r--backend/php/src/setup/setup_images/gradient_container.gifbin0 -> 179 bytes
-rw-r--r--backend/php/src/setup/setup_images/loading.gifbin0 -> 1141 bytes
-rw-r--r--backend/php/src/setup/setup_images/mini_pog.jpgbin0 -> 16299 bytes
-rw-r--r--backend/php/src/setup/setup_images/pog_setup_closed.jpgbin0 -> 2029 bytes
-rw-r--r--backend/php/src/setup/setup_images/pog_setup_open.jpgbin0 -> 2398 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_attachtables.jpgbin0 -> 2106 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_bottom3.jpgbin0 -> 499 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_bottom3tile.jpgbin0 -> 311 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_collapseall.jpgbin0 -> 2074 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_deleteall.jpgbin0 -> 1778 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_expandall.jpgbin0 -> 1974 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_footer.jpgbin0 -> 1145 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_generateform.jpgbin0 -> 2535 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_logo1.jpgbin0 -> 7992 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_logo2.jpgbin0 -> 7931 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_logo3.jpgbin0 -> 6683 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_pogmeup.gifbin0 -> 1420 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_proceed.gifbin0 -> 839 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_recheck.jpgbin0 -> 4074 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_regenerate.jpgbin0 -> 2167 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_toolbargradient.jpgbin0 -> 667 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_updateall.jpgbin0 -> 2340 bytes
-rw-r--r--backend/php/src/setup/setup_images/setup_welcome.jpgbin0 -> 3849 bytes
-rw-r--r--backend/php/src/setup/setup_images/tab_activeobjectleft.gifbin0 -> 145 bytes
-rw-r--r--backend/php/src/setup/setup_images/tab_activeobjectright.gifbin0 -> 477 bytes
-rw-r--r--backend/php/src/setup/setup_images/tab_diagnosticresults.gifbin0 -> 368 bytes
-rw-r--r--backend/php/src/setup/setup_images/tab_diagnosticresults_on.gifbin0 -> 371 bytes
-rw-r--r--backend/php/src/setup/setup_images/tab_manageobjects.gifbin0 -> 364 bytes
-rw-r--r--backend/php/src/setup/setup_images/tab_manageobjects_on.gifbin0 -> 371 bytes
-rw-r--r--backend/php/src/setup/setup_images/tab_manageplugins_off.gifbin0 -> 460 bytes
-rw-r--r--backend/php/src/setup/setup_images/tab_manageplugins_on.gifbin0 -> 1220 bytes
-rw-r--r--backend/php/src/setup/setup_images/tab_separator.gifbin0 -> 154 bytes
-rw-r--r--backend/php/src/setup/setup_images/tab_setup.gifbin0 -> 258 bytes
-rw-r--r--backend/php/src/setup/setup_images/tab_setup_on.gifbin0 -> 472 bytes
-rw-r--r--backend/php/src/setup/setup_images/toolbar_separator.gifbin0 -> 324 bytes
-rw-r--r--backend/php/src/setup/setup_library/authentication.php30
-rw-r--r--backend/php/src/setup/setup_library/class.zipfile.php212
-rw-r--r--backend/php/src/setup/setup_library/inc.footer.php6
-rw-r--r--backend/php/src/setup/setup_library/inc.header.php36
-rw-r--r--backend/php/src/setup/setup_library/setup_misc.php2357
-rw-r--r--backend/php/src/setup/setup_library/upgrade.php140
-rw-r--r--backend/php/src/setup/setup_library/xPandMenu.css55
-rw-r--r--backend/php/src/setup/setup_library/xPandMenu.js273
-rw-r--r--backend/php/src/setup/setup_library/xPandMenu.php233
-rw-r--r--backend/php/src/test.php15
-rw-r--r--backend/python/properties/python.properties.json0
-rw-r--r--backend/python/src/app.yaml20
-rw-r--r--backend/python/src/clipperz.py708
83 files changed, 9694 insertions, 0 deletions
diff --git a/backend/php/properties/php.properties.json b/backend/php/properties/php.properties.json
new file mode 100644
index 0000000..32d5084
--- a/dev/null
+++ b/backend/php/properties/php.properties.json
@@ -0,0 +1,4 @@
+{
+ "request.path": "../index.php",
+ "should.pay.toll": "false"
+} \ No newline at end of file
diff --git a/backend/php/src/configuration.php b/backend/php/src/configuration.php
new file mode 100644
index 0000000..291e3a1
--- a/dev/null
+++ b/backend/php/src/configuration.php
@@ -0,0 +1,36 @@
+<?php
+global $configuration;
+$configuration['soap'] = "http://www.phpobjectgenerator.com/services/soap.php?wsdl";
+$configuration['homepage'] = "http://www.phpobjectgenerator.com";
+$configuration['revisionNumber'] = "";
+$configuration['versionNumber'] = "3.0d";
+
+$configuration['setup_password'] = '';
+
+
+// to enable automatic data encoding, run setup, go to the manage plugins tab and install the base64 plugin.
+// then set db_encoding = 1 below.
+// when enabled, db_encoding transparently encodes and decodes data to and from the database without any
+// programmatic effort on your part.
+$configuration['db_encoding'] = 0;
+
+// edit the information below to match your database settings
+
+$configuration['db'] = 'clipperz'; // database name
+$configuration['host'] = 'localhost'; // database host
+$configuration['user'] = 'root'; // database user
+$configuration['pass'] = 'pass'; // database password
+$configuration['port'] = '3306'; // database port
+
+
+//proxy settings - if you are behnd a proxy, change the settings below
+$configuration['proxy_host'] = false;
+$configuration['proxy_port'] = false;
+$configuration['proxy_username'] = false;
+$configuration['proxy_password'] = false;
+
+
+//plugin settings
+$configuration['plugins_path'] = dirname(__FILE__).'/plugins';
+
+?> \ No newline at end of file
diff --git a/backend/php/src/dump.php b/backend/php/src/dump.php
new file mode 100644
index 0000000..d4e8544
--- a/dev/null
+++ b/backend/php/src/dump.php
@@ -0,0 +1,103 @@
+<?php
+header('Content-Type: text/html');
+header('Content-Disposition: attachment; filename=Clipperz_'.date("Ymd").'.html');
+
+
+ include "./configuration.php";
+ include "./objects/class.database.php";
+ include "./objects/class.user.php";
+ include "./objects/class.record.php";
+ include "./objects/class.recordversion.php";
+ include "./objects/class.onetimepassword.php";
+ include "./objects/class.onetimepasswordstatus.php";
+
+ $htmlContent = file_get_contents("../index.html");
+
+ session_start();
+
+ $user = new user();
+ $user = $user->Get($_SESSION["userId"]);
+ $records = $user->GetRecordList();
+
+ $recordString = "";
+ $isFirstRecord = true;
+
+ $c = count($records);
+ for ($i=0; $i<$c; $i++) {
+ $currentRecord = $records[$i];
+ $recordVersions = $currentRecord->GetRecordversionList();
+
+
+ if ($isFirstRecord == true) {
+ $isFirstRecord = false;
+ } else {
+ $recordString = $recordString . ",\n";
+ }
+
+ $versionString = "";
+ $isFirstVersion = true;
+
+ $cc = count($recordVersions);
+ for ($ii=0; $ii<$cc; $ii++) {
+ $currentVersion = $recordVersions[$ii];
+
+ if ($isFirstVersion == true) {
+ $isFirstVersion = false;
+ } else {
+ $versionString = $versionString . ",\n";
+ }
+
+ $versionsString = $versionString . "\t\t\t\t\t\t'" . $currentVersion->reference . "': {\n" .
+ "\t\t\t\t\t\t\theader: '" . $currentVersion->header . "',\n" .
+ "\t\t\t\t\t\t\tdata: '" . $currentVersion->data . "',\n" .
+ "\t\t\t\t\t\t\tversion: '" . $currentVersion->version . "',\n" .
+ "\t\t\t\t\t\t\tcreationDate: '" . $currentVersion->creation_date . "',\n" .
+ "\t\t\t\t\t\t\tupdateDate: '" . $currentVersion->update_date . "',\n" .
+ "\t\t\t\t\t\t\taccessDate: '" . $currentVersion->access_date . "'\n" .
+ "\t\t\t\t\t\t}";
+ }
+
+ $recordString = $recordString . "\t\t\t\t'" . $currentRecord->reference . "': {\n" .
+ "\t\t\t\t\tdata: '" . $currentRecord->data . "',\n" .
+ "\t\t\t\t\tversion: '" . $currentRecord->version . "',\n" .
+ "\t\t\t\t\tcreationDate: '" . $currentRecord->creation_date . "',\n" .
+ "\t\t\t\t\tupdateDate: '" . $currentRecord->update_date . "',\n" .
+ "\t\t\t\t\taccessDate: '" . $currentRecord->access_date . "',\n" .
+ "\t\t\t\t\tcurrentVersion: '" . $currentVersion->reference . "',\n" .
+ "\t\t\t\t\tversions: {\n" .
+ $versionsString . "\n" .
+ "\t\t\t\t\t}\n" .
+ "\t\t\t\t}";
+ }
+
+
+ $data = "_clipperz_dump_data_ = {\n" .
+ "\tusers:{\n" .
+ "\t\t'catchAllUser': {\n" .
+ "\t\t\t__masterkey_test_value__: 'masterkey',\n" .
+ "\t\t\ts: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',\n" .
+ "\t\t\tv: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'\n" .
+ "\t\t},\n" .
+ "\t\t'" . $user->username . "': {\n" .
+ "\t\t\ts: '" . $user->srp_s . "',\n" .
+ "\t\t\tv: '" . $user->srp_v . "',\n" .
+ "\t\t\tversion: '" . $user->auth_version . "',\n" .
+ "\t\t\tmaxNumberOfRecords: '" . "100" . "',\n" .
+ "\t\t\tuserDetails: '" . $user->header . "',\n" .
+ "\t\t\tstatistics: '" . $user->statistics . "',\n" .
+ "\t\t\tuserDetailsVersion: '" . $user->version . "',\n" .
+ "\t\t\trecords: {\n" .
+ $recordString . "\n" .
+ "\t\t\t}\n" .
+ "\t\t}\n" .
+ "\t}\n" .
+ "}\n" .
+ "\n" .
+ "Clipperz.PM.Proxy.defaultProxy = new Clipperz.PM.Proxy.Offline();\n" .
+ "Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();" .
+ "\n";
+
+ session_write_close();
+
+ echo str_replace("/*offline_data_placeholder*/", $data, $htmlContent);
+?> \ No newline at end of file
diff --git a/backend/php/src/index.php b/backend/php/src/index.php
new file mode 100644
index 0000000..eb3d75a
--- a/dev/null
+++ b/backend/php/src/index.php
@@ -0,0 +1,744 @@
+<?php
+ include "./configuration.php";
+ include "./objects/class.database.php";
+ include "./objects/class.user.php";
+ include "./objects/class.record.php";
+ include "./objects/class.recordversion.php";
+ include "./objects/class.onetimepassword.php";
+ include "./objects/class.onetimepasswordstatus.php";
+
+//-----------------------------------------------------------------------------
+
+if ( !function_exists('json_decode') ) {
+ function json_decode($content, $assoc=false) {
+ require_once 'json/JSON.php';
+ if ( $assoc ) {
+ $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
+ } else {
+ $json = new Services_JSON;
+ }
+
+ return $json->decode($content);
+ }
+}
+
+if ( !function_exists('json_encode') ) {
+ function json_encode($content) {
+ require_once 'json/JSON.php';
+ $json = new Services_JSON;
+
+ return $json->encode($content);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// 'dec2base', 'base2dec' and 'digits' are functions found on the following
+// PHP manual page: http://ch2.php.net/manual/en/ref.bc.php
+//
+
+function dec2base($dec, $base, $digits=FALSE) {
+ if ($base<2 or $base>256) {
+ die("Invalid Base: ".$base);
+ }
+
+ bcscale(0);
+ $value="";
+ if (!$digits) {
+ $digits = digits($base);
+ }
+
+ while ($dec > $base-1) {
+ $rest = bcmod($dec, $base);
+ $dec = bcdiv($dec, $base);
+ $value = $digits[$rest].$value;
+ }
+
+ $value=$digits[intval($dec)].$value;
+
+ return (string)$value;
+}
+
+//.............................................................................
+
+// convert another base value to its decimal value
+function base2dec($value, $base, $digits=FALSE) {
+ if ($base<2 or $base>256) {
+ die("Invalid Base: ".$base);
+ }
+
+ bcscale(0);
+ if ($base<37) {
+ $value=strtolower($value);
+ }
+
+ if (!$digits) {
+ $digits=digits($base);
+ }
+
+ $size = strlen($value);
+ $dec="0";
+ for ($loop=0; $loop<$size; $loop++) {
+ $element = strpos($digits, $value[$loop]);
+ $power = bcpow($base, $size-$loop-1);
+ $dec = bcadd($dec, bcmul($element,$power));
+ }
+
+ return (string)$dec;
+}
+
+//.............................................................................
+
+function digits($base) {
+ if ($base>64) {
+ $digits="";
+ for ($loop=0; $loop<256; $loop++) {
+ $digits.=chr($loop);
+ }
+ } else {
+ $digits ="0123456789abcdefghijklmnopqrstuvwxyz";
+ $digits.="ABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
+ }
+
+ $digits=substr($digits,0,$base);
+
+ return (string)$digits;
+}
+
+//-----------------------------------------------------------------------------
+
+function clipperz_hash($value) {
+ return hash("sha256", hash("sha256", $value, true));
+}
+
+//-----------------------------------------------------------------------------
+
+function clipperz_randomSeed() {
+ $result;
+
+ srand((double) microtime()*1000000);
+ $result = "";
+
+ while(strlen($result) < 64) {
+ $result = $result.dec2base(rand(), 16);
+ }
+
+ $result = substr($result, 0, 64);
+
+ return $result;
+}
+
+//-----------------------------------------------------------------------------
+
+function updateUserCredentials($parameters, &$user) {
+ $user->username = $parameters["C"];
+ $user->srp_s = $parameters["s"];
+ $user->srp_v = $parameters["v"];
+ $user->auth_version = $parameters["version"];
+}
+
+function updateUserData($parameters, &$user) {
+ $user->header = $parameters["header"];
+ $user->statistics = $parameters["statistics"];
+ $user->version = $parameters["version"];
+ $user->lock = $parameters["lock"];
+}
+
+function updateRecordData($parameters, &$record, &$recordVersion) {
+ $recordData = $parameters["record"];
+ $record->reference = $recordData["reference"];
+ $record->data = $recordData["data"];
+ $record->version = $recordData["version"];
+
+ $recordVersionData = $parameters["currentRecordVersion"];
+ $recordVersion->reference = $recordVersionData ["reference"];
+ $recordVersion->data = $recordVersionData ["data"];
+ $recordVersion->version = $recordVersionData ["version"];
+ $recordVersion->previous_version_id = $recordVersionData ["previousVersion"];
+ $recordVersion->previous_version_key = $recordVersionData ["previousVersionKey"];
+}
+
+//-----------------------------------------------------------------------------
+
+function updateOTPStatus(&$otp, $status) {
+ $otpStatus = new onetimepasswordstatus();
+ $selectedStatuses = $otpStatus->GetList(array(array("code", "=", $status)));
+ $otpStatus = $selectedStatuses[0];
+ $otp->SetOnetimepasswordstatus($otpStatus);
+}
+
+function updateOTP($parameters, &$otp, $status) {
+ $otp->reference = $parameters["reference"];
+ $otp->key = $parameters["key"];
+ $otp->key_checksum = $parameters["keyChecksum"];
+ $otp->data = $parameters["data"];
+ $otp->version = $parameters["version"];
+
+ updateOTPStatus($otp, $status);
+}
+
+function resetOTP(&$otp, $status) {
+ $otp->data = "";
+ updateOTPStatus($otp, $status);
+ $otp->Save();
+}
+
+//-----------------------------------------------------------------------------
+
+function fixOTPStatusTable() {
+ $otpStatus = new onetimepasswordstatus();
+ $otpStatusList = $otpStatus->GetList();
+ if (count($otpStatusList) != 4) {
+ $otpStatus->DeleteList();
+
+ $otpStatus->code = "ACTIVE"; $otpStatus->name = "Active"; $otpStatus->description = "Active"; $otpStatus->SaveNew();
+ $otpStatus->code = "REQUESTED"; $otpStatus->name = "Requested"; $otpStatus->description = "Requested"; $otpStatus->SaveNew();
+ $otpStatus->code = "USED"; $otpStatus->name = "Used"; $otpStatus->description = "Used"; $otpStatus->SaveNew();
+ $otpStatus->code = "DISABLED"; $otpStatus->name = "Disabled"; $otpStatus->description = "Disabled"; $otpStatus->SaveNew();
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+function arrayContainsValue($array, $value) {
+ $object = NULL;
+ for ($i=0; $i<count($array); $i++) {
+ if ($array[$i] == $value) {
+ $object = $value;
+ }
+ }
+
+ return !is_null($object);
+}
+
+//-----------------------------------------------------------------------------
+
+ $result = Array();
+
+ session_start();
+
+ $method = $_POST['method'];
+
+ if (get_magic_quotes_gpc()) {
+ $parameters = json_decode(stripslashes($_POST['parameters']), true);
+ } else {
+ $parameters = json_decode($_POST['parameters'], true);
+ }
+
+ $parameters = $parameters["parameters"];
+
+ switch($method) {
+ case "registration":
+error_log("registration");
+ $message = $parameters["message"];
+
+ if ($message == "completeRegistration") {
+ $user = new user();
+
+ updateUserCredentials($parameters["credentials"], $user);
+ updateUserData($parameters["user"], $user);
+ $user->Save();
+
+ $result["lock"] = $user->lock;
+ $result["result"] = "done";
+ }
+ break;
+
+ case "handshake":
+error_log("handshake");
+ $srp_g = "2";
+ $srp_n = base2dec("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16);
+
+ $message = $parameters["message"];
+
+ //=============================================================
+ if ($message == "connect") {
+ $user= new user();
+ $_SESSION["C"] = $parameters["parameters"]["C"];
+ $_SESSION["A"] = $parameters["parameters"]["A"];
+
+ $userList = $user->GetList(array(array("username", "=", $_SESSION["C"])));
+
+ if (count($userList) == 1) {
+ $currentUser = $userList[ 0 ];
+
+ if (array_key_exists("otpId", $_SESSION)) {
+ $otp = new onetimepassword();
+ $otp = $otp->Get($_SESSION["otpId"]);
+
+ if ($otp->GetUser()->userId != $currentUser->userId) {
+ throw new Exception("User missmatch between the current session and 'One Time Password' user");
+ } else if ($otp->GetOnetimepasswordstatus()->code != "REQUESTED") {
+ throw new Exception("Tring to use an 'One Time Password' in the wrong state");
+ }
+
+ resetOTP($otp, "USED");
+ $result["oneTimePassword"] = $otp->reference;
+ }
+
+ $_SESSION["s"] = $currentUser->srp_s;
+ $_SESSION["v"] = $currentUser->srp_v;
+ $_SESSION["userId"] = $currentUser->userId;
+ } else {
+ $_SESSION["s"] = "112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00";
+ $_SESSION["v"] = "112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00";
+ }
+
+ $_SESSION["b"] = clipperz_randomSeed();
+// $_SESSION["b"] = "5761e6c84d22ea3c5649de01702d60f674ccfe79238540eb34c61cd020230c53";
+ $_SESSION["B"] = dec2base(bcadd(base2dec($_SESSION["v"], 16), bcpowmod($srp_g, base2dec($_SESSION["b"], 16), $srp_n)), 16);
+
+ $result["s"] = $_SESSION["s"];
+ $result["B"] = $_SESSION["B"];
+
+ //=============================================================
+ } else if ($message == "credentialCheck") {
+error_log("credentialCheck");
+ $u = clipperz_hash(base2dec($_SESSION["B"],16));
+ $A = base2dec($_SESSION["A"], 16);
+ $S = bcpowmod(bcmul($A, bcpowmod(base2dec($_SESSION["v"], 16), base2dec($u, 16), $srp_n)), base2dec($_SESSION["b"], 16), $srp_n);
+ $K = clipperz_hash($S);
+ $M1 = clipperz_hash($A.base2dec($_SESSION["B"],16).$K);
+
+//$result["B"] = $_SESSION["B"];
+//$result["u"] = $u;
+//$result["A"] = $A;
+//$result["S"] = $S;
+//$result["K"] = $K;
+//$result["M1"] = $M1;
+//$result["_M1"] = $parameters["parameters"]["M1"];
+
+ if ($M1 == $parameters["parameters"]["M1"]) {
+ $_SESSION["K"] = $K;
+ $M2 = clipperz_hash($A.$M1.$K);
+
+ $result["M2"] = $M2;
+ $result["connectionId"] = "";
+ $result["loginInfo"] = array();
+ $result["loginInfo"]["latest"] = array();
+ $result["loginInfo"]["current"] = array();
+ $result["offlineCopyNeeded"] = "false";
+ $result["lock"] = "----";
+ } else {
+ $result["error"] = "?";
+ }
+ //=============================================================
+ } else if ($message == "oneTimePassword") {
+error_log("oneTimePassword");
+//{
+// "message":"oneTimePassword",
+// "version":"0.2",
+// "parameters":{
+// "oneTimePasswordKey":"06dfa7f428081f8b2af98b0895e14e18af90b0ef2ff32828e55cc2ac6b24d29b",
+// "oneTimePasswordKeyChecksum":"60bcba3f72e56f6bb3f0ff88509b9a0e5ec730dfa71daa4c1e892dbd1b0c360d"
+// }
+//}
+ $otp = new onetimepassword();
+ $otpList = $otp->GetList(array(array("key", "=", $parameters["parameters"]["oneTimePasswordKey"])));
+
+ if (count($otpList) == 1) {
+ $currentOtp = $otpList[0];
+
+ if ($currentOtp->GetOnetimepasswordstatus()->code == "ACTIVE") {
+ if ($currentOtp->key_checksum == $parameters["parameters"]["oneTimePasswordKeyChecksum"]) {
+ $_SESSION["userId"] = $currentOtp->GetUser()->userId;
+ $_SESSION["otpId"] = $currentOtp->onetimepasswordId;
+
+ $result["data"] = $currentOtp->data;
+ $result["version"] = $currentOtp->version;
+
+ resetOTP($currentOtp, "REQUESTED");
+ } else {
+ resetOTP($currentOtp, "DISABLED");
+ throw new Exception("The requested One Time Password has been disabled, due to a wrong keyChecksum");
+ }
+ } else {
+ throw new Exception("The requested One Time Password was not active");
+ }
+ } else {
+ throw new Exception("The requested One Time Password has not been found");
+ }
+
+ //=============================================================
+ }
+
+ break;
+
+ case "message":
+error_log("message");
+ if ($parameters["srpSharedSecret"] == $_SESSION["K"]) {
+ $message = $parameters["message"];
+
+ //=============================================================
+ if ($message == "getUserDetails") {
+//{"message":"getUserDetails", "srpSharedSecret":"f18e5cf7c3a83b67d4db9444af813ee48c13daf4f8f6635397d593e52ba89a08", "parameters":{}}
+ $user = new user();
+ $user = $user->Get($_SESSION["userId"]);
+
+ $result["header"] = $user->header;
+ $result["statistics"] = $user->statistics;
+ $result["version"] = $user->version;
+
+ //=============================================================
+ } else if ($message == "addNewRecords") {
+/*
+//{
+// "message":"addNewRecords",
+// "srpSharedSecret":"b58fdf62acebbcb67f63d28c0437f166069f45690c648cd4376a792ae7a325f7",
+// "parameters":{
+// "records":[
+// {
+// "record":{
+// "reference":"fda703707fee1fff42443124cd0e705f5bea0ac601758d81b2e832705339a610",
+// "data":"OBSGtcb6blXq/xaYG.....4EqlQqgAvITN",
+// "version":"0.3"
+// },
+// "currentRecordVersion":{
+// "reference":"83ad301525c18f2afd72b6ac82c0a713382e1ef70ac69935ca7e2869dd4ff980",
+// "recordReference":"fda703707fee1fff42443124cd0e705f5bea0ac601758d81b2e832705339a610",
+// "data":"NXJ5jiZhkd0CMiwwntAq....1TjjF+SGfE=",
+// "version":"0.3",
+// "previousVersion":"3e174a86afc322271d8af28bc062b0f1bfd7344fad01212cd08b2757c4b199c4",
+// "previousVersionKey":"kozaaGCzXWr71LbOKu6Z3nz520V..5U85tSBvb+u44twttv54Kw=="
+// }
+// }
+// ],
+// "user":{
+// "header":"{\"reco...ersion\":\"0.1\"}",
+// "statistics":"rKI6nR6iqggygQJ3SQ58bFUX",
+// "version":"0.3",
+// "lock":"----"
+// }
+// }
+//}
+*/
+ $user = new user();
+ $record = new record();
+ $recordVersion = new recordversion();
+
+ $user = $user->Get($_SESSION["userId"]);
+ updateUserData($parameters["parameters"]["user"], $user);
+
+ $recordParameterList = $parameters["parameters"]["records"];
+ $c = count($recordParameterList);
+ for ($i=0; $i<$c; $i++) {
+ updateRecordData($recordParameterList[$i], $record, $recordVersion);
+
+ $record->SaveNew();
+ $recordVersion->SaveNew();
+
+ $record->AddRecordversion($recordVersion);
+ $user->AddRecord($record);
+
+ $record->Save();
+ $recordVersion->Save();
+ }
+
+ $user->Save();
+
+ $result["lock"] = $user->lock;
+ $result["result"] = "done";
+
+ //=============================================================
+ } else if ($message == "getRecordDetail") {
+//{
+// "message":"getRecordDetail",
+// "srpSharedSecret":"4c00dcb66a9f2aea41a87e4707c526874e2eb29cc72d2c7086837e53d6bf2dfe",
+// "parameters":{
+// "reference":"740009737139a189cfa2b1019a6271aaa39467b59e259706564b642ff3838d50"
+// }
+//}
+//
+// result = {
+// currentVersion:{
+// reference:"88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854",
+// accessDate:"Wed, 13 February 2008 14:25:12 UTC",
+// creationDate:"Tue, 17 April 2007 17:17:52 UTC",
+// version:"0.2",
+// data:"xI3WXddQLFtL......EGyKnnAVik",
+// updateDate:"Tue, 17 April 2007 17:17:52 UTC",
+// header:"####"
+// }
+// reference:"13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551",
+// oldestUsedEncryptedVersion:"0.2",
+// accessDate:"Wed, 13 February 2008 14:25:12 UTC",
+// creationDate:"Wed, 14 March 2007 13:53:11 UTC",
+// version:"0.2",
+// updatedDate:"Tue, 17 April 2007 17:17:52 UTC",
+// data:"0/BjzyY6jeh71h...pAw2++NEyylGhMC5C5f5m8pBApYziN84s4O3JQ3khW/1UttQl4="
+// }
+ $record = new record();
+
+ $recordList = $record->GetList(array(array("reference", "=", $parameters["parameters"]["reference"])));
+ $currentRecord = $recordList[0];
+ $currentRecordVersions = $currentRecord->GetRecordversionList();
+ $currentVersion = $currentRecordVersions[0];
+
+ $result["currentVersion"] = array();
+ $result["currentVersion"]["reference"] = $currentVersion->reference;
+ $result["currentVersion"]["data"] = $currentVersion->data;
+ $result["currentVersion"]["header"] = $currentVersion->header;
+ $result["currentVersion"]["version"] = $currentVersion->version;
+ $result["currentVersion"]["creationDate"] = $currentVersion->creation_date;
+ $result["currentVersion"]["updateDate"] = $currentVersion->update_date;
+ $result["currentVersion"]["accessDate"] = $currentVersion->access_date;
+
+ $result["reference"] = $currentRecord->reference;
+ $result["data"] = $currentRecord->data;
+ $result["version"] = $currentRecord->version;
+ $result["creationDate"] = $currentRecord->creation_date;
+ $result["updateDate"] = $currentRecord->update_date;
+ $result["accessDate"] = $currentRecord->access_date;
+ $result["oldestUsedEncryptedVersion"] = "---";
+
+ //=============================================================
+ } else if ($message == "updateData") {
+//{
+// "message":"updateData",
+// "srpSharedSecret":"4e4aadb1d64513ec4dd42f5e8d5b2d4363de75e4424b6bcf178c9d6a246356c5",
+// "parameters":{
+// "records":[
+// {
+// "record":{
+// "reference":"740009737139a189cfa2b1019a6271aaa39467b59e259706564b642ff3838d50",
+// "data":"8hgR0Z+JDrUa812polDJ....JnZUKXNEqKI",
+// "version":"0.3"
+// },
+// "currentRecordVersion":{
+// "reference":"b1d82aeb9a0c4f6584bea68ba80839f43dd6ede79791549e29a1860554b144ee",
+// "recordReference":"740009737139a189cfa2b1019a6271aaa39467b59e259706564b642ff3838d50",
+// "data":"2d/UgKxxV+kBPV9GRUE.....VGonDoW0tqefxOJo=",
+// "version":"0.3",
+// "previousVersion":"55904195249037394316d3be3f5e78f08073170103bf0e7ab49a911c159cb0be",
+// "previousVersionKey":"YWiaZeMIVHaIl96OWW+2e8....6d6nHbn6cr2NA/dbQRuC2w=="
+// }
+// }
+// ],
+// "user":{
+// "header":"{\"rec.....sion\":\"0.1\"}",
+// "statistics":"tt3uU9hWBy8rNnMckgCnxMJh",
+// "version":"0.3",
+// "lock":"----"
+// }
+// }
+//}
+
+ $user = new user();
+ $user = $user->Get($_SESSION["userId"]);
+ updateUserData($parameters["parameters"]["user"], $user);
+ $user->Save();
+
+ $recordParameterList = $parameters["parameters"]["records"];
+ $c = count($recordParameterList);
+ for ($i=0; $i<$c; $i++) {
+ $recordList = $user->GetRecordList(array(array("reference", "=", $recordParameterList[$i]["record"]["reference"])));
+ $currentRecord = $recordList[0];
+ $currentRecordVersions = $currentRecord->GetRecordversionList();
+ $currentVersion = $currentRecordVersions[0];
+
+ updateRecordData($recordParameterList[$i], $currentRecord, $currentVersion);
+
+
+ $currentRecord->Save();
+ $currentVersion->Save();
+ }
+
+
+ $result["lock"] = $user->lock;
+ $result["result"] = "done";
+
+ //=============================================================
+ } else if ($message == "deleteRecords") {
+//{
+// "message":"deleteRecords",
+// "srpSharedSecret":"4a64982f7ee366954ec50b9efea62a902a097ef111410c2aa7c4d5343bd1cdd1",
+// "parameters":{
+// "recordReferences":["46494c81d10b80ab190d41e6806ef63869cfcc7a0ab8fe98cc3f93de4729bb9a"],
+// "user":{
+// "header":"{\"rec...rsion\":\"0.1\"}",
+// "statistics":"44kOOda0xYZjbcugJBdagBQx",
+// "version":"0.3",
+// "lock":"----"
+// }
+// }
+//}
+ $user = new user();
+ $user = $user->Get($_SESSION["userId"]);
+
+ $recordReferenceList = $parameters["parameters"]["recordReferences"];
+ $recordList = array();
+ $c = count($recordReferenceList);
+ for ($i=0; $i<$c; $i++) {
+ array_push($recordList, array("reference", "=", $recordReferenceList[$i]));
+ }
+
+ $record = new record();
+ $record->DeleteList($recordList, true);
+
+ updateUserData($parameters["parameters"]["user"], $user);
+ $user->Save();
+
+ $result["recordList"] = $recordList;
+ $result["lock"] = $user->lock;
+ $result["result"] = "done";
+
+ //=============================================================
+ } else if ($message == "deleteUser") {
+//{"message":"deleteUser", "srpSharedSecret":"e8e4ca6544dca49c95b3647d8358ad54c317048b74d2ac187ac25f719c9bac58", "parameters":{}}
+ $user = new user();
+ $user->Get($_SESSION["userId"]);
+ $user->Delete(true);
+
+ $result["result"] = "ok";
+
+ //=============================================================
+ } else if ($message == "addNewOneTimePassword") {
+//{
+// "message":"addNewOneTimePassword",
+// "srpSharedSecret":"96fee4af06c09ce954fe7a9f87970e943449186bebf70bac0af1d6ebb818dabb",
+// "parameters":{
+// "user":{
+// "header":"{\"records\":{\"index\":{\"419ea6....rsion\":\"0.1\"}",
+// "statistics":"rrlwNbDt83rpWT4S72upiVsC",
+// "version":"0.3",
+// "lock":"----"
+// },
+// "oneTimePassword":{
+// "reference":"29e26f3a2aae61fe5cf58c45296c6df4f3dceafe067ea550b455be345f44123c",
+// "key":"afb848208758361a96a298b9db08995cf036011747809357a90645bc93fdfa03",
+// "keyChecksum":"d1599ae443b5a566bfd93c0aeec4c81b42c0506ee09874dae050449580bb3486",
+// "data":"hsyY8DHksgR52x6c4j7XAtIUeY.....dxsr3XWt7CbGg==",
+// "version":"0.3"
+// }
+// }
+//}
+
+ fixOTPStatusTable();
+
+ $user = new user();
+ $user = $user->Get($_SESSION["userId"]);
+
+ $otp = new onetimepassword();
+ updateOTP($parameters["parameters"]["oneTimePassword"], $otp, "ACTIVE");
+ $user->AddOnetimepassword($otp);
+
+ updateUserData($parameters["parameters"]["user"], $user);
+ $user->Save();
+
+ $result["lock"] = $user->lock;
+ $result["result"] = "done";
+
+ //=============================================================
+ } else if ($message == "updateOneTimePasswords") {
+//{
+// "message":"updateOneTimePasswords",
+// "srpSharedSecret":"c78f8ed099ea421f4dd0a4e02dbaf1f7da925f0088188d99399874ff064a3d27",
+// "parameters":{
+// "user":{
+// "header":"{\"reco...sion\":\"0.1\"}",
+// "statistics":"UeRq75RZHzDC7elzrh/+OB5d",
+// "version":"0.3",
+// "lock":"----"
+// },
+// "oneTimePasswords":["f5f44c232f239efe48ab81a6236deea1a840d52946f7d4d782dad52b4c5359ce"]
+// }
+//}
+
+ $user = new user();
+ $user = $user->Get($_SESSION["userId"]);
+
+ $validOtpReferences = $parameters["parameters"]["oneTimePasswords"];
+
+ $otpList = $user->GetOnetimepasswordList();
+ $c = count($otpList);
+ for ($i=0; $i<$c; $i++) {
+ $currentOtp = $otpList[$i];
+ if (arrayContainsValue($validOtpReferences, $currentOtp->reference) == false) {
+ $currentOtp->Delete();
+ }
+ }
+
+ updateUserData($parameters["parameters"]["user"], $user);
+ $user->Save();
+
+ $result["result"] = $user->lock;
+
+ //=============================================================
+ } else if ($message == "getOneTimePasswordsDetails") {
+
+ //=============================================================
+ } else if ($message == "getLoginHistory") {
+ $result["result"] = array();
+
+ //=============================================================
+ } else if ($message == "upgradeUserCredentials") {
+//{
+// "message":"upgradeUserCredentials",
+// "srpSharedSecret":"f1c25322e1478c8fb26063e9eef2f6fc25e0460065a31cb718f80bcff8f8a735",
+// "parameters":{
+// "user":{
+// "header":"{\"reco...sion\":\"0.1\"}",
+// "statistics":"s72Xva+w7CLgH+ihwqwXUbyu",
+// "version":"0.3",
+// "lock":"----"
+// },
+// "credentials":{
+// "C":"57d15a8afbc1ae08103bd991d387ddfd8d26824276476fe709d754f098b6c26d",
+// "s":"d6735fc0486f391c4f3c947928f9e61a2418e7bed2bc9b25bb43f93acc52f636",
+// "v":"540c2ebbf941a481b6b2c9026c07fb46e8202e4408ed96864a696deb622baece",
+// "version":"0.2"
+// },
+// "oneTimePasswords":{
+// "923cdc61c4b877b263236124c44d69b459d240453a461cce8ddf7518b423ca94": "1HD6Ta0xsifEDhDwE....9WDK6tvrS6w==",
+// "fb1573cb9497652a81688a099a524fb116e604c6fbc191cf33406eb8438efa5f": "CocN0cSxLmMRdgNF9....o3xhGUEY68Q=="
+// }
+// }
+//}
+
+ $user = new user();
+ $user->Get($_SESSION["userId"]);
+
+ $otp = new onetimepassword();
+
+ updateUserCredentials($parameters["parameters"]["credentials"], $user);
+ updateUserData($parameters["parameters"]["user"], $user);
+
+ $otpList = $parameters["parameters"]["oneTimePasswords"];
+ foreach($otpList as $otpReference=>$otpData) {
+ $otpList = $otp->GetList(array(array("reference", "=", $otpReference)));
+ $currentOtp = $otpList[0];
+ $currentOtp->data = $otpData;
+ $currentOtp->Save();
+ }
+
+ $user->Save();
+
+ $result["lock"] = $user->lock;
+ $result["result"] = "done";
+
+ //=============================================================
+ } else if ($message == "echo") {
+ $result["result"] = $parameters;
+ }
+
+ //=============================================================
+ } else {
+ $result["error"] = "Wrong shared secret!";
+ }
+ break;
+
+ case "logout":
+error_log("logout");
+ session_destroy();
+ break;
+
+ default:
+error_log("default");
+ $result["result"] = $parameters;
+ break;
+ }
+
+ session_write_close();
+
+ echo(json_encode($result));
+error_log("result: ".json_encode($result));
+?> \ No newline at end of file
diff --git a/backend/php/src/json/JSON.php b/backend/php/src/json/JSON.php
new file mode 100644
index 0000000..0cddbdd
--- a/dev/null
+++ b/backend/php/src/json/JSON.php
@@ -0,0 +1,806 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Converts to and from JSON format.
+ *
+ * JSON (JavaScript Object Notation) is a lightweight data-interchange
+ * format. It is easy for humans to read and write. It is easy for machines
+ * to parse and generate. It is based on a subset of the JavaScript
+ * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
+ * This feature can also be found in Python. JSON is a text format that is
+ * completely language independent but uses conventions that are familiar
+ * to programmers of the C-family of languages, including C, C++, C#, Java,
+ * JavaScript, Perl, TCL, and many others. These properties make JSON an
+ * ideal data-interchange language.
+ *
+ * This package provides a simple encoder and decoder for JSON notation. It
+ * is intended for use with client-side Javascript applications that make
+ * use of HTTPRequest to perform server communication functions - data can
+ * be encoded into JSON notation for use in a client-side javascript, or
+ * decoded from incoming Javascript requests. JSON format is native to
+ * Javascript, and can be directly eval()'ed with no further parsing
+ * overhead
+ *
+ * All strings should be in ASCII or UTF-8 format!
+ *
+ * LICENSE: Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met: Redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following
+ * disclaimer. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * @category
+ * @package Services_JSON
+ * @author Michal Migurski <mike-json@teczno.com>
+ * @author Matt Knapp <mdknapp[at]gmail[dot]com>
+ * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
+ * @copyright 2005 Michal Migurski
+ * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
+ */
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_SLICE', 1);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_STR', 2);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_ARR', 3);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_OBJ', 4);
+
+/**
+ * Marker constant for Services_JSON::decode(), used to flag stack state
+ */
+define('SERVICES_JSON_IN_CMT', 5);
+
+/**
+ * Behavior switch for Services_JSON::decode()
+ */
+define('SERVICES_JSON_LOOSE_TYPE', 16);
+
+/**
+ * Behavior switch for Services_JSON::decode()
+ */
+define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
+
+/**
+ * Converts to and from JSON format.
+ *
+ * Brief example of use:
+ *
+ * <code>
+ * // create a new instance of Services_JSON
+ * $json = new Services_JSON();
+ *
+ * // convert a complexe value to JSON notation, and send it to the browser
+ * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
+ * $output = $json->encode($value);
+ *
+ * print($output);
+ * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
+ *
+ * // accept incoming POST data, assumed to be in JSON notation
+ * $input = file_get_contents('php://input', 1000000);
+ * $value = $json->decode($input);
+ * </code>
+ */
+class Services_JSON
+{
+ /**
+ * constructs a new JSON instance
+ *
+ * @param int $use object behavior flags; combine with boolean-OR
+ *
+ * possible values:
+ * - SERVICES_JSON_LOOSE_TYPE: loose typing.
+ * "{...}" syntax creates associative arrays
+ * instead of objects in decode().
+ * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
+ * Values which can't be encoded (e.g. resources)
+ * appear as NULL instead of throwing errors.
+ * By default, a deeply-nested resource will
+ * bubble up with an error, so all return values
+ * from encode() should be checked with isError()
+ */
+ function Services_JSON($use = 0)
+ {
+ $this->use = $use;
+ }
+
+ /**
+ * convert a string from one UTF-16 char to one UTF-8 char
+ *
+ * Normally should be handled by mb_convert_encoding, but
+ * provides a slower PHP-only method for installations
+ * that lack the multibye string extension.
+ *
+ * @param string $utf16 UTF-16 character
+ * @return string UTF-8 character
+ * @access private
+ */
+ function utf162utf8($utf16)
+ {
+ // oh please oh please oh please oh please oh please
+ if(function_exists('mb_convert_encoding')) {
+ return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
+ }
+
+ $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
+
+ switch(true) {
+ case ((0x7F & $bytes) == $bytes):
+ // this case should never be reached, because we are in ASCII range
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0x7F & $bytes);
+
+ case (0x07FF & $bytes) == $bytes:
+ // return a 2-byte UTF-8 character
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0xC0 | (($bytes >> 6) & 0x1F))
+ . chr(0x80 | ($bytes & 0x3F));
+
+ case (0xFFFF & $bytes) == $bytes:
+ // return a 3-byte UTF-8 character
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0xE0 | (($bytes >> 12) & 0x0F))
+ . chr(0x80 | (($bytes >> 6) & 0x3F))
+ . chr(0x80 | ($bytes & 0x3F));
+ }
+
+ // ignoring UTF-32 for now, sorry
+ return '';
+ }
+
+ /**
+ * convert a string from one UTF-8 char to one UTF-16 char
+ *
+ * Normally should be handled by mb_convert_encoding, but
+ * provides a slower PHP-only method for installations
+ * that lack the multibye string extension.
+ *
+ * @param string $utf8 UTF-8 character
+ * @return string UTF-16 character
+ * @access private
+ */
+ function utf82utf16($utf8)
+ {
+ // oh please oh please oh please oh please oh please
+ if(function_exists('mb_convert_encoding')) {
+ return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
+ }
+
+ switch(strlen($utf8)) {
+ case 1:
+ // this case should never be reached, because we are in ASCII range
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return $utf8;
+
+ case 2:
+ // return a UTF-16 character from a 2-byte UTF-8 char
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0x07 & (ord($utf8{0}) >> 2))
+ . chr((0xC0 & (ord($utf8{0}) << 6))
+ | (0x3F & ord($utf8{1})));
+
+ case 3:
+ // return a UTF-16 character from a 3-byte UTF-8 char
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr((0xF0 & (ord($utf8{0}) << 4))
+ | (0x0F & (ord($utf8{1}) >> 2)))
+ . chr((0xC0 & (ord($utf8{1}) << 6))
+ | (0x7F & ord($utf8{2})));
+ }
+
+ // ignoring UTF-32 for now, sorry
+ return '';
+ }
+
+ /**
+ * encodes an arbitrary variable into JSON format
+ *
+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
+ * see argument 1 to Services_JSON() above for array-parsing behavior.
+ * if var is a strng, note that encode() always expects it
+ * to be in ASCII or UTF-8 format!
+ *
+ * @return mixed JSON string representation of input var or an error if a problem occurs
+ * @access public
+ */
+ function encode($var)
+ {
+ switch (gettype($var)) {
+ case 'boolean':
+ return $var ? 'true' : 'false';
+
+ case 'NULL':
+ return 'null';
+
+ case 'integer':
+ return (int) $var;
+
+ case 'double':
+ case 'float':
+ return (float) $var;
+
+ case 'string':
+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
+ $ascii = '';
+ $strlen_var = strlen($var);
+
+ /*
+ * Iterate over every character in the string,
+ * escaping with a slash or encoding to UTF-8 where necessary
+ */
+ for ($c = 0; $c < $strlen_var; ++$c) {
+
+ $ord_var_c = ord($var{$c});
+
+ switch (true) {
+ case $ord_var_c == 0x08:
+ $ascii .= '\b';
+ break;
+ case $ord_var_c == 0x09:
+ $ascii .= '\t';
+ break;
+ case $ord_var_c == 0x0A:
+ $ascii .= '\n';
+ break;
+ case $ord_var_c == 0x0C:
+ $ascii .= '\f';
+ break;
+ case $ord_var_c == 0x0D:
+ $ascii .= '\r';
+ break;
+
+ case $ord_var_c == 0x22:
+ case $ord_var_c == 0x2F:
+ case $ord_var_c == 0x5C:
+ // double quote, slash, slosh
+ $ascii .= '\\'.$var{$c};
+ break;
+
+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
+ // characters U-00000000 - U-0000007F (same as ASCII)
+ $ascii .= $var{$c};
+ break;
+
+ case (($ord_var_c & 0xE0) == 0xC0):
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
+ $c += 1;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xF0) == 0xE0):
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c + 1}),
+ ord($var{$c + 2}));
+ $c += 2;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xF8) == 0xF0):
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c + 1}),
+ ord($var{$c + 2}),
+ ord($var{$c + 3}));
+ $c += 3;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xFC) == 0xF8):
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c + 1}),
+ ord($var{$c + 2}),
+ ord($var{$c + 3}),
+ ord($var{$c + 4}));
+ $c += 4;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xFE) == 0xFC):
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c + 1}),
+ ord($var{$c + 2}),
+ ord($var{$c + 3}),
+ ord($var{$c + 4}),
+ ord($var{$c + 5}));
+ $c += 5;
+ $utf16 = $this->utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+ }
+ }
+
+ return '"'.$ascii.'"';
+
+ case 'array':
+ /*
+ * As per JSON spec if any array key is not an integer
+ * we must treat the the whole array as an object. We
+ * also try to catch a sparsely populated associative
+ * array with numeric keys here because some JS engines
+ * will create an array with empty indexes up to
+ * max_index which can cause memory issues and because
+ * the keys, which may be relevant, will be remapped
+ * otherwise.
+ *
+ * As per the ECMA and JSON specification an object may
+ * have any string as a property. Unfortunately due to
+ * a hole in the ECMA specification if the key is a
+ * ECMA reserved word or starts with a digit the
+ * parameter is only accessible using ECMAScript's
+ * bracket notation.
+ */
+
+ // treat as a JSON object
+ if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
+ $properties = array_map(array($this, 'name_value'),
+ array_keys($var),
+ array_values($var));
+
+ foreach($properties as $property) {
+ if(Services_JSON::isError($property)) {
+ return $property;
+ }
+ }
+
+ return '{' . join(',', $properties) . '}';
+ }
+
+ // treat it like a regular array
+ $elements = array_map(array($this, 'encode'), $var);
+
+ foreach($elements as $element) {
+ if(Services_JSON::isError($element)) {
+ return $element;
+ }
+ }
+
+ return '[' . join(',', $elements) . ']';
+
+ case 'object':
+ $vars = get_object_vars($var);
+
+ $properties = array_map(array($this, 'name_value'),
+ array_keys($vars),
+ array_values($vars));
+
+ foreach($properties as $property) {
+ if(Services_JSON::isError($property)) {
+ return $property;
+ }
+ }
+
+ return '{' . join(',', $properties) . '}';
+
+ default:
+ return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
+ ? 'null'
+ : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
+ }
+ }
+
+ /**
+ * array-walking function for use in generating JSON-formatted name-value pairs
+ *
+ * @param string $name name of key to use
+ * @param mixed $value reference to an array element to be encoded
+ *
+ * @return string JSON-formatted name-value pair, like '"name":value'
+ * @access private
+ */
+ function name_value($name, $value)
+ {
+ $encoded_value = $this->encode($value);
+
+ if(Services_JSON::isError($encoded_value)) {
+ return $encoded_value;
+ }
+
+ return $this->encode(strval($name)) . ':' . $encoded_value;
+ }
+
+ /**
+ * reduce a string by removing leading and trailing comments and whitespace
+ *
+ * @param $str string string value to strip of comments and whitespace
+ *
+ * @return string string value stripped of comments and whitespace
+ * @access private
+ */
+ function reduce_string($str)
+ {
+ $str = preg_replace(array(
+
+ // eliminate single line comments in '// ...' form
+ '#^\s*//(.+)$#m',
+
+ // eliminate multi-line comments in '/* ... */' form, at start of string
+ '#^\s*/\*(.+)\*/#Us',
+
+ // eliminate multi-line comments in '/* ... */' form, at end of string
+ '#/\*(.+)\*/\s*$#Us'
+
+ ), '', $str);
+
+ // eliminate extraneous space
+ return trim($str);
+ }
+
+ /**
+ * decodes a JSON string into appropriate variable
+ *
+ * @param string $str JSON-formatted string
+ *
+ * @return mixed number, boolean, string, array, or object
+ * corresponding to given JSON input string.
+ * See argument 1 to Services_JSON() above for object-output behavior.
+ * Note that decode() always returns strings
+ * in ASCII or UTF-8 format!
+ * @access public
+ */
+ function decode($str)
+ {
+ $str = $this->reduce_string($str);
+
+ switch (strtolower($str)) {
+ case 'true':
+ return true;
+
+ case 'false':
+ return false;
+
+ case 'null':
+ return null;
+
+ default:
+ $m = array();
+
+ if (is_numeric($str)) {
+ // Lookie-loo, it's a number
+
+ // This would work on its own, but I'm trying to be
+ // good about returning integers where appropriate:
+ // return (float)$str;
+
+ // Return float or int, as appropriate
+ return ((float)$str == (integer)$str)
+ ? (integer)$str
+ : (float)$str;
+
+ } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
+ // STRINGS RETURNED IN UTF-8 FORMAT
+ $delim = substr($str, 0, 1);
+ $chrs = substr($str, 1, -1);
+ $utf8 = '';
+ $strlen_chrs = strlen($chrs);
+
+ for ($c = 0; $c < $strlen_chrs; ++$c) {
+
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
+ $ord_chrs_c = ord($chrs{$c});
+
+ switch (true) {
+ case $substr_chrs_c_2 == '\b':
+ $utf8 .= chr(0x08);
+ ++$c;
+ break;
+ case $substr_chrs_c_2 == '\t':
+ $utf8 .= chr(0x09);
+ ++$c;
+ break;
+ case $substr_chrs_c_2 == '\n':
+ $utf8 .= chr(0x0A);
+ ++$c;
+ break;
+ case $substr_chrs_c_2 == '\f':
+ $utf8 .= chr(0x0C);
+ ++$c;
+ break;
+ case $substr_chrs_c_2 == '\r':
+ $utf8 .= chr(0x0D);
+ ++$c;
+ break;
+
+ case $substr_chrs_c_2 == '\\"':
+ case $substr_chrs_c_2 == '\\\'':
+ case $substr_chrs_c_2 == '\\\\':
+ case $substr_chrs_c_2 == '\\/':
+ if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
+ ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
+ $utf8 .= $chrs{++$c};
+ }
+ break;
+
+ case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
+ // single, escaped unicode character
+ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
+ . chr(hexdec(substr($chrs, ($c + 4), 2)));
+ $utf8 .= $this->utf162utf8($utf16);
+ $c += 5;
+ break;
+
+ case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
+ $utf8 .= $chrs{$c};
+ break;
+
+ case ($ord_chrs_c & 0xE0) == 0xC0:
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
+ //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 2);
+ ++$c;
+ break;
+
+ case ($ord_chrs_c & 0xF0) == 0xE0:
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 3);
+ $c += 2;
+ break;
+
+ case ($ord_chrs_c & 0xF8) == 0xF0:
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 4);
+ $c += 3;
+ break;
+
+ case ($ord_chrs_c & 0xFC) == 0xF8:
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 5);
+ $c += 4;
+ break;
+
+ case ($ord_chrs_c & 0xFE) == 0xFC:
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 6);
+ $c += 5;
+ break;
+
+ }
+
+ }
+
+ return $utf8;
+
+ } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
+ // array, or object notation
+
+ if ($str{0} == '[') {
+ $stk = array(SERVICES_JSON_IN_ARR);
+ $arr = array();
+ } else {
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+ $stk = array(SERVICES_JSON_IN_OBJ);
+ $obj = array();
+ } else {
+ $stk = array(SERVICES_JSON_IN_OBJ);
+ $obj = new stdClass();
+ }
+ }
+
+ array_push($stk, array('what' => SERVICES_JSON_SLICE,
+ 'where' => 0,
+ 'delim' => false));
+
+ $chrs = substr($str, 1, -1);
+ $chrs = $this->reduce_string($chrs);
+
+ if ($chrs == '') {
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
+ return $arr;
+
+ } else {
+ return $obj;
+
+ }
+ }
+
+ //print("\nparsing {$chrs}\n");
+
+ $strlen_chrs = strlen($chrs);
+
+ for ($c = 0; $c <= $strlen_chrs; ++$c) {
+
+ $top = end($stk);
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
+
+ if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
+ // found a comma that is not inside a string, array, etc.,
+ // OR we've reached the end of the character list
+ $slice = substr($chrs, $top['where'], ($c - $top['where']));
+ array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
+ //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
+ // we are in an array, so just push an element onto the stack
+ array_push($arr, $this->decode($slice));
+
+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+ // we are in an object, so figure
+ // out the property name and set an
+ // element in an associative array,
+ // for now
+ $parts = array();
+
+ if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+ // "name":value pair
+ $key = $this->decode($parts[1]);
+ $val = $this->decode($parts[2]);
+
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+ $obj[$key] = $val;
+ } else {
+ $obj->$key = $val;
+ }
+ } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+ // name:value pair, where name is unquoted
+ $key = $parts[1];
+ $val = $this->decode($parts[2]);
+
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
+ $obj[$key] = $val;
+ } else {
+ $obj->$key = $val;
+ }
+ }
+
+ }
+
+ } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
+ // found a quote, and we are not inside a string
+ array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
+ //print("Found start of string at {$c}\n");
+
+ } elseif (($chrs{$c} == $top['delim']) &&
+ ($top['what'] == SERVICES_JSON_IN_STR) &&
+ ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
+ // found a quote, we're in a string, and it's not escaped
+ // we know that it's not escaped becase there is _not_ an
+ // odd number of backslashes at the end of the string so far
+ array_pop($stk);
+ //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
+
+ } elseif (($chrs{$c} == '[') &&
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+ // found a left-bracket, and we are in an array, object, or slice
+ array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
+ //print("Found start of array at {$c}\n");
+
+ } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
+ // found a right-bracket, and we're in an array
+ array_pop($stk);
+ //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ } elseif (($chrs{$c} == '{') &&
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+ // found a left-brace, and we are in an array, object, or slice
+ array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
+ //print("Found start of object at {$c}\n");
+
+ } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
+ // found a right-brace, and we're in an object
+ array_pop($stk);
+ //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ } elseif (($substr_chrs_c_2 == '/*') &&
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
+ // found a comment start, and we are in an array, object, or slice
+ array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
+ $c++;
+ //print("Found start of comment at {$c}\n");
+
+ } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
+ // found a comment end, and we're in one now
+ array_pop($stk);
+ $c++;
+
+ for ($i = $top['where']; $i <= $c; ++$i)
+ $chrs = substr_replace($chrs, ' ', $i, 1);
+
+ //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ }
+
+ }
+
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
+ return $arr;
+
+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
+ return $obj;
+
+ }
+
+ }
+ }
+ }
+
+ /**
+ * @todo Ultimately, this should just call PEAR::isError()
+ */
+ function isError($data, $code = null)
+ {
+ if (class_exists('pear')) {
+ return PEAR::isError($data, $code);
+ } elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
+ is_subclass_of($data, 'services_json_error'))) {
+ return true;
+ }
+
+ return false;
+ }
+}
+
+if (class_exists('PEAR_Error')) {
+
+ class Services_JSON_Error extends PEAR_Error
+ {
+ function Services_JSON_Error($message = 'unknown error', $code = null,
+ $mode = null, $options = null, $userinfo = null)
+ {
+ parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
+ }
+ }
+
+} else {
+
+ /**
+ * @todo Ultimately, this class shall be descended from PEAR_Error
+ */
+ class Services_JSON_Error
+ {
+ function Services_JSON_Error($message = 'unknown error', $code = null,
+ $mode = null, $options = null, $userinfo = null)
+ {
+
+ }
+ }
+
+}
+
+?>
diff --git a/backend/php/src/objects/class.database.php b/backend/php/src/objects/class.database.php
new file mode 100644
index 0000000..e8a13f7
--- a/dev/null
+++ b/backend/php/src/objects/class.database.php
@@ -0,0 +1,79 @@
+<?php
+/**
+* <b>Database Connection</b> class.
+* @author Php Object Generator
+* @version 3.0d / PHP5.1
+* @see http://www.phpobjectgenerator.com/
+* @copyright Free for personal & commercial use. (Offered under the BSD license)
+*/
+ Class Database
+{
+ public $connection;
+
+ private function Database()
+ {
+ $databaseName = $GLOBALS['configuration']['db'];
+ $serverName = $GLOBALS['configuration']['host'];
+ $databaseUser = $GLOBALS['configuration']['user'];
+ $databasePassword = $GLOBALS['configuration']['pass'];
+ $databasePort = $GLOBALS['configuration']['port'];
+ $this->connection = mysql_connect ($serverName.":".$databasePort, $databaseUser, $databasePassword);
+ if ($this->connection)
+ {
+ if (!mysql_select_db ($databaseName))
+ {
+ throw new Exception('I cannot find the specified database "'.$databaseName.'". Please edit configuration.php.');
+ }
+ }
+ else
+ {
+ throw new Exception('I cannot connect to the database. Please edit configuration.php with your database configuration.');
+ }
+ }
+
+ public static function Connect()
+ {
+ static $database = null;
+ if (!isset($database))
+ {
+ $database = new Database();
+ }
+ return $database->connection;
+ }
+
+ public static function Reader($query, $connection)
+ {
+ $cursor = mysql_query($query, $connection);
+ return $cursor;
+ }
+
+ public static function Read($cursor)
+ {
+ return mysql_fetch_assoc($cursor);
+ }
+
+ public static function NonQuery($query, $connection)
+ {
+ mysql_query($query, $connection);
+ $result = mysql_affected_rows($connection);
+ if ($result == -1)
+ {
+ return false;
+ }
+ return $result;
+
+ }
+
+ public static function Query($query, $connection)
+ {
+ $result = mysql_query($query, $connection);
+ return mysql_num_rows($result);
+ }
+
+ public static function InsertOrUpdate($query, $connection)
+ {
+ $result = mysql_query($query, $connection);
+ return intval(mysql_insert_id($connection));
+ }
+}
+?>
diff --git a/backend/php/src/objects/class.onetimepassword.php b/backend/php/src/objects/class.onetimepassword.php
new file mode 100644
index 0000000..90d5f1d
--- a/dev/null
+++ b/backend/php/src/objects/class.onetimepassword.php
@@ -0,0 +1,400 @@
+<?php
+/*
+ This SQL query will create the table to store your object.
+
+ CREATE TABLE `onetimepassword` (
+ `onetimepasswordid` int(11) NOT NULL auto_increment,
+ `userid` int(11) NOT NULL,
+ `onetimepasswordstatusid` int(11) NOT NULL,
+ `reference` VARCHAR(255) NOT NULL,
+ `key` VARCHAR(255) NOT NULL,
+ `key_checksum` VARCHAR(255) NOT NULL,
+ `data` TEXT NOT NULL,
+ `version` VARCHAR(255) NOT NULL,
+ `creation_date` TIMESTAMP NOT NULL,
+ `request_date` TIMESTAMP NOT NULL,
+ `usage_date` TIMESTAMP NOT NULL, INDEX(`userid`,`onetimepasswordstatusid`), PRIMARY KEY (`onetimepasswordid`)) ENGINE=MyISAM;
+*/
+
+/**
+* <b>onetimepassword</b> class with integrated CRUD methods.
+* @author Php Object Generator
+* @version POG 3.0d / PHP5.1
+* @copyright Free for personal & commercial use. (Offered under the BSD license)
+* @link http://www.phpobjectgenerator.com/?language=php5.1&wrapper=pog&objectName=onetimepassword&attributeList=array+%28%0A++0+%3D%3E+%27user%27%2C%0A++1+%3D%3E+%27onetimepasswordstatus%27%2C%0A++2+%3D%3E+%27reference%27%2C%0A++3+%3D%3E+%27key%27%2C%0A++4+%3D%3E+%27key_checksum%27%2C%0A++5+%3D%3E+%27data%27%2C%0A++6+%3D%3E+%27version%27%2C%0A++7+%3D%3E+%27creation_date%27%2C%0A++8+%3D%3E+%27request_date%27%2C%0A++9+%3D%3E+%27usage_date%27%2C%0A%29&typeList=array+%28%0A++0+%3D%3E+%27BELONGSTO%27%2C%0A++1+%3D%3E+%27BELONGSTO%27%2C%0A++2+%3D%3E+%27VARCHAR%28255%29%27%2C%0A++3+%3D%3E+%27VARCHAR%28255%29%27%2C%0A++4+%3D%3E+%27VARCHAR%28255%29%27%2C%0A++5+%3D%3E+%27TEXT%27%2C%0A++6+%3D%3E+%27VARCHAR%28255%29%27%2C%0A++7+%3D%3E+%27TIMESTAMP%27%2C%0A++8+%3D%3E+%27TIMESTAMP%27%2C%0A++9+%3D%3E+%27TIMESTAMP%27%2C%0A%29
+*/
+include_once('class.pog_base.php');
+class onetimepassword extends POG_Base
+{
+ public $onetimepasswordId = '';
+
+ /**
+ * @var INT(11)
+ */
+ public $userId;
+
+ /**
+ * @var INT(11)
+ */
+ public $onetimepasswordstatusId;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $reference;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $key;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $key_checksum;
+
+ /**
+ * @var TEXT
+ */
+ public $data;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $version;
+
+ /**
+ * @var TIMESTAMP
+ */
+ public $creation_date;
+
+ /**
+ * @var TIMESTAMP
+ */
+ public $request_date;
+
+ /**
+ * @var TIMESTAMP
+ */
+ public $usage_date;
+
+ public $pog_attribute_type = array(
+ "onetimepasswordId" => array('db_attributes' => array("NUMERIC", "INT")),
+ "user" => array('db_attributes' => array("OBJECT", "BELONGSTO")),
+ "onetimepasswordstatus" => array('db_attributes' => array("OBJECT", "BELONGSTO")),
+ "reference" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "key" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "key_checksum" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "data" => array('db_attributes' => array("TEXT", "TEXT")),
+ "version" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "creation_date" => array('db_attributes' => array("NUMERIC", "TIMESTAMP")),
+ "request_date" => array('db_attributes' => array("NUMERIC", "TIMESTAMP")),
+ "usage_date" => array('db_attributes' => array("NUMERIC", "TIMESTAMP")),
+ );
+ public $pog_query;
+
+
+ /**
+ * Getter for some private attributes
+ * @return mixed $attribute
+ */
+ public function __get($attribute)
+ {
+ if (isset($this->{"_".$attribute}))
+ {
+ return $this->{"_".$attribute};
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function onetimepassword($reference='', $key='', $key_checksum='', $data='', $version='', $creation_date='', $request_date='', $usage_date='')
+ {
+ $this->reference = $reference;
+ $this->key = $key;
+ $this->key_checksum = $key_checksum;
+ $this->data = $data;
+ $this->version = $version;
+ $this->creation_date = $creation_date;
+ $this->request_date = $request_date;
+ $this->usage_date = $usage_date;
+ }
+
+
+ /**
+ * Gets object from database
+ * @param integer $onetimepasswordId
+ * @return object $onetimepassword
+ */
+ function Get($onetimepasswordId)
+ {
+ $connection = Database::Connect();
+ $this->pog_query = "select * from `onetimepassword` where `onetimepasswordid`='".intval($onetimepasswordId)."' LIMIT 1";
+ $cursor = Database::Reader($this->pog_query, $connection);
+ while ($row = Database::Read($cursor))
+ {
+ $this->onetimepasswordId = $row['onetimepasswordid'];
+ $this->userId = $row['userid'];
+ $this->onetimepasswordstatusId = $row['onetimepasswordstatusid'];
+ $this->reference = $this->Unescape($row['reference']);
+ $this->key = $this->Unescape($row['key']);
+ $this->key_checksum = $this->Unescape($row['key_checksum']);
+ $this->data = $this->Unescape($row['data']);
+ $this->version = $this->Unescape($row['version']);
+ $this->creation_date = $row['creation_date'];
+ $this->request_date = $row['request_date'];
+ $this->usage_date = $row['usage_date'];
+ }
+ return $this;
+ }
+
+
+ /**
+ * Returns a sorted array of objects that match given conditions
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param string $sortBy
+ * @param boolean $ascending
+ * @param int limit
+ * @return array $onetimepasswordList
+ */
+ function GetList($fcv_array = array(), $sortBy='', $ascending=true, $limit='')
+ {
+ $connection = Database::Connect();
+ $sqlLimit = ($limit != '' ? "LIMIT $limit" : '');
+ $this->pog_query = "select * from `onetimepassword` ";
+ $onetimepasswordList = Array();
+ if (sizeof($fcv_array) > 0)
+ {
+ $this->pog_query .= " where ";
+ for ($i=0, $c=sizeof($fcv_array); $i<$c; $i++)
+ {
+ if (sizeof($fcv_array[$i]) == 1)
+ {
+ $this->pog_query .= " ".$fcv_array[$i][0]." ";
+ continue;
+ }
+ else
+ {
+ if ($i > 0 && sizeof($fcv_array[$i-1]) != 1)
+ {
+ $this->pog_query .= " AND ";
+ }
+ if (isset($this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes']) && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'SET')
+ {
+ if ($GLOBALS['configuration']['db_encoding'] == 1)
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? "BASE64_DECODE(".$fcv_array[$i][2].")" : "'".$fcv_array[$i][2]."'";
+ $this->pog_query .= "BASE64_DECODE(`".$fcv_array[$i][0]."`) ".$fcv_array[$i][1]." ".$value;
+ }
+ else
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? $fcv_array[$i][2] : "'".$this->Escape($fcv_array[$i][2])."'";
+ $this->pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." ".$value;
+ }
+ }
+ else
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? $fcv_array[$i][2] : "'".$fcv_array[$i][2]."'";
+ $this->pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." ".$value;
+ }
+ }
+ }
+ }
+ if ($sortBy != '')
+ {
+ if (isset($this->pog_attribute_type[$sortBy]['db_attributes']) && $this->pog_attribute_type[$sortBy]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$sortBy]['db_attributes'][0] != 'SET')
+ {
+ if ($GLOBALS['configuration']['db_encoding'] == 1)
+ {
+ $sortBy = "BASE64_DECODE($sortBy) ";
+ }
+ else
+ {
+ $sortBy = "$sortBy ";
+ }
+ }
+ else
+ {
+ $sortBy = "$sortBy ";
+ }
+ }
+ else
+ {
+ $sortBy = "onetimepasswordid";
+ }
+ $this->pog_query .= " order by ".$sortBy." ".($ascending ? "asc" : "desc")." $sqlLimit";
+ $thisObjectName = get_class($this);
+ $cursor = Database::Reader($this->pog_query, $connection);
+ while ($row = Database::Read($cursor))
+ {
+ $onetimepassword = new $thisObjectName();
+ $onetimepassword->onetimepasswordId = $row['onetimepasswordid'];
+ $onetimepassword->userId = $row['userid'];
+ $onetimepassword->onetimepasswordstatusId = $row['onetimepasswordstatusid'];
+ $onetimepassword->reference = $this->Unescape($row['reference']);
+ $onetimepassword->key = $this->Unescape($row['key']);
+ $onetimepassword->key_checksum = $this->Unescape($row['key_checksum']);
+ $onetimepassword->data = $this->Unescape($row['data']);
+ $onetimepassword->version = $this->Unescape($row['version']);
+ $onetimepassword->creation_date = $row['creation_date'];
+ $onetimepassword->request_date = $row['request_date'];
+ $onetimepassword->usage_date = $row['usage_date'];
+ $onetimepasswordList[] = $onetimepassword;
+ }
+ return $onetimepasswordList;
+ }
+
+
+ /**
+ * Saves the object to the database
+ * @return integer $onetimepasswordId
+ */
+ function Save()
+ {
+ $connection = Database::Connect();
+ $this->pog_query = "select `onetimepasswordid` from `onetimepassword` where `onetimepasswordid`='".$this->onetimepasswordId."' LIMIT 1";
+ $rows = Database::Query($this->pog_query, $connection);
+ if ($rows > 0)
+ {
+ $this->pog_query = "update `onetimepassword` set
+ `userid`='".$this->userId."',
+ `onetimepasswordstatusid`='".$this->onetimepasswordstatusId."',
+ `reference`='".$this->Escape($this->reference)."',
+ `key`='".$this->Escape($this->key)."',
+ `key_checksum`='".$this->Escape($this->key_checksum)."',
+ `data`='".$this->Escape($this->data)."',
+ `version`='".$this->Escape($this->version)."',
+ `creation_date`='".$this->creation_date."',
+ `request_date`='".$this->request_date."',
+ `usage_date`='".$this->usage_date."' where `onetimepasswordid`='".$this->onetimepasswordId."'";
+ }
+ else
+ {
+ $this->pog_query = "insert into `onetimepassword` (`userid`, `onetimepasswordstatusid`, `reference`, `key`, `key_checksum`, `data`, `version`, `creation_date`, `request_date`, `usage_date` ) values (
+ '".$this->userId."',
+ '".$this->onetimepasswordstatusId."',
+ '".$this->Escape($this->reference)."',
+ '".$this->Escape($this->key)."',
+ '".$this->Escape($this->key_checksum)."',
+ '".$this->Escape($this->data)."',
+ '".$this->Escape($this->version)."',
+ '".$this->creation_date."',
+ '".$this->request_date."',
+ '".$this->usage_date."' )";
+ }
+ $insertId = Database::InsertOrUpdate($this->pog_query, $connection);
+ if ($this->onetimepasswordId == "")
+ {
+ $this->onetimepasswordId = $insertId;
+ }
+ return $this->onetimepasswordId;
+ }
+
+
+ /**
+ * Clones the object and saves it to the database
+ * @return integer $onetimepasswordId
+ */
+ function SaveNew()
+ {
+ $this->onetimepasswordId = '';
+ return $this->Save();
+ }
+
+
+ /**
+ * Deletes the object from the database
+ * @return boolean
+ */
+ function Delete()
+ {
+ $connection = Database::Connect();
+ $this->pog_query = "delete from `onetimepassword` where `onetimepasswordid`='".$this->onetimepasswordId."'";
+ return Database::NonQuery($this->pog_query, $connection);
+ }
+
+
+ /**
+ * Deletes a list of objects that match given conditions
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param bool $deep
+ * @return
+ */
+ function DeleteList($fcv_array)
+ {
+ if (sizeof($fcv_array) > 0)
+ {
+ $connection = Database::Connect();
+ $pog_query = "delete from `onetimepassword` where ";
+ for ($i=0, $c=sizeof($fcv_array); $i<$c; $i++)
+ {
+ if (sizeof($fcv_array[$i]) == 1)
+ {
+ $pog_query .= " ".$fcv_array[$i][0]." ";
+ continue;
+ }
+ else
+ {
+ if ($i > 0 && sizeof($fcv_array[$i-1]) !== 1)
+ {
+ $pog_query .= " AND ";
+ }
+ if (isset($this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes']) && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'SET')
+ {
+ $pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." '".$this->Escape($fcv_array[$i][2])."'";
+ }
+ else
+ {
+ $pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." '".$fcv_array[$i][2]."'";
+ }
+ }
+ }
+ return Database::NonQuery($pog_query, $connection);
+ }
+ }
+
+
+ /**
+ * Associates the user object to this one
+ * @return boolean
+ */
+ function GetUser()
+ {
+ $user = new user();
+ return $user->Get($this->userId);
+ }
+
+
+ /**
+ * Associates the user object to this one
+ * @return
+ */
+ function SetUser(&$user)
+ {
+ $this->userId = $user->userId;
+ }
+
+
+ /**
+ * Associates the onetimepasswordstatus object to this one
+ * @return boolean
+ */
+ function GetOnetimepasswordstatus()
+ {
+ $onetimepasswordstatus = new onetimepasswordstatus();
+ return $onetimepasswordstatus->Get($this->onetimepasswordstatusId);
+ }
+
+
+ /**
+ * Associates the onetimepasswordstatus object to this one
+ * @return
+ */
+ function SetOnetimepasswordstatus(&$onetimepasswordstatus)
+ {
+ $this->onetimepasswordstatusId = $onetimepasswordstatus->onetimepasswordstatusId;
+ }
+}
+?> \ No newline at end of file
diff --git a/backend/php/src/objects/class.onetimepasswordstatus.php b/backend/php/src/objects/class.onetimepasswordstatus.php
new file mode 100644
index 0000000..f0ef08a
--- a/dev/null
+++ b/backend/php/src/objects/class.onetimepasswordstatus.php
@@ -0,0 +1,368 @@
+<?php
+/*
+ This SQL query will create the table to store your object.
+
+ CREATE TABLE `onetimepasswordstatus` (
+ `onetimepasswordstatusid` int(11) NOT NULL auto_increment,
+ `code` VARCHAR(255) NOT NULL,
+ `name` VARCHAR(255) NOT NULL,
+ `description` TEXT NOT NULL, PRIMARY KEY (`onetimepasswordstatusid`)) ENGINE=MyISAM;
+*/
+
+/**
+* <b>onetimepasswordstatus</b> class with integrated CRUD methods.
+* @author Php Object Generator
+* @version POG 3.0d / PHP5.1 MYSQL
+* @see http://www.phpobjectgenerator.com/plog/tutorials/45/pdo-mysql
+* @copyright Free for personal & commercial use. (Offered under the BSD license)
+* @link http://www.phpobjectgenerator.com/?language=php5.1&wrapper=pdo&pdoDriver=mysql&objectName=onetimepasswordstatus&attributeList=array+%28%0A++0+%3D%3E+%27onetimepassword%27%2C%0A++1+%3D%3E+%27code%27%2C%0A++2+%3D%3E+%27name%27%2C%0A++3+%3D%3E+%27description%27%2C%0A%29&typeList=array%2B%2528%250A%2B%2B0%2B%253D%253E%2B%2527HASMANY%2527%252C%250A%2B%2B1%2B%253D%253E%2B%2527VARCHAR%2528255%2529%2527%252C%250A%2B%2B2%2B%253D%253E%2B%2527VARCHAR%2528255%2529%2527%252C%250A%2B%2B3%2B%253D%253E%2B%2527TEXT%2527%252C%250A%2529
+*/
+include_once('class.pog_base.php');
+class onetimepasswordstatus extends POG_Base
+{
+ public $onetimepasswordstatusId = '';
+
+ /**
+ * @var private array of onetimepassword objects
+ */
+ private $_onetimepasswordList = array();
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $code;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $name;
+
+ /**
+ * @var TEXT
+ */
+ public $description;
+
+ public $pog_attribute_type = array(
+ "onetimepasswordstatusId" => array('db_attributes' => array("NUMERIC", "INT")),
+ "onetimepassword" => array('db_attributes' => array("OBJECT", "HASMANY")),
+ "code" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "name" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "description" => array('db_attributes' => array("TEXT", "TEXT")),
+ );
+ public $pog_query;
+
+
+ /**
+ * Getter for some private attributes
+ * @return mixed $attribute
+ */
+ public function __get($attribute)
+ {
+ if (isset($this->{"_".$attribute}))
+ {
+ return $this->{"_".$attribute};
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function onetimepasswordstatus($code='', $name='', $description='')
+ {
+ $this->_onetimepasswordList = array();
+ $this->code = $code;
+ $this->name = $name;
+ $this->description = $description;
+ }
+
+
+ /**
+ * Gets object from database
+ * @param integer $onetimepasswordstatusId
+ * @return object $onetimepasswordstatus
+ */
+ function Get($onetimepasswordstatusId)
+ {
+ $connection = Database::Connect();
+ $this->pog_query = "select * from `onetimepasswordstatus` where `onetimepasswordstatusid`='".intval($onetimepasswordstatusId)."' LIMIT 1";
+ $cursor = Database::Reader($this->pog_query, $connection);
+ while ($row = Database::Read($cursor))
+ {
+ $this->onetimepasswordstatusId = $row['onetimepasswordstatusid'];
+ $this->code = $this->Unescape($row['code']);
+ $this->name = $this->Unescape($row['name']);
+ $this->description = $this->Unescape($row['description']);
+ }
+ return $this;
+ }
+
+
+ /**
+ * Returns a sorted array of objects that match given conditions
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param string $sortBy
+ * @param boolean $ascending
+ * @param int limit
+ * @return array $onetimepasswordstatusList
+ */
+ function GetList($fcv_array = array(), $sortBy='', $ascending=true, $limit='')
+ {
+ $connection = Database::Connect();
+ $sqlLimit = ($limit != '' ? "LIMIT $limit" : '');
+ $this->pog_query = "select * from `onetimepasswordstatus` ";
+ $onetimepasswordstatusList = Array();
+ if (sizeof($fcv_array) > 0)
+ {
+ $this->pog_query .= " where ";
+ for ($i=0, $c=sizeof($fcv_array); $i<$c; $i++)
+ {
+ if (sizeof($fcv_array[$i]) == 1)
+ {
+ $this->pog_query .= " ".$fcv_array[$i][0]." ";
+ continue;
+ }
+ else
+ {
+ if ($i > 0 && sizeof($fcv_array[$i-1]) != 1)
+ {
+ $this->pog_query .= " AND ";
+ }
+ if (isset($this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes']) && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'SET')
+ {
+ if ($GLOBALS['configuration']['db_encoding'] == 1)
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? "BASE64_DECODE(".$fcv_array[$i][2].")" : "'".$fcv_array[$i][2]."'";
+ $this->pog_query .= "BASE64_DECODE(`".$fcv_array[$i][0]."`) ".$fcv_array[$i][1]." ".$value;
+ }
+ else
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? $fcv_array[$i][2] : "'".$this->Escape($fcv_array[$i][2])."'";
+ $this->pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." ".$value;
+ }
+ }
+ else
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? $fcv_array[$i][2] : "'".$fcv_array[$i][2]."'";
+ $this->pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." ".$value;
+ }
+ }
+ }
+ }
+ if ($sortBy != '')
+ {
+ if (isset($this->pog_attribute_type[$sortBy]['db_attributes']) && $this->pog_attribute_type[$sortBy]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$sortBy]['db_attributes'][0] != 'SET')
+ {
+ if ($GLOBALS['configuration']['db_encoding'] == 1)
+ {
+ $sortBy = "BASE64_DECODE($sortBy) ";
+ }
+ else
+ {
+ $sortBy = "$sortBy ";
+ }
+ }
+ else
+ {
+ $sortBy = "$sortBy ";
+ }
+ }
+ else
+ {
+ $sortBy = "onetimepasswordstatusid";
+ }
+ $this->pog_query .= " order by ".$sortBy." ".($ascending ? "asc" : "desc")." $sqlLimit";
+ $thisObjectName = get_class($this);
+ $cursor = Database::Reader($this->pog_query, $connection);
+ while ($row = Database::Read($cursor))
+ {
+ $onetimepasswordstatus = new $thisObjectName();
+ $onetimepasswordstatus->onetimepasswordstatusId = $row['onetimepasswordstatusid'];
+ $onetimepasswordstatus->code = $this->Unescape($row['code']);
+ $onetimepasswordstatus->name = $this->Unescape($row['name']);
+ $onetimepasswordstatus->description = $this->Unescape($row['description']);
+ $onetimepasswordstatusList[] = $onetimepasswordstatus;
+ }
+ return $onetimepasswordstatusList;
+ }
+
+
+ /**
+ * Saves the object to the database
+ * @return integer $onetimepasswordstatusId
+ */
+ function Save($deep = true)
+ {
+ $connection = Database::Connect();
+ $this->pog_query = "select `onetimepasswordstatusid` from `onetimepasswordstatus` where `onetimepasswordstatusid`='".$this->onetimepasswordstatusId."' LIMIT 1";
+ $rows = Database::Query($this->pog_query, $connection);
+ if ($rows > 0)
+ {
+ $this->pog_query = "update `onetimepasswordstatus` set
+ `code`='".$this->Escape($this->code)."',
+ `name`='".$this->Escape($this->name)."',
+ `description`='".$this->Escape($this->description)."' where `onetimepasswordstatusid`='".$this->onetimepasswordstatusId."'";
+ }
+ else
+ {
+ $this->pog_query = "insert into `onetimepasswordstatus` (`code`, `name`, `description` ) values (
+ '".$this->Escape($this->code)."',
+ '".$this->Escape($this->name)."',
+ '".$this->Escape($this->description)."' )";
+ }
+ $insertId = Database::InsertOrUpdate($this->pog_query, $connection);
+ if ($this->onetimepasswordstatusId == "")
+ {
+ $this->onetimepasswordstatusId = $insertId;
+ }
+ if ($deep)
+ {
+ foreach ($this->_onetimepasswordList as $onetimepassword)
+ {
+ $onetimepassword->onetimepasswordstatusId = $this->onetimepasswordstatusId;
+ $onetimepassword->Save($deep);
+ }
+ }
+ return $this->onetimepasswordstatusId;
+ }
+
+
+ /**
+ * Clones the object and saves it to the database
+ * @return integer $onetimepasswordstatusId
+ */
+ function SaveNew($deep = false)
+ {
+ $this->onetimepasswordstatusId = '';
+ return $this->Save($deep);
+ }
+
+
+ /**
+ * Deletes the object from the database
+ * @return boolean
+ */
+ function Delete($deep = false, $across = false)
+ {
+ if ($deep)
+ {
+ $onetimepasswordList = $this->GetOnetimepasswordList();
+ foreach ($onetimepasswordList as $onetimepassword)
+ {
+ $onetimepassword->Delete($deep, $across);
+ }
+ }
+ $connection = Database::Connect();
+ $this->pog_query = "delete from `onetimepasswordstatus` where `onetimepasswordstatusid`='".$this->onetimepasswordstatusId."'";
+ return Database::NonQuery($this->pog_query, $connection);
+ }
+
+
+ /**
+ * Deletes a list of objects that match given conditions
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param bool $deep
+ * @return
+ */
+ function DeleteList($fcv_array, $deep = false, $across = false)
+ {
+ if (sizeof($fcv_array) > 0)
+ {
+ if ($deep || $across)
+ {
+ $objectList = $this->GetList($fcv_array);
+ foreach ($objectList as $object)
+ {
+ $object->Delete($deep, $across);
+ }
+ }
+ else
+ {
+ $connection = Database::Connect();
+ $pog_query = "delete from `onetimepasswordstatus` where ";
+ for ($i=0, $c=sizeof($fcv_array); $i<$c; $i++)
+ {
+ if (sizeof($fcv_array[$i]) == 1)
+ {
+ $pog_query .= " ".$fcv_array[$i][0]." ";
+ continue;
+ }
+ else
+ {
+ if ($i > 0 && sizeof($fcv_array[$i-1]) !== 1)
+ {
+ $pog_query .= " AND ";
+ }
+ if (isset($this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes']) && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'SET')
+ {
+ $pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." '".$this->Escape($fcv_array[$i][2])."'";
+ }
+ else
+ {
+ $pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." '".$fcv_array[$i][2]."'";
+ }
+ }
+ }
+ return Database::NonQuery($pog_query, $connection);
+ }
+ }
+ }
+
+
+ /**
+ * Gets a list of onetimepassword objects associated to this one
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param string $sortBy
+ * @param boolean $ascending
+ * @param int limit
+ * @return array of onetimepassword objects
+ */
+ function GetOnetimepasswordList($fcv_array = array(), $sortBy='', $ascending=true, $limit='')
+ {
+ $onetimepassword = new onetimepassword();
+ $fcv_array[] = array("onetimepasswordstatusId", "=", $this->onetimepasswordstatusId);
+ $dbObjects = $onetimepassword->GetList($fcv_array, $sortBy, $ascending, $limit);
+ return $dbObjects;
+ }
+
+
+ /**
+ * Makes this the parent of all onetimepassword objects in the onetimepassword List array. Any existing onetimepassword will become orphan(s)
+ * @return null
+ */
+ function SetOnetimepasswordList(&$list)
+ {
+ $this->_onetimepasswordList = array();
+ $existingOnetimepasswordList = $this->GetOnetimepasswordList();
+ foreach ($existingOnetimepasswordList as $onetimepassword)
+ {
+ $onetimepassword->onetimepasswordstatusId = '';
+ $onetimepassword->Save(false);
+ }
+ $this->_onetimepasswordList = $list;
+ }
+
+
+ /**
+ * Associates the onetimepassword object to this one
+ * @return
+ */
+ function AddOnetimepassword(&$onetimepassword)
+ {
+ $onetimepassword->onetimepasswordstatusId = $this->onetimepasswordstatusId;
+ $found = false;
+ foreach($this->_onetimepasswordList as $onetimepassword2)
+ {
+ if ($onetimepassword->onetimepasswordId > 0 && $onetimepassword->onetimepasswordId == $onetimepassword2->onetimepasswordId)
+ {
+ $found = true;
+ break;
+ }
+ }
+ if (!$found)
+ {
+ $this->_onetimepasswordList[] = $onetimepassword;
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/backend/php/src/objects/class.pog_base.php b/backend/php/src/objects/class.pog_base.php
new file mode 100644
index 0000000..6a8f570
--- a/dev/null
+++ b/backend/php/src/objects/class.pog_base.php
@@ -0,0 +1,143 @@
+<?php
+class POG_Base
+{
+ /**
+ * Overloading
+ */
+ function __call($method, $argv)
+ {
+ include_once($GLOBALS['configuration']['plugins_path']."/IPlugin.php");
+ include_once($GLOBALS['configuration']['plugins_path']."/plugin.".strtolower($method).".php");
+ eval('$plugin = new $method($this,$argv);');
+ return $plugin->Execute();
+ }
+
+ /**
+ * constructor
+ *
+ * @return POG_Base
+ */
+ private function POG_Base()
+ {
+ }
+
+
+ function SetFieldAttribute($fieldName, $attributeName, $attributeValue)
+ {
+ if (isset($this->pog_attribute_type[$fieldName]) && isset($this->pog_attribute_type[$fieldName][$attributeName]))
+ {
+ $this->pog_attribute_type[$fieldName][$attributeName] = $attributeValue;
+ }
+ }
+
+ function GetFieldAttribute($fieldName, $attributeName)
+ {
+ if (isset($this->pog_attribute_type[$fieldName]) && isset($this->pog_attribute_type[$fieldName][$attributeName]))
+ {
+ return $this->pog_attribute_type[$fieldName][$attributeName];
+ }
+ return null;
+ }
+
+ ///////////////////////////
+ // Data manipulation
+ ///////////////////////////
+
+ /**
+ * This function will try to encode $text to base64, except when $text is a number. This allows us to Escape all data before they're inserted in the database, regardless of attribute type.
+ * @param string $text
+ * @return string encoded to base64
+ */
+ public function Escape($text)
+ {
+ if ($GLOBALS['configuration']['db_encoding'] && !is_numeric($text))
+ {
+ return base64_encode($text);
+ }
+ return addslashes($text);
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param unknown_type $text
+ * @return unknown
+ */
+ public function Unescape($text)
+ {
+ if ($GLOBALS['configuration']['db_encoding'] && !is_numeric($text))
+ {
+ return base64_decode($text);
+ }
+ return stripcslashes($text);
+ }
+
+
+ ////////////////////////////////
+ // Table -> Object Mapping
+ ////////////////////////////////
+
+ /**
+ * Executes $query against database and returns the result set as an array of POG objects
+ *
+ * @param string $query. SQL query to execute against database
+ * @param string $objectClass. POG Object type to return
+ * @param bool $lazy. If true, will also load all children/sibling
+ */
+ public function FetchObjects($query, $objectClass, $lazy = true)
+ {
+ $databaseConnection = Database::Connect();
+ $result = Database::Query($query, $databaseConnection);
+ $objectList = $this->CreateObjects($result, $objectClass, $lazy);
+ return $objectList;
+ }
+
+ private function CreateObjects($mysql_result, $objectClass, $lazyLoad = true)
+ {
+ $objectList = array();
+ while ($row = mysql_fetch_assoc($mysql_result))
+ {
+ $pog_object = new $objectClass();
+ $this->PopulateObjectAttributes($row, $pog_object);
+ $objectList[] = $pog_object;
+ }
+ return $objectList;
+ }
+
+ private function PopulateObjectAttributes($fetched_row, $pog_object)
+ {
+ foreach ($this->GetAttributes($pog_object) as $column)
+ {
+ $pog_object->{$column} = $this->Unescape($fetched_row[strtolower($column)]);
+ }
+ return $pog_object;
+ }
+
+ private function GetAttributes($object)
+ {
+ $columns = array();
+ foreach ($object->pog_attribute_type as $att => $properties)
+ {
+ if ($properties['db_attributes'][0] != 'OBJECT')
+ {
+ $columns[] = $att;
+ }
+ }
+ return $columns;
+ }
+
+ //misc
+ public static function IsColumn($value)
+ {
+ if (strlen($value) > 2)
+ {
+ if (substr($value, 0, 1) == '`' && substr($value, strlen($value) - 1, 1) == '`')
+ {
+ return true;
+ }
+ return false;
+ }
+ return false;
+ }
+}
+?> \ No newline at end of file
diff --git a/backend/php/src/objects/class.record.php b/backend/php/src/objects/class.record.php
new file mode 100644
index 0000000..a269e75
--- a/dev/null
+++ b/backend/php/src/objects/class.record.php
@@ -0,0 +1,436 @@
+<?php
+/*
+ This SQL query will create the table to store your object.
+
+ CREATE TABLE `record` (
+ `recordid` int(11) NOT NULL auto_increment,
+ `userid` int(11) NOT NULL,
+ `reference` VARCHAR(255) NOT NULL,
+ `data` LONGTEXT NOT NULL,
+ `version` VARCHAR(255) NOT NULL,
+ `creation_date` TIMESTAMP NOT NULL,
+ `update_date` TIMESTAMP NOT NULL,
+ `access_date` TIMESTAMP NOT NULL, INDEX(`userid`), PRIMARY KEY (`recordid`)) ENGINE=MyISAM;
+*/
+
+/**
+* <b>record</b> class with integrated CRUD methods.
+* @author Php Object Generator
+* @version POG 3.0e / PHP5.1 MYSQL
+* @see http://www.phpobjectgenerator.com/plog/tutorials/45/pdo-mysql
+* @copyright Free for personal & commercial use. (Offered under the BSD license)
+* @link http://www.phpobjectgenerator.com/?language=php5.1&wrapper=pdo&pdoDriver=mysql&objectName=record&attributeList=array+%28%0A++0+%3D%3E+%27user%27%2C%0A++1+%3D%3E+%27recordversion%27%2C%0A++2+%3D%3E+%27reference%27%2C%0A++3+%3D%3E+%27data%27%2C%0A++4+%3D%3E+%27version%27%2C%0A++5+%3D%3E+%27creation_date%27%2C%0A++6+%3D%3E+%27update_date%27%2C%0A++7+%3D%3E+%27access_date%27%2C%0A%29&typeList=array%2B%2528%250A%2B%2B0%2B%253D%253E%2B%2527BELONGSTO%2527%252C%250A%2B%2B1%2B%253D%253E%2B%2527HASMANY%2527%252C%250A%2B%2B2%2B%253D%253E%2B%2527VARCHAR%2528255%2529%2527%252C%250A%2B%2B3%2B%253D%253E%2B%2527LONGTEXT%2527%252C%250A%2B%2B4%2B%253D%253E%2B%2527VARCHAR%2528255%2529%2527%252C%250A%2B%2B5%2B%253D%253E%2B%2527TIMESTAMP%2527%252C%250A%2B%2B6%2B%253D%253E%2B%2527TIMESTAMP%2527%252C%250A%2B%2B7%2B%253D%253E%2B%2527TIMESTAMP%2527%252C%250A%2529
+*/
+include_once('class.pog_base.php');
+class record extends POG_Base
+{
+ public $recordId = '';
+
+ /**
+ * @var INT(11)
+ */
+ public $userId;
+
+ /**
+ * @var private array of recordversion objects
+ */
+ private $_recordversionList = array();
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $reference;
+
+ /**
+ * @var LONGTEXT
+ */
+ public $data;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $version;
+
+ /**
+ * @var TIMESTAMP
+ */
+ public $creation_date;
+
+ /**
+ * @var TIMESTAMP
+ */
+ public $update_date;
+
+ /**
+ * @var TIMESTAMP
+ */
+ public $access_date;
+
+ public $pog_attribute_type = array(
+ "recordId" => array('db_attributes' => array("NUMERIC", "INT")),
+ "user" => array('db_attributes' => array("OBJECT", "BELONGSTO")),
+ "recordversion" => array('db_attributes' => array("OBJECT", "HASMANY")),
+ "reference" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "data" => array('db_attributes' => array("TEXT", "LONGTEXT")),
+ "version" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "creation_date" => array('db_attributes' => array("NUMERIC", "TIMESTAMP")),
+ "update_date" => array('db_attributes' => array("NUMERIC", "TIMESTAMP")),
+ "access_date" => array('db_attributes' => array("NUMERIC", "TIMESTAMP")),
+ );
+ public $pog_query;
+
+
+ /**
+ * Getter for some private attributes
+ * @return mixed $attribute
+ */
+ public function __get($attribute)
+ {
+ if (isset($this->{"_".$attribute}))
+ {
+ return $this->{"_".$attribute};
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function record($reference='', $data='', $version='', $creation_date='', $update_date='', $access_date='')
+ {
+ $this->_recordversionList = array();
+ $this->reference = $reference;
+ $this->data = $data;
+ $this->version = $version;
+ $this->creation_date = $creation_date;
+ $this->update_date = $update_date;
+ $this->access_date = $access_date;
+ }
+
+
+ /**
+ * Gets object from database
+ * @param integer $recordId
+ * @return object $record
+ */
+ function Get($recordId)
+ {
+ $connection = Database::Connect();
+ $this->pog_query = "select * from `record` where `recordid`='".intval($recordId)."' LIMIT 1";
+ $cursor = Database::Reader($this->pog_query, $connection);
+ while ($row = Database::Read($cursor))
+ {
+ $this->recordId = $row['recordid'];
+ $this->userId = $row['userid'];
+ $this->reference = $this->Unescape($row['reference']);
+ $this->data = $this->Unescape($row['data']);
+ $this->version = $this->Unescape($row['version']);
+ $this->creation_date = $row['creation_date'];
+ $this->update_date = $row['update_date'];
+ $this->access_date = $row['access_date'];
+ }
+ return $this;
+ }
+
+
+ /**
+ * Returns a sorted array of objects that match given conditions
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param string $sortBy
+ * @param boolean $ascending
+ * @param int limit
+ * @return array $recordList
+ */
+ function GetList($fcv_array = array(), $sortBy='', $ascending=true, $limit='')
+ {
+ $connection = Database::Connect();
+ $sqlLimit = ($limit != '' ? "LIMIT $limit" : '');
+ $this->pog_query = "select * from `record` ";
+ $recordList = Array();
+ if (sizeof($fcv_array) > 0)
+ {
+ $this->pog_query .= " where ";
+ for ($i=0, $c=sizeof($fcv_array); $i<$c; $i++)
+ {
+ if (sizeof($fcv_array[$i]) == 1)
+ {
+ $this->pog_query .= " ".$fcv_array[$i][0]." ";
+ continue;
+ }
+ else
+ {
+ if ($i > 0 && sizeof($fcv_array[$i-1]) != 1)
+ {
+ $this->pog_query .= " AND ";
+ }
+ if (isset($this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes']) && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'SET')
+ {
+ if ($GLOBALS['configuration']['db_encoding'] == 1)
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? "BASE64_DECODE(".$fcv_array[$i][2].")" : "'".$fcv_array[$i][2]."'";
+ $this->pog_query .= "BASE64_DECODE(`".$fcv_array[$i][0]."`) ".$fcv_array[$i][1]." ".$value;
+ }
+ else
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? $fcv_array[$i][2] : "'".$this->Escape($fcv_array[$i][2])."'";
+ $this->pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." ".$value;
+ }
+ }
+ else
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? $fcv_array[$i][2] : "'".$fcv_array[$i][2]."'";
+ $this->pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." ".$value;
+ }
+ }
+ }
+ }
+ if ($sortBy != '')
+ {
+ if (isset($this->pog_attribute_type[$sortBy]['db_attributes']) && $this->pog_attribute_type[$sortBy]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$sortBy]['db_attributes'][0] != 'SET')
+ {
+ if ($GLOBALS['configuration']['db_encoding'] == 1)
+ {
+ $sortBy = "BASE64_DECODE($sortBy) ";
+ }
+ else
+ {
+ $sortBy = "$sortBy ";
+ }
+ }
+ else
+ {
+ $sortBy = "$sortBy ";
+ }
+ }
+ else
+ {
+ $sortBy = "recordid";
+ }
+ $this->pog_query .= " order by ".$sortBy." ".($ascending ? "asc" : "desc")." $sqlLimit";
+ $thisObjectName = get_class($this);
+ $cursor = Database::Reader($this->pog_query, $connection);
+ while ($row = Database::Read($cursor))
+ {
+ $record = new $thisObjectName();
+ $record->recordId = $row['recordid'];
+ $record->userId = $row['userid'];
+ $record->reference = $this->Unescape($row['reference']);
+ $record->data = $this->Unescape($row['data']);
+ $record->version = $this->Unescape($row['version']);
+ $record->creation_date = $row['creation_date'];
+ $record->update_date = $row['update_date'];
+ $record->access_date = $row['access_date'];
+ $recordList[] = $record;
+ }
+ return $recordList;
+ }
+
+
+ /**
+ * Saves the object to the database
+ * @return integer $recordId
+ */
+ function Save($deep = true)
+ {
+ $connection = Database::Connect();
+ $this->pog_query = "select `recordid` from `record` where `recordid`='".$this->recordId."' LIMIT 1";
+ $rows = Database::Query($this->pog_query, $connection);
+ if ($rows > 0)
+ {
+ $this->pog_query = "update `record` set
+ `userid`='".$this->userId."',
+ `reference`='".$this->Escape($this->reference)."',
+ `data`='".$this->Escape($this->data)."',
+ `version`='".$this->Escape($this->version)."',
+ `creation_date`='".$this->creation_date."',
+ `update_date`='".$this->update_date."',
+ `access_date`='".$this->access_date."' where `recordid`='".$this->recordId."'";
+ }
+ else
+ {
+ $this->pog_query = "insert into `record` (`userid`, `reference`, `data`, `version`, `creation_date`, `update_date`, `access_date` ) values (
+ '".$this->userId."',
+ '".$this->Escape($this->reference)."',
+ '".$this->Escape($this->data)."',
+ '".$this->Escape($this->version)."',
+ '".$this->creation_date."',
+ '".$this->update_date."',
+ '".$this->access_date."' )";
+ }
+ $insertId = Database::InsertOrUpdate($this->pog_query, $connection);
+ if ($this->recordId == "")
+ {
+ $this->recordId = $insertId;
+ }
+ if ($deep)
+ {
+ foreach ($this->_recordversionList as $recordversion)
+ {
+ $recordversion->recordId = $this->recordId;
+ $recordversion->Save($deep);
+ }
+ }
+ return $this->recordId;
+ }
+
+
+ /**
+ * Clones the object and saves it to the database
+ * @return integer $recordId
+ */
+ function SaveNew($deep = false)
+ {
+ $this->recordId = '';
+ return $this->Save($deep);
+ }
+
+
+ /**
+ * Deletes the object from the database
+ * @return boolean
+ */
+ function Delete($deep = false, $across = false)
+ {
+ if ($deep)
+ {
+ $recordversionList = $this->GetRecordversionList();
+ foreach ($recordversionList as $recordversion)
+ {
+ $recordversion->Delete($deep, $across);
+ }
+ }
+ $connection = Database::Connect();
+ $this->pog_query = "delete from `record` where `recordid`='".$this->recordId."'";
+ return Database::NonQuery($this->pog_query, $connection);
+ }
+
+
+ /**
+ * Deletes a list of objects that match given conditions
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param bool $deep
+ * @return
+ */
+ function DeleteList($fcv_array, $deep = false, $across = false)
+ {
+ if (sizeof($fcv_array) > 0)
+ {
+ if ($deep || $across)
+ {
+ $objectList = $this->GetList($fcv_array);
+ foreach ($objectList as $object)
+ {
+ $object->Delete($deep, $across);
+ }
+ }
+ else
+ {
+ $connection = Database::Connect();
+ $pog_query = "delete from `record` where ";
+ for ($i=0, $c=sizeof($fcv_array); $i<$c; $i++)
+ {
+ if (sizeof($fcv_array[$i]) == 1)
+ {
+ $pog_query .= " ".$fcv_array[$i][0]." ";
+ continue;
+ }
+ else
+ {
+ if ($i > 0 && sizeof($fcv_array[$i-1]) !== 1)
+ {
+ $pog_query .= " AND ";
+ }
+ if (isset($this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes']) && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'SET')
+ {
+ $pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." '".$this->Escape($fcv_array[$i][2])."'";
+ }
+ else
+ {
+ $pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." '".$fcv_array[$i][2]."'";
+ }
+ }
+ }
+ return Database::NonQuery($pog_query, $connection);
+ }
+ }
+ }
+
+
+ /**
+ * Associates the user object to this one
+ * @return boolean
+ */
+ function GetUser()
+ {
+ $user = new user();
+ return $user->Get($this->userId);
+ }
+
+
+ /**
+ * Associates the user object to this one
+ * @return
+ */
+ function SetUser(&$user)
+ {
+ $this->userId = $user->userId;
+ }
+
+
+ /**
+ * Gets a list of recordversion objects associated to this one
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param string $sortBy
+ * @param boolean $ascending
+ * @param int limit
+ * @return array of recordversion objects
+ */
+ function GetRecordversionList($fcv_array = array(), $sortBy='', $ascending=true, $limit='')
+ {
+ $recordversion = new recordversion();
+ $fcv_array[] = array("recordId", "=", $this->recordId);
+ $dbObjects = $recordversion->GetList($fcv_array, $sortBy, $ascending, $limit);
+ return $dbObjects;
+ }
+
+
+ /**
+ * Makes this the parent of all recordversion objects in the recordversion List array. Any existing recordversion will become orphan(s)
+ * @return null
+ */
+ function SetRecordversionList(&$list)
+ {
+ $this->_recordversionList = array();
+ $existingRecordversionList = $this->GetRecordversionList();
+ foreach ($existingRecordversionList as $recordversion)
+ {
+ $recordversion->recordId = '';
+ $recordversion->Save(false);
+ }
+ $this->_recordversionList = $list;
+ }
+
+
+ /**
+ * Associates the recordversion object to this one
+ * @return
+ */
+ function AddRecordversion(&$recordversion)
+ {
+ $recordversion->recordId = $this->recordId;
+ $found = false;
+ foreach($this->_recordversionList as $recordversion2)
+ {
+ if ($recordversion->recordversionId > 0 && $recordversion->recordversionId == $recordversion2->recordversionId)
+ {
+ $found = true;
+ break;
+ }
+ }
+ if (!$found)
+ {
+ $this->_recordversionList[] = $recordversion;
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/backend/php/src/objects/class.recordversion.php b/backend/php/src/objects/class.recordversion.php
new file mode 100644
index 0000000..3fbc436
--- a/dev/null
+++ b/backend/php/src/objects/class.recordversion.php
@@ -0,0 +1,381 @@
+<?php
+/*
+ This SQL query will create the table to store your object.
+
+ CREATE TABLE `recordversion` (
+ `recordversionid` int(11) NOT NULL auto_increment,
+ `recordid` int(11) NOT NULL,
+ `reference` VARCHAR(255) NOT NULL,
+ `header` LONGTEXT NOT NULL,
+ `data` LONGTEXT NOT NULL,
+ `version` VARCHAR(255) NOT NULL,
+ `previous_version_key` VARCHAR(255) NOT NULL,
+ `previous_version_id` INT NOT NULL,
+ `creation_date` TIMESTAMP NOT NULL,
+ `update_date` TIMESTAMP NOT NULL,
+ `access_date` TIMESTAMP NOT NULL, INDEX(`recordid`), PRIMARY KEY (`recordversionid`)) ENGINE=MyISAM;
+*/
+
+/**
+* <b>recordversion</b> class with integrated CRUD methods.
+* @author Php Object Generator
+* @version POG 3.0e / PHP5.1 MYSQL
+* @see http://www.phpobjectgenerator.com/plog/tutorials/45/pdo-mysql
+* @copyright Free for personal & commercial use. (Offered under the BSD license)
+* @link http://www.phpobjectgenerator.com/?language=php5.1=pdo&pdoDriver=mysql&objectName=recordversion&attributeList=array+%28%0A++0+%3D%3E+%27record%27%2C%0A++1+%3D%3E+%27reference%27%2C%0A++2+%3D%3E+%27header%27%2C%0A++3+%3D%3E+%27data%27%2C%0A++4+%3D%3E+%27version%27%2C%0A++5+%3D%3E+%27previous_version_key%27%2C%0A++6+%3D%3E+%27previous_version_id%27%2C%0A++7+%3D%3E+%27creation_date%27%2C%0A++8+%3D%3E+%27update_date%27%2C%0A++9+%3D%3E+%27access_date%27%2C%0A%29&typeList=array%2B%2528%250A%2B%2B0%2B%253D%253E%2B%2527BELONGSTO%2527%252C%250A%2B%2B1%2B%253D%253E%2B%2527VARCHAR%2528255%2529%2527%252C%250A%2B%2B2%2B%253D%253E%2B%2527LONGTEXT%2527%252C%250A%2B%2B3%2B%253D%253E%2B%2527LONGTEXT%2527%252C%250A%2B%2B4%2B%253D%253E%2B%2527VARCHAR%2528255%2529%2527%252C%250A%2B%2B5%2B%253D%253E%2B%2527VARCHAR%2528255%2529%2527%252C%250A%2B%2B6%2B%253D%253E%2B%2527INT%2527%252C%250A%2B%2B7%2B%253D%253E%2B%2527TIMESTAMP%2527%252C%250A%2B%2B8%2B%253D%253E%2B%2527TIMESTAMP%2527%252C%250A%2B%2B9%2B%253D%253E%2B%2527TIMESTAMP%2527%252C%250A%2529
+*/
+include_once('class.pog_base.php');
+class recordversion extends POG_Base
+{
+ public $recordversionId = '';
+
+ /**
+ * @var INT(11)
+ */
+ public $recordId;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $reference;
+
+ /**
+ * @var LONGTEXT
+ */
+ public $header;
+
+ /**
+ * @var LONGTEXT
+ */
+ public $data;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $version;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $previous_version_key;
+
+ /**
+ * @var INT
+ */
+ public $previous_version_id;
+
+ /**
+ * @var TIMESTAMP
+ */
+ public $creation_date;
+
+ /**
+ * @var TIMESTAMP
+ */
+ public $update_date;
+
+ /**
+ * @var TIMESTAMP
+ */
+ public $access_date;
+
+ public $pog_attribute_type = array(
+ "recordversionId" => array('db_attributes' => array("NUMERIC", "INT")),
+ "record" => array('db_attributes' => array("OBJECT", "BELONGSTO")),
+ "reference" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "header" => array('db_attributes' => array("TEXT", "LONGTEXT")),
+ "data" => array('db_attributes' => array("TEXT", "LONGTEXT")),
+ "version" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "previous_version_key" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "previous_version_id" => array('db_attributes' => array("NUMERIC", "INT")),
+ "creation_date" => array('db_attributes' => array("NUMERIC", "TIMESTAMP")),
+ "update_date" => array('db_attributes' => array("NUMERIC", "TIMESTAMP")),
+ "access_date" => array('db_attributes' => array("NUMERIC", "TIMESTAMP")),
+ );
+ public $pog_query;
+
+
+ /**
+ * Getter for some private attributes
+ * @return mixed $attribute
+ */
+ public function __get($attribute)
+ {
+ if (isset($this->{"_".$attribute}))
+ {
+ return $this->{"_".$attribute};
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function recordversion($reference='', $header='', $data='', $version='', $previous_version_key='', $previous_version_id='', $creation_date='', $update_date='', $access_date='')
+ {
+ $this->reference = $reference;
+ $this->header = $header;
+ $this->data = $data;
+ $this->version = $version;
+ $this->previous_version_key = $previous_version_key;
+ $this->previous_version_id = $previous_version_id;
+ $this->creation_date = $creation_date;
+ $this->update_date = $update_date;
+ $this->access_date = $access_date;
+ }
+
+
+ /**
+ * Gets object from database
+ * @param integer $recordversionId
+ * @return object $recordversion
+ */
+ function Get($recordversionId)
+ {
+ $connection = Database::Connect();
+ $this->pog_query = "select * from `recordversion` where `recordversionid`='".intval($recordversionId)."' LIMIT 1";
+ $cursor = Database::Reader($this->pog_query, $connection);
+ while ($row = Database::Read($cursor))
+ {
+ $this->recordversionId = $row['recordversionid'];
+ $this->recordId = $row['recordid'];
+ $this->reference = $this->Unescape($row['reference']);
+ $this->header = $this->Unescape($row['header']);
+ $this->data = $this->Unescape($row['data']);
+ $this->version = $this->Unescape($row['version']);
+ $this->previous_version_key = $this->Unescape($row['previous_version_key']);
+ $this->previous_version_id = $this->Unescape($row['previous_version_id']);
+ $this->creation_date = $row['creation_date'];
+ $this->update_date = $row['update_date'];
+ $this->access_date = $row['access_date'];
+ }
+ return $this;
+ }
+
+
+ /**
+ * Returns a sorted array of objects that match given conditions
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param string $sortBy
+ * @param boolean $ascending
+ * @param int limit
+ * @return array $recordversionList
+ */
+ function GetList($fcv_array = array(), $sortBy='', $ascending=true, $limit='')
+ {
+ $connection = Database::Connect();
+ $sqlLimit = ($limit != '' ? "LIMIT $limit" : '');
+ $this->pog_query = "select * from `recordversion` ";
+ $recordversionList = Array();
+ if (sizeof($fcv_array) > 0)
+ {
+ $this->pog_query .= " where ";
+ for ($i=0, $c=sizeof($fcv_array); $i<$c; $i++)
+ {
+ if (sizeof($fcv_array[$i]) == 1)
+ {
+ $this->pog_query .= " ".$fcv_array[$i][0]." ";
+ continue;
+ }
+ else
+ {
+ if ($i > 0 && sizeof($fcv_array[$i-1]) != 1)
+ {
+ $this->pog_query .= " AND ";
+ }
+ if (isset($this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes']) && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'SET')
+ {
+ if ($GLOBALS['configuration']['db_encoding'] == 1)
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? "BASE64_DECODE(".$fcv_array[$i][2].")" : "'".$fcv_array[$i][2]."'";
+ $this->pog_query .= "BASE64_DECODE(`".$fcv_array[$i][0]."`) ".$fcv_array[$i][1]." ".$value;
+ }
+ else
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? $fcv_array[$i][2] : "'".$this->Escape($fcv_array[$i][2])."'";
+ $this->pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." ".$value;
+ }
+ }
+ else
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? $fcv_array[$i][2] : "'".$fcv_array[$i][2]."'";
+ $this->pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." ".$value;
+ }
+ }
+ }
+ }
+ if ($sortBy != '')
+ {
+ if (isset($this->pog_attribute_type[$sortBy]['db_attributes']) && $this->pog_attribute_type[$sortBy]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$sortBy]['db_attributes'][0] != 'SET')
+ {
+ if ($GLOBALS['configuration']['db_encoding'] == 1)
+ {
+ $sortBy = "BASE64_DECODE($sortBy) ";
+ }
+ else
+ {
+ $sortBy = "$sortBy ";
+ }
+ }
+ else
+ {
+ $sortBy = "$sortBy ";
+ }
+ }
+ else
+ {
+ $sortBy = "recordversionid";
+ }
+ $this->pog_query .= " order by ".$sortBy." ".($ascending ? "asc" : "desc")." $sqlLimit";
+ $thisObjectName = get_class($this);
+ $cursor = Database::Reader($this->pog_query, $connection);
+ while ($row = Database::Read($cursor))
+ {
+ $recordversion = new $thisObjectName();
+ $recordversion->recordversionId = $row['recordversionid'];
+ $recordversion->recordId = $row['recordid'];
+ $recordversion->reference = $this->Unescape($row['reference']);
+ $recordversion->header = $this->Unescape($row['header']);
+ $recordversion->data = $this->Unescape($row['data']);
+ $recordversion->version = $this->Unescape($row['version']);
+ $recordversion->previous_version_key = $this->Unescape($row['previous_version_key']);
+ $recordversion->previous_version_id = $this->Unescape($row['previous_version_id']);
+ $recordversion->creation_date = $row['creation_date'];
+ $recordversion->update_date = $row['update_date'];
+ $recordversion->access_date = $row['access_date'];
+ $recordversionList[] = $recordversion;
+ }
+ return $recordversionList;
+ }
+
+
+ /**
+ * Saves the object to the database
+ * @return integer $recordversionId
+ */
+ function Save()
+ {
+ $connection = Database::Connect();
+ $this->pog_query = "select `recordversionid` from `recordversion` where `recordversionid`='".$this->recordversionId."' LIMIT 1";
+ $rows = Database::Query($this->pog_query, $connection);
+ if ($rows > 0)
+ {
+ $this->pog_query = "update `recordversion` set
+ `recordid`='".$this->recordId."',
+ `reference`='".$this->Escape($this->reference)."',
+ `header`='".$this->Escape($this->header)."',
+ `data`='".$this->Escape($this->data)."',
+ `version`='".$this->Escape($this->version)."',
+ `previous_version_key`='".$this->Escape($this->previous_version_key)."',
+ `previous_version_id`='".$this->Escape($this->previous_version_id)."',
+ `creation_date`='".$this->creation_date."',
+ `update_date`='".$this->update_date."',
+ `access_date`='".$this->access_date."' where `recordversionid`='".$this->recordversionId."'";
+ }
+ else
+ {
+ $this->pog_query = "insert into `recordversion` (`recordid`, `reference`, `header`, `data`, `version`, `previous_version_key`, `previous_version_id`, `creation_date`, `update_date`, `access_date` ) values (
+ '".$this->recordId."',
+ '".$this->Escape($this->reference)."',
+ '".$this->Escape($this->header)."',
+ '".$this->Escape($this->data)."',
+ '".$this->Escape($this->version)."',
+ '".$this->Escape($this->previous_version_key)."',
+ '".$this->Escape($this->previous_version_id)."',
+ '".$this->creation_date."',
+ '".$this->update_date."',
+ '".$this->access_date."' )";
+ }
+ $insertId = Database::InsertOrUpdate($this->pog_query, $connection);
+ if ($this->recordversionId == "")
+ {
+ $this->recordversionId = $insertId;
+ }
+ return $this->recordversionId;
+ }
+
+
+ /**
+ * Clones the object and saves it to the database
+ * @return integer $recordversionId
+ */
+ function SaveNew()
+ {
+ $this->recordversionId = '';
+ return $this->Save();
+ }
+
+
+ /**
+ * Deletes the object from the database
+ * @return boolean
+ */
+ function Delete()
+ {
+ $connection = Database::Connect();
+ $this->pog_query = "delete from `recordversion` where `recordversionid`='".$this->recordversionId."'";
+ return Database::NonQuery($this->pog_query, $connection);
+ }
+
+
+ /**
+ * Deletes a list of objects that match given conditions
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param bool $deep
+ * @return
+ */
+ function DeleteList($fcv_array)
+ {
+ if (sizeof($fcv_array) > 0)
+ {
+ $connection = Database::Connect();
+ $pog_query = "delete from `recordversion` where ";
+ for ($i=0, $c=sizeof($fcv_array); $i<$c; $i++)
+ {
+ if (sizeof($fcv_array[$i]) == 1)
+ {
+ $pog_query .= " ".$fcv_array[$i][0]." ";
+ continue;
+ }
+ else
+ {
+ if ($i > 0 && sizeof($fcv_array[$i-1]) !== 1)
+ {
+ $pog_query .= " AND ";
+ }
+ if (isset($this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes']) && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'SET')
+ {
+ $pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." '".$this->Escape($fcv_array[$i][2])."'";
+ }
+ else
+ {
+ $pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." '".$fcv_array[$i][2]."'";
+ }
+ }
+ }
+ return Database::NonQuery($pog_query, $connection);
+ }
+ }
+
+
+ /**
+ * Associates the record object to this one
+ * @return boolean
+ */
+ function GetRecord()
+ {
+ $record = new record();
+ return $record->Get($this->recordId);
+ }
+
+
+ /**
+ * Associates the record object to this one
+ * @return
+ */
+ function SetRecord(&$record)
+ {
+ $this->recordId = $record->recordId;
+ }
+}
+?> \ No newline at end of file
diff --git a/backend/php/src/objects/class.user.php b/backend/php/src/objects/class.user.php
new file mode 100644
index 0000000..f92c7ac
--- a/dev/null
+++ b/backend/php/src/objects/class.user.php
@@ -0,0 +1,502 @@
+<?php
+/*
+ This SQL query will create the table to store your object.
+
+ CREATE TABLE `user` (
+ `userid` int(11) NOT NULL auto_increment,
+ `username` VARCHAR(255) NOT NULL,
+ `srp_s` VARCHAR(255) NOT NULL,
+ `srp_v` VARCHAR(255) NOT NULL,
+ `header` LONGTEXT NOT NULL,
+ `statistics` LONGTEXT NOT NULL,
+ `auth_version` VARCHAR(255) NOT NULL,
+ `version` VARCHAR(255) NOT NULL,
+ `lock` VARCHAR(255) NOT NULL, PRIMARY KEY (`userid`)) ENGINE=MyISAM;
+*/
+
+/**
+* <b>user</b> class with integrated CRUD methods.
+* @author Php Object Generator
+* @version POG 3.0e / PHP5.1 MYSQL
+* @see http://www.phpobjectgenerator.com/plog/tutorials/45/pdo-mysql
+* @copyright Free for personal & commercial use. (Offered under the BSD license)
+* @link http://www.phpobjectgenerator.com/?language=php5.1&wrapper=pdo&pdoDriver=mysql&objectName=user&attributeList=array+%28%0A++0+%3D%3E+%27username%27%2C%0A++1+%3D%3E+%27srp_s%27%2C%0A++2+%3D%3E+%27srp_v%27%2C%0A++3+%3D%3E+%27header%27%2C%0A++4+%3D%3E+%27statistics%27%2C%0A++5+%3D%3E+%27auth_version%27%2C%0A++6+%3D%3E+%27version%27%2C%0A++7+%3D%3E+%27lock%27%2C%0A++8+%3D%3E+%27record%27%2C%0A++9+%3D%3E+%27onetimepassword%27%2C%0A%29&typeList=array%2B%2528%250A%2B%2B0%2B%253D%253E%2B%2527VARCHAR%2528255%2529%2527%252C%250A%2B%2B1%2B%253D%253E%2B%2527VARCHAR%2528255%2529%2527%252C%250A%2B%2B2%2B%253D%253E%2B%2527VARCHAR%2528255%2529%2527%252C%250A%2B%2B3%2B%253D%253E%2B%2527LONGTEXT%2527%252C%250A%2B%2B4%2B%253D%253E%2B%2527LONGTEXT%2527%252C%250A%2B%2B5%2B%253D%253E%2B%2527VARCHAR%2528255%2529%2527%252C%250A%2B%2B6%2B%253D%253E%2B%2527VARCHAR%2528255%2529%2527%252C%250A%2B%2B7%2B%253D%253E%2B%2527VARCHAR%2528255%2529%2527%252C%250A%2B%2B8%2B%253D%253E%2B%2527HASMANY%2527%252C%250A%2B%2B9%2B%253D%253E%2B%2527HASMANY%2527%252C%250A%2529
+*/
+include_once('class.pog_base.php');
+class user extends POG_Base
+{
+ public $userId = '';
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $username;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $srp_s;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $srp_v;
+
+ /**
+ * @var LONGTEXT
+ */
+ public $header;
+
+ /**
+ * @var LONGTEXT
+ */
+ public $statistics;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $auth_version;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $version;
+
+ /**
+ * @var VARCHAR(255)
+ */
+ public $lock;
+
+ /**
+ * @var private array of record objects
+ */
+ private $_recordList = array();
+
+ /**
+ * @var private array of onetimepassword objects
+ */
+ private $_onetimepasswordList = array();
+
+ public $pog_attribute_type = array(
+ "userId" => array('db_attributes' => array("NUMERIC", "INT")),
+ "username" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "srp_s" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "srp_v" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "header" => array('db_attributes' => array("TEXT", "LONGTEXT")),
+ "statistics" => array('db_attributes' => array("TEXT", "LONGTEXT")),
+ "auth_version" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "version" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "lock" => array('db_attributes' => array("TEXT", "VARCHAR", "255")),
+ "record" => array('db_attributes' => array("OBJECT", "HASMANY")),
+ "onetimepassword" => array('db_attributes' => array("OBJECT", "HASMANY")),
+ );
+ public $pog_query;
+
+
+ /**
+ * Getter for some private attributes
+ * @return mixed $attribute
+ */
+ public function __get($attribute)
+ {
+ if (isset($this->{"_".$attribute}))
+ {
+ return $this->{"_".$attribute};
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function user($username='', $srp_s='', $srp_v='', $header='', $statistics='', $auth_version='', $version='', $lock='')
+ {
+ $this->username = $username;
+ $this->srp_s = $srp_s;
+ $this->srp_v = $srp_v;
+ $this->header = $header;
+ $this->statistics = $statistics;
+ $this->auth_version = $auth_version;
+ $this->version = $version;
+ $this->lock = $lock;
+ $this->_recordList = array();
+ $this->_onetimepasswordList = array();
+ }
+
+
+ /**
+ * Gets object from database
+ * @param integer $userId
+ * @return object $user
+ */
+ function Get($userId)
+ {
+ $connection = Database::Connect();
+ $this->pog_query = "select * from `user` where `userid`='".intval($userId)."' LIMIT 1";
+ $cursor = Database::Reader($this->pog_query, $connection);
+ while ($row = Database::Read($cursor))
+ {
+ $this->userId = $row['userid'];
+ $this->username = $this->Unescape($row['username']);
+ $this->srp_s = $this->Unescape($row['srp_s']);
+ $this->srp_v = $this->Unescape($row['srp_v']);
+ $this->header = $this->Unescape($row['header']);
+ $this->statistics = $this->Unescape($row['statistics']);
+ $this->auth_version = $this->Unescape($row['auth_version']);
+ $this->version = $this->Unescape($row['version']);
+ $this->lock = $this->Unescape($row['lock']);
+ }
+ return $this;
+ }
+
+
+ /**
+ * Returns a sorted array of objects that match given conditions
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param string $sortBy
+ * @param boolean $ascending
+ * @param int limit
+ * @return array $userList
+ */
+ function GetList($fcv_array = array(), $sortBy='', $ascending=true, $limit='')
+ {
+ $connection = Database::Connect();
+ $sqlLimit = ($limit != '' ? "LIMIT $limit" : '');
+ $this->pog_query = "select * from `user` ";
+ $userList = Array();
+ if (sizeof($fcv_array) > 0)
+ {
+ $this->pog_query .= " where ";
+ for ($i=0, $c=sizeof($fcv_array); $i<$c; $i++)
+ {
+ if (sizeof($fcv_array[$i]) == 1)
+ {
+ $this->pog_query .= " ".$fcv_array[$i][0]." ";
+ continue;
+ }
+ else
+ {
+ if ($i > 0 && sizeof($fcv_array[$i-1]) != 1)
+ {
+ $this->pog_query .= " AND ";
+ }
+ if (isset($this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes']) && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'SET')
+ {
+ if ($GLOBALS['configuration']['db_encoding'] == 1)
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? "BASE64_DECODE(".$fcv_array[$i][2].")" : "'".$fcv_array[$i][2]."'";
+ $this->pog_query .= "BASE64_DECODE(`".$fcv_array[$i][0]."`) ".$fcv_array[$i][1]." ".$value;
+ }
+ else
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? $fcv_array[$i][2] : "'".$this->Escape($fcv_array[$i][2])."'";
+ $this->pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." ".$value;
+ }
+ }
+ else
+ {
+ $value = POG_Base::IsColumn($fcv_array[$i][2]) ? $fcv_array[$i][2] : "'".$fcv_array[$i][2]."'";
+ $this->pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." ".$value;
+ }
+ }
+ }
+ }
+ if ($sortBy != '')
+ {
+ if (isset($this->pog_attribute_type[$sortBy]['db_attributes']) && $this->pog_attribute_type[$sortBy]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$sortBy]['db_attributes'][0] != 'SET')
+ {
+ if ($GLOBALS['configuration']['db_encoding'] == 1)
+ {
+ $sortBy = "BASE64_DECODE($sortBy) ";
+ }
+ else
+ {
+ $sortBy = "$sortBy ";
+ }
+ }
+ else
+ {
+ $sortBy = "$sortBy ";
+ }
+ }
+ else
+ {
+ $sortBy = "userid";
+ }
+ $this->pog_query .= " order by ".$sortBy." ".($ascending ? "asc" : "desc")." $sqlLimit";
+ $thisObjectName = get_class($this);
+ $cursor = Database::Reader($this->pog_query, $connection);
+ while ($row = Database::Read($cursor))
+ {
+ $user = new $thisObjectName();
+ $user->userId = $row['userid'];
+ $user->username = $this->Unescape($row['username']);
+ $user->srp_s = $this->Unescape($row['srp_s']);
+ $user->srp_v = $this->Unescape($row['srp_v']);
+ $user->header = $this->Unescape($row['header']);
+ $user->statistics = $this->Unescape($row['statistics']);
+ $user->auth_version = $this->Unescape($row['auth_version']);
+ $user->version = $this->Unescape($row['version']);
+ $user->lock = $this->Unescape($row['lock']);
+ $userList[] = $user;
+ }
+ return $userList;
+ }
+
+
+ /**
+ * Saves the object to the database
+ * @return integer $userId
+ */
+ function Save($deep = true)
+ {
+ $connection = Database::Connect();
+ $this->pog_query = "select `userid` from `user` where `userid`='".$this->userId."' LIMIT 1";
+ $rows = Database::Query($this->pog_query, $connection);
+ if ($rows > 0)
+ {
+ $this->pog_query = "update `user` set
+ `username`='".$this->Escape($this->username)."',
+ `srp_s`='".$this->Escape($this->srp_s)."',
+ `srp_v`='".$this->Escape($this->srp_v)."',
+ `header`='".$this->Escape($this->header)."',
+ `statistics`='".$this->Escape($this->statistics)."',
+ `auth_version`='".$this->Escape($this->auth_version)."',
+ `version`='".$this->Escape($this->version)."',
+ `lock`='".$this->Escape($this->lock)."'where `userid`='".$this->userId."'";
+ }
+ else
+ {
+ $this->pog_query = "insert into `user` (`username`, `srp_s`, `srp_v`, `header`, `statistics`, `auth_version`, `version`, `lock`) values (
+ '".$this->Escape($this->username)."',
+ '".$this->Escape($this->srp_s)."',
+ '".$this->Escape($this->srp_v)."',
+ '".$this->Escape($this->header)."',
+ '".$this->Escape($this->statistics)."',
+ '".$this->Escape($this->auth_version)."',
+ '".$this->Escape($this->version)."',
+ '".$this->Escape($this->lock)."')";
+ }
+ $insertId = Database::InsertOrUpdate($this->pog_query, $connection);
+ if ($this->userId == "")
+ {
+ $this->userId = $insertId;
+ }
+ if ($deep)
+ {
+ foreach ($this->_recordList as $record)
+ {
+ $record->userId = $this->userId;
+ $record->Save($deep);
+ }
+ foreach ($this->_onetimepasswordList as $onetimepassword)
+ {
+ $onetimepassword->userId = $this->userId;
+ $onetimepassword->Save($deep);
+ }
+ }
+ return $this->userId;
+ }
+
+
+ /**
+ * Clones the object and saves it to the database
+ * @return integer $userId
+ */
+ function SaveNew($deep = false)
+ {
+ $this->userId = '';
+ return $this->Save($deep);
+ }
+
+
+ /**
+ * Deletes the object from the database
+ * @return boolean
+ */
+ function Delete($deep = false, $across = false)
+ {
+ if ($deep)
+ {
+ $recordList = $this->GetRecordList();
+ foreach ($recordList as $record)
+ {
+ $record->Delete($deep, $across);
+ }
+ $onetimepasswordList = $this->GetOnetimepasswordList();
+ foreach ($onetimepasswordList as $onetimepassword)
+ {
+ $onetimepassword->Delete($deep, $across);
+ }
+ }
+ $connection = Database::Connect();
+ $this->pog_query = "delete from `user` where `userid`='".$this->userId."'";
+ return Database::NonQuery($this->pog_query, $connection);
+ }
+
+
+ /**
+ * Deletes a list of objects that match given conditions
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param bool $deep
+ * @return
+ */
+ function DeleteList($fcv_array, $deep = false, $across = false)
+ {
+ if (sizeof($fcv_array) > 0)
+ {
+ if ($deep || $across)
+ {
+ $objectList = $this->GetList($fcv_array);
+ foreach ($objectList as $object)
+ {
+ $object->Delete($deep, $across);
+ }
+ }
+ else
+ {
+ $connection = Database::Connect();
+ $pog_query = "delete from `user` where ";
+ for ($i=0, $c=sizeof($fcv_array); $i<$c; $i++)
+ {
+ if (sizeof($fcv_array[$i]) == 1)
+ {
+ $pog_query .= " ".$fcv_array[$i][0]." ";
+ continue;
+ }
+ else
+ {
+ if ($i > 0 && sizeof($fcv_array[$i-1]) !== 1)
+ {
+ $pog_query .= " AND ";
+ }
+ if (isset($this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes']) && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'NUMERIC' && $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] != 'SET')
+ {
+ $pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." '".$this->Escape($fcv_array[$i][2])."'";
+ }
+ else
+ {
+ $pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." '".$fcv_array[$i][2]."'";
+ }
+ }
+ }
+ return Database::NonQuery($pog_query, $connection);
+ }
+ }
+ }
+
+
+ /**
+ * Gets a list of record objects associated to this one
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param string $sortBy
+ * @param boolean $ascending
+ * @param int limit
+ * @return array of record objects
+ */
+ function GetRecordList($fcv_array = array(), $sortBy='', $ascending=true, $limit='')
+ {
+ $record = new record();
+ $fcv_array[] = array("userId", "=", $this->userId);
+ $dbObjects = $record->GetList($fcv_array, $sortBy, $ascending, $limit);
+ return $dbObjects;
+ }
+
+
+ /**
+ * Makes this the parent of all record objects in the record List array. Any existing record will become orphan(s)
+ * @return null
+ */
+ function SetRecordList(&$list)
+ {
+ $this->_recordList = array();
+ $existingRecordList = $this->GetRecordList();
+ foreach ($existingRecordList as $record)
+ {
+ $record->userId = '';
+ $record->Save(false);
+ }
+ $this->_recordList = $list;
+ }
+
+
+ /**
+ * Associates the record object to this one
+ * @return
+ */
+ function AddRecord(&$record)
+ {
+ $record->userId = $this->userId;
+ $found = false;
+ foreach($this->_recordList as $record2)
+ {
+ if ($record->recordId > 0 && $record->recordId == $record2->recordId)
+ {
+ $found = true;
+ break;
+ }
+ }
+ if (!$found)
+ {
+ $this->_recordList[] = $record;
+ }
+ }
+
+
+ /**
+ * Gets a list of onetimepassword objects associated to this one
+ * @param multidimensional array {("field", "comparator", "value"), ("field", "comparator", "value"), ...}
+ * @param string $sortBy
+ * @param boolean $ascending
+ * @param int limit
+ * @return array of onetimepassword objects
+ */
+ function GetOnetimepasswordList($fcv_array = array(), $sortBy='', $ascending=true, $limit='')
+ {
+ $onetimepassword = new onetimepassword();
+ $fcv_array[] = array("userId", "=", $this->userId);
+ $dbObjects = $onetimepassword->GetList($fcv_array, $sortBy, $ascending, $limit);
+ return $dbObjects;
+ }
+
+
+ /**
+ * Makes this the parent of all onetimepassword objects in the onetimepassword List array. Any existing onetimepassword will become orphan(s)
+ * @return null
+ */
+ function SetOnetimepasswordList(&$list)
+ {
+ $this->_onetimepasswordList = array();
+ $existingOnetimepasswordList = $this->GetOnetimepasswordList();
+ foreach ($existingOnetimepasswordList as $onetimepassword)
+ {
+ $onetimepassword->userId = '';
+ $onetimepassword->Save(false);
+ }
+ $this->_onetimepasswordList = $list;
+ }
+
+
+ /**
+ * Associates the onetimepassword object to this one
+ * @return
+ */
+ function AddOnetimepassword(&$onetimepassword)
+ {
+ $onetimepassword->userId = $this->userId;
+ $found = false;
+ foreach($this->_onetimepasswordList as $onetimepassword2)
+ {
+ if ($onetimepassword->onetimepasswordId > 0 && $onetimepassword->onetimepasswordId == $onetimepassword2->onetimepasswordId)
+ {
+ $found = true;
+ break;
+ }
+ }
+ if (!$found)
+ {
+ $this->_onetimepasswordList[] = $onetimepassword;
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/backend/php/src/objects/ignore_objects.txt b/backend/php/src/objects/ignore_objects.txt
new file mode 100644
index 0000000..e69de29
--- a/dev/null
+++ b/backend/php/src/objects/ignore_objects.txt
diff --git a/backend/php/src/plugins/IPlugin.php b/backend/php/src/plugins/IPlugin.php
new file mode 100644
index 0000000..3e39e70
--- a/dev/null
+++ b/backend/php/src/plugins/IPlugin.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * All functions must be implemented to create a correct POG plugin
+ * The 'optional' functions SetupRender() and AuthorPage() must be implemented and return null
+ * if your plugin does not need them.
+ *
+ */
+interface POG_Plugin
+{
+ /**
+ *
+ * REQUIRED
+ * This function must return the version of the plugin.
+ * It will be used to automatically notify developer when your plugin is updated.
+ *
+ */
+ function Version();
+
+ /**
+ *
+ * REQUIRED
+ * This function performs the actions that your plugin provides.
+ *
+ */
+ function Execute();
+
+ /**
+ * 'OPTIONAL'
+ * If your plugin needs an administrative interface, implement this function.
+ * Else return null
+ *
+ */
+ function SetupRender();
+
+
+ /**
+ *
+ * 'OPTIONAL'
+ * Implement this function to provide a link to your homepage.
+ * e.g. return 'http://myhomepage.com';
+ *
+ * return null if you do not want to link to your homepage
+ * e.g. return null
+ *
+ */
+ function AuthorPage();
+}
+?> \ No newline at end of file
diff --git a/backend/php/src/plugins/base64_install.sql b/backend/php/src/plugins/base64_install.sql
new file mode 100644
index 0000000..40401d6
--- a/dev/null
+++ b/backend/php/src/plugins/base64_install.sql
@@ -0,0 +1,172 @@
+-- base64.sql - MySQL base64 encoding/decoding functions
+-- Copyright (C) 2006 Ian Gulliver
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of version 2 of the GNU General Public License as
+-- published by the Free Software Foundation.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+DROP TABLE IF EXISTS base64_data |
+CREATE TABLE base64_data (c CHAR(1) BINARY, val TINYINT) |
+INSERT INTO base64_data VALUES
+ ('A',0), ('B',1), ('C',2), ('D',3), ('E',4), ('F',5), ('G',6), ('H',7), ('I',8), ('J',9),
+ ('K',10), ('L',11), ('M',12), ('N',13), ('O',14), ('P',15), ('Q',16), ('R',17), ('S',18), ('T',19),
+ ('U',20), ('V',21), ('W',22), ('X',23), ('Y',24), ('Z',25), ('a',26), ('b',27), ('c',28), ('d',29),
+ ('e',30), ('f',31), ('g',32), ('h',33), ('i',34), ('j',35), ('k',36), ('l',37), ('m',38), ('n',39),
+ ('o',40), ('p',41), ('q',42), ('r',43), ('s',44), ('t',45), ('u',46), ('v',47), ('w',48), ('x',49),
+ ('y',50), ('z',51), ('0',52), ('1',53), ('2',54), ('3',55), ('4',56), ('5',57), ('6',58), ('7',59),
+ ('8',60), ('9',61), ('+',62), ('/',63), ('=',0) |
+
+
+DROP FUNCTION IF EXISTS BASE64_DECODE |
+CREATE FUNCTION BASE64_DECODE (input BLOB)
+ RETURNS BLOB
+ CONTAINS SQL
+ DETERMINISTIC
+ SQL SECURITY INVOKER
+BEGIN
+ DECLARE ret BLOB DEFAULT '';
+ DECLARE done TINYINT DEFAULT 0;
+
+ IF input IS NULL THEN
+ RETURN NULL;
+ END IF;
+
+each_block:
+ WHILE NOT done DO BEGIN
+ DECLARE accum_value BIGINT UNSIGNED DEFAULT 0;
+ DECLARE in_count TINYINT DEFAULT 0;
+ DECLARE out_count TINYINT DEFAULT 3;
+
+each_input_char:
+ WHILE in_count < 4 DO BEGIN
+ DECLARE first_char CHAR(1);
+
+ IF LENGTH(input) = 0 THEN
+ RETURN ret;
+ END IF;
+
+ SET first_char = SUBSTRING(input,1,1);
+ SET input = SUBSTRING(input,2);
+
+ BEGIN
+ DECLARE tempval TINYINT UNSIGNED;
+ DECLARE error TINYINT DEFAULT 0;
+ DECLARE base64_getval CURSOR FOR SELECT val FROM base64_data WHERE c = first_char;
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET error = 1;
+
+ OPEN base64_getval;
+ FETCH base64_getval INTO tempval;
+ CLOSE base64_getval;
+
+ IF error THEN
+ ITERATE each_input_char;
+ END IF;
+
+ SET accum_value = (accum_value << 6) + tempval;
+ END;
+
+ SET in_count = in_count + 1;
+
+ IF first_char = '=' THEN
+ SET done = 1;
+ SET out_count = out_count - 1;
+ END IF;
+ END; END WHILE;
+
+ -- We've now accumulated 24 bits; deaccumulate into bytes
+
+ -- We have to work from the left, so use the third byte position and shift left
+ WHILE out_count > 0 DO BEGIN
+ SET ret = CONCAT(ret,CHAR((accum_value & 0xff0000) >> 16));
+ SET out_count = out_count - 1;
+ SET accum_value = (accum_value << 8) & 0xffffff;
+ END; END WHILE;
+
+ END; END WHILE;
+
+ RETURN ret;
+END |
+
+DROP FUNCTION IF EXISTS BASE64_ENCODE |
+CREATE FUNCTION BASE64_ENCODE (input BLOB)
+ RETURNS BLOB
+ CONTAINS SQL
+ DETERMINISTIC
+ SQL SECURITY INVOKER
+BEGIN
+ DECLARE ret BLOB DEFAULT '';
+ DECLARE done TINYINT DEFAULT 0;
+
+ IF input IS NULL THEN
+ RETURN NULL;
+ END IF;
+
+each_block:
+ WHILE NOT done DO BEGIN
+ DECLARE accum_value BIGINT UNSIGNED DEFAULT 0;
+ DECLARE in_count TINYINT DEFAULT 0;
+ DECLARE out_count TINYINT;
+
+each_input_char:
+ WHILE in_count < 3 DO BEGIN
+ DECLARE first_char CHAR(1);
+
+ IF LENGTH(input) = 0 THEN
+ SET done = 1;
+ SET accum_value = accum_value << (8 * (3 - in_count));
+ LEAVE each_input_char;
+ END IF;
+
+ SET first_char = SUBSTRING(input,1,1);
+ SET input = SUBSTRING(input,2);
+
+ SET accum_value = (accum_value << 8) + ASCII(first_char);
+
+ SET in_count = in_count + 1;
+ END; END WHILE;
+
+ -- We've now accumulated 24 bits; deaccumulate into base64 characters
+
+ -- We have to work from the left, so use the third byte position and shift left
+ CASE
+ WHEN in_count = 3 THEN SET out_count = 4;
+ WHEN in_count = 2 THEN SET out_count = 3;
+ WHEN in_count = 1 THEN SET out_count = 2;
+ ELSE RETURN ret;
+ END CASE;
+
+ WHILE out_count > 0 DO BEGIN
+ BEGIN
+ DECLARE out_char CHAR(1);
+ DECLARE base64_getval CURSOR FOR SELECT c FROM base64_data WHERE val = (accum_value >> 18);
+
+ OPEN base64_getval;
+ FETCH base64_getval INTO out_char;
+ CLOSE base64_getval;
+
+ SET ret = CONCAT(ret,out_char);
+ SET out_count = out_count - 1;
+ SET accum_value = accum_value << 6 & 0xffffff;
+ END;
+ END; END WHILE;
+
+ CASE
+ WHEN in_count = 2 THEN SET ret = CONCAT(ret,'=');
+ WHEN in_count = 1 THEN SET ret = CONCAT(ret,'==');
+ ELSE BEGIN END;
+ END CASE;
+
+ END; END WHILE;
+
+ RETURN ret;
+END |
diff --git a/backend/php/src/plugins/base64_uninstall.sql b/backend/php/src/plugins/base64_uninstall.sql
new file mode 100644
index 0000000..02b9b6b
--- a/dev/null
+++ b/backend/php/src/plugins/base64_uninstall.sql
@@ -0,0 +1,20 @@
+-- base64.sql - MySQL base64 encoding/decoding functions
+-- Copyright (C) 2006 Ian Gulliver
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of version 2 of the GNU General Public License as
+-- published by the Free Software Foundation.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+DROP TABLE IF EXISTS base64_data |
+DROP FUNCTION IF EXISTS BASE64_DECODE |
+DROP FUNCTION IF EXISTS BASE64_ENCODE | \ No newline at end of file
diff --git a/backend/php/src/plugins/plugin.base64.php b/backend/php/src/plugins/plugin.base64.php
new file mode 100644
index 0000000..323f861
--- a/dev/null
+++ b/backend/php/src/plugins/plugin.base64.php
@@ -0,0 +1,128 @@
+<?php
+class Base64
+{
+ var $sourceObject;
+ var $argv;
+ var $version = '1.0';
+
+ function Version()
+ {
+ return $this->version;
+ }
+
+ function Base64($sourceObject, $argv)
+ {
+ $this->sourceObject = $sourceObject;
+ $this->argv = $argv;
+ }
+
+ function Execute()
+ {
+ return null;
+ }
+
+ function SetupRender()
+ {
+ if (isset($_POST['install_base64']) || isset($_POST['uninstall_base64']))
+ {
+ $this->SetupExecute();
+ }
+ else
+ {
+ $out = "This plugin allows you to install and uninstall a base64 custom function to and from your database.
+ You can then set \$configuration['db_encoding'] = 1 so that all data is transparently encoded and decoded
+ with the minimal overhead possible. Enabling data encoding has quite a few advantages: <br/><br/>
+
+ ";
+ $out .= "<br/><br/><textarea>BASE64 Status";
+ if (Base64::IsBase64FunctionInstalled())
+ {
+ $out .= "\n\tChecking MySQL function....OK!";
+ if (!isset($GLOBALS['configuration']['db_encoding']) || $GLOBALS['configuration']['db_encoding'] != 1)
+ {
+ $out .= "\n\tChecking db_encoding status....Failed";
+ $out .= "\n\n---------------------------------------------------";
+ $out .= "\n\$configuration['db_encoding'] is set to 0. Make sure you set the value to 1 to enable data encoding.";
+ }
+ else
+ {
+ $out .= "\n\tChecking db_encoding status....OK!";
+ $out .= "\n\nBASE64 Status...OK!";
+ $out .= "\n---------------------------------------------------";
+ }
+ $out .= "</textarea><div style='padding-left:250px;padding-top:10px;'><input type='submit' value='UNINSTALL' name='uninstall_base64'/></div>";
+ }
+ else
+ {
+ $out .= "\n\tChecking MySQL function....NOT INSTALLED";
+ $out .= "\n\tChecking db_encoding status ignored";
+ $out .= "\n\n---------------------------------------------------";
+ $out .= "\nClick the INSTALL button below to install the base64 function to your database.";
+ $out .= "</textarea><div style='padding-left:250px;padding-top:10px;'><input type='submit' value='INSTALL' name='install_base64'/></div>";
+ }
+ $out .= "<input type='hidden' name='plugins' value='true'/>";
+ echo $out;
+ }
+ }
+
+ function AuthorPage()
+ {
+ return null;
+ }
+
+
+ function SetupExecute()
+ {
+ $out = '';
+ $connection = Database::Connect();
+ if (isset($_POST['install_base64']) && isset($_POST['install_base64']) == true)
+ {
+ $initialData = file_get_contents('../plugins/base64_install.sql');
+ $statements = explode('|', $initialData);
+ if (sizeof($statements) > 0)
+ {
+ foreach ($statements as $statement)
+ {
+ if (trim($statement) != '')
+ {
+ Database::NonQuery($statement, $connection);
+ }
+ }
+ }
+ $out .= "<textarea>INSTALL SUCCESSFUL\n\n";
+ $out .= "Make sure you set \$configuration[db_encoding] = 1 in the configuration file.</textarea>";
+ }
+ else if (isset($_POST['uninstall_base64']) && $_POST['uninstall_base64'] == true)
+ {
+ $initialData = file_get_contents('../plugins/base64_uninstall.sql');
+ $statements = explode('|', $initialData);
+ if (sizeof($statements) > 0)
+ {
+ foreach ($statements as $statement)
+ {
+ if (trim($statement) != '')
+ {
+ Database::NonQuery($statement, $connection);
+ }
+ }
+ }
+ $out .= "<textarea>UNINSTALL SUCCESSFUL\n\n";
+ $out .= "Make sure you set \$configuration[db_encoding] = 0 in the configuration file.</textarea>";
+ }
+ echo $out;
+ }
+
+ function IsBase64FunctionInstalled()
+ {
+ $sql1 = "show function status where Db='".$GLOBALS['configuration']['db']."' and (Name='BASE64_DECODE' or Name='BASE64_ENCODE')";
+ $sql2 = "show tables like 'base64_data'";
+ $connection = Database::Connect();
+ $result = Database::Query($sql1, $connection);
+ $result2 = Database::Query($sql2, $connection);
+ if ($result == 2 && $result2 == 1)
+ {
+ return true;
+ }
+ return false;
+ }
+}
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">&nbsp;</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>&nbsp;<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>&nbsp;<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 .= "&#8249;&#8249;<a href='#' onclick='javascript:refTree(".($offset-$limit).", $limit, \"$objectName\");return false;'>Newer</a> | ";
+ $menu_html_code.= "&#8249;&#8249;<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>&#8250;&#8250;";
+ $menu_html_code.= "| <a href='#' onclick='javascript:refTree(".($offset+$limit).", $limit, \"$objectName\");return false;'>Older</a>&#8250;&#8250;";
+ }
+ $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
new file mode 100644
index 0000000..363cc1c
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/background_id.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/button_add.gif b/backend/php/src/setup/setup_images/button_add.gif
new file mode 100644
index 0000000..2b9fc72
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/button_add.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/button_delete.gif b/backend/php/src/setup/setup_images/button_delete.gif
new file mode 100644
index 0000000..31cc30f
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/button_delete.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/button_toolbar_author.gif b/backend/php/src/setup/setup_images/button_toolbar_author.gif
new file mode 100644
index 0000000..b7f9f2b
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/button_toolbar_author.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/button_toolbar_help.gif b/backend/php/src/setup/setup_images/button_toolbar_help.gif
new file mode 100644
index 0000000..324f1d4
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/button_toolbar_help.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/button_toolbar_homepage.gif b/backend/php/src/setup/setup_images/button_toolbar_homepage.gif
new file mode 100644
index 0000000..274f235
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/button_toolbar_homepage.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/button_toolbar_left.gif b/backend/php/src/setup/setup_images/button_toolbar_left.gif
new file mode 100644
index 0000000..a0bbc5f
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/button_toolbar_left.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/button_update.gif b/backend/php/src/setup/setup_images/button_update.gif
new file mode 100644
index 0000000..1ee086f
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/button_update.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/folderclose.gif b/backend/php/src/setup/setup_images/folderclose.gif
new file mode 100644
index 0000000..112a784
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/folderclose.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/folderopen.gif b/backend/php/src/setup/setup_images/folderopen.gif
new file mode 100644
index 0000000..443dd4e
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/folderopen.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/generate.jpg b/backend/php/src/setup/setup_images/generate.jpg
new file mode 100644
index 0000000..8eb8e71
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/generate.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/gradient_container.gif b/backend/php/src/setup/setup_images/gradient_container.gif
new file mode 100644
index 0000000..a6430f8
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/gradient_container.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/loading.gif b/backend/php/src/setup/setup_images/loading.gif
new file mode 100644
index 0000000..bf510da
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/loading.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/mini_pog.jpg b/backend/php/src/setup/setup_images/mini_pog.jpg
new file mode 100644
index 0000000..3cbf683
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/mini_pog.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/pog_setup_closed.jpg b/backend/php/src/setup/setup_images/pog_setup_closed.jpg
new file mode 100644
index 0000000..e493506
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/pog_setup_closed.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/pog_setup_open.jpg b/backend/php/src/setup/setup_images/pog_setup_open.jpg
new file mode 100644
index 0000000..4417e8c
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/pog_setup_open.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_attachtables.jpg b/backend/php/src/setup/setup_images/setup_attachtables.jpg
new file mode 100644
index 0000000..0ffeafa
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_attachtables.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_bottom3.jpg b/backend/php/src/setup/setup_images/setup_bottom3.jpg
new file mode 100644
index 0000000..798d96d
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_bottom3.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_bottom3tile.jpg b/backend/php/src/setup/setup_images/setup_bottom3tile.jpg
new file mode 100644
index 0000000..abbe75d
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_bottom3tile.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_collapseall.jpg b/backend/php/src/setup/setup_images/setup_collapseall.jpg
new file mode 100644
index 0000000..5a316c4
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_collapseall.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_deleteall.jpg b/backend/php/src/setup/setup_images/setup_deleteall.jpg
new file mode 100644
index 0000000..f884e74
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_deleteall.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_expandall.jpg b/backend/php/src/setup/setup_images/setup_expandall.jpg
new file mode 100644
index 0000000..52751dd
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_expandall.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_footer.jpg b/backend/php/src/setup/setup_images/setup_footer.jpg
new file mode 100644
index 0000000..4b57b24
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_footer.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_generateform.jpg b/backend/php/src/setup/setup_images/setup_generateform.jpg
new file mode 100644
index 0000000..1da8733
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_generateform.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_logo1.jpg b/backend/php/src/setup/setup_images/setup_logo1.jpg
new file mode 100644
index 0000000..6530570
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_logo1.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_logo2.jpg b/backend/php/src/setup/setup_images/setup_logo2.jpg
new file mode 100644
index 0000000..7d05645
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_logo2.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_logo3.jpg b/backend/php/src/setup/setup_images/setup_logo3.jpg
new file mode 100644
index 0000000..8d97149
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_logo3.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_pogmeup.gif b/backend/php/src/setup/setup_images/setup_pogmeup.gif
new file mode 100644
index 0000000..ab95cb7
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_pogmeup.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_proceed.gif b/backend/php/src/setup/setup_images/setup_proceed.gif
new file mode 100644
index 0000000..878b1c2
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_proceed.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_recheck.jpg b/backend/php/src/setup/setup_images/setup_recheck.jpg
new file mode 100644
index 0000000..0b0bcb7
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_recheck.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_regenerate.jpg b/backend/php/src/setup/setup_images/setup_regenerate.jpg
new file mode 100644
index 0000000..878d6bc
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_regenerate.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_toolbargradient.jpg b/backend/php/src/setup/setup_images/setup_toolbargradient.jpg
new file mode 100644
index 0000000..1a9fede
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_toolbargradient.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_updateall.jpg b/backend/php/src/setup/setup_images/setup_updateall.jpg
new file mode 100644
index 0000000..2b8be24
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_updateall.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/setup_welcome.jpg b/backend/php/src/setup/setup_images/setup_welcome.jpg
new file mode 100644
index 0000000..59a03e4
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/setup_welcome.jpg
Binary files differ
diff --git a/backend/php/src/setup/setup_images/tab_activeobjectleft.gif b/backend/php/src/setup/setup_images/tab_activeobjectleft.gif
new file mode 100644
index 0000000..c80504a
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/tab_activeobjectleft.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/tab_activeobjectright.gif b/backend/php/src/setup/setup_images/tab_activeobjectright.gif
new file mode 100644
index 0000000..646f0b0
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/tab_activeobjectright.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/tab_diagnosticresults.gif b/backend/php/src/setup/setup_images/tab_diagnosticresults.gif
new file mode 100644
index 0000000..f0e9a5b
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/tab_diagnosticresults.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/tab_diagnosticresults_on.gif b/backend/php/src/setup/setup_images/tab_diagnosticresults_on.gif
new file mode 100644
index 0000000..e2b8002
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/tab_diagnosticresults_on.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/tab_manageobjects.gif b/backend/php/src/setup/setup_images/tab_manageobjects.gif
new file mode 100644
index 0000000..06b72b2
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/tab_manageobjects.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/tab_manageobjects_on.gif b/backend/php/src/setup/setup_images/tab_manageobjects_on.gif
new file mode 100644
index 0000000..55006a3
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/tab_manageobjects_on.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/tab_manageplugins_off.gif b/backend/php/src/setup/setup_images/tab_manageplugins_off.gif
new file mode 100644
index 0000000..d55f605
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/tab_manageplugins_off.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/tab_manageplugins_on.gif b/backend/php/src/setup/setup_images/tab_manageplugins_on.gif
new file mode 100644
index 0000000..1b26ee0
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/tab_manageplugins_on.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/tab_separator.gif b/backend/php/src/setup/setup_images/tab_separator.gif
new file mode 100644
index 0000000..76bb9cf
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/tab_separator.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/tab_setup.gif b/backend/php/src/setup/setup_images/tab_setup.gif
new file mode 100644
index 0000000..a4a5a75
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/tab_setup.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/tab_setup_on.gif b/backend/php/src/setup/setup_images/tab_setup_on.gif
new file mode 100644
index 0000000..c3d4a41
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/tab_setup_on.gif
Binary files differ
diff --git a/backend/php/src/setup/setup_images/toolbar_separator.gif b/backend/php/src/setup/setup_images/toolbar_separator.gif
new file mode 100644
index 0000000..e061b56
--- a/dev/null
+++ b/backend/php/src/setup/setup_images/toolbar_separator.gif
Binary files differ
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+'&currentnode='+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\">&nbsp;&nbsp;";
+ }
+ else
+ {
+ $img = "<img onClick=\"".$img_js."xMenuShowHide(document.getElementById('Xtree".$this->treeCount."'));\" id=\"Ximg".$this->imgCount."\" src=\"".$myChild->img."\" border=\"0\">&nbsp;&nbsp;";
+ }
+ }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
diff --git a/backend/php/src/test.php b/backend/php/src/test.php
new file mode 100644
index 0000000..827ee66
--- a/dev/null
+++ b/backend/php/src/test.php
@@ -0,0 +1,15 @@
+<?php
+// $Id: index.php,v 1.0 2004/05/11 11:11:11 phppp(D.J.) Exp $
+// Copyright (c) 2004 INFOphp.com //
+// ---------------------------------------------------------------- //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License for more details. //
+// ---------------------------------------------------------------- //
+
+// include "infophp.inc";
+// echo infophp::phpinfo();
+
+ echo phpinfo();
+?> \ No newline at end of file
diff --git a/backend/python/properties/python.properties.json b/backend/python/properties/python.properties.json
new file mode 100644
index 0000000..e69de29
--- a/dev/null
+++ b/backend/python/properties/python.properties.json
diff --git a/backend/python/src/app.yaml b/backend/python/src/app.yaml
new file mode 100644
index 0000000..5e085a9
--- a/dev/null
+++ b/backend/python/src/app.yaml
@@ -0,0 +1,20 @@
+application: clipperz
+version: 1
+runtime: python
+api_version: 1
+
+handlers:
+- url: /json
+ script: clipperz.py
+
+- url: /css
+ static_dir: css
+
+- url: /js
+ static_dir: js
+
+- url: /images
+ static_dir: images
+
+- url: /.*
+ script: clipperz.py
diff --git a/backend/python/src/clipperz.py b/backend/python/src/clipperz.py
new file mode 100644
index 0000000..c8d91de
--- a/dev/null
+++ b/backend/python/src/clipperz.py
@@ -0,0 +1,708 @@
+#
+# Copyright 2008-2011 Clipperz Srl
+#
+# This file is part of Clipperz's Javascript Crypto Library.
+# Javascript Crypto Library provides web developers with an extensive
+# and efficient set of cryptographic functions. The library aims to
+# obtain maximum execution speed while preserving modularity and
+# reusability.
+# For further information about its features and functionalities please
+# refer to http://www.clipperz.com
+#
+# * Javascript Crypto Library is free software: you can redistribute
+# it and/or modify it under the terms of the GNU Affero General Public
+# License as published by the Free Software Foundation, either version
+# 3 of the License, or (at your option) any later version.
+#
+# * Javascript Crypto Library is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU Affero General Public License for more details.
+#
+# * You should have received a copy of the GNU Affero General Public
+# License along with Javascript Crypto Library. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+import os
+import cgi
+import wsgiref.handlers
+
+import datetime
+import uuid
+import random
+import hashlib
+
+import logging
+
+from google.appengine.api import users
+from google.appengine.ext import webapp
+from google.appengine.ext import db
+from google.appengine.ext.webapp import template
+
+from django.utils import simplejson
+
+#==============================================================================
+
+sessionTimeout = datetime.timedelta(minutes=-2)
+
+def randomSeed():
+ return hex(random.getrandbits(32*8))[2:-1]
+
+def clipperzHash(aString):
+ #logging.info(">>> string: " + aString)
+ firstRound = hashlib.sha256()
+ firstRound.update(aString)
+ #logging.info("firstRound: " + firstRound.hexdigest() + " - " + firstRound.digest())
+ result = hashlib.sha256()
+ result.update(firstRound.digest())
+ #logging.info("<<< finalResul: " + result.hexdigest())
+
+ return result.hexdigest()
+
+#==============================================================================
+
+class User(db.Model):
+ username = db.StringProperty()
+ srp_s = db.StringProperty()
+ srp_v = db.StringProperty()
+ header = db.TextProperty()
+ statistics = db.TextProperty()
+ auth_version= db.StringProperty()
+ version = db.StringProperty()
+ lock = db.StringProperty()
+
+ def updateCredentials(self, someCredentials):
+ self.username = someCredentials['C']
+ self.srp_s = someCredentials['s']
+ self.srp_v = someCredentials['v']
+ self.auth_version = someCredentials['version']
+
+ def update(self, someData):
+ self.header = someData['header']
+ self.statistics = someData['statistics']
+ self.version = someData['version']
+ self.lock = someData['lock']
+
+#------------------------------------------------------------------------------
+
+class Record(db.Model):
+ user = db.ReferenceProperty(User)
+ reference = db.StringProperty()
+ data = db.TextProperty()
+ version = db.StringProperty()
+ creation_date = db.DateTimeProperty(auto_now_add=True)
+ update_date = db.DateTimeProperty(auto_now_add=True)
+ access_date = db.DateTimeProperty(auto_now_add=True)
+
+#------------------------------------------------------------------------------
+
+class RecordVersion(db.Model):
+ record = db.ReferenceProperty(Record)
+ reference = db.StringProperty()
+ header = db.TextProperty()
+ data = db.TextProperty()
+ version = db.StringProperty()
+ previousVersionKey = db.StringProperty()
+ previousVersion = db.SelfReferenceProperty()
+ creation_date = db.DateTimeProperty(auto_now_add=True)
+ update_date = db.DateTimeProperty(auto_now_add=True)
+ access_date = db.DateTimeProperty(auto_now_add=True)
+
+ def update(self, someData):
+ recordData = someData['record'];
+ self.parent().reference = recordData['reference']
+ self.parent().data = recordData['data']
+ self.parent().version = recordData['version']
+ self.parent().update_date = datetime.datetime.now()
+
+ recordVersionData = someData['currentRecordVersion'];
+ self.reference = recordVersionData ['reference']
+ self.data = recordVersionData ['data']
+ self.version = recordVersionData ['version']
+ #self.previous_version = #recordVersionData ['previousVersion']
+ self.previous_version_key = recordVersionData ['previousVersionKey']
+ self.update_date = datetime.datetime.now()
+
+#------------------------------------------------------------------------------
+
+class OneTimePassword(db.Model):
+ user = db.ReferenceProperty(User)
+ status = db.StringProperty()
+ reference = db.StringProperty()
+ keyValue = db.StringProperty()
+ keyChecksum = db.StringProperty()
+ data = db.TextProperty()
+ version = db.StringProperty()
+ creation_date = db.DateTimeProperty(auto_now_add=True)
+ request_date = db.DateTimeProperty()
+ usage_date = db.DateTimeProperty()
+
+ def update(self, someParameters, aStatus):
+ self.reference = someParameters['reference']
+ self.keyValue = someParameters['key']
+ self.keyChecksum = someParameters['keyChecksum']
+ self.data = someParameters['data']
+ self.version = someParameters['version']
+ self.status = aStatus
+
+ def reset(self, aStatus):
+ self.data = ""
+ self.status = aStatus
+
+ return self
+
+#------------------------------------------------------------------------------
+
+class Session(db.Expando):
+ sessionId = db.StringProperty()
+ access_date = db.DateTimeProperty()
+
+#==============================================================================
+
+class MainPage(webapp.RequestHandler):
+ def get(self):
+ path = os.path.join(os.path.dirname(__file__), 'static%s' % self.request.path)
+ self.response.out.write(template.render(path, {}))
+
+#==============================================================================
+
+class XHR(webapp.RequestHandler):
+
+ #==========================================================================
+
+ def get(self):
+ logging.info("self.request.path: " + self.request.path)
+ if self.request.path == "/dump":
+ session = self.getSession()
+ userData = {}
+ offline_data_placeholder = ""
+
+ user = db.Query(User).filter('username =', session.C).get()
+
+ userData['users'] = {
+ 'catchAllUser': {
+ '__masterkey_test_value__': 'masterkey',
+ 's': '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ 'v': '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ }
+ }
+
+ records = {}
+ for currentRecord in db.Query(Record).ancestor(user):
+ versions = {}
+ for currentVersion in db.Query(RecordVersion).ancestor(currentRecord):
+ versions[currentVersion.reference] ={
+ 'header': currentVersion.header,
+ 'data': currentVersion.data,
+ 'version': currentVersion.version,
+ 'creationDate': str(currentVersion.creation_date),
+ 'updateDate': str(currentVersion.update_date),
+ 'accessDate': str(currentVersion.access_date)
+ }
+
+ records[currentRecord.reference] = {
+ 'data': currentRecord.data,
+ 'version': currentRecord.version,
+ 'creationDate': str(currentRecord.creation_date),
+ 'updateDate': str(currentRecord.update_date),
+ 'accessDate': str(currentRecord.access_date),
+ 'currentVersion': currentVersion.reference,
+ 'versions': versions
+ }
+
+ userData['users'][user.username] = {
+ 's': user.srp_s,
+ 'v': user.srp_v,
+ 'version': user.auth_version,
+ 'maxNumberOfRecords': '100',
+ 'userDetails': user.header,
+ 'statistics': user.statistics,
+ 'userDetailsVersion': user.version,
+ 'records': records
+ }
+
+ offline_data_placeholder = offline_data_placeholder + "_clipperz_dump_data_ = " + simplejson.dumps(userData, indent=4) + "\n"
+ offline_data_placeholder = offline_data_placeholder + "Clipperz.PM.Proxy.defaultProxy = new Clipperz.PM.Proxy.Offline();" + "\n"
+ offline_data_placeholder = offline_data_placeholder + "Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();" + "\n"
+
+ path = os.path.join(os.path.dirname(__file__), 'static/dump.html')
+
+ self.response.headers.add_header('Content-Type', 'text/html')
+ self.response.headers.add_header('Content-Disposition', 'attachment', filename='Clipperz.html')
+ self.response.out.write(template.render(path, {'offline_data_placeholder': offline_data_placeholder}))
+
+ #==========================================================================
+
+ def post(self):
+ method = self.request.get('method')
+ parameters = simplejson.loads(self.request.get('parameters'))
+ session = self.getSession()
+ result = {};
+
+ #----------------------------------------------------------------------
+
+ if method == 'registration':
+ message = parameters['message'];
+
+ if message == 'completeRegistration':
+ user = User()
+
+ user.updateCredentials(parameters['credentials'])
+ user.update(parameters['user'])
+ user.put()
+
+ result['lock'] = user.lock
+ result['result'] = "done"
+
+ #----------------------------------------------------------------------
+
+ elif method == 'handshake':
+ srp_g = 2L
+ srp_n = long("0x%s" % "115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16)
+
+ message = parameters['message'];
+
+ #------------------------------------------------------------------
+
+ if message == 'connect':
+ session.C = parameters['parameters']['C']
+ session.A = parameters['parameters']['A']
+
+ user = db.Query(User).filter('username =', session.C).get()
+
+ if user != None:
+ try:
+ optId = session.otpId
+
+ oneTimePassword = db.Query(OneTimePassword).filter('keyValue =', optId).get()
+
+ if oneTimePassword.parent().username != user.username:
+ oneTimePassword.reset('DISABLED').put()
+ raise Exception, "User missmatch between the current session and 'One Time Password' user"
+ elif oneTimePassword.status != 'REQUESTED':
+ oneTimePassword.reset('DISABLED').put()
+ raise Exception, "Tring to use an 'One Time Password' in the wrong state"
+
+ oneTimePassword.reset("USED").put()
+
+ result['oneTimePassword'] = oneTimePassword.reference
+
+ except Exception, detail:
+ logging.error("connect.optId: " + str(detail))
+
+ session.s = user.srp_s
+ session.v = user.srp_v
+ else:
+ session.s = "112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00"
+ session.v = "112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00"
+
+ session.b = randomSeed()
+ session.B = hex(long("0x%s" % session.v, 16) + pow(srp_g, long("0x%s" %session.b, 16), srp_n))[2:-1]
+
+ result['s'] = session.s
+ result['B'] = session.B
+
+ #------------------------------------------------------------------
+
+ elif message == 'credentialCheck':
+ B = long("0x%s" % session.B, 16)
+ b = long("0x%s" % session.b, 16)
+ A = long("0x%s" % session.A, 16)
+ v = long("0x%s" % session.v, 16)
+ u = long("0x%s" % clipperzHash(str(B)), 16)
+ n = srp_n
+
+ S = pow((A * pow(v, u, n)), b, n)
+ K = clipperzHash(str(S))
+ M1 = clipperzHash(str(A) + str(B) + K)
+
+ if M1 == parameters['parameters']['M1']:
+ session.K = K
+ M2 = clipperzHash(str(A) + M1 + K)
+
+ result['M2'] = M2
+ result["connectionId"] = ""
+ result["loginInfo"] = {}
+ result["loginInfo"]["latest"] = {}
+ result["loginInfo"]["current"] = {}
+ result["offlineCopyNeeded"] = "false";
+ result["lock"] = "----";
+ else:
+ result['error'] = "?"
+
+ #------------------------------------------------------------------
+
+ elif message == 'oneTimePassword':
+ oneTimePassword = db.Query(OneTimePassword).filter("keyValue =", parameters["parameters"]["oneTimePasswordKey"]).get()
+
+ if oneTimePassword != None:
+ if oneTimePassword.status == 'ACTIVE':
+ if oneTimePassword.keyChecksum == parameters['parameters']['oneTimePasswordKeyChecksum']:
+ #session.userId = str(oneTimePassword.parent().username)
+ session.otpId = str(oneTimePassword.keyValue)
+
+ result['data'] = oneTimePassword.data
+ result['version'] = oneTimePassword.version
+
+ oneTimePassword.reset('REQUESTED').put()
+
+ else:
+ oneTimePassword.reset('DISABLED').put()
+ raise Exception, "The requested One Time Password has been disabled, due to a wrong keyChecksum"
+ else:
+ raise Exception, "The requested One Time Password was not active"
+ else:
+ raise Exception, "The requested One Time Password has not been found"
+
+ #----------------------------------------------------------------------
+
+ elif method == 'message':
+ if parameters['srpSharedSecret'] == session.K:
+ message = parameters['message']
+
+ if message == 'getUserDetails':
+ # {"message":"getUserDetails", "srpSharedSecret":"f18e5cf7c3a83b67d4db9444af813ee48c13daf4f8f6635397d593e52ba89a08", "parameters":{}}
+ user = db.Query(User).filter('username =', session.C).get()
+
+ result['header'] = user.header;
+ result['statistics'] = user.statistics;
+ result['version'] = user.version;
+
+ elif message == "addNewRecords":
+ user = db.Query(User).filter('username =', session.C).get()
+ result = db.run_in_transaction(self.addNewRecords, session, user, parameters)
+
+ """
+ user = db.Query(User).filter('username =', session.C).get()
+ user.update(parameters['parameters']['user'])
+
+ for recordParameter in parameters['parameters']['records']:
+ record = Record(parent=user)
+ record.put()
+ recordVersion = RecordVersion(parent=record)
+ recordVersion.put()
+
+ recordVersion.update(recordParameter)
+
+ record.put()
+ recordVersion.put()
+
+ user.put();
+
+ result['lock'] = user.lock
+ result['result'] = 'done'
+ """
+
+ elif message == 'getRecordDetail':
+ record = db.Query(Record).ancestor(db.Query(User).filter('username =', session.C).get()).filter('reference =', parameters["parameters"]["reference"]).get()
+ recordVersion = db.Query(RecordVersion).ancestor(record).get()
+
+ result['currentVersion'] = {}
+ result['currentVersion']['reference'] = recordVersion.reference
+ result['currentVersion']['data'] = recordVersion.data
+ result['currentVersion']['header'] = recordVersion.header
+ result['currentVersion']['version'] = recordVersion.version
+ result['currentVersion']['creationDate'] = str(recordVersion.creation_date)
+ result['currentVersion']['updateDate'] = str(recordVersion.update_date)
+ result['currentVersion']['accessDate'] = str(recordVersion.access_date)
+
+ result['reference'] = record.reference
+ result['data'] = record.data
+ result['version'] = record.version
+ result['creationDate'] = str(record.creation_date)
+ result['updateDate'] = str(record.update_date)
+ result['accessDate'] = str(record.access_date)
+ result['oldestUsedEncryptedVersion'] = "---"
+
+ elif message == 'updateData':
+ user = db.Query(User).filter('username =', session.C).get()
+ user.update(parameters['parameters']['user'])
+
+ for recordParameter in parameters['parameters']['records']:
+ logging.info('reference =' + recordParameter['record']['reference'])
+ record = db.Query(Record).ancestor(user).filter('reference =', recordParameter['record']['reference']).get()
+ recordVersion = db.Query(RecordVersion).ancestor(record).get()
+
+ recordVersion.update(recordParameter)
+
+ recordVersion.put()
+ recordVersion.parent().put()
+
+ user.put();
+
+ result['lock'] = user.lock
+ result['result'] = 'done'
+
+ elif message == 'deleteRecords':
+ user = db.Query(User).filter('username =', session.C).get()
+ user.update(parameters['parameters']['user'])
+
+ for recordReference in parameters['parameters']['recordReferences']:
+ record = db.Query(Record).ancestor(user).filter('reference =', recordReference).get()
+ #recordVersion = db.Query(RecordVersion).ancestor(record).get()
+
+ db.delete(db.Query(RecordVersion).ancestor(record))
+ record.delete()
+
+ user.put()
+
+ result['lock'] = user.lock
+ result['result'] = 'done'
+
+ elif message == 'deleteUser':
+ user = db.Query(User).filter('username =', session.C).get()
+ db.delete(db.Query(RecordVersion).ancestor(user))
+ db.delete(db.Query(Record).ancestor(user))
+ user.delete()
+
+ elif message == 'addNewOneTimePassword':
+ user = db.Query(User).filter('username =', session.C).get()
+ user.update(parameters['parameters']['user'])
+
+ oneTimePassword = OneTimePassword(parent=user)
+ oneTimePassword.update(parameters['parameters']['oneTimePassword'], "ACTIVE")
+ oneTimePassword.put()
+
+ user.put()
+
+ result['lock'] = user.lock
+ result['result'] = 'done'
+
+ elif message == 'updateOneTimePasswords':
+ user = db.Query(User).filter('username =', session.C).get()
+ user.update(parameters['parameters']['user'])
+
+ validOtpReferences = parameters['parameters']['oneTimePasswords']
+ for currentOtp in db.Query(OneTimePassword).ancestor(user):
+ if currentOtp.reference in validOtpReferences:
+ pass
+ else:
+ currentOtp.delete()
+
+ user.put()
+
+ result['result'] = user.lock
+
+ elif message == 'getOneTimePasswordsDetails':
+ pass
+
+ elif message == 'getLoginHistory':
+ result["result"] = []
+
+ elif message == 'upgradeUserCredentials':
+ user = db.Query(User).filter('username =', session.C).get()
+
+ user.updateCredentials(parameters['parameters']['credentials'])
+ user.update(parameters['parameters']['user'])
+
+ for oneTimePasswordReference in parameters['parameters']['oneTimePasswords']:
+ oneTimePassword = db.Query(OneTimePassword).ancestor(user).filter("reference =", oneTimePasswordReference).get()
+
+ if oneTimePassword != None:
+ oneTimePassword.data = parameters['parameters']['oneTimePasswords'][oneTimePasswordReference]
+ oneTimePassword.put()
+
+ user.put()
+
+ result['lock'] = user.lock
+ result['result'] = 'done'
+
+ """
+ $user = new user();
+ $user->Get($_SESSION["userId"]);
+
+ $otp = new onetimepassword();
+
+ updateUserCredentials($parameters["parameters"]["credentials"], $user);
+ updateUserData($parameters["parameters"]["user"], $user);
+
+ $otpList = $parameters["parameters"]["oneTimePasswords"];
+ foreach($otpList as $otpReference=>$otpData) {
+ $otpList = $otp->GetList(array(array("reference", "=", $otpReference)));
+ $currentOtp = $otpList[0];
+ $currentOtp->data = $otpData;
+ $currentOtp->Save();
+ }
+
+ $user->Save();
+
+ $result["lock"] = $user->lock;
+ $result["result"] = "done";
+ """
+
+ #=============================================================
+
+ """
+ java.util.Map result;
+
+ try {
+ java.util.Map credentials;
+
+ if (someParameters.get("credentials") != null) {
+ credentials = (java.util.Map)someParameters.get("credentials");
+ } else {
+ credentials = someParameters;
+ }
+
+ aUser.setUsername((java.lang.String)credentials.get("C"));
+ aUser.setSrpS((java.lang.String)credentials.get("s"));
+ aUser.setSrpV((java.lang.String)credentials.get("v"));
+ aUser.setVersion((java.lang.String)credentials.get("version"));
+
+ if (someParameters.get("user") != null) {
+ com.clipperz.dataModel.EncoderHelper.updateWithMap(aUser, (java.util.Map)someParameters.get("user"));
+ }
+
+ if (someParameters.get("oneTimePasswords") != null) {
+ java.util.Map updatedOneTimePasswords;
+ java.util.List usersOneTimePasswords;
+ int i,c;
+
+ updatedOneTimePasswords = (java.util.Map)someParameters.get("oneTimePasswords");
+ usersOneTimePasswords = com.clipperz.dataModel.OneTimePassword.oneTimePasswordsForUser(this.user());
+ c = usersOneTimePasswords.size();
+ for (i=0; i<c; i++) {
+ com.clipperz.dataModel.OneTimePassword currentOneTimePassword;
+
+ currentOneTimePassword = (com.clipperz.dataModel.OneTimePassword)usersOneTimePasswords.get(i);
+
+ if (updatedOneTimePasswords.get(currentOneTimePassword.getReference()) != null) {
+ currentOneTimePassword.setData((java.lang.String)updatedOneTimePasswords.get(currentOneTimePassword.getReference()));
+ }
+ }
+ }
+
+ result = new java.util.Hashtable();
+ this.dataContext().commitChanges();
+ result.put("lock", this.user().getNewLock());
+ result.put("result", "done");
+ } catch(java.lang.Exception exception) {
+ this.dataContext().rollbackChanges();
+ logger.error(exception);
+ throw exception;
+ }
+
+ return result;
+ """
+
+ elif message == 'echo':
+ result['result'] = parameters;
+
+ else:
+ result['error'] = "Wrong shared secret!"
+
+ #----------------------------------------------------------------------
+
+ elif method == 'logout':
+ result['method'] = 'logout'
+
+ #----------------------------------------------------------------------
+
+ else:
+ result['method'] = 'PRRRRRR'
+
+ #----------------------------------------------------------------------
+
+ self.saveSession(session)
+ self.response.out.write(simplejson.dumps(result))
+
+ #==========================================================================
+
+ def addNewRecords (self, aSession, aUser, someParameters):
+ result = {}
+
+ #user = db.Query(User).filter('username =', aSession.C).get()
+ aUser.update(someParameters['parameters']['user'])
+
+ for recordParameter in someParameters['parameters']['records']:
+ record = Record(parent=aUser)
+ record.put()
+ recordVersion = RecordVersion(parent=record)
+ recordVersion.put()
+
+ recordVersion.update(recordParameter)
+
+ record.put()
+ recordVersion.put()
+
+ aUser.put();
+
+ result['lock'] = aUser.lock
+ result['result'] = 'done'
+
+ return result
+
+ #==========================================================================
+
+ def getSession(self):
+ #logging.info(">>> getSession (%d) => %s" % (db.Query(Session).count(), str(map(lambda v: v.sessionId, db.Query(Session).fetch(100)))) )
+ result = None
+ try:
+ sessionId = self.request.cookies['sessionId']
+ except:
+ sessionId = None
+
+ #logging.info("wannabe sessionId: " + str(sessionId))
+
+ if sessionId != None:
+ #query = db.Query(Session)
+ #query.filter('sessionId =', sessionId)
+
+ #result = query.get()
+
+ #result = db.Query(Session).filter('sessionId =', str(sessionId)).filter('access_date >', (datetime.datetime.utcnow() - sessionTimeout)).get()
+ result = db.Query(Session).filter('sessionId =', str(sessionId)).get()
+ #logging.info("searching session on datastore. Found: " + str(result))
+
+ if result == None:
+ sessionId = str(uuid.uuid4())
+ #logging.info("creating a new session with sessionId=" + str(sessionId))
+ result = Session(sessionId=sessionId)
+
+ result.access_date = datetime.datetime.utcnow()
+ result.put()
+
+ #logging.info("<<< getSession (%d)" % db.Query(Session).count())
+
+ return result
+
+ #==========================================================================
+
+ def saveSession(self, aSession):
+ #logging.info(">>> saveSession (%d)" % db.Query(Session).count())
+ #self.response.set_cookie('sessionId', aSession.sessionId, max_age=360, path='/', domain='example.org', secure=True)
+ aSession.put()
+ self.response.headers.add_header('Set-Cookie', 'sessionId=' + str(aSession.sessionId), path='/')
+ self.cleanOldSessions()
+ #logging.info("<<< saveSession (%d)" % db.Query(Session).count())
+
+ #==========================================================================
+
+ def cleanOldSessions(self):
+ query = db.Query(Session).filter('accessDate <', (datetime.datetime.utcnow() - sessionTimeout))
+
+ expiredSessions = query.count();
+ if expiredSessions != 0:
+ #logging.info("deleting %d sessions" % expiredSessions)
+ pass
+
+ """
+ try:
+ db.delete(query)
+ except Exception, exception:
+ logging.error("some issues raised while deleting the expired sessions")
+ logging.error("exception type: " + str(type(exception)))
+ logging.error("exception: " + str(exception))
+ """
+ pass
+
+#==============================================================================
+
+def main():
+ application = webapp.WSGIApplication([('/xhr', XHR), ('/dump', XHR), ('/.*', MainPage)], debug=True)
+ wsgiref.handlers.CGIHandler().run(application)
+
+if __name__ == "__main__":
+ main()
+