summaryrefslogtreecommitdiffstats
path: root/examples/app/class
diff options
context:
space:
mode:
Diffstat (limited to 'examples/app/class')
-rw-r--r--examples/app/class/controller.class.php66
-rw-r--r--examples/app/class/database.iface.php27
-rw-r--r--examples/app/class/externuser.class.php40
-rw-r--r--examples/app/class/form.class.php243
-rw-r--r--examples/app/class/framework.class.php144
-rw-r--r--examples/app/class/group.class.php49
-rw-r--r--examples/app/class/issue.class.php44
-rw-r--r--examples/app/class/message.class.php40
-rw-r--r--examples/app/class/model.class.php91
-rw-r--r--examples/app/class/mysql.class.php77
-rw-r--r--examples/app/class/object.class.php640
-rw-r--r--examples/app/class/pad.class.php40
-rw-r--r--examples/app/class/setting.class.php90
-rw-r--r--examples/app/class/stage.class.php39
-rw-r--r--examples/app/class/user.class.php241
15 files changed, 1871 insertions, 0 deletions
diff --git a/examples/app/class/controller.class.php b/examples/app/class/controller.class.php
new file mode 100644
index 0000000..0ab1a69
--- /dev/null
+++ b/examples/app/class/controller.class.php
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+require_once "class/framework.class.php";
+
+/*
+ * Abstract controller -- Contains app security constraints and provides access to
+ * framework internals from concrete controllers
+ */
+abstract class Controller extends Framework
+{
+ /*
+ * Abstract function for concrete controller to handle the page request
+ */
+ abstract function handle($argv);
+
+ /*
+ * Security check
+ * Assert that the current connection to this server is secure. Redirects if not.
+ */
+ function sec_require_https()
+ {
+ if (!isset($_SERVER['HTTPS']))
+ $this->redirectTo("https://" . $_SERVER['SERVER_NAME'] . $this->ap());
+ }
+
+ /*
+ * Security check
+ * Assert that the current connection to this server is NOT secure. Redirects if not.
+ */
+ function sec_forbid_https()
+ {
+ if (isset($_SERVER['HTTPS']))
+ $this->redirectTo("http://" . $_SERVER['SERVER_NAME'] . $this->ap());
+ }
+
+ /*
+ * Security check
+ * Assert that the client's IP address does not change during its session. If a change is detected, logout.
+ */
+ function sec_verify_ip()
+ {
+ $addr = $_SERVER['REMOTE_ADDR'];
+
+ if ($this->getCurrentUser() && $addr != $this->getOriginIP())
+ {
+ $this->setCurrentUser();
+ $this->redirectTo($this->ar() . "/");
+ }
+ }
+}
+
+?>
diff --git a/examples/app/class/database.iface.php b/examples/app/class/database.iface.php
new file mode 100644
index 0000000..b1427a4
--- /dev/null
+++ b/examples/app/class/database.iface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+/*
+ * Generic interface for the various database drivers Scrott may implement support for
+ */
+interface Database
+{
+ function close();
+ function query($query);
+ function esc($string);
+}
+
+?>
diff --git a/examples/app/class/externuser.class.php b/examples/app/class/externuser.class.php
new file mode 100644
index 0000000..73c41bd
--- /dev/null
+++ b/examples/app/class/externuser.class.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+require_once "class/object.class.php";
+
+/*
+ * Non-application users
+ */
+class ExternUser extends Object
+{
+ /*
+ * Constructor
+ */
+ function __construct($guid = null)
+ {
+ $cols = array(
+ "guid",
+ "email",
+ "emailConfKey"
+ );
+
+ parent::__construct("extern-user", $cols);
+ $this->loadObj($guid);
+ }
+}
+
+?>
diff --git a/examples/app/class/form.class.php b/examples/app/class/form.class.php
new file mode 100644
index 0000000..8bb6506
--- /dev/null
+++ b/examples/app/class/form.class.php
@@ -0,0 +1,243 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+/*
+ * Model web-forms and simplify the process of accepting, validating, and sanitizing input
+ */
+class Form
+{
+ /*
+ * Constructor
+ */
+ function __construct()
+ {
+ $this->textFields = array();
+ $this->numbFields = array();
+ $this->enumFields = array();
+
+ $this->errorlist = array();
+ }
+
+ /*
+ * Log an error
+ */
+ function logError($str)
+ {
+ $this->errorlist[] = $str;
+ }
+
+ /*
+ * Add new text field to the form
+ */
+ function field_text($name, $deflt = null, $req = true)
+ {
+ if ($req !== true)
+ $req = false;
+
+ $this->textFields[] = array(
+ 'name' => $name,
+ 'deflt' => $deflt,
+ 'req' => $req
+ );
+ }
+
+ /*
+ * Add new numeric field to the form
+ */
+ function field_numeric($name, $min = null, $max = null, $deflt = null, $integer = true, $req = true)
+ {
+ if ($req !== true)
+ $req = false;
+
+ if ($integer !== true)
+ $integer = false;
+
+ $this->numbFields[] = array(
+ 'name' => $name,
+ 'min' => $min,
+ 'max' => $max,
+ 'deflt' => $deflt,
+ 'int' => $integer,
+ 'req' => $req
+ );
+ }
+
+ /*
+ * Add new enumeration field to the form
+ */
+ function field_enum($name, $values, $deflt = null, $req = true)
+ {
+ if ($req !== true)
+ $req = false;
+
+ $this->enumFields[] = array(
+ 'name' => $name,
+ 'vals' => $values,
+ 'deflt' => $deflt,
+ 'req' => $req
+ );
+ }
+
+ /*
+ * Add new boolean field to the form
+ */
+ function field_bool($name)
+ {
+ $this->field_enum($name, array("1", "0"), "0");
+ }
+
+ /*
+ * Populate the form with input data from web page
+ */
+ function populate($input)
+ {
+ /* detect duplicate names */
+ $names = array();
+ foreach ($this->textFields as $fld)
+ $names[] = $fld['name'];
+ foreach ($this->numbFields as $fld)
+ $names[] = $fld['name'];
+ foreach ($this->enumFields as $fld)
+ $names[] = $fld['name'];
+
+ if (count(array_unique($names)) != count($names))
+ {
+ $this->logError("Internal error: Duplicate field names defined in form");
+ return false;
+ }
+
+ /* init text fields */
+ foreach ($this->textFields as $fld)
+ {
+ if (isset($input[$fld['name']]) && $input[$fld['name']] != "")
+ $this->{$fld['name']} = htmlEntities($input[$fld['name']], ENT_QUOTES);
+
+ else if (!is_null($fld['deflt']))
+ $this->{$fld['name']} = $fld['deflt'];
+
+ else if ($fld['req'])
+ $this->logError($fld['name'] . " is required");
+ }
+
+ /* init numeric fields */
+ foreach ($this->numbFields as $fld)
+ {
+ if (isset($input[$fld['name']]) && $input[$fld['name']] != "")
+ {
+ if (!is_numeric($input[$fld['name']]))
+ {
+ $this->logError($fld['name'] . " must be numeric");
+ continue;
+ }
+
+ if ($fld['int'] && (floor($input[$fld['name']]) != $input[$fld['name']]))
+ {
+ $this->logError($fld['name'] . " must be an integer");
+ continue;
+ }
+
+ if (!is_null($fld['min']) && ($input[$fld['name']] < $fld['min']))
+ {
+ $this->logError($fld['name'] . " must be no less than " . $fld['min']);
+ continue;
+ }
+
+ if (!is_null($fld['max']) && ($input[$fld['name']] > $fld['max']))
+ {
+ $this->logError($fld['name'] . " must be no more than " . $fld['max']);
+ continue;
+ }
+
+ $this->{$fld['name']} = $input[$fld['name']];
+ }
+
+ else if (!is_null($fld['deflt']))
+ $this->{$fld['name']} = $fld['deflt'];
+
+ else if ($fld['req'])
+ $this->logError($fld['name'] . " is required");
+ }
+
+ /* init enum fields */
+ foreach ($this->enumFields as $fld)
+ {
+ if (isset($input[$fld['name']]) && $input[$fld['name']] != "")
+ {
+ if (array_search($input[$fld['name']], $fld['vals']) === false)
+ {
+ $this->logError($fld['name'] . " is not an appropriate value");
+ continue;
+ }
+
+ $this->{$fld['name']} = $input[$fld['name']];
+ }
+
+ else if (!is_null($fld['deflt']))
+ $this->{$fld['name']} = $fld['deflt'];
+
+ else if ($fld['req'])
+ $this->logError($fld['name'] . " is required");
+ }
+
+ /* return */
+ return count($this->errorlist) == 0;
+ }
+
+ /*
+ * Handle an uploaded file
+ */
+ function saveFile($file, $maxsize, $allowed_mime, $path, $req = false)
+ {
+ if (isset($file) && !is_null($file))
+ {
+ if ($file['error'] > 0)
+ {
+ if ($file['error'] != UPLOAD_ERR_NO_FILE)
+ $this->logError("An unknown error occurred");
+
+ return false;
+ }
+
+ if ($file['size'] > $maxsize)
+ {
+ $this->logError("File must be no larger than " . $maxsize . " bytes");
+ return false;
+ }
+
+ if (is_array($allowed_mime) && array_search($file['type'], $allowed_mime) === false)
+ {
+ $this->logError("File type is not supported");
+ return false;
+ }
+
+ if (!move_uploaded_file($file['tmp_name'], $path))
+ {
+ $this->logError("Error saving uploaded file");
+ return false;
+ }
+ }
+
+ else if ($req)
+ {
+ $this->logError("File upload is required");
+ return false;
+ }
+
+ return true;
+ }
+}
+
+?>
diff --git a/examples/app/class/framework.class.php b/examples/app/class/framework.class.php
new file mode 100644
index 0000000..a3c36cb
--- /dev/null
+++ b/examples/app/class/framework.class.php
@@ -0,0 +1,144 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+/* Define Scrott version number */
+define("__VERSION__", "v0.0");
+
+/* Include the Scrott system-level configuration file if it exists */
+is_file("scrott.conf.php") &&
+ require_once "scrott.conf.php";
+
+/* Init PHP session */
+session_start();
+
+require_once "class/mysql.class.php";
+require_once "class/user.class.php";
+
+/*
+ * Global functions / operations and access to contextual or session-based information
+ */
+abstract class Framework
+{
+ static $dbobj = null;
+
+ /*
+ * Check for the existence of Scrott's system-level config
+ */
+ function scrottConfExists()
+ {
+ global $_SCROTT;
+ return isset($_SCROTT['conf']);
+ }
+
+ /*
+ * Get the absolute path on this server for the root of this app
+ */
+ function ar()
+ {
+ return substr($_SERVER['PHP_SELF'], 0, -10); // 10 = length of "/index.php"
+ }
+
+ /*
+ * Get the absolute path to the current page
+ */
+ function ap()
+ {
+ return $this->ar() . $_REQUEST['path'];
+ }
+
+ /*
+ * Redirect to the given URL and die
+ */
+ function redirectTo($url)
+ {
+ header("Location: " . $url);
+ exit;
+ }
+
+ /*
+ * Get a user object for the currently logged in user. Returns false if session is logged out.
+ */
+ function getCurrentUser()
+ {
+ if (isset($_SESSION['userguid']))
+ {
+ $user = new User($_SESSION['userguid']);
+
+ if ($user->type == "user")
+ return $user;
+
+ $this->setCurrentUser();
+ }
+
+ return false;
+ }
+
+ /*
+ * Get the IP address the client held when the current session began
+ */
+ function getOriginIP()
+ {
+ return $_SESSION['userip'];
+ }
+
+ /*
+ * Set the current logged in user
+ */
+ function setCurrentUser($user = null)
+ {
+ if ($user != null && isset($user->guid))
+ {
+ $_SESSION['userguid'] = $user->guid;
+ $_SESSION['userip'] = $_SERVER['REMOTE_ADDR'];
+ }
+
+ else
+ {
+ unset($_SESSION['userguid']);
+ unset($_SESSION['userip']);
+ }
+ }
+
+ /*
+ * Get or create the app's database connection object (this is a singleton object and dependent on system-level config)
+ */
+ static function getDbConnection()
+ {
+ global $_SCROTT;
+
+ if (self::$dbobj != null)
+ return self::$dbobj;
+
+ switch ($_SCROTT['dbEngine'])
+ {
+ case "mysql":
+ $host = $_SCROTT['dbAddress'];
+ $username = $_SCROTT['dbUser'];
+ $password = $_SCROTT['dbPass'];
+ $dbName = $_SCROTT['dbName'];
+ self::$dbobj = new Mysql($host, $username, $password, $dbName);
+ break;
+
+ default:
+ throw new Exception("Problem with Scrott Configuration. Invalid database engine specified.");
+ break;
+ }
+
+ return self::$dbobj;
+ }
+}
+
+?>
diff --git a/examples/app/class/group.class.php b/examples/app/class/group.class.php
new file mode 100644
index 0000000..246276a
--- /dev/null
+++ b/examples/app/class/group.class.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+require_once "class/object.class.php";
+
+/*
+ * User groups
+ */
+class Group extends Object
+{
+ /*
+ * Constructor
+ */
+ function __construct($guid = null)
+ {
+ parent::__construct();
+ $this->loadObj($guid);
+ }
+
+ /*
+ * Create a new user group object.
+ * On success, this object should be initialized as the new group (use only on new
+ * Group() objects)
+ */
+ function createNewGroup($name, $owner)
+ {
+ $this->perms = $this->DEFAULT_OBJECT_PERMISSIONS;
+ $this->owner = $owner->guid;
+ $this->name = $name;
+ $this->type = "group";
+
+ $this->saveObj();
+ }
+}
+
+?>
diff --git a/examples/app/class/issue.class.php b/examples/app/class/issue.class.php
new file mode 100644
index 0000000..10b1661
--- /dev/null
+++ b/examples/app/class/issue.class.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+require_once "class/object.class.php";
+
+/*
+ * Pad issues
+ */
+class Issue extends Object
+{
+ /*
+ * Constructor
+ */
+ function __construct($guid = null)
+ {
+ $cols = array(
+ "guid",
+ "number",
+ "assignee",
+ "unread",
+ "desc",
+ "due",
+ "tags"
+ );
+
+ parent::__construct("issue", $cols);
+ $this->loadObj($guid);
+ }
+}
+
+?>
diff --git a/examples/app/class/message.class.php b/examples/app/class/message.class.php
new file mode 100644
index 0000000..ac8444c
--- /dev/null
+++ b/examples/app/class/message.class.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+require_once "class/object.class.php";
+
+/*
+ * User messages and log messages
+ */
+class Message extends Object
+{
+ /*
+ * Constructor
+ */
+ function __construct($guid = null)
+ {
+ $cols = array(
+ "guid",
+ "author",
+ "message"
+ );
+
+ parent::__construct("message", $cols);
+ $this->loadObj($guid);
+ }
+}
+
+?>
diff --git a/examples/app/class/model.class.php b/examples/app/class/model.class.php
new file mode 100644
index 0000000..7d74b36
--- /dev/null
+++ b/examples/app/class/model.class.php
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+require_once "class/framework.class.php";
+
+/*
+ * Abstract model class - defines logic common to all app MVC models
+ */
+abstract class Model extends Framework
+{
+ /*
+ * Constructor
+ */
+ function __construct()
+ {
+ $this->errorlist = array();
+ $this->warninglist = array();
+ $this->noticelist = array();
+ }
+
+ /*
+ * Check for error
+ */
+ function isError()
+ {
+ return count($this->errorlist) > 0;
+ }
+
+ /*
+ * Check for warning
+ */
+ function isWarning()
+ {
+ return count($this->warninglist) > 0;
+ }
+
+ /*
+ * Check for notice
+ */
+ function isNotice()
+ {
+ return count($this->noticelist) > 0;
+ }
+
+ /*
+ * Log an error
+ */
+ function logError($str)
+ {
+ $this->errorlist[] = $str;
+ }
+
+ /*
+ * Log a warning
+ */
+ function logWarning($str)
+ {
+ $this->warninglist[] = $str;
+ }
+
+ /*
+ * Log a notice
+ */
+ function logNotice($str)
+ {
+ $this->noticelist[] = $str;
+ }
+
+ /*
+ * Log errors from a Form
+ */
+ function logFormErrors($obj)
+ {
+ $this->errorlist = array_merge($this->errorlist, $obj->errorlist);
+ }
+}
+
+?>
diff --git a/examples/app/class/mysql.class.php b/examples/app/class/mysql.class.php
new file mode 100644
index 0000000..f8f456a
--- /dev/null
+++ b/examples/app/class/mysql.class.php
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+require_once "class/database.iface.php";
+
+/*
+ * MySQL support for Scrott
+ */
+class Mysql implements Database
+{
+ /*
+ * Constructor
+ */
+ function __construct($host, $username, $password, $dbName)
+ {
+ $this->db = new mysqli($host, $username, $password, $dbName);
+
+ if ($this->db->connect_error)
+ throw new Exception("Can not connect to Mysql database. Please check your Scrott configuration.");
+ }
+
+ /*
+ * Destructor
+ */
+ function __destruct()
+ {
+ $this->close();
+ }
+
+ /*
+ * Close connection to DB
+ */
+ function close()
+ {
+ $this->db->close();
+ }
+
+ /*
+ * Make a query of the database. Return data as an array of arrays
+ */
+ function query($query)
+ {
+ $arr = array();
+ $res = $this->db->query($query);
+
+ if ($res === true || $res === false)
+ return $arr;
+
+ while ($r = $res->fetch_assoc())
+ $arr[] = $r;
+
+ return $arr;
+ }
+
+ /*
+ * Escape a string for use in a query
+ */
+ function esc($string)
+ {
+ return $this->db->real_escape_string($string);
+ }
+}
+
+?>
diff --git a/examples/app/class/object.class.php b/examples/app/class/object.class.php
new file mode 100644
index 0000000..7c0b7bb
--- /dev/null
+++ b/examples/app/class/object.class.php
@@ -0,0 +1,640 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+require_once "class/framework.class.php";
+require_once "class/user.class.php";
+
+/*
+ * Base class for Scrott database objects
+ */
+abstract class Object extends Framework
+{
+ var $DEFAULT_OBJECT_PERMISSIONS = 120;
+
+ /*
+ * Constructor
+ */
+ function __construct($childTable = "object", $childCols = null)
+ {
+ $this->db = $this->getDbConnection();
+
+ $this->table = "object";
+ $this->cols = array(
+ "guid",
+ "perms",
+ "owner",
+ "parent",
+ "name",
+ "timeCreated",
+ "timeUpdated",
+ "type"
+ );
+
+ $this->childTable = $this->db->esc($childTable);
+ $this->childCols = array();
+
+ if (is_array($childCols))
+ {
+ foreach ($childCols as $col)
+ $this->childCols[] = $this->db->esc($col);
+ }
+ }
+
+ /*
+ * Populate this object with data from the DB with a given GUID
+ */
+ function loadObj($guid = null)
+ {
+ if (is_null($guid))
+ return;
+
+ if (!$this->isGUID($guid))
+ return;
+
+ $escdGuid = $this->db->esc($guid);
+
+ /* Base fields */
+ $query = "SELECT * FROM `" . $this->table . "` WHERE `guid` = '" . $escdGuid . "'";
+ $result = $this->db->query($query)[0];
+
+ foreach ($this->cols as $col)
+ {
+ if (isset($result[$col]))
+ $this->$col = $result[$col];
+ }
+
+ /* Child Table fields */
+ $query = "SELECT * FROM `" . $this->childTable . "` WHERE `guid` = '" . $escdGuid . "'";
+ $result = $this->db->query($query)[0];
+
+ foreach ($this->childCols as $col)
+ {
+ if (isset($result[$col]))
+ $this->$col = $result[$col];
+ }
+ }
+
+ /*
+ * Write this object to the database
+ */
+ function saveObj()
+ {
+ if (isset($this->guid))
+ {
+ $this->timeUpdated = $this->getCurrentTimestamp();
+
+ /* Update Base */
+ $updateStr = "";
+
+ foreach ($this->cols as $col)
+ {
+ if (!isset($this->$col))
+ continue;
+
+ $updateStr .= "`" . $col . "` = '" . $this->db->esc($this->$col) . "', ";
+ }
+
+ if (strlen($updateStr) > 0)
+ {
+ $updateStr = substr($updateStr, 0, -2); // remove ", " from the end
+ $query = "UPDATE `" . $this->table . "` SET " . $updateStr . " WHERE `guid` = '" . $this->db->esc($this->guid) . "'";
+ $this->db->query($query);
+ }
+
+ /* Update Child */
+ $updateStr = "";
+
+ foreach ($this->childCols as $col)
+ {
+ if (!isset($this->$col))
+ continue;
+
+ $updateStr .= "`" . $col . "` = '" . $this->db->esc($this->$col) . "', ";
+ }
+
+ if (strlen($updateStr) > 0)
+ {
+ $updateStr = substr($updateStr, 0, -2); // remove ", " from the end
+ $query = "UPDATE `" . $this->childTable . "` SET " . $updateStr . " WHERE `guid` = '" . $this->db->esc($this->guid) . "'";
+ $this->db->query($query);
+ }
+ }
+
+ else
+ {
+ $this->guid = $this->getNewGUID();
+ $this->timeCreated = $this->getCurrentTimestamp();
+ $this->timeUpdated = $this->timeCreated;
+
+ /* Insert Base */
+ $colsStr = "";
+ $valsStr = "";
+
+ foreach ($this->cols as $col)
+ {
+ if (!isset($this->$col))
+ continue;
+
+ $colsStr .= "`" . $col . "`, ";
+ $valsStr .= "'" . $this->db->esc($this->$col) . "', ";
+ }
+
+ if (strlen($colsStr) > 0)
+ {
+ $colsStr = substr($colsStr, 0, -2); // remove ", "
+ $valsStr = substr($valsStr, 0, -2);
+ $query = "INSERT INTO `" . $this->table . "` (" . $colsStr . ") VALUES (" . $valsStr . ")";
+ $this->db->query($query);
+ }
+
+ /* Insert Child */
+ $colsStr = "";
+ $valsStr = "";
+
+ foreach ($this->childCols as $col)
+ {
+ if (!isset($this->$col))
+ continue;
+
+ $colsStr .= "`" . $col . "`, ";
+ $valsStr .= "'" . $this->db->esc($this->$col) . "', ";
+ }
+
+ if (strlen($colsStr) > 0)
+ {
+ $colsStr = substr($colsStr, 0, -2); // remove ", "
+ $valsStr = substr($valsStr, 0, -2);
+ $query = "INSERT INTO `" . $this->childTable . "` (" . $colsStr . ") VALUES (" . $valsStr . ")";
+ $this->db->query($query);
+ }
+ }
+ }
+
+ /*
+ * Remove this object from the database
+ */
+ function delObj()
+ {
+ if (!isset($this->guid))
+ return;
+
+ /* Delete Base */
+ $query = "DELETE FROM `" . $this->table . "` WHERE `guid` = '" . $this->db->esc($this->guid) . "'";
+ $this->db->query($query);
+
+ /* Delete Child */
+ $query = "DELETE FROM `" . $this->childTable . "` WHERE `guid` = '" . $this->db->esc($this->guid) . "'";
+ $this->db->query($query);
+
+ /* obj_member garbage collection */
+ $query = "DELETE FROM `obj_member` WHERE `guid` = '" . $this->db->esc($this->guid) . "' OR `member` = '" . $this->db->esc($this->guid) . "'";
+ $this->db->query($query);
+
+ /* msg_read garbage collection */
+ $query = "DELETE FROM `msg_read` WHERE `guid` = '" . $this->db->esc($this->guid) . "' OR `user` = '" . $this->db->esc($this->guid) . "'";
+ $this->db->query($query);
+ }
+
+ /*
+ * Get current timestamp for object database purposes
+ */
+ function getCurrentTimestamp()
+ {
+ $query = "SELECT now() AS stamp";
+ $result = $this->db->query($query);
+ return $result[0]['stamp'];
+ }
+
+ /*
+ * Check whether given GUID exists
+ */
+ function isGUID($guid)
+ {
+ $query = "SELECT `guid` FROM `object` WHERE `guid` = '" . $this->db->esc($guid) . "'";
+ $result = $this->db->query($query);
+
+ if (count($result) > 0)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * Get a new, unique GUID for a new system object
+ */
+ function getNewGUID()
+ {
+ do
+ {
+ $guid = substr($this->getBlob(), 0, 8);
+ }
+ while ($this->isGUID($guid));
+
+ return $guid;
+ }
+
+ /*
+ * Get a random sha256 blob
+ */
+ function getBlob()
+ {
+ return hash("sha256", openssl_random_pseudo_bytes(64));
+ }
+
+ /*
+ * Get a user object for this object's owner
+ */
+ function getOwner()
+ {
+ if (isset($this->owner))
+ return new User($this->owner);
+
+ return null;
+ }
+
+ /*
+ * Get an array of all members of this object
+ */
+ function getMembers()
+ {
+ $query = "SELECT member FROM obj_member WHERE guid = '" . $this->db->esc($this->guid) . "'";
+ $result = $this->db->query($query);
+
+ $members = array();
+
+ foreach ($result as $m)
+ $members[] = new User($m['member']);
+
+ return $members;
+ }
+
+ /*
+ * Check if given user (or group) is the owner of this object
+ */
+ function isOwner($ug)
+ {
+ return $this->getOwner()->guid == $ug->guid;
+ }
+
+ /*
+ * Check if given user (or group) is a member of this object
+ */
+ function isMember($ug)
+ {
+ foreach ($this->getMembers() as $member)
+ {
+ if ($member->guid == $ug->guid)
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Check if given user has permissions for this object
+ */
+ function canAccess($user)
+ {
+ if ($user->admin)
+ return true;
+
+ if ($this->isOwner($user))
+ return true;
+
+ if ($this->isMember($user))
+ return true;
+
+ if ($this->perms & 0x004) // accessible by public
+ return true;
+
+ if ($this->parent != "")
+ {
+ $parent = new DBObject($this->parent);
+
+ if ($parent->canAccessSub($user))
+ return true;
+ }
+ else if ($this->owner != $this->guid)
+ {
+ $owner = new DBObject($this->owner);
+
+ if ($owner->canAccessSub($user))
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Check if given user has permissions for this object
+ */
+ function canModify($user)
+ {
+ if ($user->admin)
+ return true;
+
+ if ($this->isOwner($user))
+ return true;
+
+ if ($this->isMember($user) && $this->perms & 0x100)
+ return true;
+
+ if ($this->parent != "")
+ {
+ $parent = new DBObject($this->parent);
+
+ if ($parent->canModifySub($user))
+ return true;
+ }
+ else if ($this->owner != $this->guid)
+ {
+ $owner = new DBObject($this->owner);
+
+ if ($owner->canModifySub($user))
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Check if given user has permissions for this object
+ */
+ function canModifyMembers($user)
+ {
+ if ($user->admin)
+ return true;
+
+ if ($this->isOwner($user))
+ return true;
+
+ if ($this->isMember($user) && $this->perms & 0x080)
+ return true;
+
+ if ($this->parent != "")
+ {
+ $parent = new DBObject($this->parent);
+
+ if ($parent->canModifySubMembers($user))
+ return true;
+ }
+ else if ($this->owner != $this->guid)
+ {
+ $owner = new DBObject($this->owner);
+
+ if ($owner->canModifySubMembers($user))
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Check if given user has permissions for this object
+ */
+ function canModifyPermissions($user)
+ {
+ if ($user->admin)
+ return true;
+
+ if ($this->isOwner($user))
+ return true;
+
+ if ($this->parent != "")
+ {
+ $parent = new DBObject($this->parent);
+
+ if ($parent->canModifySubPermissions($user))
+ return true;
+ }
+ else if ($this->owner != $this->guid)
+ {
+ $owner = new DBObject($this->owner);
+
+ if ($owner->canModifySubPermissions($user))
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Check if given user has permissions for this object
+ */
+ function canAccessSub($user)
+ {
+ if ($user->admin)
+ return true;
+
+ if ($this->isOwner($user))
+ return true;
+
+ if ($this->isMember($user) && $this->perms & 0x040)
+ return true;
+
+ if ($this->perms & 0x002) // accessible by public
+ return true;
+
+ if ($this->parent != "")
+ {
+ $parent = new DBObject($this->parent);
+
+ if ($parent->canAccessSub($user))
+ return true;
+ }
+ else if ($this->owner != $this->guid)
+ {
+ $owner = new DBObject($this->owner);
+
+ if ($owner->canAccessSub($user))
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Check if given user has permissions for this object
+ */
+ function canCreateSub($user)
+ {
+ if ($user->admin)
+ return true;
+
+ if ($this->isOwner($user))
+ return true;
+
+ if ($this->isMember($user) && $this->perms & 0x020)
+ return true;
+
+ if ($this->perms & 0x001) // accessible by public
+ return true;
+
+ if ($this->parent != "")
+ {
+ $parent = new DBObject($this->parent);
+
+ if ($parent->canCreateSub($user))
+ return true;
+ }
+ else if ($this->owner != $this->guid)
+ {
+ $owner = new DBObject($this->owner);
+
+ if ($owner->canCreateSub($user))
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Check if given user has permissions for this object
+ */
+ function canModifySub($user)
+ {
+ if ($user->admin)
+ return true;
+
+ if ($this->isOwner($user))
+ return true;
+
+ if ($this->isMember($user) && $this->perms & 0x010)
+ return true;
+
+ if ($this->parent != "")
+ {
+ $parent = new DBObject($this->parent);
+
+ if ($parent->canModifySub($user))
+ return true;
+ }
+ else if ($this->owner != $this->guid)
+ {
+ $owner = new DBObject($this->owner);
+
+ if ($owner->canModifySub($user))
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Check if given user has permissions for this object
+ */
+ function canModifySubMembers($user)
+ {
+ if ($user->admin)
+ return true;
+
+ if ($this->isOwner($user))
+ return true;
+
+ if ($this->isMember($user) && $this->perms & 0x008)
+ return true;
+
+ if ($this->parent != "")
+ {
+ $parent = new DBObject($this->parent);
+
+ if ($parent->canModifySubMembers($user))
+ return true;
+ }
+ else if ($this->owner != $this->guid)
+ {
+ $owner = new DBObject($this->owner);
+
+ if ($owner->canModifySubMembers($user))
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Check if given user has permissions for this object
+ */
+ function canModifySubPermissions($user)
+ {
+ if ($user->admin)
+ return true;
+
+ if ($this->isOwner($user))
+ return true;
+
+ if ($this->parent != "")
+ {
+ $parent = new DBObject($this->parent);
+
+ if ($parent->canModifySubPermissions($user))
+ return true;
+ }
+ else if ($this->owner != $this->guid)
+ {
+ $owner = new DBObject($this->owner);
+
+ if ($owner->canModifySubPermissions($user))
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Get URL to this object
+ */
+ function getURL()
+ {
+ return $this->ar() . "/" . $this->guid;
+ }
+
+ /*
+ * Get object's head image
+ */
+ function getHeadImage()
+ {
+ return $this->ar() . "/file.php?d=img/heads&f=" . $this->guid;
+ }
+
+ /*
+ * Remove this object's head image
+ */
+ function rmHeadImage()
+ {
+ if (!is_file("assets/img/heads/" . $this->guid))
+ return true;
+
+ return unlink("assets/img/heads/" . $this->guid);
+ }
+}
+
+/*
+ * Concrete Database Object which can be used in a polymorphic way
+ */
+class DBObject extends Object
+{
+ /*
+ * Constructor
+ */
+ function __construct($guid = null)
+ {
+ parent::__construct();
+ $this->loadObj($guid);
+ }
+}
+
+?>
diff --git a/examples/app/class/pad.class.php b/examples/app/class/pad.class.php
new file mode 100644
index 0000000..32994e5
--- /dev/null
+++ b/examples/app/class/pad.class.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+require_once "class/object.class.php";
+
+/*
+ * Scrott pads
+ */
+class Pad extends Object
+{
+ /*
+ * Constructor
+ */
+ function __construct($guid = null)
+ {
+ $cols = array(
+ "guid",
+ "stage",
+ "nextIssueNumber"
+ );
+
+ parent::__construct("pad", $cols);
+ $this->loadObj($guid);
+ }
+}
+
+?>
diff --git a/examples/app/class/setting.class.php b/examples/app/class/setting.class.php
new file mode 100644
index 0000000..c0965a3
--- /dev/null
+++ b/examples/app/class/setting.class.php
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+require_once "class/framework.class.php";
+
+/*
+ * Scrott administrative settings
+ */
+class Setting extends Framework
+{
+ /*
+ * Helper function for getting setting values from the database
+ */
+ static function getValue($key)
+ {
+ $db = parent::getDbConnection();
+ $escdKey = $db->esc($key);
+
+ $query = "SELECT `value` FROM `setting` WHERE `key` = '" . $escdKey . "'";
+ $res = $db->query($query);
+
+ if (count($res) == 0)
+ return false;
+
+ return $res[0]['value'];
+ }
+
+ /*
+ * Helper function for setting setting values on the database
+ */
+ static function setValue($key, $value)
+ {
+ $db = parent::getDbConnection();
+ $escdKey = $db->esc($key);
+ $escdValue = $db->esc($value);
+
+ if (self::getValue($key) === false)
+ $query = "INSERT INTO setting (`key`, value) VALUES('" . $escdKey . "', '" . $escdValue . "')";
+ else
+ $query = "UPDATE setting SET value = '" . $escdValue . "' WHERE `key` = '" . $escdKey . "'";
+
+ $db->query($query);
+ }
+
+ /*
+ * Force or forbid SSL connections?
+ */
+ static function settSSL($value = null)
+ {
+ $opt = "settSSL";
+
+ if ($value != null)
+ self::setValue($opt, $value);
+
+ $value = self::getValue($opt);
+
+ if ($value === false)
+ return "neither";
+
+ return $value;
+ }
+
+ /*
+ * Should the app allow the public to signup their own accounts with Scrott?
+ */
+ static function allowPublicSignup($value = null)
+ {
+ $opt = "allowPublicSignup";
+
+ if ($value != null)
+ self::setValue($opt, $value);
+
+ return self::getValue($opt);
+ }
+}
+
+?>
diff --git a/examples/app/class/stage.class.php b/examples/app/class/stage.class.php
new file mode 100644
index 0000000..1a2aadb
--- /dev/null
+++ b/examples/app/class/stage.class.php
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+require_once "class/object.class.php";
+
+/*
+ * Pad stages
+ */
+class Stage extends Object
+{
+ /*
+ * Constructor
+ */
+ function __construct($guid = null)
+ {
+ $cols = array(
+ "guid",
+ "stage"
+ );
+
+ parent::__construct("stage", $cols);
+ $this->loadObj($guid);
+ }
+}
+
+?>
diff --git a/examples/app/class/user.class.php b/examples/app/class/user.class.php
new file mode 100644
index 0000000..b8143a9
--- /dev/null
+++ b/examples/app/class/user.class.php
@@ -0,0 +1,241 @@
+<?php
+
+/*
+ * SCROTT Copyright (C) 2016 Malf Furious
+ *
+ * Scrott is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Scrott is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ */
+
+require_once "class/object.class.php";
+require_once "class/group.class.php";
+
+/*
+ * Application users
+ */
+class User extends Object
+{
+ /*
+ * Constructor
+ */
+ function __construct($guid = null)
+ {
+ $cols = array(
+ "guid",
+ "key",
+ "salt",
+ "alias",
+ "admin",
+ "email",
+ "emailConf",
+ "emailConfKey"
+ );
+
+ parent::__construct("user", $cols);
+ $this->loadObj($guid);
+ }
+
+ /*
+ * Initialize object by username
+ */
+ function initByUsername($username)
+ {
+ $query = "SELECT guid FROM object WHERE type = 'user' AND name = '" . $this->db->esc($username) . "'";
+ $result = $this->db->query($query);
+
+ if (count($result) == 0)
+ return false;
+
+ $this->loadObj($result[0]['guid']);
+ return true;
+ }
+
+ /*
+ * Get all users -- ordered by name, ascending
+ */
+ function getAllUsers_orderByName()
+ {
+ $query = "SELECT guid FROM `object` WHERE `type` = 'user' ORDER BY name";
+ $result = $this->db->query($query);
+
+ $users = array();
+
+ foreach ($result as $u)
+ $users[] = new User($u['guid']);
+
+ return $users;
+ }
+
+ /*
+ * Get all users -- ordered by admin DESC (admins first), then by name
+ */
+ function getAllUsers_orderByAdminByName()
+ {
+ $query = "SELECT o.guid FROM object o JOIN user u ON o.guid = u.guid WHERE o.type = 'user' ORDER BY u.admin DESC, o.name";
+ $result = $this->db->query($query);
+
+ $users = array();
+
+ foreach ($result as $u)
+ $users[] = new User($u['guid']);
+
+ return $users;
+ }
+
+ /*
+ * Get the number of administrative accounts in the system
+ */
+ function getNumAdmins()
+ {
+ $query = "SELECT count(*) as cnt FROM user WHERE admin = 1";
+ $results = $this->db->query($query);
+ return $results[0]['cnt'];
+ }
+
+ /*
+ * Check whether a given username is currently in use
+ */
+ function usernameInUse($username)
+ {
+ $escd_username = $this->db->esc($username);
+
+ $query = "SELECT name FROM object WHERE type = 'user' AND name = '" . $escd_username . "'";
+ $results = $this->db->query($query);
+
+ if (count($results) > 0)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * Generate a key from a user's password and salt
+ */
+ function getKey($password, $salt)
+ {
+ return hash("sha256", $salt . $password);
+ }
+
+ /*
+ * Create a new User object with the given username and keyed with the given plain-text password
+ * This function returns false if $username is already being used
+ * On success, this object should be initialized as the new user (use only on new User() objects)
+ */
+ function createNewUser($username, $password)
+ {
+ if ($this->usernameInUse($username))
+ return false;
+
+ /* if there exist no users already, make this new one an admin */
+ if (count($this->getAllUsers_orderByName()) == 0)
+ $this->admin = 1;
+
+ $this->perms = 0;
+ $this->name = $username;
+ $this->type = "user";
+ $this->setPassword($password);
+ $this->setEmail("");
+
+ $this->saveObj();
+
+ $this->owner = $this->guid;
+ $this->saveObj();
+
+ return true;
+ }
+
+ /*
+ * Validate the password for this user. Returns true if correct, false otherwise
+ */
+ function validatePassword($password)
+ {
+ $key = $this->getKey($password, $this->salt);
+ return $key == $this->key;
+ }
+
+ /*
+ * Validate the email confirmation key for a user, returns true if correct, false otherwise. On success, $this->emailConf is also set to 1
+ */
+ function confirmEmailKey($key)
+ {
+ if ($key != $this->emailConfKey)
+ return false;
+
+ $this->emailConf = 1;
+ return true;
+ }
+
+ /*
+ * Overwrite the salt and key for this user, given a new plaintext password
+ */
+ function setPassword($password)
+ {
+ $this->salt = $this->getBlob();
+ $this->key = $this->getKey($password, $this->salt);
+ }
+
+ /*
+ * Overwrite the emailConfKey and flag, and change user's saved email address
+ */
+ function setEmail($email)
+ {
+ $this->email = $email;
+ $this->emailConf = 0;
+ $this->emailConfKey = $this->getBlob();
+ }
+
+ /*
+ * If a user has an alias set, display it instead of their username
+ */
+ function getDisplayName()
+ {
+ if ($this->alias != "")
+ return $this->alias;
+
+ return $this->name;
+ }
+
+ /*
+ * Get the glyphicon to use for this user
+ */
+ function getGlyphicon()
+ {
+ if ($this->admin)
+ return "glyphicon glyphicon-sunglasses";
+
+ return "glyphicon glyphicon-user";
+ }
+
+ /*
+ * Get all groups this user owns or is a member of
+ */
+ function getGroups()
+ {
+ /* owner */
+ $query = "SELECT guid FROM object WHERE type = 'group' AND owner = '" . $this->db->esc($this->guid) . "'";
+ $result = $this->db->query($query);
+
+ $groups = array();
+
+ foreach ($result as $g)
+ $groups[] = new Group($g['guid']);
+
+ /* member */
+ $query = "SELECT o.guid FROM object o JOIN obj_member om ON o.guid = om.guid WHERE o.type = 'group' AND member = '" . $this->db->esc($this->guid) . "'";
+ $result = $this->db->query($query);
+
+ foreach ($result as $g)
+ $groups[] = new Group($g['guid']);
+
+ return $groups;
+ }
+}
+
+?>