+ * // 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);
+ *
+ */
+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
--- /dev/null
+++ b/backend/php/src/objects/class.database.php
@@ -0,0 +1,79 @@
+Database Connection 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
--- /dev/null
+++ b/backend/php/src/objects/class.onetimepassword.php
@@ -0,0 +1,400 @@
+onetimepassword 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
--- /dev/null
+++ b/backend/php/src/objects/class.onetimepasswordstatus.php
@@ -0,0 +1,368 @@
+onetimepasswordstatus 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
--- /dev/null
+++ b/backend/php/src/objects/class.pog_base.php
@@ -0,0 +1,143 @@
+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
--- /dev/null
+++ b/backend/php/src/objects/class.record.php
@@ -0,0 +1,436 @@
+record 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
--- /dev/null
+++ b/backend/php/src/objects/class.recordversion.php
@@ -0,0 +1,381 @@
+recordversion 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
--- /dev/null
+++ b/backend/php/src/objects/class.user.php
@@ -0,0 +1,502 @@
+user 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/README b/backend/php/src/objects/ignore_objects.txt
similarity index 100%
rename from README
rename to 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
--- /dev/null
+++ b/backend/php/src/plugins/IPlugin.php
@@ -0,0 +1,48 @@
+
\ 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
--- /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
--- /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
--- /dev/null
+++ b/backend/php/src/plugins/plugin.base64.php
@@ -0,0 +1,128 @@
+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: