summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--app/class/form.class.php12
-rw-r--r--app/class/group.class.php15
-rw-r--r--app/class/object.class.php370
-rw-r--r--app/class/user.class.php30
-rw-r--r--app/controller/obj.control.php49
-rw-r--r--app/controller/root.control.php12
-rw-r--r--app/model/common.mod.php151
-rw-r--r--app/model/obj.mod.php30
-rw-r--r--app/view/common/group.setting.modal.view.php96
-rw-r--r--app/view/common/newgroup.modal.view.php49
-rw-r--r--app/view/common/ownership.setting.modal.view.php35
-rw-r--r--app/view/common/permissions.setting.modal.view.php82
-rw-r--r--app/view/common/setting.modal.view.php14
-rw-r--r--app/view/common/topp.view.php26
-rw-r--r--app/view/except/default.view.php12
-rw-r--r--app/view/obj/group.view.php43
-rw-r--r--examples/example.html11
17 files changed, 1001 insertions, 36 deletions
diff --git a/app/class/form.class.php b/app/class/form.class.php
index f0d660a..8bb6506 100644
--- a/app/class/form.class.php
+++ b/app/class/form.class.php
@@ -123,10 +123,10 @@ class Form
foreach ($this->textFields as $fld)
{
if (isset($input[$fld['name']]) && $input[$fld['name']] != "")
- $this->$fld['name'] = htmlEntities($input[$fld['name']], ENT_QUOTES);
+ $this->{$fld['name']} = htmlEntities($input[$fld['name']], ENT_QUOTES);
else if (!is_null($fld['deflt']))
- $this->$fld['name'] = $fld['deflt'];
+ $this->{$fld['name']} = $fld['deflt'];
else if ($fld['req'])
$this->logError($fld['name'] . " is required");
@@ -161,11 +161,11 @@ class Form
continue;
}
- $this->$fld['name'] = $input[$fld['name']];
+ $this->{$fld['name']} = $input[$fld['name']];
}
else if (!is_null($fld['deflt']))
- $this->$fld['name'] = $fld['deflt'];
+ $this->{$fld['name']} = $fld['deflt'];
else if ($fld['req'])
$this->logError($fld['name'] . " is required");
@@ -182,11 +182,11 @@ class Form
continue;
}
- $this->$fld['name'] = $input[$fld['name']];
+ $this->{$fld['name']} = $input[$fld['name']];
}
else if (!is_null($fld['deflt']))
- $this->$fld['name'] = $fld['deflt'];
+ $this->{$fld['name']} = $fld['deflt'];
else if ($fld['req'])
$this->logError($fld['name'] . " is required");
diff --git a/app/class/group.class.php b/app/class/group.class.php
index dfa7deb..246276a 100644
--- a/app/class/group.class.php
+++ b/app/class/group.class.php
@@ -29,6 +29,21 @@ class Group extends Object
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/app/class/object.class.php b/app/class/object.class.php
index b73a54d..7c0b7bb 100644
--- a/app/class/object.class.php
+++ b/app/class/object.class.php
@@ -15,12 +15,15 @@
*/
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
*/
@@ -250,6 +253,373 @@ abstract class Object extends Framework
{
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);
+ }
}
/*
diff --git a/app/class/user.class.php b/app/class/user.class.php
index 1185f45..b8143a9 100644
--- a/app/class/user.class.php
+++ b/app/class/user.class.php
@@ -15,6 +15,7 @@
*/
require_once "class/object.class.php";
+require_once "class/group.class.php";
/*
* Application users
@@ -213,22 +214,27 @@ class User extends Object
}
/*
- * Get this user's head image
+ * Get all groups this user owns or is a member of
*/
- function getHeadImage()
+ function getGroups()
{
- return $this->ar() . "/file.php?d=img/heads&f=" . $this->guid;
- }
+ /* owner */
+ $query = "SELECT guid FROM object WHERE type = 'group' AND owner = '" . $this->db->esc($this->guid) . "'";
+ $result = $this->db->query($query);
- /*
- * Remove this user's head image
- */
- function rmHeadImage()
- {
- if (!is_file("assets/img/heads/" . $this->guid))
- return true;
+ $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 unlink("assets/img/heads/" . $this->guid);
+ return $groups;
}
}
diff --git a/app/controller/obj.control.php b/app/controller/obj.control.php
new file mode 100644
index 0000000..2154d16
--- /dev/null
+++ b/app/controller/obj.control.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/controller.class.php";
+require_once "model/obj.mod.php";
+
+/*
+ * Object viewer, Used to view groups, pads, and more!
+ */
+class Obj extends Controller
+{
+ /*
+ * Controller implementation
+ */
+ function handle($argv)
+ {
+ $mod = new ObjModel($argv[0]);
+
+ if (!$mod->obj->canAccess($this->getCurrentUser()))
+ throw new Exception("You do not have permission to access this object");
+
+ switch ($mod->obj->type)
+ {
+ case "group":
+ $this->action_group($mod);
+ break;
+ }
+ }
+
+ function action_group($mod)
+ {
+ include "view/obj/group.view.php";
+ }
+}
+
+?>
diff --git a/app/controller/root.control.php b/app/controller/root.control.php
index 9a4ebd8..7e4d1ab 100644
--- a/app/controller/root.control.php
+++ b/app/controller/root.control.php
@@ -15,12 +15,14 @@
*/
require_once "class/controller.class.php";
+require_once "class/object.class.php";
require_once "class/setting.class.php";
require_once "controller/sysconf.control.php";
require_once "controller/except.control.php";
require_once "controller/auth.control.php";
require_once "controller/deauth.control.php";
require_once "controller/dashboard.control.php";
+require_once "controller/obj.control.php";
require_once "controller/deleteacct.control.php";
/*
@@ -82,6 +84,16 @@ class Root extends Controller
case "logout": $ctrl = new Deauth(); break;
case "deleteaccount": $ctrl = new Deleteacct(); break;
default:
+ /* Check if arg is an object guid */
+ $obj = new DBObject();
+
+ if ($obj->isGUID($argv[0]))
+ {
+ $ctrl = new Obj();
+ break;
+ }
+
+ /* No page to show for requested path */
throw new Exception("The requested path is not valid.");
break;
}
diff --git a/app/model/common.mod.php b/app/model/common.mod.php
index 3d8c200..6cba871 100644
--- a/app/model/common.mod.php
+++ b/app/model/common.mod.php
@@ -17,7 +17,9 @@
require_once "model/master.mod.php";
require_once "class/form.class.php";
require_once "class/setting.class.php";
+require_once "class/object.class.php";
require_once "class/user.class.php";
+require_once "class/group.class.php";
class CommonModel extends MasterModel
{
@@ -30,10 +32,20 @@ class CommonModel extends MasterModel
/*
* Constructor
*/
- function __construct()
+ function __construct($guid = null)
{
parent::__construct();
+ $this->first_setting_tab_active = 0;
+ $this->first_setting_tab_disp = 0;
$this->common_handleFormSubmissions($_REQUEST['input'], $_FILES['attachment']);
+
+ if (!is_null($guid))
+ {
+ $this->obj = new DBObject($guid);
+ $this->owner = $this->obj->getOwner();
+ $this->members = $this->obj->getMembers();
+ }
+
$this->common_deflt();
}
@@ -59,6 +71,16 @@ class CommonModel extends MasterModel
/* Admin all-users settings tab */
$userTbl = new User();
$this->common_settingAllUsers = $userTbl->getAllUsers_orderByAdminByName();
+
+ /* Setting modal - what tabs to display? */
+ if (isset($this->obj))
+ {
+ if ($this->obj->type == "group")
+ {
+ $this->group = new Group($this->obj->guid);
+ $this->common_settingShowTab['group'] = true;
+ }
+ }
}
/*
@@ -68,6 +90,8 @@ class CommonModel extends MasterModel
{
switch ($input['action'])
{
+ case "common-group-add": $this->addNewGroup($input); break;
+ case "common-setting-group": $this->saveSettingGroup($input, $attachment); break;
case "common-setting-user": $this->saveSettingUser($input, $attachment); break;
case "common-setting-admin": $this->saveSettingAdmin($input); break;
case "common-setting-allusers-adduser": $this->saveSettingAllusersAdduser($input); break;
@@ -77,6 +101,103 @@ class CommonModel extends MasterModel
}
/*
+ * Create a new user group
+ */
+ function addNewGroup($input)
+ {
+ $form = new Form();
+ $form->field_text("name");
+
+ if (!$form->populate($input))
+ {
+ $this->logFormErrors($form);
+ return;
+ }
+
+ $group = new Group();
+ $group->createNewGroup($form->name, $this->getCurrentUser());
+ }
+
+ /*
+ * Save changes to user group settings
+ */
+ function saveSettingGroup($input, $attachment)
+ {
+ $form = new Form();
+ $form->field_text("guid");
+ $form->field_text("name");
+ $form->field_bool("perm0");
+ $form->field_bool("perm1");
+ $form->field_bool("perm2");
+ $form->field_bool("perm3");
+ $form->field_bool("perm4");
+ $form->field_bool("perm5");
+ $form->field_bool("perm6");
+ $form->field_bool("perm7");
+ $form->field_bool("perm8");
+
+ if (!$form->populate($input))
+ {
+ $this->logFormErrors($form);
+ return;
+ }
+
+ $user = $this->getCurrentUser();
+ $group = new Group($form->guid);
+
+ if (!$user || $group->type != "group" || !$group->canModify($user))
+ {
+ $this->logError("You do not have permission to modify this group");
+ return;
+ }
+
+ if (isset($input['rmImage']))
+ {
+ if ($group->rmHeadImage())
+ $this->logNotice("Image removed");
+ else
+ $this->logError("Error removing group image");
+
+ return;
+ }
+
+ $group->name = $form->name;
+
+ if ($group->canModifyPermissions($user))
+ {
+ $perms = 0;
+
+ if ($form->perm0)
+ $perms |= 0x100;
+ if ($form->perm1)
+ $perms |= 0x080;
+ if ($form->perm2)
+ $perms |= 0x040;
+ if ($form->perm3)
+ $perms |= 0x020;
+ if ($form->perm4)
+ $perms |= 0x010;
+ if ($form->perm5)
+ $perms |= 0x008;
+ if ($form->perm6)
+ $perms |= 0x004;
+ if ($form->perm7)
+ $perms |= 0x002;
+ if ($form->perm8)
+ $perms |= 0x001;
+
+ $group->perms = $perms;
+ }
+
+ $group->saveObj();
+
+ if ($form->saveFile($attachment, $this->HEAD_IMG_MAX_SIZE, $this->HEAD_IMG_MIME, "assets/img/heads/" . $group->guid))
+ $this->logNotice("Image uploaded");
+ else
+ $this->logFormErrors($form);
+ }
+
+ /*
* Save changes to user account settings
*/
function saveSettingUser($input, $attachment)
@@ -343,6 +464,34 @@ class CommonModel extends MasterModel
$this->redirectTo($this->ar() . "/");
}
}
+
+ /*
+ * Set CSS class for the first tab title in the setting modal only
+ */
+ function getSettingModalTabActiveClass()
+ {
+ if (!$this->first_setting_tab_active)
+ {
+ $this->first_setting_tab_active = 1;
+ return "active";
+ }
+
+ return "";
+ }
+
+ /*
+ * Set CSS classes for the first tab in the setting modal only
+ */
+ function getSettingModalTabDispClasses()
+ {
+ if (!$this->first_setting_tab_disp)
+ {
+ $this->first_setting_tab_disp = 1;
+ return "in active";
+ }
+
+ return "";
+ }
}
?>
diff --git a/app/model/obj.mod.php b/app/model/obj.mod.php
new file mode 100644
index 0000000..159c962
--- /dev/null
+++ b/app/model/obj.mod.php
@@ -0,0 +1,30 @@
+<?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 "model/common.mod.php";
+
+class ObjModel extends CommonModel
+{
+ /*
+ * Constructor
+ */
+ function __construct($guid)
+ {
+ parent::__construct($guid);
+ }
+}
+
+?>
diff --git a/app/view/common/group.setting.modal.view.php b/app/view/common/group.setting.modal.view.php
new file mode 100644
index 0000000..d0e11ca
--- /dev/null
+++ b/app/view/common/group.setting.modal.view.php
@@ -0,0 +1,96 @@
+<?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.
+ */
+
+?>
+
+<?php require_once "view/common/permissions.setting.modal.view.php"; ?>
+
+<div class="tab-pane fade <?=$mod->getSettingModalTabDispClasses()?>" id="settGroupTab">
+ <p>&nbsp;</p>
+
+ <form method="post" action="<?=$mod->ap()?>" enctype="multipart/form-data">
+ <input type="hidden" name="input[action]" value="common-setting-group" />
+ <input type="hidden" name="input[guid]" value="<?=$mod->group->guid?>" />
+
+ <div class="row">
+ <div class="col-md-8">
+ <div class="form-group">
+ <label>Group name</label>
+ <input type="text" name="input[name]" class="form-control" value="<?=$mod->group->name?>" required="true" maxlength="50" <?=($mod->group->canModify($mod->getCurrentUser()) ? "" : "disabled")?> />
+ </div>
+ </div>
+
+ <div class="col-md-4 text-center">
+ <img src="<?=$mod->group->getHeadImage()?>" alt="<?=$mod->group->name?>" class="img-circle" height="100" />
+
+ <?php if ($mod->group->canModify($mod->getCurrentUser())) { ?>
+ <br />
+ <br />
+ <button type="button" class="btn btn-default btn-xs" data-toggle="collapse" data-target="#inputGroupImageCollapse">
+ <span class="glyphicon glyphicon-camera"></span> Upload new image
+ </button>
+ <br />
+ <button type="submit" name="input[rmImage]" class="btn btn-danger btn-xs" onclick="return assertConfirm()">
+ <span class="glyphicon glyphicon-remove"></span> Remove image
+ </button>
+ <?php } ?>
+ </div>
+ </div>
+
+ <div class="collapse" id="inputGroupImageCollapse">
+ <div class="form-group">
+ <label>Group Image</label>
+ <input type="file" name="attachment" />
+ </div>
+ </div>
+
+ <?php common_setting_permissions($mod, $mod->group); ?>
+
+ <?php if ($mod->group->canModify($mod->getCurrentUser())) { ?>
+ <p>&nbsp;</p>
+ <button type="submit" class="btn btn-success pull-right">Save</button>
+ <?php } ?>
+ </form>
+
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+
+ <div class="btn-toolbar pull-right">
+ <?php if ($mod->group->canModifyMembers($mod->getCurrentUser())) { ?>
+ <div class="btn-group">
+ <a href="<?=$mod->group->getURL()?>/members" class="btn btn-primary btn-xs">
+ <span class="glyphicon glyphicon-user"></span> Manage Members
+ </a>
+ </div>
+ <?php } ?>
+
+ <?php if ($mod->group->isOwner($mod->getCurrentUser())) { ?>
+ <div class="btn-group">
+ <a href="<?=$mod->group->getURL()?>/transfer" class="btn btn-danger btn-xs">
+ <span class="glyphicon glyphicon-new-window"></span> Transfer Ownership
+ </a>
+ </div>
+
+ <div class="btn-group">
+ <a href="<?=$mod->group->getURL()?>/delete" class="btn btn-danger btn-xs">
+ <span class="glyphicon glyphicon-trash"></span> Delete Group
+ </a>
+ </div>
+ <?php } ?>
+ </div>
+
+ <p>&nbsp;</p>
+</div>
diff --git a/app/view/common/newgroup.modal.view.php b/app/view/common/newgroup.modal.view.php
new file mode 100644
index 0000000..3dd631c
--- /dev/null
+++ b/app/view/common/newgroup.modal.view.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.
+ */
+
+?>
+
+<div id="newgroupModal" class="modal fade" tabindex="-1" role="dialog">
+ <div class="modal-dialog modal-sm" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+
+ <button type="button" class="close" data-dismiss="modal">
+ <span aria-hidden="true">&times;</span>
+ </button>
+
+ <h4 class="modal-title"><span class="glyphicon glyphicon-th"></span> Create new Group</h4>
+
+ </div>
+
+ <div class="modal-body">
+ <form method="post" action="<?=$mod->ap()?>">
+ <input type="hidden" name="input[action]" value="common-group-add" />
+ <div class="form-group">
+ <label>Group Name</label>
+ <input type="text" name="input[name]" class="form-control" required="true" maxlength="50" />
+ </div>
+
+ <button type="submit" class="btn btn-success pull-right">
+ <span class="glyphicon glyphicon-plus"></span> Add
+ </button>
+ </form>
+
+ <p>&nbsp;</p>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/app/view/common/ownership.setting.modal.view.php b/app/view/common/ownership.setting.modal.view.php
new file mode 100644
index 0000000..3f7c382
--- /dev/null
+++ b/app/view/common/ownership.setting.modal.view.php
@@ -0,0 +1,35 @@
+<?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.
+ */
+
+?>
+
+<?php function common_setting_ownership($mod, $obj) { ?>
+ <?php if ($obj->isOwner($mod->getCurrentUser())) { ?>
+ <label class="text-danger">Change Owner</label>
+ <div class="checkbox">
+ <label data-toggle="collapse" data-target="#inputGroupOwnerCollapse">
+ <input type="checkbox" name="input[setOwner]" value="1" /> Transfer Ownership
+ </label>
+ </div>
+
+ <div class="collapse" id="inputGroupOwnerCollapse">
+ <div class="form-group has-error">
+ <label class="control-label">Owner Username</label>
+ <input type="text" name="input[newOwner]" class="form-control" value="<?=$obj->getOwner()->name?>" />
+ </div>
+ </div>
+ <?php } ?>
+<?php } ?>
diff --git a/app/view/common/permissions.setting.modal.view.php b/app/view/common/permissions.setting.modal.view.php
new file mode 100644
index 0000000..55e4157
--- /dev/null
+++ b/app/view/common/permissions.setting.modal.view.php
@@ -0,0 +1,82 @@
+<?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.
+ */
+
+?>
+
+<?php function common_setting_permissions($mod, $obj) { ?>
+ <?php if ($obj->canModifyPermissions($mod->getCurrentUser())) { ?>
+ <label>Permissions</label>
+ <div class="row">
+ <div class="col-md-6">
+ <div class="checkbox">
+ <label>
+ <input type="checkbox" name="input[perm0]" value="1" <?=($obj->perms & 0x100 ? "checked" : "")?> /> Members can modify
+ </label>
+ </div>
+
+ <div class="checkbox">
+ <label>
+ <input type="checkbox" name="input[perm1]" value="1" <?=($obj->perms & 0x080 ? "checked" : "")?> /> Members can modify members
+ </label>
+ </div>
+
+ <div class="checkbox">
+ <label>
+ <input type="checkbox" name="input[perm2]" value="1" <?=($obj->perms & 0x040 ? "checked" : "")?> /> Members can access children
+ </label>
+ </div>
+
+ <div class="checkbox">
+ <label>
+ <input type="checkbox" name="input[perm3]" value="1" <?=($obj->perms & 0x020 ? "checked" : "")?> /> Members can create children
+ </label>
+ </div>
+
+ <div class="checkbox">
+ <label>
+ <input type="checkbox" name="input[perm4]" value="1" <?=($obj->perms & 0x010 ? "checked" : "")?> /> Members can modify children
+ </label>
+ </div>
+
+ <div class="checkbox">
+ <label>
+ <input type="checkbox" name="input[perm5]" value="1" <?=($obj->perms & 0x008 ? "checked" : "")?> /> Members can modify children's members
+ </label>
+ </div>
+ </div>
+
+ <div class="col-md-6">
+ <div class="checkbox">
+ <label>
+ <input type="checkbox" name="input[perm6]" value="1" <?=($obj->perms & 0x004 ? "checked" : "")?> /> Public can access
+ </label>
+ </div>
+
+ <div class="checkbox">
+ <label>
+ <input type="checkbox" name="input[perm7]" value="1" <?=($obj->perms & 0x002 ? "checked" : "")?> /> Public can access children
+ </label>
+ </div>
+
+ <div class="checkbox">
+ <label>
+ <input type="checkbox" name="input[perm8]" value="1" <?=($obj->perms & 0x001 ? "checked" : "")?> /> Public can create children
+ </label>
+ </div>
+ </div>
+ </div>
+ <?php } ?>
+<?php } ?>
diff --git a/app/view/common/setting.modal.view.php b/app/view/common/setting.modal.view.php
index 68d3e2d..2217805 100644
--- a/app/view/common/setting.modal.view.php
+++ b/app/view/common/setting.modal.view.php
@@ -31,7 +31,13 @@
<div class="modal-body">
<ul class="nav nav-tabs" role="tablist">
- <li class="active"><a href="#settUserTab" aria-controls="settUserTab" data-toggle="tab">
+ <?php if ($mod->common_settingShowTab['group']) { ?>
+ <li class="<?=$mod->getSettingModalTabActiveClass()?>"><a href="#settGroupTab" aria-controls="settGroupTab" data-toggle="tab">
+ <span class="glyphicon glyphicon-th"></span> <?=$mod->group->name?>
+ </a></li>
+ <?php } ?>
+
+ <li class="<?=$mod->getSettingModalTabActiveClass()?>"><a href="#settUserTab" aria-controls="settUserTab" data-toggle="tab">
<span class="glyphicon glyphicon-user"></span> <?=$mod->getCurrentUser()->getDisplayName()?>
</a></li>
@@ -42,7 +48,11 @@
</ul>
<div class="tab-content">
- <div class="tab-pane fade in active" id="settUserTab">
+ <?php if ($mod->common_settingShowTab['group']) { ?>
+ <?php include "view/common/group.setting.modal.view.php"; ?>
+ <?php } ?>
+
+ <div class="tab-pane fade <?=$mod->getSettingModalTabDispClasses()?>" id="settUserTab">
<p>&nbsp;</p>
<form method="post" action="<?=$mod->ap()?>" enctype="multipart/form-data">
diff --git a/app/view/common/topp.view.php b/app/view/common/topp.view.php
index 5908462..d9e0df0 100644
--- a/app/view/common/topp.view.php
+++ b/app/view/common/topp.view.php
@@ -20,6 +20,7 @@
<?php if ($mod->getCurrentUser()) { ?>
<?php include "view/common/setting.modal.view.php"; ?>
+ <?php include "view/common/newgroup.modal.view.php"; ?>
<?php } ?>
<nav class="navbar navbar-inverse navbar-fixed-top">
@@ -39,6 +40,31 @@
<?php if (!$mod->getCurrentUser()) { ?>
<p class="navbar-text navbar-right"><i>Not Logged In&nbsp;</i></p>
<?php } else { ?>
+ <ul class="nav navbar-nav">
+ <li><a href="<?=$mod->ap()?>"><span class="glyphicon glyphicon-refresh"></span></a></li>
+
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
+ <?=(isset($mod->obj) ? $mod->obj->name : "<i>Dashboard</i>")?> <span class="caret"></span>
+ </a>
+
+ <ul class="dropdown-menu">
+ <?php foreach ($mod->getCurrentUser()->getGroups() as $group) { ?>
+ <li><a href="<?=$mod->ar()?>/<?=$group->guid?>"><?=$group->name?></a></li>
+ <?php } ?>
+ </ul>
+ </li>
+
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
+ <span class="glyphicon glyphicon-plus"></span> <span class="caret"></span>
+ </a>
+ <ul class="dropdown-menu">
+ <li><a href="#" data-toggle="modal" data-target="#newgroupModal">New Group</a></li>
+ </ul>
+ </li>
+ </ul>
+
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
diff --git a/app/view/except/default.view.php b/app/view/except/default.view.php
index 8738a37..01cf123 100644
--- a/app/view/except/default.view.php
+++ b/app/view/except/default.view.php
@@ -28,13 +28,17 @@
<?php include "view/master/topp.view.php"; ?>
<div class="container">
- <div class="jumbotron">
- <h1 class="text-center">Scrott derped</h1>
- <h5 class="text-center">System internals reported this:</h5>
+ <div class="jumbotron text-center">
+ <h1>Scrott derped</h1>
+ <h5>System internals reported this:</h5>
- <div class="well well-sm text-center text-danger">
+ <div class="well well-sm text-danger">
<h3><?=$mod->message?></h3>
</div>
+
+ <a href="<?=$mod->ar()?>/" class="btn btn-primary btn-lg">
+ <span class="glyphicon glyphicon-pencil"></span> Go to Scrott Dashboard
+ </a>
</div>
</div>
diff --git a/app/view/obj/group.view.php b/app/view/obj/group.view.php
new file mode 100644
index 0000000..dde4df1
--- /dev/null
+++ b/app/view/obj/group.view.php
@@ -0,0 +1,43 @@
+<!--
+ * 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.
+-->
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <?php include "view/common/head.view.php"; ?>
+ <title>Scrott - <?=$mod->group->name?></title>
+ </head>
+
+ <body>
+ <?php include "view/common/topp.view.php"; ?>
+
+ <div class="container">
+ <div class="well well-lg">
+ <h1><?=$mod->group->name?></h1>
+ <img src="<?=$mod->owner->getHeadImage()?>" alt="<?=$mod->owner->getDisplayName()?>" class="img-circle" height="50" />
+
+ <?php if (count($mod->members)) { ?>
+ <span class="glyphicon glyphicon-plus"></span>
+ <?php } ?>
+
+ <?php foreach ($mod->members as $member) { ?>
+ <img src="<?=$member->getHeadImage()?>" alt="<?=$member->getDisplayName()?>" class="img-circle" height="50" />
+ <?php } ?>
+ </div>
+ </div>
+
+ <?php include "view/common/foot.view.php"; ?>
+ </body>
+</html>
diff --git a/examples/example.html b/examples/example.html
index e1e5618..778f6d8 100644
--- a/examples/example.html
+++ b/examples/example.html
@@ -1,5 +1,3 @@
-<!DOCTYPE html>
-
<html lang="en">
<body>
<!--NAVBAR-->
@@ -52,15 +50,6 @@
<div class="container">
<div class="well well-lg">
<div class="row">
- <div class="col-md-4">
- <h1>Save the World <span class="glyphicon glyphicon-globe"></span><!--Denoting this pad as globally visible--></h1>
- <img src="assets/img/sonic.png" alt="Sonic" class="img-circle" height="50" />
- <span class="glyphicon glyphicon-plus"></span>
- <img src="assets/img/tails.png" alt="Miles" class="img-circle" height="50" />
- <img src="assets/img/amy.png" alt="Amy" class="img-circle" height="50" />
- <img src="assets/img/knuckles.png" alt="Knuckles" class="img-circle" height="50" />
- </div>
-
<div class="col-md-8">
<legend class="text-center">Issue Progress</legend>
<div class="progress">