diff --git a/css/master.css b/css/master.css
index 3e88452..9ffad66 100644
--- a/css/master.css
+++ b/css/master.css
@@ -212,6 +212,18 @@ input[type="submit"], input[type="reset"], input[type="button"] {
border: 1px solid black;
}
+/** Admin navigation */
+#admin-navigation {
+ float: left;
+ background-color: rgb(200, 255, 255);
+ padding: 3px;
+ list-style: none;
+}
+
+ #admin-navigation li {
+ margin: 10px;
+ }
+
/** System Options */
#settings {
width: 75%;
diff --git a/events/admin_usergroups.php b/events/admin_usergroups.php
new file mode 100644
index 0000000..c2da7c7
--- /dev/null
+++ b/events/admin_usergroups.php
@@ -0,0 +1,47 @@
+<?php
+// Bugdar 2
+// Copyright (c) 2010 Blue Static
+//
+// This program 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 any later version.
+//
+// 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, see <http://www.gnu.org/licenses/>.
+
+use phalanx\events\EventPump as EventPump;
+
+require_once BUGDAR_ROOT . '/includes/model_usergroup.php';
+
+// Queries for the list of usergroups.
+class AdminUsergroupsEvent extends phalanx\events\Event
+{
+ protected $usergroups = array();
+ public function usergroups() { return $this->usergroups; }
+
+ static public function InputList()
+ {
+ return array();
+ }
+
+ static public function OutputList()
+ {
+ return array('usergroups');
+ }
+
+ public function WillFire()
+ {
+ Bugdar::$auth->RequireAuthentication();
+ // TODO: check admin permission
+ }
+
+ public function Fire()
+ {
+ $this->usergroups = Usergroup::FetchGroup();
+ }
+}
diff --git a/events/admin_usergroups_edit.php b/events/admin_usergroups_edit.php
new file mode 100644
index 0000000..c17d3db
--- /dev/null
+++ b/events/admin_usergroups_edit.php
@@ -0,0 +1,90 @@
+<?php
+// Bugdar 2
+// Copyright (c) 2010 Blue Static
+//
+// This program 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 any later version.
+//
+// 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, see <http://www.gnu.org/licenses/>.
+
+use phalanx\events\EventPump as EventPump;
+
+require_once BUGDAR_ROOT . '/includes/model_usergroup.php';
+
+// Edits an individual usergroup.
+class AdminUsergroupsEditEvent extends phalanx\events\Event
+{
+ protected $usergroup = array();
+ public function usergroup() { return $this->usergroup; }
+
+ static public function InputList()
+ {
+ return array(
+ '_id',
+ 'title',
+ 'display_title',
+ 'permissions'
+ );
+ }
+
+ static public function OutputList()
+ {
+ return array('usergroup');
+ }
+
+ public function WillFire()
+ {
+ Bugdar::$auth->RequireAuthentication();
+ // TODO: check admin permission
+ }
+
+ public function Fire()
+ {
+ // If an ID was passed, try updating the record.
+ if ($this->input->_id) {
+ try {
+ $this->usergroup = new Usergroup($this->input->_id);
+ $this->usergroup->FetchInto();
+ } catch (\phalanx\data\ModelException $e) {
+ EventPump::Pump()->RaiseEvent(new StandardErrorEvent(l10n::S('ERROR_INVALID_ID')));
+ return;
+ }
+ } else {
+ // Otherwise, create a new one.
+ $this->usergroup = new Usergroup();
+ }
+
+ if ($this->input->_method == 'POST') {
+ $title = \phalanx\data\Cleaner::HTML($this->input->title);
+ if (empty($title)) {
+ EventPump::Pump()->RaiseEvent(new StandardErrorEvent('The title field is required.'));
+ return;
+ }
+ $this->usergroup->title = $title;
+
+ if (!empty($this->input->display_title)) {
+ $this->usergroup->display_title = \phalanx\data\Cleaner::HTML($this->input->display_title);
+ }
+
+ $mask = 0;
+ foreach ($this->input->permissions as $name => $bit) {
+ $mask += $bit * Usergroup::$permissions[$name];
+ }
+ $this->usergroup->mask = $mask;
+
+ // Save the actual record.
+ if ($this->input->_id) {
+ $this->usergroup->Update();
+ } else {
+ $this->usergroup->Insert();
+ }
+ }
+ }
+}
diff --git a/includes/model_usergroup.php b/includes/model_usergroup.php
index c1622aa..09504b8 100644
--- a/includes/model_usergroup.php
+++ b/includes/model_usergroup.php
@@ -33,23 +33,36 @@ class Usergroup extends phalanx\data\Model
);
// Permission masks {{
- const CAN_VIEW = 1;
- const CAN_REPORT = 2;
- const CAN_VOTE = 4;
- const CAN_COMMENT = 8;
- const CAN_UPDATE = 16;
- const CAN_VIEW_HIDDEN = 32;
+ const CAN_VIEW = 1;
+ const CAN_REPORT = 2;
+ const CAN_VOTE = 4;
+ const CAN_COMMENT = 8;
+ const CAN_UPDATE = 16;
+ const CAN_VIEW_HIDDEN = 32;
const CAN_EDIT_OWN_COMMENTS = 64;
const CAN_EDIT_ALL_COMMENTS = 128;
- const CAN_EDIT_REPORT = 256;
+ const CAN_EDIT_REPORT = 256;
const CAN_DELETE_COMMENTS = 512;
- const CAN_DELETE_REPORTS = 1024;
+ const CAN_DELETE_REPORTS = 1024;
// }}
+ static public $permissions = array(
+ 'CAN_VIEW' => 1,
+ 'CAN_REPORT' => 2,
+ 'CAN_VOTE' => 4,
+ 'CAN_COMMENT' => 8,
+ 'CAN_UPDATE' => 16,
+ 'CAN_VIEW_HIDDEN' => 32,
+ 'CAN_EDIT_OWN_COMMENTS' => 64,
+ 'CAN_EDIT_ALL_COMMENTS' => 128,
+ 'CAN_EDIT_REPORT' => 256,
+ 'CAN_DELETE_COMMENTS' => 512,
+ 'CAN_DELETE_REPORTS' => 1024,
+ );
// Default, built-in roles {{
- const ROLE_ANONYMOUS = 1;
- const ROLE_REGISTERED = 2;
- const ROLE_DEVELOPER = 3;
+ const ROLE_ANONYMOUS = 1;
+ const ROLE_REGISTERED = 2;
+ const ROLE_DEVELOPER = 3;
const ROLE_ADMINISTRATOR = 4;
// }}
diff --git a/languages/en-US.php b/languages/en-US.php
index ae605db..54032f7 100644
--- a/languages/en-US.php
+++ b/languages/en-US.php
@@ -36,6 +36,10 @@ class Language_en_US extends \bugdar\Language
public function & strings()
{
static $strings = array(
+ 'ERROR_INVALID_ID' => 'Could not find object with that ID.',
+ 'BUTTON_SAVE_CHANGES' => 'Save Changes',
+ 'BUTTON_RESET' => 'Reset',
+
'BUG_LIST_TITLE' => 'List',
'BUG_NEW_TITLE' => 'New Report',
@@ -51,6 +55,25 @@ class Language_en_US extends \bugdar\Language
'ADMIN_SETTINGS_WEBROOT_VAR' => 'Web Root',
'ADMIN_SETTINGS_WEBROOT_DFN' => 'The absolute path from the server root to the Bugdar installation. This should end with a trailing slash.',
'ADMIN_SETTINGS_SAVE' => 'Save Settings',
+
+ 'ADMIN_USERGROUPS_TITLE' => 'Usergroups',
+ 'ADMIN_USERGROUP_TITLE' => 'Usergroup Title',
+ 'ADMIN_USERGROUP_DISPLAY_TITLE' => 'Display Title',
+ 'ADMIN_USERGROUP_HAS_MASK' => 'Group Type',
+ 'ADMIN_USERGROUP_ROLE_GROUP' => 'Role Group',
+ 'ADMIN_USERGROUP_PURE_GROUP' => 'User Group',
+ 'ADMIN_USERGROUP_PERMISSIONS' => 'Permissions',
+ 'ADMIN_USERGROUP_PERMISSION_CAN_VIEW' => 'Can View Bug Reports',
+ 'ADMIN_USERGROUP_PERMISSION_CAN_REPORT' => 'Can Create New Bug Reports',
+ 'ADMIN_USERGROUP_PERMISSION_CAN_VOTE' => 'Can Vote on Bugs',
+ 'ADMIN_USERGROUP_PERMISSION_CAN_COMMENT' => 'Can Leave Comments on Bugs',
+ 'ADMIN_USERGROUP_PERMISSION_CAN_UPDATE' => 'Can Modify Bug Fields',
+ 'ADMIN_USERGROUP_PERMISSION_CAN_VIEW_HIDDEN' => 'Can View Hidden Bugs',
+ 'ADMIN_USERGROUP_PERMISSION_CAN_EDIT_OWN_COMMENTS' => 'Can Edit Own Comments',
+ 'ADMIN_USERGROUP_PERMISSION_CAN_EDIT_ALL_COMMENTS' => 'Can Edit All Comments',
+ 'ADMIN_USERGROUP_PERMISSION_CAN_EDIT_REPORT' => 'Can Edit Bug Reports',
+ 'ADMIN_USERGROUP_PERMISSION_CAN_DELETE_COMMENTS' => 'Can Delete Comments',
+ 'ADMIN_USERGROUP_PERMISSION_CAN_DELETE_REPORTS' => 'Can Delete Bugs',
);
return $strings;
}
diff --git a/phalanx b/phalanx
index 5c27753..f67685d 160000
--- a/phalanx
+++ b/phalanx
@@ -1 +1 @@
-Subproject commit 5c27753cb1be394dc04742f4c8638ff538d85c81
+Subproject commit f67685d80f17d17b7d2610681374ebba9937cc5d
diff --git a/templates/admin_settings.tpl b/templates/admin_settings.tpl
index 1df5a1c..5ea1e0e 100644
--- a/templates/admin_settings.tpl
+++ b/templates/admin_settings.tpl
@@ -1,4 +1,5 @@
<? InsertView('header', array('title' => l10n::S('ADMIN_SETTINGS_TITLE'))) ?>
+<? InsertView('admin_sidebar') ?>
<form action="<?= EventLink('AdminSettings') ?>" method="post">
diff --git a/templates/admin_sidebar.tpl b/templates/admin_sidebar.tpl
new file mode 100644
index 0000000..844fe3e
--- /dev/null
+++ b/templates/admin_sidebar.tpl
@@ -0,0 +1,5 @@
+
+<ul id="admin-navigation">
+ <li><a href="<?= EventLink('AdminSettings') ?>"><?= l10n::S('ADMIN_SETTINGS_TITLE') ?></a></li>
+ <li><a href="<?= EventLink('AdminUsergroups') ?>"><?= l10n::S('ADMIN_USERGROUPS_TITLE') ?></a></li>
+</ul>
diff --git a/templates/admin_usergroups.tpl b/templates/admin_usergroups.tpl
new file mode 100644
index 0000000..1269f79
--- /dev/null
+++ b/templates/admin_usergroups.tpl
@@ -0,0 +1,20 @@
+<? InsertView('header', array('title' => l10n::S('ADMIN_USERGROUPS_TITLE'))) ?>
+
+<? Insertview('admin_sidebar') ?>
+
+<table id="settings">
+ <tr>
+ <th><?= l10n::S('ADMIN_USERGROUP_TITLE') ?></th>
+ <th><?= l10n::S('ADMIN_USERGROUP_HAS_MASK') ?></th>
+ </tr>
+
+<? foreach ($this->usergroups as $usergroup): ?>
+ <tr>
+ <td><a href="<?= EventLink('AdminUsergroupsEdit', $usergroup->usergroup_id) ?>"><?= $this->HTML($usergroup->title) ?></a></td>
+ <td><?= ($usergroup->mask) ? l10n::S('ADMIN_USERGROUP_ROLE_GROUP') : l10n::S('ADMIN_USERGROUP_PURE_GROUP') ?></td>
+ </tr>
+<? endforeach?>
+
+</table>
+
+<? InsertView('footer') ?>
\ No newline at end of file
diff --git a/templates/admin_usergroups_edit.tpl b/templates/admin_usergroups_edit.tpl
new file mode 100644
index 0000000..1fbdbe6
--- /dev/null
+++ b/templates/admin_usergroups_edit.tpl
@@ -0,0 +1,39 @@
+<? InsertView('header', array('title' => l10n::S('ADMIN_USERGROUPS_TITLE'))) ?>
+
+<? Insertview('admin_sidebar') ?>
+
+<form action="<?= EventLink('AdminUsergroupsEdit', $this->usergroup->usergroup_id) ?>" method="post">
+<input type="hidden" name="_id" value="$[usergroup.usergroup_id]" />
+
+<table id="settings">
+ <tr>
+ <th><label for="title"><?= l10n::S('ADMIN_USERGROUP_TITLE') ?></label></th>
+ <td><input type="text" name="title" value="$[usergroup.title]" id="title"></th>
+ </tr>
+ <tr>
+ <th><label for="title"><?= l10n::S('ADMIN_USERGROUP_DISPLAY_TITLE') ?></label></th>
+ <td><input type="text" name="display_title" value="$[usergroup.display_title]" id="display_title"></th>
+ </tr>
+ <tr>
+ <th colspan="2" style="text-align: center; background-color: lightgray"><?= l10n::S('ADMIN_USERGROUP_PERMISSIONS') ?></th>
+ </tr>
+ <? foreach (Usergroup::$permissions as $name => $value): ?>
+ <tr>
+ <td colspan="2" style="text-align: left">
+ <? $on = ($this->usergroup->mask & $value) ?>
+ <input type="checkbox" name="permissions[<?= $name ?>]" value="1" id="permissions[<?= $name ?>]" <?= $on ? ' checked="checked"' : '' ?> />
+ <label for="permissions[<?= $name ?>]"><?= l10n::S('ADMIN_USERGROUP_PERMISSION_' . $name) ?></label>
+ </td>
+ </tr>
+ <? endforeach ?>
+ <tr>
+ <th colspan="2" style="text-align: center; background-color: lightgray">
+ <input type="submit" name="submit" value="<?= l10n::S('BUTTON_SAVE_CHANGES') ?>" id="submit" />
+ <input type="reset" name="reset" value="<?= l10n::S('BUTTON_RESET') ?>" id="reset" />
+ </th>
+ </tr>
+</table>
+
+</form>
+
+<? InsertView('footer') ?>
\ No newline at end of file