diff options
-rw-r--r-- | db/install.sql | 18 | ||||
-rw-r--r-- | db/update.sql | 3 | ||||
-rw-r--r-- | includes/controller/angeltypes_controller.php | 196 | ||||
-rw-r--r-- | includes/controller/user_angeltypes_controller.php | 272 | ||||
-rw-r--r-- | includes/model/AngelType_model.php | 134 | ||||
-rw-r--r-- | includes/model/UserAngelTypes_model.php | 69 | ||||
-rw-r--r-- | includes/model/User_model.php | 20 | ||||
-rw-r--r-- | includes/pages/admin_angel_types.php | 116 | ||||
-rw-r--r-- | includes/pages/admin_user_angeltypes.php | 14 | ||||
-rw-r--r-- | includes/sys_menu.php | 2 | ||||
-rw-r--r-- | includes/view/AngelTypes_view.php | 115 | ||||
-rw-r--r-- | includes/view/UserAngelTypes_view.php | 58 | ||||
-rw-r--r-- | public/css/base.css | 35 | ||||
-rw-r--r-- | public/index.php | 35 | ||||
-rwxr-xr-x | public/pic/icons/arrow_left.png | bin | 0 -> 345 bytes | |||
-rw-r--r-- | templates/guest_credits.html | 4 |
16 files changed, 883 insertions, 208 deletions
diff --git a/db/install.sql b/db/install.sql index 7eb404a9..896093e4 100644 --- a/db/install.sql +++ b/db/install.sql @@ -41,24 +41,6 @@ CREATE TABLE IF NOT EXISTS `AngelTypes` ( -- -------------------------------------------------------- --- --- Tabellenstruktur für Tabelle `ChangeLog` --- - -DROP TABLE IF EXISTS `ChangeLog`; -CREATE TABLE IF NOT EXISTS `ChangeLog` ( - `Time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `UID` int(11) NOT NULL DEFAULT '0', - `Commend` text NOT NULL, - `SQLCommad` text NOT NULL -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Daten für Tabelle `ChangeLog` --- - - --- -------------------------------------------------------- -- -- Tabellenstruktur für Tabelle `Counter` diff --git a/db/update.sql b/db/update.sql index 407a8539..29b4a7dc 100644 --- a/db/update.sql +++ b/db/update.sql @@ -1,3 +1,6 @@ +/* angeltype view */ +INSERT INTO `engelsystem`.`Privileges` (`id`, `name`, `desc`) VALUES (NULL , 'angeltypes', 'View angeltypes'); + /* force active */ ALTER TABLE `User` ADD `force_active` BOOLEAN NOT NULL AFTER `Aktiv`, ADD INDEX ( `force_active` ); diff --git a/includes/controller/angeltypes_controller.php b/includes/controller/angeltypes_controller.php new file mode 100644 index 00000000..03c9651d --- /dev/null +++ b/includes/controller/angeltypes_controller.php @@ -0,0 +1,196 @@ +<?php + +function angeltypes_title() { + return _("Angeltypes"); +} + +/** + * Route angeltype actions. + */ +function angeltypes_controller() { + if (! isset($_REQUEST['action'])) + $_REQUEST['action'] = 'list'; + switch ($_REQUEST['action']) { + default: + case 'list': + list($title, $content) = angeltypes_list_controller(); + break; + case 'view': + list($title, $content) = angeltype_controller(); + break; + case 'edit': + list($title, $content) = angeltype_edit_controller(); + break; + case 'delete': + list($title, $content) = angeltype_delete_controller(); + break; + } + + return array( + $title, + $content + ); +} + +function angeltype_delete_controller() { + global $privileges, $user; + + if (! in_array('admin_angel_types', $privileges)) + redirect(page_link_to('angeltypes')); + + $angeltype = mAngelType($_REQUEST['angeltype_id']); + if ($angeltype === false) + engelsystem_error("Unable to load angeltype."); + if ($angeltype == null) + redirect(page_link_to('angeltypes')); + + if (isset($_REQUEST['confirmed'])) { + $result = AngelType_delete($angeltype); + if ($result === false) + engelsystem_error("Unable to delete angeltype."); + + engelsystem_log("Deleted angeltype: " . $name); + success(sprintf(_("Angeltype %s deleted."), $name)); + redirect(page_link_to('angeltypes')); + } + + return array( + sprintf(_("Delete angeltype %s"), $angeltype['name']), + AngelType_delete_view($angeltype) + ); +} + +function angeltype_edit_controller() { + global $privileges, $user; + + if (! in_array('admin_angel_types', $privileges)) + redirect(page_link_to('angeltypes')); + + $name = ""; + $restricted = false; + if (isset($_REQUEST['angeltype_id'])) { + $angeltype = mAngelType($_REQUEST['angeltype_id']); + if ($angeltype === false) + engelsystem_error("Unable to load angeltype."); + if ($angeltype == null) + redirect(page_link_to('angeltypes')); + + $name = $angeltype['name']; + $restricted = $angeltype['restricted']; + } + + if (isset($_REQUEST['submit'])) { + $ok = true; + + if (isset($_REQUEST['name'])) { + list($valid, $name) = AngelType_validate_name($_REQUEST['name'], $angeltype); + if (! $valid) { + $ok = false; + error(_("Please check the name. Maybe it already exists.")); + } + } + + $restricted = isset($_REQUEST['restricted']); + + if ($ok) { + $restricted = $restricted ? 1 : 0; + if (isset($angeltype)) { + $result = AngelType_update($angeltype['id'], $name, $restricted); + if ($result === false) + engelsystem_error("Unable to update angeltype."); + engelsystem_log("Updated angeltype: " . $name . ", restricted: " . $restricted); + $angeltype_id = $angeltype['id']; + } else { + $angeltype_id = AngelType_create($name, $restricted); + if ($angeltype_id === false) + engelsystem_error("Unable to create angeltype."); + engelsystem_log("Created angeltype: " . $name . ", restricted: " . $restricted); + } + + success("Angel type saved."); + redirect(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype_id); + } + } + + return array( + isset($angeltype) ? sprintf(_("Edit %s"), $name) : _("Add new angeltype"), + AngelType_edit_view($name, $restricted) + ); +} + +/** + * View details of a given angeltype. + */ +function angeltype_controller() { + global $privileges, $user; + + if (! isset($_REQUEST['angeltype_id'])) + redirect(page_link_to('angeltypes')); + + $angeltype = mAngelType($_REQUEST['angeltype_id']); + if ($angeltype === false) + engelsystem_error("Unable to load angeltype."); + if ($angeltype == null) + redirect(page_link_to('angeltypes')); + + $user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype); + if ($user_angeltype === false) + engelsystem_error("Unable to load user angeltype."); + + $members = Users_by_angeltype($angeltype); + if ($members === false) + engelsystem_error("Unable to load members."); + + return array( + sprintf(_("Team %s"), $angeltype['name']), + AngelType_view($angeltype, $members, $user_angeltype, in_array('admin_user_angeltypes', $privileges), in_array('admin_angel_types', $privileges)) + ); +} + +/** + * View a list of all angeltypes. + */ +function angeltypes_list_controller() { + global $privileges, $user; + + $angeltypes = AngelTypes_with_user($user); + if ($angeltypes === false) + engelsystem_error("Unable to load angeltypes."); + + foreach ($angeltypes as &$angeltype) { + $actions = array( + '<a class="view" href="' . page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'] . '">' . _("view") . '</a>' + ); + + if (in_array('admin_angel_types', $privileges)) { + $actions[] = '<a class="edit" href="' . page_link_to('angeltypes') . '&action=edit&angeltype_id=' . $angeltype['id'] . '">' . _("edit") . '</a>'; + $actions[] = '<a class="delete" href="' . page_link_to('angeltypes') . '&action=delete&angeltype_id=' . $angeltype['id'] . '">' . _("delete") . '</a>'; + } + + $angeltype['membership'] = ""; + if ($angeltype['user_angeltype_id'] != null) { + if ($angeltype['restricted']) { + if ($angeltype['confirm_user_id'] == null) + $angeltype['membership'] = '<img src="pic/icons/lock.png" alt="' . _("Unconfirmed") . '" title="' . _("Unconfirmed") . '"> ' . _("Unconfirmed"); + else + $angeltype['membership'] = '<img src="pic/icons/tick.png" alt="' . _("Member") . '" title="' . _("Member") . '"> ' . _("Member"); + } else + $angeltype['membership'] = '<img src="pic/icons/tick.png" alt="' . _("Member") . '" title="' . _("Member") . '"> ' . _("Member"); + $actions[] = '<a class="cancel" href="' . page_link_to('user_angeltypes') . '&action=delete&user_angeltype_id=' . $angeltype['user_angeltype_id'] . '">' . _("leave") . '</a>'; + } else { + $angeltype['membership'] = '<img src="pic/icons/cross.png" alt="" title="">'; + $actions[] = '<a class="add" href="' . page_link_to('user_angeltypes') . '&action=add&angeltype_id=' . $angeltype['id'] . '">' . _("join") . '</a>'; + } + + $angeltype['restricted'] = $angeltype['restricted'] ? '<img src="pic/icons/lock.png" alt="' . _("Restricted") . '" title="' . _("Restricted") . '">' : ''; + $angeltype['name'] = '<a href="' . page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'] . '">' . $angeltype['name'] . '</a>'; + + $angeltype['actions'] = join(" ", $actions); + } + + return array( + angeltypes_title(), + AngelTypes_list_view($angeltypes, in_array('admin_angel_types', $privileges)) + ); +} +?>
\ No newline at end of file diff --git a/includes/controller/user_angeltypes_controller.php b/includes/controller/user_angeltypes_controller.php new file mode 100644 index 00000000..d110f7a7 --- /dev/null +++ b/includes/controller/user_angeltypes_controller.php @@ -0,0 +1,272 @@ +<?php + +function user_angeltypes_delete_all_controller() { + global $user, $privileges; + + if (! in_array('admin_user_angeltypes', $privileges)) { + error(_("You are not allowed to delete all users for this angeltype.")); + redirect(page_link_to('angeltypes')); + } + + if (! isset($_REQUEST['angeltype_id'])) { + error(_("Angeltype doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + $angeltype = mAngelType($_REQUEST['angeltype_id']); + if ($angeltype === false) + engelsystem_error("Unable to load angeltype."); + if ($angeltype == null) { + error(_("Angeltype doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + if (isset($_REQUEST['confirmed'])) { + $result = UserAngelTypes_delete_all($angeltype['id']); + if ($result === false) + engelsystem_error("Unable to confirm all users."); + + engelsystem_log(sprintf("Denied all users for angeltype %s", $angeltype['name'])); + success(sprintf(_("Denied all users for angeltype %s."), $angeltype['name'])); + redirect(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id']); + } + + return array( + _("Deny all users"), + UserAngelTypes_delete_all_view($angeltype) + ); +} + +function user_angeltypes_confirm_all_controller() { + global $user, $privileges; + + if (! in_array('admin_user_angeltypes', $privileges)) { + error(_("You are not allowed to confirm all users for this angeltype.")); + redirect(page_link_to('angeltypes')); + } + + if (! isset($_REQUEST['angeltype_id'])) { + error(_("Angeltype doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + $angeltype = mAngelType($_REQUEST['angeltype_id']); + if ($angeltype === false) + engelsystem_error("Unable to load angeltype."); + if ($angeltype == null) { + error(_("Angeltype doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + if (isset($_REQUEST['confirmed'])) { + $result = UserAngelTypes_confirm_all($angeltype['id'], $user); + if ($result === false) + engelsystem_error("Unable to confirm all users."); + + engelsystem_log(sprintf("Confirmed all users for angeltype %s", $angeltype['name'])); + success(sprintf(_("Confirmed all users for angeltype %s."), $angeltype['name'])); + redirect(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id']); + } + + return array( + _("Confirm all users"), + UserAngelTypes_confirm_all_view($angeltype) + ); +} + +function user_angeltype_confirm_controller() { + global $user, $privileges; + + if (! in_array('admin_user_angeltypes', $privileges)) { + error(_("You are not allowed to confirm this users angeltype.")); + redirect(page_link_to('angeltypes')); + } + + if (! isset($_REQUEST['user_angeltype_id'])) { + error(_("User angeltype doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + $user_angeltype = UserAngelType($_REQUEST['user_angeltype_id']); + if ($user_angeltype === false) + engelsystem_error("Unable to load user angeltype."); + if ($user_angeltype == null) { + error(_("User angeltype doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + $angeltype = mAngelType($user_angeltype['angeltype_id']); + if ($angeltype === false) + engelsystem_error("Unable to load angeltype."); + if ($angeltype == null) { + error(_("Angeltype doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + $user_source = User($user_angeltype['user_id']); + if ($user_source === false) + engelsystem_error("Unable to load user."); + if ($user_source == null) { + error(_("User doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + if (isset($_REQUEST['confirmed'])) { + $result = UserAngelType_confirm($user_angeltype['id'], $user); + if ($result === false) + engelsystem_error("Unable to confirm user angeltype."); + + engelsystem_log(sprintf("%s confirmed for angeltype %s", User_Nick_render($user_source), $angeltype['name'])); + success(sprintf(_("%s confirmed for angeltype %s."), User_Nick_render($user_source), $angeltype['name'])); + redirect(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id']); + } + + return array( + _("Confirm angeltype for user"), + UserAngelType_confirm_view($user_angeltype, $user, $angeltype) + ); +} + +function user_angeltype_delete_controller() { + global $user, $privileges; + + if (! isset($_REQUEST['user_angeltype_id'])) { + error(_("User angeltype doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + $user_angeltype = UserAngelType($_REQUEST['user_angeltype_id']); + if ($user_angeltype === false) + engelsystem_error("Unable to load user angeltype."); + if ($user_angeltype == null) { + error(_("User angeltype doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + $angeltype = mAngelType($user_angeltype['angeltype_id']); + if ($angeltype === false) + engelsystem_error("Unable to load angeltype."); + if ($angeltype == null) { + error(_("Angeltype doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + $user_source = User($user_angeltype['user_id']); + if ($user_source === false) + engelsystem_error("Unable to load user."); + if ($user_source == null) { + error(_("User doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + if ($user['UID'] != $user_angeltype['user_id'] && ! in_array('admin_user_angeltypes', $privileges)) { + error(_("You are not allowed to delete this users angeltype.")); + redirect(page_link_to('angeltypes')); + } + + if (isset($_REQUEST['confirmed'])) { + $result = UserAngelType_delete($user_angeltype); + if ($result === false) + engelsystem_error("Unable to delete user angeltype."); + + $success_message = sprintf(_("User %s removed from %s."), User_Nick_render($user_source), $angeltype['name']); + engelsystem_log($success_message); + success($success_message); + + redirect(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id']); + } + + return array( + _("Remove angeltype"), + UserAngelType_delete_view($user_angeltype, $user, $angeltype) + ); +} + +function user_angeltype_update_controller() { + +} + +function user_angeltype_add_controller() { + global $user, $privileges; + + if (! isset($_REQUEST['angeltype_id'])) { + error(_("Angeltype doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + $angeltype = mAngelType($_REQUEST['angeltype_id']); + if ($angeltype === false) + engelsystem_error("Unable to load angeltype."); + if ($angeltype == null) { + error(_("Angeltype doesn't exist.")); + redirect(page_link_to('angeltypes')); + } + + $user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype); + if ($user_angeltype === false) + engelsystem_error("Unable to load user angeltype."); + if ($user_angeltype != null) { + error(sprintf(_("User is already an %s."), $angeltype['name'])); + redirect(page_link_to('angeltypes')); + } + + if (isset($_REQUEST['confirmed'])) { + $user_angeltype_id = UserAngelType_create($user, $angeltype); + if ($user_angeltype_id === false) + engelsystem_error("Unable to create user angeltype."); + + $success_message = sprintf(_("User %s joined %s."), User_Nick_render($user), $angeltype['name']); + engelsystem_log($success_message); + success($success_message); + + if (in_array('admin_user_angeltypes', $privileges)) { + $result = UserAngelType_confirm($user_angeltype_id, $user); + if ($result === false) + engelsystem_error("Unable to confirm user angeltype."); + $success_message = sprintf(_("User %s confirmed as %s."), User_Nick_render($user), $angeltype['name']); + engelsystem_log($success_message); + } + + redirect(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id']); + } + + return array( + _("Add user to angeltype"), + UserAngelType_add_view($user, $angeltype) + ); +} + +function user_angeltypes_controller() { + if (! isset($_REQUEST['action'])) + redirect(page_link_to('angeltypes')); + + switch ($_REQUEST['action']) { + case 'delete_all': + list($title, $content) = user_angeltypes_delete_all_controller(); + break; + case 'confirm_all': + list($title, $content) = user_angeltypes_confirm_all_controller(); + break; + case 'confirm': + list($title, $content) = user_angeltype_confirm_controller(); + break; + case 'delete': + list($title, $content) = user_angeltype_delete_controller(); + break; + case 'update': + list($title, $content) = user_angeltype_update_controller(); + break; + case 'add': + list($title, $content) = user_angeltype_add_controller(); + break; + default: + redirect(page_link_to('angeltypes')); + } + + return array( + $title, + $content + ); +} + +?>
\ No newline at end of file diff --git a/includes/model/AngelType_model.php b/includes/model/AngelType_model.php index 49d1c702..22baa4a4 100644 --- a/includes/model/AngelType_model.php +++ b/includes/model/AngelType_model.php @@ -1,29 +1,107 @@ -<?php
-
-/**
- * Returns AngelType id array
- */
-function mAngelTypeList() {
- $angelType_source = sql_select("SELECT `id` FROM `AngelTypes`");
- if ($angelType_source === false)
- return false;
- if (count($angelType_source) > 0)
- return $angelType_source;
- return null;
-}
-
-/**
- * Returns angelType by id.
- *
- * @param $id angelType ID
- */
-function mAngelType($id) {
- $angelType_source = sql_select("SELECT * FROM `AngelTypes` WHERE `id`=" . sql_escape($id) . " LIMIT 1");
- if ($angelType_source === false)
- return false;
- if (count($angelType_source) > 0)
- return $angelType_source[0];
- return null;
-}
-
+<?php + +function AngelType_delete($angeltype) { + sql_query("DELETE FROM `NeededAngelTypes` WHERE `angel_type_id`=" . sql_escape($angeltype['id']) . " LIMIT 1"); + sql_query("DELETE FROM `ShiftEntry` WHERE `TID`=" . sql_escape($angeltype['id']) . " LIMIT 1"); + sql_query("DELETE FROM `UserAngelTypes` WHERE `angeltype_id`=" . sql_escape($angeltype['id']) . " LIMIT 1"); + return sql_query("DELETE FROM `AngelTypes` WHERE `id`=" . sql_escape($angeltype['id']) . " LIMIT 1"); +} + +function AngelType_update($angeltype_id, $name, $restricted) { + return sql_query(" + UPDATE `AngelTypes` SET + `name`='" . sql_escape($name) . "', + `restricted`=" . sql_escape($restricted) . " + WHERE `id`=" . sql_escape($angeltype_id) . " + LIMIT 1"); +} + +function AngelType_create($name, $restricted) { + $result = sql_query(" + INSERT INTO `AngelTypes` SET + `name`='" . sql_escape($name) . "', + `restricted`=" . sql_escape($restricted)); + if ($result === false) + return false; + return sql_id(); +} + +/** + * Validates a name for angeltypes. + * Returns array containing validation success and validated name. + * + * @param string $name + * @param AngelType $angeltype + */ +function AngelType_validate_name($name, $angeltype) { + $name = strip_item($name); + if ($name == "") + return array( + false, + $name + ); + if (isset($angeltype) && isset($angeltype['id'])) + return array( + sql_num_query(" + SELECT * + FROM `AngelTypes` + WHERE `name`='" . sql_escape($name) . "' + AND NOT `id`=" . sql_escape($angeltype['id']) . " + LIMIT 1") == 0, + $name + ); + else + return array( + sql_num_query(" + SELECT `id` + FROM `AngelTypes` + WHERE `name`='" . sql_escape($name) . "' + LIMIT 1") == 0, + $name + ); +} + +/** + * Returns all angeltypes and subscription state to each of them for given user. + * + * @param User $user + */ +function AngelTypes_with_user($user) { + return sql_select(" + SELECT `AngelTypes`.*, + `UserAngelTypes`.`id` as `user_angeltype_id`, + `UserAngelTypes`.`confirm_user_id` + FROM `AngelTypes` + LEFT JOIN `UserAngelTypes` ON `AngelTypes`.`id`=`UserAngelTypes`.`angeltype_id` + AND `UserAngelTypes`.`user_id`=" . $user['UID'] . " + ORDER BY `name`"); +} + +/** + * Returns AngelType id array + */ +function mAngelTypeList() { + $angelType_source = sql_select("SELECT `id` FROM `AngelTypes`"); + if ($angelType_source === false) + return false; + if (count($angelType_source) > 0) + return $angelType_source; + return null; +} + +/** + * Returns angelType by id. + * + * @param $id angelType + * ID + */ +function mAngelType($id) { + $angelType_source = sql_select("SELECT * FROM `AngelTypes` WHERE `id`=" . sql_escape($id) . " LIMIT 1"); + if ($angelType_source === false) + return false; + if (count($angelType_source) > 0) + return $angelType_source[0]; + return null; +} + ?>
\ No newline at end of file diff --git a/includes/model/UserAngelTypes_model.php b/includes/model/UserAngelTypes_model.php new file mode 100644 index 00000000..e931e04b --- /dev/null +++ b/includes/model/UserAngelTypes_model.php @@ -0,0 +1,69 @@ +<?php + +function UserAngelTypes_delete_all($angeltype_id) { + return sql_query(" + DELETE FROM `UserAngelTypes` + WHERE `angeltype_id`=" . sql_escape($angeltype_id) . " + AND `confirm_user_id` IS NULL"); +} + +function UserAngelTypes_confirm_all($angeltype_id, $confirm_user) { + return sql_query(" + UPDATE `UserAngelTypes` + SET `confirm_user_id`=" . sql_escape($confirm_user['UID']) . " + WHERE `angeltype_id`=" . sql_escape($angeltype_id) . " + AND `confirm_user_id` IS NULL"); +} + +function UserAngelType_confirm($user_angeltype_id, $confirm_user) { + return sql_query(" + UPDATE `UserAngelTypes` + SET `confirm_user_id`=" . sql_escape($confirm_user['UID']) . " + WHERE `id`=" . sql_escape($user_angeltype_id) . " + LIMIT 1"); +} + +function UserAngelType_delete($user_angeltype) { + return sql_query(" + DELETE FROM `UserAngelTypes` + WHERE `id`=" . sql_escape($user_angeltype['id']) . " + LIMIT 1"); +} + +function UserAngelType_create($user, $angeltype) { + $result = sql_query(" + INSERT INTO `UserAngelTypes` SET + `user_id`=" . sql_escape($user['UID']) . ", + `angeltype_id`=" . sql_escape($angeltype['id'])); + if ($result === false) + return false; + return sql_id(); +} + +function UserAngelType($user_angeltype_id) { + $angeltype = sql_select(" + SELECT * + FROM `UserAngelTypes` + WHERE `id`=" . sql_escape($user_angeltype_id) . " + LIMIT 1"); + if ($angeltype === false) + return false; + if (count($angeltype) == 0) + return null; + return $angeltype[0]; +} + +function UserAngelType_by_User_and_AngelType($user, $angeltype) { + $angeltype = sql_select(" + SELECT * + FROM `UserAngelTypes` + WHERE `user_id`=" . sql_escape($user['UID']) . " + AND `angeltype_id`=" . sql_escape($angeltype['id']) . " + LIMIT 1"); + if ($angeltype === false) + return false; + if (count($angeltype) == 0) + return null; + return $angeltype[0]; +} +?>
\ No newline at end of file diff --git a/includes/model/User_model.php b/includes/model/User_model.php index 6b23f74b..84097333 100644 --- a/includes/model/User_model.php +++ b/includes/model/User_model.php @@ -1,6 +1,19 @@ <?php /** + * Returns all members of given angeltype. + * @param Angeltype $angeltype + */ +function Users_by_angeltype($angeltype) { + return sql_select(" + SELECT `User`.*, `UserAngelTypes`.`id` as `user_angeltype_id`, `UserAngelTypes`.`confirm_user_id` + FROM `User` + JOIN `UserAngelTypes` ON `User`.`UID`=`UserAngelTypes`.`user_id` + WHERE `UserAngelTypes`.`angeltype_id`=" . sql_escape($angeltype['id']) . " + ORDER BY `Nick`"); +} + +/** * Returns User id array */ function mUserList() { @@ -14,7 +27,8 @@ function mUserList() { /** * Strip unwanted characters from a users nick. - * @param string $nick + * + * @param string $nick */ function User_validate_Nick($nick) { return preg_replace("/([^a-z0-9üöäß. _+*-]{1,})/ui", '', $nick); @@ -23,7 +37,7 @@ function User_validate_Nick($nick) { /** * Returns user by id. * - * @param $id UID + * @param $id UID */ function User($id) { $user_source = sql_select("SELECT * FROM `User` WHERE `UID`=" . sql_escape($id) . " LIMIT 1"); @@ -37,7 +51,7 @@ function User($id) { /** * Returns user by id (limit informations. * - * @param $id UID + * @param $id UID */ function mUser_Limit($id) { $user_source = sql_select("SELECT `UID`, `Nick`, `Name`, `Vorname`, `Telefon`, `DECT`, `Handy`, `email`, `ICQ`, `jabber`, `Avatar` FROM `User` WHERE `UID`=" . sql_escape($id) . " LIMIT 1"); diff --git a/includes/pages/admin_angel_types.php b/includes/pages/admin_angel_types.php deleted file mode 100644 index e329604f..00000000 --- a/includes/pages/admin_angel_types.php +++ /dev/null @@ -1,116 +0,0 @@ -<?php -function admin_angel_types_title() { - return _("Angeltypes"); -} - -function admin_angel_types() { - $angel_types_source = sql_select("SELECT * FROM `AngelTypes` ORDER BY `name`"); - $angel_types = array (); - foreach ($angel_types_source as $angel_type) { - $angel_types[] = array ( - 'id' => $angel_type['id'], - 'name' => $angel_type['name'], - 'restricted' => $angel_type['restricted'] == 1 ? '✓' : '', - 'actions' => '<a class="action edit" href="' . page_link_to('admin_angel_types') . '&show=edit&id=' . $angel_type['id'] . '">edit</a> <a class="action delete" href="' . page_link_to('admin_angel_types') . '&show=delete&id=' . $angel_type['id'] . '">delete</a>' - ); - } - - if (isset ($_REQUEST['show'])) { - $msg = ""; - $name = ""; - $restricted = 0; - - if (test_request_int('id')) { - $angel_type = sql_select("SELECT * FROM `AngelTypes` WHERE `id`=" . sql_escape($_REQUEST['id'])); - if (count($angel_type) > 0) { - $id = $_REQUEST['id']; - $name = $angel_type[0]['name']; - $restricted = $angel_type[0]['restricted']; - } else - redirect(page_link_to('admin_angel_types')); - } - - if ($_REQUEST['show'] == 'edit') { - if (isset ($_REQUEST['submit'])) { - $ok = true; - - if (isset ($_REQUEST['name']) && strlen(strip_request_item('name')) > 0) { - $name = strip_request_item('name'); - if (sql_num_query("SELECT * FROM `AngelTypes` WHERE NOT `id`=" . sql_escape(isset ($id) ? $id : 0) . " AND `name`='" . sql_escape(strip_request_item('name')) . "' LIMIT 1") > 0) { - $ok = false; - $msg .= error("This angel type name is already given.", true); - } - } else { - $ok = false; - $msg .= error("Please enter a name.", true); - } - - if (isset ($_REQUEST['restricted'])) - $restricted = 1; - else - $restricted = 0; - - if ($ok) { - if (isset ($id)) { - sql_query("UPDATE `AngelTypes` SET `name`='" . sql_escape($name) . "', `restricted`=" . sql_escape($restricted) . " WHERE `id`=" . sql_escape($id) . " LIMIT 1"); - engelsystem_log("Updated angeltype: " . $name . ", restricted: " . $restricted); - } else { - sql_query("INSERT INTO `AngelTypes` SET `name`='" . sql_escape($name) . "', `restricted`=" . sql_escape($restricted)); - engelsystem_log("Created angeltype: " . $name . ", restricted: " . $restricted); - } - - success("Angel type saved."); - redirect(page_link_to('admin_angel_types')); - } - } - - return page(array ( - buttons(array ( - button(page_link_to('admin_angel_types'), "Back", 'back') - )), - $msg, - form(array ( - form_text('name', 'Name', $name), - form_checkbox('restricted', 'Restricted', $restricted), - form_info("", "Restricted angel types can only be used by an angel if enabled by an archangel (double opt-in)."), - form_submit('submit', 'Save') - )) - )); - } - elseif ($_REQUEST['show'] == 'delete') { - if (isset ($_REQUEST['ack'])) { - sql_query("DELETE FROM `NeededAngelTypes` WHERE `angel_type_id`=" . sql_escape($id) . " LIMIT 1"); - sql_query("DELETE FROM `ShiftEntry` WHERE `TID`=" . sql_escape($id) . " LIMIT 1"); - sql_query("DELETE FROM `AngelTypes` WHERE `id`=" . sql_escape($id) . " LIMIT 1"); - sql_query("DELETE FROM `UserAngelTypes` WHERE `angeltype_id`=" . sql_escape($id) . " LIMIT 1"); - engelsystem_log("Deleted angel type: " . $name); - success(sprintf("Angel type %s deleted.", $name)); - redirect(page_link_to('admin_angel_types')); - } - - return page(array ( - buttons(array ( - button(page_link_to('admin_angel_types'), "Back", 'cancel') - )), - sprintf("Do you want to delete angel type %s?", $name), - buttons(array ( - button(page_link_to('admin_angel_types') . '&show=delete&id=' . $id . '&ack', "Delete", 'ok') - )) - )); - } else - redirect(page_link_to('admin_angel_types')); - } - - return page(array ( - buttons(array ( - button(page_link_to('admin_angel_types') . '&show=edit', "Add", 'add') - )), - msg(), - table(array ( - 'name' => "Name", - 'restricted' => "Restricted", - 'actions' => "" - ), $angel_types) - )); -} -?> diff --git a/includes/pages/admin_user_angeltypes.php b/includes/pages/admin_user_angeltypes.php index 9377dc20..2b623d72 100644 --- a/includes/pages/admin_user_angeltypes.php +++ b/includes/pages/admin_user_angeltypes.php @@ -97,18 +97,4 @@ function admin_user_angeltypes() { )); } -/** - * Anzeige, ob noch Engeltypen bestätigt werden müssen. Damit werden Erzengel auf jeder Seite im Kopfbereich "genervt", wenn zu ihren Aufgaben noch Engel bestätigt werden müssen. - */ -function admin_new_user_angeltypes() { - global $user, $privileges; - - if (in_array("admin_user_angeltypes", $privileges)) { - $unconfirmed_angeltypes = sql_num_query("SELECT * FROM `UserAngelTypes` JOIN `AngelTypes` ON `UserAngelTypes`.`angeltype_id`=`AngelTypes`.`id` WHERE `UserAngelTypes`.`angeltype_id` IN (SELECT `angeltype_id` FROM `UserAngelTypes` WHERE `user_id`=" . sql_escape($user['UID']) . ") AND `AngelTypes`.`restricted`=1 AND `UserAngelTypes`.`confirm_user_id` IS NULL LIMIT 1") > 0; - - if ($unconfirmed_angeltypes) - return info('<a href="' . page_link_to('admin_user_angeltypes') . '">' . _("There are unconfirmed angeltypes!") . '</a>', true); - } - return ""; -} ?> diff --git a/includes/sys_menu.php b/includes/sys_menu.php index d4620753..ae39afeb 100644 --- a/includes/sys_menu.php +++ b/includes/sys_menu.php @@ -44,6 +44,7 @@ function make_navigation() { "user_meetings" => meetings_title(), "user_myshifts" => myshifts_title(), "user_shifts" => shifts_title(), + "angeltypes" => angeltypes_title(), "user_messages" => messages_title(), "user_questions" => questions_title(), "user_wakeup" => wakeup_title(), @@ -52,7 +53,6 @@ function make_navigation() { "admin_user" => admin_user_title(), "admin_free" => admin_free_title(), "admin_questions" => admin_questions_title(), - "admin_angel_types" => admin_angel_types_title(), "admin_user_angeltypes" => admin_user_angeltypes_title(), "admin_shifts" => admin_shifts_title(), "admin_rooms" => admin_rooms_title(), diff --git a/includes/view/AngelTypes_view.php b/includes/view/AngelTypes_view.php new file mode 100644 index 00000000..f0ab0e42 --- /dev/null +++ b/includes/view/AngelTypes_view.php @@ -0,0 +1,115 @@ +<?php + +function AngelType_delete_view($angeltype) { + return page(array( + info(sprintf(_("Do you want to delete angeltype %s?"), $angeltype['name']), true), + buttons(array( + button(page_link_to('angeltypes'), _("cancel"), 'cancel'), + button(page_link_to('angeltypes') . '&action=delete&angeltype_id=' . $angeltype['id'] . '&confirmed', _("delete"), 'ok') + )) + )); +} + +function AngelType_edit_view($name, $restricted) { + return page(array( + buttons(array( + button(page_link_to('angeltypes'), _("Angeltypes"), 'back') + )), + msg(), + form(array( + form_text('name', _("Name"), $name), + form_checkbox('restricted', _("Restricted"), $restricted), + form_info("", _("Restricted angel types can only be used by an angel if enabled by an archangel (double opt-in).")), + form_submit('submit', _("Save")) + )) + )); +} + +function AngelType_view($angeltype, $members, $user_angeltype, $admin_user_angeltypes, $admin_angeltypes) { + $buttons = array( + button(page_link_to('angeltypes'), _("Angeltypes"), 'back') + ); + + if ($user_angeltype == null) + $buttons[] = button(page_link_to('user_angeltypes') . '&action=add&angeltype_id=' . $angeltype['id'], _("join"), 'add'); + else { + if ($angeltype['restricted'] && $user_angeltype['confirm_user_id'] == null) + error(sprintf(_("You are unconfirmed for this angeltype. Please go to the introduction for %s to get confirmed."), $angeltype['name'])); + $buttons[] = button(page_link_to('user_angeltypes') . '&action=delete&user_angeltype_id=' . $user_angeltype['id'], _("leave"), 'cancel'); + } + + if ($admin_angeltypes) { + $buttons[] = button(page_link_to('angeltypes') . '&action=edit&angeltype_id=' . $angeltype['id'], _("edit"), 'edit'); + $buttons[] = button(page_link_to('angeltypes') . '&action=delete&angeltype_id=' . $angeltype['id'], _("delete"), 'delete'); + } + + $page = array( + msg(), + buttons($buttons) + ); + + // $page[] = '<h3>' . _("Info") . '</h3>'; + // Description + Team-Coordinators + + $page[] = '<h3>' . _("Members") . '</h3>'; + $members_confirmed = array(); + $members_unconfirmed = array(); + foreach ($members as $member) { + $member['Nick'] = User_Nick_render($member); + if ($angeltype['restricted'] && $member['confirm_user_id'] == null) { + $member['actions'] = join(" ", array( + '<a href="' . page_link_to('user_angeltypes') . '&action=confirm&user_angeltype_id=' . $member['user_angeltype_id'] . '" class="ok">' . ("confirm") . '</a>', + '<a href="' . page_link_to('user_angeltypes') . '&action=delete&user_angeltype_id=' . $member['user_angeltype_id'] . '" class="cancel">' . ("deny") . '</a>' + )); + $members_unconfirmed[] = $member; + } else { + if ($admin_user_angeltypes) + $member['actions'] = join(" ", array( + '<a href="' . page_link_to('user_angeltypes') . '&action=delete&user_angeltype_id=' . $member['user_angeltype_id'] . '" class="cancel">' . ("remove") . '</a>' + )); + $members_confirmed[] = $member; + } + } + $page[] = table(array( + 'Nick' => _("Nick"), + 'DECT' => _("DECT"), + 'actions' => "" + ), $members_confirmed); + + if ($admin_user_angeltypes && $angeltype['restricted'] && count($members_unconfirmed) > 0) { + $page[] = '<h3>' . _("Unconfirmed") . '</h3>'; + $page[] = buttons(array( + button(page_link_to('user_angeltypes') . '&action=confirm_all&angeltype_id=' . $angeltype['id'], _("confirm all"), 'ok'), + button(page_link_to('user_angeltypes') . '&action=delete_all&angeltype_id=' . $angeltype['id'], _("deny all"), 'cancel') + )); + $page[] = table(array( + 'Nick' => _("Nick"), + 'DECT' => _("DECT"), + 'actions' => "" + ), $members_unconfirmed); + } + + return page($page); +} + +/** + * Display the list of angeltypes. + * + * @param array $angeltypes + */ +function AngelTypes_list_view($angeltypes, $admin_angeltypes) { + return page(array( + msg(), + $admin_angeltypes ? buttons(array( + button(page_link_to('angeltypes') . '&action=edit', _("New angeltype"), 'add') + )) : '', + table(array( + 'name' => _("Name"), + 'restricted' => '<img src="pic/icons/lock.png" alt="' . _("Restricted") . '" title="' . _("Restricted") . '" />', + 'membership' => _("Membership"), + 'actions' => "" + ), $angeltypes) + )); +} + +?>
\ No newline at end of file diff --git a/includes/view/UserAngelTypes_view.php b/includes/view/UserAngelTypes_view.php new file mode 100644 index 00000000..ed825c04 --- /dev/null +++ b/includes/view/UserAngelTypes_view.php @@ -0,0 +1,58 @@ +<?php + +function UserAngelTypes_delete_all_view($angeltype) { + return page(array( + msg(), + info(sprintf(_("Do you really want to deny all users for %s?"), $angeltype['name']), true), + buttons(array( + button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], _("cancel"), 'cancel'), + button(page_link_to('user_angeltypes') . '&action=delete_all&angeltype_id=' . $angeltype['id'] . '&confirmed', _("yes"), 'ok') + )) + )); +} + +function UserAngelTypes_confirm_all_view($angeltype) { + return page(array( + msg(), + info(sprintf(_("Do you really want to confirm all users for %s?"), $angeltype['name']), true), + buttons(array( + button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], _("cancel"), 'cancel'), + button(page_link_to('user_angeltypes') . '&action=confirm_all&angeltype_id=' . $angeltype['id'] . '&confirmed', _("yes"), 'ok') + )) + )); +} + +function UserAngelType_confirm_view($user_angeltype, $user, $angeltype) { + return page(array( + msg(), + info(sprintf(_("Do you really want to confirm %s for %s?"), User_Nick_render($user), $angeltype['name']), true), + buttons(array( + button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], _("cancel"), 'cancel'), + button(page_link_to('user_angeltypes') . '&action=confirm&user_angeltype_id=' . $user_angeltype['id'] . '&confirmed', _("yes"), 'ok') + )) + )); +} + +function UserAngelType_delete_view($user_angeltype, $user, $angeltype) { + return page(array( + msg(), + info(sprintf(_("Do you really want to delete %s from %s?"), User_Nick_render($user), $angeltype['name']), true), + buttons(array( + button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], _("cancel"), 'cancel'), + button(page_link_to('user_angeltypes') . '&action=delete&user_angeltype_id=' . $user_angeltype['id'] . '&confirmed', _("yes"), 'ok') + )) + )); +} + +function UserAngelType_add_view($user, $angeltype) { + return page(array( + msg(), + info(sprintf(_("Do you really want to add %s to %s?"), User_Nick_render($user), $angeltype['name']), true), + buttons(array( + button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], _("cancel"), 'cancel'), + button(page_link_to('user_angeltypes') . '&action=add&angeltype_id=' . $angeltype['id'] . '&user_id=' . $user['UID'] . '&confirmed', _("save"), 'ok') + )) + )); +} + +?>
\ No newline at end of file diff --git a/public/css/base.css b/public/css/base.css index 2f5aa18c..89fa62a5 100644 --- a/public/css/base.css +++ b/public/css/base.css @@ -357,8 +357,13 @@ tr:hover .hidden { margin: 0 0 10px 0; } +.actions a { + background: 2px 1px no-repeat; + padding-right: 5px; +} + a.button { - background: #f0f0f0; + background: #f0f0f0 2px 2px no-repeat; border: 1px solid #888; border-radius: 4px; line-height: 25px; @@ -374,26 +379,36 @@ a.button { .button:hover, .toolbar .button:hover { color: #000; - background: #fff; + background-color: #fff; } -.button.add { - background: url('../pic/icons/add.png') 2px 2px no-repeat; +.button.add, .actions .add { + background-image: url('../pic/icons/add.png'); padding-left: 20px; } -.button.edit { - background: url('../pic/icons/pencil.png') 2px 2px no-repeat; +.button.edit, .actions .edit { + background-image: url('../pic/icons/pencil.png'); padding-left: 20px; } -.button.ok { - background: url('../pic/icons/tick.png') 2px 2px no-repeat; +.button.ok, .actions .ok { + background-image: url('../pic/icons/tick.png'); + padding-left: 20px; +} + +.button.cancel, .actions .cancel { + background-image: url('../pic/icons/cross.png'); + padding-left: 20px; +} + +.button.delete, .actions .delete { + background-image: url('../pic/icons/bin.png'); padding-left: 20px; } -.button.cancel { - background: url('../pic/icons/cross.png') 2px 2px no-repeat; +.button.back, .actions .back { + background-image: url('../pic/icons/arrow_left.png'); padding-left: 20px; } diff --git a/public/index.php b/public/index.php index 24d92b9d..9cd01e40 100644 --- a/public/index.php +++ b/public/index.php @@ -10,20 +10,26 @@ require_once ('includes/sys_menu.php'); require_once ('includes/sys_page.php'); require_once ('includes/sys_template.php'); +require_once ('includes/model/AngelType_model.php'); require_once ('includes/model/LogEntries_model.php'); +require_once ('includes/model/Message_model.php'); require_once ('includes/model/NeededAngelTypes_model.php'); +require_once ('includes/model/Room_model.php'); require_once ('includes/model/ShiftEntry_model.php'); require_once ('includes/model/Shifts_model.php'); +require_once ('includes/model/UserAngelTypes_model.php'); require_once ('includes/model/User_model.php'); -require_once ('includes/model/Room_model.php'); -require_once ('includes/model/Message_model.php'); -require_once ('includes/model/AngelType_model.php'); +require_once ('includes/view/AngelTypes_view.php'); require_once ('includes/view/Questions_view.php'); require_once ('includes/view/Shifts_view.php'); require_once ('includes/view/ShiftEntry_view.php'); +require_once ('includes/view/UserAngelTypes_view.php'); require_once ('includes/view/User_view.php'); +require_once ('includes/controller/angeltypes_controller.php'); +require_once ('includes/controller/user_angeltypes_controller.php'); + require_once ('includes/helper/internationalization_helper.php'); require_once ('includes/helper/message_helper.php'); require_once ('includes/helper/error_helper.php'); @@ -34,7 +40,6 @@ if (file_exists('../config/config.php')) require_once ('config/config.php'); require_once ('includes/pages/admin_active.php'); -require_once ('includes/pages/admin_angel_types.php'); require_once ('includes/pages/admin_arrive.php'); require_once ('includes/pages/admin_free.php'); require_once ('includes/pages/admin_groups.php'); @@ -70,7 +75,8 @@ $free_pages = array( 'stats', 'shifts_json_export_all', 'user_password_recovery', - 'api' + 'api', + 'credits' ); // Gewünschte Seite/Funktion @@ -86,7 +92,7 @@ if (isset($_REQUEST['p']) && preg_match("/^[a-z0-9_]*$/i", $_REQUEST['p']) && (i require_once ('includes/controller/api.php'); error("Api disabled temporily."); redirect(page_link_to('login')); - //api_controller(); + // api_controller(); } elseif ($p == "ical") { require_once ('includes/pages/user_ical.php'); user_ical(); @@ -106,6 +112,10 @@ if (isset($_REQUEST['p']) && preg_match("/^[a-z0-9_]*$/i", $_REQUEST['p']) && (i require_once ('includes/controller/users_controller.php'); $title = user_password_recovery_title(); $content = user_password_recovery_controller(); + } elseif ($p == "angeltypes") { + list($title, $content) = angeltypes_controller(); + } elseif ($p == "user_angeltypes") { + list($title, $content) = user_angeltypes_controller(); } elseif ($p == "news") { $title = news_title(); $content = user_news(); @@ -164,9 +174,6 @@ if (isset($_REQUEST['p']) && preg_match("/^[a-z0-9_]*$/i", $_REQUEST['p']) && (i } elseif ($p == "admin_news") { require_once ('includes/pages/admin_news.php'); $content = admin_news(); - } elseif ($p == "admin_angel_types") { - $title = admin_angel_types_title(); - $content = admin_angel_types(); } elseif ($p == "admin_rooms") { $title = admin_rooms_title(); $content = admin_rooms(); @@ -206,10 +213,10 @@ if (isset($_REQUEST['p']) && preg_match("/^[a-z0-9_]*$/i", $_REQUEST['p']) && (i if (isset($user)) { $freeloaded_shifts_count = count(ShiftEntries_freeloaded_by_user($user)); - if($freeloaded_shifts_count >= $max_freeloadable_shifts) + if ($freeloaded_shifts_count >= $max_freeloadable_shifts) $content = error(sprintf(_("You freeloaded %s shifts. Shift signup is locked. Please go to heavens desk to be unlocked again."), $freeloaded_shifts_count), true) . $content; - - // Hinweis für ungelesene Nachrichten + + // Hinweis für ungelesene Nachrichten if ($p != "user_messages") $content = user_unread_messages() . $content; @@ -226,10 +233,6 @@ if (isset($user)) { // Erzengel Hinweis für unbeantwortete Fragen if ($p != "admin_questions") $content = admin_new_questions() . $content; - - // Erzengel Hinweis für freizuschaltende Engeltypen - if ($p != "admin_user_angeltypes") - $content = admin_new_user_angeltypes() . $content; } echo template_render('../templates/layout.html', array( diff --git a/public/pic/icons/arrow_left.png b/public/pic/icons/arrow_left.png Binary files differnew file mode 100755 index 00000000..5dc69678 --- /dev/null +++ b/public/pic/icons/arrow_left.png diff --git a/templates/guest_credits.html b/templates/guest_credits.html index b586c722..2b48c081 100644 --- a/templates/guest_credits.html +++ b/templates/guest_credits.html @@ -1,9 +1,9 @@ <h2>Source code</h2> -<p>The original system was written by <a href="https://github.com/cookieBerlin/engelsystem">cookie</a>. It was then completely rewritten and greatly enhanced by <a href="http://notrademark.de/">msquare</a> and <a href="http://helios.planetcyborg.de/">helios</a> of <a href="http://planetcyborg.de">planet cyborg</a> and <a href="http://jplitza.de/">jplitza</a>.</p> +<p>The original system was written by <a href="https://github.com/cookieBerlin/engelsystem">cookie</a>. It was then completely rewritten and greatly enhanced by <a href="http://notrademark.de/">msquare</a> and <a href="http://mortzu.de/">mortzu</a> of <a href="http://planetcyborg.de">planet cyborg</a> and <a href="http://jplitza.de/">jplitza</a>.</p> <h2>Hosting</h2> <p>Webspace, development platform and domain is currently provided by <a href="https://www.wybt.net/">would you buy this?</a> (ichdasich)<br /> -and adminstrated by <a href="http://helios.planetcyborg.de/">helios</a>, <a href="http://derf.homelinux.org/">derf</a> and ichdasich.</p> +and adminstrated by <a href="http://mortzu.de/">mortzu</a>, <a href="http://derf.homelinux.org/">derf</a> and ichdasich.</p> <h2>Icons</h2> <p>Some icons from the <a href="http://www.famfamfam.com/lab/icons/silk/">famfamfam.com silk iconset</a> have been used. They are licensed under the <a href="http://creativecommons.org/licenses/by/2.5/">Creative Commons Attribution 2.5 License</a>.</p> |