Merge pull request #365 from engelsystem/feature-igel-rewrite

Feature igel rewrite
This commit is contained in:
msquare 2017-11-28 15:43:51 +01:00 committed by GitHub
commit 599f2fd264
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
176 changed files with 18131 additions and 10837 deletions

8
.gitignore vendored
View File

@ -14,9 +14,15 @@ Thumbs.db
_vimrc_local.vim _vimrc_local.vim
.sass-cache .sass-cache
# PHPstorm config # PHPstorm files
/.idea/ /.idea/
/.phpstorm.meta.php
# Project files # Project files
/config/config.php /config/config.php
/test/coverage /test/coverage
/public/coverage
# Composer files
/vendor/
/composer.lock

91
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,91 @@
image: php
cache:
paths:
- .composer
services:
- mariadb:10.2
variables:
MYSQL_DATABASE: engelsystem
MYSQL_USER: engel
MYSQL_PASSWORD: engelsystem
MYSQL_HOST: mariadb
COMPOSER_HOME: .composer
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
before_script:
# Fix permissions after gitlab messed them up
- find . -type f -exec chmod 644 {} \;
- find . -type d -exec chmod 755 {} \;
# Install required Packages
- apt update -yqq
- apt install -yqq git unzip mariadb-client
- docker-php-ext-install pdo pdo_mysql gettext
# Install xdebug
- pecl install xdebug
- docker-php-ext-enable xdebug
# MySQL DB
- mysql -h "$MYSQL_HOST" -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE" < db/install.sql
- mysql -h "$MYSQL_HOST" -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE" < db/update.sql
# Install Composer
- curl -sS https://getcomposer.org/installer | php -- --no-ansi --install-dir /usr/local/bin/ --filename composer
- /usr/local/bin/composer --no-ansi install
.test_template: &test_definition
artifacts:
name: "${CI_JOB_NAME}_${CI_PROJECT_ID}_${PHP_VERSION}"
expire_in: 1 week
paths:
- ./coverage/
coverage: '/^\s*Lines:\s*(\d+(?:\.\d+)?%)/'
script: vendor/bin/phpunit --colors=never --coverage-text --coverage-html ./coverage/
test:7.0:
image: php:7.0
<<: *test_definition
test:7.1:
image: php:7.1
<<: *test_definition
deploy_staging:
stage: deploy
only:
- master
script:
- |-
if [ -z "${SSH_PRIVATE_KEY}" ] || [ -z "${REMOTE}" ] || [ -z "${REMOTE_PATH}" ]; then
echo "Skipping deployment";
exit
fi
- mkdir -p ~/.ssh
- echo "$SSH_PRIVATE_KEY" | sed -e 's/\r//g' > ~/.ssh/id_ed25519
- chmod 600 ~/.ssh/id_ed25519
- apt update && apt install -yqq rsync openssh-client
- /usr/local/bin/composer --no-ansi install --no-dev
- /usr/local/bin/composer --no-ansi dump-autoload --optimize
- echo "syncing ${PWD}/ to ${REMOTE}:${REMOTE_PATH}/${CI_JOB_ID}-${CI_COMMIT_SHA}/"
- |-
rsync -vAax --exclude '.git*' --exclude .composer/ \
-e "ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
./ "${REMOTE}:${REMOTE_PATH}/${CI_JOB_ID}-${CI_COMMIT_SHA}/"
- |-
ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${REMOTE}" "
set -e
if [[ -f \"${REMOTE_PATH}/current/config/config.php\" ]]; then
echo \"Config backup\"
cp \"${REMOTE_PATH}/current/config/config.php\" config.php
fi
echo \"Changing symlink\"
unlink \"${REMOTE_PATH}/current\"
ln -s \"${REMOTE_PATH}/${CI_JOB_ID}-${CI_COMMIT_SHA}\" \"${REMOTE_PATH}/current\"
if [[ -f config.php ]]; then
echo \"Restoring config\"
cp config.php \"${REMOTE_PATH}/current/config/config.php\"
fi
"

6
.gitmodules vendored
View File

@ -1,6 +0,0 @@
[submodule "vendor/parsedown"]
path = vendor/parsedown
url = https://github.com/erusev/parsedown.git
[submodule "vendor/bootstrap"]
path = themes/assets/bootstrap
url = https://github.com/twbs/bootstrap.git

View File

@ -1,25 +0,0 @@
# Installation of Engelsystem
## Requirements:
* PHP 5.4.x (cgi-fcgi)
* MySQL-Server 5.5.x
* Webserver, i.e. lighttpd, nginx, or Apache
## Directions:
* Clone the master branch with the submodules: `git clone --recursive https://github.com/engelsystem/engelsystem.git`
* Webserver must have write access to the 'import' directory and read access for all other directories
* Webserver must be public.
* Recommended: Directory Listing should be disabled.
* There must a be MySQL database created with a user who has full rights to that database.
* It must be created by the db/install.sql and db/update.sql files.
* If necessary, create a config/config.php to override values from config/config.default.php.
* In the browser, login with credentials admin:asdfasdf and change the password.
Engelsystem can now be used.
## Session Settings:
* Make sure the config allows for sessions.
* Both Apache and Nginx allow for different VirtualHost configurations.
Report Bugs: https://github.com/engelsystem/engelsystem/issues

View File

@ -1,28 +1,42 @@
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/20b3b0b4e93344a29da6bec77f329e7a)](https://www.codacy.com/app/engelsystem/engelsystem) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/20b3b0b4e93344a29da6bec77f329e7a)](https://www.codacy.com/app/engelsystem/engelsystem)
[![GPL](https://img.shields.io/github/license/engelsystem/engelsystem.svg?maxAge=2592000)]() [![GPL](https://img.shields.io/github/license/engelsystem/engelsystem.svg?maxAge=2592000)]()
# Installation eines frischen Engelsystems # Engelsystem
## Mindestvorrausetzungen (bzw. getestet unter): Please visit https://engelsystem.de for a feature list.
* PHP 5.4.x (cgi-fcgi)
* MySQL-Server 5.5.x
* Webserver mit PHP-Anbindung, z.B. lighttpd, nginx oder Apache
## Vorgehen: ## Installation
* Klonen des `master` inkl. submodules in lokales Verzeichnis: `git clone --recursive https://github.com/engelsystem/engelsystem.git`
* Der Webserver muss Schreibrechte auf das Verzeichnis `import` bekommen, für alle anderen Dateien reichen Leserechte.
* Der Webserver muss auf `public` als http-root zeigen.
* Empfehlung: Dirlisting sollte deaktiviert sein. ### Requirements:
* Es muss eine MySQL-Datenbank angelegt werden und ein User existieren, der alle Rechte auf dieser Datenbank besitzt. * PHP >= 7.0.0
* Es muss die db/install.sql und die db/update.sql importiert/ausgeführt werden. * MySQL-Server >= 5.5.x
* Erstelle bei Bedarf eine config/config.php, die die Werte (z.B. DB-Zugang) aus der config/config.default.php überschreibt. * Webserver, i.e. lighttpd, nginx, or Apache
* Engelsystem im Browser aufrufen, Anmeldung mit admin:asdfasdf vornehmen und Admin-Passwort ändern.
Das Engelsystem ist jetzt einsatzbereit. ### Directions:
* Clone the master branch: `git clone https://github.com/engelsystem/engelsystem.git`
* Install [Composer](https://getcomposer.org/download/)
* Install project dependencies: `composer install`
* Webserver must have write access to the 'import' directory and read access for all other directories
* Webserver must point to the public directory.
## Session Einstellungen: * Recommended: Directory Listing should be disabled.
* Einstellungen für Cookies und Sessions bitte in der PHP Config des Servers vornehmen. * There must a be MySQL database created with a user who has full rights to that database.
* Sowohl Apache als auch nginx bieten Möglichkeiten für verschiedene Konfigurationen pro VirtualHost an * It must be created by the db/install.sql and db/update.sql files.
* If necessary, create a config/config.php to override values from config/config.default.php.
* In the browser, login with credentials admin:asdfasdf and change the password.
Fehler bitte auf Github melden: https://github.com/engelsystem/engelsystem/issues Engelsystem can now be used.
### Session Settings:
* Make sure the config allows for sessions.
* Both Apache and Nginx allow for different VirtualHost configurations.
Report Bugs: https://github.com/engelsystem/engelsystem/issues
## Development
Since the engelsystem is open source, you can help to improve the system. We really love to get pull requests containing fixes or implementations of our Github issues.
Please create single pull requests for every feature instead of creating one big monster of pull request containing a complete rewrite.
### Codestyle
Please ensure that your pull requests follow [PSR-2](http://www.php-fig.org/psr/psr-2/) and [PSR-4](http://www.php-fig.org/psr/psr-4/).

38
composer.json Normal file
View File

@ -0,0 +1,38 @@
{
"name": "engelsystem/engelsystem",
"description": "Shift planning system for chaos events",
"type": "project",
"license": "GPL-2.0",
"authors": [
{
"name": "msquare",
"email": "msquare@notrademark.de"
},
{
"name": "MyIgel",
"email": "igor.scheller@igorshp.de"
}
],
"require": {
"php": ">=7.0.0",
"erusev/parsedown": "^1.6",
"illuminate/container": "5.5.*",
"psr/container": "^1.0",
"psr/log": "^1.0",
"symfony/http-foundation": "^3.3",
"twbs/bootstrap": "^3.3"
},
"require-dev": {
"filp/whoops": "^2.1",
"phpunit/phpunit": "^6.3",
"symfony/var-dumper": "^3.3"
},
"autoload": {
"psr-4": {
"Engelsystem\\": "src/"
},
"files": [
"src/helpers.php"
]
}
}

17
config/app.php Normal file
View File

@ -0,0 +1,17 @@
<?php
// Application config
return [
// Service providers
'providers' => [
\Engelsystem\Logger\LoggerServiceProvider::class,
\Engelsystem\Exceptions\ExceptionsServiceProvider::class,
\Engelsystem\Config\ConfigServiceProvider::class,
\Engelsystem\Routing\RoutingServiceProvider::class,
\Engelsystem\Renderer\RendererServiceProvider::class,
\Engelsystem\Database\DatabaseServiceProvider::class,
\Engelsystem\Http\RequestServiceProvider::class,
\Engelsystem\Http\SessionServiceProvider::class,
],
];

View File

@ -1,70 +1,125 @@
<?php <?php
// Enable maintenance mode (showin a static page) // To change settings create a config.php
$maintenance_mode = false;
// URL to the angel faq and job description return [
$faq_url = "https://events.ccc.de/congress/2013/wiki/Static:Volunteers"; // MySQL-Connection Settings
'database' => [
'host' => env('MYSQL_HOST', (env('CI', false) ? 'mariadb' : 'localhost')),
'user' => env('MYSQL_USER', 'root'),
'pw' => env('MYSQL_PASSWORD', ''),
'db' => env('MYSQL_DATABASE', 'engelsystem'),
],
// contact email address, linked on every page // For accessing stats
$contact_email = "mailto:ticket@c3heaven.de"; 'api_key' => '',
$no_reply_email = "noreply@engelsystem.de";
// Default-Theme auf der Startseite, 1=style1.css usw. // Enable maintenance mode (show a static page)
$default_theme = 1; 'maintenance' => false,
// Anzahl der News, die auf einer Seite ausgeben werden koennen... // Set to development to enable debugging messages
$DISPLAY_NEWS = 6; 'environment' => 'production',
// Anzahl Stunden bis zum Austragen eigener Schichten // URL to the angel faq and job description
$LETZTES_AUSTRAGEN = 3; 'faq_url' => 'https://events.ccc.de/congress/2013/wiki/Static:Volunteers',
// Setzt den zu verwendenden Crypto-Algorismus (entsprechend der Dokumentation von crypt()). // Contact email address, linked on every page
// Falls ein Benutzerpasswort in einem anderen Format gespeichert ist, 'contact_email' => 'mailto:ticket@c3heaven.de',
// wird es bei der ersten Benutzung des Klartext-Passworts in das neue Format
// konvertiert.
// $crypt_alg = '$1'; // MD5
// $crypt_alg = '$2y$13'; // Blowfish
// $crypt_alg = '$5$rounds=5000'; // SHA-256
$crypt_alg = '$6$rounds=5000'; // SHA-512
$min_password_length = 8; // From address of all emails
'no_reply_email' => 'noreply@engelsystem.de',
// Wenn Engel beim Registrieren oder in ihrem Profil eine T-Shirt Größe angeben sollen, auf true setzen: // Default theme, 1=style1.css
$enable_tshirt_size = true; 'theme' => 1,
// Number of shifts to freeload until angel is locked for shift signup. // Available themes
$max_freeloadable_shifts = 2; 'available_themes' => [
'4' => 'Engelsystem 33c3 (2016)',
'3' => 'Engelsystem 32c3 (2015)',
'2' => 'Engelsystem cccamp15',
'0' => 'Engelsystem light',
'1' => 'Engelsystem dark'
],
// local timezone // Number of News shown on one site
date_default_timezone_set("Europe/Berlin"); 'display_news' => 6,
// multiply "night shifts" and freeloaded shifts (start or end between 2 and 6 exclusive) by 2 // Users are able to sign up
$shift_sum_formula = "SUM( 'registration_enabled' => true,
(1+(
// Only arrived angels can sign up for shifts
'signup_requires_arrival' => false,
// Anzahl Stunden bis zum Austragen eigener Schichten
'last_unsubscribe' => 3,
// Setzt den zu verwendenden Crypto-Algorithmus (entsprechend der Dokumentation von crypt()).
// Falls ein Benutzerpasswort in einem anderen Format gespeichert ist,
// wird es bei der ersten Benutzung des Klartext-Passworts in das neue Format
// konvertiert.
// MD5 '$1'
// Blowfish '$2y$13'
// SHA-256 '$5$rounds=5000'
// SHA-512 '$6$rounds=5000'
'crypt_alg' => '$6$rounds=5000',
'min_password_length' => 8,
// Wenn Engel beim Registrieren oder in ihrem Profil eine T-Shirt Größe angeben sollen, auf true setzen:
'enable_tshirt_size' => true,
// Number of shifts to freeload until angel is locked for shift signup.
'max_freeloadable_shifts' => 2,
// local timezone
'timezone' => 'Europe/Berlin',
// weigh every shift the same
//'shift_sum_formula' => 'SUM(`end` - `start`)',
// Multiply 'night shifts' and freeloaded shifts (start or end between 2 and 6 exclusive) by 2
'shift_sum_formula' => '
SUM(
(1 +
(
(HOUR(FROM_UNIXTIME(`Shifts`.`end`)) > 2 AND HOUR(FROM_UNIXTIME(`Shifts`.`end`)) < 6) (HOUR(FROM_UNIXTIME(`Shifts`.`end`)) > 2 AND HOUR(FROM_UNIXTIME(`Shifts`.`end`)) < 6)
OR (HOUR(FROM_UNIXTIME(`Shifts`.`start`)) > 2 AND HOUR(FROM_UNIXTIME(`Shifts`.`start`)) < 6) OR (HOUR(FROM_UNIXTIME(`Shifts`.`start`)) > 2 AND HOUR(FROM_UNIXTIME(`Shifts`.`start`)) < 6)
OR (HOUR(FROM_UNIXTIME(`Shifts`.`start`)) <= 2 AND HOUR(FROM_UNIXTIME(`Shifts`.`end`)) >= 6) OR (HOUR(FROM_UNIXTIME(`Shifts`.`start`)) <= 2 AND HOUR(FROM_UNIXTIME(`Shifts`.`end`)) >= 6)
))*(`Shifts`.`end` - `Shifts`.`start`)*(1 - 3 * `ShiftEntry`.`freeloaded`) )
)"; )
* (`Shifts`.`end` - `Shifts`.`start`)
* (1 - 3 * `ShiftEntry`.`freeloaded`)
)
',
// voucher calculation // Voucher calculation
$voucher_settings = [ 'voucher_settings' => [
"initial_vouchers" => 2, 'initial_vouchers' => 2,
"shifts_per_voucher" => 1 'shifts_per_voucher' => 1,
],
// Available locales in /locale/
'locales' => [
'de_DE.UTF-8' => 'Deutsch',
'en_US.UTF-8' => 'English',
],
'default_locale' => 'en_US.UTF-8',
// Available T-Shirt sizes, set value to null if not available
'tshirt_sizes' => [
'' => _('Please select...'),
'S' => 'S',
'M' => 'M',
'L' => 'L',
'XL' => 'XL',
'2XL' => '2XL',
'3XL' => '3XL',
'4XL' => '4XL',
'5XL' => '5XL',
'S-G' => 'S Girl',
'M-G' => 'M Girl',
'L-G' => 'L Girl',
'XL-G' => 'XL Girl',
],
]; ];
// weigh every shift the same
// $shift_sum_formula = "SUM(`end` - `start`)";
// For accessing stats
$api_key = "";
// MySQL-Connection Settings
$config = [
'host' => "localhost",
'user' => "root",
'pw' => "",
'db' => "engelsystem"
];
?>

10
db/anonymize.sql Normal file
View File

@ -0,0 +1,10 @@
update User set Nick=concat('User',UID), Name=concat('Name',UID), Vorname=concat('Prename',UID), `Alter`=0, Telefon='', DECT='', Handy='', email=concat('engel', UID, '@engelsystem.de'), jabber='', Hometown='';
update Messages set Text=concat('Message', id);
update News set Betreff=concat('Subject', ID), Text=concat('News', ID);
update NewsComments set Text=concat('Comment', ID);
update Questions set Question=concat('Question', QID), Answer=concat('Answer', QID);
update ShiftEntry set Comment='', freeload_comment='';
update ShiftTypes set name=concat('Shifttype',id), description='Description';
update AngelTypes set name=concat('Angeltype',id), description=concat('Description of angeltype',id);
TRUNCATE TABLE LogEntries;

View File

@ -205,7 +205,7 @@ DROP TABLE IF EXISTS `NewsComments`;
CREATE TABLE `NewsComments` ( CREATE TABLE `NewsComments` (
`ID` bigint(11) NOT NULL, `ID` bigint(11) NOT NULL,
`Refid` int(11) NOT NULL DEFAULT '0', `Refid` int(11) NOT NULL DEFAULT '0',
`Datum` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `Datum` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
`Text` text NOT NULL, `Text` text NOT NULL,
`UID` int(11) NOT NULL DEFAULT '0' `UID` int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@ -395,7 +395,7 @@ CREATE TABLE `User` (
`Sprache` char(64) NOT NULL, `Sprache` char(64) NOT NULL,
`Menu` char(1) NOT NULL DEFAULT 'L', `Menu` char(1) NOT NULL DEFAULT 'L',
`lastLogIn` int(11) NOT NULL, `lastLogIn` int(11) NOT NULL,
`CreateDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `CreateDate` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
`Art` varchar(30) DEFAULT NULL, `Art` varchar(30) DEFAULT NULL,
`kommentar` text, `kommentar` text,
`Hometown` varchar(255) NOT NULL DEFAULT '', `Hometown` varchar(255) NOT NULL DEFAULT '',

View File

@ -17,10 +17,21 @@ ALTER TABLE `AngelTypes`
ALTER TABLE `AngelTypes` ALTER TABLE `AngelTypes`
ADD FOREIGN KEY (`contact_user_id`) REFERENCES `User`(`UID`) ON DELETE SET NULL ON UPDATE CASCADE; ADD FOREIGN KEY (`contact_user_id`) REFERENCES `User`(`UID`) ON DELETE SET NULL ON UPDATE CASCADE;
INSERT INTO `Privileges` (`id`, `name`, `desc`) VALUES (NULL, 'shiftentry_edit_angeltype_supporter', 'If user with this privilege is angeltype supporter, he can put users in shifts for their angeltype'); INSERT INTO `Privileges` (`id`, `name`, `desc`) VALUES (NULL, 'shiftentry_edit_angeltype_supporter', 'If user with this privilege is angeltype supporter, he can put users in shifts for their angeltype');
-- DB Performance -- DB Performance
ALTER TABLE `Shifts` ADD INDEX(`start`); ALTER TABLE `Shifts` ADD INDEX(`start`);
ALTER TABLE `NeededAngelTypes` ADD INDEX(`count`); ALTER TABLE `NeededAngelTypes` ADD INDEX(`count`);
-- Security
UPDATE `Groups` SET UID = UID * 10;
INSERT INTO `Groups` (Name, UID) VALUES ('News Admin', -65);
INSERT INTO `Privileges` (id, name, `desc`) VALUES (42, 'admin_news_html', 'Use HTML in news');
INSERT INTO `GroupPrivileges` (group_id, privilege_id) VALUES (-65, 14), (-65, 42);
-- Add log level to LogEntries
ALTER TABLE `LogEntries` CHANGE COLUMN `nick` `level` VARCHAR(20) NOT NULL;
-- Angeltype contact update
ALTER TABLE `AngelTypes` DROP FOREIGN KEY angeltypes_ibfk_1;
ALTER TABLE `AngelTypes` DROP `contact_user_id`;

9
includes/autoload.php Normal file
View File

@ -0,0 +1,9 @@
<?php
// Check for autoloader
if (!is_readable(__DIR__ . '/../vendor/autoload.php')) {
die('Please run composer.phar install');
}
// Include composer autoloader
$loader = require __DIR__ . '/../vendor/autoload.php';

View File

@ -1,22 +1,27 @@
<?php <?php
use Engelsystem\ShiftsFilter;
use Engelsystem\ShiftsFilterRenderer;
/** /**
* Text for Angeltype related links. * Text for Angeltype related links.
*
* @return string
*/ */
function angeltypes_title() { function angeltypes_title()
return _("Angeltypes"); {
return _('Angeltypes');
} }
/** /**
* Route angeltype actions. * Route angeltype actions.
*
* @return array
*/ */
function angeltypes_controller() { function angeltypes_controller()
{
$action = strip_request_item('action', 'list'); $action = strip_request_item('action', 'list');
switch ($action) { switch ($action) {
default:
case 'list':
return angeltypes_list_controller();
case 'view': case 'view':
return angeltype_controller(); return angeltype_controller();
case 'edit': case 'edit':
@ -25,22 +30,30 @@ function angeltypes_controller() {
return angeltype_delete_controller(); return angeltype_delete_controller();
case 'about': case 'about':
return angeltypes_about_controller(); return angeltypes_about_controller();
case 'list':
default:
return angeltypes_list_controller();
} }
} }
/** /**
* Path to angeltype view. * Path to angeltype view.
* *
* @param AngelType $angeltype_id * @param int $angeltype_id AngelType id
* @return string
*/ */
function angeltype_link($angeltype_id) { function angeltype_link($angeltype_id)
return page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype_id; {
return page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype_id]);
} }
/** /**
* Job description for all angeltypes (public to everyone) * Job description for all angeltypes (public to everyone)
*
* @return array
*/ */
function angeltypes_about_controller() { function angeltypes_about_controller()
{
global $user; global $user;
if (isset($user)) { if (isset($user)) {
@ -50,49 +63,56 @@ function angeltypes_about_controller() {
} }
return [ return [
_("Teams/Job description"), _('Teams/Job description'),
AngelTypes_about_view($angeltypes, isset($user)) AngelTypes_about_view($angeltypes, isset($user))
]; ];
} }
/** /**
* Delete an Angeltype. * Delete an Angeltype.
*
* @return array
*/ */
function angeltype_delete_controller() { function angeltype_delete_controller()
{
global $privileges; global $privileges;
if (! in_array('admin_angel_types', $privileges)) { if (!in_array('admin_angel_types', $privileges)) {
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$angeltype = load_angeltype(); $angeltype = load_angeltype();
if (isset($_REQUEST['confirmed'])) { if (request()->has('confirmed')) {
AngelType_delete($angeltype); AngelType_delete($angeltype);
success(sprintf(_("Angeltype %s deleted."), AngelType_name_render($angeltype))); success(sprintf(_('Angeltype %s deleted.'), AngelType_name_render($angeltype)));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
return [ return [
sprintf(_("Delete angeltype %s"), $angeltype['name']), sprintf(_('Delete angeltype %s'), $angeltype['name']),
AngelType_delete_view($angeltype) AngelType_delete_view($angeltype)
]; ];
} }
/** /**
* Change an Angeltype. * Change an Angeltype.
*
* @return array
*/ */
function angeltype_edit_controller() { function angeltype_edit_controller()
{
global $privileges, $user; global $privileges, $user;
// In supporter mode only allow to modify description // In supporter mode only allow to modify description
$supporter_mode = ! in_array('admin_angel_types', $privileges); $supporter_mode = !in_array('admin_angel_types', $privileges);
$request = request();
if (isset($_REQUEST['angeltype_id'])) { if ($request->has('angeltype_id')) {
// Edit existing angeltype // Edit existing angeltype
$angeltype = load_angeltype(); $angeltype = load_angeltype();
if (! User_is_AngelType_supporter($user, $angeltype)) { if (!User_is_AngelType_supporter($user, $angeltype)) {
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
} else { } else {
@ -104,27 +124,31 @@ function angeltype_edit_controller() {
$angeltype = AngelType_new(); $angeltype = AngelType_new();
} }
if (isset($_REQUEST['submit'])) { if ($request->has('submit')) {
$valid = true; $valid = true;
if (! $supporter_mode) { if (!$supporter_mode) {
if (isset($_REQUEST['name'])) { if ($request->has('name')) {
$result = AngelType_validate_name($_REQUEST['name'], $angeltype); $result = AngelType_validate_name($request->postData('name'), $angeltype);
$angeltype['name'] = $result->getValue(); $angeltype['name'] = $result->getValue();
if (! $result->isValid()) { if (!$result->isValid()) {
$valid = false; $valid = false;
error(_("Please check the name. Maybe it already exists.")); error(_('Please check the name. Maybe it already exists.'));
} }
} }
$angeltype['restricted'] = isset($_REQUEST['restricted']); $angeltype['restricted'] = $request->has('restricted');
$angeltype['no_self_signup'] = isset($_REQUEST['no_self_signup']); $angeltype['no_self_signup'] = $request->has('no_self_signup');
$angeltype['requires_driver_license'] = isset($_REQUEST['requires_driver_license']); $angeltype['requires_driver_license'] = $request->has('requires_driver_license');
} }
$angeltype['description'] = strip_request_item_nl('description', $angeltype['description']); $angeltype['description'] = strip_request_item_nl('description', $angeltype['description']);
$angeltype['contact_name'] = strip_request_item('contact_name', $angeltype['contact_name']);
$angeltype['contact_dect'] = strip_request_item('contact_dect', $angeltype['contact_dect']);
$angeltype['contact_email'] = strip_request_item('contact_email', $angeltype['contact_email']);
if ($valid) { if ($valid) {
if ($angeltype['id'] != null) { if ($angeltype['id'] != null) {
AngelType_update($angeltype); AngelType_update($angeltype);
@ -132,25 +156,28 @@ function angeltype_edit_controller() {
$angeltype = AngelType_create($angeltype); $angeltype = AngelType_create($angeltype);
} }
success("Angel type saved."); success('Angel type saved.');
redirect(angeltype_link($angeltype['id'])); redirect(angeltype_link($angeltype['id']));
} }
} }
return [ return [
sprintf(_("Edit %s"), $angeltype['name']), sprintf(_('Edit %s'), $angeltype['name']),
AngelType_edit_view($angeltype, $supporter_mode) AngelType_edit_view($angeltype, $supporter_mode)
]; ];
} }
/** /**
* View details of a given angeltype. * View details of a given angeltype.
*
* @return array
*/ */
function angeltype_controller() { function angeltype_controller()
{
global $privileges, $user; global $privileges, $user;
if (! in_array('angeltypes', $privileges)) { if (!in_array('angeltypes', $privileges)) {
redirect('?'); redirect(page_link_to('/'));
} }
$angeltype = load_angeltype(); $angeltype = load_angeltype();
@ -158,45 +185,146 @@ function angeltype_controller() {
$user_driver_license = UserDriverLicense($user['UID']); $user_driver_license = UserDriverLicense($user['UID']);
$members = Users_by_angeltype($angeltype); $members = Users_by_angeltype($angeltype);
$days = angeltype_controller_shiftsFilterDays($angeltype);
$shiftsFilter = angeltype_controller_shiftsFilter($angeltype, $days);
$shiftsFilterRenderer = new ShiftsFilterRenderer($shiftsFilter);
$shiftsFilterRenderer->enableDaySelection($days);
$shiftCalendarRenderer = shiftCalendarRendererByShiftFilter($shiftsFilter);
$request = request();
$tab = 0;
if($request->has('shifts_filter_day')) {
$tab = 1;
}
return [ return [
sprintf(_("Team %s"), $angeltype['name']), sprintf(_('Team %s'), $angeltype['name']),
AngelType_view($angeltype, $members, $user_angeltype, in_array('admin_user_angeltypes', $privileges) || $user_angeltype['supporter'], in_array('admin_angel_types', $privileges), $user_angeltype['supporter'], $user_driver_license, $user) AngelType_view(
$angeltype,
$members,
$user_angeltype,
in_array('admin_user_angeltypes', $privileges) || $user_angeltype['supporter'],
in_array('admin_angel_types', $privileges),
$user_angeltype['supporter'],
$user_driver_license,
$user,
$shiftsFilterRenderer,
$shiftCalendarRenderer,
$tab
)
]; ];
} }
/** /**
* View a list of all angeltypes. * On which days do shifts for this angeltype occur? Needed for shiftCalendar.
*
* @param Angeltype $angeltype
* @return array
*/ */
function angeltypes_list_controller() { function angeltype_controller_shiftsFilterDays($angeltype) {
$all_shifts = Shifts_by_angeltype($angeltype);
$days = [];
foreach ($all_shifts as $shift) {
$day = date('Y-m-d', $shift['start']);
if (!in_array($day, $days)) {
$days[] = $day;
}
}
return $days;
}
/**
* Sets up the shift filter for the angeltype.
*
* @param Angeltype $angeltype
* @param array $days
* @return ShiftsFilter
*/
function angeltype_controller_shiftsFilter($angeltype, $days) {
global $privileges;
$request = request();
$shiftsFilter = new ShiftsFilter(
in_array('user_shifts_admin', $privileges),
Room_ids(),
[$angeltype['id']]
);
$selected_day = date('Y-m-d');
if (!empty($days)) {
$selected_day = $days[0];
}
if ($request->has('shifts_filter_day')) {
$selected_day = $request->input('shifts_filter_day');
}
$shiftsFilter->setStartTime(parse_date('Y-m-d H:i', $selected_day . ' 00:00'));
$shiftsFilter->setEndTime(parse_date('Y-m-d H:i', $selected_day . ' 23:59'));
return $shiftsFilter;
}
/**
* View a list of all angeltypes.
*
* @return array
*/
function angeltypes_list_controller()
{
global $privileges, $user; global $privileges, $user;
if (! in_array('angeltypes', $privileges)) { if (!in_array('angeltypes', $privileges)) {
redirect('?'); redirect(page_link_to('/'));
} }
$angeltypes = AngelTypes_with_user($user); $angeltypes = AngelTypes_with_user($user);
foreach ($angeltypes as &$angeltype) { foreach ($angeltypes as &$angeltype) {
$actions = [ $actions = [
button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], _("view"), "btn-xs") button(
page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]),
_('view'),
'btn-xs'
)
]; ];
if (in_array('admin_angel_types', $privileges)) { if (in_array('admin_angel_types', $privileges)) {
$actions[] = button(page_link_to('angeltypes') . '&action=edit&angeltype_id=' . $angeltype['id'], _("edit"), "btn-xs"); $actions[] = button(
$actions[] = button(page_link_to('angeltypes') . '&action=delete&angeltype_id=' . $angeltype['id'], _("delete"), "btn-xs"); page_link_to('angeltypes', ['action' => 'edit', 'angeltype_id' => $angeltype['id']]),
_('edit'),
'btn-xs'
);
$actions[] = button(
page_link_to('angeltypes', ['action' => 'delete', 'angeltype_id' => $angeltype['id']]),
_('delete'),
'btn-xs'
);
} }
$angeltype['membership'] = AngelType_render_membership($angeltype); $angeltype['membership'] = AngelType_render_membership($angeltype);
if ($angeltype['user_angeltype_id'] != null) { if ($angeltype['user_angeltype_id'] != null) {
$actions[] = button(page_link_to('user_angeltypes') . '&action=delete&user_angeltype_id=' . $angeltype['user_angeltype_id'], _("leave"), "btn-xs"); $actions[] = button(
page_link_to('user_angeltypes',
['action' => 'delete', 'user_angeltype_id' => $angeltype['user_angeltype_id']]
),
_('leave'),
'btn-xs'
);
} else { } else {
$actions[] = button(page_link_to('user_angeltypes') . '&action=add&angeltype_id=' . $angeltype['id'], _("join"), "btn-xs"); $actions[] = button(
page_link_to('user_angeltypes', ['action' => 'add', 'angeltype_id' => $angeltype['id']]),
_('join'),
'btn-xs'
);
} }
$angeltype['restricted'] = $angeltype['restricted'] ? glyph('lock') : ''; $angeltype['restricted'] = $angeltype['restricted'] ? glyph('lock') : '';
$angeltype['no_self_signup'] = $angeltype['no_self_signup'] ? '' : glyph('share'); $angeltype['no_self_signup'] = $angeltype['no_self_signup'] ? '' : glyph('share');
$angeltype['name'] = '<a href="' . page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'] . '">' . $angeltype['name'] . '</a>'; $angeltype['name'] = '<a href="'
. page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']])
. '">'
. $angeltype['name']
. '</a>';
$angeltype['actions'] = table_buttons($actions); $angeltype['actions'] = table_buttons($actions);
} }
@ -209,18 +337,21 @@ function angeltypes_list_controller() {
/** /**
* Loads an angeltype from given angeltype_id request param. * Loads an angeltype from given angeltype_id request param.
*
* @return array
*/ */
function load_angeltype() { function load_angeltype()
if (! isset($_REQUEST['angeltype_id'])) { {
$request = request();
if (!$request->has('angeltype_id')) {
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$angeltype = AngelType($_REQUEST['angeltype_id']); $angeltype = AngelType($request->input('angeltype_id'));
if ($angeltype == null) { if ($angeltype == null) {
error(_("Angeltype doesn't exist.")); error(_('Angeltype doesn\'t exist . '));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
return $angeltype; return $angeltype;
} }
?>

View File

@ -1,16 +1,25 @@
<?php <?php
function event_config_title() { /**
return _("Event config"); * @return string
*/
function event_config_title()
{
return _('Event config');
} }
function event_config_edit_controller() { /**
* @return array
*/
function event_config_edit_controller()
{
global $privileges; global $privileges;
if (! in_array('admin_event_config', $privileges)) { if (!in_array('admin_event_config', $privileges)) {
redirect('?'); redirect(page_link_to('/'));
} }
$request = request();
$event_name = null; $event_name = null;
$event_welcome_msg = null; $event_welcome_msg = null;
$buildup_start_date = null; $buildup_start_date = null;
@ -28,76 +37,93 @@ function event_config_edit_controller() {
$event_welcome_msg = $event_config['event_welcome_msg']; $event_welcome_msg = $event_config['event_welcome_msg'];
} }
if (isset($_REQUEST['submit'])) { if ($request->has('submit')) {
$valid = true; $valid = true;
if (isset($_REQUEST['event_name'])) { if ($request->has('event_name')) {
$event_name = strip_request_item('event_name'); $event_name = strip_request_item('event_name');
} }
if ($event_name == '') { if ($event_name == '') {
$event_name = null; $event_name = null;
} }
if (isset($_REQUEST['event_welcome_msg'])) { if ($request->has('event_welcome_msg')) {
$event_welcome_msg = strip_request_item_nl('event_welcome_msg'); $event_welcome_msg = strip_request_item_nl('event_welcome_msg');
} }
if ($event_welcome_msg == '') { if ($event_welcome_msg == '') {
$event_welcome_msg = null; $event_welcome_msg = null;
} }
$result = check_request_date('buildup_start_date', _("Please enter buildup start date."), true); $result = check_request_date('buildup_start_date', _('Please enter buildup start date.'), true);
$buildup_start_date = $result->getValue(); $buildup_start_date = $result->getValue();
$valid &= $result->isValid(); $valid &= $result->isValid();
$result = check_request_date('event_start_date', _("Please enter event start date."), true); $result = check_request_date('event_start_date', _('Please enter event start date.'), true);
$event_start_date = $result->getValue(); $event_start_date = $result->getValue();
$valid &= $result->isValid(); $valid &= $result->isValid();
$result = check_request_date('event_end_date', _("Please enter event end date."), true); $result = check_request_date('event_end_date', _('Please enter event end date.'), true);
$event_end_date = $result->getValue(); $event_end_date = $result->getValue();
$valid &= $result->isValid(); $valid &= $result->isValid();
$result = check_request_date('teardown_end_date', _("Please enter teardown end date."), true); $result = check_request_date('teardown_end_date', _('Please enter teardown end date.'), true);
$teardown_end_date = $result->getValue(); $teardown_end_date = $result->getValue();
$valid &= $result->isValid(); $valid &= $result->isValid();
if ($buildup_start_date != null && $event_start_date != null && $buildup_start_date > $event_start_date) { if ($buildup_start_date != null && $event_start_date != null && $buildup_start_date > $event_start_date) {
$valid = false; $valid = false;
error(_("The buildup start date has to be before the event start date.")); error(_('The buildup start date has to be before the event start date.'));
} }
if ($event_start_date != null && $event_end_date != null && $event_start_date > $event_end_date) { if ($event_start_date != null && $event_end_date != null && $event_start_date > $event_end_date) {
$valid = false; $valid = false;
error(_("The event start date has to be before the event end date.")); error(_('The event start date has to be before the event end date.'));
} }
if ($event_end_date != null && $teardown_end_date != null && $event_end_date > $teardown_end_date) { if ($event_end_date != null && $teardown_end_date != null && $event_end_date > $teardown_end_date) {
$valid = false; $valid = false;
error(_("The event end date has to be before the teardown end date.")); error(_('The event end date has to be before the teardown end date.'));
} }
if ($buildup_start_date != null && $teardown_end_date != null && $buildup_start_date > $teardown_end_date) { if ($buildup_start_date != null && $teardown_end_date != null && $buildup_start_date > $teardown_end_date) {
$valid = false; $valid = false;
error(_("The buildup start date has to be before the teardown end date.")); error(_('The buildup start date has to be before the teardown end date.'));
} }
if ($valid) { if ($valid) {
$result = EventConfig_update($event_name, $buildup_start_date, $event_start_date, $event_end_date, $teardown_end_date, $event_welcome_msg); EventConfig_update(
$event_name,
$buildup_start_date,
$event_start_date,
$event_end_date,
$teardown_end_date,
$event_welcome_msg
);
if ($result === false) { engelsystem_log(
engelsystem_error("Unable to update event config."); sprintf('Changed event config: %s, %s, %s, %s, %s, %s',
} $event_name,
$event_welcome_msg,
engelsystem_log("Changed event config: $event_name, $event_welcome_msg, " . date("Y-m-d", $buildup_start_date) . ", " . date("Y-m-d", $event_start_date) . ", " . date("Y-m-d", $event_end_date) . ", " . date("Y-m-d", $teardown_end_date)); date('Y-m-d', $buildup_start_date),
success(_("Settings saved.")); date('Y-m-d', $event_start_date),
date('Y-m-d', $event_end_date),
date('Y-m-d', $teardown_end_date)
)
);
success(_('Settings saved.'));
redirect(page_link_to('admin_event_config')); redirect(page_link_to('admin_event_config'));
} }
} }
return [ return [
event_config_title(), event_config_title(),
EventConfig_edit_view($event_name, $event_welcome_msg, $buildup_start_date, $event_start_date, $event_end_date, $teardown_end_date) EventConfig_edit_view(
$event_name,
$event_welcome_msg,
$buildup_start_date,
$event_start_date,
$event_end_date,
$teardown_end_date
)
]; ];
} }
?>

View File

@ -1,7 +1,7 @@
<?php <?php
use Engelsystem\ShiftsFilterRenderer;
use Engelsystem\ShiftsFilter; use Engelsystem\ShiftsFilter;
use Engelsystem\ShiftCalendarRenderer; use Engelsystem\ShiftsFilterRenderer;
/** /**
* Room controllers for managing everything room related. * Room controllers for managing everything room related.
@ -9,42 +9,46 @@ use Engelsystem\ShiftCalendarRenderer;
/** /**
* View a room with its shifts. * View a room with its shifts.
*
* @return array
*/ */
function room_controller() { function room_controller()
{
global $privileges; global $privileges;
if (! in_array('view_rooms', $privileges)) { if (!in_array('view_rooms', $privileges)) {
redirect(page_link_to()); redirect(page_link_to());
} }
$request = request();
$room = load_room(); $room = load_room(false);
if ($room['show'] != 'Y' && !in_array('admin_rooms', $privileges)) {
if($room['show'] != 'Y' && !in_array('admin_rooms', $privileges)) {
redirect(page_link_to()); redirect(page_link_to());
} }
$all_shifts = Shifts_by_room($room); $all_shifts = Shifts_by_room($room);
$days = []; $days = [];
foreach ($all_shifts as $shift) { foreach ($all_shifts as $shift) {
$day = date("Y-m-d", $shift['start']); $day = date('Y-m-d', $shift['start']);
if (! in_array($day, $days)) { if (!in_array($day, $days)) {
$days[] = $day; $days[] = $day;
} }
} }
$shiftsFilter = new ShiftsFilter(true, [ $shiftsFilter = new ShiftsFilter(
$room['RID'] true,
], AngelType_ids()); [$room['RID']],
$selected_day = date("Y-m-d"); AngelType_ids()
if (! empty($days)) { );
$selected_day = date('Y-m-d');
if (!empty($days)) {
$selected_day = $days[0]; $selected_day = $days[0];
} }
if (isset($_REQUEST['shifts_filter_day'])) { if ($request->has('shifts_filter_day')) {
$selected_day = $_REQUEST['shifts_filter_day']; $selected_day = $request->input('shifts_filter_day');
} }
$shiftsFilter->setStartTime(parse_date("Y-m-d H:i", $selected_day . ' 00:00')); $shiftsFilter->setStartTime(parse_date('Y-m-d H:i', $selected_day . ' 00:00'));
$shiftsFilter->setEndTime(parse_date("Y-m-d H:i", $selected_day . ' 23:59')); $shiftsFilter->setEndTime(parse_date('Y-m-d H:i', $selected_day . ' 23:59'));
$shiftsFilterRenderer = new ShiftsFilterRenderer($shiftsFilter); $shiftsFilterRenderer = new ShiftsFilterRenderer($shiftsFilter);
$shiftsFilterRenderer->enableDaySelection($days); $shiftsFilterRenderer->enableDaySelection($days);
@ -59,43 +63,60 @@ function room_controller() {
/** /**
* Dispatch different room actions. * Dispatch different room actions.
*
* @return array
*/ */
function rooms_controller() { function rooms_controller()
if (! isset($_REQUEST['action'])) { {
$_REQUEST['action'] = 'list'; $request = request();
$action = $request->input('action');
if (!$request->has('action')) {
$action = 'list';
} }
switch ($_REQUEST['action']) { switch ($action) {
default:
case 'list':
redirect(page_link_to('admin_rooms'));
case 'view': case 'view':
return room_controller(); return room_controller();
case 'list':
default:
redirect(page_link_to('admin_rooms'));
} }
} }
function room_link($room) { /**
return page_link_to('rooms') . '&action=view&room_id=' . $room['RID']; * @param array $room
* @return string
*/
function room_link($room)
{
return page_link_to('rooms', ['action' => 'view', 'room_id' => $room['RID']]);
} }
function room_edit_link($room) { /**
return page_link_to('admin_rooms') . '&show=edit&id=' . $room['RID']; * @param array $room
* @return string
*/
function room_edit_link($room)
{
return page_link_to('admin_rooms', ['show' => 'edit', 'id' => $room['RID']]);
} }
/** /**
* Loads room by request param room_id * Loads room by request param room_id
*
* @param bool $onlyVisible
* @return array
*/ */
function load_room() { function load_room($onlyVisible = true)
if (! test_request_int('room_id')) { {
if (!test_request_int('room_id')) {
redirect(page_link_to()); redirect(page_link_to());
} }
$room = Room($_REQUEST['room_id']); $room = Room(request()->input('room_id'), $onlyVisible);
if ($room == null) { if ($room == null) {
redirect(page_link_to()); redirect(page_link_to());
} }
return $room; return $room;
} }
?>

View File

@ -1,49 +1,81 @@
<?php <?php
use Engelsystem\Database\DB;
/** /**
* Sign up for a shift. * Sign up for a shift.
*
* @return string
*/ */
function shift_entry_add_controller() { function shift_entry_add_controller()
{
global $privileges, $user; global $privileges, $user;
if (isset($_REQUEST['shift_id']) && preg_match("/^[0-9]*$/", $_REQUEST['shift_id'])) { $request = request();
$shift_id = $_REQUEST['shift_id']; $shift_id = 0;
if ($request->has('shift_id') && preg_match('/^\d+$/', $request->input('shift_id'))) {
$shift_id = $request->input('shift_id');
} else { } else {
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
// Locations laden // Locations laden
$rooms = sql_select("SELECT * FROM `Room` WHERE `show`='Y' ORDER BY `Name`"); $rooms = Rooms();
$room_array = []; $room_array = [];
foreach ($rooms as $room) { foreach ($rooms as $room) {
$room_array[$room['RID']] = $room['Name']; $room_array[$room['RID']] = $room['Name'];
} }
$shift = Shift($shift_id); $shift = Shift($shift_id);
$shift['Name'] = $room_array[$shift['RID']];
if ($shift == null) { if ($shift == null) {
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
$shift['Name'] = $room_array[$shift['RID']];
if (isset($_REQUEST['type_id']) && preg_match("/^[0-9]*$/", $_REQUEST['type_id'])) { $type_id = null;
$type_id = $_REQUEST['type_id']; if ($request->has('type_id') && preg_match('/^\d+$/', $request->input('type_id'))) {
} else { $type_id = $request->input('type_id');
redirect(page_link_to('user_shifts'));
} }
if (in_array('user_shifts_admin', $privileges) || in_array('shiftentry_edit_angeltype_supporter', $privileges)) { if (in_array('user_shifts_admin', $privileges) || in_array('shiftentry_edit_angeltype_supporter', $privileges)) {
if($type_id == null) {
// If no angeltype id is given, then select first existing angeltype.
$needed_angeltypes = NeededAngelTypes_by_shift($shift_id);
if(count($needed_angeltypes) > 0) {
$type_id = $needed_angeltypes[0]['id'];
}
}
$type = AngelType($type_id); $type = AngelType($type_id);
} else { } else {
$type = sql_select("SELECT * FROM `UserAngelTypes` JOIN `AngelTypes` ON (`UserAngelTypes`.`angeltype_id` = `AngelTypes`.`id`) WHERE `AngelTypes`.`id` = '" . sql_escape($type_id) . "' AND (`AngelTypes`.`restricted` = 0 OR (`UserAngelTypes`.`user_id` = '" . sql_escape($user['UID']) . "' AND NOT `UserAngelTypes`.`confirm_user_id` IS NULL))"); // TODO: Move queries to model
$type = $type[0]; $type = DB::selectOne('
SELECT *
FROM `UserAngelTypes`
JOIN `AngelTypes` ON (`UserAngelTypes`.`angeltype_id` = `AngelTypes`.`id`)
WHERE `AngelTypes`.`id` = ?
AND (
`AngelTypes`.`restricted` = 0
OR (
`UserAngelTypes`.`user_id` = ?
AND NOT `UserAngelTypes`.`confirm_user_id` IS NULL
)
)
', [$type_id, $user['UID']]);
} }
if ($type == null) { if (empty($type)) {
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
if (isset($_REQUEST['user_id']) && preg_match("/^[0-9]*$/", $_REQUEST['user_id']) && (in_array('user_shifts_admin', $privileges) || in_array('shiftentry_edit_angeltype_supporter', $privileges))) { if (
$user_id = $_REQUEST['user_id']; $request->has('user_id')
&& preg_match('/^\d+$/', $request->input('user_id'))
&& (
in_array('user_shifts_admin', $privileges)
|| in_array('shiftentry_edit_angeltype_supporter', $privileges)
)
) {
$user_id = $request->input('user_id');
} else { } else {
$user_id = $user['UID']; $user_id = $user['UID'];
} }
@ -51,38 +83,58 @@ function shift_entry_add_controller() {
$needed_angeltype = NeededAngeltype_by_Shift_and_Angeltype($shift, $type); $needed_angeltype = NeededAngeltype_by_Shift_and_Angeltype($shift, $type);
$shift_entries = ShiftEntries_by_shift_and_angeltype($shift['SID'], $type['id']); $shift_entries = ShiftEntries_by_shift_and_angeltype($shift['SID'], $type['id']);
$shift_signup_allowed = Shift_signup_allowed(User($user_id), $shift, $type, null, null, $needed_angeltype, $shift_entries); $shift_signup_allowed = Shift_signup_allowed(
if (! $shift_signup_allowed->isSignupAllowed()) { User($user_id),
error(_("You are not allowed to sign up for this shift. Maybe shift is full or already running.")); $shift,
$type,
null,
null,
$needed_angeltype,
$shift_entries
);
if (!$shift_signup_allowed->isSignupAllowed()) {
error(_('You are not allowed to sign up for this shift. Maybe shift is full or already running.'));
redirect(shift_link($shift)); redirect(shift_link($shift));
} }
if (isset($_REQUEST['submit'])) { if ($request->has('submit')) {
$selected_type_id = $type_id; $selected_type_id = $type_id;
if (in_array('user_shifts_admin', $privileges) || in_array('shiftentry_edit_angeltype_supporter', $privileges)) { if (in_array('user_shifts_admin', $privileges) || in_array('shiftentry_edit_angeltype_supporter',
$privileges)
) {
if (sql_num_query("SELECT * FROM `User` WHERE `UID`='" . sql_escape($user_id) . "' LIMIT 1") == 0) { if (count(DB::select('SELECT `UID` FROM `User` WHERE `UID`=? LIMIT 1', [$user_id])) == 0) {
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
if (isset($_REQUEST['angeltype_id']) && test_request_int('angeltype_id') && sql_num_query("SELECT * FROM `AngelTypes` WHERE `id`='" . sql_escape($_REQUEST['angeltype_id']) . "' LIMIT 1") > 0) { if (
$selected_type_id = $_REQUEST['angeltype_id']; $request->has('angeltype_id')
&& test_request_int('angeltype_id')
&& count(DB::select(
'SELECT `id` FROM `AngelTypes` WHERE `id`=? LIMIT 1',
[$request->input('angeltype_id')]
)) > 0
) {
$selected_type_id = $request->input('angeltype_id');
} }
} }
if (sql_num_query("SELECT * FROM `ShiftEntry` WHERE `SID`='" . sql_escape($shift['SID']) . "' AND `UID` = '" . sql_escape($user_id) . "'")) { if (count(DB::select(
return error("This angel does already have an entry for this shift.", true); 'SELECT `id` FROM `ShiftEntry` WHERE `SID`= ? AND `UID` = ?',
[$shift['SID'], $user_id]))
) {
return error('This angel does already have an entry for this shift.', true);
} }
$freeloaded = $shift['freeloaded']; $freeloaded = isset($shift['freeloaded']) ? $shift['freeloaded'] : false;
$freeload_comment = $shift['freeload_comment']; $freeload_comment = isset($shift['freeload_comment']) ? $shift['freeload_comment'] : '';
if (in_array("user_shifts_admin", $privileges)) { if (in_array('user_shifts_admin', $privileges)) {
$freeloaded = isset($_REQUEST['freeloaded']); $freeloaded = $request->has('freeloaded');
$freeload_comment = strip_request_item_nl('freeload_comment'); $freeload_comment = strip_request_item_nl('freeload_comment');
} }
$comment = strip_request_item_nl('comment'); $comment = strip_request_item_nl('comment');
$result = ShiftEntry_create([ ShiftEntry_create([
'SID' => $shift_id, 'SID' => $shift_id,
'TID' => $selected_type_id, 'TID' => $selected_type_id,
'UID' => $user_id, 'UID' => $user_id,
@ -90,29 +142,53 @@ function shift_entry_add_controller() {
'freeloaded' => $freeloaded, 'freeloaded' => $freeloaded,
'freeload_comment' => $freeload_comment 'freeload_comment' => $freeload_comment
]); ]);
if ($result === false) {
engelsystem_error('Unable to create shift entry.');
}
if ($type['restricted'] == 0 && sql_num_query("SELECT * FROM `UserAngelTypes` INNER JOIN `AngelTypes` ON `AngelTypes`.`id` = `UserAngelTypes`.`angeltype_id` WHERE `angeltype_id` = '" . sql_escape($selected_type_id) . "' AND `user_id` = '" . sql_escape($user_id) . "'") == 0) { if (
sql_query("INSERT INTO `UserAngelTypes` (`user_id`, `angeltype_id`) VALUES ('" . sql_escape($user_id) . "', '" . sql_escape($selected_type_id) . "')"); $type['restricted'] == 0
&& count(DB::select('
SELECT `UserAngelTypes`.`id` FROM `UserAngelTypes`
INNER JOIN `AngelTypes` ON `AngelTypes`.`id` = `UserAngelTypes`.`angeltype_id`
WHERE `angeltype_id` = ?
AND `user_id` = ?
', [$selected_type_id, $user_id])) == 0
) {
DB::insert(
'INSERT INTO `UserAngelTypes` (`user_id`, `angeltype_id`) VALUES (?, ?)',
[$user_id, $selected_type_id]
);
} }
$user_source = User($user_id); $user_source = User($user_id);
engelsystem_log("User " . User_Nick_render($user_source) . " signed up for shift " . $shift['name'] . " from " . date("Y-m-d H:i", $shift['start']) . " to " . date("Y-m-d H:i", $shift['end'])); engelsystem_log(
success(_("You are subscribed. Thank you!") . ' <a href="' . page_link_to('user_myshifts') . '">' . _("My shifts") . ' &raquo;</a>'); 'User ' . User_Nick_render($user_source)
. ' signed up for shift ' . $shift['name']
. ' from ' . date('Y-m-d H:i', $shift['start'])
. ' to ' . date('Y-m-d H:i', $shift['end'])
);
success(_('You are subscribed. Thank you!') . ' <a href="' . page_link_to('user_myshifts') . '">' . _('My shifts') . ' &raquo;</a>');
redirect(shift_link($shift)); redirect(shift_link($shift));
} }
$angeltype_select = '';
if (in_array('user_shifts_admin', $privileges)) { if (in_array('user_shifts_admin', $privileges)) {
$users = sql_select("SELECT *, (SELECT count(*) FROM `ShiftEntry` WHERE `freeloaded`=1 AND `ShiftEntry`.`UID`=`User`.`UID`) AS `freeloaded` FROM `User` ORDER BY `Nick`"); $users = DB::select('
SELECT *,
(
SELECT count(*)
FROM `ShiftEntry`
WHERE `freeloaded`=1
AND `ShiftEntry`.`UID`=`User`.`UID`
) AS `freeloaded`
FROM `User`
ORDER BY `Nick`
');
$users_select = []; $users_select = [];
foreach ($users as $usr) { foreach ($users as $usr) {
$users_select[$usr['UID']] = $usr['Nick'] . ($usr['freeloaded'] == 0 ? "" : " (" . _("Freeloader") . ")"); $users_select[$usr['UID']] = $usr['Nick'] . ($usr['freeloaded'] == 0 ? '' : ' (' . _('Freeloader') . ')');
} }
$user_text = html_select_key('user_id', 'user_id', $users_select, $user['UID']); $user_text = html_select_key('user_id', 'user_id', $users_select, $user['UID']);
$angeltypes_source = sql_select("SELECT * FROM `AngelTypes` ORDER BY `name`"); $angeltypes_source = DB::select('SELECT `id`, `name` FROM `AngelTypes` ORDER BY `name`');
$angeltypes = []; $angeltypes = [];
foreach ($angeltypes_source as $angeltype) { foreach ($angeltypes_source as $angeltype) {
$angeltypes[$angeltype['id']] = $angeltype['name']; $angeltypes[$angeltype['id']] = $angeltype['name'];
@ -122,7 +198,7 @@ function shift_entry_add_controller() {
$users = Users_by_angeltype($type); $users = Users_by_angeltype($type);
$users_select = []; $users_select = [];
foreach ($users as $usr) { foreach ($users as $usr) {
if (! $type['restricted'] || $usr['confirm_user_id'] != null) { if (!$type['restricted'] || $usr['confirm_user_id'] != null) {
$users_select[$usr['UID']] = $usr['Nick']; $users_select[$usr['UID']] = $usr['Nick'];
} }
} }
@ -141,47 +217,74 @@ function shift_entry_add_controller() {
$angeltype_select = $type['name']; $angeltype_select = $type['name'];
} }
return ShiftEntry_edit_view($user_text, date("Y-m-d H:i", $shift['start']) . ' &ndash; ' . date('Y-m-d H:i', $shift['end']) . ' (' . shift_length($shift) . ')', $shift['Name'], $shift['name'], $angeltype_select, "", false, null, in_array('user_shifts_admin', $privileges)); return ShiftEntry_edit_view(
$user_text,
date('Y-m-d H:i', $shift['start'])
. ' &ndash; '
. date('Y-m-d H:i', $shift['end'])
. ' (' . shift_length($shift) . ')',
$shift['Name'],
$shift['name'],
$angeltype_select, '',
false,
null,
in_array('user_shifts_admin', $privileges)
);
} }
/** /**
* Remove somebody from a shift. * Remove somebody from a shift.
*/ */
function shift_entry_delete_controller() { function shift_entry_delete_controller()
{
global $privileges, $user; global $privileges, $user;
$request = request();
if (! isset($_REQUEST['entry_id']) || ! test_request_int('entry_id')) { if (!$request->has('entry_id') || !test_request_int('entry_id')) {
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
$entry_id = $_REQUEST['entry_id']; $entry_id = $request->input('entry_id');
$shift_entry_source = sql_select(" $shift_entry_source = DB::selectOne('
SELECT `User`.`Nick`, `ShiftEntry`.`Comment`, `ShiftEntry`.`UID`, `ShiftTypes`.`name`, `Shifts`.*, `Room`.`Name`, `AngelTypes`.`name` as `angel_type`, `AngelTypes`.`id` as `angeltype_id` SELECT
`User`.`Nick`,
`User`.`Gekommen`,
`ShiftEntry`.`Comment`,
`ShiftEntry`.`UID`,
`ShiftTypes`.`name`,
`Shifts`.*,
`Room`.`Name`,
`AngelTypes`.`name` AS `angel_type`,
`AngelTypes`.`id` AS `angeltype_id`
FROM `ShiftEntry` FROM `ShiftEntry`
JOIN `User` ON (`User`.`UID`=`ShiftEntry`.`UID`) JOIN `User` ON (`User`.`UID`=`ShiftEntry`.`UID`)
JOIN `AngelTypes` ON (`ShiftEntry`.`TID` = `AngelTypes`.`id`) JOIN `AngelTypes` ON (`ShiftEntry`.`TID` = `AngelTypes`.`id`)
JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID`) JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID`)
JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`) JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`)
JOIN `Room` ON (`Shifts`.`RID` = `Room`.`RID`) JOIN `Room` ON (`Shifts`.`RID` = `Room`.`RID`)
WHERE `ShiftEntry`.`id`='" . sql_escape($entry_id) . "'"); WHERE `ShiftEntry`.`id`=?',
if (count($shift_entry_source) > 0) { [$entry_id]
$shift_entry_source = $shift_entry_source[0]; );
if (!empty($shift_entry_source)) {
if (!in_array('user_shifts_admin', $privileges) && (!in_array('shiftentry_edit_angeltype_supporter', $privileges) || !User_is_AngelType_supporter($user, AngelType($shift_entry_source['angeltype_id'])))) { if (!in_array('user_shifts_admin', $privileges) && (!in_array('shiftentry_edit_angeltype_supporter',
$privileges) || !User_is_AngelType_supporter($user, AngelType($shift_entry_source['angeltype_id'])))
) {
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
$result = ShiftEntry_delete($entry_id); ShiftEntry_delete($entry_id);
if ($result === false) {
engelsystem_error('Unable to delete shift entry.'); engelsystem_log(
'Deleted ' . User_Nick_render($shift_entry_source) . '\'s shift: ' . $shift_entry_source['name']
. ' at ' . $shift_entry_source['Name']
. ' from ' . date('Y-m-d H:i', $shift_entry_source['start'])
. ' to ' . date('Y-m-d H:i', $shift_entry_source['end'])
. ' as ' . $shift_entry_source['angel_type']
);
success(_('Shift entry deleted.'));
} else {
error(_('Entry not found.'));
} }
engelsystem_log("Deleted " . User_Nick_render($shift_entry_source) . "'s shift: " . $shift_entry_source['name'] . " at " . $shift_entry_source['Name'] . " from " . date("Y-m-d H:i", $shift_entry_source['start']) . " to " . date("Y-m-d H:i", $shift_entry_source['end']) . " as " . $shift_entry_source['angel_type']);
success(_("Shift entry deleted."));
} else {
error(_("Entry not found."));
}
redirect(shift_link($shift_entry_source)); redirect(shift_link($shift_entry_source));
} }
?>

View File

@ -1,36 +1,63 @@
<?php <?php
use Engelsystem\ShiftSignupState; use Engelsystem\ShiftSignupState;
function shift_link($shift) { /**
return page_link_to('shifts') . '&action=view&shift_id=' . $shift['SID']; * @param array $shift
* @return string
*/
function shift_link($shift)
{
$parameters = ['action' => 'view'];
if (isset($shift['SID'])) {
$parameters['shift_id'] = $shift['SID'];
}
$link = page_link_to('shifts', $parameters);
return $link;
} }
function shift_delete_link($shift) { /**
return page_link_to('user_shifts') . '&delete_shift=' . $shift['SID']; * @param array $shift
* @return string
*/
function shift_delete_link($shift)
{
return page_link_to('user_shifts', ['delete_shift' => $shift['SID']]);
} }
function shift_edit_link($shift) { /**
return page_link_to('user_shifts') . '&edit_shift=' . $shift['SID']; * @param array $shift
* @return string
*/
function shift_edit_link($shift)
{
return page_link_to('user_shifts', ['edit_shift' => $shift['SID']]);
} }
/** /**
* Edit a single shift. * Edit a single shift.
*
* @return string
*/ */
function shift_edit_controller() { function shift_edit_controller()
{
global $privileges; global $privileges;
// Schicht bearbeiten // Schicht bearbeiten
$msg = ""; $msg = '';
$valid = true; $valid = true;
$request = request();
if (! in_array('admin_shifts', $privileges)) { if (!in_array('admin_shifts', $privileges)) {
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
if (! isset($_REQUEST['edit_shift']) || ! test_request_int('edit_shift')) { if (!$request->has('edit_shift') || !test_request_int('edit_shift')) {
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
$shift_id = $_REQUEST['edit_shift']; $shift_id = $request->input('edit_shift');
$shift = Shift($shift_id); $shift = Shift($shift_id);
@ -38,9 +65,9 @@ function shift_edit_controller() {
$angeltypes = select_array(AngelTypes(), 'id', 'name'); $angeltypes = select_array(AngelTypes(), 'id', 'name');
$shifttypes = select_array(ShiftTypes(), 'id', 'name'); $shifttypes = select_array(ShiftTypes(), 'id', 'name');
$needed_angel_types = select_array(NeededAngelTypes_by_shift($shift_id), 'id', 'count'); $needed_angel_types = select_array(NeededAngelTypes_by_shift($shift_id), 'angel_type_id', 'count');
foreach (array_keys($angeltypes) as $angeltype_id) { foreach (array_keys($angeltypes) as $angeltype_id) {
if (! isset($needed_angel_types[$angeltype_id])) { if (!isset($needed_angel_types[$angeltype_id])) {
$needed_angel_types[$angeltype_id] = 0; $needed_angel_types[$angeltype_id] = 0;
} }
} }
@ -51,50 +78,62 @@ function shift_edit_controller() {
$start = $shift['start']; $start = $shift['start'];
$end = $shift['end']; $end = $shift['end'];
if (isset($_REQUEST['submit'])) { if ($request->has('submit')) {
// Name/Bezeichnung der Schicht, darf leer sein // Name/Bezeichnung der Schicht, darf leer sein
$title = strip_request_item('title'); $title = strip_request_item('title');
// Auswahl der sichtbaren Locations für die Schichten // Auswahl der sichtbaren Locations für die Schichten
if (isset($_REQUEST['rid']) && preg_match("/^[0-9]+$/", $_REQUEST['rid']) && isset($room[$_REQUEST['rid']])) { if (
$rid = $_REQUEST['rid']; $request->has('rid')
&& preg_match('/^\d+$/', $request->input('rid'))
&& isset($room[$request->input('rid')])
) {
$rid = $request->input('rid');
} else { } else {
$valid = false; $valid = false;
$msg .= error(_("Please select a room."), true); $msg .= error(_('Please select a room.'), true);
} }
if (isset($_REQUEST['shifttype_id']) && isset($shifttypes[$_REQUEST['shifttype_id']])) { if ($request->has('shifttype_id') && isset($shifttypes[$request->input('shifttype_id')])) {
$shifttype_id = $_REQUEST['shifttype_id']; $shifttype_id = $request->input('shifttype_id');
} else { } else {
$valid = false; $valid = false;
$msg .= error(_('Please select a shifttype.'), true); $msg .= error(_('Please select a shifttype.'), true);
} }
if (isset($_REQUEST['start']) && $tmp = parse_date("Y-m-d H:i", $_REQUEST['start'])) { if ($request->has('start') && $tmp = parse_date('Y-m-d H:i', $request->input('start'))) {
$start = $tmp; $start = $tmp;
} else { } else {
$valid = false; $valid = false;
$msg .= error(_("Please enter a valid starting time for the shifts."), true); $msg .= error(_('Please enter a valid starting time for the shifts.'), true);
} }
if (isset($_REQUEST['end']) && $tmp = parse_date("Y-m-d H:i", $_REQUEST['end'])) { if ($request->has('end') && $tmp = parse_date('Y-m-d H:i', $request->input('end'))) {
$end = $tmp; $end = $tmp;
} else { } else {
$valid = false; $valid = false;
$msg .= error(_("Please enter a valid ending time for the shifts."), true); $msg .= error(_('Please enter a valid ending time for the shifts.'), true);
} }
if ($start >= $end) { if ($start >= $end) {
$valid = false; $valid = false;
$msg .= error(_("The ending time has to be after the starting time."), true); $msg .= error(_('The ending time has to be after the starting time.'), true);
} }
foreach ($needed_angel_types as $needed_angeltype_id => $needed_angeltype_name) { foreach ($needed_angel_types as $needed_angeltype_id => $count) {
if (isset($_REQUEST['type_' . $needed_angeltype_id]) && test_request_int('type_' . $needed_angeltype_id)) { $needed_angel_types[$needed_angeltype_id] = 0;
$needed_angel_types[$needed_angeltype_id] = trim($_REQUEST['type_' . $needed_angeltype_id]);
$queryKey = 'type_' . $needed_angeltype_id;
if ($request->has($queryKey)) {
if (test_request_int($queryKey)) {
$needed_angel_types[$needed_angeltype_id] = trim($request->input($queryKey));
} else { } else {
$valid = false; $valid = false;
$msg .= error(sprintf(_("Please check your input for needed angels of type %s."), $needed_angeltype_name), true); $msg .= error(sprintf(
_('Please check your input for needed angels of type %s.'),
$angeltypes[$needed_angeltype_id]
), true);
}
} }
} }
@ -105,19 +144,21 @@ function shift_edit_controller() {
$shift['start'] = $start; $shift['start'] = $start;
$shift['end'] = $end; $shift['end'] = $end;
$result = Shift_update($shift); Shift_update($shift);
if ($result === false) {
engelsystem_error('Unable to update shift.');
}
NeededAngelTypes_delete_by_shift($shift_id); NeededAngelTypes_delete_by_shift($shift_id);
$needed_angel_types_info = []; $needed_angel_types_info = [];
foreach ($needed_angel_types as $type_id => $count) { foreach ($needed_angel_types as $type_id => $count) {
NeededAngelType_add($shift_id, $type_id, null, $count); NeededAngelType_add($shift_id, $type_id, null, $count);
$needed_angel_types_info[] = $angeltypes[$type_id] . ": " . $count; $needed_angel_types_info[] = $angeltypes[$type_id] . ': ' . $count;
} }
engelsystem_log("Updated shift '" . $shifttypes[$shifttype_id] . ", " . $title . "' from " . date("Y-m-d H:i", $start) . " to " . date("Y-m-d H:i", $end) . " with angel types " . join(", ", $needed_angel_types_info)); engelsystem_log(
success(_("Shift updated.")); 'Updated shift \'' . $shifttypes[$shifttype_id] . ', ' . $title
. '\' from ' . date('Y-m-d H:i', $start)
. ' to ' . date('Y-m-d H:i', $end)
. ' with angel types ' . join(', ', $needed_angel_types_info)
);
success(_('Shift updated.'));
redirect(shift_link([ redirect(shift_link([
'SID' => $shift_id 'SID' => $shift_id
@ -125,39 +166,48 @@ function shift_edit_controller() {
} }
} }
$angel_types_spinner = ""; $angel_types_spinner = '';
foreach ($angeltypes as $angeltype_id => $angeltype_name) { foreach ($angeltypes as $angeltype_id => $angeltype_name) {
$angel_types_spinner .= form_spinner('type_' . $angeltype_id, $angeltype_name, $needed_angel_types[$angeltype_id]); $angel_types_spinner .= form_spinner('type_' . $angeltype_id, $angeltype_name,
$needed_angel_types[$angeltype_id]);
} }
return page_with_title(shifts_title(), [ return page_with_title(
shifts_title(),
[
msg(), msg(),
'<noscript>' . info(_("This page is much more comfortable with javascript."), true) . '</noscript>', '<noscript>' . info(_('This page is much more comfortable with javascript.'), true) . '</noscript>',
form([ form([
form_select('shifttype_id', _('Shifttype'), $shifttypes, $shifttype_id), form_select('shifttype_id', _('Shifttype'), $shifttypes, $shifttype_id),
form_text('title', _("Title"), $title), form_text('title', _('Title'), $title),
form_select('rid', _("Room:"), $room, $rid), form_select('rid', _('Room:'), $room, $rid),
form_text('start', _("Start:"), date("Y-m-d H:i", $start)), form_text('start', _('Start:'), date('Y-m-d H:i', $start)),
form_text('end', _("End:"), date("Y-m-d H:i", $end)), form_text('end', _('End:'), date('Y-m-d H:i', $end)),
'<h2>' . _("Needed angels") . '</h2>', '<h2>' . _('Needed angels') . '</h2>',
$angel_types_spinner, $angel_types_spinner,
form_submit('submit', _("Save")) form_submit('submit', _('Save'))
]) ])
]); ]
);
} }
function shift_delete_controller() { /**
* @return string
*/
function shift_delete_controller()
{
global $privileges; global $privileges;
$request = request();
if (! in_array('user_shifts_admin', $privileges)) { if (!in_array('user_shifts_admin', $privileges)) {
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
// Schicht komplett löschen (nur für admins/user mit user_shifts_admin privileg) // Schicht komplett löschen (nur für admins/user mit user_shifts_admin privileg)
if (! isset($_REQUEST['delete_shift']) || ! preg_match("/^[0-9]*$/", $_REQUEST['delete_shift'])) { if (!$request->has('delete_shift') || !preg_match('/^\d+$/', $request->input('delete_shift'))) {
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
$shift_id = $_REQUEST['delete_shift']; $shift_id = $request->input('delete_shift');
$shift = Shift($shift_id); $shift = Shift($shift_id);
if ($shift == null) { if ($shift == null) {
@ -165,34 +215,50 @@ function shift_delete_controller() {
} }
// Schicht löschen bestätigt // Schicht löschen bestätigt
if (isset($_REQUEST['delete'])) { if ($request->has('delete')) {
Shift_delete($shift_id); Shift_delete($shift_id);
engelsystem_log("Deleted shift " . $shift['name'] . " from " . date("Y-m-d H:i", $shift['start']) . " to " . date("Y-m-d H:i", $shift['end'])); engelsystem_log(
success(_("Shift deleted.")); 'Deleted shift ' . $shift['name']
. ' from ' . date('Y-m-d H:i', $shift['start'])
. ' to ' . date('Y-m-d H:i', $shift['end'])
);
success(_('Shift deleted.'));
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
return page_with_title(shifts_title(), [ return page_with_title(shifts_title(), [
error(sprintf(_("Do you want to delete the shift %s from %s to %s?"), $shift['name'], date("Y-m-d H:i", $shift['start']), date("H:i", $shift['end'])), true), error(sprintf(
'<a class="button" href="?p=user_shifts&delete_shift=' . $shift_id . '&delete">' . _("delete") . '</a>' _('Do you want to delete the shift %s from %s to %s?'),
$shift['name'],
date('Y-m-d H:i', $shift['start']),
date('H:i', $shift['end'])
), true),
'<a class="button" href="'
. page_link_to('user_shifts', ['delete_shift' => $shift_id, 'delete' => 1]) .
'">' . _('delete') . '</a>'
]); ]);
} }
function shift_controller() { /**
* @return array
*/
function shift_controller()
{
global $user, $privileges; global $user, $privileges;
$request = request();
if (! in_array('user_shifts', $privileges)) { if (!in_array('user_shifts', $privileges)) {
redirect(page_link_to('?')); redirect(page_link_to('/'));
} }
if (! isset($_REQUEST['shift_id'])) { if (!$request->has('shift_id')) {
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
$shift = Shift($_REQUEST['shift_id']); $shift = Shift($request->input('shift_id'));
if ($shift == null) { if ($shift == null) {
error(_("Shift could not be found.")); error(_('Shift could not be found.'));
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
@ -206,7 +272,15 @@ function shift_controller() {
$needed_angeltype = NeededAngeltype_by_Shift_and_Angeltype($shift, $angeltype); $needed_angeltype = NeededAngeltype_by_Shift_and_Angeltype($shift, $angeltype);
$shift_entries = ShiftEntries_by_shift_and_angeltype($shift['SID'], $angeltype['id']); $shift_entries = ShiftEntries_by_shift_and_angeltype($shift['SID'], $angeltype['id']);
$angeltype_signup_state = Shift_signup_allowed($user, $shift, $angeltype, null, $user_shifts, $needed_angeltype, $shift_entries); $angeltype_signup_state = Shift_signup_allowed(
$user,
$shift,
$angeltype,
null,
$user_shifts,
$needed_angeltype,
$shift_entries
);
if ($shift_signup_state == null) { if ($shift_signup_state == null) {
$shift_signup_state = $angeltype_signup_state; $shift_signup_state = $angeltype_signup_state;
} else { } else {
@ -221,37 +295,42 @@ function shift_controller() {
]; ];
} }
function shifts_controller() { /**
if (! isset($_REQUEST['action'])) { * @return array|false
*/
function shifts_controller()
{
$request = request();
if (!$request->has('action')) {
redirect(page_link_to('user_shifts')); redirect(page_link_to('user_shifts'));
} }
switch ($_REQUEST['action']) { switch ($request->input('action')) {
default:
redirect(page_link_to('?'));
case 'view': case 'view':
return shift_controller(); return shift_controller();
case 'next': case 'next':
return shift_next_controller(); return shift_next_controller();
default:
redirect(page_link_to('/'));
} }
return false;
} }
/** /**
* Redirects the user to his next shift. * Redirects the user to his next shift.
*/ */
function shift_next_controller() { function shift_next_controller()
{
global $user, $privileges; global $user, $privileges;
if (! in_array('user_shifts', $privileges)) { if (!in_array('user_shifts', $privileges)) {
redirect(page_link_to('?')); redirect(page_link_to('/'));
} }
$upcoming_shifts = ShiftEntries_upcoming_for_user($user); $upcoming_shifts = ShiftEntries_upcoming_for_user($user);
if ($upcoming_shifts === false) {
return false;
}
if (count($upcoming_shifts) > 0) { if (!empty($upcoming_shifts)) {
redirect(shift_link($upcoming_shifts[0])); redirect(shift_link($upcoming_shifts[0]));
} }
@ -261,27 +340,26 @@ function shift_next_controller() {
/** /**
* Export all shifts using api-key. * Export all shifts using api-key.
*/ */
function shifts_json_export_all_controller() { function shifts_json_export_all_controller()
global $api_key; {
$api_key = config('api_key');
$request = request();
if ($api_key == "") { if (empty($api_key)) {
engelsystem_error("Config contains empty apikey."); engelsystem_error('Config contains empty apikey.');
} }
if (! isset($_REQUEST['api_key'])) { if (!$request->has('api_key')) {
engelsystem_error("Missing parameter api_key."); engelsystem_error('Missing parameter api_key.');
} }
if ($_REQUEST['api_key'] != $api_key) { if ($request->input('api_key') != $api_key) {
engelsystem_error("Invalid api_key."); engelsystem_error('Invalid api_key.');
} }
$shifts_source = Shifts(); $shifts_source = Shifts();
if ($shifts_source === false) {
engelsystem_error("Unable to load shifts.");
}
header("Content-Type: application/json; charset=utf-8"); header('Content-Type: application/json; charset=utf-8');
raw_output(json_encode($shifts_source)); raw_output(json_encode($shifts_source));
} }
@ -289,36 +367,39 @@ function shifts_json_export_all_controller() {
* Export filtered shifts via JSON. * Export filtered shifts via JSON.
* (Like iCal Export or shifts view) * (Like iCal Export or shifts view)
*/ */
function shifts_json_export_controller() { function shifts_json_export_controller()
{
global $user; global $user;
$request = request();
if (! isset($_REQUEST['key']) || ! preg_match("/^[0-9a-f]{32}$/", $_REQUEST['key'])) { if (!$request->has('key') || !preg_match('/^[\da-f]{32}$/', $request->input('key'))) {
engelsystem_error("Missing key."); engelsystem_error('Missing key.');
} }
$key = $_REQUEST['key']; $key = $request->input('key');
$user = User_by_api_key($key); $user = User_by_api_key($key);
if ($user == null) { if ($user == null) {
engelsystem_error("Key invalid."); engelsystem_error('Key invalid.');
} }
if (! in_array('shifts_json_export', privileges_for_user($user['UID']))) { if (!in_array('shifts_json_export', privileges_for_user($user['UID']))) {
engelsystem_error("No privilege for shifts_json_export."); engelsystem_error('No privilege for shifts_json_export.');
} }
$shifts = load_ical_shifts(); $shifts = load_ical_shifts();
header("Content-Type: application/json; charset=utf-8"); header('Content-Type: application/json; charset=utf-8');
raw_output(json_encode($shifts)); raw_output(json_encode($shifts));
} }
/** /**
* Returns users shifts to export. * Returns users shifts to export.
*
* @return array
*/ */
function load_ical_shifts() { function load_ical_shifts()
{
global $user; global $user;
return Shifts_by_user($user); return Shifts_by_user($user);
} }
?>

View File

@ -1,31 +1,34 @@
<?php <?php
function shifttype_link($shifttype) { /**
return page_link_to('shifttypes') . '&action=view&shifttype_id=' . $shifttype['id']; * @param array $shifttype
* @return string
*/
function shifttype_link($shifttype)
{
return page_link_to('shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype['id']]);
} }
/** /**
* Delete a shifttype. * Delete a shifttype.
*
* @return array
*/ */
function shifttype_delete_controller() { function shifttype_delete_controller()
if (! isset($_REQUEST['shifttype_id'])) { {
$request = request();
if (!$request->has('shifttype_id')) {
redirect(page_link_to('shifttypes')); redirect(page_link_to('shifttypes'));
} }
$shifttype = ShiftType($_REQUEST['shifttype_id']); $shifttype = ShiftType($request->input('shifttype_id'));
if ($shifttype === false) {
engelsystem_error('Unable to load shifttype.');
}
if ($shifttype == null) { if ($shifttype == null) {
redirect(page_link_to('shifttypes')); redirect(page_link_to('shifttypes'));
} }
if (isset($_REQUEST['confirmed'])) { if ($request->has('confirmed')) {
$result = ShiftType_delete($shifttype['id']); ShiftType_delete($shifttype['id']);
if ($result === false) {
engelsystem_error('Unable to delete shifttype.');
}
engelsystem_log('Deleted shifttype ' . $shifttype['name']); engelsystem_log('Deleted shifttype ' . $shifttype['name']);
success(sprintf(_('Shifttype %s deleted.'), $shifttype['name'])); success(sprintf(_('Shifttype %s deleted.'), $shifttype['name']));
@ -33,27 +36,28 @@ function shifttype_delete_controller() {
} }
return [ return [
sprintf(_("Delete shifttype %s"), $shifttype['name']), sprintf(_('Delete shifttype %s'), $shifttype['name']),
ShiftType_delete_view($shifttype) ShiftType_delete_view($shifttype)
]; ];
} }
/** /**
* Edit or create shift type. * Edit or create shift type.
*
* @return array
*/ */
function shifttype_edit_controller() { function shifttype_edit_controller()
{
$shifttype_id = null; $shifttype_id = null;
$name = ""; $name = '';
$angeltype_id = null; $angeltype_id = null;
$description = ""; $description = '';
$angeltypes = AngelTypes(); $angeltypes = AngelTypes();
$request = request();
if (isset($_REQUEST['shifttype_id'])) { if ($request->has('shifttype_id')) {
$shifttype = ShiftType($_REQUEST['shifttype_id']); $shifttype = ShiftType($request->input('shifttype_id'));
if ($shifttype === false) {
engelsystem_error('Unable to load shifttype.');
}
if ($shifttype == null) { if ($shifttype == null) {
error(_('Shifttype not found.')); error(_('Shifttype not found.'));
redirect(page_link_to('shifttypes')); redirect(page_link_to('shifttypes'));
@ -64,43 +68,39 @@ function shifttype_edit_controller() {
$description = $shifttype['description']; $description = $shifttype['description'];
} }
if (isset($_REQUEST['submit'])) { if ($request->has('submit')) {
$valid = true; $valid = true;
if (isset($_REQUEST['name']) && $_REQUEST['name'] != '') { if ($request->has('name') && $request->input('name') != '') {
$name = strip_request_item('name'); $name = strip_request_item('name');
} else { } else {
$valid = false; $valid = false;
error(_('Please enter a name.')); error(_('Please enter a name.'));
} }
if (isset($_REQUEST['angeltype_id']) && preg_match("/^[0-9]+$/", $_REQUEST['angeltype_id'])) { if ($request->has('angeltype_id') && preg_match('/^\d+$/', $request->input('angeltype_id'))) {
$angeltype_id = $_REQUEST['angeltype_id']; $angeltype_id = $request->input('angeltype_id');
} else { } else {
$angeltype_id = null; $angeltype_id = null;
} }
if (isset($_REQUEST['description'])) { if ($request->has('description')) {
$description = strip_request_item_nl('description'); $description = strip_request_item_nl('description');
} }
if ($valid) { if ($valid) {
if ($shifttype_id) { if ($shifttype_id) {
$result = ShiftType_update($shifttype_id, $name, $angeltype_id, $description); ShiftType_update($shifttype_id, $name, $angeltype_id, $description);
if ($result === false) {
engelsystem_error('Unable to update shifttype.');
}
engelsystem_log('Updated shifttype ' . $name); engelsystem_log('Updated shifttype ' . $name);
success(_('Updated shifttype.')); success(_('Updated shifttype.'));
} else { } else {
$shifttype_id = ShiftType_create($name, $angeltype_id, $description); $shifttype_id = ShiftType_create($name, $angeltype_id, $description);
if ($shifttype_id === false) {
engelsystem_error('Unable to create shifttype.');
}
engelsystem_log('Created shifttype ' . $name); engelsystem_log('Created shifttype ' . $name);
success(_('Created shifttype.')); success(_('Created shifttype.'));
} }
redirect(page_link_to('shifttypes') . '&action=view&shifttype_id=' . $shifttype_id); redirect(page_link_to('shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype_id]));
} }
} }
@ -110,14 +110,16 @@ function shifttype_edit_controller() {
]; ];
} }
function shifttype_controller() { /**
if (! isset($_REQUEST['shifttype_id'])) { * @return array
*/
function shifttype_controller()
{
$request = request();
if (!$request->has('shifttype_id')) {
redirect(page_link_to('shifttypes')); redirect(page_link_to('shifttypes'));
} }
$shifttype = ShiftType($_REQUEST['shifttype_id']); $shifttype = ShiftType($request->input('shifttype_id'));
if ($shifttype === false) {
engelsystem_error('Unable to load shifttype.');
}
if ($shifttype == null) { if ($shifttype == null) {
redirect(page_link_to('shifttypes')); redirect(page_link_to('shifttypes'));
} }
@ -135,12 +137,12 @@ function shifttype_controller() {
/** /**
* List all shift types. * List all shift types.
*
* @return array
*/ */
function shifttypes_list_controller() { function shifttypes_list_controller()
{
$shifttypes = ShiftTypes(); $shifttypes = ShiftTypes();
if ($shifttypes === false) {
engelsystem_error("Unable to load shifttypes.");
}
return [ return [
shifttypes_title(), shifttypes_title(),
@ -150,30 +152,36 @@ function shifttypes_list_controller() {
/** /**
* Text for shift type related links. * Text for shift type related links.
*
* @return string
*/ */
function shifttypes_title() { function shifttypes_title()
return _("Shifttypes"); {
return _('Shifttypes');
} }
/** /**
* Route shift type actions * Route shift type actions
*
* @return array
*/ */
function shifttypes_controller() { function shifttypes_controller()
if (! isset($_REQUEST['action'])) { {
$_REQUEST['action'] = 'list'; $request = request();
$action = 'list';
if ($request->has('action')) {
$action = $request->input('action');
} }
switch ($_REQUEST['action']) { switch ($action) {
default:
case 'list':
return shifttypes_list_controller();
case 'view': case 'view':
return shifttype_controller(); return shifttype_controller();
case 'edit': case 'edit':
return shifttype_edit_controller(); return shifttype_edit_controller();
case 'delete': case 'delete':
return shifttype_delete_controller(); return shifttype_delete_controller();
case 'list':
default:
return shifttypes_list_controller();
} }
} }
?>

View File

@ -2,8 +2,11 @@
/** /**
* Display a hint for team/angeltype supporters if there are unconfirmed users for his angeltype. * Display a hint for team/angeltype supporters if there are unconfirmed users for his angeltype.
*
* @return string|null
*/ */
function user_angeltypes_unconfirmed_hint() { function user_angeltypes_unconfirmed_hint()
{
global $user; global $user;
$unconfirmed_user_angeltypes = User_unconfirmed_AngelTypes($user); $unconfirmed_user_angeltypes = User_unconfirmed_AngelTypes($user);
@ -13,247 +16,281 @@ function user_angeltypes_unconfirmed_hint() {
$unconfirmed_links = []; $unconfirmed_links = [];
foreach ($unconfirmed_user_angeltypes as $user_angeltype) { foreach ($unconfirmed_user_angeltypes as $user_angeltype) {
$unconfirmed_links[] = '<a href="' . page_link_to('angeltypes') . '&action=view&angeltype_id=' . $user_angeltype['angeltype_id'] . '">' . $user_angeltype['name'] . ' (+' . $user_angeltype['count'] . ')' . '</a>'; $unconfirmed_links[] = '<a href="'
. page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $user_angeltype['angeltype_id']])
. '">' . $user_angeltype['name']
. ' (+' . $user_angeltype['count'] . ')'
. '</a>';
} }
return sprintf(ngettext("There is %d unconfirmed angeltype.", "There are %d unconfirmed angeltypes.", count($unconfirmed_user_angeltypes)), count($unconfirmed_user_angeltypes)) . " " . _('Angel types which need approvals:') . ' ' . join(', ', $unconfirmed_links); return sprintf(ngettext('There is %d unconfirmed angeltype.', 'There are %d unconfirmed angeltypes.',
count($unconfirmed_user_angeltypes)),
count($unconfirmed_user_angeltypes)) . ' ' . _('Angel types which need approvals:') . ' ' . join(', ',
$unconfirmed_links);
} }
/** /**
* Remove all unconfirmed users from a specific angeltype. * Remove all unconfirmed users from a specific angeltype.
*
* @return array
*/ */
function user_angeltypes_delete_all_controller() { function user_angeltypes_delete_all_controller()
{
global $user; global $user;
$request = request();
if (! isset($_REQUEST['angeltype_id'])) { if (!$request->has('angeltype_id')) {
error(_("Angeltype doesn't exist.")); error(_('Angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$angeltype = AngelType($_REQUEST['angeltype_id']); $angeltype = AngelType($request->input('angeltype_id'));
if ($angeltype == null) { if ($angeltype == null) {
error(_("Angeltype doesn't exist.")); error(_('Angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
if (! User_is_AngelType_supporter($user, $angeltype)) { if (!User_is_AngelType_supporter($user, $angeltype)) {
error(_("You are not allowed to delete all users for this angeltype.")); error(_('You are not allowed to delete all users for this angeltype.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
if (isset($_REQUEST['confirmed'])) { if ($request->has('confirmed')) {
UserAngelTypes_delete_all($angeltype['id']); UserAngelTypes_delete_all($angeltype['id']);
engelsystem_log(sprintf("Denied all users for angeltype %s", AngelType_name_render($angeltype))); engelsystem_log(sprintf('Denied all users for angeltype %s', AngelType_name_render($angeltype)));
success(sprintf(_("Denied all users for angeltype %s."), AngelType_name_render($angeltype))); success(sprintf(_('Denied all users for angeltype %s.'), AngelType_name_render($angeltype)));
redirect(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id']); redirect(page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]));
} }
return [ return [
_("Deny all users"), _('Deny all users'),
UserAngelTypes_delete_all_view($angeltype) UserAngelTypes_delete_all_view($angeltype)
]; ];
} }
/** /**
* Confirm all unconfirmed users for an angeltype. * Confirm all unconfirmed users for an angeltype.
*
* @return array
*/ */
function user_angeltypes_confirm_all_controller() { function user_angeltypes_confirm_all_controller()
{
global $user, $privileges; global $user, $privileges;
$request = request();
if (! isset($_REQUEST['angeltype_id'])) { if (!$request->has('angeltype_id')) {
error(_("Angeltype doesn't exist.")); error(_('Angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$angeltype = AngelType($_REQUEST['angeltype_id']); $angeltype = AngelType($request->input('angeltype_id'));
if ($angeltype == null) { if ($angeltype == null) {
error(_("Angeltype doesn't exist.")); error(_('Angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype); $user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype);
if ($user_angeltype == null) { if ($user_angeltype == null) {
error(_("User angeltype doesn't exist.")); error(_('User angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
if (! in_array('admin_user_angeltypes', $privileges) && ! $user_angeltype['supporter']) { if (!in_array('admin_user_angeltypes', $privileges) && !$user_angeltype['supporter']) {
error(_("You are not allowed to confirm all users for this angeltype.")); error(_('You are not allowed to confirm all users for this angeltype.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
if (isset($_REQUEST['confirmed'])) { if ($request->has('confirmed')) {
UserAngelTypes_confirm_all($angeltype['id'], $user); UserAngelTypes_confirm_all($angeltype['id'], $user);
engelsystem_log(sprintf("Confirmed all users for angeltype %s", AngelType_name_render($angeltype))); engelsystem_log(sprintf('Confirmed all users for angeltype %s', AngelType_name_render($angeltype)));
success(sprintf(_("Confirmed all users for angeltype %s."), AngelType_name_render($angeltype))); success(sprintf(_('Confirmed all users for angeltype %s.'), AngelType_name_render($angeltype)));
redirect(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id']); redirect(page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]));
} }
return [ return [
_("Confirm all users"), _('Confirm all users'),
UserAngelTypes_confirm_all_view($angeltype) UserAngelTypes_confirm_all_view($angeltype)
]; ];
} }
/** /**
* Confirm an user for an angeltype. * Confirm an user for an angeltype.
*
* @return array
*/ */
function user_angeltype_confirm_controller() { function user_angeltype_confirm_controller()
{
global $user; global $user;
$request = request();
if (! isset($_REQUEST['user_angeltype_id'])) { if (!$request->has('user_angeltype_id')) {
error(_("User angeltype doesn't exist.")); error(_('User angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$user_angeltype = UserAngelType($_REQUEST['user_angeltype_id']); $user_angeltype = UserAngelType($request->input('user_angeltype_id'));
if ($user_angeltype == null) { if ($user_angeltype == null) {
error(_("User angeltype doesn't exist.")); error(_('User angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$angeltype = AngelType($user_angeltype['angeltype_id']); $angeltype = AngelType($user_angeltype['angeltype_id']);
if ($angeltype == null) { if ($angeltype == null) {
error(_("Angeltype doesn't exist.")); error(_('Angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
if (! User_is_AngelType_supporter($user, $angeltype)) { if (!User_is_AngelType_supporter($user, $angeltype)) {
error(_("You are not allowed to confirm this users angeltype.")); error(_('You are not allowed to confirm this users angeltype.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$user_source = User($user_angeltype['user_id']); $user_source = User($user_angeltype['user_id']);
if ($user_source == null) { if ($user_source == null) {
error(_("User doesn't exist.")); error(_('User doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
if (isset($_REQUEST['confirmed'])) { if ($request->has('confirmed')) {
$result = UserAngelType_confirm($user_angeltype['id'], $user); 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_render($angeltype))); engelsystem_log(sprintf(
success(sprintf(_("%s confirmed for angeltype %s."), User_Nick_render($user_source), AngelType_name_render($angeltype))); '%s confirmed for angeltype %s',
redirect(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id']); User_Nick_render($user_source),
AngelType_name_render($angeltype)
));
success(sprintf(
_('%s confirmed for angeltype %s.'),
User_Nick_render($user_source),
AngelType_name_render($angeltype)
));
redirect(page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]));
} }
return [ return [
_("Confirm angeltype for user"), _('Confirm angeltype for user'),
UserAngelType_confirm_view($user_angeltype, $user_source, $angeltype) UserAngelType_confirm_view($user_angeltype, $user_source, $angeltype)
]; ];
} }
/** /**
* Remove a user from an Angeltype. * Remove a user from an Angeltype.
*
* @return array
*/ */
function user_angeltype_delete_controller() { function user_angeltype_delete_controller()
{
global $user; global $user;
$request = request();
if (! isset($_REQUEST['user_angeltype_id'])) { if (!$request->has('user_angeltype_id')) {
error(_("User angeltype doesn't exist.")); error(_('User angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$user_angeltype = UserAngelType($_REQUEST['user_angeltype_id']); $user_angeltype = UserAngelType($request->input('user_angeltype_id'));
if ($user_angeltype == null) { if ($user_angeltype == null) {
error(_("User angeltype doesn't exist.")); error(_('User angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$angeltype = AngelType($user_angeltype['angeltype_id']); $angeltype = AngelType($user_angeltype['angeltype_id']);
if ($angeltype == null) { if ($angeltype == null) {
error(_("Angeltype doesn't exist.")); error(_('Angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$user_source = User($user_angeltype['user_id']); $user_source = User($user_angeltype['user_id']);
if ($user_source == null) { if ($user_source == null) {
error(_("User doesn't exist.")); error(_('User doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
if ($user['UID'] != $user_angeltype['user_id'] && ! User_is_AngelType_supporter($user, $angeltype)) { if ($user['UID'] != $user_angeltype['user_id'] && !User_is_AngelType_supporter($user, $angeltype)) {
error(_("You are not allowed to delete this users angeltype.")); error(_('You are not allowed to delete this users angeltype.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
if (isset($_REQUEST['confirmed'])) { if ($request->has('confirmed')) {
$result = UserAngelType_delete($user_angeltype); 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']); $success_message = sprintf(_('User %s removed from %s.'), User_Nick_render($user_source), $angeltype['name']);
engelsystem_log($success_message); engelsystem_log($success_message);
success($success_message); success($success_message);
redirect(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id']); redirect(page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]));
} }
return [ return [
_("Remove angeltype"), _('Remove angeltype'),
UserAngelType_delete_view($user_angeltype, $user_source, $angeltype) UserAngelType_delete_view($user_angeltype, $user_source, $angeltype)
]; ];
} }
/** /**
* Update an UserAngelType. * Update an UserAngelType.
*
* @return array
*/ */
function user_angeltype_update_controller() { function user_angeltype_update_controller()
{
global $privileges; global $privileges;
$supporter = false;
$request = request();
if (! in_array('admin_angel_types', $privileges)) { if (!in_array('admin_angel_types', $privileges)) {
error(_("You are not allowed to set supporter rights.")); error(_('You are not allowed to set supporter rights.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
if (! isset($_REQUEST['user_angeltype_id'])) { if (!$request->has('user_angeltype_id')) {
error(_("User angeltype doesn't exist.")); error(_('User angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
if (isset($_REQUEST['supporter']) && preg_match("/^[01]$/", $_REQUEST['supporter'])) { if ($request->has('supporter') && preg_match('/^[01]$/', $request->input('supporter'))) {
$supporter = $_REQUEST['supporter'] == "1"; $supporter = $request->input('supporter') == '1';
} else { } else {
error(_("No supporter update given.")); error(_('No supporter update given.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$user_angeltype = UserAngelType($_REQUEST['user_angeltype_id']); $user_angeltype = UserAngelType($request->input('user_angeltype_id'));
if ($user_angeltype == null) { if ($user_angeltype == null) {
error(_("User angeltype doesn't exist.")); error(_('User angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$angeltype = AngelType($user_angeltype['angeltype_id']); $angeltype = AngelType($user_angeltype['angeltype_id']);
if ($angeltype == null) { if ($angeltype == null) {
error(_("Angeltype doesn't exist.")); error(_('Angeltype doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
$user_source = User($user_angeltype['user_id']); $user_source = User($user_angeltype['user_id']);
if ($user_source == null) { if ($user_source == null) {
error(_("User doesn't exist.")); error(_('User doesn\'t exist.'));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
if (isset($_REQUEST['confirmed'])) { if ($request->has('confirmed')) {
UserAngelType_update($user_angeltype['id'], $supporter); UserAngelType_update($user_angeltype['id'], $supporter);
$success_message = sprintf($supporter ? _("Added supporter rights for %s to %s.") : _("Removed supporter rights for %s from %s."), AngelType_name_render($angeltype), User_Nick_render($user_source)); $success_message = sprintf(
$supporter ? _('Added supporter rights for %s to %s.') : _('Removed supporter rights for %s from %s.'),
AngelType_name_render($angeltype),
User_Nick_render($user_source)
);
engelsystem_log($success_message); engelsystem_log($success_message);
success($success_message); success($success_message);
redirect(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id']); redirect(page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]));
} }
return [ return [
$supporter ? _("Add supporter rights") : _("Remove supporter rights"), $supporter ? _('Add supporter rights') : _('Remove supporter rights'),
UserAngelType_update_view($user_angeltype, $user_source, $angeltype, $supporter) UserAngelType_update_view($user_angeltype, $user_source, $angeltype, $supporter)
]; ];
} }
@ -261,13 +298,13 @@ function user_angeltype_update_controller() {
/** /**
* User joining an Angeltype (Or supporter doing this for him). * User joining an Angeltype (Or supporter doing this for him).
*/ */
function user_angeltype_add_controller() { function user_angeltype_add_controller()
{
global $user; global $user;
$angeltype = load_angeltype(); $angeltype = load_angeltype();
// User is joining by itself // User is joining by itself
if (! User_is_AngelType_supporter($user, $angeltype)) { if (!User_is_AngelType_supporter($user, $angeltype)) {
return user_angeltype_join_controller($angeltype); return user_angeltype_join_controller($angeltype);
} }
@ -279,70 +316,94 @@ function user_angeltype_add_controller() {
// Load possible users, that are not in the angeltype already // Load possible users, that are not in the angeltype already
$users_source = Users_by_angeltype_inverted($angeltype); $users_source = Users_by_angeltype_inverted($angeltype);
if (isset($_REQUEST['submit'])) { if (request()->has('submit')) {
$user_source = load_user(); $user_source = load_user();
if (! UserAngelType_exists($user_source, $angeltype)) { if (!UserAngelType_exists($user_source, $angeltype)) {
$user_angeltype_id = UserAngelType_create($user_source, $angeltype); $user_angeltype_id = UserAngelType_create($user_source, $angeltype);
engelsystem_log(sprintf("User %s added to %s.", User_Nick_render($user_source), AngelType_name_render($angeltype))); engelsystem_log(sprintf(
success(sprintf(_("User %s added to %s."), User_Nick_render($user_source), AngelType_name_render($angeltype))); 'User %s added to %s.',
User_Nick_render($user_source),
AngelType_name_render($angeltype)
));
success(sprintf(
_('User %s added to %s.'),
User_Nick_render($user_source),
AngelType_name_render($angeltype)
));
UserAngelType_confirm($user_angeltype_id, $user_source); UserAngelType_confirm($user_angeltype_id, $user_source);
engelsystem_log(sprintf("User %s confirmed as %s.", User_Nick_render($user), AngelType_name_render($angeltype))); engelsystem_log(sprintf(
'User %s confirmed as %s.',
User_Nick_render($user),
AngelType_name_render($angeltype)
));
redirect(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id']); redirect(page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]));
} }
} }
return [ return [
_("Add user to angeltype"), _('Add user to angeltype'),
UserAngelType_add_view($angeltype, $users_source, $user_source['UID']) UserAngelType_add_view($angeltype, $users_source, $user_source['UID'])
]; ];
} }
/** /**
* A user joins an angeltype. * A user joins an angeltype.
*
* @param array $angeltype
* @return array
*/ */
function user_angeltype_join_controller($angeltype) { function user_angeltype_join_controller($angeltype)
{
global $user, $privileges; global $user, $privileges;
$user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype); $user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype);
if ($user_angeltype != null) { if ($user_angeltype != null) {
error(sprintf(_("You are already a %s."), $angeltype['name'])); error(sprintf(_('You are already a %s.'), $angeltype['name']));
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
if (isset($_REQUEST['confirmed'])) { if (request()->has('confirmed')) {
$user_angeltype_id = UserAngelType_create($user, $angeltype); $user_angeltype_id = UserAngelType_create($user, $angeltype);
$success_message = sprintf(_("You joined %s."), $angeltype['name']); $success_message = sprintf(_('You joined %s.'), $angeltype['name']);
engelsystem_log(sprintf("User %s joined %s.", User_Nick_render($user), AngelType_name_render($angeltype))); engelsystem_log(sprintf('User %s joined %s.', User_Nick_render($user), AngelType_name_render($angeltype)));
success($success_message); success($success_message);
if (in_array('admin_user_angeltypes', $privileges)) { if (in_array('admin_user_angeltypes', $privileges)) {
UserAngelType_confirm($user_angeltype_id, $user); UserAngelType_confirm($user_angeltype_id, $user);
engelsystem_log(sprintf("User %s confirmed as %s.", User_Nick_render($user), AngelType_name_render($angeltype))); engelsystem_log(sprintf(
'User %s confirmed as %s.',
User_Nick_render($user),
AngelType_name_render($angeltype)
));
} }
redirect(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id']); redirect(page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]));
} }
return [ return [
sprintf(_("Become a %s"), $angeltype['name']), sprintf(_('Become a %s'), $angeltype['name']),
UserAngelType_join_view($user, $angeltype) UserAngelType_join_view($user, $angeltype)
]; ];
} }
/** /**
* Route UserAngelType actions. * Route UserAngelType actions.
*
* @return array
*/ */
function user_angeltypes_controller() { function user_angeltypes_controller()
if (! isset($_REQUEST['action'])) { {
$request = request();
if (!$request->has('action')) {
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
switch ($_REQUEST['action']) { switch ($request->input('action')) {
case 'delete_all': case 'delete_all':
return user_angeltypes_delete_all_controller(); return user_angeltypes_delete_all_controller();
case 'confirm_all': case 'confirm_all':
@ -359,5 +420,3 @@ function user_angeltypes_controller() {
redirect(page_link_to('angeltypes')); redirect(page_link_to('angeltypes'));
} }
} }
?>

View File

@ -1,9 +1,13 @@
<?php <?php
/** /**
* Generates a hint, if user joined angeltypes that require a driving license and the user has no driver license information provided. * Generates a hint, if user joined angeltypes that require a driving license and the user has no driver license
* information provided.
*
* @return string|null
*/ */
function user_driver_license_required_hint() { function user_driver_license_required_hint()
{
global $user; global $user;
$angeltypes = User_angeltypes($user); $angeltypes = User_angeltypes($user);
@ -16,7 +20,10 @@ function user_driver_license_required_hint() {
foreach ($angeltypes as $angeltype) { foreach ($angeltypes as $angeltype) {
if ($angeltype['requires_driver_license']) { if ($angeltype['requires_driver_license']) {
return sprintf(_("You joined an angeltype which requires a driving license. Please edit your driving license information here: %s."), '<a href="' . user_driver_license_edit_link() . '">' . _("driving license information") . '</a>'); return sprintf(
_('You joined an angeltype which requires a driving license. Please edit your driving license information here: %s.'),
'<a href="' . user_driver_license_edit_link() . '">' . _('driving license information') . '</a>'
);
} }
} }
@ -25,11 +32,14 @@ function user_driver_license_required_hint() {
/** /**
* Route user driver licenses actions. * Route user driver licenses actions.
*
* @return array
*/ */
function user_driver_licenses_controller() { function user_driver_licenses_controller()
{
global $user; global $user;
if (! isset($user)) { if (!isset($user)) {
redirect(page_link_to('')); redirect(page_link_to(''));
} }
@ -45,25 +55,30 @@ function user_driver_licenses_controller() {
/** /**
* Link to user driver license edit page for given user. * Link to user driver license edit page for given user.
* *
* @param User $user * @param array $user
* @return string
*/ */
function user_driver_license_edit_link($user = null) { function user_driver_license_edit_link($user = null)
{
if ($user == null) { if ($user == null) {
return page_link_to('user_driver_licenses'); return page_link_to('user_driver_licenses');
} }
return page_link_to('user_driver_licenses') . '&user_id=' . $user['UID']; return page_link_to('user_driver_licenses', ['user_id' => $user['UID']]);
} }
/** /**
* Loads the user for the driver license. * Loads the user for the driver license.
*
* @return array
*/ */
function user_driver_license_load_user() { function user_driver_license_load_user()
{
global $user; global $user;
$request = request();
$user_source = $user; $user_source = $user;
if (isset($_REQUEST['user_id'])) { if ($request->has('user_id')) {
$user_source = User($_REQUEST['user_id']); $user_source = User($request->input('user_id'));
if ($user_source == null) { if ($user_source == null) {
redirect(user_driver_license_edit_link()); redirect(user_driver_license_edit_link());
} }
@ -74,14 +89,17 @@ function user_driver_license_load_user() {
/** /**
* Edit a users driver license information. * Edit a users driver license information.
*
* @return array
*/ */
function user_driver_license_edit_controller() { function user_driver_license_edit_controller()
{
global $privileges, $user; global $privileges, $user;
$request = request();
$user_source = user_driver_license_load_user(); $user_source = user_driver_license_load_user();
// only privilege admin_user can edit other users driver license information // only privilege admin_user can edit other users driver license information
if ($user['UID'] != $user_source['UID'] && ! in_array('admin_user', $privileges)) { if ($user['UID'] != $user_source['UID'] && !in_array('admin_user', $privileges)) {
redirect(user_driver_license_edit_link()); redirect(user_driver_license_edit_link());
} }
@ -93,40 +111,38 @@ function user_driver_license_edit_controller() {
$wants_to_drive = true; $wants_to_drive = true;
} }
if (isset($_REQUEST['submit'])) { if ($request->has('submit')) {
$wants_to_drive = isset($_REQUEST['wants_to_drive']); $wants_to_drive = $request->has('wants_to_drive');
if ($wants_to_drive) { if ($wants_to_drive) {
$user_driver_license['has_car'] = isset($_REQUEST['has_car']); $user_driver_license['has_car'] = $request->has('has_car');
$user_driver_license['has_license_car'] = isset($_REQUEST['has_license_car']); $user_driver_license['has_license_car'] = $request->has('has_license_car');
$user_driver_license['has_license_3_5t_transporter'] = isset($_REQUEST['has_license_3_5t_transporter']); $user_driver_license['has_license_3_5t_transporter'] = $request->has('has_license_3_5t_transporter');
$user_driver_license['has_license_7_5t_truck'] = isset($_REQUEST['has_license_7_5t_truck']); $user_driver_license['has_license_7_5t_truck'] = $request->has('has_license_7_5t_truck');
$user_driver_license['has_license_12_5t_truck'] = isset($_REQUEST['has_license_12_5t_truck']); $user_driver_license['has_license_12_5t_truck'] = $request->has('has_license_12_5t_truck');
$user_driver_license['has_license_forklift'] = isset($_REQUEST['has_license_forklift']); $user_driver_license['has_license_forklift'] = $request->has('has_license_forklift');
if (UserDriverLicense_valid($user_driver_license)) { if (UserDriverLicense_valid($user_driver_license)) {
if ($user_driver_license['user_id'] == null) { if ($user_driver_license['user_id'] == null) {
$user_driver_license = UserDriverLicenses_create($user_driver_license, $user); $user_driver_license = UserDriverLicenses_create($user_driver_license, $user_source);
} else { } else {
UserDriverLicenses_update($user_driver_license); UserDriverLicenses_update($user_driver_license);
} }
engelsystem_log("Driver license information updated."); engelsystem_log('Driver license information updated.');
success(_("Your driver license information has been saved.")); success(_('Your driver license information has been saved.'));
redirect(user_link($user_source)); redirect(user_link($user_source));
} else { } else {
error(_("Please select at least one driving license.")); error(_('Please select at least one driving license.'));
} }
} elseif ($user_driver_license['id'] != null) { } elseif ($user_driver_license['user_id'] != null) {
UserDriverLicenses_delete($user_source['UID']); UserDriverLicenses_delete($user_source['UID']);
engelsystem_log("Driver license information removed."); engelsystem_log('Driver license information removed.');
success(_("Your driver license information has been removed.")); success(_('Your driver license information has been removed.'));
redirect(user_link($user_source)); redirect(user_link($user_source));
} }
} }
return [ return [
sprintf(_("Edit %s driving license information"), $user_source['Nick']), sprintf(_('Edit %s driving license information'), $user_source['Nick']),
UserDriverLicense_edit_view($user_source, $wants_to_drive, $user_driver_license) UserDriverLicense_edit_view($user_source, $wants_to_drive, $user_driver_license)
]; ];
} }
?>

View File

@ -1,239 +1,316 @@
<?php <?php
use Engelsystem\ShiftsFilter;
use Engelsystem\Database\DB;
use Engelsystem\ShiftCalendarRenderer; use Engelsystem\ShiftCalendarRenderer;
use Engelsystem\ShiftsFilter;
/** /**
* Route user actions. * Route user actions.
*
* @return array
*/ */
function users_controller() { function users_controller()
{
global $user; global $user;
$request = request();
if (! isset($user)) { if (!isset($user)) {
redirect(page_link_to('')); redirect(page_link_to(''));
} }
if (! isset($_REQUEST['action'])) { $action = 'list';
$_REQUEST['action'] = 'list'; if ($request->has('action')) {
$action = $request->input('action');
} }
switch ($_REQUEST['action']) { switch ($action) {
default:
case 'list':
return users_list_controller();
case 'view': case 'view':
return user_controller(); return user_controller();
case 'edit':
return user_edit_controller();
case 'delete': case 'delete':
return user_delete_controller(); return user_delete_controller();
case 'edit_vouchers': case 'edit_vouchers':
return user_edit_vouchers_controller(); return user_edit_vouchers_controller();
case 'list':
default:
return users_list_controller();
} }
} }
/** /**
* Delete a user, requires to enter own password for reasons. * Delete a user, requires to enter own password for reasons.
*
* @return array
*/ */
function user_delete_controller() { function user_delete_controller()
{
global $privileges, $user; global $privileges, $user;
$request = request();
if (isset($_REQUEST['user_id'])) { if ($request->has('user_id')) {
$user_source = User($_REQUEST['user_id']); $user_source = User($request->query->get('user_id'));
} else { } else {
$user_source = $user; $user_source = $user;
} }
if (! in_array('admin_user', $privileges)) { if (!in_array('admin_user', $privileges)) {
redirect(page_link_to('')); redirect(page_link_to(''));
} }
// You cannot delete yourself // You cannot delete yourself
if ($user['UID'] == $user_source['UID']) { if ($user['UID'] == $user_source['UID']) {
error(_("You cannot delete yourself.")); error(_('You cannot delete yourself.'));
redirect(user_link($user)); redirect(user_link($user));
} }
if (isset($_REQUEST['submit'])) { if ($request->has('submit')) {
$valid = true; $valid = true;
if (! (isset($_REQUEST['password']) && verify_password($_REQUEST['password'], $user['Passwort'], $user['UID']))) { if (
!(
$request->has('password')
&& verify_password($request->postData('password'), $user['Passwort'], $user['UID'])
)
) {
$valid = false; $valid = false;
error(_("Your password is incorrect. Please try it again.")); error(_('Your password is incorrect. Please try it again.'));
} }
if ($valid) { if ($valid) {
$result = User_delete($user_source['UID']); User_delete($user_source['UID']);
if ($result === false) {
engelsystem_error('Unable to delete user.');
}
mail_user_delete($user_source); mail_user_delete($user_source);
success(_("User deleted.")); success(_('User deleted.'));
engelsystem_log(sprintf("Deleted %s", User_Nick_render($user_source))); engelsystem_log(sprintf('Deleted %s', User_Nick_render($user_source)));
redirect(users_link()); redirect(users_link());
} }
} }
return [ return [
sprintf(_("Delete %s"), $user_source['Nick']), sprintf(_('Delete %s'), $user_source['Nick']),
User_delete_view($user_source) User_delete_view($user_source)
]; ];
} }
function users_link() { /**
* @return string
*/
function users_link()
{
return page_link_to('users'); return page_link_to('users');
} }
function user_edit_link($user) { /**
return page_link_to('admin_user') . '&user_id=' . $user['UID']; * @param array $user
* @return string
*/
function user_edit_link($user)
{
return page_link_to('admin_user', ['user_id' => $user['UID']]);
} }
function user_delete_link($user) { /**
return page_link_to('users') . '&action=delete&user_id=' . $user['UID']; * @param array $user
* @return string
*/
function user_delete_link($user)
{
return page_link_to('users', ['action' => 'delete', 'user_id' => $user['UID']]);
} }
function user_link($user) { /**
return page_link_to('users') . '&action=view&user_id=' . $user['UID']; * @param array $user
* @return string
*/
function user_link($user)
{
return page_link_to('users', ['action' => 'view', 'user_id' => $user['UID']]);
} }
function user_edit_vouchers_controller() { /**
* @return array
*/
function user_edit_vouchers_controller()
{
global $privileges, $user; global $privileges, $user;
$request = request();
if (isset($_REQUEST['user_id'])) { if ($request->has('user_id')) {
$user_source = User($_REQUEST['user_id']); $user_source = User($request->input('user_id'));
} else { } else {
$user_source = $user; $user_source = $user;
} }
if (! in_array('admin_user', $privileges)) { if (!in_array('admin_user', $privileges)) {
redirect(page_link_to('')); redirect(page_link_to(''));
} }
if (isset($_REQUEST['submit'])) { if ($request->has('submit')) {
$valid = true; $valid = true;
if (isset($_REQUEST['vouchers']) && test_request_int('vouchers') && trim($_REQUEST['vouchers']) >= 0) { $vouchers = '';
$vouchers = trim($_REQUEST['vouchers']); if (
$request->has('vouchers')
&& test_request_int('vouchers')
&& trim($request->input('vouchers')) >= 0
) {
$vouchers = trim($request->input('vouchers'));
} else { } else {
$valid = false; $valid = false;
error(_("Please enter a valid number of vouchers.")); error(_('Please enter a valid number of vouchers.'));
} }
if ($valid) { if ($valid) {
$user_source['got_voucher'] = $vouchers; $user_source['got_voucher'] = $vouchers;
$result = User_update($user_source); User_update($user_source);
if ($result === false) {
engelsystem_error('Unable to update user.');
}
success(_("Saved the number of vouchers.")); success(_('Saved the number of vouchers.'));
engelsystem_log(User_Nick_render($user_source) . ': ' . sprintf("Got %s vouchers", $user_source['got_voucher'])); engelsystem_log(User_Nick_render($user_source) . ': ' . sprintf('Got %s vouchers',
$user_source['got_voucher']));
redirect(user_link($user_source)); redirect(user_link($user_source));
} }
} }
return [ return [
sprintf(_("%s's vouchers"), $user_source['Nick']), sprintf(_('%s\'s vouchers'), $user_source['Nick']),
User_edit_vouchers_view($user_source) User_edit_vouchers_view($user_source)
]; ];
} }
function user_controller() { /**
* @return array
*/
function user_controller()
{
global $privileges, $user; global $privileges, $user;
$request = request();
$user_source = $user; $user_source = $user;
if (isset($_REQUEST['user_id'])) { if ($request->has('user_id')) {
$user_source = User($_REQUEST['user_id']); $user_source = User($request->input('user_id'));
if ($user_source == null) { if ($user_source == null) {
error(_("User not found.")); error(_('User not found.'));
redirect('?'); redirect(page_link_to('/'));
} }
} }
$shifts = Shifts_by_user($user_source, in_array("user_shifts_admin", $privileges)); $shifts = Shifts_by_user($user_source, in_array('user_shifts_admin', $privileges));
foreach ($shifts as &$shift) { foreach ($shifts as &$shift) {
// TODO: Move queries to model // TODO: Move queries to model
$shift['needed_angeltypes'] = sql_select("SELECT DISTINCT `AngelTypes`.* FROM `ShiftEntry` JOIN `AngelTypes` ON `ShiftEntry`.`TID`=`AngelTypes`.`id` WHERE `ShiftEntry`.`SID`='" . sql_escape($shift['SID']) . "' ORDER BY `AngelTypes`.`name`"); $shift['needed_angeltypes'] = DB::select('
SELECT DISTINCT `AngelTypes`.*
FROM `ShiftEntry`
JOIN `AngelTypes` ON `ShiftEntry`.`TID`=`AngelTypes`.`id`
WHERE `ShiftEntry`.`SID` = ?
ORDER BY `AngelTypes`.`name`
',
[$shift['SID']]
);
foreach ($shift['needed_angeltypes'] as &$needed_angeltype) { foreach ($shift['needed_angeltypes'] as &$needed_angeltype) {
$needed_angeltype['users'] = sql_select(" $needed_angeltype['users'] = DB::select('
SELECT `ShiftEntry`.`freeloaded`, `User`.* SELECT `ShiftEntry`.`freeloaded`, `User`.*
FROM `ShiftEntry` FROM `ShiftEntry`
JOIN `User` ON `ShiftEntry`.`UID`=`User`.`UID` JOIN `User` ON `ShiftEntry`.`UID`=`User`.`UID`
WHERE `ShiftEntry`.`SID`='" . sql_escape($shift['SID']) . "' WHERE `ShiftEntry`.`SID` = ?
AND `ShiftEntry`.`TID`='" . sql_escape($needed_angeltype['id']) . "'"); AND `ShiftEntry`.`TID` = ?
',
[$shift['SID'], $needed_angeltype['id']]
);
} }
} }
if ($user_source['api_key'] == "") { if ($user_source['api_key'] == '') {
User_reset_api_key($user_source, false); User_reset_api_key($user_source, false);
} }
return [ return [
$user_source['Nick'], $user_source['Nick'],
User_view($user_source, in_array('admin_user', $privileges), User_is_freeloader($user_source), User_angeltypes($user_source), User_groups($user_source), $shifts, $user['UID'] == $user_source['UID']) User_view(
$user_source,
in_array('admin_user', $privileges),
User_is_freeloader($user_source),
User_angeltypes($user_source),
User_groups($user_source),
$shifts,
$user['UID'] == $user_source['UID']
)
]; ];
} }
/** /**
* List all users. * List all users.
*
* @return array
*/ */
function users_list_controller() { function users_list_controller()
{
global $privileges; global $privileges;
$request = request();
if (! in_array('admin_user', $privileges)) { if (!in_array('admin_user', $privileges)) {
redirect(page_link_to('')); redirect(page_link_to(''));
} }
$order_by = 'Nick'; $order_by = 'Nick';
if (isset($_REQUEST['OrderBy']) && in_array($_REQUEST['OrderBy'], User_sortable_columns())) { if ($request->has('OrderBy') && in_array($request->input('OrderBy'), User_sortable_columns())) {
$order_by = $_REQUEST['OrderBy']; $order_by = $request->input('OrderBy');
} }
$users = Users($order_by); $users = Users($order_by);
if ($users === false) {
engelsystem_error('Unable to load users.');
}
foreach ($users as &$user) { foreach ($users as &$user) {
$user['freeloads'] = count(ShiftEntries_freeloaded_by_user($user)); $user['freeloads'] = count(ShiftEntries_freeloaded_by_user($user));
} }
return [ return [
_('All users'), _('All users'),
Users_view($users, $order_by, User_arrived_count(), User_active_count(), User_force_active_count(), ShiftEntries_freeleaded_count(), User_tshirts_count(), User_got_voucher_count()) Users_view(
$users,
$order_by,
User_arrived_count(),
User_active_count(),
User_force_active_count(),
ShiftEntries_freeleaded_count(),
User_tshirts_count(),
User_got_voucher_count()
)
]; ];
} }
/** /**
* Second step of password recovery: set a new password using the token link from email * Second step of password recovery: set a new password using the token link from email
*
* @return string
*/ */
function user_password_recovery_set_new_controller() { function user_password_recovery_set_new_controller()
global $min_password_length; {
$user_source = User_by_password_recovery_token($_REQUEST['token']); $request = request();
$user_source = User_by_password_recovery_token($request->input('token'));
if ($user_source == null) { if ($user_source == null) {
error(_("Token is not correct.")); error(_('Token is not correct.'));
redirect(page_link_to('login')); redirect(page_link_to('login'));
} }
if (isset($_REQUEST['submit'])) { if ($request->has('submit')) {
$valid = true; $valid = true;
if (isset($_REQUEST['password']) && strlen($_REQUEST['password']) >= $min_password_length) { if (
if ($_REQUEST['password'] != $_REQUEST['password2']) { $request->has('password')
&& strlen($request->postData('password')) >= config('min_password_length')
) {
if ($request->postData('password') != $request->postData('password2')) {
$valid = false; $valid = false;
error(_("Your passwords don't match.")); error(_('Your passwords don\'t match.'));
} }
} else { } else {
$valid = false; $valid = false;
error(_("Your password is to short (please use at least 6 characters).")); error(_('Your password is to short (please use at least 6 characters).'));
} }
if ($valid) { if ($valid) {
set_password($user_source['UID'], $_REQUEST['password']); set_password($user_source['UID'], $request->postData('password'));
success(_("Password saved.")); success(_('Password saved.'));
redirect(page_link_to('login')); redirect(page_link_to('login'));
} }
} }
@ -243,32 +320,43 @@ function user_password_recovery_set_new_controller() {
/** /**
* First step of password recovery: display a form that asks for your email and send email with recovery link * First step of password recovery: display a form that asks for your email and send email with recovery link
*
* @return string
*/ */
function user_password_recovery_start_controller() { function user_password_recovery_start_controller()
if (isset($_REQUEST['submit'])) { {
$request = request();
if ($request->has('submit')) {
$valid = true; $valid = true;
if (isset($_REQUEST['email']) && strlen(strip_request_item('email')) > 0) { if ($request->has('email') && strlen(strip_request_item('email')) > 0) {
$email = strip_request_item('email'); $email = strip_request_item('email');
if (check_email($email)) { if (check_email($email)) {
$user_source = User_by_email($email); $user_source = User_by_email($email);
if ($user_source == null) { if ($user_source == null) {
$valid = false; $valid = false;
error(_("E-mail address is not correct.")); error(_('E-mail address is not correct.'));
} }
} else { } else {
$valid = false; $valid = false;
error(_("E-mail address is not correct.")); error(_('E-mail address is not correct.'));
} }
} else { } else {
$valid = false; $valid = false;
error(_("Please enter your e-mail.")); error(_('Please enter your e-mail.'));
} }
if ($valid) { if ($valid) {
$token = User_generate_password_recovery_token($user_source); $token = User_generate_password_recovery_token($user_source);
engelsystem_email_to_user($user_source, _("Password recovery"), sprintf(_("Please visit %s to recover your password."), page_link_to_absolute('user_password_recovery') . '&token=' . $token)); engelsystem_email_to_user(
success(_("We sent an email containing your password recovery link.")); $user_source,
_('Password recovery'),
sprintf(
_('Please visit %s to recover your password.'),
page_link_to('user_password_recovery', ['token' => $token])
)
);
success(_('We sent an email containing your password recovery link.'));
redirect(page_link_to('login')); redirect(page_link_to('login'));
} }
} }
@ -279,44 +367,56 @@ function user_password_recovery_start_controller() {
/** /**
* User password recovery in 2 steps. * User password recovery in 2 steps.
* (By email) * (By email)
*
* @return string
*/ */
function user_password_recovery_controller() { function user_password_recovery_controller()
if (isset($_REQUEST['token'])) { {
if (request()->has('token')) {
return user_password_recovery_set_new_controller(); return user_password_recovery_set_new_controller();
} else {
return user_password_recovery_start_controller();
} }
return user_password_recovery_start_controller();
} }
/** /**
* Menu title for password recovery. * Menu title for password recovery.
*
* @return string
*/ */
function user_password_recovery_title() { function user_password_recovery_title()
return _("Password recovery"); {
return _('Password recovery');
} }
/** /**
* Loads a user from param user_id. * Loads a user from param user_id.
*
* return array
*/ */
function load_user() { function load_user()
if (! isset($_REQUEST['user_id'])) { {
$request = request();
if (!$request->has('user_id')) {
redirect(page_link_to()); redirect(page_link_to());
} }
$user = User($_REQUEST['user_id']); $user = User($request->input('user_id'));
if ($user === false) {
engelsystem_error("Unable to load user.");
}
if ($user == null) { if ($user == null) {
error(_("User doesn't exist.")); error(_('User doesn\'t exist.'));
redirect(page_link_to()); redirect(page_link_to());
} }
return $user; return $user;
} }
function shiftCalendarRendererByShiftFilter(ShiftsFilter $shiftsFilter) { /**
* @param ShiftsFilter $shiftsFilter
* @return ShiftCalendarRenderer
*/
function shiftCalendarRendererByShiftFilter(ShiftsFilter $shiftsFilter)
{
$shifts = Shifts_by_ShiftsFilter($shiftsFilter); $shifts = Shifts_by_ShiftsFilter($shiftsFilter);
$needed_angeltypes_source = NeededAngeltypes_by_ShiftsFilter($shiftsFilter); $needed_angeltypes_source = NeededAngeltypes_by_ShiftsFilter($shiftsFilter);
$shift_entries_source = ShiftEntries_by_ShiftsFilter($shiftsFilter); $shift_entries_source = ShiftEntries_by_ShiftsFilter($shiftsFilter);
@ -340,18 +440,22 @@ function shiftCalendarRendererByShiftFilter(ShiftsFilter $shiftsFilter) {
unset($needed_angeltypes_source); unset($needed_angeltypes_source);
unset($shift_entries_source); unset($shift_entries_source);
if (in_array(ShiftsFilter::FILLED_FREE, $shiftsFilter->getFilled()) && in_array(ShiftsFilter::FILLED_FILLED, $shiftsFilter->getFilled())) { if (
in_array(ShiftsFilter::FILLED_FREE, $shiftsFilter->getFilled())
&& in_array(ShiftsFilter::FILLED_FILLED, $shiftsFilter->getFilled())
) {
return new ShiftCalendarRenderer($shifts, $needed_angeltypes, $shift_entries, $shiftsFilter); return new ShiftCalendarRenderer($shifts, $needed_angeltypes, $shift_entries, $shiftsFilter);
} }
$filtered_shifts = []; $filtered_shifts = [];
foreach ($shifts as $shift) { foreach ($shifts as $shift) {
$needed_angels_count = 0; $needed_angels_count = 0;
$taken = 0;
foreach ($needed_angeltypes[$shift['SID']] as $needed_angeltype) { foreach ($needed_angeltypes[$shift['SID']] as $needed_angeltype) {
$taken = 0; $taken = 0;
foreach ($shift_entries[$shift['SID']] as $shift_entry) { foreach ($shift_entries[$shift['SID']] as $shift_entry) {
if ($needed_angeltype['angel_type_id'] == $shift_entry['TID'] && $shift_entry['freeloaded'] == 0) { if ($needed_angeltype['angel_type_id'] == $shift_entry['TID'] && $shift_entry['freeloaded'] == 0) {
$taken ++; $taken++;
} }
} }
@ -367,5 +471,3 @@ function shiftCalendarRendererByShiftFilter(ShiftsFilter $shiftsFilter) {
return new ShiftCalendarRenderer($filtered_shifts, $needed_angeltypes, $shift_entries, $shiftsFilter); return new ShiftCalendarRenderer($filtered_shifts, $needed_angeltypes, $shift_entries, $shiftsFilter);
} }
?>

63
includes/engelsystem.php Normal file
View File

@ -0,0 +1,63 @@
<?php
use Engelsystem\Application;
use Engelsystem\Config\Config;
use Engelsystem\Exceptions\Handler;
use Engelsystem\Exceptions\Handlers\HandlerInterface;
/**
* This file includes all needed functions, connects to the db etc.
*/
require_once __DIR__ . '/autoload.php';
/**
* Include legacy code
*/
require __DIR__ . '/includes.php';
/**
* Initialize and bootstrap the application
*/
$app = new Application(realpath(__DIR__ . DIRECTORY_SEPARATOR . '..'));
$appConfig = $app->make(Config::class);
$appConfig->set(require config_path('app.php'));
$app->bootstrap($appConfig);
/**
* Configure application
*/
date_default_timezone_set($app->get('config')->get('timezone'));
if (config('environment') == 'development') {
$errorHandler = $app->get('error.handler');
$errorHandler->setEnvironment(Handler::ENV_DEVELOPMENT);
$app->bind(HandlerInterface::class, 'error.handler.development');
ini_set('display_errors', true);
error_reporting(E_ALL);
} else {
ini_set('display_errors', false);
}
/**
* Check for maintenance
*/
if ($app->get('config')->get('maintenance')) {
echo file_get_contents(__DIR__ . '/../templates/maintenance.html');
die();
}
/**
* Init translations
*/
gettext_init();
/**
* Init authorization
*/
load_auth();

View File

@ -1,104 +0,0 @@
<?php
/**
* This file includes all needed functions, connects to the db etc.
*/
require_once realpath(__DIR__ . '/../includes/mysqli_provider.php');
require_once realpath(__DIR__ . '/../includes/sys_auth.php');
require_once realpath(__DIR__ . '/../includes/sys_form.php');
require_once realpath(__DIR__ . '/../includes/sys_log.php');
require_once realpath(__DIR__ . '/../includes/sys_menu.php');
require_once realpath(__DIR__ . '/../includes/sys_page.php');
require_once realpath(__DIR__ . '/../includes/sys_template.php');
require_once realpath(__DIR__ . '/../includes/model/AngelType_model.php');
require_once realpath(__DIR__ . '/../includes/model/EventConfig_model.php');
require_once realpath(__DIR__ . '/../includes/model/LogEntries_model.php');
require_once realpath(__DIR__ . '/../includes/model/Message_model.php');
require_once realpath(__DIR__ . '/../includes/model/NeededAngelTypes_model.php');
require_once realpath(__DIR__ . '/../includes/model/Room_model.php');
require_once realpath(__DIR__ . '/../includes/model/ShiftEntry_model.php');
require_once realpath(__DIR__ . '/../includes/model/Shifts_model.php');
require_once realpath(__DIR__ . '/../includes/model/ShiftsFilter.php');
require_once realpath(__DIR__ . '/../includes/model/ShiftSignupState.php');
require_once realpath(__DIR__ . '/../includes/model/ShiftTypes_model.php');
require_once realpath(__DIR__ . '/../includes/model/UserAngelTypes_model.php');
require_once realpath(__DIR__ . '/../includes/model/UserDriverLicenses_model.php');
require_once realpath(__DIR__ . '/../includes/model/UserGroups_model.php');
require_once realpath(__DIR__ . '/../includes/model/User_model.php');
require_once realpath(__DIR__ . '/../includes/model/ValidationResult.php');
require_once realpath(__DIR__ . '/../includes/view/AngelTypes_view.php');
require_once realpath(__DIR__ . '/../includes/view/EventConfig_view.php');
require_once realpath(__DIR__ . '/../includes/view/Questions_view.php');
require_once realpath(__DIR__ . '/../includes/view/Rooms_view.php');
require_once realpath(__DIR__ . '/../includes/view/ShiftCalendarLane.php');
require_once realpath(__DIR__ . '/../includes/view/ShiftCalendarRenderer.php');
require_once realpath(__DIR__ . '/../includes/view/ShiftCalendarShiftRenderer.php');
require_once realpath(__DIR__ . '/../includes/view/ShiftsFilterRenderer.php');
require_once realpath(__DIR__ . '/../includes/view/Shifts_view.php');
require_once realpath(__DIR__ . '/../includes/view/ShiftEntry_view.php');
require_once realpath(__DIR__ . '/../includes/view/ShiftTypes_view.php');
require_once realpath(__DIR__ . '/../includes/view/UserAngelTypes_view.php');
require_once realpath(__DIR__ . '/../includes/view/UserDriverLicenses_view.php');
require_once realpath(__DIR__ . '/../includes/view/UserHintsRenderer.php');
require_once realpath(__DIR__ . '/../includes/view/User_view.php');
require_once realpath(__DIR__ . '/../includes/controller/angeltypes_controller.php');
require_once realpath(__DIR__ . '/../includes/controller/event_config_controller.php');
require_once realpath(__DIR__ . '/../includes/controller/rooms_controller.php');
require_once realpath(__DIR__ . '/../includes/controller/shift_entries_controller.php');
require_once realpath(__DIR__ . '/../includes/controller/shifts_controller.php');
require_once realpath(__DIR__ . '/../includes/controller/shifttypes_controller.php');
require_once realpath(__DIR__ . '/../includes/controller/users_controller.php');
require_once realpath(__DIR__ . '/../includes/controller/user_angeltypes_controller.php');
require_once realpath(__DIR__ . '/../includes/controller/user_driver_licenses_controller.php');
require_once realpath(__DIR__ . '/../includes/helper/graph_helper.php');
require_once realpath(__DIR__ . '/../includes/helper/internationalization_helper.php');
require_once realpath(__DIR__ . '/../includes/helper/message_helper.php');
require_once realpath(__DIR__ . '/../includes/helper/error_helper.php');
require_once realpath(__DIR__ . '/../includes/helper/email_helper.php');
require_once realpath(__DIR__ . '/../includes/mailer/shifts_mailer.php');
require_once realpath(__DIR__ . '/../includes/mailer/users_mailer.php');
require_once realpath(__DIR__ . '/../config/config.default.php');
if (file_exists(realpath(__DIR__ . '/../config/config.php'))) {
require_once realpath(__DIR__ . '/../config/config.php');
}
if ($maintenance_mode) {
echo file_get_contents(__DIR__ . '/../public/maintenance.html');
die();
}
require_once realpath(__DIR__ . '/../includes/pages/admin_active.php');
require_once realpath(__DIR__ . '/../includes/pages/admin_arrive.php');
require_once realpath(__DIR__ . '/../includes/pages/admin_free.php');
require_once realpath(__DIR__ . '/../includes/pages/admin_groups.php');
require_once realpath(__DIR__ . '/../includes/pages/admin_import.php');
require_once realpath(__DIR__ . '/../includes/pages/admin_log.php');
require_once realpath(__DIR__ . '/../includes/pages/admin_questions.php');
require_once realpath(__DIR__ . '/../includes/pages/admin_rooms.php');
require_once realpath(__DIR__ . '/../includes/pages/admin_shifts.php');
require_once realpath(__DIR__ . '/../includes/pages/admin_user.php');
require_once realpath(__DIR__ . '/../includes/pages/guest_login.php');
require_once realpath(__DIR__ . '/../includes/pages/user_messages.php');
require_once realpath(__DIR__ . '/../includes/pages/user_myshifts.php');
require_once realpath(__DIR__ . '/../includes/pages/user_news.php');
require_once realpath(__DIR__ . '/../includes/pages/user_questions.php');
require_once realpath(__DIR__ . '/../includes/pages/user_settings.php');
require_once realpath(__DIR__ . '/../includes/pages/user_shifts.php');
require_once realpath(__DIR__ . '/../vendor/parsedown/Parsedown.php');
session_start();
gettext_init();
sql_connect($config['host'], $config['user'], $config['pw'], $config['db']);
load_auth();
?>

View File

@ -1,6 +1,14 @@
<?php <?php
function engelsystem_email_to_user($recipient_user, $title, $message, $not_if_its_me = false) { /**
* @param array $recipient_user
* @param string $title
* @param string $message
* @param bool $not_if_its_me
* @return bool
*/
function engelsystem_email_to_user($recipient_user, $title, $message, $not_if_its_me = false)
{
global $user; global $user;
if ($not_if_its_me && $user['UID'] == $recipient_user['UID']) { if ($not_if_its_me && $user['UID'] == $recipient_user['UID']) {
@ -9,18 +17,34 @@ function engelsystem_email_to_user($recipient_user, $title, $message, $not_if_it
gettext_locale($recipient_user['Sprache']); gettext_locale($recipient_user['Sprache']);
$message = sprintf(_("Hi %s,"), $recipient_user['Nick']) . "\n\n" . _("here is a message for you from the engelsystem:") . "\n\n" . $message . "\n\n" . _("This email is autogenerated and has not to be signed. You got this email because you are registered in the engelsystem."); $message = sprintf(_('Hi %s,'), $recipient_user['Nick']) . "\n\n"
. _('here is a message for you from the engelsystem:') . "\n\n"
. $message . "\n\n"
. _('This email is autogenerated and has not to be signed. You got this email because you are registered in the engelsystem.');
gettext_locale(); gettext_locale();
return engelsystem_email($recipient_user['email'], $title, $message); return engelsystem_email($recipient_user['email'], $title, $message);
} }
function engelsystem_email($address, $title, $message) { /**
global $no_reply_email; * @param string $address
$result = mail($address, $title, $message, sprintf("Content-Type: text/plain; charset=UTF-8\r\nFrom: Engelsystem <%s>", $no_reply_email)); * @param string $title
* @param string $message
* @return bool
*/
function engelsystem_email($address, $title, $message)
{
$result = mail(
$address,
$title,
$message,
sprintf("Content-Type: text/plain; charset=UTF-8\r\nFrom: Engelsystem <%s>", config('no_reply_email'))
);
if ($result === false) { if ($result === false) {
engelsystem_error('Unable to send email.'); engelsystem_error('Unable to send email.');
} }
}
?> return true;
}

View File

@ -5,8 +5,7 @@
* *
* @param string $message * @param string $message
*/ */
function engelsystem_error($message) { function engelsystem_error($message)
{
raw_output($message); raw_output($message);
} }
?>

View File

@ -2,12 +2,16 @@
/** /**
* Renders a bargraph * Renders a bargraph
* @param string $key keyname of the x-axis *
* @param array $row_names keynames for the data rows * @param string $dom_id
* @param unknown $colors colors for the data rows * @param string $key key name of the x-axis
* @param unknown $data the data * @param array $row_names key names for the data rows
* @param array $colors colors for the data rows
* @param array $data the data
* @return string
*/ */
function bargraph($dom_id, $key, $row_names, $colors, $data) { function bargraph($dom_id, $key, $row_names, $colors, $data)
{
$labels = []; $labels = [];
foreach ($data as $dataset) { foreach ($data as $dataset) {
$labels[] = $dataset[$key]; $labels[] = $dataset[$key];
@ -37,5 +41,3 @@ function bargraph($dom_id, $key, $row_names, $colors, $data) {
}); });
</script>'; </script>';
} }
?>

View File

@ -1,39 +1,42 @@
<?php <?php
$locales = [
'de_DE.UTF-8' => "Deutsch",
'en_US.UTF-8' => "English"
];
$default_locale = 'en_US.UTF-8';
/** /**
* Return currently active locale * Return currently active locale
*
* @return string
*/ */
function locale() { function locale()
return $_SESSION['locale']; {
return session()->get('locale');
} }
/** /**
* Returns two letter language code from currently active locale * Returns two letter language code from currently active locale
*
* @return string
*/ */
function locale_short() { function locale_short()
{
return substr(locale(), 0, 2); return substr(locale(), 0, 2);
} }
/** /**
* Initializes gettext for internationalization and updates the sessions locale to use for translation. * Initializes gettext for internationalization and updates the sessions locale to use for translation.
*/ */
function gettext_init() { function gettext_init()
global $locales, $default_locale; {
$locales = config('locales');
$request = request();
$session = session();
if (isset($_REQUEST['set_locale']) && isset($locales[$_REQUEST['set_locale']])) { if ($request->has('set_locale') && isset($locales[$request->input('set_locale')])) {
$_SESSION['locale'] = $_REQUEST['set_locale']; $session->set('locale', $request->input('set_locale'));
} elseif (! isset($_SESSION['locale'])) { } elseif (!$session->has('locale')) {
$_SESSION['locale'] = $default_locale; $session->set('locale', config('default_locale'));
} }
gettext_locale(); gettext_locale();
bindtextdomain('default', realpath(__DIR__ . '/../../locale')); bindtextdomain('default', app('path.lang'));
bind_textdomain_codeset('default', 'UTF-8'); bind_textdomain_codeset('default', 'UTF-8');
textdomain('default'); textdomain('default');
} }
@ -43,9 +46,10 @@ function gettext_init() {
* *
* @param string $locale * @param string $locale
*/ */
function gettext_locale($locale = null) { function gettext_locale($locale = null)
{
if ($locale == null) { if ($locale == null) {
$locale = $_SESSION['locale']; $locale = session()->get('locale');
} }
putenv('LC_ALL=' . $locale); putenv('LC_ALL=' . $locale);
@ -55,17 +59,25 @@ function gettext_locale($locale = null) {
/** /**
* Renders language selection. * Renders language selection.
* *
* @return string * @return array
*/ */
function make_langselect() { function make_langselect()
global $locales; {
$URL = $_SERVER["REQUEST_URI"] . (strpos($_SERVER["REQUEST_URI"], "?") > 0 ? '&' : '?') . "set_locale="; $request = app('request');
$items = []; $items = [];
foreach ($locales as $locale => $name) { foreach (config('locales') as $locale => $name) {
$items[] = toolbar_item_link(htmlspecialchars($URL) . $locale, '', '<img src="pic/flag/' . $locale . '.png" alt="' . $name . '" title="' . $name . '"> ' . $name); $url = url($request->getPathInfo(), ['set_locale' => $locale]);
$items[] = toolbar_item_link(
htmlspecialchars($url),
'',
sprintf(
'<img src="%s" alt="%s" title="%2$s"> %2$s',
url('pic/flag/' . $locale . '.png'),
$name
)
);
} }
return $items; return $items;
} }
?>

View File

@ -2,52 +2,78 @@
/** /**
* Gibt zwischengespeicherte Fehlermeldungen zurück und löscht den Zwischenspeicher * Gibt zwischengespeicherte Fehlermeldungen zurück und löscht den Zwischenspeicher
*
* @return string
*/ */
function msg() { function msg()
if (! isset($_SESSION['msg'])) { {
return ""; $session = session();
}
$msg = $_SESSION['msg']; $message = $session->get('msg', '');
$_SESSION['msg'] = ""; $session->set('msg', '');
return $msg;
return $message;
} }
/** /**
* Rendert eine Information * Rendert eine Information
*
* @param string $msg
* @param bool $immediately
* @return string
*/ */
function info($msg, $immediatly = false) { function info($msg, $immediately = false)
return alert('info', $msg, $immediatly); {
return alert('info', $msg, $immediately);
} }
/** /**
* Rendert eine Fehlermeldung * Rendert eine Fehlermeldung
*
* @param string $msg
* @param bool $immediately
* @return string
*/ */
function error($msg, $immediatly = false) { function error($msg, $immediately = false)
return alert('danger', $msg, $immediatly); {
return alert('danger', $msg, $immediately);
} }
/** /**
* Rendert eine Erfolgsmeldung * Rendert eine Erfolgsmeldung
*
* @param string $msg
* @param bool $immediately
* @return string
*/ */
function success($msg, $immediatly = false) { function success($msg, $immediately = false)
return alert('success', $msg, $immediatly); {
return alert('success', $msg, $immediately);
} }
/** /**
* Renders an alert with given alert-* class. * Renders an alert with given alert-* class.
*
* @param string $class
* @param string $msg
* @param bool $immediately
* @return string
*/ */
function alert($class, $msg, $immediatly = false) { function alert($class, $msg, $immediately = false)
if ($immediatly) { {
if ($msg == "") { $session = session();
return "";
if (empty($msg)) {
return '';
} }
if ($immediately) {
return '<div class="alert alert-' . $class . '">' . $msg . '</div>'; return '<div class="alert alert-' . $class . '">' . $msg . '</div>';
} }
if (! isset($_SESSION['msg'])) { $message = $session->get('msg', '');
$_SESSION['msg'] = ""; $message .= alert($class, $msg, true);
} $session->set('msg', $message);
$_SESSION['msg'] .= alert($class, $msg, true);
}
?> return '';
}

86
includes/includes.php Normal file
View File

@ -0,0 +1,86 @@
<?php
/**
* Include legacy code
*/
$includeFiles = [
__DIR__ . '/../includes/sys_auth.php',
__DIR__ . '/../includes/sys_form.php',
__DIR__ . '/../includes/sys_log.php',
__DIR__ . '/../includes/sys_menu.php',
__DIR__ . '/../includes/sys_page.php',
__DIR__ . '/../includes/sys_template.php',
__DIR__ . '/../includes/model/AngelType_model.php',
__DIR__ . '/../includes/model/EventConfig_model.php',
__DIR__ . '/../includes/model/LogEntries_model.php',
__DIR__ . '/../includes/model/Message_model.php',
__DIR__ . '/../includes/model/NeededAngelTypes_model.php',
__DIR__ . '/../includes/model/Room_model.php',
__DIR__ . '/../includes/model/ShiftEntry_model.php',
__DIR__ . '/../includes/model/Shifts_model.php',
__DIR__ . '/../includes/model/ShiftsFilter.php',
__DIR__ . '/../includes/model/ShiftSignupState.php',
__DIR__ . '/../includes/model/ShiftTypes_model.php',
__DIR__ . '/../includes/model/UserAngelTypes_model.php',
__DIR__ . '/../includes/model/UserDriverLicenses_model.php',
__DIR__ . '/../includes/model/UserGroups_model.php',
__DIR__ . '/../includes/model/User_model.php',
__DIR__ . '/../includes/model/ValidationResult.php',
__DIR__ . '/../includes/view/AngelTypes_view.php',
__DIR__ . '/../includes/view/EventConfig_view.php',
__DIR__ . '/../includes/view/Questions_view.php',
__DIR__ . '/../includes/view/Rooms_view.php',
__DIR__ . '/../includes/view/ShiftCalendarLane.php',
__DIR__ . '/../includes/view/ShiftCalendarRenderer.php',
__DIR__ . '/../includes/view/ShiftCalendarShiftRenderer.php',
__DIR__ . '/../includes/view/ShiftsFilterRenderer.php',
__DIR__ . '/../includes/view/Shifts_view.php',
__DIR__ . '/../includes/view/ShiftEntry_view.php',
__DIR__ . '/../includes/view/ShiftTypes_view.php',
__DIR__ . '/../includes/view/UserAngelTypes_view.php',
__DIR__ . '/../includes/view/UserDriverLicenses_view.php',
__DIR__ . '/../includes/view/UserHintsRenderer.php',
__DIR__ . '/../includes/view/User_view.php',
__DIR__ . '/../includes/controller/angeltypes_controller.php',
__DIR__ . '/../includes/controller/event_config_controller.php',
__DIR__ . '/../includes/controller/rooms_controller.php',
__DIR__ . '/../includes/controller/shift_entries_controller.php',
__DIR__ . '/../includes/controller/shifts_controller.php',
__DIR__ . '/../includes/controller/shifttypes_controller.php',
__DIR__ . '/../includes/controller/users_controller.php',
__DIR__ . '/../includes/controller/user_angeltypes_controller.php',
__DIR__ . '/../includes/controller/user_driver_licenses_controller.php',
__DIR__ . '/../includes/helper/graph_helper.php',
__DIR__ . '/../includes/helper/internationalization_helper.php',
__DIR__ . '/../includes/helper/message_helper.php',
__DIR__ . '/../includes/helper/error_helper.php',
__DIR__ . '/../includes/helper/email_helper.php',
__DIR__ . '/../includes/mailer/shifts_mailer.php',
__DIR__ . '/../includes/mailer/users_mailer.php',
__DIR__ . '/../includes/pages/admin_active.php',
__DIR__ . '/../includes/pages/admin_arrive.php',
__DIR__ . '/../includes/pages/admin_free.php',
__DIR__ . '/../includes/pages/admin_groups.php',
__DIR__ . '/../includes/pages/admin_import.php',
__DIR__ . '/../includes/pages/admin_log.php',
__DIR__ . '/../includes/pages/admin_questions.php',
__DIR__ . '/../includes/pages/admin_rooms.php',
__DIR__ . '/../includes/pages/admin_shifts.php',
__DIR__ . '/../includes/pages/admin_user.php',
__DIR__ . '/../includes/pages/guest_login.php',
__DIR__ . '/../includes/pages/user_messages.php',
__DIR__ . '/../includes/pages/user_myshifts.php',
__DIR__ . '/../includes/pages/user_news.php',
__DIR__ . '/../includes/pages/user_questions.php',
__DIR__ . '/../includes/pages/user_settings.php',
__DIR__ . '/../includes/pages/user_shifts.php',
];
foreach ($includeFiles as $file) {
require_once realpath($file);
}

View File

@ -1,104 +1,129 @@
<?php <?php
function mail_shift_change($old_shift, $new_shift) { /**
$users = ShiftEntries_by_shift($old_shift["SID"]); * @param array $old_shift
$old_room = Room($old_shift["RID"]); * @param array $new_shift
$new_room = Room($new_shift["RID"]); */
function mail_shift_change($old_shift, $new_shift)
{
$users = ShiftEntries_by_shift($old_shift['SID']);
$old_room = Room($old_shift['RID']);
$new_room = Room($new_shift['RID']);
$noticable_changes = false; $noticeable_changes = false;
$message = _("A Shift you are registered on has changed:"); $message = _('A Shift you are registered on has changed:');
$message .= "\n"; $message .= "\n";
if ($old_shift["name"] != $new_shift["name"]) { if ($old_shift['name'] != $new_shift['name']) {
$message .= sprintf(_("* Shift type changed from %s to %s"), $old_shift["name"], $new_shift["name"]) . "\n"; $message .= sprintf(_('* Shift type changed from %s to %s'), $old_shift['name'], $new_shift['name']) . "\n";
$noticable_changes = true; $noticeable_changes = true;
} }
if ($old_shift["title"] != $new_shift["title"]) { if ($old_shift['title'] != $new_shift['title']) {
$message .= sprintf(_("* Shift title changed from %s to %s"), $old_shift["title"], $new_shift["title"]) . "\n"; $message .= sprintf(_('* Shift title changed from %s to %s'), $old_shift['title'], $new_shift['title']) . "\n";
$noticable_changes = true; $noticeable_changes = true;
} }
if ($old_shift["start"] != $new_shift["start"]) { if ($old_shift['start'] != $new_shift['start']) {
$message .= sprintf(_("* Shift Start changed from %s to %s"), date("Y-m-d H:i", $old_shift["start"]), date("Y-m-d H:i", $new_shift["start"])) . "\n"; $message .= sprintf(
$noticable_changes = true; _('* Shift Start changed from %s to %s'),
date('Y-m-d H:i', $old_shift['start']),
date('Y-m-d H:i', $new_shift['start'])
) . "\n";
$noticeable_changes = true;
} }
if ($old_shift["end"] != $new_shift["end"]) { if ($old_shift['end'] != $new_shift['end']) {
$message .= sprintf(_("* Shift End changed from %s to %s"), date("Y-m-d H:i", $old_shift["end"]), date("Y-m-d H:i", $new_shift["end"])) . "\n"; $message .= sprintf(
$noticable_changes = true; _('* Shift End changed from %s to %s'),
date('Y-m-d H:i', $old_shift['end']),
date('Y-m-d H:i', $new_shift['end'])
) . "\n";
$noticeable_changes = true;
} }
if ($old_shift["RID"] != $new_shift["RID"]) { if ($old_shift['RID'] != $new_shift['RID']) {
$message .= sprintf(_("* Shift Location changed from %s to %s"), $old_room["Name"], $new_room["Name"]) . "\n"; $message .= sprintf(_('* Shift Location changed from %s to %s'), $old_room['Name'], $new_room['Name']) . "\n";
$noticable_changes = true; $noticeable_changes = true;
} }
if (! $noticable_changes) { if (!$noticeable_changes) {
// There are no changes worth sending an E-Mail // There are no changes worth sending an E-Mail
return; return;
} }
$message .= "\n"; $message .= "\n";
$message .= _("The updated Shift:") . "\n"; $message .= _('The updated Shift:') . "\n";
$message .= $new_shift["name"] . "\n"; $message .= $new_shift['name'] . "\n";
$message .= $new_shift["title"] . "\n"; $message .= $new_shift['title'] . "\n";
$message .= date("Y-m-d H:i", $new_shift["start"]) . " - " . date("H:i", $new_shift["end"]) . "\n"; $message .= date('Y-m-d H:i', $new_shift['start']) . ' - ' . date('H:i', $new_shift['end']) . "\n";
$message .= $new_room["Name"] . "\n"; $message .= $new_room['Name'] . "\n";
foreach ($users as $user) { foreach ($users as $user) {
if ($user["email_shiftinfo"]) { if ($user['email_shiftinfo']) {
engelsystem_email_to_user($user, '[engelsystem] ' . _("Your Shift has changed"), $message, true); engelsystem_email_to_user($user, '[engelsystem] ' . _('Your Shift has changed'), $message, true);
} }
} }
} }
function mail_shift_delete($shift) { /**
$users = ShiftEntries_by_shift($shift["SID"]); * @param array $shift
$room = Room($shift["RID"]); */
function mail_shift_delete($shift)
{
$users = ShiftEntries_by_shift($shift['SID']);
$room = Room($shift['RID']);
$message = _("A Shift you are registered on was deleted:") . "\n"; $message = _('A Shift you are registered on was deleted:') . "\n";
$message .= $shift["name"] . "\n"; $message .= $shift['name'] . "\n";
$message .= $shift["title"] . "\n"; $message .= $shift['title'] . "\n";
$message .= date("Y-m-d H:i", $shift["start"]) . " - " . date("H:i", $shift["end"]) . "\n"; $message .= date('Y-m-d H:i', $shift['start']) . ' - ' . date('H:i', $shift['end']) . "\n";
$message .= $room["Name"] . "\n"; $message .= $room['Name'] . "\n";
foreach ($users as $user) { foreach ($users as $user) {
if ($user["email_shiftinfo"]) { if ($user['email_shiftinfo']) {
engelsystem_email_to_user($user, '[engelsystem] ' . _("Your Shift was deleted"), $message, true); engelsystem_email_to_user($user, '[engelsystem] ' . _('Your Shift was deleted'), $message, true);
} }
} }
} }
function mail_shift_assign($user, $shift) { /**
if ($user["email_shiftinfo"]) { * @param array $user
$room = Room($shift["RID"]); * @param array $shift
*/
$message = _("You have been assigned to a Shift:") . "\n"; function mail_shift_assign($user, $shift)
$message .= $shift["name"] . "\n"; {
$message .= $shift["title"] . "\n"; if (!$user['email_shiftinfo']) {
$message .= date("Y-m-d H:i", $shift["start"]) . " - " . date("H:i", $shift["end"]) . "\n"; return;
$message .= $room["Name"] . "\n";
engelsystem_email_to_user($user, '[engelsystem] ' . _("Assigned to Shift"), $message, true);
} }
$room = Room($shift['RID']);
$message = _('You have been assigned to a Shift:') . "\n";
$message .= $shift['name'] . "\n";
$message .= $shift['title'] . "\n";
$message .= date('Y-m-d H:i', $shift['start']) . ' - ' . date('H:i', $shift['end']) . "\n";
$message .= $room['Name'] . "\n";
engelsystem_email_to_user($user, '[engelsystem] ' . _('Assigned to Shift'), $message, true);
} }
function mail_shift_removed($user, $shift) { function mail_shift_removed($user, $shift)
if ($user["email_shiftinfo"]) { {
$room = Room($shift["RID"]); if (!$user['email_shiftinfo']) {
return;
$message = _("You have been removed from a Shift:") . "\n";
$message .= $shift["name"] . "\n";
$message .= $shift["title"] . "\n";
$message .= date("Y-m-d H:i", $shift["start"]) . " - " . date("H:i", $shift["end"]) . "\n";
$message .= $room["Name"] . "\n";
engelsystem_email_to_user($user, '[engelsystem] ' . _("Removed from Shift"), $message, true);
} }
}
?> $room = Room($shift['RID']);
$message = _('You have been removed from a Shift:') . "\n";
$message .= $shift['name'] . "\n";
$message .= $shift['title'] . "\n";
$message .= date('Y-m-d H:i', $shift['start']) . ' - ' . date('H:i', $shift['end']) . "\n";
$message .= $room['Name'] . "\n";
engelsystem_email_to_user($user, '[engelsystem] ' . _('Removed from Shift'), $message, true);
}

View File

@ -1,9 +1,14 @@
<?php <?php
/** /**
* @param User $user_source * @param array $user
* @return bool
*/ */
function mail_user_delete($user) { function mail_user_delete($user)
engelsystem_email_to_user($user, '[engelsystem] ' . _("Your account has been deleted"), _("Your angelsystem account has been deleted. If you have any questions regarding your account deletion, please contact heaven.")); {
return engelsystem_email_to_user(
$user,
'[engelsystem] ' . _('Your account has been deleted'),
_('Your angelsystem account has been deleted. If you have any questions regarding your account deletion, please contact heaven.')
);
} }
?>

View File

@ -1,19 +1,21 @@
<?php <?php
use Engelsystem\Database\DB;
use Engelsystem\ValidationResult; use Engelsystem\ValidationResult;
/** /**
* Returns an array containing the basic attributes of angeltypes. * Returns an array containing the basic attributes of angeltypes.
* FIXME! This is the big sign for needing entity objects * FIXME! This is the big sign for needing entity objects
*/ */
function AngelType_new() { function AngelType_new()
{
return [ return [
'id' => null, 'id' => null,
'name' => "", 'name' => '',
'restricted' => false, 'restricted' => false,
'no_self_signup' => false, 'no_self_signup' => false,
'description' => '', 'description' => '',
'requires_driver_license' => false, 'requires_driver_license' => false,
'contact_user_id' => null,
'contact_name' => null, 'contact_name' => null,
'contact_dect' => null, 'contact_dect' => null,
'contact_email' => null 'contact_email' => null
@ -21,120 +23,115 @@ function AngelType_new() {
} }
/** /**
* Validates the contact user * Checks if the angeltype has any contact information.
* *
* @param Angeltype $angeltype * @param Angeltype $angeltype
* The angeltype * @return bool
* @return ValidationResult
*/ */
function AngelType_validate_contact_user_id($angeltype) { function AngelType_has_contact_info($angeltype) {
if (! isset($angeltype['contact_user_id'])) { return !empty($angeltype['contact_name'])
return new ValidationResult(true, null); || !empty($angeltype['contact_dect'])
} || !empty($angeltype['contact_email']);
if (isset($angeltype['contact_name']) || isset($angeltype['contact_dect']) || isset($angeltype['contact_email'])) {
return new ValidationResult(false, $angeltype['contact_user_id']);
}
if (User($angeltype['contact_user_id']) == null) {
return new ValidationResult(false, $angeltype['contact_user_id']);
}
return new ValidationResult(true, $angeltype['contact_user_id']);
}
/**
* Returns contact data (name, dect, email) for given angeltype or null
*
* @param Angeltype $angeltype
* The angeltype
*/
function AngelType_contact_info($angeltype) {
if (isset($angeltype['contact_user_id'])) {
$contact_user = User($angeltype['contact_user_id']);
$contact_data = [
'contact_name' => $contact_user['Nick'],
'contact_dect' => $contact_user['DECT']
];
if ($contact_user['email_by_human_allowed']) {
$contact_data['contact_email'] = $contact_user['email'];
}
return $contact_data;
}
if (isset($angeltype['contact_name'])) {
return [
'contact_name' => $angeltype['contact_name'],
'contact_dect' => $angeltype['contact_dect'],
'contact_email' => $angeltype['contact_email']
];
}
return null;
} }
/** /**
* Delete an Angeltype. * Delete an Angeltype.
* *
* @param Angeltype $angeltype * @param array $angeltype
*/ */
function AngelType_delete($angeltype) { function AngelType_delete($angeltype)
$result = sql_query(" {
DB::delete('
DELETE FROM `AngelTypes` DELETE FROM `AngelTypes`
WHERE `id`='" . sql_escape($angeltype['id']) . "' WHERE `id`=?
LIMIT 1"); LIMIT 1
if ($result === false) { ', [$angeltype['id']]);
engelsystem_error("Unable to delete angeltype."); engelsystem_log('Deleted angeltype: ' . AngelType_name_render($angeltype));
}
engelsystem_log("Deleted angeltype: " . AngelType_name_render($angeltype));
return $result;
} }
/** /**
* Update Angeltype. * Update Angeltype.
* *
* @param Angeltype $angeltype * @param array $angeltype The angeltype
* The angeltype
*/ */
function AngelType_update($angeltype) { function AngelType_update($angeltype)
$result = sql_query(" {
DB::update('
UPDATE `AngelTypes` SET UPDATE `AngelTypes` SET
`name`='" . sql_escape($angeltype['name']) . "', `name` = ?,
`restricted`=" . sql_bool($angeltype['restricted']) . ", `restricted` = ?,
`description`='" . sql_escape($angeltype['description']) . "', `description` = ?,
`requires_driver_license`=" . sql_bool($angeltype['requires_driver_license']) . ", `requires_driver_license` = ?,
`no_self_signup`=" . sql_bool($angeltype['no_self_signup']) . ", `no_self_signup` = ?,
`contact_user_id`=" . sql_null($angeltype['contact_user_id']) . ", `contact_name` = ?,
`contact_name`=" . sql_null($angeltype['contact_name']) . ", `contact_dect` = ?,
`contact_dect`=" . sql_null($angeltype['contact_dect']) . ", `contact_email` = ?
`contact_email`=" . sql_null($angeltype['contact_email']) . " WHERE `id` = ?',
WHERE `id`='" . sql_escape($angeltype['id']) . "'"); [
if ($result === false) { $angeltype['name'],
engelsystem_error("Unable to update angeltype."); (int)$angeltype['restricted'],
} $angeltype['description'],
engelsystem_log("Updated angeltype: " . $angeltype['name'] . ($angeltype['restricted'] ? ", restricted" : "") . ($angeltype['no_self_signup'] ? ", no_self_signup" : "") . ($angeltype['requires_driver_license'] ? ", requires driver license" : "")); (int)$angeltype['requires_driver_license'],
return $result; (int)$angeltype['no_self_signup'],
$angeltype['contact_name'],
$angeltype['contact_dect'],
$angeltype['contact_email'],
$angeltype['id'],
]
);
engelsystem_log(
'Updated angeltype: ' . $angeltype['name'] . ($angeltype['restricted'] ? ', restricted' : '')
. ($angeltype['no_self_signup'] ? ', no_self_signup' : '')
. ($angeltype['requires_driver_license'] ? ', requires driver license' : '') . ', '
. $angeltype['contact_name'] . ', '
. $angeltype['contact_dect'] . ', '
. $angeltype['contact_email']
);
} }
/** /**
* Create an Angeltype. * Create an Angeltype.
* *
* @param Angeltype $angeltype * @param array $angeltype The angeltype
* The angeltype * @return array the created angeltype
* @return the created angeltype
*/ */
function AngelType_create($angeltype) { function AngelType_create($angeltype)
$result = sql_query(" {
INSERT INTO `AngelTypes` SET DB::insert('
`name`='" . sql_escape($angeltype['name']) . "', INSERT INTO `AngelTypes` (
`restricted`=" . sql_bool($angeltype['restricted']) . ", `name`,
`description`='" . sql_escape($angeltype['description']) . "', `restricted`,
`requires_driver_license`=" . sql_bool($angeltype['requires_driver_license']) . ", `description`,
`no_self_signup`=" . sql_bool($angeltype['no_self_signup']) . ", `requires_driver_license`,
`contact_user_id`=" . sql_null($angeltype['contact_user_id']) . ", `no_self_signup`,
`contact_name`=" . sql_null($angeltype['contact_name']) . ", `contact_name`,
`contact_dect`=" . sql_null($angeltype['contact_dect']) . ", `contact_dect`,
`contact_email`=" . sql_null($angeltype['contact_email'])); `contact_email`
if ($result === false) { )
engelsystem_error("Unable to create angeltype."); VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
} ',
$angeltype['id'] = sql_id(); [
engelsystem_log("Created angeltype: " . $angeltype['name'] . ($angeltype['restricted'] ? ", restricted" : "") . ($angeltype['requires_driver_license'] ? ", requires driver license" : "")); $angeltype['name'],
(int)$angeltype['restricted'],
$angeltype['description'],
(int)$angeltype['requires_driver_license'],
(int)$angeltype['no_self_signup'],
$angeltype['contact_name'],
$angeltype['contact_dect'],
$angeltype['contact_email'],
]
);
$angeltype['id'] = DB::getPdo()->lastInsertId();
engelsystem_log(
'Created angeltype: ' . $angeltype['name']
. ($angeltype['restricted'] ? ', restricted' : '')
. ($angeltype['requires_driver_license'] ? ', requires driver license' : '') . ', '
. $angeltype['contact_name'] . ', '
. $angeltype['contact_dect'] . ', '
. $angeltype['contact_email']
);
return $angeltype; return $angeltype;
} }
@ -142,95 +139,88 @@ function AngelType_create($angeltype) {
* Validates a name for angeltypes. * Validates a name for angeltypes.
* Returns ValidationResult containing validation success and validated name. * Returns ValidationResult containing validation success and validated name.
* *
* @param string $name * @param string $name Wanted name for the angeltype
* Wanted name for the angeltype * @param array $angeltype The angeltype the name is for
* @param AngelType $angeltype *
* The angeltype the name is for
* @return ValidationResult result and validated name * @return ValidationResult result and validated name
*/ */
function AngelType_validate_name($name, $angeltype) { function AngelType_validate_name($name, $angeltype)
{
$name = strip_item($name); $name = strip_item($name);
if ($name == "") { if ($name == '') {
return new ValidationResult(false, ""); return new ValidationResult(false, '');
} }
if ($angeltype != null && isset($angeltype['id'])) { if ($angeltype != null && isset($angeltype['id'])) {
$valid = sql_num_query(" $valid = (count(DB::select('
SELECT *
FROM `AngelTypes`
WHERE `name`='" . sql_escape($name) . "'
AND NOT `id`='" . sql_escape($angeltype['id']) . "'
LIMIT 1") == 0;
return new ValidationResult($valid, $name);
}
$valid = sql_num_query("
SELECT `id` SELECT `id`
FROM `AngelTypes` FROM `AngelTypes`
WHERE `name`='" . sql_escape($name) . "' WHERE `name`=?
LIMIT 1") == 0; AND NOT `id`=?
LIMIT 1
', [$name, $angeltype['id']])) == 0);
return new ValidationResult($valid, $name);
}
$valid = (count(DB::select('
SELECT `id`
FROM `AngelTypes`
WHERE `name`=?
LIMIT 1', [$name])) == 0);
return new ValidationResult($valid, $name); return new ValidationResult($valid, $name);
} }
/** /**
* Returns all angeltypes and subscription state to each of them for given user. * Returns all angeltypes and subscription state to each of them for given user.
* *
* @param User $user * @param array $user
* @return array
*/ */
function AngelTypes_with_user($user) { function AngelTypes_with_user($user)
$result = sql_select(" {
return DB::select('
SELECT `AngelTypes`.*, SELECT `AngelTypes`.*,
`UserAngelTypes`.`id` as `user_angeltype_id`, `UserAngelTypes`.`id` AS `user_angeltype_id`,
`UserAngelTypes`.`confirm_user_id`, `UserAngelTypes`.`confirm_user_id`,
`UserAngelTypes`.`supporter` `UserAngelTypes`.`supporter`
FROM `AngelTypes` FROM `AngelTypes`
LEFT JOIN `UserAngelTypes` ON `AngelTypes`.`id`=`UserAngelTypes`.`angeltype_id` LEFT JOIN `UserAngelTypes` ON `AngelTypes`.`id`=`UserAngelTypes`.`angeltype_id`
AND `UserAngelTypes`.`user_id`=" . $user['UID'] . " AND `UserAngelTypes`.`user_id` = ?
ORDER BY `name`"); ORDER BY `name`', [$user['UID']]);
if ($result === false) {
engelsystem_error("Unable to load angeltypes.");
}
return $result;
} }
/** /**
* Returns all angeltypes. * Returns all angeltypes.
*
* @return array
*/ */
function AngelTypes() { function AngelTypes()
$result = sql_select(" {
return DB::select('
SELECT * SELECT *
FROM `AngelTypes` FROM `AngelTypes`
ORDER BY `name`"); ORDER BY `name`');
if ($result === false) {
engelsystem_error("Unable to load angeltypes.");
}
return $result;
} }
/** /**
* Returns AngelType id array * Returns AngelType id array
*
* @return array
*/ */
function AngelType_ids() { function AngelType_ids()
$result = sql_select("SELECT `id` FROM `AngelTypes`"); {
if ($result === false) { $result = DB::select('SELECT `id` FROM `AngelTypes`');
engelsystem_error("Unable to load angeltypes.");
}
return select_array($result, 'id', 'id'); return select_array($result, 'id', 'id');
} }
/** /**
* Returns angelType by id. * Returns angelType by id.
* *
* @param $angeltype_id angelType * @param int $angeltype_id angelType ID
* ID * @return array|null
*/ */
function AngelType($angeltype_id) { function AngelType($angeltype_id)
$angelType_source = sql_select("SELECT * FROM `AngelTypes` WHERE `id`='" . sql_escape($angeltype_id) . "'"); {
if ($angelType_source === false) { return DB::selectOne(
engelsystem_error("Unable to load angeltype."); 'SELECT * FROM `AngelTypes` WHERE `id`=?',
} [$angeltype_id]
if (count($angelType_source) > 0) { );
return $angelType_source[0];
}
return null;
} }
?>

View File

@ -1,18 +1,15 @@
<?php <?php
use Engelsystem\Database\DB;
/** /**
* Get event config. * Get event config.
*
* @return array|null
*/ */
function EventConfig() { function EventConfig()
$event_config = sql_select("SELECT * FROM `EventConfig` LIMIT 1"); {
if ($event_config === false) { return DB::selectOne('SELECT * FROM `EventConfig` LIMIT 1');
engelsystem_error("Unable to load event config.");
return false;
}
if (count($event_config) > 0) {
return $event_config[0];
}
return null;
} }
/** /**
@ -24,23 +21,55 @@ function EventConfig() {
* @param int $event_end_date * @param int $event_end_date
* @param int $teardown_end_date * @param int $teardown_end_date
* @param string $event_welcome_msg * @param string $event_welcome_msg
* @return int Rows updated
*/ */
function EventConfig_update($event_name, $buildup_start_date, $event_start_date, $event_end_date, $teardown_end_date, $event_welcome_msg) { function EventConfig_update(
$event_name,
$buildup_start_date,
$event_start_date,
$event_end_date,
$teardown_end_date,
$event_welcome_msg
) {
if (EventConfig() == null) { if (EventConfig() == null) {
return sql_query("INSERT INTO `EventConfig` SET return DB::insert('
`event_name`=" . sql_null($event_name) . ", INSERT INTO `EventConfig` (
`buildup_start_date`=" . sql_null($buildup_start_date) . ", `event_name`,
`event_start_date`=" . sql_null($event_start_date) . ", `buildup_start_date`,
`event_end_date`=" . sql_null($event_end_date) . ", `event_start_date`,
`teardown_end_date`=" . sql_null($teardown_end_date) . ", `event_end_date`,
`event_welcome_msg`=" . sql_null($event_welcome_msg)); `teardown_end_date`,
`event_welcome_msg`
)
VALUES (?, ?, ?, ?, ?, ?)
',
[
$event_name,
$buildup_start_date,
$event_start_date,
$event_end_date,
$teardown_end_date,
$event_welcome_msg
]
);
} }
return sql_query("UPDATE `EventConfig` SET
`event_name`=" . sql_null($event_name) . ", return DB::update('
`buildup_start_date`=" . sql_null($buildup_start_date) . ", UPDATE `EventConfig` SET
`event_start_date`=" . sql_null($event_start_date) . ", `event_name` = ?,
`event_end_date`=" . sql_null($event_end_date) . ", `buildup_start_date` = ?,
`teardown_end_date`=" . sql_null($teardown_end_date) . ", `event_start_date` = ?,
`event_welcome_msg`=" . sql_null($event_welcome_msg)); `event_end_date` = ?,
`teardown_end_date` = ?,
`event_welcome_msg` = ?
',
[
$event_name,
$buildup_start_date,
$event_start_date,
$event_end_date,
$teardown_end_date,
$event_welcome_msg,
]
);
} }
?>

View File

@ -1,38 +1,62 @@
<?php <?php
use Engelsystem\Database\DB;
/** /**
* Creates a log entry. * Creates a log entry.
* *
* @param $nick Username * @param string $logLevel Log level
* @param $message Log * @param string $message Log Message
* Message * @return bool
*/ */
function LogEntry_create($nick, $message) { function LogEntry_create($logLevel, $message)
return sql_query("INSERT INTO `LogEntries` SET `timestamp`='" . sql_escape(time()) . "', `nick`='" . sql_escape($nick) . "', `message`='" . sql_escape($message) . "'"); {
return DB::insert('
INSERT INTO `LogEntries` (`timestamp`, `level`, `message`)
VALUES(?, ?, ?)
', [time(), $logLevel, $message]);
} }
/** /**
* Returns log entries with maximum count of 10000. * Returns log entries with maximum count of 10000.
*
* @return array
*/ */
function LogEntries() { function LogEntries()
return sql_select("SELECT * FROM `LogEntries` ORDER BY `timestamp` DESC LIMIT 10000"); {
return DB::select('SELECT * FROM `LogEntries` ORDER BY `timestamp` DESC LIMIT 10000');
} }
/** /**
* Returns log entries filtered by a keyword * Returns log entries filtered by a keyword
*
* @param string $keyword
* @return array
*/ */
function LogEntries_filter($keyword) { function LogEntries_filter($keyword)
if ($keyword == "") { {
if ($keyword == '') {
return LogEntries(); return LogEntries();
} }
return sql_select("SELECT * FROM `LogEntries` WHERE `nick` LIKE '%" . sql_escape($keyword) . "%' OR `message` LIKE '%" . sql_escape($keyword) . "%' ORDER BY `timestamp` DESC");
$keyword = '%' . $keyword . '%';
return DB::select('
SELECT *
FROM `LogEntries`
WHERE `level` LIKE ?
OR `message` LIKE ?
ORDER BY `timestamp` DESC
',
[$keyword, $keyword]
);
} }
/** /**
* Delete all log entries. * Delete all log entries.
*
* @return bool
*/ */
function LogEntries_clear_all() { function LogEntries_clear_all()
return sql_query("TRUNCATE `LogEntries`"); {
return DB::statement('TRUNCATE `LogEntries`');
} }
?>

View File

@ -1,27 +1,26 @@
<?php <?php
use Engelsystem\Database\DB;
/** /**
* Returns Message id array * Returns Message id array
*
* @return array
*/ */
function Message_ids() { function Message_ids()
return sql_select("SELECT `id` FROM `Messages`"); {
return DB::select('SELECT `id` FROM `Messages`');
} }
/** /**
* Returns message by id. * Returns message by id.
* *
* @param $message_id message * @param int $message_id message ID
* ID * @return array|null
*/ */
function Message($message_id) { function Message($message_id)
$message_source = sql_select("SELECT * FROM `Messages` WHERE `id`='" . sql_escape($message_id) . "' LIMIT 1"); {
if ($message_source === false) { return DB::selectOne('SELECT * FROM `Messages` WHERE `id`=? LIMIT 1', [$message_id]);
return false;
}
if (count($message_source) > 0) {
return $message_source[0];
}
return null;
} }
/** /**
@ -29,23 +28,39 @@ function Message($message_id) {
* TODO: global $user con not be used in model! * TODO: global $user con not be used in model!
* send message * send message
* *
* @param $receiver_user_id User * @param int $receiver_user_id User ID of Reciever
* ID of Reciever * @param string $text Text of Message
* @param $text Text * @return bool
* of Message
*/ */
function Message_send($receiver_user_id, $text) { function Message_send($receiver_user_id, $text)
{
global $user; global $user;
$text = preg_replace("/([^\p{L}\p{P}\p{Z}\p{N}\n]{1,})/ui", '', strip_tags($text)); $text = preg_replace("/([^\p{L}\p{P}\p{Z}\p{N}\n]{1,})/ui", '', strip_tags($text));
$receiver_user_id = preg_replace("/([^0-9]{1,})/ui", '', strip_tags($receiver_user_id)); $receiver_user_id = preg_replace('/([^\d]{1,})/ui', '', strip_tags($receiver_user_id));
if (($text != "" && is_numeric($receiver_user_id)) && (sql_num_query("SELECT * FROM `User` WHERE `UID`='" . sql_escape($receiver_user_id) . "' AND NOT `UID`='" . sql_escape($user['UID']) . "' LIMIT 1") > 0)) { if (
sql_query("INSERT INTO `Messages` SET `Datum`='" . sql_escape(time()) . "', `SUID`='" . sql_escape($user['UID']) . "', `RUID`='" . sql_escape($receiver_user_id) . "', `Text`='" . sql_escape($text) . "'"); ($text != '' && is_numeric($receiver_user_id))
return true; && count(DB::select('
SELECT `UID`
FROM `User`
WHERE `UID` = ?
AND NOT `UID` = ?
LIMIT 1
', [$receiver_user_id, $user['UID']])) > 0
) {
return DB::insert('
INSERT INTO `Messages` (`Datum`, `SUID`, `RUID`, `Text`)
VALUES(?, ?, ?, ?)
',
[
time(),
$user['UID'],
$receiver_user_id,
$text
]
);
} }
return false; return false;
} }
?>

View File

@ -1,5 +1,7 @@
<?php <?php
use Engelsystem\Database\DB;
/** /**
* Entity needed angeltypes describes how many angels of given type are needed for a shift or in a room. * Entity needed angeltypes describes how many angels of given type are needed for a shift or in a room.
*/ */
@ -7,81 +9,80 @@
/** /**
* Insert a new needed angel type. * Insert a new needed angel type.
* *
* @param int $shift_id * @param int $shift_id The shift. Can be null, but then a room_id must be given.
* The shift. Can be null, but then a room_id must be given. * @param int $angeltype_id The angeltype
* @param int $angeltype_id * @param int $room_id The room. Can be null, but then a shift_id must be given.
* The angeltype * @param int $count How many angels are needed?
* @param int $room_id * @return int|false
* The room. Can be null, but then a shift_id must be given.
* @param int $count
* How many angels are needed?
*/ */
function NeededAngelType_add($shift_id, $angeltype_id, $room_id, $count) { function NeededAngelType_add($shift_id, $angeltype_id, $room_id, $count)
$result = sql_query(" {
INSERT INTO `NeededAngelTypes` SET DB::insert('
`shift_id`=" . sql_null($shift_id) . ", INSERT INTO `NeededAngelTypes` ( `shift_id`, `angel_type_id`, `room_id`, `count`)
`angel_type_id`='" . sql_escape($angeltype_id) . "', VALUES (?, ?, ?, ?)
`room_id`=" . sql_null($room_id) . ", ',
`count`='" . sql_escape($count) . "'"); [
if ($result === false) { $shift_id,
return false; $angeltype_id,
} $room_id,
return sql_id(); $count,
]);
return DB::getPdo()->lastInsertId();
} }
/** /**
* Deletes all needed angel types from given shift. * Deletes all needed angel types from given shift.
* *
* @param int $shift_id * @param int $shift_id id of the shift
* id of the shift
*/ */
function NeededAngelTypes_delete_by_shift($shift_id) { function NeededAngelTypes_delete_by_shift($shift_id)
return sql_query("DELETE FROM `NeededAngelTypes` WHERE `shift_id`='" . sql_escape($shift_id) . "'"); {
DB::delete('DELETE FROM `NeededAngelTypes` WHERE `shift_id` = ?', [$shift_id]);
} }
/** /**
* Deletes all needed angel types from given room. * Deletes all needed angel types from given room.
* *
* @param int $room_id * @param int $room_id id of the room
* id of the room
*/ */
function NeededAngelTypes_delete_by_room($room_id) { function NeededAngelTypes_delete_by_room($room_id)
return sql_query("DELETE FROM `NeededAngelTypes` WHERE `room_id`='" . sql_escape($room_id) . "'"); {
DB::delete(
'DELETE FROM `NeededAngelTypes` WHERE `room_id` = ?',
[$room_id]
);
} }
/** /**
* Returns all needed angeltypes and already taken needs. * Returns all needed angeltypes and already taken needs.
* *
* @param int $shiftID * @param int $shiftId id of shift
* id of shift * @return array
*/ */
function NeededAngelTypes_by_shift($shiftId) { function NeededAngelTypes_by_shift($shiftId)
$needed_angeltypes_source = sql_select(" {
$needed_angeltypes_source = DB::select('
SELECT `NeededAngelTypes`.*, `AngelTypes`.`id`, `AngelTypes`.`name`, `AngelTypes`.`restricted`, `AngelTypes`.`no_self_signup` SELECT `NeededAngelTypes`.*, `AngelTypes`.`id`, `AngelTypes`.`name`, `AngelTypes`.`restricted`, `AngelTypes`.`no_self_signup`
FROM `NeededAngelTypes` FROM `NeededAngelTypes`
JOIN `AngelTypes` ON `AngelTypes`.`id` = `NeededAngelTypes`.`angel_type_id` JOIN `AngelTypes` ON `AngelTypes`.`id` = `NeededAngelTypes`.`angel_type_id`
WHERE `shift_id`='" . sql_escape($shiftId) . "' WHERE `shift_id` = ?
AND `count` > 0 AND `count` > 0
ORDER BY `room_id` DESC ORDER BY `room_id` DESC',
"); [$shiftId]
if ($needed_angeltypes_source === false) { );
engelsystem_error("Unable to load needed angeltypes.");
}
// Use settings from room // Use settings from room
if (count($needed_angeltypes_source) == 0) { if (count($needed_angeltypes_source) == 0) {
$needed_angeltypes_source = sql_select(" $needed_angeltypes_source = DB::select('
SELECT `NeededAngelTypes`.*, `AngelTypes`.`name`, `AngelTypes`.`restricted` SELECT `NeededAngelTypes`.*, `AngelTypes`.`name`, `AngelTypes`.`restricted`
FROM `NeededAngelTypes` FROM `NeededAngelTypes`
JOIN `AngelTypes` ON `AngelTypes`.`id` = `NeededAngelTypes`.`angel_type_id` JOIN `AngelTypes` ON `AngelTypes`.`id` = `NeededAngelTypes`.`angel_type_id`
JOIN `Shifts` ON `Shifts`.`RID` = `NeededAngelTypes`.`room_id` JOIN `Shifts` ON `Shifts`.`RID` = `NeededAngelTypes`.`room_id`
WHERE `Shifts`.`SID`='" . sql_escape($shiftId) . "' WHERE `Shifts`.`SID` = ?
AND `count` > 0 AND `count` > 0
ORDER BY `room_id` DESC ORDER BY `room_id` DESC
"); ', [$shiftId]);
if ($needed_angeltypes_source === false) {
engelsystem_error("Unable to load needed angeltypes.");
}
} }
$shift_entries = ShiftEntries_by_shift($shiftId); $shift_entries = ShiftEntries_by_shift($shiftId);
@ -91,7 +92,7 @@ function NeededAngelTypes_by_shift($shiftId) {
$angeltype['taken'] = 0; $angeltype['taken'] = 0;
foreach ($shift_entries as $shift_entry) { foreach ($shift_entries as $shift_entry) {
if ($shift_entry['TID'] == $angeltype['angel_type_id'] && $shift_entry['freeloaded'] == 0) { if ($shift_entry['TID'] == $angeltype['angel_type_id'] && $shift_entry['freeloaded'] == 0) {
$angeltype['taken'] ++; $angeltype['taken']++;
$angeltype['shift_entries'][] = $shift_entry; $angeltype['shift_entries'][] = $shift_entry;
} }
} }
@ -101,5 +102,3 @@ function NeededAngelTypes_by_shift($shiftId) {
return $needed_angeltypes; return $needed_angeltypes;
} }
?>

View File

@ -1,11 +1,27 @@
<?php <?php
use Engelsystem\Database\DB;
/** /**
* returns a list of rooms. * returns a list of rooms.
*
* @param boolean $show_all returns also hidden rooms when true * @param boolean $show_all returns also hidden rooms when true
* @return array
*/ */
function Rooms($show_all = false) { function Rooms($show_all = false)
return sql_select("SELECT * FROM `Room`" . ($show_all ? "" : " WHERE `show`='Y'") . " ORDER BY `Name`"); {
return DB::select('SELECT * FROM `Room`' . ($show_all ? '' : ' WHERE `show`=\'Y\'') . ' ORDER BY `Name`');
}
/**
* Returns Room id array
*
* @return array
*/
function Room_ids()
{
$result = DB::select('SELECT `RID` FROM `Room`');
return select_array($result, 'RID', 'RID');
} }
/** /**
@ -13,48 +29,51 @@ function Rooms($show_all = false) {
* *
* @param int $room_id * @param int $room_id
*/ */
function Room_delete($room_id) { function Room_delete($room_id)
return sql_query("DELETE FROM `Room` WHERE `RID`=" . sql_escape($room_id)); {
DB::delete('DELETE FROM `Room` WHERE `RID` = ?', [$room_id]);
} }
/** /**
* Create a new room * Create a new room
* *
* @param string $name * @param string $name Name of the room
* Name of the room * @param boolean $from_frab Is this a frab imported room?
* @param boolean $from_frab * @param boolean $public Is the room visible for angels?
* Is this a frab imported room? * @param int $number Room number
* @param boolean $public * @return false|int
* Is the room visible for angels?
*/ */
function Room_create($name, $from_frab, $public) { function Room_create($name, $from_frab, $public, $number = null)
$result = sql_query(" {
INSERT INTO `Room` SET DB::insert('
`Name`='" . sql_escape($name) . "', INSERT INTO `Room` (`Name`, `FromPentabarf`, `show`, `Number`)
`FromPentabarf`='" . sql_escape($from_frab ? 'Y' : '') . "', VALUES (?, ?, ?, ?)
`show`='" . sql_escape($public ? 'Y' : '') . "', ',
`Number`=0"); [
if ($result === false) { $name,
return false; $from_frab ? 'Y' : '',
} $public ? 'Y' : '',
return sql_id(); (int)$number,
]
);
return DB::getPdo()->lastInsertId();
} }
/** /**
* Returns room by id. * Returns room by id.
* *
* @param $room_id RID * @param int $room_id RID
* @param bool $onlyVisible
* @return array|false
*/ */
function Room($room_id) { function Room($room_id, $onlyVisible = true)
$room_source = sql_select("SELECT * FROM `Room` WHERE `RID`='" . sql_escape($room_id) . "'"); {
return DB::selectOne('
if ($room_source === false) { SELECT *
return false; FROM `Room`
} WHERE `RID` = ?
if (count($room_source) > 0) { ' . ($onlyVisible ? 'AND `show` = \'Y\'' : ''),
return $room_source[0]; [$room_id]
} );
return null;
} }
?>

View File

@ -1,10 +1,15 @@
<?php <?php
use Engelsystem\Database\DB;
/** /**
* Returns an array with the attributes of shift entries. * Returns an array with the attributes of shift entries.
* FIXME! Needs entity object. * FIXME! Needs entity object.
*
* @return array
*/ */
function ShiftEntry_new() { function ShiftEntry_new()
{
return [ return [
'id' => null, 'id' => null,
'SID' => null, 'SID' => null,
@ -18,106 +23,173 @@ function ShiftEntry_new() {
/** /**
* Counts all freeloaded shifts. * Counts all freeloaded shifts.
*
* @return int
*/ */
function ShiftEntries_freeleaded_count() { function ShiftEntries_freeleaded_count()
return sql_select_single_cell("SELECT COUNT(*) FROM `ShiftEntry` WHERE `freeloaded` = 1"); {
$result = DB::selectOne('SELECT COUNT(*) FROM `ShiftEntry` WHERE `freeloaded` = 1');
if (empty($result)) {
return 0;
}
return (int)array_shift($result);
} }
/** /**
* List users subsribed to a given shift. * List users subsribed to a given shift.
*
* @param int $shift_id
* @return array
*/ */
function ShiftEntries_by_shift($shift_id) { function ShiftEntries_by_shift($shift_id)
return sql_select(" {
SELECT `User`.`Nick`, `User`.`email`, `User`.`email_shiftinfo`, `User`.`Sprache`, `User`.`Gekommen`, `ShiftEntry`.`UID`, `ShiftEntry`.`TID`, `ShiftEntry`.`SID`, `AngelTypes`.`name` as `angel_type_name`, `ShiftEntry`.`Comment`, `ShiftEntry`.`freeloaded` return DB::select('
SELECT
`User`.`Nick`,
`User`.`email`,
`User`.`email_shiftinfo`,
`User`.`Sprache`,
`User`.`Gekommen`,
`ShiftEntry`.`UID`,
`ShiftEntry`.`TID`,
`ShiftEntry`.`SID`,
`AngelTypes`.`name` AS `angel_type_name`,
`ShiftEntry`.`Comment`,
`ShiftEntry`.`freeloaded`
FROM `ShiftEntry` FROM `ShiftEntry`
JOIN `User` ON `ShiftEntry`.`UID`=`User`.`UID` JOIN `User` ON `ShiftEntry`.`UID`=`User`.`UID`
JOIN `AngelTypes` ON `ShiftEntry`.`TID`=`AngelTypes`.`id` JOIN `AngelTypes` ON `ShiftEntry`.`TID`=`AngelTypes`.`id`
WHERE `ShiftEntry`.`SID`='" . sql_escape($shift_id) . "'"); WHERE `ShiftEntry`.`SID` = ?',
[$shift_id]
);
} }
/** /**
* Create a new shift entry. * Create a new shift entry.
* *
* @param ShiftEntry $shift_entry * @param array $shift_entry
* @return bool
*/ */
function ShiftEntry_create($shift_entry) { function ShiftEntry_create($shift_entry)
{
mail_shift_assign(User($shift_entry['UID']), Shift($shift_entry['SID'])); mail_shift_assign(User($shift_entry['UID']), Shift($shift_entry['SID']));
return sql_query("INSERT INTO `ShiftEntry` SET return DB::insert('
`SID`='" . sql_escape($shift_entry['SID']) . "', INSERT INTO `ShiftEntry` (
`TID`='" . sql_escape($shift_entry['TID']) . "', `SID`,
`UID`='" . sql_escape($shift_entry['UID']) . "', `TID`,
`Comment`='" . sql_escape($shift_entry['Comment']) . "', `UID`,
`freeload_comment`='" . sql_escape($shift_entry['freeload_comment']) . "', `Comment`,
`freeloaded`=" . sql_bool($shift_entry['freeloaded'])); `freeload_comment`,
`freeloaded`
)
VALUES(?, ?, ?, ?, ?, ?)
',
[
$shift_entry['SID'],
$shift_entry['TID'],
$shift_entry['UID'],
$shift_entry['Comment'],
$shift_entry['freeload_comment'],
(int)$shift_entry['freeloaded'],
]
);
} }
/** /**
* Update a shift entry. * Update a shift entry.
*
* @param array $shift_entry
*/ */
function ShiftEntry_update($shift_entry) { function ShiftEntry_update($shift_entry)
return sql_query("UPDATE `ShiftEntry` SET {
`Comment`='" . sql_escape($shift_entry['Comment']) . "', DB::update('
`freeload_comment`='" . sql_escape($shift_entry['freeload_comment']) . "', UPDATE `ShiftEntry`
`freeloaded`=" . sql_bool($shift_entry['freeloaded']) . " SET
WHERE `id`='" . sql_escape($shift_entry['id']) . "'"); `Comment` = ?,
`freeload_comment` = ?,
`freeloaded` = ?
WHERE `id` = ?',
[
$shift_entry['Comment'],
$shift_entry['freeload_comment'],
(int)$shift_entry['freeloaded'],
$shift_entry['id']
]
);
} }
/** /**
* Get a shift entry. * Get a shift entry.
*
* @param int $shift_entry_id
* @return array|null
*/ */
function ShiftEntry($shift_entry_id) { function ShiftEntry($shift_entry_id)
$shift_entry = sql_select("SELECT * FROM `ShiftEntry` WHERE `id`='" . sql_escape($shift_entry_id) . "'"); {
if ($shift_entry === false) { return DB::selectOne('SELECT * FROM `ShiftEntry` WHERE `id` = ?', [$shift_entry_id]);
return false;
}
if (count($shift_entry) == 0) {
return null;
}
return $shift_entry[0];
} }
/** /**
* Delete a shift entry. * Delete a shift entry.
*
* @param int $shift_entry_id
*/ */
function ShiftEntry_delete($shift_entry_id) { function ShiftEntry_delete($shift_entry_id)
{
$shift_entry = ShiftEntry($shift_entry_id); $shift_entry = ShiftEntry($shift_entry_id);
mail_shift_removed(User($shift_entry['UID']), Shift($shift_entry['SID'])); mail_shift_removed(User($shift_entry['UID']), Shift($shift_entry['SID']));
return sql_query("DELETE FROM `ShiftEntry` WHERE `id`='" . sql_escape($shift_entry_id) . "'"); DB::delete('DELETE FROM `ShiftEntry` WHERE `id` = ?', [$shift_entry_id]);
} }
/** /**
* Returns next (or current) shifts of given user. * Returns next (or current) shifts of given user.
* *
* @param User $user * @param array $user
* @return array
*/ */
function ShiftEntries_upcoming_for_user($user) { function ShiftEntries_upcoming_for_user($user)
return sql_select(" {
return DB::select('
SELECT * SELECT *
FROM `ShiftEntry` FROM `ShiftEntry`
JOIN `Shifts` ON (`Shifts`.`SID` = `ShiftEntry`.`SID`) JOIN `Shifts` ON (`Shifts`.`SID` = `ShiftEntry`.`SID`)
JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id` JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id`
WHERE `ShiftEntry`.`UID`=" . sql_escape($user['UID']) . " WHERE `ShiftEntry`.`UID` = ?
AND `Shifts`.`end` > " . sql_escape(time()) . " AND `Shifts`.`end` > ?
ORDER BY `Shifts`.`end` ORDER BY `Shifts`.`end`
"); ',
[
$user['UID'],
time(),
]
);
} }
/** /**
* Returns shifts completed by the given user. * Returns shifts completed by the given user.
* *
* @param User $user * @param array $user
* @return array
*/ */
function ShiftEntries_finished_by_user($user) { function ShiftEntries_finished_by_user($user)
return sql_select(" {
return DB::select('
SELECT * SELECT *
FROM `ShiftEntry` FROM `ShiftEntry`
JOIN `Shifts` ON (`Shifts`.`SID` = `ShiftEntry`.`SID`) JOIN `Shifts` ON (`Shifts`.`SID` = `ShiftEntry`.`SID`)
JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id` JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id`
WHERE `ShiftEntry`.`UID`=" . sql_escape($user['UID']) . " WHERE `ShiftEntry`.`UID` = ?
AND `Shifts`.`end` < " . sql_escape(time()) . " AND `Shifts`.`end` < ?
AND `ShiftEntry`.`freeloaded` = 0 AND `ShiftEntry`.`freeloaded` = 0
ORDER BY `Shifts`.`end` ORDER BY `Shifts`.`end`
"); ',
[
$user['UID'],
time(),
]
);
} }
/** /**
@ -125,28 +197,39 @@ function ShiftEntries_finished_by_user($user) {
* *
* @param int $shift_id * @param int $shift_id
* @param int $angeltype_id * @param int $angeltype_id
* @return array
*/ */
function ShiftEntries_by_shift_and_angeltype($shift_id, $angeltype_id) { function ShiftEntries_by_shift_and_angeltype($shift_id, $angeltype_id)
$result = sql_select(" {
return DB::select('
SELECT * SELECT *
FROM `ShiftEntry` FROM `ShiftEntry`
WHERE `SID`=" . sql_escape($shift_id) . " WHERE `SID` = ?
AND `TID`=" . sql_escape($angeltype_id) . " AND `TID` = ?
"); ',
if ($result === false) { [
engelsystem_error("Unable to load shift entries."); $shift_id,
} $angeltype_id,
return $result; ]
);
} }
/** /**
* Returns all freeloaded shifts for given user. * Returns all freeloaded shifts for given user.
*
* @param array $user
* @return array
*/ */
function ShiftEntries_freeloaded_by_user($user) { function ShiftEntries_freeloaded_by_user($user)
return sql_select("SELECT * {
return DB::select('
SELECT *
FROM `ShiftEntry` FROM `ShiftEntry`
WHERE `freeloaded` = 1 WHERE `freeloaded` = 1
AND `UID`=" . sql_escape($user['UID'])); AND `UID` = ?
',
[
$user['UID']
]
);
} }
?>

View File

@ -6,8 +6,8 @@ namespace Engelsystem;
* BO to represent if there are free slots on a shift for a given angeltype * BO to represent if there are free slots on a shift for a given angeltype
* and if signup for a given user is possible (or not, because of collisions, etc.) * and if signup for a given user is possible (or not, because of collisions, etc.)
*/ */
class ShiftSignupState { class ShiftSignupState
{
/** /**
* Shift has free places * Shift has free places
*/ */
@ -43,11 +43,20 @@ class ShiftSignupState {
*/ */
const SIGNED_UP = 'SIGNED_UP'; const SIGNED_UP = 'SIGNED_UP';
/** @var string */
private $state; private $state;
/** @var int */
private $freeEntries; private $freeEntries;
public function __construct($state, $free_entries) { /**
* ShiftSignupState constructor.
*
* @param string $state
* @param int $free_entries
*/
public function __construct($state, $free_entries)
{
$this->state = $state; $this->state = $state;
$this->freeEntries = $free_entries; $this->freeEntries = $free_entries;
} }
@ -58,7 +67,8 @@ class ShiftSignupState {
* @param ShiftSignupState $shiftSignupState * @param ShiftSignupState $shiftSignupState
* The other state to combine * The other state to combine
*/ */
public function combineWith(ShiftSignupState $shiftSignupState) { public function combineWith(ShiftSignupState $shiftSignupState)
{
$this->freeEntries += $shiftSignupState->getFreeEntries(); $this->freeEntries += $shiftSignupState->getFreeEntries();
if ($this->valueForState($shiftSignupState->state) > $this->valueForState($this->state)) { if ($this->valueForState($shiftSignupState->state) > $this->valueForState($this->state)) {
@ -66,7 +76,12 @@ class ShiftSignupState {
} }
} }
private function valueForState($state) { /**
* @param string $state
* @return int
*/
private function valueForState($state)
{
switch ($state) { switch ($state) {
case ShiftSignupState::SHIFT_ENDED: case ShiftSignupState::SHIFT_ENDED:
return 100; return 100;
@ -84,13 +99,18 @@ class ShiftSignupState {
case ShiftSignupState::OCCUPIED: case ShiftSignupState::OCCUPIED:
case ShiftSignupState::ADMIN: case ShiftSignupState::ADMIN:
return 60; return 60;
default:
return 0;
} }
} }
/** /**
* Returns true, if signup is allowed * Returns true, if signup is allowed
*
* @return bool
*/ */
public function isSignupAllowed() { public function isSignupAllowed()
{
switch ($this->state) { switch ($this->state) {
case ShiftSignupState::FREE: case ShiftSignupState::FREE:
case ShiftSignupState::ADMIN: case ShiftSignupState::ADMIN:
@ -101,17 +121,21 @@ class ShiftSignupState {
/** /**
* Return the shift signup state * Return the shift signup state
*
* @return string
*/ */
public function getState() { public function getState()
{
return $this->state; return $this->state;
} }
/** /**
* How many places are free in this shift for the angeltype? * How many places are free in this shift for the angeltype?
*
* @return int
*/ */
public function getFreeEntries() { public function getFreeEntries()
{
return $this->freeEntries; return $this->freeEntries;
} }
} }
?>

View File

@ -1,11 +1,15 @@
<?php <?php
use Engelsystem\Database\DB;
/** /**
* Delete a shift type. * Delete a shift type.
*
* @param int $shifttype_id * @param int $shifttype_id
*/ */
function ShiftType_delete($shifttype_id) { function ShiftType_delete($shifttype_id)
return sql_query("DELETE FROM `ShiftTypes` WHERE `id`='" . sql_escape($shifttype_id) . "'"); {
DB::delete('DELETE FROM `ShiftTypes` WHERE `id`=?', [$shifttype_id]);
} }
/** /**
@ -16,12 +20,22 @@ function ShiftType_delete($shifttype_id) {
* @param int $angeltype_id * @param int $angeltype_id
* @param string $description * @param string $description
*/ */
function ShiftType_update($shifttype_id, $name, $angeltype_id, $description) { function ShiftType_update($shifttype_id, $name, $angeltype_id, $description)
return sql_query("UPDATE `ShiftTypes` SET {
`name`='" . sql_escape($name) . "', DB::update('
`angeltype_id`=" . sql_null($angeltype_id) . ", UPDATE `ShiftTypes` SET
`description`='" . sql_escape($description) . "' `name`=?,
WHERE `id`='" . sql_escape($shifttype_id) . "'"); `angeltype_id`=?,
`description`=?
WHERE `id`=?
',
[
$name,
$angeltype_id,
$description,
$shifttype_id,
]
);
} }
/** /**
@ -30,40 +44,41 @@ function ShiftType_update($shifttype_id, $name, $angeltype_id, $description) {
* @param string $name * @param string $name
* @param int $angeltype_id * @param int $angeltype_id
* @param string $description * @param string $description
* @return new shifttype id * @return int|false new shifttype id
*/ */
function ShiftType_create($name, $angeltype_id, $description) { function ShiftType_create($name, $angeltype_id, $description)
$result = sql_query("INSERT INTO `ShiftTypes` SET {
`name`='" . sql_escape($name) . "', DB::insert('
`angeltype_id`=" . sql_null($angeltype_id) . ", INSERT INTO `ShiftTypes` (`name`, `angeltype_id`, `description`)
`description`='" . sql_escape($description) . "'"); VALUES(?, ?, ?)
if ($result === false) { ',
return false; [
} $name,
return sql_id(); $angeltype_id,
$description
]
);
return DB::getPdo()->lastInsertId();
} }
/** /**
* Get a shift type by id. * Get a shift type by id.
* *
* @param int $shifttype_id * @param int $shifttype_id
* @return array|null
*/ */
function ShiftType($shifttype_id) { function ShiftType($shifttype_id)
$shifttype = sql_select("SELECT * FROM `ShiftTypes` WHERE `id`='" . sql_escape($shifttype_id) . "'"); {
if ($shifttype === false) { return DB::selectOne('SELECT * FROM `ShiftTypes` WHERE `id`=?', [$shifttype_id]);
engelsystem_error('Unable to load shift type.');
}
if ($shifttype == null) {
return null;
}
return $shifttype[0];
} }
/** /**
* Get all shift types. * Get all shift types.
*
* @return array
*/ */
function ShiftTypes() { function ShiftTypes()
return sql_select("SELECT * FROM `ShiftTypes` ORDER BY `name`"); {
return DB::select('SELECT * FROM `ShiftTypes` ORDER BY `name`');
} }
?>

View File

@ -7,14 +7,8 @@ namespace Engelsystem;
* *
* @author msquare * @author msquare
*/ */
class ShiftsFilter { class ShiftsFilter
{
/**
* How long can the time interval be?
*/
const MAX_DURATION = 86400;
// one day
/** /**
* Shift is completely full. * Shift is completely full.
*/ */
@ -32,17 +26,30 @@ class ShiftsFilter {
*/ */
private $userShiftsAdmin; private $userShiftsAdmin;
/** @var int[] */
private $filled = []; private $filled = [];
/** @var int[] */
private $rooms = []; private $rooms = [];
/** @var int[] */
private $types = []; private $types = [];
/** @var int unix timestamp */
private $startTime = null; private $startTime = null;
/** @var int unix timestamp */
private $endTime = null; private $endTime = null;
public function __construct($user_shifts_admin, $rooms, $types) { /**
* ShiftsFilter constructor.
*
* @param bool $user_shifts_admin
* @param int[] $rooms
* @param int[] $types
*/
public function __construct($user_shifts_admin, $rooms, $types)
{
$this->user_shifts_admin = $user_shifts_admin; $this->user_shifts_admin = $user_shifts_admin;
$this->rooms = $rooms; $this->rooms = $rooms;
$this->types = $types; $this->types = $types;
@ -56,66 +63,105 @@ class ShiftsFilter {
} }
} }
public function getStartTime() { /**
* @return int unix timestamp
*/
public function getStartTime()
{
return $this->startTime; return $this->startTime;
} }
public function setStartTime($startTime) { /**
* @param int $startTime unix timestamp
*/
public function setStartTime($startTime)
{
$this->startTime = $startTime; $this->startTime = $startTime;
} }
public function getEndTime() { /**
* @return int unix timestamp
*/
public function getEndTime()
{
return $this->endTime; return $this->endTime;
} }
public function setEndTime($endTime) { /**
if ($endTime - $this->startTime > ShiftsFilter::MAX_DURATION) { * @param int $endTime unix timestamp
$endTime = $this->startTime + ShiftsFilter::MAX_DURATION; */
} public function setEndTime($endTime)
{
$this->endTime = $endTime; $this->endTime = $endTime;
} }
public function getTypes() { /**
* @return int[]
*/
public function getTypes()
{
if (count($this->types) == 0) { if (count($this->types) == 0) {
return [ return [0];
0
];
} }
return $this->types; return $this->types;
} }
public function setTypes($types) { /**
* @param int[] $types
*/
public function setTypes($types)
{
$this->types = $types; $this->types = $types;
} }
public function getRooms() { /**
* @return int[]
*/
public function getRooms()
{
if (count($this->rooms) == 0) { if (count($this->rooms) == 0) {
return [ return [0];
0
];
} }
return $this->rooms; return $this->rooms;
} }
public function setRooms($rooms) { /**
* @param int[] $rooms
*/
public function setRooms($rooms)
{
$this->rooms = $rooms; $this->rooms = $rooms;
} }
public function isUserShiftsAdmin() { /**
* @return bool
*/
public function isUserShiftsAdmin()
{
return $this->userShiftsAdmin; return $this->userShiftsAdmin;
} }
public function setUserShiftsAdmin($userShiftsAdmin) { /**
* @param bool $userShiftsAdmin
*/
public function setUserShiftsAdmin($userShiftsAdmin)
{
$this->userShiftsAdmin = $userShiftsAdmin; $this->userShiftsAdmin = $userShiftsAdmin;
} }
public function getFilled() { /**
* @return int[]
*/
public function getFilled()
{
return $this->filled; return $this->filled;
} }
public function setFilled($filled) { /**
* @param int[] $filled
*/
public function setFilled($filled)
{
$this->filled = $filled; $this->filled = $filled;
} }
} }
?>

View File

@ -1,126 +1,225 @@
<?php <?php
use Engelsystem\Database\DB;
use Engelsystem\ShiftsFilter; use Engelsystem\ShiftsFilter;
use Engelsystem\ShiftSignupState; use Engelsystem\ShiftSignupState;
function Shifts_by_room($room) { /**
$result = sql_select("SELECT * FROM `Shifts` WHERE `RID`=" . sql_escape($room['RID']) . " ORDER BY `start`"); * @param array $angeltype
if ($result === false) { * @return array
engelsystem_error("Unable to load shifts."); */
} function Shifts_by_angeltype($angeltype) {
return $result; return DB::select('
} SELECT DISTINCT `Shifts`.* FROM `Shifts`
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id` = `Shifts`.`SID`
function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter) { WHERE `NeededAngelTypes`.`angel_type_id` = ?
$SQL = "SELECT * FROM (
SELECT DISTINCT `Shifts`.*, `ShiftTypes`.`name`, `Room`.`Name` as `room_name`
FROM `Shifts`
JOIN `Room` USING (`RID`)
JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id`
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`
WHERE `Shifts`.`RID` IN (" . implode(',', $shiftsFilter->getRooms()) . ")
AND `start` BETWEEN " . $shiftsFilter->getStartTime() . " AND " . $shiftsFilter->getEndTime() . "
AND `NeededAngelTypes`.`angel_type_id` IN (" . implode(',', $shiftsFilter->getTypes()) . ")
AND `NeededAngelTypes`.`count` > 0 AND `NeededAngelTypes`.`count` > 0
AND `Shifts`.`PSID` IS NULL AND `Shifts`.`PSID` IS NULL
UNION UNION
SELECT DISTINCT `Shifts`.*, `ShiftTypes`.`name`, `Room`.`Name` as `room_name` SELECT DISTINCT `Shifts`.* FROM `Shifts`
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id` = `Shifts`.`RID`
WHERE `NeededAngelTypes`.`angel_type_id` = ?
AND `NeededAngelTypes`.`count` > 0
AND NOT `Shifts`.`PSID` IS NULL
', [$angeltype['id'], $angeltype['id']]);
}
/**
* @param array $room
* @return array
*/
function Shifts_by_room($room)
{
return DB::select('SELECT * FROM `Shifts` WHERE `RID`=? ORDER BY `start`', [$room['RID']]);
}
/**
* @param ShiftsFilter $shiftsFilter
* @return array[]
*/
function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
{
$sql = 'SELECT * FROM (
SELECT DISTINCT `Shifts`.*, `ShiftTypes`.`name`, `Room`.`Name` AS `room_name`
FROM `Shifts`
JOIN `Room` USING (`RID`)
JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id`
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id` = `Shifts`.`SID`
WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
AND `start` BETWEEN ? AND ?
AND `NeededAngelTypes`.`angel_type_id` IN (' . implode(',', $shiftsFilter->getTypes()) . ')
AND `NeededAngelTypes`.`count` > 0
AND `Shifts`.`PSID` IS NULL
UNION
SELECT DISTINCT `Shifts`.*, `ShiftTypes`.`name`, `Room`.`Name` AS `room_name`
FROM `Shifts` FROM `Shifts`
JOIN `Room` USING (`RID`) JOIN `Room` USING (`RID`)
JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id` JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id`
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`Shifts`.`RID` JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`Shifts`.`RID`
WHERE `Shifts`.`RID` IN (" . implode(',', $shiftsFilter->getRooms()) . ") WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
AND `start` BETWEEN " . $shiftsFilter->getStartTime() . " AND " . $shiftsFilter->getEndTime() . " AND `start` BETWEEN ? AND ?
AND `NeededAngelTypes`.`angel_type_id` IN (" . implode(',', $shiftsFilter->getTypes()) . ") AND `NeededAngelTypes`.`angel_type_id` IN (' . implode(',', $shiftsFilter->getTypes()) . ')
AND `NeededAngelTypes`.`count` > 0 AND `NeededAngelTypes`.`count` > 0
AND NOT `Shifts`.`PSID` IS NULL) as tmp_shifts AND NOT `Shifts`.`PSID` IS NULL) AS tmp_shifts
ORDER BY `start`"; ORDER BY `start`';
$result = sql_select($SQL);
if ($result === false) { return DB::select(
engelsystem_error("Unable to load shifts by filter."); $sql,
} [
return $result; $shiftsFilter->getStartTime(),
$shiftsFilter->getEndTime(),
$shiftsFilter->getStartTime(),
$shiftsFilter->getEndTime(),
]
);
} }
function NeededAngeltypes_by_ShiftsFilter(ShiftsFilter $shiftsFilter) { /**
$SQL = "SELECT `NeededAngelTypes`.*, `Shifts`.`SID`, `AngelTypes`.`id`, `AngelTypes`.`name`, `AngelTypes`.`restricted`, `AngelTypes`.`no_self_signup` * @param ShiftsFilter $shiftsFilter
* @return array[]
*/
function NeededAngeltypes_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
{
$sql = '
SELECT
`NeededAngelTypes`.*,
`Shifts`.`SID`,
`AngelTypes`.`id`,
`AngelTypes`.`name`,
`AngelTypes`.`restricted`,
`AngelTypes`.`no_self_signup`
FROM `Shifts` FROM `Shifts`
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id`=`Shifts`.`SID` JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`
JOIN `AngelTypes` ON `AngelTypes`.`id`= `NeededAngelTypes`.`angel_type_id` JOIN `AngelTypes` ON `AngelTypes`.`id`= `NeededAngelTypes`.`angel_type_id`
WHERE `Shifts`.`RID` IN (" . implode(',', $shiftsFilter->getRooms()) . ") WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
AND `start` BETWEEN " . $shiftsFilter->getStartTime() . " AND " . $shiftsFilter->getEndTime() . " AND `start` BETWEEN ? AND ?
AND `Shifts`.`PSID` IS NULL AND `Shifts`.`PSID` IS NULL
UNION UNION
SELECT `NeededAngelTypes`.*, `Shifts`.`SID`, `AngelTypes`.`id`, `AngelTypes`.`name`, `AngelTypes`.`restricted`, `AngelTypes`.`no_self_signup` SELECT
`NeededAngelTypes`.*,
`Shifts`.`SID`,
`AngelTypes`.`id`,
`AngelTypes`.`name`,
`AngelTypes`.`restricted`,
`AngelTypes`.`no_self_signup`
FROM `Shifts` FROM `Shifts`
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`Shifts`.`RID` JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`Shifts`.`RID`
JOIN `AngelTypes` ON `AngelTypes`.`id`= `NeededAngelTypes`.`angel_type_id` JOIN `AngelTypes` ON `AngelTypes`.`id`= `NeededAngelTypes`.`angel_type_id`
WHERE `Shifts`.`RID` IN (" . implode(',', $shiftsFilter->getRooms()) . ") WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
AND `start` BETWEEN " . $shiftsFilter->getStartTime() . " AND " . $shiftsFilter->getEndTime() . " AND `start` BETWEEN ? AND ?
AND NOT `Shifts`.`PSID` IS NULL"; AND NOT `Shifts`.`PSID` IS NULL';
$result = sql_select($SQL);
if ($result === false) { return DB::select(
engelsystem_error("Unable to load needed angeltypes by filter."); $sql,
} [
return $result; $shiftsFilter->getStartTime(),
$shiftsFilter->getEndTime(),
$shiftsFilter->getStartTime(),
$shiftsFilter->getEndTime(),
]
);
} }
function NeededAngeltype_by_Shift_and_Angeltype($shift, $angeltype) { /**
$result = sql_select("SELECT `NeededAngelTypes`.*, `Shifts`.`SID`, `AngelTypes`.`id`, `AngelTypes`.`name`, `AngelTypes`.`restricted`, `AngelTypes`.`no_self_signup` * @param array $shift
* @param array $angeltype
* @return array|null
*/
function NeededAngeltype_by_Shift_and_Angeltype($shift, $angeltype)
{
return DB::selectOne('
SELECT
`NeededAngelTypes`.*,
`Shifts`.`SID`,
`AngelTypes`.`id`,
`AngelTypes`.`name`,
`AngelTypes`.`restricted`,
`AngelTypes`.`no_self_signup`
FROM `Shifts` FROM `Shifts`
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id`=`Shifts`.`SID` JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`
JOIN `AngelTypes` ON `AngelTypes`.`id`= `NeededAngelTypes`.`angel_type_id` JOIN `AngelTypes` ON `AngelTypes`.`id`= `NeededAngelTypes`.`angel_type_id`
WHERE `Shifts`.`SID`=" . sql_escape($shift['SID']) . " WHERE `Shifts`.`SID`=?
AND `AngelTypes`.`id`=" . sql_escape($angeltype['id']) . " AND `AngelTypes`.`id`=?
AND `Shifts`.`PSID` IS NULL AND `Shifts`.`PSID` IS NULL
UNION UNION
SELECT `NeededAngelTypes`.*, `Shifts`.`SID`, `AngelTypes`.`id`, `AngelTypes`.`name`, `AngelTypes`.`restricted`, `AngelTypes`.`no_self_signup` SELECT
`NeededAngelTypes`.*,
`Shifts`.`SID`,
`AngelTypes`.`id`,
`AngelTypes`.`name`,
`AngelTypes`.`restricted`,
`AngelTypes`.`no_self_signup`
FROM `Shifts` FROM `Shifts`
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`Shifts`.`RID` JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id`=`Shifts`.`RID`
JOIN `AngelTypes` ON `AngelTypes`.`id`= `NeededAngelTypes`.`angel_type_id` JOIN `AngelTypes` ON `AngelTypes`.`id`= `NeededAngelTypes`.`angel_type_id`
WHERE `Shifts`.`SID`=" . sql_escape($shift['SID']) . " WHERE `Shifts`.`SID`=?
AND `AngelTypes`.`id`=" . sql_escape($angeltype['id']) . " AND `AngelTypes`.`id`=?
AND NOT `Shifts`.`PSID` IS NULL"); AND NOT `Shifts`.`PSID` IS NULL
if ($result === false) { ',
engelsystem_error("Unable to load needed angeltypes by filter."); [
} $shift['SID'],
if (count($result) == 0) { $angeltype['id'],
return null; $shift['SID'],
} $angeltype['id']
return $result[0]; ]
);
} }
function ShiftEntries_by_ShiftsFilter(ShiftsFilter $shiftsFilter) { /**
$SQL = "SELECT `User`.`Nick`, `User`.`email`, `User`.`email_shiftinfo`, `User`.`Sprache`, `User`.`Gekommen`, `ShiftEntry`.`UID`, `ShiftEntry`.`TID`, `ShiftEntry`.`SID`, `ShiftEntry`.`Comment`, `ShiftEntry`.`freeloaded` * @param ShiftsFilter $shiftsFilter
* @return array
*/
function ShiftEntries_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
{
$sql = '
SELECT
`User`.`Nick`,
`User`.`email`,
`User`.`email_shiftinfo`,
`User`.`Sprache`,
`User`.`Gekommen`,
`ShiftEntry`.`UID`,
`ShiftEntry`.`TID`,
`ShiftEntry`.`SID`,
`ShiftEntry`.`Comment`,
`ShiftEntry`.`freeloaded`
FROM `Shifts` FROM `Shifts`
JOIN `ShiftEntry` ON `ShiftEntry`.`SID`=`Shifts`.`SID` JOIN `ShiftEntry` ON `ShiftEntry`.`SID`=`Shifts`.`SID`
JOIN `User` ON `ShiftEntry`.`UID`=`User`.`UID` JOIN `User` ON `ShiftEntry`.`UID`=`User`.`UID`
WHERE `Shifts`.`RID` IN (" . implode(',', $shiftsFilter->getRooms()) . ") WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
AND `start` BETWEEN " . $shiftsFilter->getStartTime() . " AND " . $shiftsFilter->getEndTime() . " AND `start` BETWEEN ? AND ?
ORDER BY `Shifts`.`start`"; ORDER BY `Shifts`.`start`';
$result = sql_select($SQL); return DB::select(
if ($result === false) { $sql,
engelsystem_error("Unable to load shift entries by filter."); [
} $shiftsFilter->getStartTime(),
return $result; $shiftsFilter->getEndTime(),
]
);
} }
/** /**
* Check if a shift collides with other shifts (in time). * Check if a shift collides with other shifts (in time).
* *
* @param Shift $shift * @param array $shift
* @param array<Shift> $shifts * @param array $shifts
* @return bool
*/ */
function Shift_collides($shift, $shifts) { function Shift_collides($shift, $shifts)
{
foreach ($shifts as $other_shift) { foreach ($shifts as $other_shift) {
if ($shift['SID'] != $other_shift['SID']) { if ($shift['SID'] != $other_shift['SID']) {
if (! ($shift['start'] >= $other_shift['end'] || $shift['end'] <= $other_shift['start'])) { if (!($shift['start'] >= $other_shift['end'] || $shift['end'] <= $other_shift['start'])) {
return true; return true;
} }
} }
@ -130,12 +229,17 @@ function Shift_collides($shift, $shifts) {
/** /**
* Returns the number of needed angels/free shift entries for an angeltype. * Returns the number of needed angels/free shift entries for an angeltype.
*
* @param array $needed_angeltype
* @param array[] $shift_entries
* @return int
*/ */
function Shift_free_entries($needed_angeltype, $shift_entries) { function Shift_free_entries($needed_angeltype, $shift_entries)
{
$taken = 0; $taken = 0;
foreach ($shift_entries as $shift_entry) { foreach ($shift_entries as $shift_entry) {
if ($shift_entry['freeloaded'] == 0) { if ($shift_entry['freeloaded'] == 0) {
$taken ++; $taken++;
} }
} }
return max(0, $needed_angeltype['count'] - $taken); return max(0, $needed_angeltype['count'] - $taken);
@ -144,19 +248,27 @@ function Shift_free_entries($needed_angeltype, $shift_entries) {
/** /**
* Check if shift signup is allowed from the end users point of view (no admin like privileges) * Check if shift signup is allowed from the end users point of view (no admin like privileges)
* *
* @param Shift $shift * @param array $user
* The shift * @param array $shift The shift
* @param AngelType $angeltype * @param array $angeltype The angeltype to which the user wants to sign up
* The angeltype to which the user wants to sign up * @param array|null $user_angeltype
* @param array<Shift> $user_shifts * @param array|null $user_shifts List of the users shifts
* List of the users shifts * @param array $needed_angeltype
* @param boolean $angeltype_supporter * @param array[] $shift_entries
* True, if the user has angeltype supporter rights for the angeltype, which enables him to sign somebody up for the shift. * @return ShiftSignupState
*/ */
function Shift_signup_allowed_angel($user, $shift, $angeltype, $user_angeltype, $user_shifts, $needed_angeltype, $shift_entries) { function Shift_signup_allowed_angel(
$user,
$shift,
$angeltype,
$user_angeltype,
$user_shifts,
$needed_angeltype,
$shift_entries
) {
$free_entries = Shift_free_entries($needed_angeltype, $shift_entries); $free_entries = Shift_free_entries($needed_angeltype, $shift_entries);
if ($user['Gekommen'] == 0) { if (config('signup_requires_arrival') && !$user['Gekommen']) {
return new ShiftSignupState(ShiftSignupState::SHIFT_ENDED, $free_entries); return new ShiftSignupState(ShiftSignupState::SHIFT_ENDED, $free_entries);
} }
@ -190,7 +302,11 @@ function Shift_signup_allowed_angel($user, $shift, $angeltype, $user_angeltype,
$user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype); $user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype);
} }
if ($user_angeltype == null || ($angeltype['no_self_signup'] == 1 && $user_angeltype != null) || ($angeltype['restricted'] == 1 && $user_angeltype != null && ! isset($user_angeltype['confirm_user_id']))) { if (
$user_angeltype == null
|| ($angeltype['no_self_signup'] == 1 && $user_angeltype != null)
|| ($angeltype['restricted'] == 1 && $user_angeltype != null && !isset($user_angeltype['confirm_user_id']))
) {
// you cannot join if user is not of this angel type // you cannot join if user is not of this angel type
// you cannot join if you are not confirmed // you cannot join if you are not confirmed
// you cannot join if angeltype has no self signup // you cannot join if angeltype has no self signup
@ -209,8 +325,13 @@ function Shift_signup_allowed_angel($user, $shift, $angeltype, $user_angeltype,
/** /**
* Check if an angeltype supporter can sign up a user to a shift. * Check if an angeltype supporter can sign up a user to a shift.
*
* @param array $needed_angeltype
* @param array[] $shift_entries
* @return ShiftSignupState
*/ */
function Shift_signup_allowed_angeltype_supporter($angeltype, $needed_angeltype, $shift_entries) { function Shift_signup_allowed_angeltype_supporter($needed_angeltype, $shift_entries)
{
$free_entries = Shift_free_entries($needed_angeltype, $shift_entries); $free_entries = Shift_free_entries($needed_angeltype, $shift_entries);
if ($free_entries == 0) { if ($free_entries == 0) {
return new ShiftSignupState(ShiftSignupState::OCCUPIED, $free_entries); return new ShiftSignupState(ShiftSignupState::OCCUPIED, $free_entries);
@ -222,12 +343,12 @@ function Shift_signup_allowed_angeltype_supporter($angeltype, $needed_angeltype,
/** /**
* Check if an admin can sign up a user to a shift. * Check if an admin can sign up a user to a shift.
* *
* @param Shift $shift * @param array $needed_angeltype
* The shift * @param array[] $shift_entries
* @param AngelType $angeltype * @return ShiftSignupState
* The angeltype to which the user wants to sign up
*/ */
function Shift_signup_allowed_admin($angeltype, $needed_angeltype, $shift_entries) { function Shift_signup_allowed_admin($needed_angeltype, $shift_entries)
{
$free_entries = Shift_free_entries($needed_angeltype, $shift_entries); $free_entries = Shift_free_entries($needed_angeltype, $shift_entries);
if ($free_entries == 0) { if ($free_entries == 0) {
@ -241,162 +362,230 @@ function Shift_signup_allowed_admin($angeltype, $needed_angeltype, $shift_entrie
/** /**
* Check if an angel can sign up for given shift. * Check if an angel can sign up for given shift.
* *
* @param Shift $shift * @param array $signup_user
* The shift * @param array $shift The shift
* @param AngelType $angeltype * @param array $angeltype The angeltype to which the user wants to sign up
* The angeltype to which the user wants to sign up * @param array|null $user_angeltype
* @param array<Shift> $user_shifts * @param array|null $user_shifts List of the users shifts
* List of the users shifts * @param array $needed_angeltype
* @param array[] $shift_entries
* @return ShiftSignupState
*/ */
function Shift_signup_allowed($signup_user, $shift, $angeltype, $user_angeltype = null, $user_shifts = null, $needed_angeltype, $shift_entries) { function Shift_signup_allowed(
$signup_user,
$shift,
$angeltype,
$user_angeltype,
$user_shifts,
$needed_angeltype,
$shift_entries
) {
global $user, $privileges; global $user, $privileges;
if (in_array('user_shifts_admin', $privileges)) { if (in_array('user_shifts_admin', $privileges)) {
return Shift_signup_allowed_admin($angeltype, $needed_angeltype, $shift_entries); return Shift_signup_allowed_admin($needed_angeltype, $shift_entries);
} }
if (in_array('shiftentry_edit_angeltype_supporter', $privileges) && User_is_AngelType_supporter($user, $angeltype)) { if (
return Shift_signup_allowed_angeltype_supporter($angeltype, $needed_angeltype, $shift_entries); in_array('shiftentry_edit_angeltype_supporter', $privileges)
&& User_is_AngelType_supporter($user, $angeltype)
) {
return Shift_signup_allowed_angeltype_supporter($needed_angeltype, $shift_entries);
} }
return Shift_signup_allowed_angel($signup_user, $shift, $angeltype, $user_angeltype, $user_shifts, $needed_angeltype, $shift_entries); return Shift_signup_allowed_angel(
$signup_user,
$shift,
$angeltype,
$user_angeltype,
$user_shifts,
$needed_angeltype,
$shift_entries
);
} }
/** /**
* Delete a shift by its external id. * Delete a shift by its external id.
*
* @param int $shift_psid
*/ */
function Shift_delete_by_psid($shift_psid) { function Shift_delete_by_psid($shift_psid)
return sql_query("DELETE FROM `Shifts` WHERE `PSID`='" . sql_escape($shift_psid) . "'"); {
DB::delete('DELETE FROM `Shifts` WHERE `PSID`=?', [$shift_psid]);
} }
/** /**
* Delete a shift. * Delete a shift.
*
* @param int $shift_id
*/ */
function Shift_delete($shift_id) { function Shift_delete($shift_id)
{
mail_shift_delete(Shift($shift_id)); mail_shift_delete(Shift($shift_id));
$result = sql_query("DELETE FROM `Shifts` WHERE `SID`='" . sql_escape($shift_id) . "'"); DB::delete('DELETE FROM `Shifts` WHERE `SID`=?', [$shift_id]);
if ($result === false) {
engelsystem_error('Unable to delete shift.');
}
return $result;
} }
/** /**
* Update a shift. * Update a shift.
*
* @param array $shift
* @return int Updated row count
*/ */
function Shift_update($shift) { function Shift_update($shift)
{
global $user; global $user;
$shift['name'] = ShiftType($shift['shifttype_id'])['name']; $shift['name'] = ShiftType($shift['shifttype_id'])['name'];
mail_shift_change(Shift($shift['SID']), $shift); mail_shift_change(Shift($shift['SID']), $shift);
return sql_query("UPDATE `Shifts` SET return DB::update('
`shifttype_id`='" . sql_escape($shift['shifttype_id']) . "', UPDATE `Shifts` SET
`start`='" . sql_escape($shift['start']) . "', `shifttype_id` = ?,
`end`='" . sql_escape($shift['end']) . "', `start` = ?,
`RID`='" . sql_escape($shift['RID']) . "', `end` = ?,
`title`=" . sql_null($shift['title']) . ", `RID` = ?,
`URL`=" . sql_null($shift['URL']) . ", `title` = ?,
`PSID`=" . sql_null($shift['PSID']) . ", `URL` = ?,
`edited_by_user_id`='" . sql_escape($user['UID']) . "', `PSID` = ?,
`edited_at_timestamp`=" . time() . " `edited_by_user_id` = ?,
WHERE `SID`='" . sql_escape($shift['SID']) . "'"); `edited_at_timestamp` = ?
WHERE `SID` = ?
',
[
$shift['shifttype_id'],
$shift['start'],
$shift['end'],
$shift['RID'],
$shift['title'],
$shift['URL'],
$shift['PSID'],
$user['UID'],
time(),
$shift['SID']
]
);
} }
/** /**
* Update a shift by its external id. * Update a shift by its external id.
*
* @param array $shift
* @return bool|null
* @throws Exception
*/ */
function Shift_update_by_psid($shift) { function Shift_update_by_psid($shift)
$shift_source = sql_select("SELECT `SID` FROM `Shifts` WHERE `PSID`=" . $shift['PSID']); {
if ($shift_source === false) { $shift_source = DB::selectOne('SELECT `SID` FROM `Shifts` WHERE `PSID`=?', [$shift['PSID']]);
return false;
if (empty($shift_source)) {
throw new Exception('Shift not found.');
} }
if (count($shift_source) == 0) {
return null; $shift['SID'] = $shift_source['SID'];
}
$shift['SID'] = $shift_source[0]['SID'];
return Shift_update($shift); return Shift_update($shift);
} }
/** /**
* Create a new shift. * Create a new shift.
* *
* @return new shift id or false * @param array $shift
* @return int ID of the new created shift
*/ */
function Shift_create($shift) { function Shift_create($shift)
{
global $user; global $user;
$result = sql_query("INSERT INTO `Shifts` SET DB::insert('
`shifttype_id`='" . sql_escape($shift['shifttype_id']) . "', INSERT INTO `Shifts` (
`start`='" . sql_escape($shift['start']) . "', `shifttype_id`,
`end`='" . sql_escape($shift['end']) . "', `start`,
`RID`='" . sql_escape($shift['RID']) . "', `end`,
`title`=" . sql_null($shift['title']) . ", `RID`,
`URL`=" . sql_null($shift['URL']) . ", `title`,
`PSID`=" . sql_null($shift['PSID']) . ", `URL`,
`created_by_user_id`='" . sql_escape($user['UID']) . "', `PSID`,
`created_at_timestamp`=" . time()); `created_by_user_id`,
if ($result === false) { `edited_at_timestamp`,
return false; `created_at_timestamp`
} )
return sql_id(); VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
',
[
$shift['shifttype_id'],
$shift['start'],
$shift['end'],
$shift['RID'],
$shift['title'],
$shift['URL'],
$shift['PSID'],
$user['UID'],
time(),
time(),
]
);
return DB::getPdo()->lastInsertId();
} }
/** /**
* Return users shifts. * Return users shifts.
*
* @param array $user
* @param bool $include_freeload_comments
* @return array
*/ */
function Shifts_by_user($user, $include_freeload_comments = false) { function Shifts_by_user($user, $include_freeload_comments = false)
$result = sql_select(" {
SELECT `ShiftTypes`.`id` as `shifttype_id`, `ShiftTypes`.`name`, return DB::select('
SELECT `ShiftTypes`.`id` AS `shifttype_id`, `ShiftTypes`.`name`,
`ShiftEntry`.`id`, `ShiftEntry`.`SID`, `ShiftEntry`.`TID`, `ShiftEntry`.`UID`, `ShiftEntry`.`freeloaded`, `ShiftEntry`.`Comment`, `ShiftEntry`.`id`, `ShiftEntry`.`SID`, `ShiftEntry`.`TID`, `ShiftEntry`.`UID`, `ShiftEntry`.`freeloaded`, `ShiftEntry`.`Comment`,
" . ($include_freeload_comments ? "`ShiftEntry`.`freeload_comment`, " : "") . " ' . ($include_freeload_comments ? '`ShiftEntry`.`freeload_comment`, ' : '') . '
`Shifts`.*, `Room`.* `Shifts`.*, `Room`.*
FROM `ShiftEntry` FROM `ShiftEntry`
JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID`) JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID`)
JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`) JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`)
JOIN `Room` ON (`Shifts`.`RID` = `Room`.`RID`) JOIN `Room` ON (`Shifts`.`RID` = `Room`.`RID`)
WHERE `UID`='" . sql_escape($user['UID']) . "' WHERE `UID` = ?
ORDER BY `start` ORDER BY `start`
"); ',
if ($result === false) { [
engelsystem_error('Unable to load users shifts.'); $user['UID']
} ]
return $result; );
} }
/** /**
* Returns Shift by id. * Returns Shift by id.
* *
* @param $shift_id Shift * @param int $shift_id Shift ID
* ID * @return array|null
*/ */
function Shift($shift_id) { function Shift($shift_id)
$shifts_source = sql_select(" {
$result = DB::selectOne('
SELECT `Shifts`.*, `ShiftTypes`.`name` SELECT `Shifts`.*, `ShiftTypes`.`name`
FROM `Shifts` FROM `Shifts`
JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`) JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`)
WHERE `SID`='" . sql_escape($shift_id) . "'"); WHERE `SID`=?', [$shift_id]);
$shiftsEntry_source = sql_select("SELECT `id`, `TID` , `UID` , `freeloaded` FROM `ShiftEntry` WHERE `SID`='" . sql_escape($shift_id) . "'");
if ($shifts_source === false) { if (empty($result)) {
engelsystem_error('Unable to load shift.');
}
if (empty($shifts_source)) {
return null; return null;
} }
$result = $shifts_source[0]; $shiftsEntry_source = DB::select('
SELECT `id`, `TID` , `UID` , `freeloaded`
FROM `ShiftEntry`
WHERE `SID`=?', [$shift_id]);
$result['ShiftEntry'] = $shiftsEntry_source; $result['ShiftEntry'] = $shiftsEntry_source;
$result['NeedAngels'] = []; $result['NeedAngels'] = [];
$temp = NeededAngelTypes_by_shift($shift_id); $angelTypes = NeededAngelTypes_by_shift($shift_id);
foreach ($temp as $e) { foreach ($angelTypes as $type) {
$result['NeedAngels'][] = [ $result['NeedAngels'][] = [
'TID' => $e['angel_type_id'], 'TID' => $type['angel_type_id'],
'count' => $e['count'], 'count' => $type['count'],
'restricted' => $e['restricted'], 'restricted' => $type['restricted'],
'taken' => $e['taken'] 'taken' => $type['taken']
]; ];
} }
@ -405,28 +594,22 @@ function Shift($shift_id) {
/** /**
* Returns all shifts with needed angeltypes and count of subscribed jobs. * Returns all shifts with needed angeltypes and count of subscribed jobs.
*
* @return array
*/ */
function Shifts() { function Shifts()
$shifts_source = sql_select(" {
SELECT `ShiftTypes`.`name`, `Shifts`.*, `Room`.`RID`, `Room`.`Name` as `room_name` $shifts_source = DB::select('
SELECT `ShiftTypes`.`name`, `Shifts`.*, `Room`.`RID`, `Room`.`Name` AS `room_name`
FROM `Shifts` FROM `Shifts`
JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`) JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`)
JOIN `Room` ON `Room`.`RID` = `Shifts`.`RID` JOIN `Room` ON `Room`.`RID` = `Shifts`.`RID`
"); ');
if ($shifts_source === false) {
return false;
}
foreach ($shifts_source as &$shift) { foreach ($shifts_source as &$shift) {
$needed_angeltypes = NeededAngelTypes_by_shift($shift['SID']); $needed_angeltypes = NeededAngelTypes_by_shift($shift['SID']);
if ($needed_angeltypes === false) {
return false;
}
$shift['angeltypes'] = $needed_angeltypes; $shift['angeltypes'] = $needed_angeltypes;
} }
return $shifts_source; return $shifts_source;
} }
?>

View File

@ -1,5 +1,7 @@
<?php <?php
use Engelsystem\Database\DB;
/** /**
* User angeltypes model * User angeltypes model
*/ */
@ -7,83 +9,87 @@
/** /**
* Checks if a user joined an angeltype. * Checks if a user joined an angeltype.
* *
* @param User $user * @param array $user The user to be checked
* The user to be checked * @param array $angeltype The angeltype to be checked
* @param Angeltype $angeltype
* The angeltype to be checked
* @return boolean * @return boolean
*/ */
function UserAngelType_exists($user, $angeltype) { function UserAngelType_exists($user, $angeltype)
return sql_num_query(" {
return count(DB::select('
SELECT `id` SELECT `id`
FROM `UserAngelTypes` FROM `UserAngelTypes`
WHERE `UserAngelTypes`.`user_id`='" . sql_escape($user['UID']) . "' WHERE `UserAngelTypes`.`user_id`=?
AND `angeltype_id`='" . sql_escape($angeltype['id']) . "' AND `angeltype_id`=?
") > 0; ', [$user['UID'], $angeltype['id']])) > 0;
} }
/** /**
* List users angeltypes. * List users angeltypes.
* *
* @param User $user * @param array $user
* @return array
*/ */
function User_angeltypes($user) { function User_angeltypes($user)
$result = sql_select(" {
return DB::select('
SELECT `AngelTypes`.*, `UserAngelTypes`.`confirm_user_id`, `UserAngelTypes`.`supporter` SELECT `AngelTypes`.*, `UserAngelTypes`.`confirm_user_id`, `UserAngelTypes`.`supporter`
FROM `UserAngelTypes` FROM `UserAngelTypes`
JOIN `AngelTypes` ON `UserAngelTypes`.`angeltype_id` = `AngelTypes`.`id` JOIN `AngelTypes` ON `UserAngelTypes`.`angeltype_id` = `AngelTypes`.`id`
WHERE `UserAngelTypes`.`user_id`='" . sql_escape($user['UID']) . "' WHERE `UserAngelTypes`.`user_id`=?
"); ', [$user['UID']]);
if ($result === false) {
engelsystem_error("Unable to load user angeltypes.");
return false;
}
return $result;
} }
/** /**
* Gets unconfirmed user angeltypes for angeltypes of which the given user is a supporter. * Gets unconfirmed user angeltypes for angeltypes of which the given user is a supporter.
* *
* @param User $user * @param array $user
* @return array
*/ */
function User_unconfirmed_AngelTypes($user) { function User_unconfirmed_AngelTypes($user)
$result = sql_select(" {
return DB::select('
SELECT SELECT
`UserAngelTypes`.*, `UserAngelTypes`.*,
`AngelTypes`.`name`, `AngelTypes`.`name`,
count(`UnconfirmedMembers`.`user_id`) as `count` count(`UnconfirmedMembers`.`user_id`) AS `count`
FROM `UserAngelTypes` FROM `UserAngelTypes`
JOIN `AngelTypes` ON `UserAngelTypes`.`angeltype_id`=`AngelTypes`.`id` JOIN `AngelTypes` ON `UserAngelTypes`.`angeltype_id`=`AngelTypes`.`id`
JOIN `UserAngelTypes` as `UnconfirmedMembers` ON `UserAngelTypes`.`angeltype_id`=`UnconfirmedMembers`.`angeltype_id` JOIN `UserAngelTypes` AS `UnconfirmedMembers` ON `UserAngelTypes`.`angeltype_id`=`UnconfirmedMembers`.`angeltype_id`
WHERE `UserAngelTypes`.`user_id`='" . sql_escape($user['UID']) . "' WHERE `UserAngelTypes`.`user_id`=?
AND `UserAngelTypes`.`supporter`=TRUE AND `UserAngelTypes`.`supporter`=TRUE
AND `AngelTypes`.`restricted`=TRUE AND `AngelTypes`.`restricted`=TRUE
AND `UnconfirmedMembers`.`confirm_user_id` IS NULL AND `UnconfirmedMembers`.`confirm_user_id` IS NULL
GROUP BY `UserAngelTypes`.`angeltype_id` GROUP BY `UserAngelTypes`.`angeltype_id`, `UserAngelTypes`.`id`
ORDER BY `AngelTypes`.`name`"); ORDER BY `AngelTypes`.`name`
if ($result === false) { ', [$user['UID']]);
engelsystem_error("Unable to load user angeltypes.");
}
return $result;
} }
/** /**
* Returns true if user is angeltype supporter or has privilege admin_user_angeltypes. * Returns true if user is angeltype supporter or has privilege admin_user_angeltypes.
* *
* @param User $user * @param array $user
* @param AngelType $angeltype * @param array $angeltype
* @return bool
*/ */
function User_is_AngelType_supporter(&$user, $angeltype) { function User_is_AngelType_supporter(&$user, $angeltype)
if(!isset($user['privileges'])) { {
if (!isset($user['privileges'])) {
$user['privileges'] = privileges_for_user($user['UID']); $user['privileges'] = privileges_for_user($user['UID']);
} }
return (sql_num_query(" return (count(DB::select('
SELECT `id` SELECT `id`
FROM `UserAngelTypes` FROM `UserAngelTypes`
WHERE `user_id`='" . sql_escape($user['UID']) . "' WHERE `user_id`=?
AND `angeltype_id`='" . sql_escape($angeltype['id']) . "' AND `angeltype_id`=?
AND `supporter`=TRUE AND `supporter`=TRUE
LIMIT 1") > 0) || in_array('admin_user_angeltypes', $user['privileges']); LIMIT 1
',
[
$user['UID'],
$angeltype['id']
]
)) > 0)
|| in_array('admin_user_angeltypes', $user['privileges']);
} }
/** /**
@ -92,16 +98,14 @@ function User_is_AngelType_supporter(&$user, $angeltype) {
* @param int $user_angeltype_id * @param int $user_angeltype_id
* @param bool $supporter * @param bool $supporter
*/ */
function UserAngelType_update($user_angeltype_id, $supporter) { function UserAngelType_update($user_angeltype_id, $supporter)
$result = sql_query(" {
DB::update('
UPDATE `UserAngelTypes` UPDATE `UserAngelTypes`
SET `supporter`=" . sql_bool($supporter) . " SET `supporter`=?
WHERE `id`='" . sql_escape($user_angeltype_id) . "' WHERE `id`=?
LIMIT 1"); LIMIT 1
if ($result === false) { ', [$supporter, $user_angeltype_id]);
engelsystem_error("Unable to update supporter rights.");
}
return $result;
} }
/** /**
@ -109,121 +113,116 @@ function UserAngelType_update($user_angeltype_id, $supporter) {
* *
* @param int $angeltype_id * @param int $angeltype_id
*/ */
function UserAngelTypes_delete_all($angeltype_id) { function UserAngelTypes_delete_all($angeltype_id)
$result = sql_query(" {
DB::delete('
DELETE FROM `UserAngelTypes` DELETE FROM `UserAngelTypes`
WHERE `angeltype_id`='" . sql_escape($angeltype_id) . "' WHERE `angeltype_id`=?
AND `confirm_user_id` IS NULL"); AND `confirm_user_id` IS NULL
if ($result === false) { ', [$angeltype_id]);
engelsystem_error("Unable to delete all unconfirmed users.");
}
return $result;
} }
/** /**
* Confirm all unconfirmed UserAngelTypes for given Angeltype. * Confirm all unconfirmed UserAngelTypes for given Angeltype.
* *
* @param int $angeltype_id * @param int $angeltype_id
* @param User $confirm_user * @param array $confirm_user
*/ */
function UserAngelTypes_confirm_all($angeltype_id, $confirm_user) { function UserAngelTypes_confirm_all($angeltype_id, $confirm_user)
$result = sql_query(" {
DB::update('
UPDATE `UserAngelTypes` UPDATE `UserAngelTypes`
SET `confirm_user_id`='" . sql_escape($confirm_user['UID']) . "' SET `confirm_user_id`=?
WHERE `angeltype_id`='" . sql_escape($angeltype_id) . "' WHERE `angeltype_id`=?
AND `confirm_user_id` IS NULL"); AND `confirm_user_id` IS NULL
if ($result === false) { ', [$confirm_user['UID'], $angeltype_id]);
engelsystem_error("Unable to confirm all users.");
}
return $result;
} }
/** /**
* Confirm an UserAngelType with confirming user. * Confirm an UserAngelType with confirming user.
* *
* @param int $user_angeltype_id * @param int $user_angeltype_id
* @param User $confirm_user * @param array $confirm_user
* @return bool
*/ */
function UserAngelType_confirm($user_angeltype_id, $confirm_user) { function UserAngelType_confirm($user_angeltype_id, $confirm_user)
$result = sql_query(" {
DB::update('
UPDATE `UserAngelTypes` UPDATE `UserAngelTypes`
SET `confirm_user_id`='" . sql_escape($confirm_user['UID']) . "' SET `confirm_user_id`=?
WHERE `id`='" . sql_escape($user_angeltype_id) . "' WHERE `id`=?
LIMIT 1"); LIMIT 1', [$confirm_user['UID'], $user_angeltype_id]);
if ($result === false) {
engelsystem_error("Unable to confirm user angeltype.");
}
return $result;
} }
/** /**
* Delete an UserAngelType. * Delete an UserAngelType.
* *
* @param UserAngelType $user_angeltype * @param array $user_angeltype
*/ */
function UserAngelType_delete($user_angeltype) { function UserAngelType_delete($user_angeltype)
return sql_query(" {
DB::delete('
DELETE FROM `UserAngelTypes` DELETE FROM `UserAngelTypes`
WHERE `id`='" . sql_escape($user_angeltype['id']) . "' WHERE `id`=?
LIMIT 1"); LIMIT 1', [$user_angeltype['id']]);
} }
/** /**
* Create an UserAngelType. * Create an UserAngelType.
* *
* @param User $user * @param array $user
* @param Angeltype $angeltype * @param array $angeltype
* @return int
*/ */
function UserAngelType_create($user, $angeltype) { function UserAngelType_create($user, $angeltype)
$result = sql_query(" {
INSERT INTO `UserAngelTypes` SET DB::insert('
`user_id`='" . sql_escape($user['UID']) . "', INSERT INTO `UserAngelTypes` (`user_id`, `angeltype_id`, `supporter`)
`angeltype_id`='" . sql_escape($angeltype['id']) . "'"); VALUES (?, ?, FALSE)
if ($result === false) { ',
engelsystem_error("Unable to create user angeltype."); [
} $user['UID'],
return sql_id(); $angeltype['id']
]
);
return DB::getPdo()->lastInsertId();
} }
/** /**
* Get an UserAngelType by its id. * Get an UserAngelType by its id.
* *
* @param int $user_angeltype_id * @param int $user_angeltype_id
* @return array|null
*/ */
function UserAngelType($user_angeltype_id) { function UserAngelType($user_angeltype_id)
$angeltype = sql_select(" {
return DB::selectOne('
SELECT * SELECT *
FROM `UserAngelTypes` FROM `UserAngelTypes`
WHERE `id`='" . sql_escape($user_angeltype_id) . "' WHERE `id`=?
LIMIT 1"); LIMIT 1', [$user_angeltype_id]);
if ($angeltype === false) {
engelsystem_error("Unable to load user angeltype.");
}
if (count($angeltype) == 0) {
return null;
}
return $angeltype[0];
} }
/** /**
* Get an UserAngelType by user and angeltype. * Get an UserAngelType by user and angeltype.
* *
* @param User $user * @param array $user
* @param Angeltype $angeltype * @param array $angeltype
* @return array|null
*/ */
function UserAngelType_by_User_and_AngelType($user, $angeltype) { function UserAngelType_by_User_and_AngelType($user, $angeltype)
$angeltype = sql_select(" {
return DB::selectOne('
SELECT * SELECT *
FROM `UserAngelTypes` FROM `UserAngelTypes`
WHERE `user_id`='" . sql_escape($user['UID']) . "' WHERE `user_id`=?
AND `angeltype_id`='" . sql_escape($angeltype['id']) . "' AND `angeltype_id`=?
LIMIT 1"); LIMIT 1
if ($angeltype === false) { ',
engelsystem_error("Unable to load user angeltype."); [
} $user['UID'],
if (count($angeltype) == 0) { $angeltype['id']
return null; ]
} );
return $angeltype[0];
} }
?>

View File

@ -1,10 +1,15 @@
<?php <?php
use Engelsystem\Database\DB;
/** /**
* Returns a new empty UserDriverLicense * Returns a new empty UserDriverLicense
* FIXME entity object needed * FIXME entity object needed
*
* @return array
*/ */
function UserDriverLicense_new() { function UserDriverLicense_new()
{
return [ return [
'user_id' => null, 'user_id' => null,
'has_car' => false, 'has_car' => false,
@ -19,74 +24,97 @@ function UserDriverLicense_new() {
/** /**
* Is it valid? * Is it valid?
* *
* @param UserDriverLicense $user_driver_license * @param array $user_driver_license The UserDriverLicense to check
* The UserDriverLicense to check
* @return boolean * @return boolean
*/ */
function UserDriverLicense_valid($user_driver_license) { function UserDriverLicense_valid($user_driver_license)
return $user_driver_license['has_license_car'] || $user_driver_license['has_license_3_5t_transporter'] || $user_driver_license['has_license_7_5t_truck'] || $user_driver_license['has_license_12_5t_truck'] || $user_driver_license['has_license_forklift']; {
return
$user_driver_license['has_license_car']
|| $user_driver_license['has_license_3_5t_transporter']
|| $user_driver_license['has_license_7_5t_truck']
|| $user_driver_license['has_license_12_5t_truck']
|| $user_driver_license['has_license_forklift'];
} }
/** /**
* Get a users driver license information * Get a users driver license information
* *
* @param int $user_id * @param int $user_id The users id
* The users id * @return array|null
*/ */
function UserDriverLicense($user_id) { function UserDriverLicense($user_id)
$user_driver_license = sql_select("SELECT * FROM `UserDriverLicenses` WHERE `user_id`='" . sql_escape($user_id) . "'"); {
if ($user_driver_license === false) { return DB::selectOne('
engelsystem_error('Unable to load user driver license.'); SELECT *
return false; FROM `UserDriverLicenses`
} WHERE `user_id`=?', [$user_id]);
if (count($user_driver_license) > 0) {
return $user_driver_license[0];
}
return null;
} }
/** /**
* Create a user's driver license entry * Create a user's driver license entry
* *
* @param UserDriverLicense $user_driver_license * @param array $user_driver_license The UserDriverLicense to create
* The UserDriverLicense to create * @param array $user
* @return array
*/ */
function UserDriverLicenses_create($user_driver_license, $user) { function UserDriverLicenses_create($user_driver_license, $user)
{
$user_driver_license['user_id'] = $user['UID']; $user_driver_license['user_id'] = $user['UID'];
$result = sql_query(" DB::insert('
INSERT INTO `UserDriverLicenses` SET INSERT INTO `UserDriverLicenses` (
`user_id`=" . sql_escape($user_driver_license['user_id']) . ", `user_id`,
`has_car`=" . sql_bool($user_driver_license['has_car']) . ", `has_car`,
`has_license_car`=" . sql_bool($user_driver_license['has_license_car']) . ", `has_license_car`,
`has_license_3_5t_transporter`=" . sql_bool($user_driver_license['has_license_3_5t_transporter']) . ", `has_license_3_5t_transporter`,
`has_license_7_5t_truck`=" . sql_bool($user_driver_license['has_license_7_5t_truck']) . ", `has_license_7_5t_truck`,
`has_license_12_5t_truck`=" . sql_bool($user_driver_license['has_license_12_5t_truck']) . ", `has_license_12_5t_truck`,
`has_license_forklift`=" . sql_bool($user_driver_license['has_license_forklift'])); `has_license_forklift`
if ($result === false) { )
engelsystem_error('Unable to create user driver license'); VALUES (?, ?, ?, ?, ?, ?, ?)
} ',
[
$user_driver_license['user_id'],
(int)$user_driver_license['has_car'],
(int)$user_driver_license['has_license_car'],
(int)$user_driver_license['has_license_3_5t_transporter'],
(int)$user_driver_license['has_license_7_5t_truck'],
(int)$user_driver_license['has_license_12_5t_truck'],
(int)$user_driver_license['has_license_forklift'],
]
);
return $user_driver_license; return $user_driver_license;
} }
/** /**
* Update a user's driver license entry * Update a user's driver license entry
* *
* @param UserDriverLicense $user_driver_license * @param array $user_driver_license The UserDriverLicense to update
* The UserDriverLicense to update
*/ */
function UserDriverLicenses_update($user_driver_license) { function UserDriverLicenses_update($user_driver_license)
$result = sql_query("UPDATE `UserDriverLicenses` SET {
`has_car`=" . sql_bool($user_driver_license['has_car']) . ", DB::update('
`has_license_car`=" . sql_bool($user_driver_license['has_license_car']) . ", UPDATE `UserDriverLicenses`
`has_license_3_5t_transporter`=" . sql_bool($user_driver_license['has_license_3_5t_transporter']) . ", SET
`has_license_7_5t_truck`=" . sql_bool($user_driver_license['has_license_7_5t_truck']) . ", `has_car`=?,
`has_license_12_5t_truck`=" . sql_bool($user_driver_license['has_license_12_5t_truck']) . ", `has_license_car`=?,
`has_license_forklift`=" . sql_bool($user_driver_license['has_license_forklift']) . " `has_license_3_5t_transporter`=?,
WHERE `user_id`='" . sql_escape($user_driver_license['user_id']) . "'"); `has_license_7_5t_truck`=?,
if ($result === false) { `has_license_12_5t_truck`=?,
engelsystem_error("Unable to update user driver license information"); `has_license_forklift`=?
} WHERE `user_id`=?
return $result; ',
[
(int)$user_driver_license['has_car'],
(int)$user_driver_license['has_license_car'],
(int)$user_driver_license['has_license_3_5t_transporter'],
(int)$user_driver_license['has_license_7_5t_truck'],
(int)$user_driver_license['has_license_12_5t_truck'],
(int)$user_driver_license['has_license_forklift'],
$user_driver_license['user_id'],
]
);
} }
/** /**
@ -94,11 +122,7 @@ function UserDriverLicenses_update($user_driver_license) {
* *
* @param int $user_id * @param int $user_id
*/ */
function UserDriverLicenses_delete($user_id) { function UserDriverLicenses_delete($user_id)
$result = sql_query("DELETE FROM `UserDriverLicenses` WHERE `user_id`=" . sql_escape($user_id)); {
if ($result === false) { DB::delete('DELETE FROM `UserDriverLicenses` WHERE `user_id`=?', [$user_id]);
engelsystem_error("Unable to remove user driver license information");
}
return $result;
} }
?>

View File

@ -1,17 +1,22 @@
<?php <?php
use Engelsystem\Database\DB;
/** /**
* Returns users groups * Returns users groups
* @param User $user *
* @param array $user
* @return array
*/ */
function User_groups($user) { function User_groups($user)
return sql_select(" {
return DB::select('
SELECT `Groups`.* SELECT `Groups`.*
FROM `UserGroups` FROM `UserGroups`
JOIN `Groups` ON `Groups`.`UID`=`UserGroups`.`group_id` JOIN `Groups` ON `Groups`.`UID`=`UserGroups`.`group_id`
WHERE `UserGroups`.`uid`='" . sql_escape($user['UID']) . "' WHERE `UserGroups`.`uid`=?
ORDER BY `UserGroups`.`group_id` ORDER BY `UserGroups`.`group_id`
"); ',
[$user['UID']]
);
} }
?>

View File

@ -1,4 +1,6 @@
<?php <?php
use Engelsystem\Database\DB;
use Engelsystem\ValidationResult; use Engelsystem\ValidationResult;
/** /**
@ -10,70 +12,153 @@ use Engelsystem\ValidationResult;
* *
* @param int $user_id * @param int $user_id
*/ */
function User_delete($user_id) { function User_delete($user_id)
return sql_query("DELETE FROM `User` WHERE `UID`='" . sql_escape($user_id) . "'"); {
DB::delete('DELETE FROM `User` WHERE `UID`=?', [$user_id]);
} }
/** /**
* Update user. * Update user.
* *
* @param User $user * @param array $user
*/ */
function User_update($user) { function User_update($user)
return sql_query("UPDATE `User` SET {
`Nick`='" . sql_escape($user['Nick']) . "', DB::update('
`Name`='" . sql_escape($user['Name']) . "', UPDATE `User` SET
`Vorname`='" . sql_escape($user['Vorname']) . "', `Nick`=?,
`Alter`='" . sql_escape($user['Alter']) . "', `Name`=?,
`Telefon`='" . sql_escape($user['Telefon']) . "', `Vorname`=?,
`DECT`='" . sql_escape($user['DECT']) . "', `Alter`=?,
`Handy`='" . sql_escape($user['Handy']) . "', `Telefon`=?,
`email`='" . sql_escape($user['email']) . "', `DECT`=?,
`email_shiftinfo`=" . sql_bool($user['email_shiftinfo']) . ", `Handy`=?,
`email_by_human_allowed`=" . sql_bool($user['email_by_human_allowed']) . ", `email`=?,
`jabber`='" . sql_escape($user['jabber']) . "', `email_shiftinfo`=?,
`Size`='" . sql_escape($user['Size']) . "', `email_by_human_allowed`=?,
`Gekommen`='" . sql_escape($user['Gekommen']) . "', `jabber`=?,
`Aktiv`='" . sql_escape($user['Aktiv']) . "', `Size`=?,
`force_active`=" . sql_bool($user['force_active']) . ", `Gekommen`=?,
`Tshirt`='" . sql_escape($user['Tshirt']) . "', `Aktiv`=?,
`color`='" . sql_escape($user['color']) . "', `force_active`=?,
`Sprache`='" . sql_escape($user['Sprache']) . "', `Tshirt`=?,
`Hometown`='" . sql_escape($user['Hometown']) . "', `color`=?,
`got_voucher`='" . sql_escape($user['got_voucher']) . "', `Sprache`=?,
`arrival_date`='" . sql_escape($user['arrival_date']) . "', `Hometown`=?,
`planned_arrival_date`='" . sql_escape($user['planned_arrival_date']) . "', `got_voucher`=?,
`planned_departure_date`=" . sql_null($user['planned_departure_date']) . " `arrival_date`=?,
WHERE `UID`='" . sql_escape($user['UID']) . "'"); `planned_arrival_date`=?,
`planned_departure_date`=?
WHERE `UID`=?
',
[
$user['Nick'],
$user['Name'],
$user['Vorname'],
$user['Alter'],
$user['Telefon'],
$user['DECT'],
$user['Handy'],
$user['email'],
(int)$user['email_shiftinfo'],
(int)$user['email_by_human_allowed'],
$user['jabber'],
$user['Size'],
$user['Gekommen'],
$user['Aktiv'],
(int)$user['force_active'],
$user['Tshirt'],
$user['color'],
$user['Sprache'],
$user['Hometown'],
$user['got_voucher'],
$user['arrival_date'],
$user['planned_arrival_date'],
$user['planned_departure_date'],
$user['UID'],
]
);
} }
/** /**
* Counts all forced active users. * Counts all forced active users.
*
* @return int
*/ */
function User_force_active_count() { function User_force_active_count()
return sql_select_single_cell("SELECT COUNT(*) FROM `User` WHERE `force_active` = 1"); {
$result = DB::selectOne('SELECT COUNT(*) FROM `User` WHERE `force_active` = 1');
if (empty($result)) {
return 0;
}
return (int)array_shift($result);
} }
function User_active_count() { /**
return sql_select_single_cell("SELECT COUNT(*) FROM `User` WHERE `Aktiv` = 1"); * @return int
*/
function User_active_count()
{
$result = DB::selectOne('SELECT COUNT(*) FROM `User` WHERE `Aktiv` = 1');
if (empty($result)) {
return 0;
}
return (int)array_shift($result);
} }
function User_got_voucher_count() { /**
return sql_select_single_cell("SELECT SUM(`got_voucher`) FROM `User`"); * @return int
*/
function User_got_voucher_count()
{
$result = DB::selectOne('SELECT SUM(`got_voucher`) FROM `User`');
if (empty($result)) {
return 0;
}
return (int)array_shift($result);
} }
function User_arrived_count() { /**
return sql_select_single_cell("SELECT COUNT(*) FROM `User` WHERE `Gekommen` = 1"); * @return int
*/
function User_arrived_count()
{
$result = DB::selectOne('SELECT COUNT(*) FROM `User` WHERE `Gekommen` = 1');
if (empty($result)) {
return 0;
}
return (int)array_shift($result);
} }
function User_tshirts_count() { /**
return sql_select_single_cell("SELECT COUNT(*) FROM `User` WHERE `Tshirt` = 1"); * @return int
*/
function User_tshirts_count()
{
$result = DB::selectOne('SELECT COUNT(*) FROM `User` WHERE `Tshirt` = 1');
if (empty($result)) {
return 0;
}
return (int)array_shift($result);
} }
/** /**
* Returns all column names for sorting in an array. * Returns all column names for sorting in an array.
*
* @return array
*/ */
function User_sortable_columns() { function User_sortable_columns()
{
return [ return [
'Nick', 'Nick',
'Name', 'Name',
@ -94,78 +179,101 @@ function User_sortable_columns() {
* Get all users, ordered by Nick by default or by given param. * Get all users, ordered by Nick by default or by given param.
* *
* @param string $order_by * @param string $order_by
* @return array
*/ */
function Users($order_by = 'Nick') { function Users($order_by = 'Nick')
return sql_select("SELECT * FROM `User` ORDER BY `" . sql_escape($order_by) . "` ASC"); {
return DB::select(sprintf('
SELECT *
FROM `User`
ORDER BY `%s` ASC
',
trim(DB::getPdo()->quote($order_by), '\'')
));
} }
/** /**
* Returns true if user is freeloader * Returns true if user is freeloader
* *
* @param User $user * @param array $user
* @return bool
*/ */
function User_is_freeloader($user) { function User_is_freeloader($user)
global $max_freeloadable_shifts, $user; {
global $user;
return count(ShiftEntries_freeloaded_by_user($user)) >= $max_freeloadable_shifts; return count(ShiftEntries_freeloaded_by_user($user)) >= config('max_freeloadable_shifts');
} }
/** /**
* Returns all users that are not member of given angeltype. * Returns all users that are not member of given angeltype.
* *
* @param Angeltype $angeltype * @param array $angeltype Angeltype
* @return array
*/ */
function Users_by_angeltype_inverted($angeltype) { function Users_by_angeltype_inverted($angeltype)
$result = sql_select(" {
return DB::select('
SELECT `User`.* SELECT `User`.*
FROM `User` FROM `User`
LEFT JOIN `UserAngelTypes` ON (`User`.`UID`=`UserAngelTypes`.`user_id` AND `angeltype_id`='" . sql_escape($angeltype['id']) . "') LEFT JOIN `UserAngelTypes`
ON (`User`.`UID`=`UserAngelTypes`.`user_id` AND `angeltype_id`=?)
WHERE `UserAngelTypes`.`id` IS NULL WHERE `UserAngelTypes`.`id` IS NULL
ORDER BY `Nick`"); ORDER BY `Nick`
if ($result === false) { ',
engelsystem_error("Unable to load users."); [
} $angeltype['id']
return $result; ]
);
} }
/** /**
* Returns all members of given angeltype. * Returns all members of given angeltype.
* *
* @param Angeltype $angeltype * @param array $angeltype
* @return array
*/ */
function Users_by_angeltype($angeltype) { function Users_by_angeltype($angeltype)
$result = sql_select(" {
return DB::select('
SELECT SELECT
`User`.*, `User`.*,
`UserAngelTypes`.`id` as `user_angeltype_id`, `UserAngelTypes`.`id` AS `user_angeltype_id`,
`UserAngelTypes`.`confirm_user_id`, `UserAngelTypes`.`confirm_user_id`,
`UserAngelTypes`.`supporter`, `UserAngelTypes`.`supporter`,
(`UserDriverLicenses`.`user_id` IS NOT NULL) AS `wants_to_drive`,
`UserDriverLicenses`.* `UserDriverLicenses`.*
FROM `User` FROM `User`
JOIN `UserAngelTypes` ON `User`.`UID`=`UserAngelTypes`.`user_id` JOIN `UserAngelTypes` ON `User`.`UID`=`UserAngelTypes`.`user_id`
LEFT JOIN `UserDriverLicenses` ON `User`.`UID`=`UserDriverLicenses`.`user_id` LEFT JOIN `UserDriverLicenses` ON `User`.`UID`=`UserDriverLicenses`.`user_id`
WHERE `UserAngelTypes`.`angeltype_id`='" . sql_escape($angeltype['id']) . "' WHERE `UserAngelTypes`.`angeltype_id`=?
ORDER BY `Nick`"); ORDER BY `Nick`
if ($result === false) { ',
engelsystem_error("Unable to load members."); [
} $angeltype['id']
return $result; ]
);
} }
/** /**
* Returns User id array * Returns User id array
*
* @return array
*/ */
function User_ids() { function User_ids()
return sql_select("SELECT `UID` FROM `User`"); {
return DB::select('SELECT `UID` FROM `User`');
} }
/** /**
* Strip unwanted characters from a users nick. * Strip unwanted characters from a users nick.
* *
* @param string $nick * @param string $nick
* @return string
*/ */
function User_validate_Nick($nick) { function User_validate_Nick($nick)
return preg_replace("/([^a-z0-9üöäß. _+*-]{1,})/ui", '', $nick); {
return preg_replace('/([^\wüöäß. +*-]{1,})/ui', '', $nick);
} }
/** /**
@ -175,7 +283,8 @@ function User_validate_Nick($nick) {
* The email address to validate * The email address to validate
* @return ValidationResult * @return ValidationResult
*/ */
function User_validate_mail($mail) { function User_validate_mail($mail)
{
$mail = strip_item($mail); $mail = strip_item($mail);
return new ValidationResult(check_email($mail), $mail); return new ValidationResult(check_email($mail), $mail);
} }
@ -187,7 +296,8 @@ function User_validate_mail($mail) {
* Jabber-ID to validate * Jabber-ID to validate
* @return ValidationResult * @return ValidationResult
*/ */
function User_validate_jabber($jabber) { function User_validate_jabber($jabber)
{
$jabber = strip_item($jabber); $jabber = strip_item($jabber);
if ($jabber == '') { if ($jabber == '') {
// Empty is ok // Empty is ok
@ -199,11 +309,11 @@ function User_validate_jabber($jabber) {
/** /**
* Validate the planned arrival date * Validate the planned arrival date
* *
* @param int $planned_arrival_date * @param int $planned_arrival_date Unix timestamp
* Unix timestamp
* @return ValidationResult * @return ValidationResult
*/ */
function User_validate_planned_arrival_date($planned_arrival_date) { function User_validate_planned_arrival_date($planned_arrival_date)
{
if ($planned_arrival_date == null) { if ($planned_arrival_date == null) {
// null is not okay // null is not okay
return new ValidationResult(false, time()); return new ValidationResult(false, time());
@ -233,7 +343,8 @@ function User_validate_planned_arrival_date($planned_arrival_date) {
* Unix timestamp * Unix timestamp
* @return ValidationResult * @return ValidationResult
*/ */
function User_validate_planned_departure_date($planned_arrival_date, $planned_departure_date) { function User_validate_planned_departure_date($planned_arrival_date, $planned_departure_date)
{
if ($planned_departure_date == null) { if ($planned_departure_date == null) {
// null is okay // null is okay
return new ValidationResult(true, null); return new ValidationResult(true, null);
@ -261,17 +372,12 @@ function User_validate_planned_departure_date($planned_arrival_date, $planned_de
/** /**
* Returns user by id. * Returns user by id.
* *
* @param $user_id UID * @param int $user_id UID
* @return array|null
*/ */
function User($user_id) { function User($user_id)
$user_source = sql_select("SELECT * FROM `User` WHERE `UID`='" . sql_escape($user_id) . "' LIMIT 1"); {
if ($user_source === false) { return DB::selectOne('SELECT * FROM `User` WHERE `UID`=? LIMIT 1', [$user_id]);
engelsystem_error("Unable to load user.");
}
if (count($user_source) > 0) {
return $user_source[0];
}
return null;
} }
/** /**
@ -279,87 +385,92 @@ function User($user_id) {
* *
* @param string $api_key * @param string $api_key
* User api key * User api key
* @return Matching user, null or false on error * @return array|null Matching user, null if not found
*/ */
function User_by_api_key($api_key) { function User_by_api_key($api_key)
$user = sql_select("SELECT * FROM `User` WHERE `api_key`='" . sql_escape($api_key) . "' LIMIT 1"); {
if ($user === false) { return DB::selectOne('SELECT * FROM `User` WHERE `api_key`=? LIMIT 1', [$api_key]);
engelsystem_error("Unable to find user by api key.");
}
if (count($user) == 0) {
return null;
}
return $user[0];
} }
/** /**
* Returns User by email. * Returns User by email.
* *
* @param string $email * @param string $email
* @return Matching user, null or false on error * @return array|null Matching user, null or false on error
*/ */
function User_by_email($email) { function User_by_email($email)
$user = sql_select("SELECT * FROM `User` WHERE `email`='" . sql_escape($email) . "' LIMIT 1"); {
if ($user === false) { return DB::selectOne('SELECT * FROM `User` WHERE `email`=? LIMIT 1', [$email]);
engelsystem_error("Unable to load user.");
}
if (count($user) == 0) {
return null;
}
return $user[0];
} }
/** /**
* Returns User by password token. * Returns User by password token.
* *
* @param string $token * @param string $token
* @return Matching user, null or false on error * @return array|null Matching user, null when not found
*/ */
function User_by_password_recovery_token($token) { function User_by_password_recovery_token($token)
$user = sql_select("SELECT * FROM `User` WHERE `password_recovery_token`='" . sql_escape($token) . "' LIMIT 1"); {
if ($user === false) { return DB::selectOne('SELECT * FROM `User` WHERE `password_recovery_token`=? LIMIT 1', [$token]);
engelsystem_error("Unable to load user.");
}
if (count($user) == 0) {
return null;
}
return $user[0];
} }
/** /**
* Generates a new api key for given user. * Generates a new api key for given user.
* *
* @param User $user * @param array $user
* @param bool $log
*/ */
function User_reset_api_key(&$user, $log = true) { function User_reset_api_key(&$user, $log = true)
{
$user['api_key'] = md5($user['Nick'] . time() . rand()); $user['api_key'] = md5($user['Nick'] . time() . rand());
$result = sql_query("UPDATE `User` SET `api_key`='" . sql_escape($user['api_key']) . "' WHERE `UID`='" . sql_escape($user['UID']) . "' LIMIT 1"); DB::update('
if ($result === false) { UPDATE `User`
return false; SET `api_key`=?
} WHERE `UID`=?
LIMIT 1
',
[
$user['api_key'],
$user['UID']
]
);
if ($log) { if ($log) {
engelsystem_log(sprintf("API key resetted (%s).", User_Nick_render($user))); engelsystem_log(sprintf('API key resetted (%s).', User_Nick_render($user)));
} }
} }
/** /**
* Generates a new password recovery token for given user. * Generates a new password recovery token for given user.
* *
* @param User $user * @param array $user
* @return string
*/ */
function User_generate_password_recovery_token(&$user) { function User_generate_password_recovery_token(&$user)
{
$user['password_recovery_token'] = md5($user['Nick'] . time() . rand()); $user['password_recovery_token'] = md5($user['Nick'] . time() . rand());
$result = sql_query("UPDATE `User` SET `password_recovery_token`='" . sql_escape($user['password_recovery_token']) . "' WHERE `UID`='" . sql_escape($user['UID']) . "' LIMIT 1"); DB::update('
if ($result === false) { UPDATE `User`
engelsystem_error("Unable to generate password recovery token."); SET `password_recovery_token`=?
} WHERE `UID`=?
engelsystem_log("Password recovery for " . User_Nick_render($user) . " started."); LIMIT 1
',
[
$user['password_recovery_token'],
$user['UID'],
]
);
engelsystem_log('Password recovery for ' . User_Nick_render($user) . ' started.');
return $user['password_recovery_token']; return $user['password_recovery_token'];
} }
function User_get_eligable_voucher_count(&$user) { /**
global $voucher_settings; * @param array $user
* @return float
*/
function User_get_eligable_voucher_count(&$user)
{
$voucher_settings = config('voucher_settings');
$shifts_done = count(ShiftEntries_finished_by_user($user)); $shifts_done = count(ShiftEntries_finished_by_user($user));
$earned_vouchers = $user['got_voucher'] - $voucher_settings['initial_vouchers']; $earned_vouchers = $user['got_voucher'] - $voucher_settings['initial_vouchers'];
@ -370,5 +481,3 @@ function User_get_eligable_voucher_count(&$user) {
return $elegible_vouchers; return $elegible_vouchers;
} }
?>

View File

@ -6,37 +6,41 @@ namespace Engelsystem;
* BO that represents the result of an entity attribute validation. * BO that represents the result of an entity attribute validation.
* It contains the validated value and a bool for validation success. * It contains the validated value and a bool for validation success.
*/ */
class ValidationResult { class ValidationResult
{
/** @var bool */
private $valid; private $valid;
/** @var mixed */
private $value; private $value;
/** /**
* Constructor. * @param boolean $valid Is the value valid?
* * @param mixed $value The validated value
* @param boolean $valid
* Is the value valid?
* @param * $value
* The validated value
*/ */
public function __construct($valid, $value) { public function __construct($valid, $value)
{
$this->valid = $valid; $this->valid = $valid;
$this->value = $value; $this->value = $value;
} }
/** /**
* Is the value valid? * Is the value valid?
*
* @return bool
*/ */
public function isValid() { public function isValid()
{
return $this->valid; return $this->valid;
} }
/** /**
* The parsed/validated value. * The parsed/validated value.
*
* @return mixed
*/ */
public function getValue() { public function getValue()
{
return $this->value; return $this->value;
} }
} }
?>

View File

@ -1,216 +0,0 @@
<?php
/**
* Close connection.
*/
function sql_close() {
global $sql_connection;
return $sql_connection->close();
}
/**
* Return NULL if given value is null.
*/
function sql_null($value = null) {
return $value == null ? 'NULL' : ("'" . sql_escape($value) . "'");
}
/**
* Start new transaction.
*/
function sql_transaction_start() {
global $sql_nested_transaction_level;
if ($sql_nested_transaction_level ++ == 0) {
return sql_query("BEGIN");
}
return true;
}
/**
* Commit transaction.
*/
function sql_transaction_commit() {
global $sql_nested_transaction_level;
if (-- $sql_nested_transaction_level == 0) {
return sql_query("COMMIT");
}
return true;
}
/**
* Stop transaction, revert database.
*/
function sql_transaction_rollback() {
global $sql_nested_transaction_level;
if (-- $sql_nested_transaction_level == 0) {
return sql_query("ROLLBACK");
}
return true;
}
/**
* Logs an sql error.
*
* @param string $message
* @return false
*/
function sql_error($message) {
sql_close();
$message = trim($message) . "\n";
$message .= debug_string_backtrace() . "\n";
error_log('mysql_provider error: ' . $message);
return false;
}
/**
* Connect to mysql server.
*
* @param string $host
* Host
* @param string $user
* Username
* @param string $pass
* Password
* @param string $db_name
* DB to select
* @return mysqli The connection handler
*/
function sql_connect($host, $user, $pass, $db_name) {
global $sql_connection;
$sql_connection = new mysqli($host, $user, $pass, $db_name);
if ($sql_connection->connect_errno) {
error("Unable to connect to MySQL: " . $sql_connection->connect_error);
return sql_error("Unable to connect to MySQL: " . $sql_connection->connect_error);
}
$result = $sql_connection->query("SET CHARACTER SET utf8;");
if (! $result) {
return sql_error("Unable to set utf8 character set (" . $sql_connection->errno . ") " . $sql_connection->error);
}
$result = $sql_connection->set_charset('utf8');
if (! $result) {
return sql_error("Unable to set utf8 names (" . $sql_connection->errno . ") " . $sql_connection->error);
}
return $sql_connection;
}
/**
* Change the selected db in current mysql-connection.
*
* @param
* $db_name
* @return bool true on success, false on error
*/
function sql_select_db($db_name) {
global $sql_connection;
if (! $sql_connection->select_db($db_name)) {
return sql_error("No database selected.");
}
return true;
}
/**
* MySQL SELECT query
*
* @param string $query
* @return Result array or false on error
*/
function sql_select($query) {
global $sql_connection;
// echo $query . ";\n";
// echo debug_string_backtrace() . "\n";
$result = $sql_connection->query($query);
if ($result) {
$data = [];
while ($line = $result->fetch_assoc()) {
array_push($data, $line);
}
return $data;
}
return sql_error("MySQL-query error: " . $query . " (" . $sql_connection->errno . ") " . $sql_connection->error);
}
/**
* MySQL execute a query
*
* @param string $query
* @return mysqli_result boolean resource or false on error
*/
function sql_query($query) {
global $sql_connection;
$result = $sql_connection->query($query);
if ($result) {
return $result;
}
return sql_error("MySQL-query error: " . $query . " (" . $sql_connection->errno . ") " . $sql_connection->error);
}
/**
* Returns last inserted id.
*
* @return int
*/
function sql_id() {
global $sql_connection;
return $sql_connection->insert_id;
}
/**
* Escape a string for a sql query.
*
* @param string $query
* @return string
*/
function sql_escape($query) {
global $sql_connection;
return $sql_connection->real_escape_string($query);
}
/**
* Convert a boolean for mysql-queries.
*
* @param boolean $boolean
* @return string
*/
function sql_bool($boolean) {
return $boolean == true ? 'TRUE' : 'FALSE';
}
/**
* Count query result lines.
*
* @param string $query
* @return int Count of result lines
*/
function sql_num_query($query) {
return sql_query($query)->num_rows;
}
function sql_select_single_col($query) {
$result = sql_select($query);
return array_map('array_shift', $result);
}
function sql_select_single_cell($query) {
return array_shift(array_shift(sql_select($query)));
}
?>

View File

@ -1,121 +1,162 @@
<?php <?php
function admin_active_title() { use Engelsystem\Database\DB;
return _("Active angels");
/**
* @return string
*/
function admin_active_title()
{
return _('Active angels');
} }
function admin_active() { /**
global $tshirt_sizes, $shift_sum_formula; * @return string
*/
function admin_active()
{
$tshirt_sizes = config('tshirt_sizes');
$shift_sum_formula = config('shift_sum_formula');
$request = request();
$msg = ""; $msg = '';
$search = ""; $search = '';
$forced_count = sql_num_query("SELECT * FROM `User` WHERE `force_active`=1"); $forced_count = count(DB::select('SELECT `UID` FROM `User` WHERE `force_active`=1'));
$count = $forced_count; $count = $forced_count;
$limit = ""; $limit = '';
$set_active = ""; $set_active = '';
if (isset($_REQUEST['search'])) { if ($request->has('search')) {
$search = strip_request_item('search'); $search = strip_request_item('search');
} }
$show_all_shifts = isset($_REQUEST['show_all_shifts']); $show_all_shifts = $request->has('show_all_shifts');
if (isset($_REQUEST['set_active'])) { if ($request->has('set_active')) {
$valid = true; $valid = true;
if (isset($_REQUEST['count']) && preg_match("/^[0-9]+$/", $_REQUEST['count'])) { if ($request->has('count') && preg_match('/^\d+$/', $request->input('count'))) {
$count = strip_request_item('count'); $count = strip_request_item('count');
if ($count < $forced_count) { if ($count < $forced_count) {
error(sprintf(_("At least %s angels are forced to be active. The number has to be greater."), $forced_count)); error(sprintf(
_('At least %s angels are forced to be active. The number has to be greater.'),
$forced_count
));
redirect(page_link_to('admin_active')); redirect(page_link_to('admin_active'));
} }
} else { } else {
$valid = false; $valid = false;
$msg .= error(_("Please enter a number of angels to be marked as active."), true); $msg .= error(_('Please enter a number of angels to be marked as active.'), true);
} }
if ($valid) { if ($valid) {
$limit = " LIMIT " . $count; $limit = ' LIMIT ' . $count;
} }
if (isset($_REQUEST['ack'])) { if ($request->has('ack')) {
sql_query("UPDATE `User` SET `Aktiv` = 0 WHERE `Tshirt` = 0"); DB::update('UPDATE `User` SET `Aktiv` = 0 WHERE `Tshirt` = 0');
$users = sql_select(" $users = DB::select(sprintf('
SELECT `User`.*, COUNT(`ShiftEntry`.`id`) as `shift_count`, $shift_sum_formula as `shift_length` SELECT
`User`.*,
COUNT(`ShiftEntry`.`id`) AS `shift_count`,
%s AS `shift_length`
FROM `User` FROM `User`
LEFT JOIN `ShiftEntry` ON `User`.`UID` = `ShiftEntry`.`UID` LEFT JOIN `ShiftEntry` ON `User`.`UID` = `ShiftEntry`.`UID`
LEFT JOIN `Shifts` ON `ShiftEntry`.`SID` = `Shifts`.`SID` LEFT JOIN `Shifts` ON `ShiftEntry`.`SID` = `Shifts`.`SID`
WHERE `User`.`Gekommen` = 1 AND `User`.`force_active`=0 WHERE `User`.`Gekommen` = 1
AND `User`.`force_active`=0
GROUP BY `User`.`UID` GROUP BY `User`.`UID`
ORDER BY `force_active` DESC, `shift_length` DESC" . $limit); ORDER BY `force_active` DESC, `shift_length` DESC
%s
',
$shift_sum_formula,
$limit
));
$user_nicks = []; $user_nicks = [];
foreach ($users as $usr) { foreach ($users as $usr) {
sql_query("UPDATE `User` SET `Aktiv` = 1 WHERE `UID`='" . sql_escape($usr['UID']) . "'"); DB::update('UPDATE `User` SET `Aktiv` = 1 WHERE `UID`=?', [$usr['UID']]);
$user_nicks[] = User_Nick_render($usr); $user_nicks[] = User_Nick_render($usr);
} }
sql_query("UPDATE `User` SET `Aktiv`=1 WHERE `force_active`=TRUE"); DB::update('UPDATE `User` SET `Aktiv`=1 WHERE `force_active`=TRUE');
engelsystem_log("These angels are active now: " . join(", ", $user_nicks)); engelsystem_log('These angels are active now: ' . join(', ', $user_nicks));
$limit = ""; $limit = '';
$msg = success(_("Marked angels."), true); $msg = success(_('Marked angels.'), true);
} else { } else {
$set_active = '<a href="' . page_link_to('admin_active') . '&amp;serach=' . $search . '">&laquo; ' . _("back") . '</a> | <a href="' . page_link_to('admin_active') . '&amp;search=' . $search . '&amp;count=' . $count . '&amp;set_active&amp;ack">' . _("apply") . '</a>'; $set_active = '<a href="' . page_link_to('admin_active', ['search' => $search]) . '">&laquo; '
. _('back')
. '</a> | <a href="'
. page_link_to(
'admin_active',
['search' => $search, 'count' => $count, 'set_active' => 1, 'ack' => 1]
) . '">'
. _('apply')
. '</a>';
} }
} }
if (isset($_REQUEST['active']) && preg_match("/^[0-9]+$/", $_REQUEST['active'])) { if ($request->has('active') && preg_match('/^\d+$/', $request->input('active'))) {
$user_id = $_REQUEST['active']; $user_id = $request->input('active');
$user_source = User($user_id); $user_source = User($user_id);
if ($user_source != null) { if ($user_source != null) {
sql_query("UPDATE `User` SET `Aktiv`=1 WHERE `UID`='" . sql_escape($user_id) . "' LIMIT 1"); DB::update('UPDATE `User` SET `Aktiv`=1 WHERE `UID`=? LIMIT 1', [$user_id]);
engelsystem_log("User " . User_Nick_render($user_source) . " is active now."); engelsystem_log('User ' . User_Nick_render($user_source) . ' is active now.');
$msg = success(_("Angel has been marked as active."), true); $msg = success(_('Angel has been marked as active.'), true);
} else { } else {
$msg = error(_("Angel not found."), true); $msg = error(_('Angel not found.'), true);
} }
} elseif (isset($_REQUEST['not_active']) && preg_match("/^[0-9]+$/", $_REQUEST['not_active'])) { } elseif ($request->has('not_active') && preg_match('/^\d+$/', $request->input('not_active'))) {
$user_id = $_REQUEST['not_active']; $user_id = $request->input('not_active');
$user_source = User($user_id); $user_source = User($user_id);
if ($user_source != null) { if ($user_source != null) {
sql_query("UPDATE `User` SET `Aktiv`=0 WHERE `UID`='" . sql_escape($user_id) . "' LIMIT 1"); DB::update('UPDATE `User` SET `Aktiv`=0 WHERE `UID`=? LIMIT 1', [$user_id]);
engelsystem_log("User " . User_Nick_render($user_source) . " is NOT active now."); engelsystem_log('User ' . User_Nick_render($user_source) . ' is NOT active now.');
$msg = success(_("Angel has been marked as not active."), true); $msg = success(_('Angel has been marked as not active.'), true);
} else { } else {
$msg = error(_("Angel not found."), true); $msg = error(_('Angel not found.'), true);
} }
} elseif (isset($_REQUEST['tshirt']) && preg_match("/^[0-9]+$/", $_REQUEST['tshirt'])) { } elseif ($request->has('tshirt') && preg_match('/^\d+$/', $request->input('tshirt'))) {
$user_id = $_REQUEST['tshirt']; $user_id = $request->input('tshirt');
$user_source = User($user_id); $user_source = User($user_id);
if ($user_source != null) { if ($user_source != null) {
sql_query("UPDATE `User` SET `Tshirt`=1 WHERE `UID`='" . sql_escape($user_id) . "' LIMIT 1"); DB::update('UPDATE `User` SET `Tshirt`=1 WHERE `UID`=? LIMIT 1', [$user_id]);
engelsystem_log("User " . User_Nick_render($user_source) . " has tshirt now."); engelsystem_log('User ' . User_Nick_render($user_source) . ' has tshirt now.');
$msg = success(_("Angel has got a t-shirt."), true); $msg = success(_('Angel has got a t-shirt.'), true);
} else { } else {
$msg = error("Angel not found.", true); $msg = error('Angel not found.', true);
} }
} elseif (isset($_REQUEST['not_tshirt']) && preg_match("/^[0-9]+$/", $_REQUEST['not_tshirt'])) { } elseif ($request->has('not_tshirt') && preg_match('/^\d+$/', $request->input('not_tshirt'))) {
$user_id = $_REQUEST['not_tshirt']; $user_id = $request->input('not_tshirt');
$user_source = User($user_id); $user_source = User($user_id);
if ($user_source != null) { if ($user_source != null) {
sql_query("UPDATE `User` SET `Tshirt`=0 WHERE `UID`='" . sql_escape($user_id) . "' LIMIT 1"); DB::update('UPDATE `User` SET `Tshirt`=0 WHERE `UID`=? LIMIT 1', [$user_id]);
engelsystem_log("User " . User_Nick_render($user_source) . " has NO tshirt."); engelsystem_log('User ' . User_Nick_render($user_source) . ' has NO tshirt.');
$msg = success(_("Angel has got no t-shirt."), true); $msg = success(_('Angel has got no t-shirt.'), true);
} else { } else {
$msg = error(_("Angel not found."), true); $msg = error(_('Angel not found.'), true);
} }
} }
$users = sql_select(" $users = DB::select(sprintf('
SELECT `User`.*, COUNT(`ShiftEntry`.`id`) as `shift_count`, ${shift_sum_formula} as `shift_length` SELECT
`User`.*,
COUNT(`ShiftEntry`.`id`) AS `shift_count`,
%s AS `shift_length`
FROM `User` LEFT JOIN `ShiftEntry` ON `User`.`UID` = `ShiftEntry`.`UID` FROM `User` LEFT JOIN `ShiftEntry` ON `User`.`UID` = `ShiftEntry`.`UID`
LEFT JOIN `Shifts` ON `ShiftEntry`.`SID` = `Shifts`.`SID` " . ($show_all_shifts ? "" : "AND (`Shifts`.`end` < " . time() . " OR `Shifts`.`end` IS NULL)") . " LEFT JOIN `Shifts` ON `ShiftEntry`.`SID` = `Shifts`.`SID` '
. ($show_all_shifts ? '' : 'AND (`Shifts`.`end` < ' . time() . " OR `Shifts`.`end` IS NULL)") . '
WHERE `User`.`Gekommen` = 1 WHERE `User`.`Gekommen` = 1
GROUP BY `User`.`UID` GROUP BY `User`.`UID`
ORDER BY `force_active` DESC, `shift_length` DESC" . $limit); ORDER BY `force_active` DESC, `shift_length` DESC
%s
',
$shift_sum_formula,
$limit
));
$matched_users = []; $matched_users = [];
if ($search == "") { if ($search == '') {
$tokens = []; $tokens = [];
} else { } else {
$tokens = explode(" ", $search); $tokens = explode(' ', $search);
} }
foreach ($users as &$usr) { foreach ($users as &$usr) {
if (count($tokens) > 0) { if (count($tokens) > 0) {
@ -126,7 +167,7 @@ function admin_active() {
break; break;
} }
} }
if (! $match) { if (!$match) {
continue; continue;
} }
} }
@ -139,14 +180,48 @@ function admin_active() {
$actions = []; $actions = [];
if ($usr['Aktiv'] == 0) { if ($usr['Aktiv'] == 0) {
$actions[] = '<a href="' . page_link_to('admin_active') . '&amp;active=' . $usr['UID'] . ($show_all_shifts ? '&amp;show_all_shifts=' : '') . '&amp;search=' . $search . '">' . _("set active") . '</a>'; $parameters = [
'active' => $usr['UID'],
'search' => $search,
];
if ($show_all_shifts) {
$parameters['show_all_shifts'] = 1;
}
$actions[] = '<a href="' . page_link_to('admin_active', $parameters) . '">'
. _('set active')
. '</a>';
} }
if ($usr['Aktiv'] == 1 && $usr['Tshirt'] == 0) { if ($usr['Aktiv'] == 1 && $usr['Tshirt'] == 0) {
$actions[] = '<a href="' . page_link_to('admin_active') . '&amp;not_active=' . $usr['UID'] . ($show_all_shifts ? '&amp;show_all_shifts=' : '') . '&amp;search=' . $search . '">' . _("remove active") . '</a>'; $parametersRemove = [
$actions[] = '<a href="' . page_link_to('admin_active') . '&amp;tshirt=' . $usr['UID'] . ($show_all_shifts ? '&amp;show_all_shifts=' : '') . '&amp;search=' . $search . '">' . _("got t-shirt") . '</a>'; 'not_active' => $usr['UID'],
'search' => $search,
];
$parametersShirt = [
'tshirt' => $usr['UID'],
'search' => $search,
];
if ($show_all_shifts) {
$parametersRemove['show_all_shifts'] = 1;
$parametersShirt['show_all_shifts'] = 1;
}
$actions[] = '<a href="' . page_link_to('admin_active', $parametersRemove) . '">'
. _('remove active')
. '</a>';
$actions[] = '<a href="' . page_link_to('admin_active', $parametersShirt) . '">'
. _('got t-shirt')
. '</a>';
} }
if ($usr['Tshirt'] == 1) { if ($usr['Tshirt'] == 1) {
$actions[] = '<a href="' . page_link_to('admin_active') . '&amp;not_tshirt=' . $usr['UID'] . ($show_all_shifts ? '&amp;show_all_shifts=' : '') . '&amp;search=' . $search . '">' . _("remove t-shirt") . '</a>'; $parameters = [
'not_tshirt' => $usr['UID'],
'search' => $search,
];
if ($show_all_shifts) {
$parameters['show_all_shifts'] = 1;
}
$actions[] = '<a href="' . page_link_to('admin_active', $parameters) . '">'
. _('remove t-shirt')
. '</a>';
} }
$usr['actions'] = join(' ', $actions); $usr['actions'] = join(' ', $actions);
@ -156,47 +231,62 @@ function admin_active() {
$shirt_statistics = []; $shirt_statistics = [];
foreach (array_keys($tshirt_sizes) as $size) { foreach (array_keys($tshirt_sizes) as $size) {
if ($size != '') { if (!empty($size)) {
$sc = DB::selectOne(
'SELECT count(*) FROM `User` WHERE `Size`=? AND `Gekommen`=1',
[$size]
);
$sc = array_shift($sc);
$gc = DB::selectOne(
'SELECT count(*) FROM `User` WHERE `Size`=? AND `Tshirt`=1',
[$size]
);
$gc = array_shift($gc);
$shirt_statistics[] = [ $shirt_statistics[] = [
'size' => $size, 'size' => $size,
'needed' => sql_select_single_cell("SELECT count(*) FROM `User` WHERE `Size`='" . sql_escape($size) . "' AND `Gekommen`=1"), 'needed' => (int)$sc,
'given' => sql_select_single_cell("SELECT count(*) FROM `User` WHERE `Size`='" . sql_escape($size) . "' AND `Tshirt`=1") 'given' => (int)$gc
]; ];
} }
} }
$shirtCount = DB::selectOne('SELECT count(*) FROM `User` WHERE `Tshirt`=1');
$shirtCount = array_shift($shirtCount);
$shirt_statistics[] = [ $shirt_statistics[] = [
'size' => '<b>' . _("Sum") . '</b>', 'size' => '<b>' . _('Sum') . '</b>',
'needed' => '<b>' . User_arrived_count() . '</b>', 'needed' => '<b>' . User_arrived_count() . '</b>',
'given' => '<b>' . sql_select_single_cell("SELECT count(*) FROM `User` WHERE `Tshirt`=1") . '</b>' 'given' => '<b>' . (int)$shirtCount . '</b>'
]; ];
return page_with_title(admin_active_title(), [ return page_with_title(admin_active_title(), [
form([ form([
form_text('search', _("Search angel:"), $search), form_text('search', _('Search angel:'), $search),
form_checkbox('show_all_shifts', _("Show all shifts"), $show_all_shifts), form_checkbox('show_all_shifts', _('Show all shifts'), $show_all_shifts),
form_submit('submit', _("Search")) form_submit('submit', _('Search'))
], page_link_to('admin_active')), ], page_link_to('admin_active')),
$set_active == "" ? form([ $set_active == '' ? form([
form_text('count', _("How much angels should be active?"), $count), form_text('count', _('How much angels should be active?'), $count),
form_submit('set_active', _("Preview")) form_submit('set_active', _('Preview'))
]) : $set_active, ]) : $set_active,
msg(), $msg . msg(),
table([ table([
'nick' => _("Nickname"), 'nick' => _('Nickname'),
'shirt_size' => _("Size"), 'shirt_size' => _('Size'),
'shift_count' => _("Shifts"), 'shift_count' => _('Shifts'),
'work_time' => _("Length"), 'work_time' => _('Length'),
'active' => _("Active?"), 'active' => _('Active?'),
'force_active' => _("Forced"), 'force_active' => _('Forced'),
'tshirt' => _("T-shirt?"), 'tshirt' => _('T-shirt?'),
'actions' => "" 'actions' => ''
], $matched_users), ], $matched_users),
'<h2>' . _("Shirt statistics") . '</h2>', '<h2>' . _('Shirt statistics') . '</h2>',
table([ table([
'size' => _("Size"), 'size' => _('Size'),
'needed' => _("Needed shirts"), 'needed' => _('Needed shirts'),
'given' => _("Given shirts") 'given' => _('Given shirts')
], $shirt_statistics) ], $shirt_statistics)
]); ]);
} }
?>

View File

@ -1,61 +1,83 @@
<?php <?php
function admin_arrive_title() { use Engelsystem\Database\DB;
return _("Arrived angels");
/**
* @return string
*/
function admin_arrive_title()
{
return _('Arrived angels');
} }
function admin_arrive() { /**
$msg = ""; * @return string
$search = ""; */
if (isset($_REQUEST['search'])) { function admin_arrive()
{
$msg = '';
$search = '';
$request = request();
if ($request->has('search')) {
$search = strip_request_item('search'); $search = strip_request_item('search');
} }
if (isset($_REQUEST['reset']) && preg_match("/^[0-9]*$/", $_REQUEST['reset'])) { if ($request->has('reset') && preg_match('/^\d+$/', $request->input('reset'))) {
$user_id = $_REQUEST['reset']; $user_id = $request->input('reset');
$user_source = User($user_id); $user_source = User($user_id);
if ($user_source != null) { if ($user_source != null) {
sql_query("UPDATE `User` SET `Gekommen`=0, `arrival_date` = NULL WHERE `UID`='" . sql_escape($user_id) . "' LIMIT 1"); DB::update('
engelsystem_log("User set to not arrived: " . User_Nick_render($user_source)); UPDATE `User`
success(_("Reset done. Angel has not arrived.")); SET `Gekommen`=0, `arrival_date` = NULL
WHERE `UID`=?
LIMIT 1
', [$user_id]);
engelsystem_log('User set to not arrived: ' . User_Nick_render($user_source));
success(_('Reset done. Angel has not arrived.'));
redirect(user_link($user_source)); redirect(user_link($user_source));
} else { } else {
$msg = error(_("Angel not found."), true); $msg = error(_('Angel not found.'), true);
} }
} elseif (isset($_REQUEST['arrived']) && preg_match("/^[0-9]*$/", $_REQUEST['arrived'])) { } elseif ($request->has('arrived') && preg_match('/^\d+$/', $request->input('arrived'))) {
$user_id = $_REQUEST['arrived']; $user_id = $request->input('arrived');
$user_source = User($user_id); $user_source = User($user_id);
if ($user_source != null) { if ($user_source != null) {
sql_query("UPDATE `User` SET `Gekommen`=1, `arrival_date`='" . time() . "' WHERE `UID`='" . sql_escape($user_id) . "' LIMIT 1"); DB::update('
engelsystem_log("User set has arrived: " . User_Nick_render($user_source)); UPDATE `User`
success(_("Angel has been marked as arrived.")); SET `Gekommen`=1, `arrival_date`=?
WHERE `UID`=?
LIMIT 1
', [time(), $user_id]);
engelsystem_log('User set has arrived: ' . User_Nick_render($user_source));
success(_('Angel has been marked as arrived.'));
redirect(user_link($user_source)); redirect(user_link($user_source));
} else { } else {
$msg = error(_("Angel not found."), true); $msg = error(_('Angel not found.'), true);
} }
} }
$users = sql_select("SELECT * FROM `User` ORDER BY `Nick`"); $users = DB::select('SELECT * FROM `User` ORDER BY `Nick`');
$arrival_count_at_day = []; $arrival_count_at_day = [];
$planned_arrival_count_at_day = []; $planned_arrival_count_at_day = [];
$planned_departure_count_at_day = []; $planned_departure_count_at_day = [];
$users_matched = []; $users_matched = [];
if ($search == "") { if ($search == '') {
$tokens = []; $tokens = [];
} else { } else {
$tokens = explode(" ", $search); $tokens = explode(' ', $search);
} }
foreach ($users as $usr) { foreach ($users as $usr) {
if (count($tokens) > 0) { if (count($tokens) > 0) {
$match = false; $match = false;
$index = join(" ", $usr); $index = join(' ', $usr);
foreach ($tokens as $t) { foreach ($tokens as $t) {
if (stristr($index, trim($t))) { if (stristr($index, trim($t))) {
$match = true; $match = true;
break; break;
} }
} }
if (! $match) { if (!$match) {
continue; continue;
} }
} }
@ -67,32 +89,40 @@ function admin_arrive() {
$usr['rendered_planned_departure_date'] = '-'; $usr['rendered_planned_departure_date'] = '-';
} }
$usr['rendered_planned_arrival_date'] = date('Y-m-d', $usr['planned_arrival_date']); $usr['rendered_planned_arrival_date'] = date('Y-m-d', $usr['planned_arrival_date']);
$usr['rendered_arrival_date'] = $usr['arrival_date'] > 0 ? date('Y-m-d', $usr['arrival_date']) : "-"; $usr['rendered_arrival_date'] = $usr['arrival_date'] > 0 ? date('Y-m-d', $usr['arrival_date']) : '-';
$usr['arrived'] = $usr['Gekommen'] == 1 ? _("yes") : ""; $usr['arrived'] = $usr['Gekommen'] == 1 ? _('yes') : '';
$usr['actions'] = $usr['Gekommen'] == 1 ? '<a href="' . page_link_to('admin_arrive') . '&reset=' . $usr['UID'] . '&search=' . $search . '">' . _("reset") . '</a>' : '<a href="' . page_link_to('admin_arrive') . '&arrived=' . $usr['UID'] . '&search=' . $search . '">' . _("arrived") . '</a>'; $usr['actions'] = $usr['Gekommen'] == 1
? '<a href="' . page_link_to(
'admin_arrive',
['reset' => $usr['UID'], 'search' => $search]
) . '">' . _('reset') . '</a>'
: '<a href="' . page_link_to(
'admin_arrive',
['arrived' => $usr['UID'], 'search' => $search]
) . '">' . _('arrived') . '</a>';
if ($usr['arrival_date'] > 0) { if ($usr['arrival_date'] > 0) {
$day = date('Y-m-d', $usr['arrival_date']); $day = date('Y-m-d', $usr['arrival_date']);
if (! isset($arrival_count_at_day[$day])) { if (!isset($arrival_count_at_day[$day])) {
$arrival_count_at_day[$day] = 0; $arrival_count_at_day[$day] = 0;
} }
$arrival_count_at_day[$day] ++; $arrival_count_at_day[$day]++;
} }
if ($usr['planned_arrival_date'] != null) { if ($usr['planned_arrival_date'] != null) {
$day = date('Y-m-d', $usr['planned_arrival_date']); $day = date('Y-m-d', $usr['planned_arrival_date']);
if (! isset($planned_arrival_count_at_day[$day])) { if (!isset($planned_arrival_count_at_day[$day])) {
$planned_arrival_count_at_day[$day] = 0; $planned_arrival_count_at_day[$day] = 0;
} }
$planned_arrival_count_at_day[$day] ++; $planned_arrival_count_at_day[$day]++;
} }
if ($usr['planned_departure_date'] != null && $usr['Gekommen'] == 1) { if ($usr['planned_departure_date'] != null && $usr['Gekommen'] == 1) {
$day = date('Y-m-d', $usr['planned_departure_date']); $day = date('Y-m-d', $usr['planned_departure_date']);
if (! isset($planned_departure_count_at_day[$day])) { if (!isset($planned_departure_count_at_day[$day])) {
$planned_departure_count_at_day[$day] = 0; $planned_departure_count_at_day[$day] = 0;
} }
$planned_departure_count_at_day[$day] ++; $planned_departure_count_at_day[$day]++;
} }
$users_matched[] = $usr; $users_matched[] = $usr;
@ -136,66 +166,65 @@ function admin_arrive() {
} }
return page_with_title(admin_arrive_title(), [ return page_with_title(admin_arrive_title(), [
msg(), $msg . msg(),
form([ form([
form_text('search', _("Search"), $search), form_text('search', _('Search'), $search),
form_submit('submit', _("Search")) form_submit('submit', _('Search'))
]), ]),
table([ table([
'nick' => _("Nickname"), 'nick' => _('Nickname'),
'rendered_planned_arrival_date' => _("Planned arrival"), 'rendered_planned_arrival_date' => _('Planned arrival'),
'arrived' => _("Arrived?"), 'arrived' => _('Arrived?'),
'rendered_arrival_date' => _("Arrival date"), 'rendered_arrival_date' => _('Arrival date'),
'rendered_planned_departure_date' => _("Planned departure"), 'rendered_planned_departure_date' => _('Planned departure'),
'actions' => "" 'actions' => ''
], $users_matched), ], $users_matched),
div('row', [ div('row', [
div('col-md-4', [ div('col-md-4', [
heading(_("Planned arrival statistics"), 2), heading(_('Planned arrival statistics'), 2),
bargraph('planned_arrives', 'day', [ bargraph('planned_arrives', 'day', [
'count' => _("arrived"), 'count' => _('arrived'),
'sum' => _("arrived sum") 'sum' => _('arrived sum')
], [ ], [
'count' => '#090', 'count' => '#090',
'sum' => '#888' 'sum' => '#888'
], $planned_arrival_at_day), ], $planned_arrival_at_day),
table([ table([
'day' => _("Date"), 'day' => _('Date'),
'count' => _("Count"), 'count' => _('Count'),
'sum' => _("Sum") 'sum' => _('Sum')
], $planned_arrival_at_day) ], $planned_arrival_at_day)
]), ]),
div('col-md-4', [ div('col-md-4', [
heading(_("Arrival statistics"), 2), heading(_('Arrival statistics'), 2),
bargraph('arrives', 'day', [ bargraph('arrives', 'day', [
'count' => _("arrived"), 'count' => _('arrived'),
'sum' => _("arrived sum") 'sum' => _('arrived sum')
], [ ], [
'count' => '#090', 'count' => '#090',
'sum' => '#888' 'sum' => '#888'
], $arrival_at_day), ], $arrival_at_day),
table([ table([
'day' => _("Date"), 'day' => _('Date'),
'count' => _("Count"), 'count' => _('Count'),
'sum' => _("Sum") 'sum' => _('Sum')
], $arrival_at_day) ], $arrival_at_day)
]), ]),
div('col-md-4', [ div('col-md-4', [
heading(_("Planned departure statistics"), 2), heading(_('Planned departure statistics'), 2),
bargraph('planned_departures', 'day', [ bargraph('planned_departures', 'day', [
'count' => _("arrived"), 'count' => _('arrived'),
'sum' => _("arrived sum") 'sum' => _('arrived sum')
], [ ], [
'count' => '#090', 'count' => '#090',
'sum' => '#888' 'sum' => '#888'
], $planned_departure_at_day), ], $planned_departure_at_day),
table([ table([
'day' => _("Date"), 'day' => _('Date'),
'count' => _("Count"), 'count' => _('Count'),
'sum' => _("Sum") 'sum' => _('Sum')
], $planned_departure_at_day) ], $planned_departure_at_day)
]) ])
]) ])
]); ]);
} }
?>

View File

@ -1,29 +1,41 @@
<?php <?php
function admin_free_title() { use Engelsystem\Database\DB;
return _("Free angels");
/**
* @return string
*/
function admin_free_title()
{
return _('Free angels');
} }
function admin_free() { /**
* @return string
*/
function admin_free()
{
global $privileges; global $privileges;
$request = request();
$search = ""; $search = '';
if (isset($_REQUEST['search'])) { if ($request->has('search')) {
$search = strip_request_item('search'); $search = strip_request_item('search');
} }
$angeltypesearch = ""; $angelTypeSearch = '';
if (empty($_REQUEST['angeltype'])) { $angelType = $request->input('angeltype', '');
$_REQUEST['angeltype'] = ''; if (!empty($angelType)) {
} else { $angelTypeSearch = ' INNER JOIN `UserAngelTypes` ON (`UserAngelTypes`.`angeltype_id` = '
$angeltypesearch = " INNER JOIN `UserAngelTypes` ON (`UserAngelTypes`.`angeltype_id` = '" . sql_escape($_REQUEST['angeltype']) . "' AND `UserAngelTypes`.`user_id` = `User`.`UID`"; . DB::getPdo()->quote($angelType)
if (isset($_REQUEST['confirmed_only'])) { . ' AND `UserAngelTypes`.`user_id` = `User`.`UID`';
$angeltypesearch .= " AND `UserAngelTypes`.`confirm_user_id`"; if ($request->has('confirmed_only')) {
$angelTypeSearch .= ' AND `UserAngelTypes`.`confirm_user_id`';
} }
$angeltypesearch .= ") "; $angelTypeSearch .= ') ';
} }
$angel_types_source = sql_select("SELECT `id`, `name` FROM `AngelTypes` ORDER BY `name`"); $angel_types_source = DB::select('SELECT `id`, `name` FROM `AngelTypes` ORDER BY `name`');
$angel_types = [ $angel_types = [
'' => 'alle Typen' '' => 'alle Typen'
]; ];
@ -31,33 +43,45 @@ function admin_free() {
$angel_types[$angel_type['id']] = $angel_type['name']; $angel_types[$angel_type['id']] = $angel_type['name'];
} }
$users = sql_select(" $users = DB::select('
SELECT `User`.* SELECT `User`.*
FROM `User` FROM `User`
${angeltypesearch} ' . $angelTypeSearch . '
LEFT JOIN `ShiftEntry` ON `User`.`UID` = `ShiftEntry`.`UID` LEFT JOIN `ShiftEntry` ON `User`.`UID` = `ShiftEntry`.`UID`
LEFT JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID` AND `Shifts`.`start` < '" . sql_escape(time()) . "' AND `Shifts`.`end` > '" . sql_escape(time()) . "') LEFT JOIN `Shifts`
WHERE `User`.`Gekommen` = 1 AND `Shifts`.`SID` IS NULL ON (
`ShiftEntry`.`SID` = `Shifts`.`SID`
AND `Shifts`.`start` < ?
AND `Shifts`.`end` > ?
)
WHERE `User`.`Gekommen` = 1
AND `Shifts`.`SID` IS NULL
GROUP BY `User`.`UID` GROUP BY `User`.`UID`
ORDER BY `Nick`"); ORDER BY `Nick`
',
[
time(),
time(),
]
);
$free_users_table = []; $free_users_table = [];
if ($search == "") { if ($search == '') {
$tokens = []; $tokens = [];
} else { } else {
$tokens = explode(" ", $search); $tokens = explode(' ', $search);
} }
foreach ($users as $usr) { foreach ($users as $usr) {
if (count($tokens) > 0) { if (count($tokens) > 0) {
$match = false; $match = false;
$index = join("", $usr); $index = join('', $usr);
foreach ($tokens as $t) { foreach ($tokens as $t) {
if (stristr($index, trim($t))) { if (stristr($index, trim($t))) {
$match = true; $match = true;
break; break;
} }
} }
if (! $match) { if (!$match) {
continue; continue;
} }
} }
@ -68,34 +92,36 @@ function admin_free() {
'dect' => $usr['DECT'], 'dect' => $usr['DECT'],
'jabber' => $usr['jabber'], 'jabber' => $usr['jabber'],
'email' => $usr['email_by_human_allowed'] ? $usr['email'] : glyph('eye-close'), 'email' => $usr['email_by_human_allowed'] ? $usr['email'] : glyph('eye-close'),
'actions' => in_array('admin_user', $privileges) ? button(page_link_to('admin_user') . '&amp;id=' . $usr['UID'], _("edit"), 'btn-xs') : '' 'actions' =>
in_array('admin_user', $privileges)
? button(page_link_to('admin_user', ['id' => $usr['UID']]), _('edit'), 'btn-xs')
: ''
]; ];
} }
return page_with_title(admin_free_title(), [ return page_with_title(admin_free_title(), [
form([ form([
div('row', [ div('row', [
div('col-md-4', [ div('col-md-4', [
form_text('search', _("Search"), $search) form_text('search', _('Search'), $search)
]), ]),
div('col-md-4', [ div('col-md-4', [
form_select('angeltype', _("Angeltype"), $angel_types, $_REQUEST['angeltype']) form_select('angeltype', _('Angeltype'), $angel_types, $angelType)
]), ]),
div('col-md-2', [ div('col-md-2', [
form_checkbox('confirmed_only', _("Only confirmed"), isset($_REQUEST['confirmed_only'])) form_checkbox('confirmed_only', _('Only confirmed'), $request->has('confirmed_only'))
]), ]),
div('col-md-2', [ div('col-md-2', [
form_submit('submit', _("Search")) form_submit('submit', _('Search'))
]) ])
]) ])
]), ]),
table([ table([
'name' => _("Nick"), 'name' => _('Nick'),
'shift_state' => '', 'shift_state' => '',
'dect' => _("DECT"), 'dect' => _('DECT'),
'jabber' => _("Jabber"), 'jabber' => _('Jabber'),
'email' => _("E-Mail"), 'email' => _('E-Mail'),
'actions' => '' 'actions' => ''
], $free_users_table) ], $free_users_table)
]); ]);
} }
?>

View File

@ -1,97 +1,150 @@
<?php <?php
function admin_groups_title() { use Engelsystem\Database\DB;
return _("Grouprights");
/**
* @return string
*/
function admin_groups_title()
{
return _('Grouprights');
} }
function admin_groups() { /**
$html = ""; * @return string
$groups = sql_select("SELECT * FROM `Groups` ORDER BY `Name`"); */
if (! isset($_REQUEST["action"])) { function admin_groups()
{
$html = '';
$request = request();
$groups = DB::select('SELECT * FROM `Groups` ORDER BY `Name`');
if (!$request->has('action')) {
$groups_table = []; $groups_table = [];
foreach ($groups as $group) { foreach ($groups as $group) {
$privileges = sql_select("SELECT * FROM `GroupPrivileges` JOIN `Privileges` ON (`GroupPrivileges`.`privilege_id` = `Privileges`.`id`) WHERE `group_id`='" . sql_escape($group['UID']) . "'"); $privileges = DB::select('
SELECT `name`
FROM `GroupPrivileges`
JOIN `Privileges` ON (`GroupPrivileges`.`privilege_id` = `Privileges`.`id`)
WHERE `group_id`=?
', [$group['UID']]);
$privileges_html = []; $privileges_html = [];
foreach ($privileges as $priv) { foreach ($privileges as $privilege) {
$privileges_html[] = $priv['name']; $privileges_html[] = $privilege['name'];
} }
$groups_table[] = [ $groups_table[] = [
'name' => $group['Name'], 'name' => $group['Name'],
'privileges' => join(', ', $privileges_html), 'privileges' => join(', ', $privileges_html),
'actions' => button(page_link_to('admin_groups') . '&action=edit&id=' . $group['UID'], _("edit"), 'btn-xs') 'actions' => button(
page_link_to('admin_groups',
['action' => 'edit', 'id' => $group['UID']]),
_('edit'),
'btn-xs'
)
]; ];
} }
return page_with_title(admin_groups_title(), [ return page_with_title(admin_groups_title(), [
table([ table([
'name' => _("Name"), 'name' => _('Name'),
'privileges' => _("Privileges"), 'privileges' => _('Privileges'),
'actions' => '' 'actions' => ''
], $groups_table) ], $groups_table)
]); ]);
} else { } else {
switch ($_REQUEST["action"]) { switch ($request->input('action')) {
case 'edit': case 'edit':
if (isset($_REQUEST['id']) && preg_match("/^-[0-9]{1,11}$/", $_REQUEST['id'])) { if ($request->has('id') && preg_match('/^-\d{1,11}$/', $request->input('id'))) {
$group_id = $_REQUEST['id']; $group_id = $request->input('id');
} else { } else {
return error("Incomplete call, missing Groups ID.", true); return error('Incomplete call, missing Groups ID.', true);
} }
$group = sql_select("SELECT * FROM `Groups` WHERE `UID`='" . sql_escape($group_id) . "' LIMIT 1"); $group = DB::select('SELECT * FROM `Groups` WHERE `UID`=? LIMIT 1', [$group_id]);
if (count($group) > 0) { if (!empty($group)) {
list($group) = $group; $privileges = DB::select('
$privileges = sql_select("SELECT `Privileges`.*, `GroupPrivileges`.`group_id` FROM `Privileges` LEFT OUTER JOIN `GroupPrivileges` ON (`Privileges`.`id` = `GroupPrivileges`.`privilege_id` AND `GroupPrivileges`.`group_id`='" . sql_escape($group_id) . "') ORDER BY `Privileges`.`name`"); SELECT `Privileges`.*, `GroupPrivileges`.`group_id`
$privileges_html = ""; FROM `Privileges`
LEFT OUTER JOIN `GroupPrivileges`
ON (
`Privileges`.`id` = `GroupPrivileges`.`privilege_id`
AND `GroupPrivileges`.`group_id`=?
)
ORDER BY `Privileges`.`name`
', [$group_id]);
$privileges_html = '';
$privileges_form = []; $privileges_form = [];
foreach ($privileges as $priv) { foreach ($privileges as $privilege) {
$privileges_form[] = form_checkbox('privileges[]', $priv['desc'] . ' (' . $priv['name'] . ')', $priv['group_id'] != "", $priv['id']); $privileges_form[] = form_checkbox(
$privileges_html .= sprintf('<tr><td><input type="checkbox" ' . 'name="privileges[]" value="%s" %s />' . '</td> <td>%s</td> <td>%s</td></tr>', $priv['id'], ($priv['group_id'] != "" ? 'checked="checked"' : ''), $priv['name'], $priv['desc']); 'privileges[]',
$privilege['desc'] . ' (' . $privilege['name'] . ')',
$privilege['group_id'] != '',
$privilege['id'],
'privilege-' . $privilege['name']
);
$privileges_html .= sprintf(
'<tr><td><input type="checkbox" name="privileges[]" value="%s" %s /></td> <td>%s</td> <td>%s</td></tr>',
$privilege['id'],
($privilege['group_id'] != '' ? 'checked="checked"' : ''),
$privilege['name'],
$privilege['desc']
);
} }
$privileges_form[] = form_submit('submit', _("Save")); $privileges_form[] = form_submit('submit', _('Save'));
$html .= page_with_title(_("Edit group"), [ $html .= page_with_title(_('Edit group'), [
form($privileges_form, page_link_to('admin_groups') . '&action=save&id=' . $group_id) form(
$privileges_form,
page_link_to('admin_groups', ['action' => 'save', 'id' => $group_id])
)
]); ]);
} else { } else {
return error("No Group found.", true); return error('No Group found.', true);
} }
break; break;
case 'save': case 'save':
if (isset($_REQUEST['id']) && preg_match("/^-[0-9]{1,11}$/", $_REQUEST['id'])) { if ($request->has('id') && preg_match('/^-\d{1,11}$/', $request->input('id'))) {
$group_id = $_REQUEST['id']; $group_id = $request->input('id');
} else { } else {
return error("Incomplete call, missing Groups ID.", true); return error('Incomplete call, missing Groups ID.', true);
} }
$group = sql_select("SELECT * FROM `Groups` WHERE `UID`='" . sql_escape($group_id) . "' LIMIT 1"); $group = DB::selectOne('SELECT * FROM `Groups` WHERE `UID`=? LIMIT 1', [$group_id]);
if (! is_array($_REQUEST['privileges'])) { $privileges = $request->postData('privileges');
$_REQUEST['privileges'] = []; if (!is_array($privileges)) {
$privileges = [];
} }
if (count($group) > 0) { if (!empty($group)) {
list($group) = $group; DB::delete('DELETE FROM `GroupPrivileges` WHERE `group_id`=?', [$group_id]);
sql_query("DELETE FROM `GroupPrivileges` WHERE `group_id`='" . sql_escape($group_id) . "'");
$privilege_names = []; $privilege_names = [];
foreach ($_REQUEST['privileges'] as $priv) { foreach ($privileges as $privilege) {
if (preg_match("/^[0-9]{1,}$/", $priv)) { if (preg_match('/^\d{1,}$/', $privilege)) {
$group_privileges_source = sql_select("SELECT * FROM `Privileges` WHERE `id`='" . sql_escape($priv) . "' LIMIT 1"); $group_privileges_source = DB::selectOne(
if (count($group_privileges_source) > 0) { 'SELECT `name` FROM `Privileges` WHERE `id`=? LIMIT 1',
sql_query("INSERT INTO `GroupPrivileges` SET `group_id`='" . sql_escape($group_id) . "', `privilege_id`='" . sql_escape($priv) . "'"); [$privilege]
$privilege_names[] = $group_privileges_source[0]['name']; );
if (!empty($group_privileges_source)) {
DB::insert(
'INSERT INTO `GroupPrivileges` (`group_id`, `privilege_id`) VALUES (?, ?)',
[$group_id, $privilege]
);
$privilege_names[] = $group_privileges_source['name'];
} }
} }
} }
engelsystem_log("Group privileges of group " . $group['Name'] . " edited: " . join(", ", $privilege_names)); engelsystem_log(
redirect(page_link_to("admin_groups")); 'Group privileges of group ' . $group['Name']
. ' edited: ' . join(', ', $privilege_names)
);
redirect(page_link_to('admin_groups'));
} else { } else {
return error("No Group found.", true); return error('No Group found.', true);
} }
break; break;
} }
} }
return $html; return $html;
} }
?>

View File

@ -1,22 +1,35 @@
<?php <?php
function admin_import_title() { use Engelsystem\Database\DB;
return _("Frab import");
/**
* @return string
*/
function admin_import_title()
{
return _('Frab import');
} }
function admin_import() { /**
global $rooms_import; * @return string
global $user; */
$html = ""; function admin_import()
{
global $rooms_import, $user;
$html = '';
$import_dir = __DIR__ . '/../../import'; $import_dir = __DIR__ . '/../../import';
$request = request();
$step = "input"; $step = 'input';
if (isset($_REQUEST['step']) && in_array($step, [ if (
$request->has('step')
&& in_array($request->input('step'), [
'input', 'input',
'check', 'check',
'import' 'import'
])) { ])
$step = $_REQUEST['step']; ) {
$step = $request->input('step');
} }
if ($test_handle = @fopen($import_dir . '/tmp', 'w')) { if ($test_handle = @fopen($import_dir . '/tmp', 'w')) {
@ -32,9 +45,6 @@ function admin_import() {
$add_minutes_end = 15; $add_minutes_end = 15;
$shifttypes_source = ShiftTypes(); $shifttypes_source = ShiftTypes();
if ($shifttypes_source === false) {
engelsystem_error('Unable to load shifttypes.');
}
$shifttypes = []; $shifttypes = [];
foreach ($shifttypes_source as $shifttype) { foreach ($shifttypes_source as $shifttype) {
$shifttypes[$shifttype['id']] = $shifttype['name']; $shifttypes[$shifttype['id']] = $shifttype['name'];
@ -44,28 +54,28 @@ function admin_import() {
case 'input': case 'input':
$valid = false; $valid = false;
if (isset($_REQUEST['submit'])) { if ($request->has('submit')) {
$valid = true; $valid = true;
if (isset($_REQUEST['shifttype_id']) && isset($shifttypes[$_REQUEST['shifttype_id']])) { if ($request->has('shifttype_id') && isset($shifttypes[$request->input('shifttype_id')])) {
$shifttype_id = $_REQUEST['shifttype_id']; $shifttype_id = $request->input('shifttype_id');
} else { } else {
$valid = false; $valid = false;
error(_('Please select a shift type.')); error(_('Please select a shift type.'));
} }
if (isset($_REQUEST['add_minutes_start']) && is_numeric(trim($_REQUEST['add_minutes_start']))) { if ($request->has('add_minutes_start') && is_numeric(trim($request->input('add_minutes_start')))) {
$add_minutes_start = trim($_REQUEST['add_minutes_start']); $add_minutes_start = trim($request->input('add_minutes_start'));
} else { } else {
$valid = false; $valid = false;
error(_("Please enter an amount of minutes to add to a talk's begin.")); error(_('Please enter an amount of minutes to add to a talk\'s begin.'));
} }
if (isset($_REQUEST['add_minutes_end']) && is_numeric(trim($_REQUEST['add_minutes_end']))) { if ($request->has('add_minutes_end') && is_numeric(trim($request->input('add_minutes_end')))) {
$add_minutes_end = trim($_REQUEST['add_minutes_end']); $add_minutes_end = trim($request->input('add_minutes_end'));
} else { } else {
$valid = false; $valid = false;
error(_("Please enter an amount of minutes to add to a talk's end.")); error(_('Please enter an amount of minutes to add to a talk\'s end.'));
} }
if (isset($_FILES['xcal_file']) && ($_FILES['xcal_file']['error'] == 0)) { if (isset($_FILES['xcal_file']) && ($_FILES['xcal_file']['error'] == 0)) {
@ -87,19 +97,29 @@ function admin_import() {
} }
if ($valid) { if ($valid) {
redirect(page_link_to('admin_import') . "&step=check&shifttype_id=" . $shifttype_id . "&add_minutes_end=" . $add_minutes_end . "&add_minutes_start=" . $add_minutes_start); redirect(
page_link_to('admin_import', [
'step' => 'check',
'shifttype_id' => $shifttype_id,
'add_minutes_end' => $add_minutes_end,
'add_minutes_start' => $add_minutes_start,
])
);
} else { } else {
$html .= div('well well-sm text-center', [ $html .= div('well well-sm text-center', [
_('File Upload') . mute(glyph('arrow-right')) . mute(_('Validation')) . mute(glyph('arrow-right')) . mute(_('Import')) _('File Upload') . mute(glyph('arrow-right')) . mute(_('Validation')) . mute(glyph('arrow-right')) . mute(_('Import'))
]) . div('row', [ ]) . div('row', [
div('col-md-offset-3 col-md-6', [ div('col-md-offset-3 col-md-6', [
form([ form([
form_info('', _("This import will create/update/delete rooms and shifts by given FRAB-export file. The needed file format is xcal.")), form_info(
'',
_('This import will create/update/delete rooms and shifts by given FRAB-export file. The needed file format is xcal.')
),
form_select('shifttype_id', _('Shifttype'), $shifttypes, $shifttype_id), form_select('shifttype_id', _('Shifttype'), $shifttypes, $shifttype_id),
form_spinner('add_minutes_start', _("Add minutes to start"), $add_minutes_start), form_spinner('add_minutes_start', _('Add minutes to start'), $add_minutes_start),
form_spinner('add_minutes_end', _("Add minutes to end"), $add_minutes_end), form_spinner('add_minutes_end', _('Add minutes to end'), $add_minutes_end),
form_file('xcal_file', _("xcal-File (.xcal)")), form_file('xcal_file', _('xcal-File (.xcal)')),
form_submit('submit', _("Import")) form_submit('submit', _('Import'))
]) ])
]) ])
]); ]);
@ -107,151 +127,167 @@ function admin_import() {
break; break;
case 'check': case 'check':
if (! file_exists($import_file)) { if (!file_exists($import_file)) {
error(_('Missing import file.')); error(_('Missing import file.'));
redirect(page_link_to('admin_import')); redirect(page_link_to('admin_import'));
} }
if (isset($_REQUEST['shifttype_id']) && isset($shifttypes[$_REQUEST['shifttype_id']])) { if ($request->has('shifttype_id') && isset($shifttypes[$request->input('shifttype_id')])) {
$shifttype_id = $_REQUEST['shifttype_id']; $shifttype_id = $request->input('shifttype_id');
} else { } else {
error(_('Please select a shift type.')); error(_('Please select a shift type.'));
redirect(page_link_to('admin_import')); redirect(page_link_to('admin_import'));
} }
if (isset($_REQUEST['add_minutes_start']) && is_numeric(trim($_REQUEST['add_minutes_start']))) { if ($request->has('add_minutes_start') && is_numeric(trim($request->input('add_minutes_start')))) {
$add_minutes_start = trim($_REQUEST['add_minutes_start']); $add_minutes_start = trim($request->input('add_minutes_start'));
} else { } else {
error(_("Please enter an amount of minutes to add to a talk's begin.")); error(_('Please enter an amount of minutes to add to a talk\'s begin.'));
redirect(page_link_to('admin_import')); redirect(page_link_to('admin_import'));
} }
if (isset($_REQUEST['add_minutes_end']) && is_numeric(trim($_REQUEST['add_minutes_end']))) { if ($request->has('add_minutes_end') && is_numeric(trim($request->input(('add_minutes_end'))))) {
$add_minutes_end = trim($_REQUEST['add_minutes_end']); $add_minutes_end = trim($request->input('add_minutes_end'));
} else { } else {
error(_("Please enter an amount of minutes to add to a talk's end.")); error(_('Please enter an amount of minutes to add to a talk\'s end.'));
redirect(page_link_to('admin_import')); redirect(page_link_to('admin_import'));
} }
list($rooms_new, $rooms_deleted) = prepare_rooms($import_file); list($rooms_new, $rooms_deleted) = prepare_rooms($import_file);
list($events_new, $events_updated, $events_deleted) = prepare_events($import_file, $shifttype_id, $add_minutes_start, $add_minutes_end); list($events_new, $events_updated, $events_deleted) = prepare_events(
$import_file,
$shifttype_id,
$add_minutes_start,
$add_minutes_end
);
$html .= div('well well-sm text-center', [ $html .= div(
'<span class="text-success">' . _('File Upload') . glyph('ok-circle') . '</span>' . mute(glyph('arrow-right')) . _('Validation') . mute(glyph('arrow-right')) . mute(_('Import')) 'well well-sm text-center',
]) . form([ [
'<span class="text-success">' . _('File Upload') . glyph('ok-circle') . '</span>'
. mute(glyph('arrow-right')) . _('Validation') . mute(glyph('arrow-right')) . mute(_('Import'))
]
)
. form(
[
div('row', [ div('row', [
div('col-sm-6', [ div('col-sm-6', [
'<h3>' . _("Rooms to create") . '</h3>', '<h3>' . _('Rooms to create') . '</h3>',
table(_("Name"), $rooms_new) table(_('Name'), $rooms_new)
]), ]),
div('col-sm-6', [ div('col-sm-6', [
'<h3>' . _("Rooms to delete") . '</h3>', '<h3>' . _('Rooms to delete') . '</h3>',
table(_("Name"), $rooms_deleted) table(_('Name'), $rooms_deleted)
]) ])
]), ]),
'<h3>' . _("Shifts to create") . '</h3>', '<h3>' . _('Shifts to create') . '</h3>',
table([ table([
'day' => _("Day"), 'day' => _('Day'),
'start' => _("Start"), 'start' => _('Start'),
'end' => _("End"), 'end' => _('End'),
'shifttype' => _('Shift type'), 'shifttype' => _('Shift type'),
'title' => _("Title"), 'title' => _('Title'),
'room' => _("Room") 'room' => _('Room')
], shifts_printable($events_new, $shifttypes)), ], shifts_printable($events_new, $shifttypes)),
'<h3>' . _("Shifts to update") . '</h3>', '<h3>' . _('Shifts to update') . '</h3>',
table([ table([
'day' => _("Day"), 'day' => _('Day'),
'start' => _("Start"), 'start' => _('Start'),
'end' => _("End"), 'end' => _('End'),
'shifttype' => _('Shift type'), 'shifttype' => _('Shift type'),
'title' => _("Title"), 'title' => _('Title'),
'room' => _("Room") 'room' => _('Room')
], shifts_printable($events_updated, $shifttypes)), ], shifts_printable($events_updated, $shifttypes)),
'<h3>' . _("Shifts to delete") . '</h3>', '<h3>' . _('Shifts to delete') . '</h3>',
table([ table([
'day' => _("Day"), 'day' => _('Day'),
'start' => _("Start"), 'start' => _('Start'),
'end' => _("End"), 'end' => _('End'),
'shifttype' => _('Shift type'), 'shifttype' => _('Shift type'),
'title' => _("Title"), 'title' => _('Title'),
'room' => _("Room") 'room' => _('Room')
], shifts_printable($events_deleted, $shifttypes)), ], shifts_printable($events_deleted, $shifttypes)),
form_submit('submit', _("Import")) form_submit('submit', _('Import'))
], page_link_to('admin_import') . '&step=import&shifttype_id=' . $shifttype_id . "&add_minutes_end=" . $add_minutes_end . "&add_minutes_start=" . $add_minutes_start); ],
page_link_to('admin_import', [
'step' => 'import',
'shifttype_id' => $shifttype_id,
'add_minutes_end' => $add_minutes_end,
'add_minutes_start' => $add_minutes_start,
])
);
break; break;
case 'import': case 'import':
if (! file_exists($import_file)) { if (!file_exists($import_file)) {
error(_('Missing import file.')); error(_('Missing import file.'));
redirect(page_link_to('admin_import')); redirect(page_link_to('admin_import'));
} }
if (! file_exists($import_file)) { if (!file_exists($import_file)) {
redirect(page_link_to('admin_import')); redirect(page_link_to('admin_import'));
} }
if (isset($_REQUEST['shifttype_id']) && isset($shifttypes[$_REQUEST['shifttype_id']])) { if ($request->has('shifttype_id') && isset($shifttypes[$request->input('shifttype_id')])) {
$shifttype_id = $_REQUEST['shifttype_id']; $shifttype_id = $request->input('shifttype_id');
} else { } else {
error(_('Please select a shift type.')); error(_('Please select a shift type.'));
redirect(page_link_to('admin_import')); redirect(page_link_to('admin_import'));
} }
if (isset($_REQUEST['add_minutes_start']) && is_numeric(trim($_REQUEST['add_minutes_start']))) { if ($request->has('add_minutes_start') && is_numeric(trim($request->input('add_minutes_start')))) {
$add_minutes_start = trim($_REQUEST['add_minutes_start']); $add_minutes_start = trim($request->input('add_minutes_start'));
} else { } else {
error(_("Please enter an amount of minutes to add to a talk's begin.")); error(_('Please enter an amount of minutes to add to a talk\'s begin.'));
redirect(page_link_to('admin_import')); redirect(page_link_to('admin_import'));
} }
if (isset($_REQUEST['add_minutes_end']) && is_numeric(trim($_REQUEST['add_minutes_end']))) { if ($request->has('add_minutes_end') && is_numeric(trim($request->input('add_minutes_end')))) {
$add_minutes_end = trim($_REQUEST['add_minutes_end']); $add_minutes_end = trim($request->input('add_minutes_end'));
} else { } else {
error(_("Please enter an amount of minutes to add to a talk's end.")); error(_('Please enter an amount of minutes to add to a talk\'s end.'));
redirect(page_link_to('admin_import')); redirect(page_link_to('admin_import'));
} }
list($rooms_new, $rooms_deleted) = prepare_rooms($import_file); list($rooms_new, $rooms_deleted) = prepare_rooms($import_file);
foreach ($rooms_new as $room) { foreach ($rooms_new as $room) {
$result = Room_create($room, true, true); $result = Room_create($room, true, true);
if ($result === false) {
engelsystem_error('Unable to create room.'); $rooms_import[trim($room)] = $result;
}
$rooms_import[trim($room)] = sql_id();
} }
foreach ($rooms_deleted as $room) { foreach ($rooms_deleted as $room) {
sql_query("DELETE FROM `Room` WHERE `Name`='" . sql_escape($room) . "' LIMIT 1"); DB::delete('DELETE FROM `Room` WHERE `Name`=? LIMIT 1', [$room]);
} }
list($events_new, $events_updated, $events_deleted) = prepare_events($import_file, $shifttype_id, $add_minutes_start, $add_minutes_end); list($events_new, $events_updated, $events_deleted) = prepare_events(
$import_file,
$shifttype_id,
$add_minutes_start,
$add_minutes_end
);
foreach ($events_new as $event) { foreach ($events_new as $event) {
$result = Shift_create($event); Shift_create($event);
if ($result === false) {
engelsystem_error('Unable to create shift.');
}
} }
foreach ($events_updated as $event) { foreach ($events_updated as $event) {
$result = Shift_update_by_psid($event); Shift_update_by_psid($event);
if ($result === false) {
engelsystem_error('Unable to update shift.');
}
} }
foreach ($events_deleted as $event) { foreach ($events_deleted as $event) {
$result = Shift_delete_by_psid($event['PSID']); Shift_delete_by_psid($event['PSID']);
if ($result === false) {
engelsystem_error('Unable to delete shift.');
}
} }
engelsystem_log("Frab import done"); engelsystem_log('Frab import done');
unlink($import_file); unlink($import_file);
$html .= div('well well-sm text-center', [ $html .= div('well well-sm text-center', [
'<span class="text-success">' . _('File Upload') . glyph('ok-circle') . '</span>' . mute(glyph('arrow-right')) . '<span class="text-success">' . _('Validation') . glyph('ok-circle') . '</span>' . mute(glyph('arrow-right')) . '<span class="text-success">' . _('Import') . glyph('ok-circle') . '</span>' '<span class="text-success">' . _('File Upload') . glyph('ok-circle') . '</span>'
]) . success(_("It's done!"), true); . mute(glyph('arrow-right'))
. '<span class="text-success">' . _('Validation') . glyph('ok-circle') . '</span>'
. mute(glyph('arrow-right'))
. '<span class="text-success">' . _('Import') . glyph('ok-circle') . '</span>'
]) . success(_('It\'s done!'), true);
break; break;
default: default:
redirect(page_link_to('admin_import')); redirect(page_link_to('admin_import'));
@ -263,24 +299,29 @@ function admin_import() {
]); ]);
} }
function prepare_rooms($file) { /**
* @param string $file
* @return array
*/
function prepare_rooms($file)
{
global $rooms_import; global $rooms_import;
$data = read_xml($file); $data = read_xml($file);
// Load rooms from db for compare with input // Load rooms from db for compare with input
$rooms = sql_select("SELECT * FROM `Room` WHERE `FromPentabarf`='Y'"); $rooms = DB::select('SELECT `Name`, `RID` FROM `Room` WHERE `FromPentabarf`=\'Y\'');
$rooms_db = []; $rooms_db = [];
$rooms_import = []; $rooms_import = [];
foreach ($rooms as $room) { foreach ($rooms as $room) {
$rooms_db[] = (string) $room['Name']; $rooms_db[] = $room['Name'];
$rooms_import[$room['Name']] = $room['RID']; $rooms_import[$room['Name']] = $room['RID'];
} }
$events = $data->vcalendar->vevent; $events = $data->vcalendar->vevent;
$rooms_pb = []; $rooms_pb = [];
foreach ($events as $event) { foreach ($events as $event) {
$rooms_pb[] = (string) $event->location; $rooms_pb[] = (string)$event->location;
if (! isset($rooms_import[trim($event->location)])) { if (!isset($rooms_import[trim($event->location)])) {
$rooms_import[trim($event->location)] = trim($event->location); $rooms_import[trim($event->location)] = trim($event->location);
} }
} }
@ -295,11 +336,19 @@ function prepare_rooms($file) {
]; ];
} }
function prepare_events($file, $shifttype_id, $add_minutes_start, $add_minutes_end) { /**
* @param string $file
* @param int $shifttype_id
* @param int $add_minutes_start
* @param int $add_minutes_end
* @return array
*/
function prepare_events($file, $shifttype_id, $add_minutes_start, $add_minutes_end)
{
global $rooms_import; global $rooms_import;
$data = read_xml($file); $data = read_xml($file);
$rooms = sql_select("SELECT * FROM `Room`"); $rooms = Rooms(true);
$rooms_db = []; $rooms_db = [];
foreach ($rooms as $room) { foreach ($rooms as $room) {
$rooms_db[$room['Name']] = $room['RID']; $rooms_db[$room['Name']] = $room['RID'];
@ -308,9 +357,8 @@ function prepare_events($file, $shifttype_id, $add_minutes_start, $add_minutes_e
$events = $data->vcalendar->vevent; $events = $data->vcalendar->vevent;
$shifts_pb = []; $shifts_pb = [];
foreach ($events as $event) { foreach ($events as $event) {
$event_pb = $event->children("http://pentabarf.org"); $event_pb = $event->children('http://pentabarf.org');
$event_id = trim($event_pb->{ $event_id = trim($event_pb->{'event-id'});
'event-id' });
$shifts_pb[$event_id] = [ $shifts_pb[$event_id] = [
'shifttype_id' => $shifttype_id, 'shifttype_id' => $shifttype_id,
'start' => parse_date("Ymd\THis", $event->dtstart) - $add_minutes_start * 60, 'start' => parse_date("Ymd\THis", $event->dtstart) - $add_minutes_start * 60,
@ -322,7 +370,7 @@ function prepare_events($file, $shifttype_id, $add_minutes_start, $add_minutes_e
]; ];
} }
$shifts = sql_select("SELECT * FROM `Shifts` WHERE `PSID` IS NOT NULL ORDER BY `start`"); $shifts = DB::select('SELECT * FROM `Shifts` WHERE `PSID` IS NOT NULL ORDER BY `start`');
$shifts_db = []; $shifts_db = [];
foreach ($shifts as $shift) { foreach ($shifts as $shift) {
$shifts_db[$shift['PSID']] = $shift; $shifts_db[$shift['PSID']] = $shift;
@ -331,11 +379,18 @@ function prepare_events($file, $shifttype_id, $add_minutes_start, $add_minutes_e
$shifts_new = []; $shifts_new = [];
$shifts_updated = []; $shifts_updated = [];
foreach ($shifts_pb as $shift) { foreach ($shifts_pb as $shift) {
if (! isset($shifts_db[$shift['PSID']])) { if (!isset($shifts_db[$shift['PSID']])) {
$shifts_new[] = $shift; $shifts_new[] = $shift;
} else { } else {
$tmp = $shifts_db[$shift['PSID']]; $tmp = $shifts_db[$shift['PSID']];
if ($shift['shifttype_id'] != $tmp['shifttype_id'] || $shift['title'] != $tmp['title'] || $shift['start'] != $tmp['start'] || $shift['end'] != $tmp['end'] || $shift['RID'] != $tmp['RID'] || $shift['URL'] != $tmp['URL']) { if (
$shift['shifttype_id'] != $tmp['shifttype_id']
|| $shift['title'] != $tmp['title']
|| $shift['start'] != $tmp['start']
|| $shift['end'] != $tmp['end']
|| $shift['RID'] != $tmp['RID']
|| $shift['URL'] != $tmp['URL']
) {
$shifts_updated[] = $shift; $shifts_updated[] = $shift;
} }
} }
@ -343,7 +398,7 @@ function prepare_events($file, $shifttype_id, $add_minutes_start, $add_minutes_e
$shifts_deleted = []; $shifts_deleted = [];
foreach ($shifts_db as $shift) { foreach ($shifts_db as $shift) {
if (! isset($shifts_pb[$shift['PSID']])) { if (!isset($shifts_pb[$shift['PSID']])) {
$shifts_deleted[] = $shift; $shifts_deleted[] = $shift;
} }
} }
@ -355,15 +410,26 @@ function prepare_events($file, $shifttype_id, $add_minutes_start, $add_minutes_e
]; ];
} }
function read_xml($file) { /**
* @param string $file
* @return SimpleXMLElement
*/
function read_xml($file)
{
global $xml_import; global $xml_import;
if (! isset($xml_import)) { if (!isset($xml_import)) {
$xml_import = simplexml_load_file($file); $xml_import = simplexml_load_file($file);
} }
return $xml_import; return $xml_import;
} }
function shifts_printable($shifts, $shifttypes) { /**
* @param array $shifts
* @param array $shifttypes
* @return array
*/
function shifts_printable($shifts, $shifttypes)
{
global $rooms_import; global $rooms_import;
$rooms = array_flip($rooms_import); $rooms = array_flip($rooms_import);
@ -372,21 +438,26 @@ function shifts_printable($shifts, $shifttypes) {
$shifts_printable = []; $shifts_printable = [];
foreach ($shifts as $shift) { foreach ($shifts as $shift) {
$shifts_printable[] = [ $shifts_printable[] = [
'day' => date("l, Y-m-d", $shift['start']), 'day' => date('l, Y-m-d', $shift['start']),
'start' => date("H:i", $shift['start']), 'start' => date('H:i', $shift['start']),
'shifttype' => ShiftType_name_render([ 'shifttype' => ShiftType_name_render([
'id' => $shift['shifttype_id'], 'id' => $shift['shifttype_id'],
'name' => $shifttypes[$shift['shifttype_id']] 'name' => $shifttypes[$shift['shifttype_id']]
]), ]),
'title' => shorten($shift['title']), 'title' => shorten($shift['title']),
'end' => date("H:i", $shift['end']), 'end' => date('H:i', $shift['end']),
'room' => $rooms[$shift['RID']] 'room' => $rooms[$shift['RID']]
]; ];
} }
return $shifts_printable; return $shifts_printable;
} }
function shift_sort($shift_a, $shift_b) { /**
return ($shift_a['start'] < $shift_b['start']) ? - 1 : 1; * @param array $shift_a
* @param array $shift_b
* @return int
*/
function shift_sort($shift_a, $shift_b)
{
return ($shift_a['start'] < $shift_b['start']) ? -1 : 1;
} }
?>

View File

@ -1,33 +1,38 @@
<?php <?php
function admin_log_title() { /**
return _("Log"); * @return string
*/
function admin_log_title()
{
return _('Log');
} }
function admin_log() { /**
$filter = ""; * @return string
if (isset($_REQUEST['keyword'])) { */
function admin_log()
{
$filter = '';
if (request()->has('keyword')) {
$filter = strip_request_item('keyword'); $filter = strip_request_item('keyword');
} }
$log_entries_source = LogEntries_filter($filter); $log_entries = LogEntries_filter($filter);
$log_entries = []; foreach ($log_entries as &$log_entry) {
foreach ($log_entries_source as $log_entry) { $log_entry['date'] = date('d.m.Y H:i', $log_entry['timestamp']);
$log_entry['date'] = date("d.m.Y H:i", $log_entry['timestamp']);
$log_entries[] = $log_entry;
} }
return page_with_title(admin_log_title(), [ return page_with_title(admin_log_title(), [
msg(), msg(),
form([ form([
form_text('keyword', _("Search"), $filter), form_text('keyword', _('Search'), $filter),
form_submit(_("Search"), "Go") form_submit(_('Search'), 'Go')
]), ]),
table([ table([
'date' => "Time", 'date' => 'Time',
'nick' => "Angel", 'level' => 'Type',
'message' => "Log Entry" 'message' => 'Log Entry'
], $log_entries) ], $log_entries)
]); ]);
} }
?>

View File

@ -1,67 +1,92 @@
<?php <?php
function admin_news() { use Engelsystem\Database\DB;
global $user;
if (! isset($_GET["action"])) { /**
redirect(page_link_to("news")); * @return string
} */
function admin_news()
{
global $user, $privileges;
$request = request();
$html = '<div class="col-md-12"><h1>' . _("Edit news entry") . '</h1>' . msg(); if (!$request->has('action')) {
if (isset($_REQUEST['id']) && preg_match("/^[0-9]{1,11}$/", $_REQUEST['id'])) {
$news_id = $_REQUEST['id'];
} else {
return error("Incomplete call, missing News ID.", true);
}
$news = sql_select("SELECT * FROM `News` WHERE `ID`='" . sql_escape($news_id) . "' LIMIT 1");
if (empty($news)) {
return error("No News found.", true);
}
switch ($_REQUEST["action"]) {
default:
redirect(page_link_to('news')); redirect(page_link_to('news'));
case 'edit': }
list($news) = $news;
$html = '<div class="col-md-12"><h1>' . _('Edit news entry') . '</h1>' . msg();
if ($request->has('id') && preg_match('/^\d{1,11}$/', $request->input('id'))) {
$news_id = $request->input('id');
} else {
return error('Incomplete call, missing News ID.', true);
}
$news = DB::selectOne('SELECT * FROM `News` WHERE `ID`=? LIMIT 1', [$news_id]);
if (empty($news)) {
return error('No News found.', true);
}
switch ($request->input('action')) {
case 'edit':
$user_source = User($news['UID']); $user_source = User($news['UID']);
$html .= form([ $html .= form(
form_info(_("Date"), date("Y-m-d H:i", $news['Datum'])), [
form_info(_("Author"), User_Nick_render($user_source)), form_info(_('Date'), date('Y-m-d H:i', $news['Datum'])),
form_text('eBetreff', _("Subject"), $news['Betreff']), form_info(_('Author'), User_Nick_render($user_source)),
form_textarea('eText', _("Message"), $news['Text']), form_text('eBetreff', _('Subject'), $news['Betreff']),
form_checkbox('eTreffen', _("Meeting"), $news['Treffen'] == 1, 1), form_textarea('eText', _('Message'), $news['Text']),
form_submit('submit', _("Save")) form_checkbox('eTreffen', _('Meeting'), $news['Treffen'] == 1, 1),
], page_link_to('admin_news&action=save&id=' . $news_id)); form_submit('submit', _('Save'))
],
page_link_to('admin_news', ['action' => 'save', 'id' => $news_id])
);
$html .= '<a class="btn btn-danger" href="' . page_link_to('admin_news&action=delete&id=' . $news_id) . '"><span class="glyphicon glyphicon-trash"></span> ' . _("Delete") . '</a>'; $html .= '<a class="btn btn-danger" href="'
. page_link_to('admin_news', ['action' => 'delete', 'id' => $news_id])
. '">'
. '<span class="glyphicon glyphicon-trash"></span> ' . _('Delete')
. '</a>';
break; break;
case 'save': case 'save':
list($news) = $news; $text = $request->postData('eText');
if (!in_array('admin_news_html', $privileges)) {
$text = strip_tags($text);
}
sql_query("UPDATE `News` SET DB::update('
`Datum`='" . sql_escape(time()) . "', UPDATE `News` SET
`Betreff`='" . sql_escape($_POST["eBetreff"]) . "', `Datum`=?,
`Text`='" . sql_escape($_POST["eText"]) . "', `Betreff`=?,
`UID`='" . sql_escape($user['UID']) . "', `Text`=?,
`Treffen`='" . sql_escape($_POST["eTreffen"]) . "' `UID`=?,
WHERE `ID`='" . sql_escape($news_id) . "'"); `Treffen`=?
engelsystem_log("News updated: " . $_POST["eBetreff"]); WHERE `ID`=?
success(_("News entry updated.")); ',
redirect(page_link_to("news")); [
time(),
strip_tags($request->postData('eBetreff')),
$text,
$user['UID'],
$request->has('eTreffen') ? 1 : 0,
$news_id
]
);
engelsystem_log('News updated: ' . $request->postData('eBetreff'));
success(_('News entry updated.'));
redirect(page_link_to('news'));
break; break;
case 'delete': case 'delete':
list($news) = $news; DB::delete('DELETE FROM `News` WHERE `ID`=? LIMIT 1', [$news_id]);
engelsystem_log('News deleted: ' . $news['Betreff']);
sql_query("DELETE FROM `News` WHERE `ID`='" . sql_escape($news_id) . "' LIMIT 1"); success(_('News entry deleted.'));
engelsystem_log("News deleted: " . $news['Betreff']); redirect(page_link_to('news'));
success(_("News entry deleted."));
redirect(page_link_to("news"));
break; break;
default:
redirect(page_link_to('news'));
} }
return $html . '</div>'; return $html . '</div>';
} }
?>

View File

@ -1,21 +1,30 @@
<?php <?php
function admin_questions_title() { use Engelsystem\Database\DB;
return _("Answer questions");
/**
* @return string
*/
function admin_questions_title()
{
return _('Answer questions');
} }
/** /**
* Renders a hint for new questions to answer. * Renders a hint for new questions to answer.
*
* @return string|null
*/ */
function admin_new_questions() { function admin_new_questions()
{
global $privileges, $page; global $privileges, $page;
if ($page != "admin_questions") { if ($page != 'admin_questions') {
if (in_array("admin_questions", $privileges)) { if (in_array('admin_questions', $privileges)) {
$new_messages = sql_num_query("SELECT * FROM `Questions` WHERE `AID` IS NULL"); $new_messages = count(DB::select('SELECT `QID` FROM `Questions` WHERE `AID` IS NULL'));
if ($new_messages > 0) { if ($new_messages > 0) {
return '<a href="' . page_link_to("admin_questions") . '">' . _('There are unanswered questions!') . '</a>'; return '<a href="' . page_link_to('admin_questions') . '">' . _('There are unanswered questions!') . '</a>';
} }
} }
} }
@ -23,98 +32,133 @@ function admin_new_questions() {
return null; return null;
} }
function admin_questions() { /**
* @return string
*/
function admin_questions()
{
global $user; global $user;
$request = request();
if (! isset($_REQUEST['action'])) { if (!$request->has('action')) {
$unanswered_questions_table = []; $unanswered_questions_table = [];
$questions = sql_select("SELECT * FROM `Questions` WHERE `AID` IS NULL"); $questions = DB::select('SELECT * FROM `Questions` WHERE `AID` IS NULL');
foreach ($questions as $question) { foreach ($questions as $question) {
$user_source = User($question['UID']); $user_source = User($question['UID']);
$unanswered_questions_table[] = [ $unanswered_questions_table[] = [
'from' => User_Nick_render($user_source), 'from' => User_Nick_render($user_source),
'question' => str_replace("\n", "<br />", $question['Question']), 'question' => str_replace("\n", '<br />', $question['Question']),
'answer' => form([ 'answer' => form([
form_textarea('answer', '', ''), form_textarea('answer', '', ''),
form_submit('submit', _("Save")) form_submit('submit', _('Save'))
], page_link_to('admin_questions') . '&action=answer&id=' . $question['QID']), ], page_link_to('admin_questions', ['action' => 'answer', 'id' => $question['QID']])),
'actions' => button(page_link_to("admin_questions") . '&action=delete&id=' . $question['QID'], _("delete"), 'btn-xs') 'actions' => button(
page_link_to('admin_questions', ['action' => 'delete', 'id' => $question['QID']]),
_('delete'),
'btn-xs'
)
]; ];
} }
$answered_questions_table = []; $answered_questions_table = [];
$questions = sql_select("SELECT * FROM `Questions` WHERE NOT `AID` IS NULL"); $questions = DB::select('SELECT * FROM `Questions` WHERE NOT `AID` IS NULL');
foreach ($questions as $question) { foreach ($questions as $question) {
$user_source = User($question['UID']); $user_source = User($question['UID']);
$answer_user_source = User($question['AID']); $answer_user_source = User($question['AID']);
$answered_questions_table[] = [ $answered_questions_table[] = [
'from' => User_Nick_render($user_source), 'from' => User_Nick_render($user_source),
'question' => str_replace("\n", "<br />", $question['Question']), 'question' => str_replace("\n", '<br />', $question['Question']),
'answered_by' => User_Nick_render($answer_user_source), 'answered_by' => User_Nick_render($answer_user_source),
'answer' => str_replace("\n", "<br />", $question['Answer']), 'answer' => str_replace("\n", '<br />', $question['Answer']),
'actions' => button(page_link_to("admin_questions") . '&action=delete&id=' . $question['QID'], _("delete"), 'btn-xs') 'actions' => button(
page_link_to('admin_questions', ['action' => 'delete', 'id' => $question['QID']]),
_('delete'),
'btn-xs'
)
]; ];
} }
return page_with_title(admin_questions_title(), [ return page_with_title(admin_questions_title(), [
'<h2>' . _("Unanswered questions") . '</h2>', '<h2>' . _('Unanswered questions') . '</h2>',
table([ table([
'from' => _("From"), 'from' => _('From'),
'question' => _("Question"), 'question' => _('Question'),
'answer' => _("Answer"), 'answer' => _('Answer'),
'actions' => '' 'actions' => ''
], $unanswered_questions_table), ], $unanswered_questions_table),
'<h2>' . _("Answered questions") . '</h2>', '<h2>' . _('Answered questions') . '</h2>',
table([ table([
'from' => _("From"), 'from' => _('From'),
'question' => _("Question"), 'question' => _('Question'),
'answered_by' => _("Answered by"), 'answered_by' => _('Answered by'),
'answer' => _("Answer"), 'answer' => _('Answer'),
'actions' => '' 'actions' => ''
], $answered_questions_table) ], $answered_questions_table)
]); ]);
} else { } else {
switch ($_REQUEST['action']) { switch ($request->input('action')) {
case 'answer': case 'answer':
if (isset($_REQUEST['id']) && preg_match("/^[0-9]{1,11}$/", $_REQUEST['id'])) { if ($request->has('id') && preg_match('/^\d{1,11}$/', $request->input('id'))) {
$question_id = $_REQUEST['id']; $question_id = $request->input('id');
} else { } else {
return error("Incomplete call, missing Question ID.", true); return error('Incomplete call, missing Question ID.', true);
} }
$question = sql_select("SELECT * FROM `Questions` WHERE `QID`='" . sql_escape($question_id) . "' LIMIT 1"); $question = DB::selectOne(
if (count($question) > 0 && $question[0]['AID'] == null) { 'SELECT * FROM `Questions` WHERE `QID`=? LIMIT 1',
$answer = trim(preg_replace("/([^\p{L}\p{P}\p{Z}\p{N}\n]{1,})/ui", '', strip_tags($_REQUEST['answer']))); [$question_id]
);
if (!empty($question) && $question['AID'] == null) {
$answer = trim(
preg_replace("/([^\p{L}\p{P}\p{Z}\p{N}\n]{1,})/ui",
'',
strip_tags($request->input('answer'))
));
if ($answer != "") { if ($answer != '') {
sql_query("UPDATE `Questions` SET `AID`='" . sql_escape($user['UID']) . "', `Answer`='" . sql_escape($answer) . "' WHERE `QID`='" . sql_escape($question_id) . "' LIMIT 1"); DB::update('
engelsystem_log("Question " . $question[0]['Question'] . " answered: " . $answer); UPDATE `Questions`
redirect(page_link_to("admin_questions")); SET `AID`=?, `Answer`=?
WHERE `QID`=?
LIMIT 1
',
[
$user['UID'],
$answer,
$question_id,
]
);
engelsystem_log('Question ' . $question['Question'] . ' answered: ' . $answer);
redirect(page_link_to('admin_questions'));
} else { } else {
return error("Enter an answer!", true); return error('Enter an answer!', true);
} }
} else { } else {
return error("No question found.", true); return error('No question found.', true);
} }
break; break;
case 'delete': case 'delete':
if (isset($_REQUEST['id']) && preg_match("/^[0-9]{1,11}$/", $_REQUEST['id'])) { if ($request->has('id') && preg_match('/^\d{1,11}$/', $request->input('id'))) {
$question_id = $_REQUEST['id']; $question_id = $request->input('id');
} else { } else {
return error("Incomplete call, missing Question ID.", true); return error('Incomplete call, missing Question ID.', true);
} }
$question = sql_select("SELECT * FROM `Questions` WHERE `QID`='" . sql_escape($question_id) . "' LIMIT 1"); $question = DB::selectOne(
if (count($question) > 0) { 'SELECT * FROM `Questions` WHERE `QID`=? LIMIT 1',
sql_query("DELETE FROM `Questions` WHERE `QID`='" . sql_escape($question_id) . "' LIMIT 1"); [$question_id]
engelsystem_log("Question deleted: " . $question[0]['Question']); );
redirect(page_link_to("admin_questions")); if (!empty($question)) {
DB::delete('DELETE FROM `Questions` WHERE `QID`=? LIMIT 1', [$question_id]);
engelsystem_log('Question deleted: ' . $question['Question']);
redirect(page_link_to('admin_questions'));
} else { } else {
return error("No question found.", true); return error('No question found.', true);
} }
break; break;
} }
} }
return '';
} }
?>

View File

@ -1,33 +1,46 @@
<?php <?php
function admin_rooms_title() { use Engelsystem\Database\DB;
return _("Rooms");
/**
* @return string
*/
function admin_rooms_title()
{
return _('Rooms');
} }
function admin_rooms() { /**
$rooms_source = sql_select("SELECT * FROM `Room` ORDER BY `Name`"); * @return string
*/
function admin_rooms()
{
$rooms_source = DB::select('SELECT * FROM `Room` ORDER BY `Name`');
$rooms = []; $rooms = [];
$request = request();
foreach ($rooms_source as $room) { foreach ($rooms_source as $room) {
$rooms[] = [ $rooms[] = [
'name' => Room_name_render($room), 'name' => Room_name_render($room),
'from_pentabarf' => $room['FromPentabarf'] == 'Y' ? '&#10003;' : '', 'from_pentabarf' => glyph_bool($room['FromPentabarf'] == 'Y'),
'public' => $room['show'] == 'Y' ? '&#10003;' : '', 'public' => glyph_bool($room['show'] == 'Y'),
'actions' => table_buttons([ 'actions' => table_buttons([
button(page_link_to('admin_rooms') . '&show=edit&id=' . $room['RID'], _("edit"), 'btn-xs'), button(page_link_to('admin_rooms', ['show' => 'edit', 'id' => $room['RID']]), _('edit'), 'btn-xs'),
button(page_link_to('admin_rooms') . '&show=delete&id=' . $room['RID'], _("delete"), 'btn-xs') button(page_link_to('admin_rooms', ['show' => 'delete', 'id' => $room['RID']]), _('delete'), 'btn-xs')
]) ])
]; ];
} }
$room = null; $room = null;
if (isset($_REQUEST['show'])) { if ($request->has('show')) {
$msg = ""; $msg = '';
$name = ""; $name = '';
$from_pentabarf = ""; $from_pentabarf = '';
$public = 'Y'; $public = 'Y';
$number = ""; $number = '';
$room_id = 0;
$angeltypes_source = sql_select("SELECT * FROM `AngelTypes` ORDER BY `name`"); $angeltypes_source = DB::select('SELECT `id`, `name` FROM `AngelTypes` ORDER BY `name`');
$angeltypes = []; $angeltypes = [];
$angeltypes_count = []; $angeltypes_count = [];
foreach ($angeltypes_source as $angeltype) { foreach ($angeltypes_source as $angeltype) {
@ -36,78 +49,112 @@ function admin_rooms() {
} }
if (test_request_int('id')) { if (test_request_int('id')) {
$room = Room($_REQUEST['id']); $room = Room($request->input('id'), false);
if ($room === false) {
engelsystem_error("Unable to load room.");
}
if ($room == null) { if ($room == null) {
redirect(page_link_to('admin_rooms')); redirect(page_link_to('admin_rooms'));
} }
$room_id = $_REQUEST['id']; $room_id = $request->input('id');
$name = $room['Name']; $name = $room['Name'];
$from_pentabarf = $room['FromPentabarf']; $from_pentabarf = $room['FromPentabarf'];
$public = $room['show']; $public = $room['show'];
$number = $room['Number']; $number = $room['Number'];
$needed_angeltypes = sql_select("SELECT * FROM `NeededAngelTypes` WHERE `room_id`='" . sql_escape($room_id) . "'"); $needed_angeltypes = DB::select(
'SELECT `angel_type_id`, `count` FROM `NeededAngelTypes` WHERE `room_id`=?',
[$room_id]
);
foreach ($needed_angeltypes as $needed_angeltype) { foreach ($needed_angeltypes as $needed_angeltype) {
$angeltypes_count[$needed_angeltype['angel_type_id']] = $needed_angeltype['count']; $angeltypes_count[$needed_angeltype['angel_type_id']] = $needed_angeltype['count'];
} }
} }
if ($_REQUEST['show'] == 'edit') { if ($request->input('show') == 'edit') {
if (isset($_REQUEST['submit'])) { if ($request->has('submit')) {
$valid = true; $valid = true;
if (isset($_REQUEST['name']) && strlen(strip_request_item('name')) > 0) { if ($request->has('name') && strlen(strip_request_item('name')) > 0) {
$name = strip_request_item('name'); $name = strip_request_item('name');
if (isset($room) && sql_num_query("SELECT * FROM `Room` WHERE `Name`='" . sql_escape($name) . "' AND NOT `RID`=" . sql_escape($room_id)) > 0) { if (
isset($room)
&& count(DB::select(
'SELECT RID FROM `Room` WHERE `Name`=? AND NOT `RID`=?',
[$name, $room_id]
)) > 0
) {
$valid = false; $valid = false;
$msg .= error(_("This name is already in use."), true); $msg .= error(_('This name is already in use.'), true);
} }
} else { } else {
$valid = false; $valid = false;
$msg .= error(_("Please enter a name."), true); $msg .= error(_('Please enter a name.'), true);
} }
if (isset($_REQUEST['from_pentabarf'])) {
$from_pentabarf = 'Y';
} else {
$from_pentabarf = ''; $from_pentabarf = '';
if ($request->has('from_pentabarf')) {
$from_pentabarf = 'Y';
} }
if (isset($_REQUEST['public'])) {
$public = 'Y';
} else {
$public = ''; $public = '';
if ($request->has('public')) {
$public = 'Y';
} }
if (isset($_REQUEST['number'])) { if ($request->has('number')) {
$number = strip_request_item('number'); $number = strip_request_item('number');
} else { } else {
$valid = false; $valid = false;
} }
foreach ($angeltypes as $angeltype_id => $angeltype) { foreach ($angeltypes as $angeltype_id => $angeltype) {
if (isset($_REQUEST['angeltype_count_' . $angeltype_id]) && preg_match("/^[0-9]{1,4}$/", $_REQUEST['angeltype_count_' . $angeltype_id])) { $angeltypes_count[$angeltype_id] = 0;
$angeltypes_count[$angeltype_id] = $_REQUEST['angeltype_count_' . $angeltype_id]; $queryKey = 'angeltype_count_' . $angeltype_id;
if (!$request->has($queryKey)) {
continue;
}
if (preg_match('/^\d{1,4}$/', $request->input($queryKey))) {
$angeltypes_count[$angeltype_id] = $request->input($queryKey);
} else { } else {
$valid = false; $valid = false;
$msg .= error(sprintf(_("Please enter needed angels for type %s.", $angeltype)), true); $msg .= error(sprintf(_('Please enter needed angels for type %s.'), $angeltype), true);
} }
} }
if ($valid) { if ($valid) {
if (isset($room_id)) { if (!empty($room_id)) {
sql_query("UPDATE `Room` SET `Name`='" . sql_escape($name) . "', `FromPentabarf`='" . sql_escape($from_pentabarf) . "', `show`='" . sql_escape($public) . "', `Number`='" . sql_escape($number) . "' WHERE `RID`='" . sql_escape($room_id) . "' LIMIT 1"); DB::update('
engelsystem_log("Room updated: " . $name . ", pentabarf import: " . $from_pentabarf . ", public: " . $public . ", number: " . $number); UPDATE `Room`
SET
`Name`=?,
`FromPentabarf`=?,
`show`=?,
`Number`=?
WHERE `RID`=?
LIMIT 1
', [
$name,
$from_pentabarf,
$public,
$number,
$room_id,
]);
engelsystem_log(
'Room updated: ' . $name
. ', pentabarf import: ' . $from_pentabarf
. ', public: ' . $public
. ', number: ' . $number
);
} else { } else {
$room_id = Room_create($name, $from_pentabarf, $public, $number); $room_id = Room_create($name, $from_pentabarf, $public, $number);
if ($room_id === false) {
engelsystem_error("Unable to create room."); engelsystem_log(
} 'Room created: ' . $name
engelsystem_log("Room created: " . $name . ", pentabarf import: " . $from_pentabarf . ", public: " . $public . ", number: " . $number); . ', pentabarf import: '
. $from_pentabarf
. ', public: ' . $public
. ', number: ' . $number
);
} }
NeededAngelTypes_delete_by_room($room_id); NeededAngelTypes_delete_by_room($room_id);
@ -116,13 +163,16 @@ function admin_rooms() {
$angeltype = AngelType($angeltype_id); $angeltype = AngelType($angeltype_id);
if ($angeltype != null) { if ($angeltype != null) {
NeededAngelType_add(null, $angeltype_id, $room_id, $angeltype_count); NeededAngelType_add(null, $angeltype_id, $room_id, $angeltype_count);
$needed_angeltype_info[] = $angeltype['name'] . ": " . $angeltype_count; $needed_angeltype_info[] = $angeltype['name'] . ': ' . $angeltype_count;
} }
} }
engelsystem_log("Set needed angeltypes of room " . $name . " to: " . join(", ", $needed_angeltype_info)); engelsystem_log(
success(_("Room saved.")); 'Set needed angeltypes of room ' . $name
redirect(page_link_to("admin_rooms")); . ' to: ' . join(', ', $needed_angeltype_info)
);
success(_('Room saved.'));
redirect(page_link_to('admin_rooms'));
} }
} }
$angeltypes_count_form = []; $angeltypes_count_form = [];
@ -134,47 +184,49 @@ function admin_rooms() {
return page_with_title(admin_rooms_title(), [ return page_with_title(admin_rooms_title(), [
buttons([ buttons([
button(page_link_to('admin_rooms'), _("back"), 'back') button(page_link_to('admin_rooms'), _('back'), 'back')
]), ]),
$msg, $msg,
form([ form([
div('row', [ div('row', [
div('col-md-6', [ div('col-md-6', [
form_text('name', _("Name"), $name), form_text('name', _('Name'), $name),
form_checkbox('from_pentabarf', _("Frab import"), $from_pentabarf), form_checkbox('from_pentabarf', _('Frab import'), $from_pentabarf),
form_checkbox('public', _("Public"), $public), form_checkbox('public', _('Public'), $public),
form_text('number', _("Room number"), $number) form_text('number', _('Room number'), $number)
]), ]),
div('col-md-6', [ div('col-md-6', [
div('row', [ div('row', [
div('col-md-12', [ div('col-md-12', [
form_info(_("Needed angels:")) form_info(_('Needed angels:'))
]), ]),
join($angeltypes_count_form) join($angeltypes_count_form)
]) ])
]) ])
]), ]),
form_submit('submit', _("Save")) form_submit('submit', _('Save'))
]) ])
]); ]);
} elseif ($_REQUEST['show'] == 'delete') { } elseif ($request->input('show') == 'delete') {
if (isset($_REQUEST['ack'])) { if ($request->has('ack')) {
if (! Room_delete($room_id)) { Room_delete($room_id);
engelsystem_error("Unable to delete room.");
}
engelsystem_log("Room deleted: " . $name); engelsystem_log('Room deleted: ' . $name);
success(sprintf(_("Room %s deleted."), $name)); success(sprintf(_('Room %s deleted.'), $name));
redirect(page_link_to('admin_rooms')); redirect(page_link_to('admin_rooms'));
} }
return page_with_title(admin_rooms_title(), [ return page_with_title(admin_rooms_title(), [
buttons([ buttons([
button(page_link_to('admin_rooms'), _("back"), 'back') button(page_link_to('admin_rooms'), _('back'), 'back')
]), ]),
sprintf(_("Do you want to delete room %s?"), $name), sprintf(_('Do you want to delete room %s?'), $name),
buttons([ buttons([
button(page_link_to('admin_rooms') . '&show=delete&id=' . $room_id . '&ack', _("Delete"), 'delete') button(
page_link_to('admin_rooms', ['show' => 'delete', 'id' => $room_id, 'ack' => 1]),
_('Delete'),
'delete btn-danger'
)
]) ])
]); ]);
} }
@ -182,15 +234,14 @@ function admin_rooms() {
return page_with_title(admin_rooms_title(), [ return page_with_title(admin_rooms_title(), [
buttons([ buttons([
button(page_link_to('admin_rooms') . '&show=edit', _("add")) button(page_link_to('admin_rooms', ['show' => 'edit']), _('add'))
]), ]),
msg(), msg(),
table([ table([
'name' => _("Name"), 'name' => _('Name'),
'from_pentabarf' => _("Frab import"), 'from_pentabarf' => _('Frab import'),
'public' => _("Public"), 'public' => _('Public'),
'actions' => "" 'actions' => ''
], $rooms) ], $rooms)
]); ]);
} }
?>

View File

@ -1,32 +1,43 @@
<?php <?php
function admin_shifts_title() { use Engelsystem\Database\DB;
return _("Create shifts");
/**
* @return string
*/
function admin_shifts_title()
{
return _('Create shifts');
} }
// Assistent zum Anlegen mehrerer neuer Schichten /**
function admin_shifts() { * Assistent zum Anlegen mehrerer neuer Schichten
*
* @return string
*/
function admin_shifts()
{
$valid = true; $valid = true;
$request = request();
$rid = 0; $session = session();
$start = parse_date("Y-m-d H:i", date("Y-m-d") . " 00:00"); $start = parse_date('Y-m-d H:i', date('Y-m-d') . ' 00:00');
$end = $start; $end = $start;
$mode = 'single'; $mode = 'single';
$angelmode = 'manually'; $angelmode = 'manually';
$length = ''; $length = '';
$change_hours = []; $change_hours = [];
$title = ""; $title = '';
$shifttype_id = null; $shifttype_id = null;
// Locations laden (auch unsichtbare - fuer Erzengel ist das ok) // Locations laden (auch unsichtbare - fuer Erzengel ist das ok)
$rooms = sql_select("SELECT * FROM `Room` ORDER BY `Name`"); $rooms = DB::select('SELECT `RID`, `Name` FROM `Room` ORDER BY `Name`');
$room_array = []; $room_array = [];
foreach ($rooms as $room) { foreach ($rooms as $room) {
$room_array[$room['RID']] = $room['Name']; $room_array[$room['RID']] = $room['Name'];
} }
// Engeltypen laden // Engeltypen laden
$types = sql_select("SELECT * FROM `AngelTypes` ORDER BY `name`"); $types = DB::select('SELECT * FROM `AngelTypes` ORDER BY `name`');
$needed_angel_types = []; $needed_angel_types = [];
foreach ($types as $type) { foreach ($types as $type) {
$needed_angel_types[$type['id']] = 0; $needed_angel_types[$type['id']] = 0;
@ -34,25 +45,19 @@ function admin_shifts() {
// Load shift types // Load shift types
$shifttypes_source = ShiftTypes(); $shifttypes_source = ShiftTypes();
if ($shifttypes_source === false) {
engelsystem_error('Unable to load shift types.');
}
$shifttypes = []; $shifttypes = [];
foreach ($shifttypes_source as $shifttype) { foreach ($shifttypes_source as $shifttype) {
$shifttypes[$shifttype['id']] = $shifttype['name']; $shifttypes[$shifttype['id']] = $shifttype['name'];
} }
if (isset($_REQUEST['preview']) || isset($_REQUEST['back'])) { if ($request->has('preview') || $request->has('back')) {
if (isset($_REQUEST['shifttype_id'])) { if ($request->has('shifttype_id')) {
$shifttype = ShiftType($_REQUEST['shifttype_id']); $shifttype = ShiftType($request->input('shifttype_id'));
if ($shifttype === false) {
engelsystem_error('Unable to load shift type.');
}
if ($shifttype == null) { if ($shifttype == null) {
$valid = false; $valid = false;
error(_('Please select a shift type.')); error(_('Please select a shift type.'));
} else { } else {
$shifttype_id = $_REQUEST['shifttype_id']; $shifttype_id = $request->input('shifttype_id');
} }
} else { } else {
$valid = false; $valid = false;
@ -63,22 +68,26 @@ function admin_shifts() {
$title = strip_request_item('title'); $title = strip_request_item('title');
// Auswahl der sichtbaren Locations für die Schichten // Auswahl der sichtbaren Locations für die Schichten
if (isset($_REQUEST['rid']) && preg_match("/^[0-9]+$/", $_REQUEST['rid']) && isset($room_array[$_REQUEST['rid']])) { if (
$rid = $_REQUEST['rid']; $request->has('rid')
&& preg_match('/^\d+$/', $request->input('rid'))
&& isset($room_array[$request->input('rid')])
) {
$rid = $request->input('rid');
} else { } else {
$valid = false; $valid = false;
$rid = $rooms[0]['RID']; $rid = $rooms[0]['RID'];
error(_('Please select a location.')); error(_('Please select a location.'));
} }
if (isset($_REQUEST['start']) && $tmp = parse_date("Y-m-d H:i", $_REQUEST['start'])) { if ($request->has('start') && $tmp = parse_date('Y-m-d H:i', $request->input('start'))) {
$start = $tmp; $start = $tmp;
} else { } else {
$valid = false; $valid = false;
error(_('Please select a start time.')); error(_('Please select a start time.'));
} }
if (isset($_REQUEST['end']) && $tmp = parse_date("Y-m-d H:i", $_REQUEST['end'])) { if ($request->has('end') && $tmp = parse_date('Y-m-d H:i', $request->input('end'))) {
$end = $tmp; $end = $tmp;
} else { } else {
$valid = false; $valid = false;
@ -90,21 +99,24 @@ function admin_shifts() {
error(_('The shifts end has to be after its start.')); error(_('The shifts end has to be after its start.'));
} }
if (isset($_REQUEST['mode'])) { if ($request->has('mode')) {
if ($_REQUEST['mode'] == 'single') { if ($request->input('mode') == 'single') {
$mode = 'single'; $mode = 'single';
} elseif ($_REQUEST['mode'] == 'multi') { } elseif ($request->input('mode') == 'multi') {
if (isset($_REQUEST['length']) && preg_match("/^[0-9]+$/", trim($_REQUEST['length']))) { if ($request->has('length') && preg_match('/^\d+$/', trim($request->input('length')))) {
$mode = 'multi'; $mode = 'multi';
$length = trim($_REQUEST['length']); $length = trim($request->input('length'));
} else { } else {
$valid = false; $valid = false;
error(_('Please enter a shift duration in minutes.')); error(_('Please enter a shift duration in minutes.'));
} }
} elseif ($_REQUEST['mode'] == 'variable') { } elseif ($request->input('mode') == 'variable') {
if (isset($_REQUEST['change_hours']) && preg_match("/^([0-9]{2}(,|$))/", trim(str_replace(" ", "", $_REQUEST['change_hours'])))) { if (
$request->has('change_hours')
&& preg_match('/^(\d{2}(,|$))/', trim(str_replace(' ', '', $request->input('change_hours'))))
) {
$mode = 'variable'; $mode = 'variable';
$change_hours = array_map('trim', explode(",", $_REQUEST['change_hours'])); $change_hours = array_map('trim', explode(',', $request->input('change_hours')));
} else { } else {
$valid = false; $valid = false;
error(_('Please split the shift-change hours by colons.')); error(_('Please split the shift-change hours by colons.'));
@ -115,19 +127,20 @@ function admin_shifts() {
error(_('Please select a mode.')); error(_('Please select a mode.'));
} }
if (isset($_REQUEST['angelmode'])) { if ($request->has('angelmode')) {
if ($_REQUEST['angelmode'] == 'location') { if ($request->input('angelmode') == 'location') {
$angelmode = 'location'; $angelmode = 'location';
} elseif ($_REQUEST['angelmode'] == 'manually') { } elseif ($request->input('angelmode') == 'manually') {
$angelmode = 'manually'; $angelmode = 'manually';
foreach ($types as $type) { foreach ($types as $type) {
if (isset($_REQUEST['type_' . $type['id']]) && preg_match("/^[0-9]+$/", trim($_REQUEST['type_' . $type['id']]))) { if (preg_match('/^\d+$/', trim($request->input('type_' . $type['id'], 0)))) {
$needed_angel_types[$type['id']] = trim($_REQUEST['type_' . $type['id']]); $needed_angel_types[$type['id']] = trim($request->input('type_' . $type['id'], 0));
} else { } else {
$valid = false; $valid = false;
error(sprintf(_('Please check the needed angels for team %s.'), $type['name'])); error(sprintf(_('Please check the needed angels for team %s.'), $type['name']));
} }
} }
if (array_sum($needed_angel_types) == 0) { if (array_sum($needed_angel_types) == 0) {
$valid = false; $valid = false;
error(_('There are 0 angels needed. Please enter the amounts of needed angels.')); error(_('There are 0 angels needed. Please enter the amounts of needed angels.'));
@ -142,7 +155,7 @@ function admin_shifts() {
} }
// Beim Zurück-Knopf das Formular zeigen // Beim Zurück-Knopf das Formular zeigen
if (isset($_REQUEST['back'])) { if ($request->has('back')) {
$valid = false; $valid = false;
} }
@ -150,7 +163,13 @@ function admin_shifts() {
if ($valid) { if ($valid) {
if ($angelmode == 'location') { if ($angelmode == 'location') {
$needed_angel_types = []; $needed_angel_types = [];
$needed_angel_types_location = sql_select("SELECT * FROM `NeededAngelTypes` WHERE `room_id`='" . sql_escape($rid) . "'"); $needed_angel_types_location = DB::select('
SELECT `angel_type_id`, `count`
FROM `NeededAngelTypes`
WHERE `room_id`=?
',
[$rid]
);
foreach ($needed_angel_types_location as $type) { foreach ($needed_angel_types_location as $type) {
$needed_angel_types[$type['angel_type_id']] = $type['count']; $needed_angel_types[$type['angel_type_id']] = $type['count'];
} }
@ -165,9 +184,9 @@ function admin_shifts() {
'shifttype_id' => $shifttype_id 'shifttype_id' => $shifttype_id
]; ];
} elseif ($mode == 'multi') { } elseif ($mode == 'multi') {
$shift_start = $start; $shift_start = (int)$start;
do { do {
$shift_end = $shift_start + $length * 60; $shift_end = $shift_start + (int)$length * 60;
if ($shift_end > $end) { if ($shift_end > $end) {
$shift_end = $end; $shift_end = $end;
@ -188,7 +207,7 @@ function admin_shifts() {
} while ($shift_end < $end); } while ($shift_end < $end);
} elseif ($mode == 'variable') { } elseif ($mode == 'variable') {
rsort($change_hours); rsort($change_hours);
$day = parse_date("Y-m-d H:i", date("Y-m-d", $start) . " 00:00"); $day = parse_date('Y-m-d H:i', date('Y-m-d', $start) . ' 00:00');
$change_index = 0; $change_index = 0;
// Ersten/nächsten passenden Schichtwechsel suchen // Ersten/nächsten passenden Schichtwechsel suchen
foreach ($change_hours as $i => $change_hour) { foreach ($change_hours as $i => $change_hour) {
@ -205,7 +224,7 @@ function admin_shifts() {
$shift_start = $start; $shift_start = $start;
do { do {
$day = parse_date("Y-m-d H:i", date("Y-m-d", $shift_start) . " 00:00"); $day = parse_date('Y-m-d H:i', date('Y-m-d', $shift_start) . ' 00:00');
$shift_end = $day + $change_hours[$change_index] * 60 * 60; $shift_end = $day + $change_hours[$change_index] * 60 * 60;
if ($shift_end > $end) { if ($shift_end > $end) {
@ -231,8 +250,16 @@ function admin_shifts() {
$shifts_table = []; $shifts_table = [];
foreach ($shifts as $shift) { foreach ($shifts as $shift) {
$shifts_table_entry = [ $shifts_table_entry = [
'timeslot' => '<span class="glyphicon glyphicon-time"></span> ' . date("Y-m-d H:i", $shift['start']) . ' - ' . date("H:i", $shift['end']) . '<br />' . Room_name_render(Room($shift['RID'])), 'timeslot' =>
'title' => ShiftType_name_render(ShiftType($shifttype_id)) . ($shift['title'] ? '<br />' . $shift['title'] : ''), '<span class="glyphicon glyphicon-time"></span> '
. date('Y-m-d H:i', $shift['start'])
. ' - '
. date('H:i', $shift['end'])
. '<br />'
. Room_name_render(Room($shift['RID'])),
'title' =>
ShiftType_name_render(ShiftType($shifttype_id))
. ($shift['title'] ? '<br />' . $shift['title'] : ''),
'needed_angels' => '' 'needed_angels' => ''
]; ];
foreach ($types as $type) { foreach ($types as $type) {
@ -244,103 +271,141 @@ function admin_shifts() {
} }
// Fürs Anlegen zwischenspeichern: // Fürs Anlegen zwischenspeichern:
$_SESSION['admin_shifts_shifts'] = $shifts; $session->set('admin_shifts_shifts', $shifts);
$_SESSION['admin_shifts_types'] = $needed_angel_types; $session->set('admin_shifts_types', $needed_angel_types);
$hidden_types = ""; $hidden_types = '';
foreach ($needed_angel_types as $type_id => $count) { foreach ($needed_angel_types as $type_id => $count) {
$hidden_types .= form_hidden('type_' . $type_id, $count); $hidden_types .= form_hidden('type_' . $type_id, $count);
} }
return page_with_title(_("Preview"), [ return page_with_title(_('Preview'), [
form([ form([
$hidden_types, $hidden_types,
form_hidden('shifttype_id', $shifttype_id), form_hidden('shifttype_id', $shifttype_id),
form_hidden('title', $title), form_hidden('title', $title),
form_hidden('rid', $rid), form_hidden('rid', $rid),
form_hidden('start', date("Y-m-d H:i", $start)), form_hidden('start', date('Y-m-d H:i', $start)),
form_hidden('end', date("Y-m-d H:i", $end)), form_hidden('end', date('Y-m-d H:i', $end)),
form_hidden('mode', $mode), form_hidden('mode', $mode),
form_hidden('length', $length), form_hidden('length', $length),
form_hidden('change_hours', implode(', ', $change_hours)), form_hidden('change_hours', implode(', ', $change_hours)),
form_hidden('angelmode', $angelmode), form_hidden('angelmode', $angelmode),
form_submit('back', _("back")), form_submit('back', _('back')),
table([ table([
'timeslot' => _('Time and location'), 'timeslot' => _('Time and location'),
'title' => _('Type and title'), 'title' => _('Type and title'),
'needed_angels' => _('Needed angels') 'needed_angels' => _('Needed angels')
], $shifts_table), ], $shifts_table),
form_submit('submit', _("Save")) form_submit('submit', _('Save'))
]) ])
]); ]);
} }
} elseif (isset($_REQUEST['submit'])) { } elseif ($request->has('submit')) {
if (! is_array($_SESSION['admin_shifts_shifts']) || ! is_array($_SESSION['admin_shifts_types'])) { if (
!is_array($session->get('admin_shifts_shifts'))
|| !is_array($session->get('admin_shifts_types'))
) {
redirect(page_link_to('admin_shifts')); redirect(page_link_to('admin_shifts'));
} }
foreach ($_SESSION['admin_shifts_shifts'] as $shift) { foreach ($session->get('admin_shifts_shifts', []) as $shift) {
$shift['URL'] = null; $shift['URL'] = null;
$shift['PSID'] = null; $shift['PSID'] = null;
$shift_id = Shift_create($shift); $shift_id = Shift_create($shift);
if ($shift_id === false) {
engelsystem_error('Unable to create shift.');
}
engelsystem_log("Shift created: " . $shifttypes[$shift['shifttype_id']] . " with title " . $shift['title'] . " from " . date("Y-m-d H:i", $shift['start']) . " to " . date("Y-m-d H:i", $shift['end'])); engelsystem_log(
'Shift created: ' . $shifttypes[$shift['shifttype_id']]
. ' with title ' . $shift['title']
. ' from ' . date('Y-m-d H:i', $shift['start'])
. ' to ' . date('Y-m-d H:i', $shift['end'])
);
$needed_angel_types_info = []; $needed_angel_types_info = [];
foreach ($_SESSION['admin_shifts_types'] as $type_id => $count) { foreach ($session->get('admin_shifts_types', []) as $type_id => $count) {
$angel_type_source = sql_select("SELECT * FROM `AngelTypes` WHERE `id`='" . sql_escape($type_id) . "' LIMIT 1"); $angel_type_source = DB::selectOne('
if (count($angel_type_source) > 0) { SELECT *
sql_query("INSERT INTO `NeededAngelTypes` SET `shift_id`='" . sql_escape($shift_id) . "', `angel_type_id`='" . sql_escape($type_id) . "', `count`='" . sql_escape($count) . "'"); FROM `AngelTypes`
$needed_angel_types_info[] = $angel_type_source[0]['name'] . ": " . $count; WHERE `id` = ?
LIMIT 1', [$type_id]);
if (!empty($angel_type_source)) {
DB::insert('
INSERT INTO `NeededAngelTypes` (`shift_id`, `angel_type_id`, `count`)
VALUES (?, ?, ?)
',
[
$shift_id,
$type_id,
$count
]
);
$needed_angel_types_info[] = $angel_type_source['name'] . ': ' . $count;
} }
} }
engelsystem_log('Shift needs following angel types: ' . join(', ', $needed_angel_types_info));
} }
engelsystem_log("Shift needs following angel types: " . join(", ", $needed_angel_types_info)); success('Schichten angelegt.');
success("Schichten angelegt.");
redirect(page_link_to('admin_shifts')); redirect(page_link_to('admin_shifts'));
} else { } else {
unset($_SESSION['admin_shifts_shifts']); $session->remove('admin_shifts_shifts');
unset($_SESSION['admin_shifts_types']); $session->remove('admin_shifts_types');
} }
if (! isset($_REQUEST['rid'])) { $rid = null;
$_REQUEST['rid'] = null; if ($request->has('rid')) {
$rid = $request->input('rid');
} }
$angel_types = ""; $angel_types = '';
foreach ($types as $type) { foreach ($types as $type) {
$angel_types .= '<div class="col-md-4">' . form_spinner('type_' . $type['id'], $type['name'], $needed_angel_types[$type['id']]) . '</div>'; $angel_types .= '<div class="col-md-4">' . form_spinner(
'type_' . $type['id'],
$type['name'],
$needed_angel_types[$type['id']]
)
. '</div>';
} }
return page_with_title(admin_shifts_title(), [ return page_with_title(admin_shifts_title(), [
msg(), msg(),
form([ form([
form_select('shifttype_id', _('Shifttype'), $shifttypes, $shifttype_id), form_select('shifttype_id', _('Shifttype'), $shifttypes, $shifttype_id),
form_text('title', _("Title"), $title), form_text('title', _('Title'), $title),
form_select('rid', _("Room"), $room_array, $_REQUEST['rid']), form_select('rid', _('Room'), $room_array, $rid),
div('row', [ div('row', [
div('col-md-6', [ div('col-md-6', [
form_text('start', _("Start"), date("Y-m-d H:i", $start)), form_text('start', _('Start'), date('Y-m-d H:i', $start)),
form_text('end', _("End"), date("Y-m-d H:i", $end)), form_text('end', _('End'), date('Y-m-d H:i', $end)),
form_info(_("Mode"), ''), form_info(_('Mode'), ''),
form_radio('mode', _("Create one shift"), $mode == 'single', 'single'), form_radio('mode', _('Create one shift'), $mode == 'single', 'single'),
form_radio('mode', _("Create multiple shifts"), $mode == 'multi', 'multi'), form_radio('mode', _('Create multiple shifts'), $mode == 'multi', 'multi'),
form_text('length', _("Length"), ! empty($_REQUEST['length']) ? $_REQUEST['length'] : '120'), form_text('length', _('Length'), $request->has('length') ? $request->input('length') : '120'),
form_radio('mode', _("Create multiple shifts with variable length"), $mode == 'variable', 'variable'), form_radio(
form_text('change_hours', _("Shift change hours"), ! empty($_REQUEST['change_hours']) ? $_REQUEST['change_hours'] : '00, 04, 08, 10, 12, 14, 16, 18, 20, 22') 'mode',
_('Create multiple shifts with variable length'),
$mode == 'variable',
'variable'
),
form_text(
'change_hours',
_('Shift change hours'),
$request->has('change_hours') ? $request->input('input') : '00, 04, 08, 10, 12, 14, 16, 18, 20, 22'
)
]), ]),
div('col-md-6', [ div('col-md-6', [
form_info(_("Needed angels"), ''), form_info(_('Needed angels'), ''),
form_radio('angelmode', _("Take needed angels from room settings"), $angelmode == 'location', 'location'), form_radio(
form_radio('angelmode', _("The following angels are needed"), $angelmode == 'manually', 'manually'), 'angelmode',
_('Take needed angels from room settings'),
$angelmode == 'location',
'location'
),
form_radio('angelmode', _('The following angels are needed'), $angelmode == 'manually', 'manually'),
div('row', [ div('row', [
$angel_types $angel_types
]) ])
]) ])
]), ]),
form_submit('preview', _("Preview")) form_submit('preview', _('Preview'))
]) ])
]); ]);
} }
?>

View File

@ -1,135 +1,215 @@
<?php <?php
function admin_user_title() { use Engelsystem\Database\DB;
return _("All Angels");
/**
* @return string
*/
function admin_user_title()
{
return _('All Angels');
} }
function admin_user() { /**
global $user, $privileges, $tshirt_sizes, $privileges; * @return string
*/
function admin_user()
{
global $user, $privileges;
$tshirt_sizes = config('tshirt_sizes');
$request = request();
foreach ($tshirt_sizes as $key => $size) {
if (empty($size)) {
unset($tshirt_sizes[$key]);
}
}
$html = ''; $html = '';
if (! isset($_REQUEST['id'])) { if (!$request->has('id')) {
redirect(users_link()); redirect(users_link());
} }
$user_id = $_REQUEST['id']; $user_id = $request->input('id');
if (! isset($_REQUEST['action'])) { if (!$request->has('action')) {
$user_source = User($user_id); $user_source = User($user_id);
if ($user_source == null) { if ($user_source == null) {
error(_('This user does not exist.')); error(_('This user does not exist.'));
redirect(users_link()); redirect(users_link());
} }
$html .= "Hallo,<br />" . "hier kannst du den Eintrag &auml;ndern. Unter dem Punkt 'Gekommen' " . "wird der Engel als anwesend markiert, ein Ja bei Aktiv bedeutet, " . "dass der Engel aktiv war und damit ein Anspruch auf ein T-Shirt hat. " . "Wenn T-Shirt ein 'Ja' enth&auml;lt, bedeutet dies, dass der Engel " . "bereits sein T-Shirt erhalten hat.<br /><br />\n"; $html .= 'Hallo,<br />'
. 'hier kannst du den Eintrag &auml;ndern. Unter dem Punkt \'Gekommen\' '
. 'wird der Engel als anwesend markiert, ein Ja bei Aktiv bedeutet, '
. 'dass der Engel aktiv war und damit ein Anspruch auf ein T-Shirt hat. '
. 'Wenn T-Shirt ein \'Ja\' enth&auml;lt, bedeutet dies, dass der Engel '
. 'bereits sein T-Shirt erhalten hat.<br /><br />' . "\n";
$html .= "<form action=\"" . page_link_to("admin_user") . "&action=save&id=$user_id\" method=\"post\">\n"; $html .= '<form action="'
$html .= "<table border=\"0\">\n"; . page_link_to('admin_user', ['action' => 'save', 'id' => $user_id])
$html .= "<input type=\"hidden\" name=\"Type\" value=\"Normal\">\n"; . '" method="post">' . "\n";
$html .= "<tr><td>\n"; $html .= '<table border="0">' . "\n";
$html .= "<table>\n"; $html .= '<input type="hidden" name="Type" value="Normal">' . "\n";
$html .= " <tr><td>Nick</td><td>" . "<input type=\"text\" size=\"40\" name=\"eNick\" value=\"" . $user_source['Nick'] . "\"></td></tr>\n"; $html .= '<tr><td>' . "\n";
$html .= " <tr><td>lastLogIn</td><td>" . date("Y-m-d H:i", $user_source['lastLogIn']) . "</td></tr>\n"; $html .= '<table>' . "\n";
$html .= " <tr><td>Name</td><td>" . "<input type=\"text\" size=\"40\" name=\"eName\" value=\"" . $user_source['Name'] . "\"></td></tr>\n"; $html .= ' <tr><td>Nick</td><td>' . '<input size="40" name="eNick" value="' . $user_source['Nick'] . '" class="form-control"></td></tr>' . "\n";
$html .= " <tr><td>Vorname</td><td>" . "<input type=\"text\" size=\"40\" name=\"eVorname\" value=\"" . $user_source['Vorname'] . "\"></td></tr>\n"; $html .= ' <tr><td>Last login</td><td><p class="help-block">'
$html .= " <tr><td>Alter</td><td>" . "<input type=\"text\" size=\"5\" name=\"eAlter\" value=\"" . $user_source['Alter'] . "\"></td></tr>\n"; . date('Y-m-d H:i', $user_source['lastLogIn'])
$html .= " <tr><td>Telefon</td><td>" . "<input type=\"text\" size=\"40\" name=\"eTelefon\" value=\"" . $user_source['Telefon'] . "\"></td></tr>\n"; . '</p></td></tr>' . "\n";
$html .= " <tr><td>Handy</td><td>" . "<input type=\"text\" size=\"40\" name=\"eHandy\" value=\"" . $user_source['Handy'] . "\"></td></tr>\n"; $html .= ' <tr><td>Name</td><td>' . '<input size="40" name="eName" value="' . $user_source['Name'] . '" class="form-control"></td></tr>' . "\n";
$html .= " <tr><td>DECT</td><td>" . "<input type=\"text\" size=\"4\" name=\"eDECT\" value=\"" . $user_source['DECT'] . "\"></td></tr>\n"; $html .= ' <tr><td>Vorname</td><td>' . '<input size="40" name="eVorname" value="' . $user_source['Vorname'] . '" class="form-control"></td></tr>' . "\n";
$html .= ' <tr><td>Alter</td><td>' . '<input size="5" name="eAlter" value="' . $user_source['Alter'] . '" class="form-control"></td></tr>' . "\n";
$html .= ' <tr><td>Telefon</td><td>' . '<input size="40" name="eTelefon" value="' . $user_source['Telefon'] . '" class="form-control"></td></tr>' . "\n";
$html .= ' <tr><td>Handy</td><td>' . '<input size="40" name="eHandy" value="' . $user_source['Handy'] . '" class="form-control"></td></tr>' . "\n";
$html .= ' <tr><td>DECT</td><td>' . '<input size="4" name="eDECT" value="' . $user_source['DECT'] . '" class="form-control"></td></tr>' . "\n";
if ($user_source['email_by_human_allowed']) { if ($user_source['email_by_human_allowed']) {
$html .= " <tr><td>email</td><td>" . "<input type=\"text\" size=\"40\" name=\"eemail\" value=\"" . $user_source['email'] . "\"></td></tr>\n"; $html .= " <tr><td>email</td><td>" . '<input size="40" name="eemail" value="' . $user_source['email'] . '" class="form-control"></td></tr>' . "\n";
} }
$html .= " <tr><td>jabber</td><td>" . "<input type=\"text\" size=\"40\" name=\"ejabber\" value=\"" . $user_source['jabber'] . "\"></td></tr>\n"; $html .= " <tr><td>jabber</td><td>" . '<input size="40" name="ejabber" value="' . $user_source['jabber'] . '" class="form-control"></td></tr>' . "\n";
$html .= " <tr><td>Size</td><td>" . html_select_key('size', 'eSize', $tshirt_sizes, $user_source['Size']) . "</td></tr>\n"; $html .= ' <tr><td>Size</td><td>'
. html_select_key('size', 'eSize', $tshirt_sizes, $user_source['Size']) . '</td></tr>' . "\n";
$options = [ $options = [
'1' => _("Yes"), '1' => _('Yes'),
'0' => _("No") '0' => _('No')
]; ];
// Gekommen? // Gekommen?
$html .= " <tr><td>Gekommen</td><td>\n"; $html .= ' <tr><td>Gekommen</td><td>' . "\n";
$html .= html_options('eGekommen', $options, $user_source['Gekommen']) . "</td></tr>\n"; $html .= html_options('eGekommen', $options, $user_source['Gekommen']) . '</td></tr>' . "\n";
// Aktiv? // Aktiv?
$html .= " <tr><td>Aktiv</td><td>\n"; $html .= ' <tr><td>Aktiv</td><td>' . "\n";
$html .= html_options('eAktiv', $options, $user_source['Aktiv']) . "</td></tr>\n"; $html .= html_options('eAktiv', $options, $user_source['Aktiv']) . '</td></tr>' . "\n";
// Aktiv erzwingen // Aktiv erzwingen
if (in_array('admin_active', $privileges)) { if (in_array('admin_active', $privileges)) {
$html .= " <tr><td>" . _("Force active") . "</td><td>\n"; $html .= ' <tr><td>' . _('Force active') . '</td><td>' . "\n";
$html .= html_options('force_active', $options, $user_source['force_active']) . "</td></tr>\n"; $html .= html_options('force_active', $options, $user_source['force_active']) . '</td></tr>' . "\n";
} }
// T-Shirt bekommen? // T-Shirt bekommen?
$html .= " <tr><td>T-Shirt</td><td>\n"; $html .= ' <tr><td>T-Shirt</td><td>' . "\n";
$html .= html_options('eTshirt', $options, $user_source['Tshirt']) . "</td></tr>\n"; $html .= html_options('eTshirt', $options, $user_source['Tshirt']) . '</td></tr>' . "\n";
$html .= " <tr><td>Hometown</td><td>" . "<input type=\"text\" size=\"40\" name=\"Hometown\" value=\"" . $user_source['Hometown'] . "\"></td></tr>\n"; $html .= ' <tr><td>Hometown</td><td>' . '<input size="40" name="Hometown" value="' . $user_source['Hometown'] . '" class="form-control"></td></tr>' . "\n";
$html .= "</table>\n</td><td valign=\"top\"></td></tr>"; $html .= '</table>' . "\n" . '</td><td valign="top"></td></tr>';
$html .= "</td></tr>\n"; $html .= '</td></tr>' . "\n";
$html .= "</table>\n<br />\n"; $html .= '</table>' . "\n" . '<br />' . "\n";
$html .= "<input type=\"submit\" value=\"Speichern\">\n"; $html .= '<input type="submit" value="Speichern" class="btn btn-primary">';
$html .= "</form>"; $html .= '</form>';
$html .= "<hr />"; $html .= '<hr />';
$html .= form_info('', _('Please visit the angeltypes page or the users profile to manage users angeltypes.')); $html .= form_info('', _('Please visit the angeltypes page or the users profile to manage users angeltypes.'));
$html .= "Hier kannst Du das Passwort dieses Engels neu setzen:<form action=\"" . page_link_to("admin_user") . "&action=change_pw&id=$user_id\" method=\"post\">\n"; $html .= 'Hier kannst Du das Passwort dieses Engels neu setzen:<form action="'
$html .= "<table>\n"; . page_link_to('admin_user', ['action' => 'change_pw', 'id' => $user_id])
$html .= " <tr><td>Passwort</td><td>" . "<input type=\"password\" size=\"40\" name=\"new_pw\" value=\"\"></td></tr>\n"; . '" method="post">' . "\n";
$html .= " <tr><td>Wiederholung</td><td>" . "<input type=\"password\" size=\"40\" name=\"new_pw2\" value=\"\"></td></tr>\n"; $html .= '<table>' . "\n";
$html .= ' <tr><td>Passwort</td><td>' . '<input type="password" size="40" name="new_pw" value="" class="form-control"></td></tr>' . "\n";
$html .= ' <tr><td>Wiederholung</td><td>' . '<input type="password" size="40" name="new_pw2" value="" class="form-control"></td></tr>' . "\n";
$html .= "</table>"; $html .= '</table>' . "\n" . '<br />' . "\n";
$html .= "<input type=\"submit\" value=\"Speichern\">\n"; $html .= '<input type="submit" value="Speichern" class="btn btn-primary">' . "\n";
$html .= "</form>"; $html .= '</form>';
$html .= "<hr />"; $html .= '<hr />';
$my_highest_group = sql_select("SELECT * FROM `UserGroups` WHERE `uid`='" . sql_escape($user['UID']) . "' ORDER BY `group_id` LIMIT 1"); $my_highest_group = DB::selectOne(
if (count($my_highest_group) > 0) { 'SELECT group_id FROM `UserGroups` WHERE `uid`=? ORDER BY `group_id` LIMIT 1',
$my_highest_group = $my_highest_group[0]['group_id']; [$user['UID']]
);
if (!empty($my_highest_group)) {
$my_highest_group = $my_highest_group['group_id'];
} }
$his_highest_group = sql_select("SELECT * FROM `UserGroups` WHERE `uid`='" . sql_escape($user_id) . "' ORDER BY `group_id` LIMIT 1"); $his_highest_group = DB::selectOne(
if (count($his_highest_group) > 0) { 'SELECT `group_id` FROM `UserGroups` WHERE `uid`=? ORDER BY `group_id` LIMIT 1',
$his_highest_group = $his_highest_group[0]['group_id']; [$user_id]
);
if (!empty($his_highest_group)) {
$his_highest_group = $his_highest_group['group_id'];
} }
if ($user_id != $user['UID'] && $my_highest_group <= $his_highest_group) { if ($user_id != $user['UID'] && $my_highest_group <= $his_highest_group) {
$html .= "Hier kannst Du die Benutzergruppen des Engels festlegen:<form action=\"" . page_link_to("admin_user") . "&action=save_groups&id=" . $user_id . "\" method=\"post\">\n"; $html .= 'Hier kannst Du die Benutzergruppen des Engels festlegen:<form action="'
. page_link_to('admin_user', ['action' => 'save_groups', 'id' => $user_id])
. '" method="post">' . "\n";
$html .= '<table>'; $html .= '<table>';
$groups = sql_select("SELECT * FROM `Groups` LEFT OUTER JOIN `UserGroups` ON (`UserGroups`.`group_id` = `Groups`.`UID` AND `UserGroups`.`uid` = '" . sql_escape($user_id) . "') WHERE `Groups`.`UID` >= '" . sql_escape($my_highest_group) . "' ORDER BY `Groups`.`Name`"); $groups = DB::select('
SELECT *
FROM `Groups`
LEFT OUTER JOIN `UserGroups` ON (
`UserGroups`.`group_id` = `Groups`.`UID`
AND `UserGroups`.`uid` = ?
)
WHERE `Groups`.`UID` >= ?
ORDER BY `Groups`.`Name`
',
[
$user_id,
$my_highest_group,
]
);
foreach ($groups as $group) { foreach ($groups as $group) {
$html .= '<tr><td><input type="checkbox" name="groups[]" value="' . $group['UID'] . '"' . ($group['group_id'] != "" ? ' checked="checked"' : '') . ' /></td><td>' . $group['Name'] . '</td></tr>'; $html .= '<tr><td><input type="checkbox" name="groups[]" value="' . $group['UID'] . '" '
. ($group['group_id'] != '' ? ' checked="checked"' : '')
. ' /></td><td>' . $group['Name'] . '</td></tr>';
} }
$html .= '</table>'; $html .= '</table><br>';
$html .= "<input type=\"submit\" value=\"Speichern\">\n"; $html .= '<input type="submit" value="Speichern" class="btn btn-primary">' . "\n";
$html .= "</form>"; $html .= '</form>';
$html .= "<hr />"; $html .= '<hr />';
} }
$html .= buttons([ $html .= buttons([
button(user_delete_link($user_source), glyph('lock') . _("delete"), 'btn-danger') button(user_delete_link($user_source), glyph('lock') . _('delete'), 'btn-danger')
]); ]);
$html .= "<hr />"; $html .= "<hr />";
} else { } else {
switch ($_REQUEST['action']) { switch ($request->input('action')) {
case 'save_groups': case 'save_groups':
if ($user_id != $user['UID']) { if ($user_id != $user['UID']) {
$my_highest_group = sql_select("SELECT * FROM `UserGroups` WHERE `uid`='" . sql_escape($user['UID']) . "' ORDER BY `group_id`"); $my_highest_group = DB::selectOne(
$his_highest_group = sql_select("SELECT * FROM `UserGroups` WHERE `uid`='" . sql_escape($user_id) . "' ORDER BY `group_id`"); 'SELECT * FROM `UserGroups` WHERE `uid`=? ORDER BY `group_id`',
[$user['UID']]
);
$his_highest_group = DB::selectOne(
'SELECT * FROM `UserGroups` WHERE `uid`=? ORDER BY `group_id`',
[$user_id]
);
if (count($my_highest_group) > 0 && (count($his_highest_group) == 0 || ($my_highest_group[0]['group_id'] <= $his_highest_group[0]['group_id']))) { if (
$groups_source = sql_select("SELECT * FROM `Groups` LEFT OUTER JOIN `UserGroups` ON (`UserGroups`.`group_id` = `Groups`.`UID` AND `UserGroups`.`uid` = '" . sql_escape($user_id) . "') WHERE `Groups`.`UID` >= '" . sql_escape($my_highest_group[0]['group_id']) . "' ORDER BY `Groups`.`Name`"); count($my_highest_group) > 0
&& (
count($his_highest_group) == 0
|| ($my_highest_group['group_id'] <= $his_highest_group['group_id'])
)
) {
$groups_source = DB::select('
SELECT *
FROM `Groups`
LEFT OUTER JOIN `UserGroups` ON (
`UserGroups`.`group_id` = `Groups`.`UID`
AND `UserGroups`.`uid` = ?
)
WHERE `Groups`.`UID` >= ?
ORDER BY `Groups`.`Name`
',
[
$user_id,
$my_highest_group['group_id'],
]
);
$groups = []; $groups = [];
$grouplist = []; $grouplist = [];
foreach ($groups_source as $group) { foreach ($groups_source as $group) {
@ -137,72 +217,100 @@ function admin_user() {
$grouplist[] = $group['UID']; $grouplist[] = $group['UID'];
} }
if (! is_array($_REQUEST['groups'])) { $groupsRequest = $request->input('groups');
$_REQUEST['groups'] = []; if (!is_array($groupsRequest)) {
$groupsRequest = [];
} }
sql_query("DELETE FROM `UserGroups` WHERE `uid`='" . sql_escape($user_id) . "'"); DB::delete('DELETE FROM `UserGroups` WHERE `uid`=?', [$user_id]);
$user_groups_info = []; $user_groups_info = [];
foreach ($_REQUEST['groups'] as $group) { foreach ($groupsRequest as $group) {
if (in_array($group, $grouplist)) { if (in_array($group, $grouplist)) {
sql_query("INSERT INTO `UserGroups` SET `uid`='" . sql_escape($user_id) . "', `group_id`='" . sql_escape($group) . "'"); DB::insert(
'INSERT INTO `UserGroups` (`uid`, `group_id`) VALUES (?, ?)',
[$user_id, $group]
);
$user_groups_info[] = $groups[$group]['Name']; $user_groups_info[] = $groups[$group]['Name'];
} }
} }
$user_source = User($user_id); $user_source = User($user_id);
engelsystem_log("Set groups of " . User_Nick_render($user_source) . " to: " . join(", ", $user_groups_info)); engelsystem_log(
$html .= success("Benutzergruppen gespeichert.", true); 'Set groups of ' . User_Nick_render($user_source) . ' to: ' . join(', ', $user_groups_info)
);
$html .= success('Benutzergruppen gespeichert.', true);
} else { } else {
$html .= error("Du kannst keine Engel mit mehr Rechten bearbeiten.", true); $html .= error('Du kannst keine Engel mit mehr Rechten bearbeiten.', true);
} }
} else { } else {
$html .= error("Du kannst Deine eigenen Rechte nicht bearbeiten.", true); $html .= error('Du kannst Deine eigenen Rechte nicht bearbeiten.', true);
} }
break; break;
case 'save': case 'save':
$force_active = $user['force_active']; $force_active = $user['force_active'];
$user_source = User($user_id);
if (in_array('admin_active', $privileges)) { if (in_array('admin_active', $privileges)) {
$force_active = $_REQUEST['force_active']; $force_active = $request->input('force_active');
} }
$SQL = "UPDATE `User` SET $sql = '
`Nick` = '" . sql_escape($_POST["eNick"]) . "', UPDATE `User` SET
`Name` = '" . sql_escape($_POST["eName"]) . "', `Nick` = ?,
`Vorname` = '" . sql_escape($_POST["eVorname"]) . "', `Name` = ?,
`Telefon` = '" . sql_escape($_POST["eTelefon"]) . "', `Vorname` = ?,
`Handy` = '" . sql_escape($_POST["eHandy"]) . "', `Telefon` = ?,
`Alter` = '" . sql_escape($_POST["eAlter"]) . "', `Handy` = ?,
`DECT` = '" . sql_escape($_POST["eDECT"]) . "', `Alter` =?,
" . ($user_source['email_by_human_allowed'] ? "`email` = '" . sql_escape($_POST["eemail"]) . "'" : "") . " `DECT` = ?,
`jabber` = '" . sql_escape($_POST["ejabber"]) . "', ' . ($user_source['email_by_human_allowed'] ? '`email` = ' . DB::getPdo()->quote($request->postData('eemail')) . ',' : '') . '
`Size` = '" . sql_escape($_POST["eSize"]) . "', `jabber` = ?,
`Gekommen`= '" . sql_escape($_POST["eGekommen"]) . "', `Size` = ?,
`Aktiv`= '" . sql_escape($_POST["eAktiv"]) . "', `Gekommen`= ?,
`force_active`= " . sql_escape($force_active) . ", `Aktiv`= ?,
`Tshirt` = '" . sql_escape($_POST["eTshirt"]) . "', `force_active`= ?,
`Hometown` = '" . sql_escape($_POST["Hometown"]) . "' `Tshirt` = ?,
WHERE `UID` = '" . sql_escape($user_id) . "' `Hometown` = ?
LIMIT 1"; WHERE `UID` = ?
sql_query($SQL); LIMIT 1';
engelsystem_log("Updated user: " . $_POST["eNick"] . ", " . $_POST["eSize"] . ", arrived: " . $_POST["eGekommen"] . ", active: " . $_POST["eAktiv"] . ", tshirt: " . $_POST["eTshirt"]); DB::update($sql, [
$html .= success("Änderung wurde gespeichert...\n", true); User_validate_Nick($request->postData('eNick')),
$request->postData('eName'),
$request->postData('eVorname'),
$request->postData('eTelefon'),
$request->postData('eHandy'),
$request->postData('eAlter'),
$request->postData('eDECT'),
$request->postData('ejabber'),
$request->postData('eSize'),
$request->postData('eGekommen'),
$request->postData('eAktiv'),
$force_active,
$request->postData('eTshirt'),
$request->postData('Hometown'),
$user_id,
]);
engelsystem_log(
'Updated user: ' . $request->postData('eNick') . ', ' . $request->postData('eSize')
. ', arrived: ' . $request->postData('eVorname')
. ', active: ' . $request->postData('eAktiv')
. ', tshirt: ' . $request->postData('eTshirt')
);
$html .= success('Änderung wurde gespeichert...' . "\n", true);
break; break;
case 'change_pw': case 'change_pw':
if ($_REQUEST['new_pw'] != "" && $_REQUEST['new_pw'] == $_REQUEST['new_pw2']) { if ($request->postData('new_pw') != '' && $request->postData('new_pw') == $request->postData('new_pw2')) {
set_password($user_id, $_REQUEST['new_pw']); set_password($user_id, $request->postData('new_pw'));
$user_source = User($user_id); $user_source = User($user_id);
engelsystem_log("Set new password for " . User_Nick_render($user_source)); engelsystem_log('Set new password for ' . User_Nick_render($user_source));
$html .= success("Passwort neu gesetzt.", true); $html .= success('Passwort neu gesetzt.', true);
} else { } else {
$html .= error("Die Eingaben müssen übereinstimmen und dürfen nicht leer sein!", true); $html .= error('Die Eingaben müssen übereinstimmen und dürfen nicht leer sein!', true);
} }
break; break;
} }
} }
return page_with_title(_("Edit user"), [ return page_with_title(_('Edit user'), [
$html $html
]); ]);
} }
?>

View File

@ -1,9 +1,17 @@
<?php <?php
function credits_title() {
return _("Credits"); /**
* @return string
*/
function credits_title()
{
return _('Credits');
} }
function guest_credits() { /**
return template_render(__DIR__ . '/../../templates/guest_credits.html', []); * @return string
*/
function guest_credits()
{
return view(__DIR__ . '/../../templates/guest_credits.html');
} }
?>

View File

@ -1,192 +1,277 @@
<?php <?php
function login_title() { use Engelsystem\Database\DB;
return _("Login");
/**
* @return string
*/
function login_title()
{
return _('Login');
} }
function register_title() { /**
return _("Register"); * @return string
*/
function register_title()
{
return _('Register');
} }
function logout_title() { /**
return _("Logout"); * @return string
*/
function logout_title()
{
return _('Logout');
} }
// Engel registrieren /**
function guest_register() { * Engel registrieren
global $tshirt_sizes, $enable_tshirt_size, $default_theme, $user, $min_password_length; *
* @return string
*/
function guest_register()
{
global $user, $privileges;
$tshirt_sizes = config('tshirt_sizes');
$enable_tshirt_size = config('enable_tshirt_size');
$min_password_length = config('min_password_length');
$event_config = EventConfig(); $event_config = EventConfig();
$request = request();
$session = session();
$msg = ""; $msg = '';
$nick = ""; $nick = '';
$lastname = ""; $lastName = '';
$prename = ""; $preName = '';
$age = ""; $age = 0;
$tel = ""; $tel = '';
$dect = ""; $dect = '';
$mobile = ""; $mobile = '';
$mail = ""; $mail = '';
$email_shiftinfo = false; $email_shiftinfo = false;
$email_by_human_allowed = false; $email_by_human_allowed = false;
$jabber = ""; $jabber = '';
$hometown = ""; $hometown = '';
$comment = ""; $comment = '';
$tshirt_size = ''; $tshirt_size = '';
$password_hash = ""; $password_hash = '';
$selected_angel_types = []; $selected_angel_types = [];
$planned_arrival_date = null; $planned_arrival_date = null;
$angel_types_source = AngelTypes(); $angel_types_source = AngelTypes();
$angel_types = []; $angel_types = [];
foreach ($angel_types_source as $angel_type) { foreach ($angel_types_source as $angel_type) {
$angel_types[$angel_type['id']] = $angel_type['name'] . ($angel_type['restricted'] ? " (restricted)" : ""); $angel_types[$angel_type['id']] = $angel_type['name'] . ($angel_type['restricted'] ? ' (restricted)' : '');
if (! $angel_type['restricted']) { if (!$angel_type['restricted']) {
$selected_angel_types[] = $angel_type['id']; $selected_angel_types[] = $angel_type['id'];
} }
} }
if (isset($_REQUEST['submit'])) { foreach ($tshirt_sizes as $key => $size) {
if (empty($size)) {
unset($tshirt_sizes[$key]);
}
}
if (!in_array('register', $privileges) || (!isset($user) && !config('registration_enabled'))) {
error(_('Registration is disabled.'));
return page_with_title(register_title(), [
msg(),
]);
}
if ($request->has('submit')) {
$valid = true; $valid = true;
if (isset($_REQUEST['nick']) && strlen(User_validate_Nick($_REQUEST['nick'])) > 1) { if ($request->has('nick') && strlen(User_validate_Nick($request->input('nick'))) > 1) {
$nick = User_validate_Nick($_REQUEST['nick']); $nick = User_validate_Nick($request->input('nick'));
if (sql_num_query("SELECT * FROM `User` WHERE `Nick`='" . sql_escape($nick) . "' LIMIT 1") > 0) { if (count(DB::select('SELECT `UID` FROM `User` WHERE `Nick`=? LIMIT 1', [$nick])) > 0) {
$valid = false; $valid = false;
$msg .= error(sprintf(_("Your nick &quot;%s&quot; already exists."), $nick), true); $msg .= error(sprintf(_('Your nick &quot;%s&quot; already exists.'), $nick), true);
} }
} else { } else {
$valid = false; $valid = false;
$msg .= error(sprintf(_("Your nick &quot;%s&quot; is too short (min. 2 characters)."), User_validate_Nick($_REQUEST['nick'])), true); $msg .= error(sprintf(
_('Your nick &quot;%s&quot; is too short (min. 2 characters).'),
User_validate_Nick($request->input('nick'))
), true);
} }
if (isset($_REQUEST['mail']) && strlen(strip_request_item('mail')) > 0) { if ($request->has('mail') && strlen(strip_request_item('mail')) > 0) {
$mail = strip_request_item('mail'); $mail = strip_request_item('mail');
if (! check_email($mail)) { if (!check_email($mail)) {
$valid = false; $valid = false;
$msg .= error(_("E-mail address is not correct."), true); $msg .= error(_('E-mail address is not correct.'), true);
} }
} else { } else {
$valid = false; $valid = false;
$msg .= error(_("Please enter your e-mail."), true); $msg .= error(_('Please enter your e-mail.'), true);
} }
if (isset($_REQUEST['email_shiftinfo'])) { if ($request->has('email_shiftinfo')) {
$email_shiftinfo = true; $email_shiftinfo = true;
} }
if (isset($_REQUEST['email_by_human_allowed'])) { if ($request->has('email_by_human_allowed')) {
$email_by_human_allowed = true; $email_by_human_allowed = true;
} }
if (isset($_REQUEST['jabber']) && strlen(strip_request_item('jabber')) > 0) { if ($request->has('jabber') && strlen(strip_request_item('jabber')) > 0) {
$jabber = strip_request_item('jabber'); $jabber = strip_request_item('jabber');
if (! check_email($jabber)) { if (!check_email($jabber)) {
$valid = false; $valid = false;
$msg .= error(_("Please check your jabber account information."), true); $msg .= error(_('Please check your jabber account information.'), true);
} }
} }
if ($enable_tshirt_size) { if ($enable_tshirt_size) {
if (isset($_REQUEST['tshirt_size']) && isset($tshirt_sizes[$_REQUEST['tshirt_size']]) && $_REQUEST['tshirt_size'] != '') { if ($request->has('tshirt_size') && isset($tshirt_sizes[$request->input('tshirt_size')])) {
$tshirt_size = $_REQUEST['tshirt_size']; $tshirt_size = $request->input('tshirt_size');
} else { } else {
$valid = false; $valid = false;
$msg .= error(_("Please select your shirt size."), true); $msg .= error(_('Please select your shirt size.'), true);
} }
} }
if (isset($_REQUEST['password']) && strlen($_REQUEST['password']) >= $min_password_length) { if ($request->has('password') && strlen($request->postData('password')) >= $min_password_length) {
if ($_REQUEST['password'] != $_REQUEST['password2']) { if ($request->postData('password') != $request->postData('password2')) {
$valid = false; $valid = false;
$msg .= error(_("Your passwords don't match."), true); $msg .= error(_('Your passwords don\'t match.'), true);
} }
} else { } else {
$valid = false; $valid = false;
$msg .= error(sprintf(_("Your password is too short (please use at least %s characters)."), $min_password_length), true); $msg .= error(sprintf(
_('Your password is too short (please use at least %s characters).'),
$min_password_length
), true);
} }
if (isset($_REQUEST['planned_arrival_date'])) { if ($request->has('planned_arrival_date')) {
$tmp = parse_date("Y-m-d H:i", $_REQUEST['planned_arrival_date'] . " 00:00"); $tmp = parse_date('Y-m-d H:i', $request->input('planned_arrival_date') . ' 00:00');
$result = User_validate_planned_arrival_date($tmp); $result = User_validate_planned_arrival_date($tmp);
$planned_arrival_date = $result->getValue(); $planned_arrival_date = $result->getValue();
if (! $result->isValid()) { if (!$result->isValid()) {
$valid = false; $valid = false;
error(_("Please enter your planned date of arrival. It should be after the buildup start date and before teardown end date.")); error(_('Please enter your planned date of arrival. It should be after the buildup start date and before teardown end date.'));
} }
} else {
$valid = false;
error(_('Please enter your planned date of arrival. It should be after the buildup start date and before teardown end date.'));
} }
$selected_angel_types = []; $selected_angel_types = [];
foreach (array_keys($angel_types) as $angel_type_id) { foreach (array_keys($angel_types) as $angel_type_id) {
if (isset($_REQUEST['angel_types_' . $angel_type_id])) { if ($request->has('angel_types_' . $angel_type_id)) {
$selected_angel_types[] = $angel_type_id; $selected_angel_types[] = $angel_type_id;
} }
} }
// Trivia // Trivia
if (isset($_REQUEST['lastname'])) { if ($request->has('lastname')) {
$lastname = strip_request_item('lastname'); $lastName = strip_request_item('lastname');
} }
if (isset($_REQUEST['prename'])) { if ($request->has('prename')) {
$prename = strip_request_item('prename'); $preName = strip_request_item('prename');
} }
if (isset($_REQUEST['age']) && preg_match("/^[0-9]{0,4}$/", $_REQUEST['age'])) { if ($request->has('age') && preg_match('/^\d{0,4}$/', $request->input('age'))) {
$age = strip_request_item('age'); $age = strip_request_item('age');
} }
if (isset($_REQUEST['tel'])) { if ($request->has('tel')) {
$tel = strip_request_item('tel'); $tel = strip_request_item('tel');
} }
if (isset($_REQUEST['dect'])) { if ($request->has('dect')) {
if(strlen(strip_request_item('dect')) <= 5) {
$dect = strip_request_item('dect'); $dect = strip_request_item('dect');
} else {
$valid = false;
error(_('For dect numbers are only 5 digits allowed.'));
} }
if (isset($_REQUEST['mobile'])) { }
if ($request->has('mobile')) {
$mobile = strip_request_item('mobile'); $mobile = strip_request_item('mobile');
} }
if (isset($_REQUEST['hometown'])) { if ($request->has('hometown')) {
$hometown = strip_request_item('hometown'); $hometown = strip_request_item('hometown');
} }
if (isset($_REQUEST['comment'])) { if ($request->has('comment')) {
$comment = strip_request_item_nl('comment'); $comment = strip_request_item_nl('comment');
} }
if ($valid) { if ($valid) {
sql_query(" DB::insert('
INSERT INTO `User` SET INSERT INTO `User` (
`color`='" . sql_escape($default_theme) . "', `color`,
`Nick`='" . sql_escape($nick) . "', `Nick`,
`Vorname`='" . sql_escape($prename) . "', `Vorname`,
`Name`='" . sql_escape($lastname) . "', `Name`,
`Alter`='" . sql_escape($age) . "', `Alter`,
`Telefon`='" . sql_escape($tel) . "', `Telefon`,
`DECT`='" . sql_escape($dect) . "', `DECT`,
`Handy`='" . sql_escape($mobile) . "', `Handy`,
`email`='" . sql_escape($mail) . "', `email`,
`email_shiftinfo`=" . sql_bool($email_shiftinfo) . ", `email_shiftinfo`,
`email_by_human_allowed`=" . sql_bool($email_by_human_allowed) . ", `email_by_human_allowed`,
`jabber`='" . sql_escape($jabber) . "', `jabber`,
`Size`='" . sql_escape($tshirt_size) . "', `Size`,
`Passwort`='" . sql_escape($password_hash) . "', `Passwort`,
`kommentar`='" . sql_escape($comment) . "', `kommentar`,
`Hometown`='" . sql_escape($hometown) . "', `Hometown`,
`CreateDate`=NOW(), `CreateDate`,
`Sprache`='" . sql_escape($_SESSION["locale"]) . "', `Sprache`,
`arrival_date`=NULL, `arrival_date`,
`planned_arrival_date`='" . sql_escape($planned_arrival_date) . "'"); `planned_arrival_date`,
`force_active`,
`lastLogIn`,
`api_key`,
`got_voucher`
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), ?, NULL, ?, FALSE, 0, "", 0)
',
[
config('theme'),
$nick,
$preName,
$lastName,
$age,
$tel,
$dect,
$mobile,
$mail,
(int)$email_shiftinfo,
(int)$email_by_human_allowed,
$jabber,
$tshirt_size,
$password_hash,
$comment,
$hometown,
$session->get('locale'),
$planned_arrival_date,
]
);
// Assign user-group and set password // Assign user-group and set password
$user_id = sql_id(); $user_id = DB::getPdo()->lastInsertId();
sql_query("INSERT INTO `UserGroups` SET `uid`='" . sql_escape($user_id) . "', `group_id`=-2"); DB::insert('INSERT INTO `UserGroups` (`uid`, `group_id`) VALUES (?, -20)', [$user_id]);
set_password($user_id, $_REQUEST['password']); set_password($user_id, $request->postData('password'));
// Assign angel-types // Assign angel-types
$user_angel_types_info = []; $user_angel_types_info = [];
foreach ($selected_angel_types as $selected_angel_type_id) { foreach ($selected_angel_types as $selected_angel_type_id) {
sql_query("INSERT INTO `UserAngelTypes` SET `user_id`='" . sql_escape($user_id) . "', `angeltype_id`='" . sql_escape($selected_angel_type_id) . "'"); DB::insert(
'INSERT INTO `UserAngelTypes` (`user_id`, `angeltype_id`, `supporter`) VALUES (?, ?, FALSE)',
[$user_id, $selected_angel_type_id]
);
$user_angel_types_info[] = $angel_types[$selected_angel_type_id]; $user_angel_types_info[] = $angel_types[$selected_angel_type_id];
} }
engelsystem_log("User " . User_Nick_render(User($user_id)) . " signed up as: " . join(", ", $user_angel_types_info)); engelsystem_log(
success(_("Angel registration successful!")); 'User ' . User_Nick_render(User($user_id))
. ' signed up as: ' . join(', ', $user_angel_types_info)
);
success(_('Angel registration successful!'));
// User is already logged in - that means a supporter has registered an angel. Return to register page. // User is already logged in - that means a supporter has registered an angel. Return to register page.
if (isset($user)) { if (isset($user)) {
@ -198,7 +283,7 @@ function guest_register() {
return User_registration_success_view($event_config['event_welcome_msg']); return User_registration_success_view($event_config['event_welcome_msg']);
} }
redirect('?'); redirect(page_link_to('/'));
} }
} }
@ -208,13 +293,13 @@ function guest_register() {
if (isset($event_config['buildup_start_date'])) { if (isset($event_config['buildup_start_date'])) {
$buildup_start_date = $event_config['buildup_start_date']; $buildup_start_date = $event_config['buildup_start_date'];
} }
if(isset($event_config['teardown_end_date'])) { if (isset($event_config['teardown_end_date'])) {
$teardown_end_date = $event_config['teardown_end_date']; $teardown_end_date = $event_config['teardown_end_date'];
} }
} }
return page_with_title(register_title(), [ return page_with_title(register_title(), [
_("By completing this form you're registering as a Chaos-Angel. This script will create you an account in the angel task scheduler."), _('By completing this form you\'re registering as a Chaos-Angel. This script will create you an account in the angel task scheduler.'),
$msg, $msg,
msg(), msg(),
form([ form([
@ -222,114 +307,153 @@ function guest_register() {
div('col-md-6', [ div('col-md-6', [
div('row', [ div('row', [
div('col-sm-4', [ div('col-sm-4', [
form_text('nick', _("Nick") . ' ' . entry_required(), $nick) form_text('nick', _('Nick') . ' ' . entry_required(), $nick)
]), ]),
div('col-sm-8', [ div('col-sm-8', [
form_email('mail', _("E-Mail") . ' ' . entry_required(), $mail), form_email('mail', _('E-Mail') . ' ' . entry_required(), $mail),
form_checkbox('email_shiftinfo', _("The engelsystem is allowed to send me an email (e.g. when my shifts change)"), $email_shiftinfo), form_checkbox(
form_checkbox('email_by_human_allowed', _("Humans are allowed to send me an email (e.g. for ticket vouchers)"), $email_by_human_allowed) 'email_shiftinfo',
_('The engelsystem is allowed to send me an email (e.g. when my shifts change)'),
$email_shiftinfo
),
form_checkbox(
'email_by_human_allowed',
_('Humans are allowed to send me an email (e.g. for ticket vouchers)'),
$email_by_human_allowed
)
]) ])
]), ]),
div('row', [ div('row', [
div('col-sm-6', [ div('col-sm-6', [
form_date('planned_arrival_date', _("Planned date of arrival") . ' ' . entry_required(), $planned_arrival_date, $buildup_start_date, $teardown_end_date) form_date(
'planned_arrival_date',
_('Planned date of arrival') . ' ' . entry_required(),
$planned_arrival_date, $buildup_start_date, $teardown_end_date
)
]), ]),
div('col-sm-6', [ div('col-sm-6', [
$enable_tshirt_size ? form_select('tshirt_size', _("Shirt size") . ' ' . entry_required(), $tshirt_sizes, $tshirt_size) : '' $enable_tshirt_size ? form_select('tshirt_size',
_('Shirt size') . ' ' . entry_required(),
$tshirt_sizes, $tshirt_size) : ''
]) ])
]), ]),
div('row', [ div('row', [
div('col-sm-6', [ div('col-sm-6', [
form_password('password', _("Password") . ' ' . entry_required()) form_password('password', _('Password') . ' ' . entry_required())
]), ]),
div('col-sm-6', [ div('col-sm-6', [
form_password('password2', _("Confirm password") . ' ' . entry_required()) form_password('password2', _('Confirm password') . ' ' . entry_required())
]) ])
]), ]),
form_checkboxes('angel_types', _("What do you want to do?") . sprintf(" (<a href=\"%s\">%s</a>)", page_link_to('angeltypes') . '&action=about', _("Description of job types")), $angel_types, $selected_angel_types), form_checkboxes(
form_info("", _("Restricted angel types need will be confirmed later by a supporter. You can change your selection in the options section.")) 'angel_types',
_('What do you want to do?') . sprintf(
' (<a href="%s">%s</a>)',
page_link_to('angeltypes', ['action' => 'about']),
_('Description of job types')
),
$angel_types,
$selected_angel_types
),
form_info(
'',
_('Restricted angel types need will be confirmed later by a supporter. You can change your selection in the options section.')
)
]), ]),
div('col-md-6', [ div('col-md-6', [
div('row', [ div('row', [
div('col-sm-4', [ div('col-sm-4', [
form_text('dect', _("DECT"), $dect) form_text('dect', _('DECT'), $dect)
]), ]),
div('col-sm-4', [ div('col-sm-4', [
form_text('mobile', _("Mobile"), $mobile) form_text('mobile', _('Mobile'), $mobile)
]), ]),
div('col-sm-4', [ div('col-sm-4', [
form_text('tel', _("Phone"), $tel) form_text('tel', _('Phone'), $tel)
]) ])
]), ]),
form_text('jabber', _("Jabber"), $jabber), form_text('jabber', _('Jabber'), $jabber),
div('row', [ div('row', [
div('col-sm-6', [ div('col-sm-6', [
form_text('prename', _("First name"), $prename) form_text('prename', _('First name'), $preName)
]), ]),
div('col-sm-6', [ div('col-sm-6', [
form_text('lastname', _("Last name"), $lastname) form_text('lastname', _('Last name'), $lastName)
]) ])
]), ]),
div('row', [ div('row', [
div('col-sm-3', [ div('col-sm-3', [
form_text('age', _("Age"), $age) form_text('age', _('Age'), $age)
]), ]),
div('col-sm-9', [ div('col-sm-9', [
form_text('hometown', _("Hometown"), $hometown) form_text('hometown', _('Hometown'), $hometown)
]) ])
]), ]),
form_info(entry_required() . ' = ' . _("Entry required!")) form_info(entry_required() . ' = ' . _('Entry required!'))
]) ])
]), ]),
// form_textarea('comment', _("Did you help at former CCC events and which tasks have you performed then?"), $comment), // form_textarea('comment', _('Did you help at former CCC events and which tasks have you performed then?'), $comment),
form_submit('submit', _("Register")) form_submit('submit', _('Register'))
]) ])
]); ]);
} }
function entry_required() { /**
* @return string
*/
function entry_required()
{
return '<span class="text-info glyphicon glyphicon-warning-sign"></span>'; return '<span class="text-info glyphicon glyphicon-warning-sign"></span>';
} }
function guest_logout() { /**
session_destroy(); * @return bool
redirect(page_link_to("start")); */
function guest_logout()
{
session()->invalidate();
redirect(page_link_to('start'));
return true;
} }
function guest_login() { /**
$nick = ""; * @return string
*/
unset($_SESSION['uid']); function guest_login()
{
$nick = '';
$request = request();
$session = session();
$valid = true; $valid = true;
if (isset($_REQUEST['submit'])) { $session->remove('uid');
if (isset($_REQUEST['nick']) && strlen(User_validate_Nick($_REQUEST['nick'])) > 0) { if ($request->has('submit')) {
$nick = User_validate_Nick($_REQUEST['nick']); if ($request->has('nick') && strlen(User_validate_Nick($request->input('nick'))) > 0) {
$login_user = sql_select("SELECT * FROM `User` WHERE `Nick`='" . sql_escape($nick) . "'"); $nick = User_validate_Nick($request->input('nick'));
if (count($login_user) > 0) { $login_user = DB::selectOne('SELECT * FROM `User` WHERE `Nick`=?', [$nick]);
$login_user = $login_user[0]; if (!empty($login_user)) {
if (isset($_REQUEST['password'])) { if ($request->has('password')) {
if (! verify_password($_REQUEST['password'], $login_user['Passwort'], $login_user['UID'])) { if (!verify_password($request->postData('password'), $login_user['Passwort'], $login_user['UID'])) {
$valid = false; $valid = false;
error(_("Your password is incorrect. Please try it again.")); error(_('Your password is incorrect. Please try it again.'));
} }
} else { } else {
$valid = false; $valid = false;
error(_("Please enter a password.")); error(_('Please enter a password.'));
} }
} else { } else {
$valid = false; $valid = false;
error(_("No user was found with that Nickname. Please try again. If you are still having problems, ask a Dispatcher.")); error(_('No user was found with that Nickname. Please try again. If you are still having problems, ask a Dispatcher.'));
} }
} else { } else {
$valid = false; $valid = false;
error(_("Please enter a nickname.")); error(_('Please enter a nickname.'));
} }
if ($valid) { if ($valid && !empty($login_user)) {
$_SESSION['uid'] = $login_user['UID']; $session->set('uid', $login_user['UID']);
$_SESSION['locale'] = $login_user['Sprache']; $session->set('locale', $login_user['Sprache']);
redirect(page_link_to('news')); redirect(page_link_to('news'));
} }
@ -346,21 +470,21 @@ function guest_login() {
div('col-sm-6 col-sm-offset-3 col-md-4 col-md-offset-4', [ div('col-sm-6 col-sm-offset-3 col-md-4 col-md-offset-4', [
div('panel panel-primary first', [ div('panel panel-primary first', [
div('panel-heading', [ div('panel-heading', [
'<span class="icon-icon_angel"></span> ' . _("Login") '<span class="icon-icon_angel"></span> ' . _('Login')
]), ]),
div('panel-body', [ div('panel-body', [
msg(), msg(),
form([ form([
form_text_placeholder('nick', _("Nick"), $nick), form_text_placeholder('nick', _('Nick'), $nick),
form_password_placeholder('password', _("Password")), form_password_placeholder('password', _('Password')),
form_submit('submit', _("Login")), form_submit('submit', _('Login')),
! $valid ? buttons([ !$valid ? buttons([
button(page_link_to('user_password_recovery'), _("I forgot my password")) button(page_link_to('user_password_recovery'), _('I forgot my password'))
]) : '' ]) : ''
]) ])
]), ]),
div('panel-footer', [ div('panel-footer', [
glyph('info-sign') . _("Please note: You have to activate cookies!") glyph('info-sign') . _('Please note: You have to activate cookies!')
]) ])
]) ])
]) ])
@ -371,10 +495,13 @@ function guest_login() {
get_register_hint() get_register_hint()
]), ]),
div('col-sm-6 text-center', [ div('col-sm-6 text-center', [
heading(_("What can I do?"), 2), heading(_('What can I do?'), 2),
'<p>' . _("Please read about the jobs you can do to help us.") . '</p>', '<p>' . _('Please read about the jobs you can do to help us.') . '</p>',
buttons([ buttons([
button(page_link_to('angeltypes') . '&action=about', _("Teams/Job description") . ' &raquo;') button(
page_link_to('angeltypes', ['action' => 'about']),
_('Teams/Job description') . ' &raquo;'
)
]) ])
]) ])
]) ])
@ -382,19 +509,21 @@ function guest_login() {
]); ]);
} }
function get_register_hint() { /**
* @return string
*/
function get_register_hint()
{
global $privileges; global $privileges;
if (in_array('register', $privileges)) { if (in_array('register', $privileges) && config('registration_enabled')) {
return join('', [ return join('', [
'<p>' . _("Please sign up, if you want to help us!") . '</p>', '<p>' . _('Please sign up, if you want to help us!') . '</p>',
buttons([ buttons([
button(page_link_to('register'), register_title() . ' &raquo;') button(page_link_to('register'), register_title() . ' &raquo;')
]) ])
]); ]);
} }
//FIXME: return error(_("Registration is disabled."), true); return error(_('Registration is disabled.'), true);
return error("Registration is <a href='https://engelsystem.de/33c3/overwhelmed.html'>disabled</a>.", true);
} }
?>

View File

@ -1,5 +1,6 @@
<?php <?php
function guest_start() { function guest_start()
{
redirect(page_link_to('login')); redirect(page_link_to('login'));
return true;
} }
?>

View File

@ -1,35 +1,48 @@
<?php <?php
function guest_stats() { use Engelsystem\Database\DB;
global $api_key;
if (isset($_REQUEST['api_key'])) { function guest_stats()
if ($_REQUEST['api_key'] == $api_key) { {
$apiKey = config('api_key');
$request = request();
if ($request->has('api_key')) {
if (!empty($apiKey) && $request->input('api_key') == $apiKey) {
$stats = []; $stats = [];
list($user_count) = sql_select("SELECT count(*) as `user_count` FROM `User`"); list($user_count) = DB::select('SELECT count(*) AS `user_count` FROM `User`');
$stats['user_count'] = $user_count['user_count']; $stats['user_count'] = $user_count['user_count'];
list($arrived_user_count) = sql_select("SELECT count(*) as `user_count` FROM `User` WHERE `Gekommen`=1"); list($arrived_user_count) = DB::select('SELECT count(*) AS `user_count` FROM `User` WHERE `Gekommen`=1');
$stats['arrived_user_count'] = $arrived_user_count['user_count']; $stats['arrived_user_count'] = $arrived_user_count['user_count'];
$done_shifts_seconds = sql_select_single_cell("SELECT SUM(`Shifts`.`end` - `Shifts`.`start`) FROM `ShiftEntry` JOIN `Shifts` USING (`SID`) WHERE `Shifts`.`end` < UNIX_TIMESTAMP()"); $done_shifts_seconds = DB::selectOne('
SELECT SUM(`Shifts`.`end` - `Shifts`.`start`)
FROM `ShiftEntry`
JOIN `Shifts` USING (`SID`)
WHERE `Shifts`.`end` < UNIX_TIMESTAMP()
');
$done_shifts_seconds = (int)array_shift($done_shifts_seconds);
$stats['done_work_hours'] = round($done_shifts_seconds / (60 * 60), 0); $stats['done_work_hours'] = round($done_shifts_seconds / (60 * 60), 0);
$users_in_action = sql_select("SELECT `Shifts`.`start`, `Shifts`.`end` FROM `ShiftEntry` JOIN `Shifts` ON `Shifts`.`SID`=`ShiftEntry`.`SID` WHERE UNIX_TIMESTAMP() BETWEEN `Shifts`.`start` AND `Shifts`.`end`"); $users_in_action = DB::select('
SELECT `Shifts`.`start`, `Shifts`.`end`
FROM `ShiftEntry`
JOIN `Shifts` ON `Shifts`.`SID`=`ShiftEntry`.`SID`
WHERE UNIX_TIMESTAMP() BETWEEN `Shifts`.`start` AND `Shifts`.`end`
');
$stats['users_in_action'] = count($users_in_action); $stats['users_in_action'] = count($users_in_action);
header("Content-Type: application/json"); header('Content-Type: application/json');
raw_output(json_encode($stats)); raw_output(json_encode($stats));
return; return;
} }
raw_output(json_encode([ raw_output(json_encode([
'error' => "Wrong api_key." 'error' => 'Wrong api_key.'
])); ]));
} }
raw_output(json_encode([ raw_output(json_encode([
'error' => "Missing parameter api_key." 'error' => 'Missing parameter api_key.'
])); ]));
} }
?>

View File

@ -1,51 +1,76 @@
<?php <?php
// publically available page to feed the news to feedreaders use Engelsystem\Database\DB;
function user_atom() {
global $user, $DISPLAY_NEWS;
if (! isset($_REQUEST['key']) || ! preg_match("/^[0-9a-f]{32}$/", $_REQUEST['key'])) { /**
engelsystem_error("Missing key."); * Publically available page to feed the news to feed readers
*/
function user_atom()
{
global $user;
$request = request();
if (!$request->has('key') || !preg_match('/^[\da-f]{32}$/', $request->input('key'))) {
engelsystem_error('Missing key.');
} }
$key = $_REQUEST['key']; $key = $request->input('key');
$user = User_by_api_key($key); $user = User_by_api_key($key);
if ($user == null) { if ($user == null) {
engelsystem_error("Key invalid."); engelsystem_error('Key invalid.');
} }
if (! in_array('atom', privileges_for_user($user['UID']))) { if (!in_array('atom', privileges_for_user($user['UID']))) {
engelsystem_error("No privilege for atom."); engelsystem_error('No privilege for atom.');
} }
$news = sql_select("SELECT * FROM `News` " . (empty($_REQUEST['meetings']) ? '' : 'WHERE `Treffen` = 1 ') . "ORDER BY `ID` DESC LIMIT " . sql_escape($DISPLAY_NEWS)); $news = DB::select('
SELECT *
FROM `News`
' . (!$request->has('meetings') ? '' : 'WHERE `Treffen` = 1 ') . '
ORDER BY `ID`
DESC LIMIT ' . (int)config('display_news')
);
$output = make_atom_entries_from_news($news); $output = make_atom_entries_from_news($news);
header('Content-Type: application/atom+xml; charset=utf-8'); header('Content-Type: application/atom+xml; charset=utf-8');
header("Content-Length: " . strlen($output)); header('Content-Length: ' . strlen($output));
raw_output($output); raw_output($output);
} }
function make_atom_entries_from_news($news_entries) { /**
* @param array[] $news_entries
* @return string
*/
function make_atom_entries_from_news($news_entries)
{
$request = app('request');
$html = '<?xml version="1.0" encoding="utf-8"?> $html = '<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"> <feed xmlns="http://www.w3.org/2005/Atom">
<title>Engelsystem</title> <title>Engelsystem</title>
<id>' . $_SERVER['HTTP_HOST'] . htmlspecialchars(preg_replace('#[&?]key=[a-f0-9]{32}#', '', $_SERVER['REQUEST_URI'])) . '</id> <id>' . $request->getHttpHost()
<updated>' . date('Y-m-d\TH:i:sP', $news_entries[0]['Datum']) . "</updated>\n"; . htmlspecialchars(preg_replace(
'#[&?]key=[a-f\d]{32}#',
'',
$request->getRequestUri()
))
. '</id>
<updated>' . date('Y-m-d\TH:i:sP', $news_entries[0]['Datum']) . '</updated>' . "\n";
foreach ($news_entries as $news_entry) { foreach ($news_entries as $news_entry) {
$html .= make_atom_entry_from_news($news_entry); $html .= make_atom_entry_from_news($news_entry);
} }
$html .= "</feed>"; $html .= '</feed>';
return $html; return $html;
} }
function make_atom_entry_from_news($news_entry) { function make_atom_entry_from_news($news_entry)
return " <entry> {
<title>" . htmlspecialchars($news_entry['Betreff']) . "</title> return '
<link href=\"" . page_link_to_absolute("news_comments&amp;nid=") . "${news_entry['ID']}\"/> <entry>
<id>" . preg_replace('#^https?://#', '', page_link_to_absolute("news")) . "-${news_entry['ID']}</id> <title>' . htmlspecialchars($news_entry['Betreff']) . '</title>
<updated>" . date('Y-m-d\TH:i:sP', $news_entry['Datum']) . "</updated> <link href="' . page_link_to('news_comments', ['nid' => $news_entry['ID']]) . '"/>
<summary type=\"html\">" . htmlspecialchars($news_entry['Text']) . "</summary> <id>' . preg_replace('#^https?://#', '', page_link_to('news_comments', ['nid' => $news_entry['ID']])) . '</id>
</entry>\n"; <updated>' . date('Y-m-d\TH:i:sP', $news_entry['Datum']) . '</updated>
<summary>' . htmlspecialchars($news_entry['Text']) . '</summary>
</entry>' . "\n";
} }
?>

View File

@ -3,21 +3,23 @@
/** /**
* Controller for ical output of users own shifts or any user_shifts filter. * Controller for ical output of users own shifts or any user_shifts filter.
*/ */
function user_ical() { function user_ical()
{
global $user; global $user;
$request = request();
if (! isset($_REQUEST['key']) || ! preg_match("/^[0-9a-f]{32}$/", $_REQUEST['key'])) { if (!$request->has('key') || !preg_match('/^[\da-f]{32}$/', $request->input('key'))) {
engelsystem_error("Missing key."); engelsystem_error('Missing key.');
} }
$key = $_REQUEST['key']; $key = $request->input('key');
$user = User_by_api_key($key); $user = User_by_api_key($key);
if ($user == null) { if ($user == null) {
engelsystem_error("Key invalid."); engelsystem_error('Key invalid.');
} }
if (! in_array('ical', privileges_for_user($user['UID']))) { if (!in_array('ical', privileges_for_user($user['UID']))) {
engelsystem_error("No privilege for ical."); engelsystem_error('No privilege for ical.');
} }
$ical_shifts = load_ical_shifts(); $ical_shifts = load_ical_shifts();
@ -28,36 +30,40 @@ function user_ical() {
/** /**
* Renders an ical calender from given shifts array. * Renders an ical calender from given shifts array.
* *
* @param array<Shift> $shifts * @param array <Shift> $shifts
*/ */
function send_ical_from_shifts($shifts) { function send_ical_from_shifts($shifts)
header("Content-Type: text/calendar; charset=utf-8"); {
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename=shifts.ics');
$output = "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//-//Engelsystem//DE\r\nCALSCALE:GREGORIAN\r\n"; $output = "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//-//Engelsystem//DE\r\nCALSCALE:GREGORIAN\r\n";
foreach ($shifts as $shift) { foreach ($shifts as $shift) {
$output .= make_ical_entry_from_shift($shift); $output .= make_ical_entry_from_shift($shift);
} }
$output .= "END:VCALENDAR\r\n"; $output .= "END:VCALENDAR\r\n";
$output = trim($output, "\x0A"); $output = trim($output, "\x0A");
header("Content-Length: " . strlen($output)); header('Content-Length: ' . strlen($output));
raw_output($output); raw_output($output);
} }
/** /**
* Renders an ical vevent from given shift. * Renders an ical vevent from given shift.
* *
* @param Shift $shift * @param array $shift
* @return string
*/ */
function make_ical_entry_from_shift($shift) { function make_ical_entry_from_shift($shift)
{
$output = "BEGIN:VEVENT\r\n"; $output = "BEGIN:VEVENT\r\n";
$output .= "UID:" . md5($shift['start'] . $shift['end'] . $shift['name']) . "\r\n"; $output .= 'UID:' . md5($shift['start'] . $shift['end'] . $shift['name']) . "\r\n";
$output .= "SUMMARY:" . str_replace("\n", "\\n", $shift['name']) . " (" . str_replace("\n", "\\n", $shift['title']) . ")\r\n"; $output .= 'SUMMARY:' . str_replace("\n", "\\n", $shift['name'])
. ' (' . str_replace("\n", "\\n", $shift['title']) . ")\r\n";
if (isset($shift['Comment'])) { if (isset($shift['Comment'])) {
$output .= "DESCRIPTION:" . str_replace("\n", "\\n", $shift['Comment']) . "\r\n"; $output .= 'DESCRIPTION:' . str_replace("\n", "\\n", $shift['Comment']) . "\r\n";
} }
$output .= "DTSTART;TZID=Europe/Berlin:" . date("Ymd\THis", $shift['start']) . "\r\n"; $output .= 'DTSTART;TZID=Europe/Berlin:' . date("Ymd\THis", $shift['start']) . "\r\n";
$output .= "DTEND;TZID=Europe/Berlin:" . date("Ymd\THis", $shift['end']) . "\r\n"; $output .= 'DTEND;TZID=Europe/Berlin:' . date("Ymd\THis", $shift['end']) . "\r\n";
$output .= "LOCATION:" . $shift['Name'] . "\r\n"; $output .= 'LOCATION:' . $shift['Name'] . "\r\n";
$output .= "END:VEVENT\r\n"; $output .= "END:VEVENT\r\n";
return $output; return $output;
} }
?>

View File

@ -1,14 +1,27 @@
<?php <?php
function messages_title() { use Engelsystem\Database\DB;
return _("Messages");
/**
* @return string
*/
function messages_title()
{
return _('Messages');
} }
function user_unread_messages() { /**
* @return string
*/
function user_unread_messages()
{
global $user; global $user;
if (isset($user)) { if (isset($user)) {
$new_messages = sql_num_query("SELECT * FROM `Messages` WHERE isRead='N' AND `RUID`='" . sql_escape($user['UID']) . "'"); $new_messages = count(DB::select(
'SELECT `id` FROM `Messages` WHERE isRead=\'N\' AND `RUID`=?',
[$user['UID']]
));
if ($new_messages > 0) { if ($new_messages > 0) {
return ' <span class="badge danger">' . $new_messages . '</span>'; return ' <span class="badge danger">' . $new_messages . '</span>';
} }
@ -16,14 +29,22 @@ function user_unread_messages() {
return ''; return '';
} }
function user_messages() { /**
* @return string
*/
function user_messages()
{
global $user; global $user;
$request = request();
if (! isset($_REQUEST['action'])) { if (!$request->has('action')) {
$users = sql_select("SELECT * FROM `User` WHERE NOT `UID`='" . sql_escape($user['UID']) . "' ORDER BY `Nick`"); $users = DB::select(
'SELECT `UID`, `Nick` FROM `User` WHERE NOT `UID`=? ORDER BY `Nick`',
[$user['UID']]
);
$to_select_data = [ $to_select_data = [
"" => _("Select recipient...") '' => _('Select recipient...')
]; ];
foreach ($users as $u) { foreach ($users as $u) {
@ -32,16 +53,27 @@ function user_messages() {
$to_select = html_select_key('to', 'to', $to_select_data, ''); $to_select = html_select_key('to', 'to', $to_select_data, '');
$messages = sql_select("SELECT * FROM `Messages` WHERE `SUID`='" . sql_escape($user['UID']) . "' OR `RUID`='" . sql_escape($user['UID']) . "' ORDER BY `isRead`,`Datum` DESC"); $messages = DB::select('
SELECT *
FROM `Messages`
WHERE `SUID`=?
OR `RUID`=?
ORDER BY `isRead`,`Datum` DESC
',
[
$user['UID'],
$user['UID'],
]
);
$messages_table = [ $messages_table = [
[ [
'news' => '', 'news' => '',
'timestamp' => date("Y-m-d H:i"), 'timestamp' => date('Y-m-d H:i'),
'from' => User_Nick_render($user), 'from' => User_Nick_render($user),
'to' => $to_select, 'to' => $to_select,
'text' => form_textarea('text', '', ''), 'text' => form_textarea('text', '', ''),
'actions' => form_submit('submit', _("Save")) 'actions' => form_submit('submit', _('Save'))
] ]
]; ];
@ -51,7 +83,7 @@ function user_messages() {
$messages_table_entry = [ $messages_table_entry = [
'new' => $message['isRead'] == 'N' ? '<span class="glyphicon glyphicon-envelope"></span>' : '', 'new' => $message['isRead'] == 'N' ? '<span class="glyphicon glyphicon-envelope"></span>' : '',
'timestamp' => date("Y-m-d H:i", $message['Datum']), 'timestamp' => date('Y-m-d H:i', $message['Datum']),
'from' => User_Nick_render($sender_user_source), 'from' => User_Nick_render($sender_user_source),
'to' => User_Nick_render($receiver_user_source), 'to' => User_Nick_render($receiver_user_source),
'text' => str_replace("\n", '<br />', $message['Text']) 'text' => str_replace("\n", '<br />', $message['Text'])
@ -59,73 +91,92 @@ function user_messages() {
if ($message['RUID'] == $user['UID']) { if ($message['RUID'] == $user['UID']) {
if ($message['isRead'] == 'N') { if ($message['isRead'] == 'N') {
$messages_table_entry['actions'] = button(page_link_to("user_messages") . '&action=read&id=' . $message['id'], _("mark as read"), 'btn-xs'); $messages_table_entry['actions'] = button(
page_link_to('user_messages', ['action' => 'read', 'id' => $message['id']]),
_('mark as read'),
'btn-xs'
);
} }
} else { } else {
$messages_table_entry['actions'] = button(page_link_to("user_messages") . '&action=delete&id=' . $message['id'], _("delete message"), 'btn-xs'); $messages_table_entry['actions'] = button(
page_link_to('user_messages', ['action' => 'delete', 'id' => $message['id']]),
_('delete message'),
'btn-xs'
);
} }
$messages_table[] = $messages_table_entry; $messages_table[] = $messages_table_entry;
} }
return page_with_title(messages_title(), [ return page_with_title(messages_title(), [
msg(), msg(),
sprintf(_("Hello %s, here can you leave messages for other angels"), User_Nick_render($user)), sprintf(_('Hello %s, here can you leave messages for other angels'), User_Nick_render($user)),
form([ form([
table([ table([
'new' => _("New"), 'new' => _('New'),
'timestamp' => _("Date"), 'timestamp' => _('Date'),
'from' => _("Transmitted"), 'from' => _('Transmitted'),
'to' => _("Recipient"), 'to' => _('Recipient'),
'text' => _("Message"), 'text' => _('Message'),
'actions' => '' 'actions' => ''
], $messages_table) ], $messages_table)
], page_link_to('user_messages') . '&action=send') ], page_link_to('user_messages', ['action' => 'send']))
]); ]);
} else { } else {
switch ($_REQUEST['action']) { switch ($request->input('action')) {
case "read": case 'read':
if (isset($_REQUEST['id']) && preg_match("/^[0-9]{1,11}$/", $_REQUEST['id'])) { if ($request->has('id') && preg_match('/^\d{1,11}$/', $request->input('id'))) {
$message_id = $_REQUEST['id']; $message_id = $request->input('id');
} else { } else {
return error(_("Incomplete call, missing Message ID."), true); return error(_('Incomplete call, missing Message ID.'), true);
} }
$message = sql_select("SELECT * FROM `Messages` WHERE `id`='" . sql_escape($message_id) . "' LIMIT 1"); $message = DB::selectOne(
if (count($message) > 0 && $message[0]['RUID'] == $user['UID']) { 'SELECT `RUID` FROM `Messages` WHERE `id`=? LIMIT 1',
sql_query("UPDATE `Messages` SET `isRead`='Y' WHERE `id`='" . sql_escape($message_id) . "' LIMIT 1"); [$message_id]
redirect(page_link_to("user_messages")); );
if (!empty($message) && $message['RUID'] == $user['UID']) {
DB::update(
'UPDATE `Messages` SET `isRead`=\'Y\' WHERE `id`=? LIMIT 1',
[$message_id]
);
redirect(page_link_to('user_messages'));
} else { } else {
return error(_("No Message found."), true); return error(_('No Message found.'), true);
} }
break; break;
case "delete": case 'delete':
if (isset($_REQUEST['id']) && preg_match("/^[0-9]{1,11}$/", $_REQUEST['id'])) { if ($request->has('id') && preg_match('/^\d{1,11}$/', $request->input('id'))) {
$message_id = $_REQUEST['id']; $message_id = $request->input('id');
} else { } else {
return error(_("Incomplete call, missing Message ID."), true); return error(_('Incomplete call, missing Message ID.'), true);
} }
$message = sql_select("SELECT * FROM `Messages` WHERE `id`='" . sql_escape($message_id) . "' LIMIT 1"); $message = DB::selectOne(
if (count($message) > 0 && $message[0]['SUID'] == $user['UID']) { 'SELECT `SUID` FROM `Messages` WHERE `id`=? LIMIT 1',
sql_query("DELETE FROM `Messages` WHERE `id`='" . sql_escape($message_id) . "' LIMIT 1"); [$message_id]
redirect(page_link_to("user_messages")); );
if (!empty($message) && $message['SUID'] == $user['UID']) {
DB::delete('DELETE FROM `Messages` WHERE `id`=? LIMIT 1', [$message_id]);
redirect(page_link_to('user_messages'));
} else { } else {
return error(_("No Message found."), true); return error(_('No Message found.'), true);
} }
break; break;
case "send": case 'send':
if (Message_send($_REQUEST['to'], $_REQUEST['text']) === true) { // @TODO: Validation?
redirect(page_link_to("user_messages")); if (Message_send($request->input('to'), $request->input('text'))) {
redirect(page_link_to('user_messages'));
} else { } else {
return error(_("Transmitting was terminated with an Error."), true); return error(_('Transmitting was terminated with an Error.'), true);
} }
break; break;
default: default:
return error(_("Wrong action."), true); return error(_('Wrong action.'), true);
} }
} }
return '';
} }
?>

View File

@ -1,35 +1,55 @@
<?php <?php
function myshifts_title() { use Engelsystem\Database\DB;
return _("My shifts");
/**
* @return string
*/
function myshifts_title()
{
return _('My shifts');
} }
// Zeigt die Schichten an, die ein Benutzer belegt /**
function user_myshifts() { * Zeigt die Schichten an, die ein Benutzer belegt
global $LETZTES_AUSTRAGEN; *
* @return string
*/
function user_myshifts()
{
global $user, $privileges; global $user, $privileges;
$request = request();
if (isset($_REQUEST['id']) && in_array("user_shifts_admin", $privileges) && preg_match("/^[0-9]{1,}$/", $_REQUEST['id']) && sql_num_query("SELECT * FROM `User` WHERE `UID`='" . sql_escape($_REQUEST['id']) . "'") > 0) { if (
$user_id = $_REQUEST['id']; $request->has('id')
&& in_array('user_shifts_admin', $privileges)
&& preg_match('/^\d{1,}$/', $request->input('id'))
&& count(DB::select('SELECT `UID` FROM `User` WHERE `UID`=?', [$request->input('id')])) > 0
) {
$user_id = $request->input('id');
} else { } else {
$user_id = $user['UID']; $user_id = $user['UID'];
} }
list($shifts_user) = sql_select("SELECT * FROM `User` WHERE `UID`='" . sql_escape($user_id) . "' LIMIT 1"); $shifts_user = DB::selectOne('SELECT * FROM `User` WHERE `UID`=? LIMIT 1', [$user_id]);
if (isset($_REQUEST['reset'])) { if ($request->has('reset')) {
if ($_REQUEST['reset'] == "ack") { if ($request->input('reset') == 'ack') {
User_reset_api_key($user); User_reset_api_key($user);
success(_("Key changed.")); success(_('Key changed.'));
redirect(page_link_to('users') . '&action=view&user_id=' . $shifts_user['UID']); redirect(page_link_to('users', ['action' => 'view', 'user_id' => $shifts_user['UID']]));
} }
return page_with_title(_("Reset API key"), [ return page_with_title(_('Reset API key'), [
error(_("If you reset the key, the url to your iCal- and JSON-export and your atom feed changes! You have to update it in every application using one of these exports."), true), error(
button(page_link_to('user_myshifts') . '&reset=ack', _("Continue"), 'btn-danger') _('If you reset the key, the url to your iCal- and JSON-export and your atom feed changes! You have to update it in every application using one of these exports.'),
true
),
button(page_link_to('user_myshifts', ['reset' => 'ack']), _('Continue'), 'btn-danger')
]); ]);
} elseif (isset($_REQUEST['edit']) && preg_match("/^[0-9]*$/", $_REQUEST['edit'])) { } elseif ($request->has('edit') && preg_match('/^\d+$/', $request->input('edit'))) {
$user_id = $_REQUEST['edit']; $user_id = $request->input('edit');
$shift = sql_select("SELECT $shift = DB::selectOne('
SELECT
`ShiftEntry`.`freeloaded`, `ShiftEntry`.`freeloaded`,
`ShiftEntry`.`freeload_comment`, `ShiftEntry`.`freeload_comment`,
`ShiftEntry`.`Comment`, `ShiftEntry`.`Comment`,
@ -37,27 +57,33 @@ function user_myshifts() {
`ShiftTypes`.`name`, `ShiftTypes`.`name`,
`Shifts`.*, `Shifts`.*,
`Room`.`Name`, `Room`.`Name`,
`AngelTypes`.`name` as `angel_type` `AngelTypes`.`name` AS `angel_type`
FROM `ShiftEntry` FROM `ShiftEntry`
JOIN `AngelTypes` ON (`ShiftEntry`.`TID` = `AngelTypes`.`id`) JOIN `AngelTypes` ON (`ShiftEntry`.`TID` = `AngelTypes`.`id`)
JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID`) JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID`)
JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`) JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`)
JOIN `Room` ON (`Shifts`.`RID` = `Room`.`RID`) JOIN `Room` ON (`Shifts`.`RID` = `Room`.`RID`)
WHERE `ShiftEntry`.`id`='" . sql_escape($user_id) . "' WHERE `ShiftEntry`.`id`=?
AND `UID`='" . sql_escape($shifts_user['UID']) . "' LIMIT 1"); AND `UID`=?
LIMIT 1
',
[
$user_id,
$shifts_user['UID'],
]
);
if (count($shift) > 0) { if (count($shift) > 0) {
$shift = $shift[0];
$freeloaded = $shift['freeloaded']; $freeloaded = $shift['freeloaded'];
$freeload_comment = $shift['freeload_comment']; $freeload_comment = $shift['freeload_comment'];
if (isset($_REQUEST['submit'])) { if ($request->has('submit')) {
$valid = true; $valid = true;
if (in_array("user_shifts_admin", $privileges)) { if (in_array('user_shifts_admin', $privileges)) {
$freeloaded = isset($_REQUEST['freeloaded']); $freeloaded = $request->has('freeloaded');
$freeload_comment = strip_request_item_nl('freeload_comment'); $freeload_comment = strip_request_item_nl('freeload_comment');
if ($freeloaded && $freeload_comment == '') { if ($freeloaded && $freeload_comment == '') {
$valid = false; $valid = false;
error(_("Please enter a freeload comment!")); error(_('Please enter a freeload comment!'));
} }
} }
@ -65,54 +91,79 @@ function user_myshifts() {
$user_source = User($shift['UID']); $user_source = User($shift['UID']);
if ($valid) { if ($valid) {
$result = ShiftEntry_update([ ShiftEntry_update([
'id' => $user_id, 'id' => $user_id,
'Comment' => $comment, 'Comment' => $comment,
'freeloaded' => $freeloaded, 'freeloaded' => $freeloaded,
'freeload_comment' => $freeload_comment 'freeload_comment' => $freeload_comment
]); ]);
if ($result === false) {
engelsystem_error('Unable to update shift entry.');
}
engelsystem_log("Updated " . User_Nick_render($user_source) . "'s shift " . $shift['name'] . " from " . date("Y-m-d H:i", $shift['start']) . " to " . date("Y-m-d H:i", $shift['end']) . " with comment " . $comment . ". Freeloaded: " . ($freeloaded ? "YES Comment: " . $freeload_comment : "NO")); engelsystem_log(
success(_("Shift saved.")); 'Updated ' . User_Nick_render($user_source) . '\'s shift ' . $shift['name']
redirect(page_link_to('users') . '&action=view&user_id=' . $shifts_user['UID']); . ' from ' . date('Y-m-d H:i', $shift['start'])
. ' to ' . date('Y-m-d H:i', $shift['end'])
. ' with comment ' . $comment
. '. Freeloaded: ' . ($freeloaded ? 'YES Comment: ' . $freeload_comment : 'NO')
);
success(_('Shift saved.'));
redirect(page_link_to('users', ['action' => 'view', 'user_id' => $shifts_user['UID']]));
} }
} }
return ShiftEntry_edit_view(User_Nick_render($shifts_user), date("Y-m-d H:i", $shift['start']) . ', ' . shift_length($shift), $shift['Name'], $shift['name'], $shift['angel_type'], $shift['Comment'], $shift['freeloaded'], $shift['freeload_comment'], in_array("user_shifts_admin", $privileges)); return ShiftEntry_edit_view(
User_Nick_render($shifts_user),
date('Y-m-d H:i', $shift['start']) . ', ' . shift_length($shift),
$shift['Name'],
$shift['name'],
$shift['angel_type'],
$shift['Comment'],
$shift['freeloaded'],
$shift['freeload_comment'],
in_array('user_shifts_admin', $privileges)
);
} else { } else {
redirect(page_link_to('user_myshifts')); redirect(page_link_to('user_myshifts'));
} }
} elseif (isset($_REQUEST['cancel']) && preg_match("/^[0-9]*$/", $_REQUEST['cancel'])) { } elseif ($request->has('cancel') && preg_match('/^\d+$/', $request->input('cancel'))) {
$user_id = $_REQUEST['cancel']; $user_id = $request->input('cancel');
$shift = sql_select(" $shift = DB::selectOne('
SELECT * SELECT *
FROM `Shifts` FROM `Shifts`
INNER JOIN `ShiftEntry` USING (`SID`) INNER JOIN `ShiftEntry` USING (`SID`)
WHERE `ShiftEntry`.`id`='" . sql_escape($user_id) . "' AND `UID`='" . sql_escape($shifts_user['UID']) . "'"); WHERE `ShiftEntry`.`id`=? AND `UID`=?
',
[
$user_id,
$shifts_user['UID'],
]
);
if (count($shift) > 0) { if (count($shift) > 0) {
$shift = $shift[0]; if (
if (($shift['start'] > time() + $LETZTES_AUSTRAGEN * 3600) || in_array('user_shifts_admin', $privileges)) { ($shift['start'] > time() + config('last_unsubscribe') * 3600)
$result = ShiftEntry_delete($user_id); || in_array('user_shifts_admin', $privileges)
if ($result === false) { ) {
engelsystem_error('Unable to delete shift entry.'); ShiftEntry_delete($user_id);
}
$room = Room($shift['RID']); $room = Room($shift['RID']);
$angeltype = AngelType($shift['TID']); $angeltype = AngelType($shift['TID']);
$shifttype = ShiftType($shift['shifttype_id']); $shifttype = ShiftType($shift['shifttype_id']);
engelsystem_log("Deleted own shift: " . $shifttype['name'] . " at " . $room['Name'] . " from " . date("Y-m-d H:i", $shift['start']) . " to " . date("Y-m-d H:i", $shift['end']) . " as " . $angeltype['name']); engelsystem_log(
success(_("Shift canceled.")); 'Deleted own shift: ' . $shifttype['name']
. ' at ' . $room['Name']
. ' from ' . date('Y-m-d H:i', $shift['start'])
. ' to ' . date('Y-m-d H:i', $shift['end'])
. ' as ' . $angeltype['name']
);
success(_('Shift canceled.'));
} else { } else {
error(_("It's too late to sign yourself off the shift. If neccessary, ask the dispatcher to do so.")); error(_('It\'s too late to sign yourself off the shift. If neccessary, ask the dispatcher to do so.'));
} }
} else { } else {
redirect(user_link($shifts_user)); redirect(user_link($shifts_user));
} }
} }
redirect(page_link_to('users') . '&action=view&user_id=' . $shifts_user['UID']); redirect(page_link_to('users', ['action' => 'view', 'user_id' => $shifts_user['UID']]));
return '';
} }
?>

View File

@ -1,51 +1,82 @@
<?php <?php
function user_news_comments_title() { use Engelsystem\Database\DB;
return _("News comments");
/**
* @return string
*/
function user_news_comments_title()
{
return _('News comments');
} }
function news_title() { /**
return _("News"); * @return string
*/
function news_title()
{
return _('News');
} }
function meetings_title() { /**
return _("Meetings"); * @return string
*/
function meetings_title()
{
return _('Meetings');
} }
function user_meetings() { /**
global $DISPLAY_NEWS; * @return string
*/
function user_meetings()
{
$display_news = config('display_news');
$html = '<div class="col-md-12"><h1>' . meetings_title() . '</h1>' . msg(); $html = '<div class="col-md-12"><h1>' . meetings_title() . '</h1>' . msg();
$request = request();
if (isset($_REQUEST['page']) && preg_match("/^[0-9]{1,}$/", $_REQUEST['page'])) { if (preg_match('/^\d{1,}$/', $request->input('page', 0))) {
$page = $_REQUEST['page']; $page = $request->input('page', 0);
} else { } else {
$page = 0; $page = 0;
} }
$news = sql_select("SELECT * FROM `News` WHERE `Treffen`=1 ORDER BY `Datum` DESC LIMIT " . sql_escape($page * $DISPLAY_NEWS) . ", " . sql_escape($DISPLAY_NEWS)); $news = DB::select(sprintf('
SELECT *
FROM `News`
WHERE `Treffen`=1
ORDER BY `Datum`DESC
LIMIT %u, %u',
$page * $display_news,
$display_news
));
foreach ($news as $entry) { foreach ($news as $entry) {
$html .= display_news($entry); $html .= display_news($entry);
} }
$dis_rows = ceil(sql_num_query("SELECT * FROM `News`") / $DISPLAY_NEWS); $dis_rows = ceil(count(DB::select('SELECT `ID` FROM `News`')) / $display_news);
$html .= '<div class="text-center">' . '<ul class="pagination">'; $html .= '<div class="text-center">' . '<ul class="pagination">';
for ($i = 0; $i < $dis_rows; $i ++) { for ($i = 0; $i < $dis_rows; $i++) {
if (isset($_REQUEST['page']) && $i == $_REQUEST['page']) { if ($request->has('page') && $i == $request->input('page', 0)) {
$html .= '<li class="active">'; $html .= '<li class="active">';
} elseif (! isset($_REQUEST['page']) && $i == 0) { } elseif (!$request->has('page') && $i == 0) {
$html .= '<li class="active">'; $html .= '<li class="active">';
} else { } else {
$html .= '<li>'; $html .= '<li>';
} }
$html .= '<a href="' . page_link_to("user_meetings") . '&page=' . $i . '">' . ($i + 1) . '</a></li>'; $html .= '<a href="' . page_link_to('user_meetings', ['page' => $i]) . '">' . ($i + 1) . '</a></li>';
} }
$html .= '</ul></div></div>'; $html .= '</ul></div></div>';
return $html; return $html;
} }
function display_news($news) { /**
* @param array $news
* @return string
*/
function display_news($news)
{
global $privileges, $page; global $privileges, $page;
$html = ''; $html = '';
@ -56,44 +87,74 @@ function display_news($news) {
$html .= '<div class="panel-body">' . ReplaceSmilies(nl2br($news['Text'])) . '</div>'; $html .= '<div class="panel-body">' . ReplaceSmilies(nl2br($news['Text'])) . '</div>';
$html .= '<div class="panel-footer text-muted">'; $html .= '<div class="panel-footer text-muted">';
if (in_array("admin_news", $privileges)) { if (in_array('admin_news', $privileges)) {
$html .= '<div class="pull-right">' . button_glyph(page_link_to("admin_news") . '&action=edit&id=' . $news['ID'], 'edit', 'btn-xs') . '</div>'; $html .= '<div class="pull-right">'
. button_glyph(page_link_to('admin_news', ['action' => 'edit', 'id' => $news['ID']]), 'edit', 'btn-xs')
. '</div>';
} }
$html .= '<span class="glyphicon glyphicon-time"></span> ' . date("Y-m-d H:i", $news['Datum']) . '&emsp;'; $html .= '<span class="glyphicon glyphicon-time"></span> ' . date('Y-m-d H:i', $news['Datum']) . '&emsp;';
$user_source = User($news['UID']); $user_source = User($news['UID']);
$html .= User_Nick_render($user_source); $html .= User_Nick_render($user_source);
if ($page != "news_comments") { if ($page != 'news_comments') {
$html .= '&emsp;<a href="' . page_link_to("news_comments") . '&nid=' . $news['ID'] . '"><span class="glyphicon glyphicon-comment"></span> ' . _("Comments") . ' &raquo;</a> <span class="badge">' . sql_num_query("SELECT * FROM `NewsComments` WHERE `Refid`='" . sql_escape($news['ID']) . "'") . '</span>'; $html .= '&emsp;<a href="' . page_link_to('news_comments', ['nid' => $news['ID']]) . '">'
. '<span class="glyphicon glyphicon-comment"></span> '
. _('Comments') . ' &raquo;</a> '
. '<span class="badge">'
. count(DB::select('SELECT `ID` FROM `NewsComments` WHERE `Refid`=?', [$news['ID']]))
. '</span>';
} }
$html .= '</div>'; $html .= '</div>';
$html .= '</div>'; $html .= '</div>';
return $html; return $html;
} }
function user_news_comments() { /**
* @return string
*/
function user_news_comments()
{
global $user; global $user;
$request = request();
$html = '<div class="col-md-12"><h1>' . user_news_comments_title() . '</h1>'; $html = '<div class="col-md-12"><h1>' . user_news_comments_title() . '</h1>';
if (isset($_REQUEST["nid"]) && preg_match("/^[0-9]{1,}$/", $_REQUEST['nid']) && sql_num_query("SELECT * FROM `News` WHERE `ID`='" . sql_escape($_REQUEST['nid']) . "' LIMIT 1") > 0) { if (
$nid = $_REQUEST["nid"]; $request->has('nid')
list($news) = sql_select("SELECT * FROM `News` WHERE `ID`='" . sql_escape($nid) . "' LIMIT 1"); && preg_match('/^\d{1,}$/', $request->input('nid'))
if (isset($_REQUEST["text"])) { && count(DB::select('SELECT `ID` FROM `News` WHERE `ID`=? LIMIT 1', [$request->input('nid')])) > 0
$text = preg_replace("/([^\p{L}\p{P}\p{Z}\p{N}\n]{1,})/ui", '', strip_tags($_REQUEST['text'])); ) {
sql_query("INSERT INTO `NewsComments` (`Refid`, `Datum`, `Text`, `UID`) VALUES ('" . sql_escape($nid) . "', '" . date("Y-m-d H:i:s") . "', '" . sql_escape($text) . "', '" . sql_escape($user["UID"]) . "')"); $nid = $request->input('nid');
engelsystem_log("Created news_comment: " . $text); $news = DB::selectOne('SELECT * FROM `News` WHERE `ID`=? LIMIT 1', [$nid]);
$html .= success(_("Entry saved."), true); if ($request->has('text')) {
$text = preg_replace("/([^\p{L}\p{P}\p{Z}\p{N}\n]{1,})/ui", '', strip_tags($request->input('text')));
DB::insert('
INSERT INTO `NewsComments` (`Refid`, `Datum`, `Text`, `UID`)
VALUES (?, ?, ?, ?)
',
[
$nid,
date('Y-m-d H:i:s'),
$text,
$user["UID"],
]
);
engelsystem_log('Created news_comment: ' . $text);
$html .= success(_('Entry saved.'), true);
} }
$html .= display_news($news); $html .= display_news($news);
$comments = sql_select("SELECT * FROM `NewsComments` WHERE `Refid`='" . sql_escape($nid) . "' ORDER BY 'ID'"); $comments = DB::select(
'SELECT * FROM `NewsComments` WHERE `Refid`=? ORDER BY \'ID\'',
[$nid]
);
foreach ($comments as $comment) { foreach ($comments as $comment) {
$user_source = User($comment['UID']); $user_source = User($comment['UID']);
$html .= '<div class="panel panel-default">'; $html .= '<div class="panel panel-default">';
$html .= '<div class="panel-body">' . nl2br($comment['Text']) . '</div>'; $html .= '<div class="panel-body">' . nl2br(htmlspecialchars($comment['Text'])) . '</div>';
$html .= '<div class="panel-footer text-muted">'; $html .= '<div class="panel-footer text-muted">';
$html .= '<span class="glyphicon glyphicon-time"></span> ' . $comment['Datum'] . '&emsp;'; $html .= '<span class="glyphicon glyphicon-time"></span> ' . $comment['Datum'] . '&emsp;';
$html .= User_Nick_render($user_source); $html .= User_Nick_render($user_source);
@ -101,69 +162,100 @@ function user_news_comments() {
$html .= '</div>'; $html .= '</div>';
} }
$html .= '<hr /><h2>' . _("New Comment:") . '</h2>'; $html .= '<hr /><h2>' . _('New Comment:') . '</h2>';
$html .= form([ $html .= form([
form_textarea('text', _("Message"), ''), form_textarea('text', _('Message'), ''),
form_submit('submit', _("Save")) form_submit('submit', _('Save'))
], page_link_to('news_comments') . '&nid=' . $news['ID']); ], page_link_to('news_comments', ['nid' => $news['ID']]));
} else { } else {
$html .= _("Invalid request."); $html .= _('Invalid request.');
} }
return $html . '</div>'; return $html . '</div>';
} }
function user_news() { /**
global $DISPLAY_NEWS, $privileges, $user; * @return string
*/
function user_news()
{
global $privileges, $user;
$display_news = config('display_news');
$request = request();
$html = '<div class="col-md-12"><h1>' . news_title() . '</h1>' . msg(); $html = '<div class="col-md-12"><h1>' . news_title() . '</h1>' . msg();
if (isset($_POST["text"]) && isset($_POST["betreff"]) && in_array("admin_news", $privileges)) { $isMeeting = $request->postData('treffen');
if (! isset($_POST["treffen"]) || ! in_array("admin_news", $privileges)) { if ($request->has('text') && $request->has('betreff') && in_array('admin_news', $privileges)) {
$_POST["treffen"] = 0; if (!$request->has('treffen')) {
$isMeeting = 0;
} }
sql_query("INSERT INTO `News` (`Datum`, `Betreff`, `Text`, `UID`, `Treffen`) " . "VALUES ('" . sql_escape(time()) . "', '" . sql_escape($_POST["betreff"]) . "', '" . sql_escape($_POST["text"]) . "', '" . sql_escape($user['UID']) . "', '" . sql_escape($_POST["treffen"]) . "');");
engelsystem_log("Created news: " . $_POST["betreff"] . ", treffen: " . $_POST["treffen"]); $text = $request->postData('text');
success(_("Entry saved.")); if (!in_array('admin_news_html', $privileges)) {
$text = strip_tags($text);
}
DB::insert('
INSERT INTO `News` (`Datum`, `Betreff`, `Text`, `UID`, `Treffen`)
VALUES (?, ?, ?, ?, ?)
',
[
time(),
strip_tags($request->postData('betreff')),
$text,
$user['UID'],
$isMeeting,
]
);
engelsystem_log('Created news: ' . $request->postData('betreff') . ', treffen: ' . $isMeeting);
success(_('Entry saved.'));
redirect(page_link_to('news')); redirect(page_link_to('news'));
} }
if (isset($_REQUEST['page']) && preg_match("/^[0-9]{1,}$/", $_REQUEST['page'])) { if (preg_match('/^\d{1,}$/', $request->input('page', 0))) {
$page = $_REQUEST['page']; $page = $request->input('page', 0);
} else { } else {
$page = 0; $page = 0;
} }
$news = sql_select("SELECT * FROM `News` ORDER BY `Datum` DESC LIMIT " . sql_escape($page * $DISPLAY_NEWS) . ", " . sql_escape($DISPLAY_NEWS)); $news = DB::select(sprintf('
SELECT *
FROM `News`
ORDER BY `Datum`
DESC LIMIT %u, %u
',
$page * $display_news,
$display_news
));
foreach ($news as $entry) { foreach ($news as $entry) {
$html .= display_news($entry); $html .= display_news($entry);
} }
$dis_rows = ceil(sql_num_query("SELECT * FROM `News`") / $DISPLAY_NEWS); $dis_rows = ceil(count(DB::select('SELECT `ID` FROM `News`')) / $display_news);
$html .= '<div class="text-center">' . '<ul class="pagination">'; $html .= '<div class="text-center">' . '<ul class="pagination">';
for ($i = 0; $i < $dis_rows; $i ++) { for ($i = 0; $i < $dis_rows; $i++) {
if (isset($_REQUEST['page']) && $i == $_REQUEST['page']) { if ($request->has('page') && $i == $request->input('page', 0)) {
$html .= '<li class="active">'; $html .= '<li class="active">';
} elseif (! isset($_REQUEST['page']) && $i == 0) { } elseif (!$request->has('page') && $i == 0) {
$html .= '<li class="active">'; $html .= '<li class="active">';
} else { } else {
$html .= '<li>'; $html .= '<li>';
} }
$html .= '<a href="' . page_link_to("news") . '&page=' . $i . '">' . ($i + 1) . '</a></li>'; $html .= '<a href="' . page_link_to('news', ['page' => $i]) . '">' . ($i + 1) . '</a></li>';
} }
$html .= '</ul></div>'; $html .= '</ul></div>';
if (in_array("admin_news", $privileges)) { if (in_array('admin_news', $privileges)) {
$html .= '<hr />'; $html .= '<hr />';
$html .= '<h2>' . _("Create news:") . '</h2>'; $html .= '<h2>' . _('Create news:') . '</h2>';
$html .= form([ $html .= form([
form_text('betreff', _("Subject"), ''), form_text('betreff', _('Subject'), ''),
form_textarea('text', _("Message"), ''), form_textarea('text', _('Message'), ''),
form_checkbox('treffen', _("Meeting"), false, 1), form_checkbox('treffen', _('Meeting'), false, 1),
form_submit('submit', _("Save")) form_submit('submit', _('Save'))
]); ]);
} }
return $html . '</div>'; return $html . '</div>';
} }
?>

View File

@ -1,57 +1,88 @@
<?php <?php
function questions_title() { use Engelsystem\Database\DB;
return _("Ask the Heaven");
/**
* @return string
*/
function questions_title()
{
return _('Ask the Heaven');
} }
function user_questions() { /**
* @return string
*/
function user_questions()
{
global $user; global $user;
$request = request();
if (! isset($_REQUEST['action'])) { if (!$request->has('action')) {
$open_questions = sql_select("SELECT * FROM `Questions` WHERE `AID` IS NULL AND `UID`='" . sql_escape($user['UID']) . "'"); $open_questions = DB::select(
'SELECT * FROM `Questions` WHERE `AID` IS NULL AND `UID`=?',
[$user['UID']]
);
$answered_questions = sql_select("SELECT * FROM `Questions` WHERE NOT `AID` IS NULL AND `UID`='" . sql_escape($user['UID']) . "'"); $answered_questions = DB::select(
'SELECT * FROM `Questions` WHERE NOT `AID` IS NULL AND `UID`=?',
[$user['UID']]
);
foreach ($answered_questions as &$question) { foreach ($answered_questions as &$question) {
$answer_user_source = User($question['AID']); $answer_user_source = User($question['AID']);
$question['answer_user'] = User_Nick_render($answer_user_source); $question['answer_user'] = User_Nick_render($answer_user_source);
} }
return Questions_view($open_questions, $answered_questions, page_link_to("user_questions") . '&action=ask'); return Questions_view(
$open_questions,
$answered_questions,
page_link_to('user_questions', ['action' => 'ask'])
);
} else { } else {
switch ($_REQUEST['action']) { switch ($request->input('action')) {
case 'ask': case 'ask':
$question = strip_request_item_nl('question'); $question = strip_request_item_nl('question');
if ($question != "") { if ($question != '') {
$result = sql_query("INSERT INTO `Questions` SET `UID`='" . sql_escape($user['UID']) . "', `Question`='" . sql_escape($question) . "'"); DB::insert('
if ($result === false) { INSERT INTO `Questions` (`UID`, `Question`)
engelsystem_error(_("Unable to save question.")); VALUES (?, ?)
} ',
success(_("You question was saved.")); [$user['UID'], $question]
redirect(page_link_to("user_questions")); );
success(_('You question was saved.'));
redirect(page_link_to('user_questions'));
} else { } else {
return page_with_title(questions_title(), [ return page_with_title(questions_title(), [
error(_("Please enter a question!"), true) error(_('Please enter a question!'), true)
]); ]);
} }
break; break;
case 'delete': case 'delete':
if (isset($_REQUEST['id']) && preg_match("/^[0-9]{1,11}$/", $_REQUEST['id'])) { if ($request->has('id') && preg_match('/^\d{1,11}$/', $request->input('id'))) {
$question_id = $_REQUEST['id']; $question_id = $request->input('id');
} else { } else {
return error(_("Incomplete call, missing Question ID."), true); return error(_('Incomplete call, missing Question ID.'), true);
} }
$question = sql_select("SELECT * FROM `Questions` WHERE `QID`='" . sql_escape($question_id) . "' LIMIT 1"); $question = DB::selectOne(
if (count($question) > 0 && $question[0]['UID'] == $user['UID']) { 'SELECT `UID` FROM `Questions` WHERE `QID`=? LIMIT 1',
sql_query("DELETE FROM `Questions` WHERE `QID`='" . sql_escape($question_id) . "' LIMIT 1"); [$question_id]
redirect(page_link_to("user_questions")); );
if (!empty($question) && $question['UID'] == $user['UID']) {
DB::delete(
'DELETE FROM `Questions` WHERE `QID`=? LIMIT 1',
[$question_id]
);
redirect(page_link_to('user_questions'));
} else { } else {
return page_with_title(questions_title(), [ return page_with_title(questions_title(), [
error(_("No question found."), true) error(_('No question found.'), true)
]); ]);
} }
break; break;
} }
} }
return '';
} }
?>

View File

@ -1,65 +1,75 @@
<?php <?php
function settings_title() { use Engelsystem\Database\DB;
return _("Settings");
/**
* @return string
*/
function settings_title()
{
return _('Settings');
} }
/** /**
* Change user main attributes (name, dates, etc.) * Change user main attributes (name, dates, etc.)
* *
* @param User $user_source * @param array $user_source The user
* The user * @param bool $enable_tshirt_size
* @param array $tshirt_sizes
* @return array
*/ */
function user_settings_main($user_source, $enable_tshirt_size, $tshirt_sizes) { function user_settings_main($user_source, $enable_tshirt_size, $tshirt_sizes)
{
$valid = true; $valid = true;
$request = request();
if (isset($_REQUEST['mail'])) { if ($request->has('mail')) {
$result = User_validate_mail($_REQUEST['mail']); $result = User_validate_mail($request->input('mail'));
$user_source['email'] = $result->getValue(); $user_source['email'] = $result->getValue();
if (! $result->isValid()) { if (!$result->isValid()) {
$valid = false; $valid = false;
error(_("E-mail address is not correct.")); error(_('E-mail address is not correct.'));
} }
} else { } else {
$valid = false; $valid = false;
error(_("Please enter your e-mail.")); error(_('Please enter your e-mail.'));
} }
$user_source['email_shiftinfo'] = isset($_REQUEST['email_shiftinfo']); $user_source['email_shiftinfo'] = $request->has('email_shiftinfo');
$user_source['email_by_human_allowed'] = isset($_REQUEST['email_by_human_allowed']); $user_source['email_by_human_allowed'] = $request->has('email_by_human_allowed');
if (isset($_REQUEST['jabber'])) { if ($request->has('jabber')) {
$result = User_validate_jabber($_REQUEST['jabber']); $result = User_validate_jabber($request->input('jabber'));
$user_source['jabber'] = $result->getValue(); $user_source['jabber'] = $result->getValue();
if (! $result->isValid()) { if (!$result->isValid()) {
$valid = false; $valid = false;
error(_("Please check your jabber account information.")); error(_('Please check your jabber account information.'));
} }
} }
if (isset($_REQUEST['tshirt_size']) && isset($tshirt_sizes[$_REQUEST['tshirt_size']])) { if ($request->has('tshirt_size') && isset($tshirt_sizes[$request->input('tshirt_size')])) {
$user_source['Size'] = $_REQUEST['tshirt_size']; $user_source['Size'] = $request->input('tshirt_size');
} elseif ($enable_tshirt_size) { } elseif ($enable_tshirt_size) {
$valid = false; $valid = false;
} }
if (isset($_REQUEST['planned_arrival_date'])) { if ($request->has('planned_arrival_date')) {
$tmp = parse_date("Y-m-d H:i", $_REQUEST['planned_arrival_date'] . " 00:00"); $tmp = parse_date('Y-m-d H:i', $request->input('planned_arrival_date') . ' 00:00');
$result = User_validate_planned_arrival_date($tmp); $result = User_validate_planned_arrival_date($tmp);
$user_source['planned_arrival_date'] = $result->getValue(); $user_source['planned_arrival_date'] = $result->getValue();
if (! $result->isValid()) { if (!$result->isValid()) {
$valid = false; $valid = false;
error(_("Please enter your planned date of arrival. It should be after the buildup start date and before teardown end date.")); error(_('Please enter your planned date of arrival. It should be after the buildup start date and before teardown end date.'));
} }
} }
if (isset($_REQUEST['planned_departure_date'])) { if ($request->has('planned_departure_date')) {
$tmp = parse_date("Y-m-d H:i", $_REQUEST['planned_departure_date'] . " 00:00"); $tmp = parse_date('Y-m-d H:i', $request->input('planned_departure_date') . ' 00:00');
$result = User_validate_planned_departure_date($user_source['planned_arrival_date'], $tmp); $result = User_validate_planned_departure_date($user_source['planned_arrival_date'], $tmp);
$user_source['planned_departure_date'] = $result->getValue(); $user_source['planned_departure_date'] = $result->getValue();
if (! $result->isValid()) { if (!$result->isValid()) {
$valid = false; $valid = false;
error(_("Please enter your planned date of departure. It should be after your planned arrival date and after buildup start date and before teardown end date.")); error(_('Please enter your planned date of departure. It should be after your planned arrival date and after buildup start date and before teardown end date.'));
} }
} }
@ -68,13 +78,19 @@ function user_settings_main($user_source, $enable_tshirt_size, $tshirt_sizes) {
$user_source['Vorname'] = strip_request_item('prename', $user_source['Vorname']); $user_source['Vorname'] = strip_request_item('prename', $user_source['Vorname']);
$user_source['Alter'] = strip_request_item('age', $user_source['Alter']); $user_source['Alter'] = strip_request_item('age', $user_source['Alter']);
$user_source['Telefon'] = strip_request_item('tel', $user_source['Telefon']); $user_source['Telefon'] = strip_request_item('tel', $user_source['Telefon']);
if(strlen(strip_request_item('dect')) <= 5) {
$user_source['DECT'] = strip_request_item('dect', $user_source['DECT']); $user_source['DECT'] = strip_request_item('dect', $user_source['DECT']);
} else {
$valid = false;
error(_('For dect numbers are only 5 digits allowed.'));
}
$user_source['Handy'] = strip_request_item('mobile', $user_source['Handy']); $user_source['Handy'] = strip_request_item('mobile', $user_source['Handy']);
$user_source['Hometown'] = strip_request_item('hometown', $user_source['Hometown']); $user_source['Hometown'] = strip_request_item('hometown', $user_source['Hometown']);
if ($valid) { if ($valid) {
User_update($user_source); User_update($user_source);
success(_("Settings saved."));
success(_('Settings saved.'));
redirect(page_link_to('user_settings')); redirect(page_link_to('user_settings'));
} }
@ -84,21 +100,23 @@ function user_settings_main($user_source, $enable_tshirt_size, $tshirt_sizes) {
/** /**
* Change user password. * Change user password.
* *
* @param User $user_source * @param array $user_source The user
* The user
*/ */
function user_settings_password($user_source) { function user_settings_password($user_source)
global $min_password_length; {
if (! isset($_REQUEST['password']) || ! verify_password($_REQUEST['password'], $user_source['Passwort'], $user_source['UID'])) { $request = request();
error(_("-> not OK. Please try again.")); if (
} elseif (strlen($_REQUEST['new_password']) < $min_password_length) { !$request->has('password')
error(_("Your password is to short (please use at least 6 characters).")); || !verify_password($request->postData('password'), $user_source['Passwort'], $user_source['UID'])
} elseif ($_REQUEST['new_password'] != $_REQUEST['new_password2']) { ) {
error(_("Your passwords don't match.")); error(_('-> not OK. Please try again.'));
} elseif (set_password($user_source['UID'], $_REQUEST['new_password'])) { } elseif (strlen($request->postData('new_password')) < config('min_password_length')) {
success(_("Password saved.")); error(_('Your password is to short (please use at least 6 characters).'));
} elseif ($request->postData('new_password') != $request->postData('new_password2')) {
error(_('Your passwords don\'t match.'));
} else { } else {
error(_("Failed setting password.")); set_password($user_source['UID'], $request->postData('new_password'));
success(_('Password saved.'));
} }
redirect(page_link_to('user_settings')); redirect(page_link_to('user_settings'));
} }
@ -106,24 +124,34 @@ function user_settings_password($user_source) {
/** /**
* Change user theme * Change user theme
* *
* @param User $user_sources * @param array $user_source The user
* The user * @param array $themes List of available themes
* @param array<String> $themes * @return mixed
* List of available themes
*/ */
function user_settings_theme($user_source, $themes) { function user_settings_theme($user_source, $themes)
{
$valid = true; $valid = true;
$request = request();
if (isset($_REQUEST['theme']) && isset($themes[$_REQUEST['theme']])) { if ($request->has('theme') && isset($themes[$request->input('theme')])) {
$user_source['color'] = $_REQUEST['theme']; $user_source['color'] = $request->input('theme');
} else { } else {
$valid = false; $valid = false;
} }
if ($valid) { if ($valid) {
sql_query("UPDATE `User` SET `color`='" . sql_escape($user_source['color']) . "' WHERE `UID`='" . sql_escape($user_source['UID']) . "'"); DB::update('
UPDATE `User`
SET `color`=?
WHERE `UID`=?
',
[
$user_source['color'],
$user_source['UID'],
]
);
success(_("Theme changed.")); success(_('Theme changed.'));
redirect(page_link_to('user_settings')); redirect(page_link_to('user_settings'));
} }
@ -133,25 +161,36 @@ function user_settings_theme($user_source, $themes) {
/** /**
* Change use locale * Change use locale
* *
* @param User $user_source * @param array $user_source The user
* The user * @param array $locales List of available locales
* @param array<String> $locales * @return array
* List of available locales
*/ */
function user_settings_locale($user_source, $locales) { function user_settings_locale($user_source, $locales)
{
$valid = true; $valid = true;
$request = request();
$session = session();
if (isset($_REQUEST['language']) && isset($locales[$_REQUEST['language']])) { if ($request->has('language') && isset($locales[$request->input('language')])) {
$user_source['Sprache'] = $_REQUEST['language']; $user_source['Sprache'] = $request->input('language');
} else { } else {
$valid = false; $valid = false;
} }
if ($valid) { if ($valid) {
sql_query("UPDATE `User` SET `Sprache`='" . sql_escape($user_source['Sprache']) . "' WHERE `UID`='" . sql_escape($user_source['UID']) . "'"); DB::update('
$_SESSION['locale'] = $user_source['Sprache']; UPDATE `User`
SET `Sprache`=?
WHERE `UID`=?
',
[
$user_source['Sprache'],
$user_source['UID'],
]
);
$session->set('locale', $user_source['Sprache']);
success("Language changed."); success('Language changed.');
redirect(page_link_to('user_settings')); redirect(page_link_to('user_settings'));
} }
@ -160,10 +199,18 @@ function user_settings_locale($user_source, $locales) {
/** /**
* Main user settings page/controller * Main user settings page/controller
*
* @return string
*/ */
function user_settings() { function user_settings()
global $enable_tshirt_size, $tshirt_sizes, $themes, $locales; {
global $user; global $user;
$request = request();
$themes = config('available_themes');
$enable_tshirt_size = config('enable_tshirt_size');
$tshirt_sizes = config('tshirt_sizes');
$locales = config('locales');
$buildup_start_date = null; $buildup_start_date = null;
$teardown_end_date = null; $teardown_end_date = null;
@ -177,18 +224,31 @@ function user_settings() {
} }
} }
foreach ($tshirt_sizes as $key => $size) {
if (empty($size)) {
unset($tshirt_sizes[$key]);
}
}
$user_source = $user; $user_source = $user;
if (isset($_REQUEST['submit'])) { if ($request->has('submit')) {
$user_source = user_settings_main($user_source, $enable_tshirt_size, $tshirt_sizes); $user_source = user_settings_main($user_source, $enable_tshirt_size, $tshirt_sizes);
} elseif (isset($_REQUEST['submit_password'])) { } elseif ($request->has('submit_password')) {
user_settings_password($user_source); user_settings_password($user_source);
} elseif (isset($_REQUEST['submit_theme'])) { } elseif ($request->has('submit_theme')) {
$user_source = user_settings_theme($user_source, $themes); $user_source = user_settings_theme($user_source, $themes);
} elseif (isset($_REQUEST['submit_language'])) { } elseif ($request->has('submit_language')) {
$user_source = user_settings_locale($user_source, $locales); $user_source = user_settings_locale($user_source, $locales);
} }
return User_settings_view($user_source, $locales, $themes, $buildup_start_date, $teardown_end_date, $enable_tshirt_size, $tshirt_sizes); return User_settings_view(
$user_source,
$locales,
$themes,
$buildup_start_date,
$teardown_end_date,
$enable_tshirt_size,
$tshirt_sizes
);
} }
?>

View File

@ -1,8 +1,14 @@
<?php <?php
use Engelsystem\Database\DB;
use Engelsystem\ShiftsFilter; use Engelsystem\ShiftsFilter;
function shifts_title() { /**
return _("Shifts"); * @return string
*/
function shifts_title()
{
return _('Shifts');
} }
/** /**
@ -11,22 +17,27 @@ function shifts_title() {
* Transform into shift controller and shift entry controller. * Transform into shift controller and shift entry controller.
* Split actions into shift edit, shift delete, shift entry edit, shift entry delete * Split actions into shift edit, shift delete, shift entry edit, shift entry delete
* Introduce simpler and beautiful actions for shift entry join/leave for users * Introduce simpler and beautiful actions for shift entry join/leave for users
*
* @return string
*/ */
function user_shifts() { function user_shifts()
{
global $user; global $user;
$request = request();
if (User_is_freeloader($user)) { if (User_is_freeloader($user)) {
redirect(page_link_to('user_myshifts')); redirect(page_link_to('user_myshifts'));
} }
// Löschen einzelner Schicht-Einträge (Also Belegung einer Schicht von Engeln) durch Admins // Löschen einzelner Schicht-Einträge (Also Belegung einer Schicht von Engeln) durch Admins
if (isset($_REQUEST['entry_id'])) { if ($request->has('entry_id')) {
return shift_entry_delete_controller(); shift_entry_delete_controller();
} elseif (isset($_REQUEST['edit_shift'])) { return '';
} elseif ($request->has('edit_shift')) {
return shift_edit_controller(); return shift_edit_controller();
} elseif (isset($_REQUEST['delete_shift'])) { } elseif ($request->has('delete_shift')) {
return shift_delete_controller(); return shift_delete_controller();
} elseif (isset($_REQUEST['shift_id'])) { } elseif ($request->has('shift_id')) {
return shift_entry_add_controller(); return shift_entry_add_controller();
} }
return view_user_shifts(); return view_user_shifts();
@ -36,10 +47,11 @@ function user_shifts() {
* Helper function that updates the start and end time from request data. * Helper function that updates the start and end time from request data.
* Use update_ShiftsFilter(). * Use update_ShiftsFilter().
* *
* @param ShiftsFilter $shiftsFilter * @param ShiftsFilter $shiftsFilter The shiftfilter to update.
* The shiftfilter to update. * @param string[] $days
*/ */
function update_ShiftsFilter_timerange(ShiftsFilter $shiftsFilter, $days) { function update_ShiftsFilter_timerange(ShiftsFilter $shiftsFilter, $days)
{
$start_time = $shiftsFilter->getStartTime(); $start_time = $shiftsFilter->getStartTime();
if ($start_time == null) { if ($start_time == null) {
$start_time = time(); $start_time = time();
@ -61,14 +73,12 @@ function update_ShiftsFilter_timerange(ShiftsFilter $shiftsFilter, $days) {
/** /**
* Update given ShiftsFilter with filter params from user input * Update given ShiftsFilter with filter params from user input
* *
* @param ShiftsFilter $shiftsFilter * @param ShiftsFilter $shiftsFilter The shifts filter to update from request data
* The shifts filter to update from request data * @param boolean $user_shifts_admin Has the user user_shift_admin privilege?
* @param boolean $user_shifts_admin * @param string[] $days An array of available filter days
* Has the user user_shift_admin privilege?
* @param string[] $days
* An array of available filter days
*/ */
function update_ShiftsFilter(ShiftsFilter $shiftsFilter, $user_shifts_admin, $days) { function update_ShiftsFilter(ShiftsFilter $shiftsFilter, $user_shifts_admin, $days)
{
$shiftsFilter->setUserShiftsAdmin($user_shifts_admin); $shiftsFilter->setUserShiftsAdmin($user_shifts_admin);
$shiftsFilter->setFilled(check_request_int_array('filled', $shiftsFilter->getFilled())); $shiftsFilter->setFilled(check_request_int_array('filled', $shiftsFilter->getFilled()));
$shiftsFilter->setRooms(check_request_int_array('rooms', $shiftsFilter->getRooms())); $shiftsFilter->setRooms(check_request_int_array('rooms', $shiftsFilter->getRooms()));
@ -76,122 +86,198 @@ function update_ShiftsFilter(ShiftsFilter $shiftsFilter, $user_shifts_admin, $da
update_ShiftsFilter_timerange($shiftsFilter, $days); update_ShiftsFilter_timerange($shiftsFilter, $days);
} }
function load_rooms() { /**
$rooms = sql_select("SELECT `RID` AS `id`, `Name` AS `name` FROM `Room` WHERE `show`='Y' ORDER BY `Name`"); * @return array
if (count($rooms) == 0) { */
error(_("The administration has not configured any rooms yet.")); function load_rooms()
redirect('?'); {
$rooms = DB::select(
'SELECT `RID` AS `id`, `Name` AS `name` FROM `Room` WHERE `show`=\'Y\' ORDER BY `Name`'
);
if (empty($rooms)) {
error(_('The administration has not configured any rooms yet.'));
redirect(page_link_to('/'));
} }
return $rooms; return $rooms;
} }
function load_days() { /**
$days = sql_select_single_col(" * @return array
*/
function load_days()
{
$days = DB::select('
SELECT DISTINCT DATE(FROM_UNIXTIME(`start`)) AS `id`, DATE(FROM_UNIXTIME(`start`)) AS `name` SELECT DISTINCT DATE(FROM_UNIXTIME(`start`)) AS `id`, DATE(FROM_UNIXTIME(`start`)) AS `name`
FROM `Shifts` FROM `Shifts`
ORDER BY `start`"); ORDER BY `id`, `name`
if (count($days) == 0) { ');
error(_("The administration has not configured any shifts yet.")); $days = array_map('array_shift', $days);
redirect('?');
if (empty($days)) {
error(_('The administration has not configured any shifts yet.'));
redirect(page_link_to('/'));
} }
return $days; return $days;
} }
function load_types() { /**
* @return array|false
*/
function load_types()
{
global $user; global $user;
if (sql_num_query("SELECT `id`, `name` FROM `AngelTypes` WHERE `restricted` = 0") == 0) { if (!count(DB::select('SELECT `id`, `name` FROM `AngelTypes` WHERE `restricted` = 0'))) {
error(_("The administration has not configured any angeltypes yet - or you are not subscribed to any angeltype.")); error(_('The administration has not configured any angeltypes yet - or you are not subscribed to any angeltype.'));
redirect('?'); redirect(page_link_to('/'));
} }
$types = sql_select("SELECT `AngelTypes`.`id`, `AngelTypes`.`name`, (`AngelTypes`.`restricted`=0 OR (NOT `UserAngelTypes`.`confirm_user_id` IS NULL OR `UserAngelTypes`.`id` IS NULL)) as `enabled` FROM `AngelTypes` LEFT JOIN `UserAngelTypes` ON (`UserAngelTypes`.`angeltype_id`=`AngelTypes`.`id` AND `UserAngelTypes`.`user_id`='" . sql_escape($user['UID']) . "') ORDER BY `AngelTypes`.`name`"); $types = DB::select('
SELECT
`AngelTypes`.`id`,
`AngelTypes`.`name`,
(
`AngelTypes`.`restricted`=0
OR (
NOT `UserAngelTypes`.`confirm_user_id` IS NULL
OR `UserAngelTypes`.`id` IS NULL
)
) AS `enabled`
FROM `AngelTypes`
LEFT JOIN `UserAngelTypes`
ON (
`UserAngelTypes`.`angeltype_id`=`AngelTypes`.`id`
AND `UserAngelTypes`.`user_id`=?
)
ORDER BY `AngelTypes`.`name`
',
[
$user['UID'],
]
);
if (empty($types)) { if (empty($types)) {
return sql_select("SELECT `id`, `name` FROM `AngelTypes` WHERE `restricted` = 0"); return DB::select('SELECT `id`, `name` FROM `AngelTypes` WHERE `restricted` = 0');
} }
return $types; return $types;
} }
function view_user_shifts() { /**
global $user, $privileges; * @return string
global $ical_shifts; */
function view_user_shifts()
{
global $user, $privileges, $ical_shifts;
$session = session();
$ical_shifts = []; $ical_shifts = [];
$days = load_days(); $days = load_days();
$rooms = load_rooms(); $rooms = load_rooms();
$types = load_types(); $types = load_types();
if (! isset($_SESSION['ShiftsFilter'])) { if (!$session->has('ShiftsFilter')) {
$room_ids = [ $room_ids = [
$rooms[0]['id'] $rooms[0]['id']
]; ];
$type_ids = array_map('get_ids_from_array', $types); $type_ids = array_map('get_ids_from_array', $types);
$_SESSION['ShiftsFilter'] = new ShiftsFilter(in_array('user_shifts_admin', $privileges), $room_ids, $type_ids); $shiftsFilter = new ShiftsFilter(in_array('user_shifts_admin', $privileges), $room_ids, $type_ids);
$session->set('ShiftsFilter', $shiftsFilter);
} }
update_ShiftsFilter($_SESSION['ShiftsFilter'], in_array('user_shifts_admin', $privileges), $days);
$shiftsFilter = $_SESSION['ShiftsFilter']; $shiftsFilter = $session->get('ShiftsFilter');
update_ShiftsFilter($shiftsFilter, in_array('user_shifts_admin', $privileges), $days);
$shiftCalendarRenderer = shiftCalendarRendererByShiftFilter($shiftsFilter); $shiftCalendarRenderer = shiftCalendarRendererByShiftFilter($shiftsFilter);
if ($user['api_key'] == "") { if ($user['api_key'] == '') {
User_reset_api_key($user, false); User_reset_api_key($user, false);
} }
$filled = [ $filled = [
[ [
'id' => '1', 'id' => '1',
'name' => _("occupied") 'name' => _('occupied')
], ],
[ [
'id' => '0', 'id' => '0',
'name' => _("free") 'name' => _('free')
] ]
]; ];
$start_day = date("Y-m-d", $shiftsFilter->getStartTime()); $start_day = date('Y-m-d', $shiftsFilter->getStartTime());
$start_time = date("H:i", $shiftsFilter->getStartTime()); $start_time = date('H:i', $shiftsFilter->getStartTime());
$end_day = date("Y-m-d", $shiftsFilter->getEndTime()); $end_day = date('Y-m-d', $shiftsFilter->getEndTime());
$end_time = date("H:i", $shiftsFilter->getEndTime()); $end_time = date('H:i', $shiftsFilter->getEndTime());
$assignNotice = '';
if (config('signup_requires_arrival') && !$user['Gekommen']) {
$assignNotice = info(render_user_arrived_hint(), true);
}
return page([ return page([
div('col-md-12', [ div('col-md-12', [
msg(), msg(),
template_render(__DIR__ . '/../../templates/user_shifts.html', [ view(__DIR__ . '/../../templates/user_shifts.html', [
'title' => shifts_title(), 'title' => shifts_title(),
'room_select' => make_select($rooms, $shiftsFilter->getRooms(), "rooms", _("Rooms")), 'room_select' => make_select($rooms, $shiftsFilter->getRooms(), 'rooms', _('Rooms')),
'start_select' => html_select_key("start_day", "start_day", array_combine($days, $days), $start_day), 'start_select' => html_select_key('start_day', 'start_day', array_combine($days, $days), $start_day),
'start_time' => $start_time, 'start_time' => $start_time,
'end_select' => html_select_key("end_day", "end_day", array_combine($days, $days), $end_day), 'end_select' => html_select_key('end_day', 'end_day', array_combine($days, $days), $end_day),
'end_time' => $end_time, 'end_time' => $end_time,
'type_select' => make_select($types, $shiftsFilter->getTypes(), "types", _("Angeltypes") . '<sup>1</sup>'), 'type_select' => make_select(
'filled_select' => make_select($filled, $shiftsFilter->getFilled(), "filled", _("Occupancy")), $types,
'task_notice' => '<sup>1</sup>' . _("The tasks shown here are influenced by the angeltypes you joined already!") . " <a href=\"" . page_link_to('angeltypes') . '&action=about' . "\">" . _("Description of the jobs.") . "</a>", $shiftsFilter->getTypes(),
'types',
_('Angeltypes') . '<sup>1</sup>'
),
'filled_select' => make_select($filled, $shiftsFilter->getFilled(), 'filled', _('Occupancy')),
'task_notice' =>
'<sup>1</sup>'
. _('The tasks shown here are influenced by the angeltypes you joined already!')
. ' <a href="' . page_link_to('angeltypes', ['action' => 'about']) . '">'
. _('Description of the jobs.')
. '</a>',
'assign_notice' => $assignNotice,
'shifts_table' => msg() . $shiftCalendarRenderer->render(), 'shifts_table' => msg() . $shiftCalendarRenderer->render(),
'ical_text' => '<h2>' . _("iCal export") . '</h2><p>' . sprintf(_("Export of shown shifts. <a href=\"%s\">iCal format</a> or <a href=\"%s\">JSON format</a> available (please keep secret, otherwise <a href=\"%s\">reset the api key</a>)."), page_link_to_absolute('ical') . '&key=' . $user['api_key'], page_link_to_absolute('shifts_json_export') . '&key=' . $user['api_key'], page_link_to('user_myshifts') . '&reset') . '</p>', 'ical_text' => '<h2>' . _('iCal export') . '</h2><p>' . sprintf(
'filter' => _("Filter") _('Export of shown shifts. <a href="%s">iCal format</a> or <a href="%s">JSON format</a> available (please keep secret, otherwise <a href="%s">reset the api key</a>).'),
page_link_to('ical', ['key' => $user['api_key']]),
page_link_to('shifts_json_export', ['key' => $user['api_key']]),
page_link_to('user_myshifts', ['reset' => 1])
) . '</p>',
'filter' => _('Filter')
]) ])
]) ])
]); ]);
} }
function get_ids_from_array($array) { /**
return $array["id"]; * @param array $array
* @return array
*/
function get_ids_from_array($array)
{
return $array['id'];
} }
function make_select($items, $selected, $name, $title = null) { function make_select($items, $selected, $name, $title = null)
{
$html_items = []; $html_items = [];
if (isset($title)) { if (isset($title)) {
$html_items[] = '<h4>' . $title . '</h4>' . "\n"; $html_items[] = '<h4>' . $title . '</h4>' . "\n";
} }
foreach ($items as $i) { foreach ($items as $i) {
$html_items[] = '<div class="checkbox"><label><input type="checkbox" name="' . $name . '[]" value="' . $i['id'] . '"' . (in_array($i['id'], $selected) ? ' checked="checked"' : '') . '> ' . $i['name'] . '</label>' . (! isset($i['enabled']) || $i['enabled'] ? '' : glyph("lock")) . '</div><br />'; $html_items[] = '<div class="checkbox">'
. '<label><input type="checkbox" name="' . $name . '[]" value="' . $i['id'] . '" '
. (in_array($i['id'], $selected) ? ' checked="checked"' : '')
. ' > ' . $i['name'] . '</label>'
. (!isset($i['enabled']) || $i['enabled'] ? '' : glyph('lock'))
. '</div><br />';
} }
$html = '<div id="selection_' . $name . '" class="selection ' . $name . '">' . "\n"; $html = '<div id="selection_' . $name . '" class="selection ' . $name . '">' . "\n";
$html .= implode("\n", $html_items); $html .= implode("\n", $html_items);
$html .= buttons([ $html .= buttons([
button("javascript: checkAll('selection_" . $name . "', true)", _("All"), ""), button('javascript: checkAll(\'selection_' . $name . '\', true)', _('All'), ''),
button("javascript: checkAll('selection_" . $name . "', false)", _("None"), "") button('javascript: checkAll(\'selection_' . $name . '\', false)', _('None'), '')
]); ]);
$html .= '</div>' . "\n"; $html .= '</div>' . "\n";
return $html; return $html;
} }
?>

View File

@ -1,35 +1,52 @@
<?php <?php
use Engelsystem\Database\DB;
/** /**
* Testet ob ein User eingeloggt ist und lädt die entsprechenden Privilegien * Testet ob ein User eingeloggt ist und lädt die entsprechenden Privilegien
*/ */
function load_auth() { function load_auth()
{
global $user, $privileges; global $user, $privileges;
$user = null; $user = null;
if (isset($_SESSION['uid'])) { $session = session();
$user = sql_select("SELECT * FROM `User` WHERE `UID`='" . sql_escape($_SESSION['uid']) . "' LIMIT 1");
if (count($user) > 0) { if ($session->has('uid')) {
$user = DB::selectOne('SELECT * FROM `User` WHERE `UID`=? LIMIT 1', [$session->get('uid')]);
if (!empty($user)) {
// User ist eingeloggt, Datensatz zur Verfügung stellen und Timestamp updaten // User ist eingeloggt, Datensatz zur Verfügung stellen und Timestamp updaten
list($user) = $user; DB::update('
sql_query("UPDATE `User` SET " . "`lastLogIn` = '" . time() . "'" . " WHERE `UID` = '" . sql_escape($_SESSION['uid']) . "' LIMIT 1;"); UPDATE `User`
SET `lastLogIn` = ?
WHERE `UID` = ?
LIMIT 1
', [
time(),
$session->get('uid'),
]);
$privileges = privileges_for_user($user['UID']); $privileges = privileges_for_user($user['UID']);
return; return;
} }
unset($_SESSION['uid']);
$session->remove('uid');
} }
// guest privileges // guest privileges
$privileges = privileges_for_group(- 1); $privileges = privileges_for_group(-10);
} }
/** /**
* generate a salt (random string) of arbitrary length suitable for the use with crypt() * generate a salt (random string) of arbitrary length suitable for the use with crypt()
*
* @param int $length
* @return string
*/ */
function generate_salt($length = 16) { function generate_salt($length = 16)
$alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; {
$salt = ""; $alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
for ($i = 0; $i < $length; $i ++) { $salt = '';
for ($i = 0; $i < $length; $i++) {
$salt .= $alphabet[rand(0, strlen($alphabet) - 1)]; $salt .= $alphabet[rand(0, strlen($alphabet) - 1)];
} }
return $salt; return $salt;
@ -37,22 +54,38 @@ function generate_salt($length = 16) {
/** /**
* set the password of a user * set the password of a user
*
* @param int $uid
* @param string $password
*/ */
function set_password($uid, $password) { function set_password($uid, $password)
global $crypt_alg; {
$result = sql_query("UPDATE `User` SET `Passwort` = '" . sql_escape(crypt($password, $crypt_alg . '$' . generate_salt(16) . '$')) . "', `password_recovery_token`=NULL WHERE `UID` = " . intval($uid) . " LIMIT 1"); DB::update('
if ($result === false) { UPDATE `User`
engelsystem_error('Unable to update password.'); SET `Passwort` = ?,
} `password_recovery_token`=NULL
return $result; WHERE `UID` = ?
LIMIT 1
',
[
crypt($password, config('crypt_alg') . '$' . generate_salt(16) . '$'),
$uid
]
);
} }
/** /**
* verify a password given a precomputed salt. * verify a password given a precomputed salt.
* if $uid is given and $salt is an old-style salt (plain md5), we convert it automatically * if $uid is given and $salt is an old-style salt (plain md5), we convert it automatically
*
* @param string $password
* @param string $salt
* @param int $uid
* @return bool
*/ */
function verify_password($password, $salt, $uid = false) { function verify_password($password, $salt, $uid = null)
global $crypt_alg; {
$crypt_alg = config('crypt_alg');
$correct = false; $correct = false;
if (substr($salt, 0, 1) == '$') { // new-style crypt() if (substr($salt, 0, 1) == '$') { // new-style crypt()
$correct = crypt($password, $salt) == $salt; $correct = crypt($password, $salt) == $salt;
@ -62,30 +95,63 @@ function verify_password($password, $salt, $uid = false) {
$correct = md5($password) == $salt; $correct = md5($password) == $salt;
} }
if ($correct && substr($salt, 0, strlen($crypt_alg)) != $crypt_alg && $uid) { if ($correct && substr($salt, 0, strlen($crypt_alg)) != $crypt_alg && intval($uid)) {
// this password is stored in another format than we want it to be. // this password is stored in another format than we want it to be.
// let's update it! // let's update it!
// we duplicate the query from the above set_password() function to have the extra safety of checking the old hash // we duplicate the query from the above set_password() function to have the extra safety of checking the old hash
sql_query("UPDATE `User` SET `Passwort` = '" . sql_escape(crypt($password, $crypt_alg . '$' . generate_salt() . '$')) . "' WHERE `UID` = " . intval($uid) . " AND `Passwort` = '" . sql_escape($salt) . "' LIMIT 1"); DB::update('
UPDATE `User`
SET `Passwort` = ?
WHERE `UID` = ?
AND `Passwort` = ?
LIMIT 1
',
[
crypt($password, $crypt_alg . '$' . generate_salt() . '$'),
$uid,
$salt,
]
);
} }
return $correct; return $correct;
} }
function privileges_for_user($user_id) { /**
* @param int $user_id
* @return array
*/
function privileges_for_user($user_id)
{
$privileges = []; $privileges = [];
$user_privs = sql_select("SELECT `Privileges`.`name` FROM `User` JOIN `UserGroups` ON (`User`.`UID` = `UserGroups`.`uid`) JOIN `GroupPrivileges` ON (`UserGroups`.`group_id` = `GroupPrivileges`.`group_id`) JOIN `Privileges` ON (`GroupPrivileges`.`privilege_id` = `Privileges`.`id`) WHERE `User`.`UID`='" . sql_escape($user_id) . "'"); $user_privileges = DB::select('
foreach ($user_privs as $user_priv) { SELECT `Privileges`.`name`
$privileges[] = $user_priv['name']; FROM `User`
JOIN `UserGroups` ON (`User`.`UID` = `UserGroups`.`uid`)
JOIN `GroupPrivileges` ON (`UserGroups`.`group_id` = `GroupPrivileges`.`group_id`)
JOIN `Privileges` ON (`GroupPrivileges`.`privilege_id` = `Privileges`.`id`)
WHERE `User`.`UID`=?
', [$user_id]);
foreach ($user_privileges as $user_privilege) {
$privileges[] = $user_privilege['name'];
} }
return $privileges; return $privileges;
} }
function privileges_for_group($group_id) { /**
* @param int $group_id
* @return array
*/
function privileges_for_group($group_id)
{
$privileges = []; $privileges = [];
$groups_privs = sql_select("SELECT * FROM `GroupPrivileges` JOIN `Privileges` ON (`GroupPrivileges`.`privilege_id` = `Privileges`.`id`) WHERE `group_id`='" . sql_escape($group_id) . "'"); $groups_privileges = DB::select('
foreach ($groups_privs as $guest_priv) { SELECT `name`
$privileges[] = $guest_priv['name']; FROM `GroupPrivileges`
JOIN `Privileges` ON (`GroupPrivileges`.`privilege_id` = `Privileges`.`id`)
WHERE `group_id`=?
', [$group_id]);
foreach ($groups_privileges as $guest_privilege) {
$privileges[] = $guest_privilege['name'];
} }
return $privileges; return $privileges;
} }
?>

View File

@ -4,23 +4,28 @@
/** /**
* Renders a hidden input * Renders a hidden input
* *
* @param string $name * @param string $name Name of the input
* Name of the input * @param string $value The value
* @param string $value
* The value
* @return string rendered html * @return string rendered html
*/ */
function form_hidden($name, $value) { function form_hidden($name, $value)
return '<input type="hidden" name="' . $name . '" value="' . $value . '" />'; {
return '<input type="hidden" name="' . $name . '" value="' . htmlspecialchars($value) . '" />';
} }
/** /**
* Rendert ein Zahlenfeld mit Buttons zum verstellen * Rendert ein Zahlenfeld mit Buttons zum verstellen
*
* @param string $name
* @param string $label
* @param string $value
* @return string
*/ */
function form_spinner($name, $label, $value) { function form_spinner($name, $label, $value)
{
return form_element($label, ' return form_element($label, '
<div class="input-group"> <div class="input-group">
<input id="spinner-' . $name . '" class="form-control" type="text" name="' . $name . '" value="' . $value . '" /> <input id="spinner-' . $name . '" class="form-control" name="' . $name . '" value="' . htmlspecialchars($value) . '" />
<div class="input-group-btn"> <div class="input-group-btn">
<button id="spinner-' . $name . '-down" class="btn btn-default" type="button"> <button id="spinner-' . $name . '-down" class="btn btn-default" type="button">
<span class="glyphicon glyphicon-minus"></span> <span class="glyphicon glyphicon-minus"></span>
@ -31,11 +36,13 @@ function form_spinner($name, $label, $value) {
</div> </div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
$("#spinner-' . $name . '-down").click(function(e) { $("#spinner-' . $name . '-down").click(function() {
$("#spinner-' . $name . '").val(parseInt($("#spinner-' . $name . '").val()) - 1); var spinner = $("#spinner-' . $name . '");
spinner.val(parseInt(spinner.val()) - 1);
}); });
$("#spinner-' . $name . '-up").click(function(e) { $("#spinner-' . $name . '-up").click(function() {
$("#spinner-' . $name . '").val(parseInt($("#spinner-' . $name . '").val()) + 1); var spinner = $("#spinner-' . $name . '");
spinner.val(parseInt(spinner.val()) + 1);
}); });
</script> </script>
'); ');
@ -44,24 +51,23 @@ function form_spinner($name, $label, $value) {
/** /**
* Render a bootstrap datepicker * Render a bootstrap datepicker
* *
* @param string $name * @param string $name Name of the parameter
* Name of the parameter * @param string $label Label
* @param string $label * @param int $value Unix Timestamp
* Label * @param string $start_date Earliest possible date
* @param int $value * @param string $end_date
* Unix Timestamp * @return string HTML
* @param int $min_date
* Earliest possible date
* @return HTML
*/ */
function form_date($name, $label, $value, $start_date = '', $end_date = '') { function form_date($name, $label, $value, $start_date = '', $end_date = '')
{
$dom_id = $name . '-date'; $dom_id = $name . '-date';
$value = is_numeric($value) ? date('Y-m-d', $value) : ''; $value = is_numeric($value) ? date('Y-m-d', $value) : '';
$start_date = is_numeric($start_date) ? date('Y-m-d', $start_date) : ''; $start_date = is_numeric($start_date) ? date('Y-m-d', $start_date) : '';
$end_date = is_numeric($end_date) ? date('Y-m-d', $end_date) : ''; $end_date = is_numeric($end_date) ? date('Y-m-d', $end_date) : '';
return form_element($label, ' return form_element($label, '
<div class="input-group date" id="' . $dom_id . '"> <div class="input-group date" id="' . $dom_id . '">
<input type="text" name="' . $name . '" class="form-control" value="' . $value . '"><span class="input-group-addon">' . glyph('th') . '</span> <input name="' . $name . '" class="form-control" value="' . htmlspecialchars($value) . '">'
. '<span class="input-group-addon">' . glyph('th') . '</span>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
$(function(){ $(function(){
@ -80,16 +86,14 @@ function form_date($name, $label, $value, $start_date = '', $end_date = '') {
/** /**
* Rendert eine Liste von Checkboxen für ein Formular * Rendert eine Liste von Checkboxen für ein Formular
* *
* @param * @param string $name Die Namen der Checkboxen werden aus name_key gebildet
* name Die Namen der Checkboxen werden aus name_key gebildet * @param string $label Die Beschriftung der Liste
* @param * @param array $items Array mit den einzelnen Checkboxen
* label Die Beschriftung der Liste * @param array $selected Array mit den Keys, die ausgewählt sind
* @param * @return string
* items Array mit den einzelnen Checkboxen
* @param
* selected Array mit den Keys, die ausgewählt sind
*/ */
function form_checkboxes($name, $label, $items, $selected) { function form_checkboxes($name, $label, $items, $selected)
{
$html = form_element($label, ''); $html = form_element($label, '');
foreach ($items as $key => $item) { foreach ($items as $key => $item) {
$html .= form_checkbox($name . '_' . $key, $item, array_search($key, $selected) !== false); $html .= form_checkbox($name . '_' . $key, $item, array_search($key, $selected) !== false);
@ -100,61 +104,94 @@ function form_checkboxes($name, $label, $items, $selected) {
/** /**
* Rendert eine Tabelle von Checkboxen für ein Formular * Rendert eine Tabelle von Checkboxen für ein Formular
* *
* @param * @param string[] $names Assoziatives Array mit Namen der Checkboxen als Keys und Überschriften als Values
* names Assoziatives Array mit Namen der Checkboxen als Keys und Überschriften als Values * @param string $label Die Beschriftung der gesamten Tabelle
* @param * @param string[] $items Array mit den Beschriftungen der Zeilen
* label Die Beschriftung der gesamten Tabelle * @param array[] $selected Mehrdimensionales Array, wobei $selected[foo] ein Array der in der Datenreihe foo
* @param * markierten Checkboxen ist
* items Array mit den Beschriftungen der Zeilen * @param array $disabled Wie selected, nur dass die entsprechenden Checkboxen deaktiviert statt markiert sind
* @param * @return string
* selected Mehrdimensionales Array, wobei $selected[foo] ein Array der in der Datenreihe foo markierten Checkboxen ist
* @param
* disabled Wie selected, nur dass die entsprechenden Checkboxen deaktiviert statt markiert sind
*/ */
function form_multi_checkboxes($names, $label, $items, $selected, $disabled = []) { function form_multi_checkboxes($names, $label, $items, $selected, $disabled = [])
$html = "<table><thead><tr>"; {
$html = '<table><thead><tr>';
foreach ($names as $title) { foreach ($names as $title) {
$html .= "<th>$title</th>"; $html .= '<th>' . $title . '</th>';
} }
$html .= "</tr></thead><tbody>"; $html .= '</tr></thead><tbody>';
foreach ($items as $key => $item) { foreach ($items as $key => $item) {
$html .= "<tr>"; $html .= '<tr>';
$dom_id = '';
foreach ($names as $name => $title) { foreach ($names as $name => $title) {
$dom_id = $name . '_' . $key; $dom_id = $name . '_' . $key;
$sel = array_search($key, $selected[$name]) !== false ? ' checked="checked"' : ""; $sel = array_search($key, $selected[$name]) !== false ? ' checked="checked"' : '';
if (! empty($disabled) && ! empty($disabled[$name]) && array_search($key, $disabled[$name]) !== false) { if (!empty($disabled) && !empty($disabled[$name]) && array_search($key, $disabled[$name]) !== false) {
$sel .= ' disabled="disabled"'; $sel .= ' disabled="disabled"';
} }
$html .= '<td style="text-align: center;"><input type="checkbox" id="' . $dom_id . '" name="' . $name . '[]" value="' . $key . '"' . $sel . ' /></td>'; $html .= '<td style="text-align: center;">'
. '<input type="checkbox" id="' . $dom_id . '" name="' . $name . '[]" value="' . $key . '" ' . $sel . ' />'
. '</td>';
} }
$html .= '<td><label for="' . $dom_id . '">' . $item . '</label></td></tr>'; $html .= '<td><label for="' . $dom_id . '">' . $item . '</label></td></tr>';
} }
$html .= "</tbody></table>"; $html .= '</tbody></table>';
return form_element($label, $html); return form_element($label, $html);
} }
/** /**
* Rendert eine Checkbox * Rendert eine Checkbox
*
* @param string $name
* @param string $label
* @param string $selected
* @param string $value
* @param string $id
* @return string
*/ */
function form_checkbox($name, $label, $selected, $value = 'checked') { function form_checkbox($name, $label, $selected, $value = 'checked', $id = null)
return '<div class="checkbox"><label><input type="checkbox" id="' . $name . '" name="' . $name . '" value="' . $value . '"' . ($selected ? ' checked="checked"' : '') . ' /> ' . $label . '</label></div>'; {
if (is_null($id)) {
$id = $name;
}
return '<div class="checkbox"><label>'
. '<input type="checkbox" id="' . $id . '" name="' . $name . '" value="' . htmlspecialchars($value) . '" '
. ($selected ? ' checked="checked"' : '') . ' /> '
. $label
. '</label></div>';
} }
/** /**
* Rendert einen Radio * Rendert einen Radio
*
* @param string $name
* @param string $label
* @param string $selected
* @param string $value
* @return string
*/ */
function form_radio($name, $label, $selected, $value) { function form_radio($name, $label, $selected, $value)
return '<div class="radio"><label><input type="radio" id="' . $name . '" name="' . $name . '" value="' . $value . '"' . ($selected ? ' checked="checked"' : '') . ' /> ' . $label . '</label></div>'; {
return '<div class="radio">'
. '<label><input type="radio" id="' . $name . '" name="' . $name . '" value="' . htmlspecialchars($value) . '" '
. ($selected ? ' checked="checked"' : '') . ' /> '
. $label
. '</label></div>';
} }
/** /**
* Rendert einen Infotext in das Formular * Rendert einen Infotext in das Formular
*
* @param string $label
* @param string $text
* @return string
*/ */
function form_info($label, $text = "") { function form_info($label, $text = '')
if ($label == "") { {
if ($label == '') {
return '<span class="help-block">' . glyph('info-sign') . $text . '</span>'; return '<span class="help-block">' . glyph('info-sign') . $text . '</span>';
} }
if ($text == "") { if ($text == '') {
return '<h4>' . $label . '</h4>'; return '<h4>' . $label . '</h4>';
} }
return form_element($label, '<p class="form-control-static">' . $text . '</p>', ''); return form_element($label, '<p class="form-control-static">' . $text . '</p>', '');
@ -162,86 +199,171 @@ function form_info($label, $text = "") {
/** /**
* Rendert den Absenden-Button eines Formulars * Rendert den Absenden-Button eines Formulars
*
* @param string $name
* @param string $label
* @return string
*/ */
function form_submit($name, $label) { function form_submit($name, $label)
return form_element('<input class="btn btn-primary" type="submit" name="' . $name . '" value="' . $label . '" />', ""); {
return form_element(
'<input class="btn btn-primary" type="submit" name="' . $name . '" value="' . $label . '" />',
''
);
} }
/** /**
* Rendert ein Formular-Textfeld * Rendert ein Formular-Textfeld
*
* @param string $name
* @param string $label
* @param string $value
* @param bool $disabled
* @return string
*/ */
function form_text($name, $label, $value, $disabled = false) { function form_text($name, $label, $value, $disabled = false)
{
$disabled = $disabled ? ' disabled="disabled"' : ''; $disabled = $disabled ? ' disabled="disabled"' : '';
return form_element($label, '<input class="form-control" id="form_' . $name . '" type="text" name="' . $name . '" value="' . htmlspecialchars($value) . '" ' . $disabled . '/>', 'form_' . $name); return form_element(
$label,
'<input class="form-control" id="form_' . $name . '" type="text" name="' . $name
. '" value="' . htmlspecialchars($value) . '" ' . $disabled . '/>',
'form_' . $name
);
} }
/** /**
* Renders a text input with placeholder instead of label. * Renders a text input with placeholder instead of label.
* *
* @param String $name * @param String $name Input name
* Input name * @param String $placeholder Placeholder
* @param String $placeholder * @param String $value The value
* Placeholder * @param Boolean $disabled Is the field enabled?
* @param String $value * @return string
* The value
* @param Boolean $disabled
* Is the field enabled?
*/ */
function form_text_placeholder($name, $placeholder, $value, $disabled = false) { function form_text_placeholder($name, $placeholder, $value, $disabled = false)
{
$disabled = $disabled ? ' disabled="disabled"' : ''; $disabled = $disabled ? ' disabled="disabled"' : '';
return form_element('', '<input class="form-control" id="form_' . $name . '" type="text" name="' . $name . '" value="' . htmlspecialchars($value) . '" placeholder="' . $placeholder . '" ' . $disabled . '/>'); return form_element('',
'<input class="form-control" id="form_' . $name . '" type="text" name="' . $name
. '" value="' . htmlspecialchars($value) . '" placeholder="' . $placeholder
. '" ' . $disabled . '/>'
);
} }
/** /**
* Rendert ein Formular-Emailfeld * Rendert ein Formular-Emailfeld
*
* @param string $name
* @param string $label
* @param string $value
* @param bool $disabled
* @return string
*/ */
function form_email($name, $label, $value, $disabled = false) { function form_email($name, $label, $value, $disabled = false)
{
$disabled = $disabled ? ' disabled="disabled"' : ''; $disabled = $disabled ? ' disabled="disabled"' : '';
return form_element($label, '<input class="form-control" id="form_' . $name . '" type="email" name="' . $name . '" value="' . htmlspecialchars($value) . '" ' . $disabled . '/>', 'form_' . $name); return form_element(
$label,
'<input class="form-control" id="form_' . $name . '" type="email" name="' . $name . '" value="'
. htmlspecialchars($value) . '" ' . $disabled . '/>',
'form_' . $name
);
} }
/** /**
* Rendert ein Formular-Dateifeld * Rendert ein Formular-Dateifeld
*
* @param string $name
* @param string $label
* @return string
*/ */
function form_file($name, $label) { function form_file($name, $label)
{
return form_element($label, '<input id="form_' . $name . '" type="file" name="' . $name . '" />', 'form_' . $name); return form_element($label, '<input id="form_' . $name . '" type="file" name="' . $name . '" />', 'form_' . $name);
} }
/** /**
* Rendert ein Formular-Passwortfeld * Rendert ein Formular-Passwortfeld
*
* @param string $name
* @param string $label
* @param bool $disabled
* @return string
*/ */
function form_password($name, $label, $disabled = false) { function form_password($name, $label, $disabled = false)
{
$disabled = $disabled ? ' disabled="disabled"' : ''; $disabled = $disabled ? ' disabled="disabled"' : '';
return form_element($label, '<input class="form-control" id="form_' . $name . '" type="password" name="' . $name . '" value="" ' . $disabled . '/>', 'form_' . $name); return form_element(
$label,
'<input class="form-control" id="form_' . $name . '" type="password" name="' . $name . '" value="" ' . $disabled . '/>',
'form_' . $name
);
} }
/** /**
* Renders a password input with placeholder instead of label. * Renders a password input with placeholder instead of label.
*
* @param string $name
* @param string $placeholder
* @param bool $disabled
* @return string
*/ */
function form_password_placeholder($name, $placeholder, $disabled = false) { function form_password_placeholder($name, $placeholder, $disabled = false)
{
$disabled = $disabled ? ' disabled="disabled"' : ''; $disabled = $disabled ? ' disabled="disabled"' : '';
return form_element('', '<input class="form-control" id="form_' . $name . '" type="password" name="' . $name . '" value="" placeholder="' . $placeholder . '" ' . $disabled . '/>', 'form_' . $name); return form_element(
'',
'<input class="form-control" id="form_' . $name . '" type="password" name="'
. $name . '" value="" placeholder="' . $placeholder . '" ' . $disabled . '/>',
'form_' . $name
);
} }
/** /**
* Rendert ein Formular-Textfeld * Rendert ein Formular-Textfeld
*
* @param string $name
* @param string $label
* @param string $value
* @param bool $disabled
* @return string
*/ */
function form_textarea($name, $label, $value, $disabled = false) { function form_textarea($name, $label, $value, $disabled = false)
{
$disabled = $disabled ? ' disabled="disabled"' : ''; $disabled = $disabled ? ' disabled="disabled"' : '';
return form_element($label, '<textarea rows="5" class="form-control" id="form_' . $name . '" type="text" name="' . $name . '" ' . $disabled . '>' . $value . '</textarea>', 'form_' . $name); return form_element(
$label,
'<textarea rows="5" class="form-control" id="form_' . $name . '" name="'
. $name . '" ' . $disabled . '>' . htmlspecialchars($value) . '</textarea>',
'form_' . $name
);
} }
/** /**
* Rendert ein Formular-Auswahlfeld * Rendert ein Formular-Auswahlfeld
*
* @param string $name
* @param string $label
* @param string[] $values
* @param string $selected
* @return string
*/ */
function form_select($name, $label, $values, $selected) { function form_select($name, $label, $values, $selected)
{
return form_element($label, html_select_key('form_' . $name, $name, $values, $selected), 'form_' . $name); return form_element($label, html_select_key('form_' . $name, $name, $values, $selected), 'form_' . $name);
} }
/** /**
* Rendert ein Formular-Element * Rendert ein Formular-Element
*
* @param string $label
* @param string $input
* @param string $for
* @return string
*/ */
function form_element($label, $input, $for = "") { function form_element($label, $input, $for = '')
{
if ($label == '') { if ($label == '') {
return '<div class="form-group">' . $input . '</div>'; return '<div class="form-group">' . $input . '</div>';
} }
@ -251,24 +373,45 @@ function form_element($label, $input, $for = "") {
/** /**
* Rendert ein Formular * Rendert ein Formular
*
* @param string[] $elements
* @param string $action
* @return string
*/ */
function form($elements, $action = "") { function form($elements, $action = '')
return '<form role="form" action="' . $action . '" enctype="multipart/form-data" method="post">' . join($elements) . '</form>'; {
return '<form action="' . $action . '" enctype="multipart/form-data" method="post">' . join($elements) . '</form>';
} }
function html_options($name, $options, $selected = "") { /**
$html = ""; * @param string $name
* @param String[] $options
* @param string $selected
* @return string
*/
function html_options($name, $options, $selected = '')
{
$html = '';
foreach ($options as $value => $label) { foreach ($options as $value => $label) {
$html .= '<input type="radio"' . ($value == $selected ? ' checked="checked"' : '') . ' name="' . $name . '" value="' . $value . '"> ' . $label; $html .= '<input type="radio"' . ($value == $selected ? ' checked="checked"' : '') . ' name="'
. $name . '" value="' . $value . '"> ' . $label;
} }
return $html; return $html;
} }
function html_select_key($dom_id, $name, $rows, $selected) { /**
* @param string $dom_id
* @param string $name
* @param string[] $rows
* @param string $selected
* @return string
*/
function html_select_key($dom_id, $name, $rows, $selected)
{
$html = '<select class="form-control" id="' . $dom_id . '" name="' . $name . '">'; $html = '<select class="form-control" id="' . $dom_id . '" name="' . $name . '">';
foreach ($rows as $key => $row) { foreach ($rows as $key => $row) {
if (($key == $selected) || ($row == $selected)) { if (($key == $selected) || ($row === $selected)) {
$html .= '<option value="' . $key . '" selected="selected">' . $row . '</option>'; $html .= '<option value="' . $key . '" selected="selected">' . $row . '</option>';
} else { } else {
$html .= '<option value="' . $key . '">' . $row . '</option>'; $html .= '<option value="' . $key . '">' . $row . '</option>';
@ -277,5 +420,3 @@ function html_select_key($dom_id, $name, $rows, $selected) {
$html .= '</select>'; $html .= '</select>';
return $html; return $html;
} }
?>

View File

@ -4,36 +4,17 @@
* Write a log entry. * Write a log entry.
* This should be used to log user's activity. * This should be used to log user's activity.
* *
* @param * @param string $message
* $message
*/ */
function engelsystem_log($message) { function engelsystem_log($message)
{
global $user; global $user;
$nick = "Guest"; $nick = "Guest";
$logger = app('logger');
if (isset($user)) { if (isset($user)) {
$nick = User_Nick_render($user); $nick = User_Nick_render($user);
} }
LogEntry_create($nick, $message);
$logger->info('{nick}: {message}', ['nick' => $nick, 'message' => $message]);
} }
/**
* Generates a PHP Stacktrace.
*/
function debug_string_backtrace() {
ob_start();
debug_print_backtrace();
$trace = ob_get_contents();
ob_end_clean();
// Remove first item from backtrace as it's this function which
// is redundant.
$trace = preg_replace('/^#0\s+' . __FUNCTION__ . "[^\n]*\n/", '', $trace, 1);
// Renumber backtrace items.
// $trace = preg_replace('/^#(\d+)/me', '\'#\' . ($1 - 1)', $trace);
return $trace;
}
?>

View File

@ -1,21 +1,25 @@
<?php <?php
use Engelsystem\UserHintsRenderer; use Engelsystem\UserHintsRenderer;
function page_link_to($page = "") { /**
if ($page == "") { * @param string $page
return '?'; * @param array $parameters get parameters
} * @return string
return '?p=' . $page; */
} function page_link_to($page = '', $parameters = [])
{
function page_link_to_absolute($page) { $page = str_replace('_', '-', $page);
return (isset($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . preg_replace("/\?.*$/", '', $_SERVER['REQUEST_URI']) . page_link_to($page); return url($page, $parameters);
} }
/** /**
* Render the user hints * Render the user hints
*
* @return string
*/ */
function header_render_hints() { function header_render_hints()
{
global $user; global $user;
$hints_renderer = new UserHintsRenderer(); $hints_renderer = new UserHintsRenderer();
@ -38,17 +42,24 @@ function header_render_hints() {
/** /**
* Renders the header toolbar containing search, login/logout, user and settings links. * Renders the header toolbar containing search, login/logout, user and settings links.
*
* @return string
*/ */
function header_toolbar() { function header_toolbar()
{
global $page, $privileges, $user; global $page, $privileges, $user;
$toolbar_items = []; $toolbar_items = [];
if (isset($user)) { if (isset($user)) {
$toolbar_items[] = toolbar_item_link(page_link_to('shifts') . '&amp;action=next', 'time', User_shift_state_render($user)); $toolbar_items[] = toolbar_item_link(
page_link_to('shifts', ['action' => 'next']),
'time',
User_shift_state_render($user)
);
} }
if (! isset($user) && in_array('register', $privileges)) { if (!isset($user) && in_array('register', $privileges) && config('registration_enabled')) {
$toolbar_items[] = toolbar_item_link(page_link_to('register'), 'plus', register_title(), $page == 'register'); $toolbar_items[] = toolbar_item_link(page_link_to('register'), 'plus', register_title(), $page == 'register');
} }
@ -62,7 +73,12 @@ function header_toolbar() {
$toolbar_items[] = header_render_hints(); $toolbar_items[] = header_render_hints();
if (in_array('user_myshifts', $privileges)) { if (in_array('user_myshifts', $privileges)) {
$toolbar_items[] = toolbar_item_link(page_link_to('users') . '&amp;action=view', ' icon-icon_angel', $user['Nick'], $page == 'users'); $toolbar_items[] = toolbar_item_link(
page_link_to('users', ['action' => 'view']),
' icon-icon_angel',
$user['Nick'],
$page == 'users'
);
} }
$user_submenu = make_user_submenu(); $user_submenu = make_user_submenu();
@ -73,7 +89,11 @@ function header_toolbar() {
return toolbar($toolbar_items, true); return toolbar($toolbar_items, true);
} }
function make_user_submenu() { /**
* @return array
*/
function make_user_submenu()
{
global $privileges, $page; global $privileges, $page;
$user_submenu = make_langselect(); $user_submenu = make_langselect();
@ -83,7 +103,12 @@ function make_user_submenu() {
} }
if (in_array('user_settings', $privileges)) { if (in_array('user_settings', $privileges)) {
$user_submenu[] = toolbar_item_link(page_link_to('user_settings'), 'list-alt', settings_title(), $page == 'user_settings'); $user_submenu[] = toolbar_item_link(
page_link_to('user_settings'),
'list-alt',
settings_title(),
$page == 'user_settings'
);
} }
if (in_array('logout', $privileges)) { if (in_array('logout', $privileges)) {
@ -93,16 +118,20 @@ function make_user_submenu() {
return $user_submenu; return $user_submenu;
} }
function make_navigation() { /**
* @return string
*/
function make_navigation()
{
global $page, $privileges; global $page, $privileges;
$menu = []; $menu = [];
$pages = [ $pages = [
"news" => news_title(), 'news' => news_title(),
"user_meetings" => meetings_title(), 'user_meetings' => meetings_title(),
"user_shifts" => shifts_title(), 'user_shifts' => shifts_title(),
"angeltypes" => angeltypes_title(), 'angeltypes' => angeltypes_title(),
"user_questions" => questions_title() 'user_questions' => questions_title()
]; ];
foreach ($pages as $menu_page => $title) { foreach ($pages as $menu_page => $title) {
@ -115,18 +144,18 @@ function make_navigation() {
$admin_menu = []; $admin_menu = [];
$admin_pages = [ $admin_pages = [
"admin_arrive" => admin_arrive_title(), 'admin_arrive' => admin_arrive_title(),
"admin_active" => admin_active_title(), 'admin_active' => admin_active_title(),
"admin_user" => admin_user_title(), 'admin_user' => admin_user_title(),
"admin_free" => admin_free_title(), 'admin_free' => admin_free_title(),
"admin_questions" => admin_questions_title(), 'admin_questions' => admin_questions_title(),
"shifttypes" => shifttypes_title(), 'shifttypes' => shifttypes_title(),
"admin_shifts" => admin_shifts_title(), 'admin_shifts' => admin_shifts_title(),
"admin_rooms" => admin_rooms_title(), 'admin_rooms' => admin_rooms_title(),
"admin_groups" => admin_groups_title(), 'admin_groups' => admin_groups_title(),
"admin_import" => admin_import_title(), 'admin_import' => admin_import_title(),
"admin_log" => admin_log_title(), 'admin_log' => admin_log_title(),
"admin_event_config" => event_config_title() 'admin_event_config' => event_config_title()
]; ];
foreach ($admin_pages as $menu_page => $title) { foreach ($admin_pages as $menu_page => $title) {
@ -136,7 +165,7 @@ function make_navigation() {
} }
if (count($admin_menu) > 0) { if (count($admin_menu) > 0) {
$menu[] = toolbar_dropdown('', _("Admin"), $admin_menu); $menu[] = toolbar_dropdown('', _('Admin'), $admin_menu);
} }
return toolbar($menu); return toolbar($menu);
@ -145,41 +174,48 @@ function make_navigation() {
/** /**
* Adds room navigation to the given menu. * Adds room navigation to the given menu.
* *
* @param string[] $menu * @param string[] $menu Rendered menu
* Rendered menu * @return string[]
*/ */
function make_room_navigation($menu) { function make_room_navigation($menu)
{
global $privileges; global $privileges;
if (! in_array('view_rooms', $privileges)) { if (!in_array('view_rooms', $privileges)) {
return $menu; return $menu;
} }
//get a list of all rooms // Get a list of all rooms
$rooms = Rooms(true); $rooms = Rooms(true);
$room_menu = []; $room_menu = [];
if (in_array('admin_rooms', $privileges)) { if (in_array('admin_rooms', $privileges)) {
$room_menu[] = toolbar_item_link(page_link_to('admin_rooms'), 'list', _("Manage rooms")); $room_menu[] = toolbar_item_link(page_link_to('admin_rooms'), 'list', _('Manage rooms'));
} }
if (count($room_menu) > 0) { if (count($room_menu) > 0) {
$room_menu[] = toolbar_item_divider(); $room_menu[] = toolbar_item_divider();
} }
foreach ($rooms as $room) { foreach ($rooms as $room) {
if($room['show'] == 'Y' || // room is public if (
($room['show'] != 'Y' && in_array('admin_rooms', $privileges)) // room is not public, but user can admin_rooms $room['show'] == 'Y' // room is public
|| (
// room is not public, but user can admin_rooms
$room['show'] != 'Y'
&& in_array('admin_rooms', $privileges)
)
) { ) {
$room_menu[] = toolbar_item_link(room_link($room), 'map-marker', $room['Name']); $room_menu[] = toolbar_item_link(room_link($room), 'map-marker', $room['Name']);
} }
} }
if (count($room_menu > 0)) { if (count($room_menu) > 0) {
$menu[] = toolbar_dropdown('map-marker', _("Rooms"), $room_menu); $menu[] = toolbar_dropdown('map-marker', _('Rooms'), $room_menu);
} }
return $menu; return $menu;
} }
function make_menu() { /**
* @return string
*/
function make_menu()
{
return make_navigation(); return make_navigation();
} }
?>

View File

@ -1,4 +1,5 @@
<?php <?php
use Engelsystem\ValidationResult; use Engelsystem\ValidationResult;
/** /**
@ -8,39 +9,38 @@ use Engelsystem\ValidationResult;
/** /**
* Parse a date from da day and a time textfield. * Parse a date from da day and a time textfield.
* *
* @param string $date_name * @param string $date_name Name of the textfield containing the day (format Y-m-d)
* Name of the textfield containing the day (format Y-m-d) * @param string $time_name Name of the textfield containing the time (format H:i)
* @param string $time_name * @param string[] $allowed_days List of allowed days in format Y-m-d
* Name of the textfield containing the time (format H:i) * @param int $default_value Default value unix timestamp
* @param string[] $allowed_days * @return int|null
* List of allowed days in format Y-m-d
* @param int $default_value
* Default value unix timestamp
*/ */
function check_request_datetime($date_name, $time_name, $allowed_days, $default_value) { function check_request_datetime($date_name, $time_name, $allowed_days, $default_value)
$time = date("H:i", $default_value); {
$day = date("Y-m-d", $default_value); $time = date('H:i', $default_value);
$day = date('Y-m-d', $default_value);
$request = request();
if (isset($_REQUEST[$time_name]) && preg_match('#^\d{1,2}:\d\d$#', trim($_REQUEST[$time_name]))) { if ($request->has($time_name) && preg_match('#^\d{1,2}:\d\d$#', trim($request->input($time_name)))) {
$time = trim($_REQUEST[$time_name]); $time = trim($request->input($time_name));
}
if (isset($_REQUEST[$date_name]) && in_array($_REQUEST[$date_name], $allowed_days)) {
$day = $_REQUEST[$date_name];
} }
return parse_date("Y-m-d H:i", $day . " " . $time); if ($request->has($date_name) && in_array($request->input($date_name), $allowed_days)) {
$day = $request->input($date_name);
}
return parse_date('Y-m-d H:i', $day . ' ' . $time);
} }
/** /**
* Parse a date into unix timestamp * Parse a date into unix timestamp
* *
* @param string $pattern * @param string $pattern The date pattern (i.e. Y-m-d H:i)
* The date pattern (i.e. Y-m-d H:i) * @param string $value The string to parse
* @param string $value * @return int|null The parsed unix timestamp
* The string to parse
* @return The parsed unix timestamp
*/ */
function parse_date($pattern, $value) { function parse_date($pattern, $value)
{
$datetime = DateTime::createFromFormat($pattern, trim($value)); $datetime = DateTime::createFromFormat($pattern, trim($value));
if ($datetime == null) { if ($datetime == null) {
return null; return null;
@ -50,19 +50,22 @@ function parse_date($pattern, $value) {
/** /**
* Leitet den Browser an die übergebene URL weiter und hält das Script an. * Leitet den Browser an die übergebene URL weiter und hält das Script an.
*
* @param string $url
*/ */
function redirect($url) { function redirect($url)
header("Location: " . $url, true, 302); {
raw_output(""); header('Location: ' . $url, true, 302);
raw_output('');
} }
/** /**
* Echoes given output and dies. * Echoes given output and dies.
* *
* @param String $output * @param String $output String to display
* String to display
*/ */
function raw_output($output) { function raw_output($output = '')
{
echo $output; echo $output;
die(); die();
} }
@ -70,32 +73,33 @@ function raw_output($output) {
/** /**
* Helper function for transforming list of entities into array for select boxes. * Helper function for transforming list of entities into array for select boxes.
* *
* @param array $data * @param array $data The data array
* The data array * @param string $key_name name of the column to use as id/key
* @param string $key_name * @param string $value_name name of the column to use as displayed value
* name of the column to use as id/key *
* @param string $value_name * @return array
* name of the column to use as displayed value
*/ */
function select_array($data, $key_name, $value_name) { function select_array($data, $key_name, $value_name)
$ret = []; {
$return = [];
foreach ($data as $value) { foreach ($data as $value) {
$ret[$value[$key_name]] = $value[$value_name]; $return[$value[$key_name]] = $value[$value_name];
} }
return $ret; return $return;
} }
/** /**
* Returns an int[] from given request param name. * Returns an int[] from given request param name.
* *
* @param String $name * @param string $name Name of the request param
* Name of the request param * @param array $default Default return value, if param is not set
* @param array<int> $default * @return array
* Default return value, if param is not set
*/ */
function check_request_int_array($name, $default = []) { function check_request_int_array($name, $default = [])
if (isset($_REQUEST[$name]) && is_array($_REQUEST[$name])) { {
return array_filter($_REQUEST[$name], 'is_numeric'); $request = request();
if ($request->has($name) && is_array($request->input($name))) {
return array_filter($request->input($name), 'is_numeric');
} }
return $default; return $default;
} }
@ -104,35 +108,32 @@ function check_request_int_array($name, $default = []) {
* Checks if given request item (name) can be parsed to a date. * Checks if given request item (name) can be parsed to a date.
* If not parsable, given error message is put into msg() and null is returned. * If not parsable, given error message is put into msg() and null is returned.
* *
* @param string $input * @param string $name to be parsed into a date.
* String to be parsed into a date. * @param string $error_message the error message displayed if $input is not parsable
* @param string $error_message * @param boolean $null_allowed is a null value allowed?
* the error message displayed if $input is not parsable
* @param boolean $null_allowed
* is a null value allowed?
* @return ValidationResult containing the parsed date * @return ValidationResult containing the parsed date
*/ */
function check_request_date($name, $error_message = null, $null_allowed = false) { function check_request_date($name, $error_message = null, $null_allowed = false)
if (! isset($_REQUEST[$name])) { {
$request = request();
if (!$request->has($name)) {
return new ValidationResult($null_allowed, null); return new ValidationResult($null_allowed, null);
} }
return check_date($_REQUEST[$name], $error_message, $null_allowed); return check_date($request->input($name), $error_message, $null_allowed);
} }
/** /**
* Checks if given string can be parsed to a date. * Checks if given string can be parsed to a date.
* If not parsable, given error message is put into msg() and null is returned. * If not parsable, given error message is put into msg() and null is returned.
* *
* @param string $input * @param string $input String to be parsed into a date.
* String to be parsed into a date. * @param string $error_message the error message displayed if $input is not parsable
* @param string $error_message * @param boolean $null_allowed is a null value allowed?
* the error message displayed if $input is not parsable
* @param boolean $null_allowed
* is a null value allowed?
* @return ValidationResult containing the parsed date * @return ValidationResult containing the parsed date
*/ */
function check_date($input, $error_message = null, $null_allowed = false) { function check_date($input, $error_message = null, $null_allowed = false)
if ($tmp = parse_date("Y-m-d H:i", trim($input) . " 00:00")) { {
if ($tmp = parse_date('Y-m-d H:i', trim($input) . ' 00:00')) {
return new ValidationResult(true, $tmp); return new ValidationResult(true, $tmp);
} }
if ($null_allowed) { if ($null_allowed) {
@ -145,10 +146,16 @@ function check_date($input, $error_message = null, $null_allowed = false) {
/** /**
* Returns REQUEST value filtered or default value (null) if not set. * Returns REQUEST value filtered or default value (null) if not set.
*
* @param string $name
* @param string $default_value
* @return mixed|null
*/ */
function strip_request_item($name, $default_value = null) { function strip_request_item($name, $default_value = null)
if (isset($_REQUEST[$name])) { {
return strip_item($_REQUEST[$name]); $request = request();
if ($request->has($name)) {
return strip_item($request->input($name));
} }
return $default_value; return $default_value;
} }
@ -156,36 +163,58 @@ function strip_request_item($name, $default_value = null) {
/** /**
* Testet, ob der angegebene REQUEST Wert ein Integer ist, bzw. * Testet, ob der angegebene REQUEST Wert ein Integer ist, bzw.
* eine ID sein könnte. * eine ID sein könnte.
*
* @param string $name
* @return int|false
*/ */
function test_request_int($name) { function test_request_int($name)
if (isset($_REQUEST[$name])) { {
return preg_match("/^[0-9]*$/", $_REQUEST[$name]); $input = request()->input($name);
} if (is_null($input)) {
return false; return false;
}
return preg_match('/^\d+$/', $input);
} }
/** /**
* Gibt den gefilterten REQUEST Wert mit Zeilenumbrüchen zurück * Gibt den gefilterten REQUEST Wert mit Zeilenumbrüchen zurück
*
* @param string $name
* @param mixed $default_value
* @return mixed
*/ */
function strip_request_item_nl($name, $default_value = null) { function strip_request_item_nl($name, $default_value = null)
if (isset($_REQUEST[$name])) { {
return preg_replace("/([^\p{L}\p{S}\p{P}\p{Z}\p{N}+\n]{1,})/ui", '', strip_tags($_REQUEST[$name])); $request = request();
if ($request->has($name)) {
return preg_replace(
"/([^\p{L}\p{S}\p{P}\p{Z}\p{N}+\n]{1,})/ui",
'',
strip_tags($request->input($name))
);
} }
return $default_value; return $default_value;
} }
/** /**
* Entfernt unerwünschte Zeichen * Entfernt unerwünschte Zeichen
*
* @param string $item
* @return string
*/ */
function strip_item($item) { function strip_item($item)
{
return preg_replace("/([^\p{L}\p{S}\p{P}\p{Z}\p{N}+]{1,})/ui", '', strip_tags($item)); return preg_replace("/([^\p{L}\p{S}\p{P}\p{Z}\p{N}+]{1,})/ui", '', strip_tags($item));
} }
/** /**
* Überprüft eine E-Mail-Adresse. * Überprüft eine E-Mail-Adresse.
*
* @param string $email
* @return bool
*/ */
function check_email($email) { function check_email($email)
return (bool) filter_var($email, FILTER_VALIDATE_EMAIL); {
return (bool)filter_var($email, FILTER_VALIDATE_EMAIL);
} }
?>

View File

@ -1,47 +1,83 @@
<?php <?php
/** /**
* Liste der verfügbaren Themes * Renders tabs from the array. Array key is tab name, array value is tab content.
*
* @param array $tabs
* @param int $selected The selected tab, default 0
* @return string HTML
*/ */
$themes = [ function tabs($tabs, $selected = 0)
'4' => "Engelsystem 33c3 (2016)", {
'3' => "Engelsystem 32c3 (2015)", $tab_header = [];
"2" => "Engelsystem cccamp15", $tab_content = [];
"0" => "Engelsystem light", foreach($tabs as $header => $content) {
"1" => "Engelsystem dark" $class = '';
]; if(count($tab_header) == $selected) {
$class = 'active';
}
$tab_header[] = '<li role="presentation" class="' . $class . '">
<a href="#' . $header . '" aria-controls="' . $header . '" role="tab" data-toggle="tab">'
. $header . '</a></li>';
$tab_content[] = '<div role="tabpanel" class="tab-pane ' . $class . '" id="' . $header . '">' . $content . '</div>';
}
return div('', [
'<ul class="nav nav-tabs" role="tablist">' . join($tab_header) . '</ul>',
'<div class="tab-content">' . join($tab_content) . '</div>'
]);
}
/** /**
* Display muted (grey) text. * Display muted (grey) text.
* *
* @param string $text * @param string $text
* @return string
*/ */
function mute($text) { function mute($text)
{
return '<span class="text-muted">' . $text . '</span>'; return '<span class="text-muted">' . $text . '</span>';
} }
/** /**
* Renders a bootstrap label with given content and class. * Renders a bootstrap label with given content and class.
* *
* @param string $content * @param string $content The text
* The text * @param string $class default, primary, info, success, warning, danger
* @param string $class * @return string
* default, primary, info, success, warning, danger
*/ */
function label($content, $class = 'default') { function label($content, $class = 'default')
{
return '<span class="label label-' . $class . '">' . $content . '</span>'; return '<span class="label label-' . $class . '">' . $content . '</span>';
} }
function progress_bar($valuemin, $valuemax, $valuenow, $class = '', $content = '') { /**
return '<div class="progress"><div class="progress-bar ' . $class . '" role="progressbar" aria-valuenow="' . $valuenow . '" aria-valuemin="' . $valuemin . '" aria-valuemax="' . $valuemax . '" style="width: ' . floor(($valuenow - $valuemin) * 100 / ($valuemax - $valuemin)) . '%">' . $content . '</div></div>'; * @param int $valuemin
* @param int $valuemax
* @param int $valuenow
* @param string $class
* @param string $content
* @return string
*/
function progress_bar($valuemin, $valuemax, $valuenow, $class = '', $content = '')
{
return '<div class="progress">'
. '<div class="progress-bar ' . $class . '" role="progressbar" '
. 'aria-valuenow="' . $valuenow . '" aria-valuemin="' . $valuemin . '" aria-valuemax="' . $valuemax . '" '
. 'style="width: ' . floor(($valuenow - $valuemin) * 100 / ($valuemax - $valuemin)) . '%"'
. '>'
. $content . ''
. '</div>'
. '</div>';
} }
/** /**
* Render glyphicon * Render glyphicon
* *
* @param string $glyph_name * @param string $glyph_name
* @return string
*/ */
function glyph($glyph_name) { function glyph($glyph_name)
{
return ' <span class="glyphicon glyphicon-' . $glyph_name . '"></span> '; return ' <span class="glyphicon glyphicon-' . $glyph_name . '"></span> ';
} }
@ -49,12 +85,21 @@ function glyph($glyph_name) {
* Renders a tick or a cross by given boolean * Renders a tick or a cross by given boolean
* *
* @param boolean $boolean * @param boolean $boolean
* @return string
*/ */
function glyph_bool($boolean) { function glyph_bool($boolean)
{
return '<span class="text-' . ($boolean ? 'success' : 'danger') . '">' . glyph($boolean ? 'ok' : 'remove') . '</span>'; return '<span class="text-' . ($boolean ? 'success' : 'danger') . '">' . glyph($boolean ? 'ok' : 'remove') . '</span>';
} }
function div($class, $content = [], $dom_id = "") { /**
* @param string $class
* @param array $content
* @param string $dom_id
* @return string
*/
function div($class, $content = [], $dom_id = '')
{
if (is_array($content)) { if (is_array($content)) {
$content = join("\n", $content); $content = join("\n", $content);
} }
@ -62,21 +107,34 @@ function div($class, $content = [], $dom_id = "") {
return '<div' . $dom_id . ' class="' . $class . '">' . $content . '</div>'; return '<div' . $dom_id . ' class="' . $class . '">' . $content . '</div>';
} }
function heading($content, $number = 1) { /**
return "<h" . $number . ">" . $content . "</h" . $number . ">"; * @param string $content
* @param int $number
* @return string
*/
function heading($content, $number = 1)
{
return '<h' . $number . '>' . $content . '</h' . $number . '>';
} }
/** /**
* Render a toolbar. * Render a toolbar.
* *
* @param array $items * @param array $items
* @param bool $right
* @return string * @return string
*/ */
function toolbar($items = [], $right = false) { function toolbar($items = [], $right = false)
{
return '<ul class="nav navbar-nav' . ($right ? ' navbar-right' : '') . '">' . join("\n", $items) . '</ul>'; return '<ul class="nav navbar-nav' . ($right ? ' navbar-right' : '') . '">' . join("\n", $items) . '</ul>';
} }
function toolbar_pills($items) { /**
* @param string[] $items
* @return string
*/
function toolbar_pills($items)
{
return '<ul class="nav nav-pills">' . join("\n", $items) . '</ul>'; return '<ul class="nav nav-pills">' . join("\n", $items) . '</ul>';
} }
@ -89,24 +147,58 @@ function toolbar_pills($items) {
* @param bool $selected * @param bool $selected
* @return string * @return string
*/ */
function toolbar_item_link($href, $glyphicon, $label, $selected = false) { function toolbar_item_link($href, $glyphicon, $label, $selected = false)
return '<li class="' . ($selected ? 'active' : '') . '"><a href="' . $href . '">' . ($glyphicon != '' ? '<span class="glyphicon glyphicon-' . $glyphicon . '"></span> ' : '') . $label . '</a></li>'; {
return '<li class="' . ($selected ? 'active' : '') . '">'
. '<a href="' . $href . '">'
. ($glyphicon != '' ? '<span class="glyphicon glyphicon-' . $glyphicon . '"></span> ' : '')
. $label
. '</a>'
. '</li>';
} }
function toolbar_item_divider() { /**
* @return string
*/
function toolbar_item_divider()
{
return '<li class="divider"></li>'; return '<li class="divider"></li>';
} }
function toolbar_dropdown($glyphicon, $label, $submenu, $class = '') { /**
* @param string $glyphicon
* @param string $label
* @param array $submenu
* @param string $class
* @return string
*/
function toolbar_dropdown($glyphicon, $label, $submenu, $class = '')
{
return '<li class="dropdown ' . $class . '"> return '<li class="dropdown ' . $class . '">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">' . ($glyphicon != '' ? '<span class="glyphicon glyphicon-' . $glyphicon . '"></span> ' : '') . $label . ' <span class="caret"></span></a> <a href="#" class="dropdown-toggle" data-toggle="dropdown">'
<ul class="dropdown-menu" role="menu">' . join("\n", $submenu) . '</ul></li>'; . ($glyphicon != '' ? '<span class="glyphicon glyphicon-' . $glyphicon . '"></span> ' : '')
. $label
. ' <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">'
. join("\n", $submenu)
. '</ul></li>';
} }
function toolbar_popover($glyphicon, $label, $content, $class = '') { /**
* @param string $glyphicon
* @param string $label
* @param string[] $content
* @param string $class
* @return string
*/
function toolbar_popover($glyphicon, $label, $content, $class = '')
{
$dom_id = md5(microtime() . $glyphicon . $label); $dom_id = md5(microtime() . $glyphicon . $label);
return '<li class="dropdown messages ' . $class . '"> return '<li class="dropdown messages ' . $class . '">
<a id="' . $dom_id . '" href="#" tabindex="0">' . ($glyphicon != '' ? '<span class="glyphicon glyphicon-' . $glyphicon . '"></span> ' : '') . $label . ' <span class="caret"></span></a> <a id="' . $dom_id . '" href="#" tabindex="0">'
. ($glyphicon != '' ? '<span class="glyphicon glyphicon-' . $glyphicon . '"></span> ' : '')
. $label
. ' <span class="caret"></span></a>
<script type="text/javascript"> <script type="text/javascript">
$(function(){ $(function(){
$("#' . $dom_id . '").popover({ $("#' . $dom_id . '").popover({
@ -124,25 +216,54 @@ function toolbar_popover($glyphicon, $label, $content, $class = '') {
/** /**
* Generiert HTML Code für eine "Seite". * Generiert HTML Code für eine "Seite".
* Fügt dazu die übergebenen Elemente zusammen. * Fügt dazu die übergebenen Elemente zusammen.
*
* @param string[] $elements
* @return string
*/ */
function page($elements) { function page($elements)
{
return join($elements); return join($elements);
} }
/** /**
* Generiert HTML Code für eine "Seite" mit zentraler Überschrift * Generiert HTML Code für eine "Seite" mit zentraler Überschrift
* Fügt dazu die übergebenen Elemente zusammen. * Fügt dazu die übergebenen Elemente zusammen.
*
* @param string $title
* @param string[] $elements
* @return string
*/ */
function page_with_title($title, $elements) { function page_with_title($title, $elements)
{
return '<div class="col-md-12"><h1>' . $title . '</h1>' . join($elements) . '</div>'; return '<div class="col-md-12"><h1>' . $title . '</h1>' . join($elements) . '</div>';
} }
/** /**
* Rendert eine Datentabelle * Renders a description based on the data arrays key and values as label an description.
* @param array $data
*/ */
function table($columns, $rows_raw, $data = true) { function description($data) {
$elements = [];
foreach($data as $label => $description) {
if(!empty($label) && !empty($description)) {
$elements[] = '<dt>' . $label . '</dt><dd>' . $description . '</dd>';
}
}
return '<dl class="dl-horizontal">' . join($elements) . '</dl>';
}
/**
* Rendert eine Datentabelle
*
* @param array|string $columns
* @param array[] $rows_raw
* @param bool $data
* @return string
*/
function table($columns, $rows_raw, $data = true)
{
// If only one column is given // If only one column is given
if (! is_array($columns)) { if (!is_array($columns)) {
$rows = []; $rows = [];
foreach ($rows_raw as $row) { foreach ($rows_raw as $row) {
$rows[] = [ $rows[] = [
@ -160,10 +281,16 @@ function table($columns, $rows_raw, $data = true) {
/** /**
* Helper for rendering a html-table. * Helper for rendering a html-table.
* use table() * use table()
*
* @param string[] $columns
* @param array[] $rows
* @param bool $data
* @return string
*/ */
function render_table($columns, $rows, $data = true) { function render_table($columns, $rows, $data = true)
{
if (count($rows) == 0) { if (count($rows) == 0) {
return info(_("No data found."), true); return info(_('No data found.'), true);
} }
$html = '<table class="table table-striped' . ($data ? ' data' : '') . '">'; $html = '<table class="table table-striped' . ($data ? ' data' : '') . '">';
@ -191,88 +318,112 @@ function render_table($columns, $rows, $data = true) {
/** /**
* Rendert einen Knopf * Rendert einen Knopf
*
* @param string $href
* @param string $label
* @param string $class
* @return string
*/ */
function button($href, $label, $class = "") { function button($href, $label, $class = '')
{
return '<a href="' . $href . '" class="btn btn-default ' . $class . '">' . $label . '</a>'; return '<a href="' . $href . '" class="btn btn-default ' . $class . '">' . $label . '</a>';
} }
/** /**
* Rendert einen Knopf mit Glyph * Rendert einen Knopf mit Glyph
*
* @param string $href
* @param string $glyph
* @param string $class
* @return string
*/ */
function button_glyph($href, $glyph, $class = "") { function button_glyph($href, $glyph, $class = '')
{
return button($href, glyph($glyph), $class); return button($href, glyph($glyph), $class);
} }
/** /**
* Rendert eine Toolbar mit Knöpfen * Rendert eine Toolbar mit Knöpfen
*
* @param array $buttons
* @return string
*/ */
function buttons($buttons = []) { function buttons($buttons = [])
{
return '<div class="form-group">' . table_buttons($buttons) . '</div>'; return '<div class="form-group">' . table_buttons($buttons) . '</div>';
} }
function table_buttons($buttons = []) { /**
* @param array $buttons
* @return string
*/
function table_buttons($buttons = [])
{
return '<div class="btn-group">' . join(' ', $buttons) . '</div>'; return '<div class="btn-group">' . join(' ', $buttons) . '</div>';
} }
// Load and render template /**
function template_render($file, $data) { * @param string $str
if (file_exists($file)) { * @param int $length
$template = file_get_contents($file); * @return string
if (is_array($data)) { */
foreach ($data as $name => $content) { function shorten($str, $length = 50)
$template = str_replace("%" . $name . "%", $content, $template); {
}
}
return $template;
}
engelsystem_error("Cannot find template file &laquo;" . $file . "&raquo;.");
}
function shorten($str, $length = 50) {
if (strlen($str) < $length) { if (strlen($str) < $length) {
return $str; return $str;
} }
return '<span title="' . htmlentities($str, ENT_COMPAT, 'UTF-8') . '">' . substr($str, 0, $length - 3) . '...</span>'; return '<span title="' . htmlentities($str, ENT_COMPAT, 'UTF-8') . '">'
. substr($str, 0, $length - 3)
. '...</span>';
} }
function table_body($array) { /**
$html = ""; * @param array[] $array
* @return string
*/
function table_body($array)
{
$html = '';
foreach ($array as $line) { foreach ($array as $line) {
$html .= "<tr>"; $html .= '<tr>';
if (is_array($line)) { if (is_array($line)) {
foreach ($line as $td) { foreach ($line as $td) {
$html .= "<td>" . $td . "</td>"; $html .= '<td>' . $td . '</td>';
} }
} else { } else {
$html .= "<td>" . $line . "</td>"; $html .= '<td>' . $line . '</td>';
} }
$html .= "</tr>"; $html .= '</tr>';
} }
return $html; return $html;
} }
function ReplaceSmilies($neueckig) { /**
$neueckig = str_replace(";o))", "<img src=\"pic/smiles/icon_redface.gif\">", $neueckig); * @param string $msg
$neueckig = str_replace(":-))", "<img src=\"pic/smiles/icon_redface.gif\">", $neueckig); * @return mixed
$neueckig = str_replace(";o)", "<img src=\"pic/smiles/icon_wind.gif\">", $neueckig); */
$neueckig = str_replace(":)", "<img src=\"pic/smiles/icon_smile.gif\">", $neueckig); function ReplaceSmilies($msg)
$neueckig = str_replace(":-)", "<img src=\"pic/smiles/icon_smile.gif\">", $neueckig); {
$neueckig = str_replace(":(", "<img src=\"pic/smiles/icon_sad.gif\">", $neueckig); $msg = str_replace(';o))', '<img src="pic/smiles/icon_redface.gif">', $msg);
$neueckig = str_replace(":-(", "<img src=\"pic/smiles/icon_sad.gif\">", $neueckig); $msg = str_replace(':-))', '<img src="pic/smiles/icon_redface.gif">', $msg);
$neueckig = str_replace(":o(", "<img src=\"pic/smiles/icon_sad.gif\">", $neueckig); $msg = str_replace(';o)', '<img src="pic/smiles/icon_wind.gif">', $msg);
$neueckig = str_replace(":o)", "<img src=\"pic/smiles/icon_lol.gif\">", $neueckig); $msg = str_replace(':)', '<img src="pic/smiles/icon_smile.gif">', $msg);
$neueckig = str_replace(";o(", "<img src=\"pic/smiles/icon_cry.gif\">", $neueckig); $msg = str_replace(':-)', '<img src="pic/smiles/icon_smile.gif">', $msg);
$neueckig = str_replace(";(", "<img src=\"pic/smiles/icon_cry.gif\">", $neueckig); $msg = str_replace(':(', '<img src="pic/smiles/icon_sad.gif">', $msg);
$neueckig = str_replace(";-(", "<img src=\"pic/smiles/icon_cry.gif\">", $neueckig); $msg = str_replace(':-(', '<img src="pic/smiles/icon_sad.gif">', $msg);
$neueckig = str_replace("8)", "<img src=\"pic/smiles/icon_rolleyes.gif\">", $neueckig); $msg = str_replace(':o(', '<img src="pic/smiles/icon_sad.gif">', $msg);
$neueckig = str_replace("8o)", "<img src=\"pic/smiles/icon_rolleyes.gif\">", $neueckig); $msg = str_replace(':o)', '<img src="pic/smiles/icon_lol.gif">', $msg);
$neueckig = str_replace(":P", "<img src=\"pic/smiles/icon_evil.gif\">", $neueckig); $msg = str_replace(';o(', '<img src="pic/smiles/icon_cry.gif">', $msg);
$neueckig = str_replace(":-P", "<img src=\"pic/smiles/icon_evil.gif\">", $neueckig); $msg = str_replace(';(', '<img src="pic/smiles/icon_cry.gif">', $msg);
$neueckig = str_replace(":oP", "<img src=\"pic/smiles/icon_evil.gif\">", $neueckig); $msg = str_replace(';-(', '<img src="pic/smiles/icon_cry.gif">', $msg);
$neueckig = str_replace(";P", "<img src=\"pic/smiles/icon_mad.gif\">", $neueckig); $msg = str_replace('8)', '<img src="pic/smiles/icon_rolleyes.gif">', $msg);
$neueckig = str_replace(";oP", "<img src=\"pic/smiles/icon_mad.gif\">", $neueckig); $msg = str_replace('8o)', '<img src="pic/smiles/icon_rolleyes.gif">', $msg);
$neueckig = str_replace("?)", "<img src=\"pic/smiles/icon_question.gif\">", $neueckig); $msg = str_replace(':P', '<img src="pic/smiles/icon_evil.gif">', $msg);
$msg = str_replace(':-P', '<img src="pic/smiles/icon_evil.gif">', $msg);
$msg = str_replace(':oP', '<img src="pic/smiles/icon_evil.gif">', $msg);
$msg = str_replace(';P', '<img src="pic/smiles/icon_mad.gif">', $msg);
$msg = str_replace(';oP', '<img src="pic/smiles/icon_mad.gif">', $msg);
$msg = str_replace('?)', '<img src="pic/smiles/icon_question.gif">', $msg);
return $neueckig; return $msg;
} }
?>

View File

@ -1,5 +1,7 @@
<?php <?php
use Engelsystem\ShiftsFilterRenderer;
use Engelsystem\ShiftCalendarRenderer;
/** /**
* AngelTypes * AngelTypes
*/ */
@ -7,42 +9,56 @@
/** /**
* Renders the angeltypes name as link. * Renders the angeltypes name as link.
* *
* @param AngelType $angeltype * @param array $angeltype
* @return string
*/ */
function AngelType_name_render($angeltype) { function AngelType_name_render($angeltype)
{
return '<a href="' . angeltype_link($angeltype['id']) . '">' . ($angeltype['restricted'] ? glyph('lock') : '') . $angeltype['name'] . '</a>'; return '<a href="' . angeltype_link($angeltype['id']) . '">' . ($angeltype['restricted'] ? glyph('lock') : '') . $angeltype['name'] . '</a>';
} }
/** /**
* Render angeltype membership state * Render angeltype membership state
* *
* @param UserAngelType $user_angeltype * @param array $user_angeltype UserAngelType and AngelType
* UserAngelType and AngelType
* @return string * @return string
*/ */
function AngelType_render_membership($user_angeltype) { function AngelType_render_membership($user_angeltype)
{
if ($user_angeltype['user_angeltype_id'] != null) { if ($user_angeltype['user_angeltype_id'] != null) {
if ($user_angeltype['restricted']) { if ($user_angeltype['restricted']) {
if ($user_angeltype['confirm_user_id'] == null) { if ($user_angeltype['confirm_user_id'] == null) {
return glyph('lock') . _("Unconfirmed"); return glyph('lock') . _('Unconfirmed');
} elseif ($user_angeltype['supporter']) { } elseif ($user_angeltype['supporter']) {
return glyph_bool(true) . _("supporter"); return glyph_bool(true) . _('supporter');
} }
return glyph_bool(true) . _("Member"); return glyph_bool(true) . _('Member');
} elseif ($user_angeltype['supporter']) { } elseif ($user_angeltype['supporter']) {
return glyph_bool(true) . _("supporter"); return glyph_bool(true) . _('supporter');
} }
return glyph_bool(true) . _("Member"); return glyph_bool(true) . _('Member');
} }
return glyph_bool(false); return glyph_bool(false);
} }
function AngelType_delete_view($angeltype) { /**
return page_with_title(sprintf(_("Delete angeltype %s"), $angeltype['name']), [ * @param array $angeltype
info(sprintf(_("Do you want to delete angeltype %s?"), $angeltype['name']), true), * @return string
*/
function AngelType_delete_view($angeltype)
{
return page_with_title(sprintf(_('Delete angeltype %s'), $angeltype['name']), [
info(sprintf(_('Do you want to delete angeltype %s?'), $angeltype['name']), true),
buttons([ buttons([
button(page_link_to('angeltypes'), _("cancel"), 'cancel'), button(page_link_to('angeltypes'), _('cancel'), 'cancel'),
button(page_link_to('angeltypes') . '&action=delete&angeltype_id=' . $angeltype['id'] . '&confirmed', _("delete"), 'ok') button(
page_link_to(
'angeltypes',
['action' => 'delete', 'angeltype_id' => $angeltype['id'], 'confirmed' => 1]
),
_('delete'),
'ok'
)
]) ])
]); ]);
} }
@ -50,64 +66,110 @@ function AngelType_delete_view($angeltype) {
/** /**
* Render angeltype edit form. * Render angeltype edit form.
* *
* @param Angeltype $angeltype * @param array $angeltype The angeltype to edit
* The angeltype to edit * @param boolean $supporter_mode Is the user a supporter of this angeltype?
* @param boolean $supporter_mode * @return string
* Is the user a supporter of this angeltype?
*/ */
function AngelType_edit_view($angeltype, $supporter_mode) { function AngelType_edit_view($angeltype, $supporter_mode)
$contact_info = AngelType_contact_info($angeltype); {
return page_with_title(sprintf(_("Edit %s"), $angeltype['name']), [ return page_with_title(sprintf(_('Edit %s'), $angeltype['name']), [
buttons([ buttons([
button(page_link_to('angeltypes'), _("Angeltypes"), 'back') button(page_link_to('angeltypes'), _('Angeltypes'), 'back')
]), ]),
msg(), msg(),
form([ form([
$supporter_mode ? form_info(_("Name"), $angeltype['name']) : form_text('name', _("Name"), $angeltype['name']), $supporter_mode
$supporter_mode ? form_info(_("Restricted"), $angeltype['restricted'] ? _("Yes") : _("No")) : form_checkbox('restricted', _("Restricted"), $angeltype['restricted']), ? form_info(_('Name'), $angeltype['name'])
$supporter_mode ? form_info(_("No Self Sign Up"), $angeltype['no_self_signup'] ? _("Yes") : _("No")) : form_checkbox('no_self_signup', _("No Self Sign Up"), $angeltype['no_self_signup']), : form_text('name', _('Name'), $angeltype['name']),
$supporter_mode ? form_info(_("Requires driver license"), $angeltype['requires_driver_license'] ? _("Yes") : _("No")) : form_checkbox('requires_driver_license', _("Requires driver license"), $angeltype['requires_driver_license']), $supporter_mode
//form_text('contact_name', _("Name"), $angeltype['contact_name']), ? form_info(_('Restricted'), $angeltype['restricted'] ? _('Yes') : _('No'))
//form_text('contact_dect', _("DECT"), $angeltype['contact_dect']), : form_checkbox('restricted', _('Restricted'), $angeltype['restricted']),
//form_text('contact_email', _("E-Mail"), $angeltype['contact_email']), $supporter_mode
form_info("", _("Restricted angel types can only be used by an angel if enabled by a supporter (double opt-in).")), ? form_info(_('No Self Sign Up'), $angeltype['no_self_signup'] ? _('Yes') : _('No'))
form_textarea('description', _("Description"), $angeltype['description']), : form_checkbox('no_self_signup', _('No Self Sign Up'), $angeltype['no_self_signup']),
form_info("", _("Please use markdown for the description.")), $supporter_mode
form_submit('submit', _("Save")) ? form_info(_('Requires driver license'), $angeltype['requires_driver_license'] ? _('Yes') : _('No'))
: form_checkbox(
'requires_driver_license',
_('Requires driver license'),
$angeltype['requires_driver_license']
),
form_info(
'',
_('Restricted angel types can only be used by an angel if enabled by a supporter (double opt-in).')
),
form_textarea('description', _('Description'), $angeltype['description']),
form_info('', _('Please use markdown for the description.')),
heading(_('Contact'), 3),
form_info(
'',
_('Primary contact person/desk for user questions.')
),
form_text('contact_name', _('Name'), $angeltype['contact_name']),
form_text('contact_dect', _('DECT'), $angeltype['contact_dect']),
form_text('contact_email', _('E-Mail'), $angeltype['contact_email']),
form_submit('submit', _('Save'))
]) ])
]); ]);
} }
/** /**
* Renders the buttons for the angeltype view. * Renders the buttons for the angeltype view.
*
* @param array $angeltype
* @param array|null $user_angeltype
* @param bool $admin_angeltypes
* @param bool $supporter
* @param array|null $user_driver_license
* @param array|null $user
* @return string
*/ */
function AngelType_view_buttons($angeltype, $user_angeltype, $admin_angeltypes, $supporter, $user_driver_license, $user) { function AngelType_view_buttons($angeltype, $user_angeltype, $admin_angeltypes, $supporter, $user_driver_license, $user)
{
$buttons = [ $buttons = [
button(page_link_to('angeltypes'), _("Angeltypes"), 'back') button(page_link_to('angeltypes'), _('Angeltypes'), 'back')
]; ];
if ($angeltype['requires_driver_license']) { if ($angeltype['requires_driver_license']) {
$buttons[] = button(user_driver_license_edit_link($user), glyph("road") . _("my driving license")); $buttons[] = button(user_driver_license_edit_link($user), glyph('road') . _('my driving license'));
} }
if ($user_angeltype == null) { if ($user_angeltype == null) {
$buttons[] = button(page_link_to('user_angeltypes') . '&action=add&angeltype_id=' . $angeltype['id'], _("join"), 'add'); $buttons[] = button(
page_link_to('user_angeltypes', ['action' => 'add', 'angeltype_id' => $angeltype['id']]),
_('join'),
'add'
);
} else { } else {
if ($angeltype['requires_driver_license'] && $user_driver_license == null) { if ($angeltype['requires_driver_license'] && $user_driver_license == null) {
error(_("This angeltype requires a driver license. Please enter your driver license information!")); error(_('This angeltype requires a driver license. Please enter your driver license information!'));
} }
if ($angeltype['restricted'] && $user_angeltype['confirm_user_id'] == null) { 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'])); 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'); $buttons[] = button(
page_link_to('user_angeltypes', ['action' => 'delete', 'user_angeltype_id' => $user_angeltype['id']]),
_('leave'), 'cancel'
);
} }
if ($admin_angeltypes || $supporter) { if ($admin_angeltypes || $supporter) {
$buttons[] = button(page_link_to('angeltypes') . '&action=edit&angeltype_id=' . $angeltype['id'], _("edit"), 'edit'); $buttons[] = button(
page_link_to('angeltypes', ['action' => 'edit', 'angeltype_id' => $angeltype['id']]),
_('edit'),
'edit'
);
} }
if ($admin_angeltypes) { if ($admin_angeltypes) {
$buttons[] = button(page_link_to('angeltypes') . '&action=delete&angeltype_id=' . $angeltype['id'], _("delete"), 'delete'); $buttons[] = button(
page_link_to('angeltypes', ['action' => 'delete', 'angeltype_id' => $angeltype['id']]),
_('delete'),
'delete'
);
} }
return buttons($buttons); return buttons($buttons);
@ -116,15 +178,19 @@ function AngelType_view_buttons($angeltype, $user_angeltype, $admin_angeltypes,
/** /**
* Renders and sorts the members of an angeltype into supporters, members and unconfirmed members. * Renders and sorts the members of an angeltype into supporters, members and unconfirmed members.
* *
* @return [supporters, members, unconfirmed members] * @param array $angeltype
* @param array $members
* @param bool $admin_user_angeltypes
* @param bool $admin_angeltypes
* @return array [supporters, members, unconfirmed members]
*/ */
function AngelType_view_members($angeltype, $members, $admin_user_angeltypes, $admin_angeltypes) { function AngelType_view_members($angeltype, $members, $admin_user_angeltypes, $admin_angeltypes)
{
$supporters = []; $supporters = [];
$members_confirmed = []; $members_confirmed = [];
$members_unconfirmed = []; $members_unconfirmed = [];
foreach ($members as $member) { foreach ($members as $member) {
$member['Nick'] = User_Nick_render($member); $member['Nick'] = User_Nick_render($member);
if ($angeltype['requires_driver_license']) { if ($angeltype['requires_driver_license']) {
$member['wants_to_drive'] = glyph_bool($member['wants_to_drive']); $member['wants_to_drive'] = glyph_bool($member['wants_to_drive']);
$member['has_car'] = glyph_bool($member['has_car']); $member['has_car'] = glyph_bool($member['has_car']);
@ -137,14 +203,36 @@ function AngelType_view_members($angeltype, $members, $admin_user_angeltypes, $a
if ($angeltype['restricted'] && $member['confirm_user_id'] == null) { if ($angeltype['restricted'] && $member['confirm_user_id'] == null) {
$member['actions'] = table_buttons([ $member['actions'] = table_buttons([
button(page_link_to('user_angeltypes') . '&action=confirm&user_angeltype_id=' . $member['user_angeltype_id'], _("confirm"), 'btn-xs'), button(
button(page_link_to('user_angeltypes') . '&action=delete&user_angeltype_id=' . $member['user_angeltype_id'], _("deny"), 'btn-xs') page_link_to(
'user_angeltypes',
['action' => 'confirm', 'user_angeltype_id' => $member['user_angeltype_id']]
),
_('confirm'),
'btn-xs'
),
button(
page_link_to(
'user_angeltypes',
['action' => 'delete', 'user_angeltype_id' => $member['user_angeltype_id']]
),
_('deny'),
'btn-xs'
)
]); ]);
$members_unconfirmed[] = $member; $members_unconfirmed[] = $member;
} elseif ($member['supporter']) { } elseif ($member['supporter']) {
if ($admin_angeltypes) { if ($admin_angeltypes) {
$member['actions'] = table_buttons([ $member['actions'] = table_buttons([
button(page_link_to('user_angeltypes') . '&action=update&user_angeltype_id=' . $member['user_angeltype_id'] . '&supporter=0', _("Remove supporter rights"), 'btn-xs') button(
page_link_to('user_angeltypes', [
'action' => 'update',
'user_angeltype_id' => $member['user_angeltype_id'],
'supporter' => 0
]),
_('Remove supporter rights'),
'btn-xs'
)
]); ]);
} else { } else {
$member['actions'] = ''; $member['actions'] = '';
@ -153,8 +241,22 @@ function AngelType_view_members($angeltype, $members, $admin_user_angeltypes, $a
} else { } else {
if ($admin_user_angeltypes) { if ($admin_user_angeltypes) {
$member['actions'] = table_buttons([ $member['actions'] = table_buttons([
$admin_angeltypes ? button(page_link_to('user_angeltypes') . '&action=update&user_angeltype_id=' . $member['user_angeltype_id'] . '&supporter=1', _("Add supporter rights"), 'btn-xs') : '', $admin_angeltypes
button(page_link_to('user_angeltypes') . '&action=delete&user_angeltype_id=' . $member['user_angeltype_id'], _("remove"), 'btn-xs') ? button(page_link_to('user_angeltypes', [
'action' => 'update',
'user_angeltype_id' => $member['user_angeltype_id'],
'supporter' => 1
]),
_('Add supporter rights'), 'btn-xs')
: '',
button(
page_link_to('user_angeltypes', [
'action' => 'delete',
'user_angeltype_id' => $member['user_angeltype_id']
]),
_('remove'),
'btn-xs'
)
]); ]);
} }
$members_confirmed[] = $member; $members_confirmed[] = $member;
@ -170,50 +272,138 @@ function AngelType_view_members($angeltype, $members, $admin_user_angeltypes, $a
/** /**
* Creates the needed member table headers according to given rights and settings from the angeltype. * Creates the needed member table headers according to given rights and settings from the angeltype.
*
* @param array $angeltype
* @param bool $supporter
* @param bool $admin_angeltypes
* @return array
*/ */
function AngelType_view_table_headers($angeltype, $supporter, $admin_angeltypes) { function AngelType_view_table_headers($angeltype, $supporter, $admin_angeltypes)
{
if ($angeltype['requires_driver_license'] && ($supporter || $admin_angeltypes)) { if ($angeltype['requires_driver_license'] && ($supporter || $admin_angeltypes)) {
return [ return [
'Nick' => _("Nick"), 'Nick' => _('Nick'),
'DECT' => _("DECT"), 'DECT' => _('DECT'),
'wants_to_drive' => _("Driver"), 'wants_to_drive' => _('Driver'),
'has_car' => _("Has car"), 'has_car' => _('Has car'),
'has_license_car' => _("Car"), 'has_license_car' => _('Car'),
'has_license_3_5t_transporter' => _("3,5t Transporter"), 'has_license_3_5t_transporter' => _('3,5t Transporter'),
'has_license_7_5t_truck' => _("7,5t Truck"), 'has_license_7_5t_truck' => _('7,5t Truck'),
'has_license_12_5t_truck' => _("12,5t Truck"), 'has_license_12_5t_truck' => _('12,5t Truck'),
'has_license_forklift' => _("Forklift"), 'has_license_forklift' => _('Forklift'),
'actions' => '' 'actions' => ''
]; ];
} }
return [ return [
'Nick' => _("Nick"), 'Nick' => _('Nick'),
'DECT' => _("DECT"), 'DECT' => _('DECT'),
'actions' => '' 'actions' => ''
]; ];
} }
/** /**
* Render an angeltype page containing the member lists. * Render an angeltype page containing the member lists.
*
* @param array $angeltype
* @param array[] $members
* @param array $user_angeltype
* @param bool $admin_user_angeltypes
* @param bool $admin_angeltypes
* @param bool $supporter
* @param array $user_driver_license
* @param array $user
* @param ShiftsFilterRenderer $shiftsFilterRenderer
* @param ShiftCalendarRenderer $shiftCalendarRenderer
* @param int $tab The selected tab
* @return string
*/ */
function AngelType_view($angeltype, $members, $user_angeltype, $admin_user_angeltypes, $admin_angeltypes, $supporter, $user_driver_license, $user) { function AngelType_view(
$page = [ $angeltype,
$members,
$user_angeltype,
$admin_user_angeltypes,
$admin_angeltypes,
$supporter,
$user_driver_license,
$user,
ShiftsFilterRenderer $shiftsFilterRenderer,
ShiftCalendarRenderer $shiftCalendarRenderer,
$tab
) {
return page_with_title(sprintf(_('Team %s'), $angeltype['name']), [
AngelType_view_buttons($angeltype, $user_angeltype, $admin_angeltypes, $supporter, $user_driver_license, $user), AngelType_view_buttons($angeltype, $user_angeltype, $admin_angeltypes, $supporter, $user_driver_license, $user),
msg() msg(),
]; tabs([
_('Info') => AngelType_view_info(
$angeltype,
$members,
$admin_user_angeltypes,
$admin_angeltypes,
$supporter
),
_('Shifts') => AngelType_view_shifts(
$angeltype,
$shiftsFilterRenderer,
$shiftCalendarRenderer
)
], $tab)
]);
}
$page[] = '<h3>' . _("Description") . '</h3>'; /**
$parsedown = new Parsedown(); * @param Angeltype $angeltype
if ($angeltype['description'] != "") { * @param ShiftsFilterRenderer $shiftsFilterRenderer
$page[] = '<div class="well">' . $parsedown->parse($angeltype['description']) . '</div>'; * @param ShiftCalendarRenderer $shiftCalendarRenderer
* @return string HTML
*/
function AngelType_view_shifts($angeltype, $shiftsFilterRenderer, $shiftCalendarRenderer)
{
$shifts = $shiftsFilterRenderer->render(page_link_to('angeltypes', [
'action' => 'view',
'angeltype_id' => $angeltype['id']
]));
$shifts .= $shiftCalendarRenderer->render();
return div('first', $shifts);
}
/**
* @param Angeltype $angeltype
* @param array $members
* @param bool $admin_user_angeltypes
* @param bool $admin_angeltypes
* @param bool $supporter
* @return string HTML
*/
function AngelType_view_info(
$angeltype,
$members,
$admin_user_angeltypes,
$admin_angeltypes,
$supporter
) {
$info = [];
if(AngelType_has_contact_info($angeltype)) {
$info[] = AngelTypes_render_contact_info($angeltype);
} }
list($supporters, $members_confirmed, $members_unconfirmed) = AngelType_view_members($angeltype, $members, $admin_user_angeltypes, $admin_angeltypes); $info[] = '<h3>' . _('Description') . '</h3>';
$parsedown = new Parsedown();
if ($angeltype['description'] != '') {
$info[] = '<div class="well">' . $parsedown->parse($angeltype['description']) . '</div>';
}
list($supporters, $members_confirmed, $members_unconfirmed) = AngelType_view_members(
$angeltype,
$members,
$admin_user_angeltypes,
$admin_angeltypes
);
$table_headers = AngelType_view_table_headers($angeltype, $supporter, $admin_angeltypes); $table_headers = AngelType_view_table_headers($angeltype, $supporter, $admin_angeltypes);
if (count($supporters) > 0) { if (count($supporters) > 0) {
$page[] = '<h3>' . _("supporters") . '</h3>'; $info[] = '<h3>' . _('supporters') . '</h3>';
$page[] = table($table_headers, $supporters); $info[] = table($table_headers, $supporters);
} }
if (count($members_confirmed) > 0) { if (count($members_confirmed) > 0) {
@ -232,70 +422,127 @@ function AngelType_view($angeltype, $members, $user_angeltype, $admin_user_angel
]; ];
} }
$page[] = '<h3>' . _("Members") . '</h3>'; $info[] = '<h3>' . _('Members') . '</h3>';
if ($admin_user_angeltypes) { if ($admin_user_angeltypes) {
$page[] = buttons([ $info[] = buttons([
button(page_link_to('user_angeltypes') . '&action=add&angeltype_id=' . $angeltype['id'], _("Add"), 'add') button(
page_link_to(
'user_angeltypes',
['action' => 'add', 'angeltype_id' => $angeltype['id']]
),
_('Add'),
'add'
)
]); ]);
} }
$page[] = table($table_headers, $members_confirmed); $info[] = table($table_headers, $members_confirmed);
if ($admin_user_angeltypes && $angeltype['restricted'] && count($members_unconfirmed) > 0) { if ($admin_user_angeltypes && $angeltype['restricted'] && count($members_unconfirmed) > 0) {
$page[] = '<h3>' . _("Unconfirmed") . '</h3>'; $info[] = '<h3>' . _('Unconfirmed') . '</h3>';
$page[] = buttons([ $info[] = buttons([
button(page_link_to('user_angeltypes') . '&action=confirm_all&angeltype_id=' . $angeltype['id'], _("confirm all"), 'ok'), button(
button(page_link_to('user_angeltypes') . '&action=delete_all&angeltype_id=' . $angeltype['id'], _("deny all"), 'cancel') 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($table_headers, $members_unconfirmed); $info[] = table($table_headers, $members_unconfirmed);
} }
return page_with_title(sprintf(_("Team %s"), $angeltype['name']), $page); return join($info);
}
/**
* Renders the contact info
*
* @param Anteltype $angeltype
* @return string HTML
*/
function AngelTypes_render_contact_info($angeltype)
{
return heading(_('Contact'), 3) . description([
_('Name') => $angeltype['contact_name'],
_('DECT') => $angeltype['contact_dect'],
_('E-Mail') => $angeltype['contact_email']
]);
} }
/** /**
* Display the list of angeltypes. * Display the list of angeltypes.
* *
* @param array $angeltypes * @param array $angeltypes
* @param bool $admin_angeltypes
* @return string
*/ */
function AngelTypes_list_view($angeltypes, $admin_angeltypes) { function AngelTypes_list_view($angeltypes, $admin_angeltypes)
{
return page_with_title(angeltypes_title(), [ return page_with_title(angeltypes_title(), [
msg(), msg(),
buttons([ buttons([
$admin_angeltypes ? button(page_link_to('angeltypes') . '&action=edit', _("New angeltype"), 'add') : '', $admin_angeltypes
button(page_link_to('angeltypes') . '&action=about', _("Teams/Job description")) ? button(page_link_to('angeltypes', ['action' => 'edit']), _('New angeltype'), 'add')
: '',
button(page_link_to('angeltypes', ['action' => 'about']), _('Teams/Job description'))
]), ]),
table([ table([
'name' => _("Name"), 'name' => _('Name'),
'restricted' => glyph('lock') . _("Restricted"), 'restricted' => glyph('lock') . _('Restricted'),
'no_self_signup' => glyph('share') . _("Self Sign Up Allowed"), 'no_self_signup' => glyph('share') . _('Self Sign Up Allowed'),
'membership' => _("Membership"), 'membership' => _('Membership'),
'actions' => "" 'actions' => ''
], $angeltypes) ], $angeltypes)
]); ]);
} }
/** /**
* Renders the about info for an angeltype. * Renders the about info for an angeltype.
*
* @param array $angeltype
* @return string
*/ */
function AngelTypes_about_view_angeltype($angeltype) { function AngelTypes_about_view_angeltype($angeltype)
{
$parsedown = new Parsedown(); $parsedown = new Parsedown();
$html = '<h2>' . $angeltype['name'] . '</h2>'; $html = '<h2>' . $angeltype['name'] . '</h2>';
if(AngelType_has_contact_info($angeltype)) {
$html .= AngelTypes_render_contact_info($angeltype);
}
if (isset($angeltype['user_angeltype_id'])) { if (isset($angeltype['user_angeltype_id'])) {
$buttons = []; $buttons = [];
if ($angeltype['user_angeltype_id'] != null) { if ($angeltype['user_angeltype_id'] != null) {
$buttons[] = button(page_link_to('user_angeltypes') . '&action=delete&user_angeltype_id=' . $angeltype['user_angeltype_id'], _("leave"), 'cancel'); $buttons[] = button(
page_link_to(
'user_angeltypes',
['action' => 'delete', 'user_angeltype_id' => $angeltype['user_angeltype_id']]
),
_('leave'),
'cancel'
);
} else { } else {
$buttons[] = button(page_link_to('user_angeltypes') . '&action=add&angeltype_id=' . $angeltype['id'], _("join"), 'add'); $buttons[] = button(
page_link_to('user_angeltypes', ['action' => 'add', 'angeltype_id' => $angeltype['id']]),
_('join'),
'add'
);
} }
$html .= buttons($buttons); $html .= buttons($buttons);
} }
if ($angeltype['restricted']) { if ($angeltype['restricted']) {
$html .= info(_("This angeltype is restricted by double-opt-in by a team supporter. Please show up at the according introduction meetings."), true); $html .= info(
_('This angeltype is restricted by double-opt-in by a team supporter. Please show up at the according introduction meetings.'),
true
);
} }
if ($angeltype['description'] != "") { if ($angeltype['description'] != '') {
$html .= '<div class="well">' . $parsedown->parse($angeltype['description']) . '</div>'; $html .= '<div class="well">' . $parsedown->parse($angeltype['description']) . '</div>';
} }
$html .= '<hr />'; $html .= '<hr />';
@ -305,25 +552,40 @@ function AngelTypes_about_view_angeltype($angeltype) {
/** /**
* Renders a site that contains every angeltype and its description, basically as an overview of the needed help types. * Renders a site that contains every angeltype and its description, basically as an overview of the needed help types.
*
* @param array[] $angeltypes
* @param bool $user_logged_in
* @return string
*/ */
function AngelTypes_about_view($angeltypes, $user_logged_in) { function AngelTypes_about_view($angeltypes, $user_logged_in)
global $faq_url; {
global $privileges;
$buttons = [];
if ($user_logged_in) {
$buttons[] = button(page_link_to('angeltypes'), angeltypes_title(), 'back');
} else {
if (in_array('register', $privileges) && config('registration_enabled')) {
$buttons[] = button(page_link_to('register'), register_title());
}
$buttons[] = button(page_link_to('login'), login_title());
}
$faqUrl = config('faq_url');
if (!empty($faqUrl)) {
$buttons[] = button($faqUrl, _('FAQ'), 'btn-primary');
}
$content = [ $content = [
buttons([ buttons($buttons),
! $user_logged_in ? button(page_link_to('register'), register_title()) : '', '<p>' . _('Here is the list of teams and their tasks. If you have questions, read the FAQ.') . '</p>',
! $user_logged_in ? button(page_link_to('login'), login_title()) : '',
$user_logged_in ? button(page_link_to('angeltypes'), angeltypes_title(), 'back') : '',
button($faq_url, _("FAQ"), "btn-primary")
]),
'<p>' . _("Here is the list of teams and their tasks. If you have questions, read the FAQ.") . '</p>',
'<hr />' '<hr />'
]; ];
foreach ($angeltypes as $angeltype) { foreach ($angeltypes as $angeltype) {
$content[] = AngelTypes_about_view_angeltype($angeltype); $content[] = AngelTypes_about_view_angeltype($angeltype);
} }
return page_with_title(_("Teams/Job description"), $content); return page_with_title(_('Teams/Job description'), $content);
} }
?>

View File

@ -2,12 +2,15 @@
/** /**
* Shows basic event infos and countdowns. * Shows basic event infos and countdowns.
* @param EventConfig $event_config The event configuration *
* @param array $event_config The event configuration
* @return string
*/ */
function EventConfig_countdown_page($event_config) { function EventConfig_countdown_page($event_config)
{
if ($event_config == null) { if ($event_config == null) {
return div('col-md-12 text-center', [ return div('col-md-12 text-center', [
heading(sprintf(_("Welcome to the %s!"), '<span class="icon-icon_angel"></span> ENGELSYSTEM'), 2) heading(sprintf(_('Welcome to the %s!'), '<span class="icon-icon_angel"></span> ENGELSYSTEM'), 2)
]); ]);
} }
@ -15,66 +18,85 @@ function EventConfig_countdown_page($event_config) {
if ($event_config['event_name'] != null) { if ($event_config['event_name'] != null) {
$elements[] = div('col-sm-12 text-center', [ $elements[] = div('col-sm-12 text-center', [
heading(sprintf(_("Welcome to the %s!"), $event_config['event_name'] . ' <span class="icon-icon_angel"></span> ENGELSYSTEM'), 2) heading(sprintf(
_('Welcome to the %s!'),
$event_config['event_name'] . ' <span class="icon-icon_angel"></span> ENGELSYSTEM'
), 2)
]); ]);
} }
if ($event_config['buildup_start_date'] != null && time() < $event_config['buildup_start_date']) { if ($event_config['buildup_start_date'] != null && time() < $event_config['buildup_start_date']) {
$elements[] = div('col-sm-3 text-center hidden-xs', [ $elements[] = div('col-sm-3 text-center hidden-xs', [
heading(_("Buildup starts"), 4), heading(_('Buildup starts'), 4),
'<span class="moment-countdown text-big" data-timestamp="' . $event_config['buildup_start_date'] . '">%c</span>', '<span class="moment-countdown text-big" data-timestamp="' . $event_config['buildup_start_date'] . '">%c</span>',
'<small>' . date(_("Y-m-d"), $event_config['buildup_start_date']) . '</small>' '<small>' . date(_('Y-m-d'), $event_config['buildup_start_date']) . '</small>'
]); ]);
} }
if ($event_config['event_start_date'] != null && time() < $event_config['event_start_date']) { if ($event_config['event_start_date'] != null && time() < $event_config['event_start_date']) {
$elements[] = div('col-sm-3 text-center hidden-xs', [ $elements[] = div('col-sm-3 text-center hidden-xs', [
heading(_("Event starts"), 4), heading(_('Event starts'), 4),
'<span class="moment-countdown text-big" data-timestamp="' . $event_config['event_start_date'] . '">%c</span>', '<span class="moment-countdown text-big" data-timestamp="' . $event_config['event_start_date'] . '">%c</span>',
'<small>' . date(_("Y-m-d"), $event_config['event_start_date']) . '</small>' '<small>' . date(_('Y-m-d'), $event_config['event_start_date']) . '</small>'
]); ]);
} }
if ($event_config['event_end_date'] != null && time() < $event_config['event_end_date']) { if ($event_config['event_end_date'] != null && time() < $event_config['event_end_date']) {
$elements[] = div('col-sm-3 text-center hidden-xs', [ $elements[] = div('col-sm-3 text-center hidden-xs', [
heading(_("Event ends"), 4), heading(_('Event ends'), 4),
'<span class="moment-countdown text-big" data-timestamp="' . $event_config['event_end_date'] . '">%c</span>', '<span class="moment-countdown text-big" data-timestamp="' . $event_config['event_end_date'] . '">%c</span>',
'<small>' . date(_("Y-m-d"), $event_config['event_end_date']) . '</small>' '<small>' . date(_('Y-m-d'), $event_config['event_end_date']) . '</small>'
]); ]);
} }
if ($event_config['teardown_end_date'] != null && time() < $event_config['teardown_end_date']) { if ($event_config['teardown_end_date'] != null && time() < $event_config['teardown_end_date']) {
$elements[] = div('col-sm-3 text-center hidden-xs', [ $elements[] = div('col-sm-3 text-center hidden-xs', [
heading(_("Teardown ends"), 4), heading(_('Teardown ends'), 4),
'<span class="moment-countdown text-big" data-timestamp="' . $event_config['teardown_end_date'] . '">%c</span>', '<span class="moment-countdown text-big" data-timestamp="' . $event_config['teardown_end_date'] . '">%c</span>',
'<small>' . date(_("Y-m-d"), $event_config['teardown_end_date']) . '</small>' '<small>' . date(_('Y-m-d'), $event_config['teardown_end_date']) . '</small>'
]); ]);
} }
return join("", $elements); return join('', $elements);
} }
/** /**
* Converts event name and start+end date into a line of text. * Converts event name and start+end date into a line of text.
*
* @param array $event_config
* @return string
*/ */
function EventConfig_info($event_config) { function EventConfig_info($event_config)
{
if ($event_config == null) { if ($event_config == null) {
return ""; return '';
} }
// Event name, start+end date are set // Event name, start+end date are set
if ($event_config['event_name'] != null && $event_config['event_start_date'] != null && $event_config['event_end_date'] != null) { if ($event_config['event_name'] != null && $event_config['event_start_date'] != null && $event_config['event_end_date'] != null) {
return sprintf(_("%s, from %s to %s"), $event_config['event_name'], date(_("Y-m-d"), $event_config['event_start_date']), date(_("Y-m-d"), $event_config['event_end_date'])); return sprintf(
_('%s, from %s to %s'),
$event_config['event_name'],
date(_('Y-m-d'), $event_config['event_start_date']),
date(_('Y-m-d'), $event_config['event_end_date'])
);
} }
// Event name, start date are set // Event name, start date are set
if ($event_config['event_name'] != null && $event_config['event_start_date'] != null) { if ($event_config['event_name'] != null && $event_config['event_start_date'] != null) {
return sprintf(_("%s, starting %s"), $event_config['event_name'], date(_("Y-m-d"), $event_config['event_start_date'])); return sprintf(
_('%s, starting %s'), $event_config['event_name'],
date(_('Y-m-d'), $event_config['event_start_date'])
);
} }
// Event start+end date are set // Event start+end date are set
if ($event_config['event_start_date'] != null && $event_config['event_end_date'] != null) { if ($event_config['event_start_date'] != null && $event_config['event_end_date'] != null) {
return sprintf(_("Event from %s to %s"), date(_("Y-m-d"), $event_config['event_start_date']), date(_("Y-m-d"), $event_config['event_end_date'])); return sprintf(
_('Event from %s to %s'),
date(_('Y-m-d'), $event_config['event_start_date']),
date(_('Y-m-d'), $event_config['event_end_date'])
);
} }
// Only event name is set // Only event name is set
@ -82,48 +104,52 @@ function EventConfig_info($event_config) {
return sprintf($event_config['event_name']); return sprintf($event_config['event_name']);
} }
return ""; return '';
} }
/** /**
* Render edit page for event config. * Render edit page for event config.
* *
* @param string $event_name * @param string $event_name The event name
* The event name * @param string $event_welcome_msg The welcome message
* @param string $event_welcome_msg * @param int $buildup_start_date unix time stamp
* The welcome message * @param int $event_start_date unix time stamp
* @param date $buildup_start_date * @param int $event_end_date unix time stamp
* @param date $event_start_date * @param int $teardown_end_date unix time stamp
* @param date $event_end_date * @return string
* @param date $teardown_end_date
*/ */
function EventConfig_edit_view($event_name, $event_welcome_msg, $buildup_start_date, $event_start_date, $event_end_date, $teardown_end_date) { function EventConfig_edit_view(
$event_name,
$event_welcome_msg,
$buildup_start_date,
$event_start_date,
$event_end_date,
$teardown_end_date
) {
return page_with_title(event_config_title(), [ return page_with_title(event_config_title(), [
msg(), msg(),
form([ form([
div('row', [ div('row', [
div('col-md-6', [ div('col-md-6', [
form_text('event_name', _("Event Name"), $event_name), form_text('event_name', _('Event Name'), $event_name),
form_info('', _("Event Name is shown on the start page.")), form_info('', _('Event Name is shown on the start page.')),
form_textarea('event_welcome_msg', _("Event Welcome Message"), $event_welcome_msg), form_textarea('event_welcome_msg', _('Event Welcome Message'), $event_welcome_msg),
form_info('', _("Welcome message is shown after successful registration. You can use markdown.")) form_info('', _('Welcome message is shown after successful registration. You can use markdown.'))
]), ]),
div('col-md-3 col-xs-6', [ div('col-md-3 col-xs-6', [
form_date('buildup_start_date', _("Buildup date"), $buildup_start_date), form_date('buildup_start_date', _('Buildup date'), $buildup_start_date),
form_date('event_start_date', _("Event start date"), $event_start_date) form_date('event_start_date', _('Event start date'), $event_start_date)
]), ]),
div('col-md-3 col-xs-6', [ div('col-md-3 col-xs-6', [
form_date('teardown_end_date', _("Teardown end date"), $teardown_end_date), form_date('teardown_end_date', _('Teardown end date'), $teardown_end_date),
form_date('event_end_date', _("Event end date"), $event_end_date) form_date('event_end_date', _('Event end date'), $event_end_date)
]) ])
]), ]),
div('row', [ div('row', [
div('col-md-6', [ div('col-md-6', [
form_submit('submit', _("Save")) form_submit('submit', _('Save'))
]) ])
]) ])
]) ])
]); ]);
} }
?>

View File

@ -1,37 +1,50 @@
<?php <?php
function Questions_view($open_questions, $answered_questions, $ask_action) { /**
* @param array[] $open_questions
* @param array[] $answered_questions
* @param string $ask_action
* @return string
*/
function Questions_view($open_questions, $answered_questions, $ask_action)
{
foreach ($open_questions as &$question) { foreach ($open_questions as &$question) {
$question['actions'] = '<a href="' . page_link_to("user_questions") . '&action=delete&id=' . $question['QID'] . '">' . _("delete") . '</a>'; $question['actions'] = '<a href="'
. page_link_to('user_questions', ['action' => 'delete', 'id' => $question['QID']])
. '">'
. _('delete')
. '</a>';
$question['Question'] = str_replace("\n", '<br />', $question['Question']); $question['Question'] = str_replace("\n", '<br />', $question['Question']);
} }
foreach ($answered_questions as &$question) { foreach ($answered_questions as &$question) {
$question['Question'] = str_replace("\n", '<br />', $question['Question']); $question['Question'] = str_replace("\n", '<br />', $question['Question']);
$question['Answer'] = str_replace("\n", '<br />', $question['Answer']); $question['Answer'] = str_replace("\n", '<br />', $question['Answer']);
$question['actions'] = '<a href="' . page_link_to("user_questions") . '&action=delete&id=' . $question['QID'] . '">' . _("delete") . '</a>'; $question['actions'] = '<a href="'
. page_link_to('user_questions', ['action' => 'delete', 'id' => $question['QID']])
. '">'
. _('delete')
. '</a>';
} }
return page_with_title(questions_title(), [ return page_with_title(questions_title(), [
msg(), msg(),
heading(_("Open questions"), 2), heading(_('Open questions'), 2),
table([ table([
'Question' => _("Question"), 'Question' => _('Question'),
'actions' => "" 'actions' => ''
], $open_questions), ], $open_questions),
heading(_("Answered questions"), 2), heading(_('Answered questions'), 2),
table([ table([
'Question' => _("Question"), 'Question' => _('Question'),
'answer_user' => _("Answered by"), 'answer_user' => _('Answered by'),
'Answer' => _("Answer"), 'Answer' => _('Answer'),
'actions' => "" 'actions' => ''
], $answered_questions), ], $answered_questions),
heading(_("Ask the Heaven"), 2), heading(_('Ask the Heaven'), 2),
form([ form([
form_textarea('question', _("Your Question:"), ""), form_textarea('question', _('Your Question:'), ''),
form_submit('submit', _("Save")) form_submit('submit', _('Save'))
], $ask_action) ], $ask_action)
]); ]);
} }
?>

View File

@ -1,20 +1,42 @@
<?php <?php
use Engelsystem\ShiftsFilterRenderer;
use Engelsystem\ShiftCalendarRenderer;
function Room_view($room, ShiftsFilterRenderer $shiftsFilterRenderer, ShiftCalendarRenderer $shiftCalendarRenderer) { use Engelsystem\ShiftCalendarRenderer;
use Engelsystem\ShiftsFilterRenderer;
/**
* @param array $room
* @param ShiftsFilterRenderer $shiftsFilterRenderer
* @param ShiftCalendarRenderer $shiftCalendarRenderer
* @return string
*/
function Room_view($room, ShiftsFilterRenderer $shiftsFilterRenderer, ShiftCalendarRenderer $shiftCalendarRenderer)
{
global $user;
$assignNotice = '';
if (config('signup_requires_arrival') && !$user['Gekommen']) {
$assignNotice = info(render_user_arrived_hint(), true);
}
return page_with_title(glyph('map-marker') . $room['Name'], [ return page_with_title(glyph('map-marker') . $room['Name'], [
$shiftsFilterRenderer->render(room_link($room)) , $shiftsFilterRenderer->render(page_link_to('rooms', [
'action' => 'view',
'room_id' => $room['RID']
])),
$assignNotice,
$shiftCalendarRenderer->render() $shiftCalendarRenderer->render()
]); ]);
} }
function Room_name_render($room) { /**
* @param array $room
* @return string
*/
function Room_name_render($room)
{
global $privileges; global $privileges;
if (in_array('view_rooms', $privileges)) { if (in_array('view_rooms', $privileges)) {
return '<a href="' . room_link($room) . '">' . glyph('map-marker') . $room['Name'] . '</a>'; return '<a href="' . room_link($room) . '">' . glyph('map-marker') . $room['Name'] . '</a>';
} }
return glyph('map-marker') . $room['Name']; return glyph('map-marker') . $room['Name'];
} }
?>

View File

@ -2,20 +2,34 @@
namespace Engelsystem; namespace Engelsystem;
use Exception;
/** /**
* Represents a single lane in a shifts calendar. * Represents a single lane in a shifts calendar.
*/ */
class ShiftCalendarLane { class ShiftCalendarLane
{
/** @var int */
private $firstBlockStartTime; private $firstBlockStartTime;
/** @var int */
private $blockCount; private $blockCount;
/** @var string */
private $header; private $header;
/** @var array[] */
private $shifts = []; private $shifts = [];
public function __construct($header, $firstBlockStartTime, $blockCount) { /**
* ShiftCalendarLane constructor.
*
* @param string $header
* @param int $firstBlockStartTime Unix timestamp
* @param int $blockCount
*/
public function __construct($header, $firstBlockStartTime, $blockCount)
{
$this->header = $header; $this->header = $header;
$this->firstBlockStartTime = $firstBlockStartTime; $this->firstBlockStartTime = $firstBlockStartTime;
$this->blockCount = $blockCount; $this->blockCount = $blockCount;
@ -25,39 +39,48 @@ class ShiftCalendarLane {
* Adds a shift to the lane, but only if it fits. * Adds a shift to the lane, but only if it fits.
* Returns true on success. * Returns true on success.
* *
* @param Shift $shift * @param array $shift The shift to add
* The shift to add * @throws Exception if the shift doesn't fit into the lane.
* @return boolean true on success
*/ */
public function addShift($shift) { public function addShift($shift)
{
if ($this->shiftFits($shift)) { if ($this->shiftFits($shift)) {
$this->shifts[] = $shift; $this->shifts[] = $shift;
return true; return;
} }
return false; throw new Exception('Unable to add shift to shift calendar lane.');
} }
/** /**
* Returns true if given shift fits into this lane. * Returns true if given shift fits into this lane.
* *
* @param Shift $shift * @param array $newShift
* The shift to fit into this lane * @return bool
* @internal param array $shift The shift to fit into this lane
*/ */
public function shiftFits($newShift) { public function shiftFits($newShift)
{
foreach ($this->shifts as $laneShift) { foreach ($this->shifts as $laneShift) {
if (! ($newShift['start'] >= $laneShift['end'] || $newShift['end'] <= $laneShift['start'])) { if (!($newShift['start'] >= $laneShift['end'] || $newShift['end'] <= $laneShift['start'])) {
return false; return false;
} }
} }
return true; return true;
} }
public function getHeader() { /**
* @return string
*/
public function getHeader()
{
return $this->header; return $this->header;
} }
public function getShifts() { /**
* @return array[]
*/
public function getShifts()
{
return $this->shifts; return $this->shifts;
} }
} }
?>

View File

@ -2,8 +2,8 @@
namespace Engelsystem; namespace Engelsystem;
class ShiftCalendarRenderer { class ShiftCalendarRenderer
{
/** /**
* 15m * 60s/m = 900s * 15m * 60s/m = 900s
*/ */
@ -25,21 +25,37 @@ class ShiftCalendarRenderer {
*/ */
const TIME_MARGIN = 1800; const TIME_MARGIN = 1800;
/** @var array */
private $lanes; private $lanes;
/** @var ShiftsFilter */
private $shiftsFilter; private $shiftsFilter;
private $firstBlockStartTime = null; /** @var int */
private $firstBlockStartTime = 0;
private $lastBlockEndTime = null; /** @var int */
private $lastBlockEndTime = 0;
/** @var int */
private $blocksPerSlot = null; private $blocksPerSlot = null;
private $needed_angeltypes = null; /** @var array[] */
private $needed_angeltypes = [];
private $shift_entries = null; /** @var array[] */
private $shift_entries = [];
public function __construct($shifts, $needed_angeltypes, $shift_entries, ShiftsFilter $shiftsFilter) { /**
* ShiftCalendarRenderer constructor.
*
* @param array[] $shifts
* @param array[] $needed_angeltypes
* @param array[] $shift_entries
* @param ShiftsFilter $shiftsFilter
*/
public function __construct($shifts, $needed_angeltypes, $shift_entries, ShiftsFilter $shiftsFilter)
{
$this->shiftsFilter = $shiftsFilter; $this->shiftsFilter = $shiftsFilter;
$this->firstBlockStartTime = $this->calcFirstBlockStartTime($shifts); $this->firstBlockStartTime = $this->calcFirstBlockStartTime($shifts);
$this->lastBlockEndTime = $this->calcLastBlockEndTime($shifts); $this->lastBlockEndTime = $this->calcLastBlockEndTime($shifts);
@ -51,12 +67,11 @@ class ShiftCalendarRenderer {
/** /**
* Assigns the shifts to different lanes per room if they collide * Assigns the shifts to different lanes per room if they collide
* *
* @param Shift[] $shifts * @param array[] $shifts The shifts to assign
* The shifts to assign * @return array Returns an array that assigns a room_id to an array of ShiftCalendarLane containing the shifts
*
* @return Returns an array that assigns a room_id to an array of ShiftCalendarLane containing the shifts
*/ */
private function assignShiftsToLanes($shifts) { private function assignShiftsToLanes($shifts)
{
// array that assigns a room id to a list of lanes (per room) // array that assigns a room id to a list of lanes (per room)
$lanes = []; $lanes = [];
@ -66,7 +81,7 @@ class ShiftCalendarRenderer {
'RID' => $room_id, 'RID' => $room_id,
'Name' => $shift['room_name'] 'Name' => $shift['room_name']
]); ]);
if (! isset($lanes[$room_id])) { if (!isset($lanes[$room_id])) {
// initialize room with one lane // initialize room with one lane
$lanes[$room_id] = [ $lanes[$room_id] = [
new ShiftCalendarLane($header, $this->getFirstBlockStartTime(), $this->getBlocksPerSlot()) new ShiftCalendarLane($header, $this->getFirstBlockStartTime(), $this->getBlocksPerSlot())
@ -75,17 +90,17 @@ class ShiftCalendarRenderer {
// Try to add the shift to the existing lanes for this room // Try to add the shift to the existing lanes for this room
$shift_added = false; $shift_added = false;
foreach ($lanes[$room_id] as $lane) { foreach ($lanes[$room_id] as $lane) {
$shift_added = $lane->addShift($shift); /** @var ShiftCalendarLane $lane */
if ($shift_added == true) { if ($lane->shiftFits($shift)) {
$lane->addShift($shift);
$shift_added = true;
break; break;
} }
} }
// If all lanes for this room are busy, create a new lane and add shift to it // If all lanes for this room are busy, create a new lane and add shift to it
if ($shift_added == false) { if ($shift_added == false) {
$newLane = new ShiftCalendarLane($header, $this->getFirstBlockStartTime(), $this->getBlocksPerSlot()); $newLane = new ShiftCalendarLane($header, $this->getFirstBlockStartTime(), $this->getBlocksPerSlot());
if (! $newLane->addShift($shift)) { $newLane->addShift($shift);
engelsystem_error("Unable to add shift to new lane.");
}
$lanes[$room_id][] = $newLane; $lanes[$room_id][] = $newLane;
} }
} }
@ -93,15 +108,27 @@ class ShiftCalendarRenderer {
return $lanes; return $lanes;
} }
public function getFirstBlockStartTime() { /**
* @return int
*/
public function getFirstBlockStartTime()
{
return $this->firstBlockStartTime; return $this->firstBlockStartTime;
} }
public function getLastBlockEndTime() { /**
* @return int
*/
public function getLastBlockEndTime()
{
return $this->lastBlockEndTime; return $this->lastBlockEndTime;
} }
public function getBlocksPerSlot() { /**
* @return float
*/
public function getBlocksPerSlot()
{
if ($this->blocksPerSlot == null) { if ($this->blocksPerSlot == null) {
$this->blocksPerSlot = $this->calcBlocksPerSlot(); $this->blocksPerSlot = $this->calcBlocksPerSlot();
} }
@ -111,11 +138,12 @@ class ShiftCalendarRenderer {
/** /**
* Renders the whole calendar * Renders the whole calendar
* *
* @return the generated html * @return string the generated html
*/ */
public function render() { public function render()
{
if (count($this->lanes) == 0) { if (count($this->lanes) == 0) {
return ''; return info(_('No shifts found.'), true);
} }
return div('shift-calendar', [ return div('shift-calendar', [
$this->renderTimeLane(), $this->renderTimeLane(),
@ -125,9 +153,12 @@ class ShiftCalendarRenderer {
/** /**
* Renders the lanes containing the shifts * Renders the lanes containing the shifts
*
* @return string
*/ */
private function renderShiftLanes() { private function renderShiftLanes()
$html = ""; {
$html = '';
foreach ($this->lanes as $room_lanes) { foreach ($this->lanes as $room_lanes) {
foreach ($room_lanes as $lane) { foreach ($room_lanes as $lane) {
$html .= $this->renderLane($lane); $html .= $this->renderLane($lane);
@ -140,14 +171,15 @@ class ShiftCalendarRenderer {
/** /**
* Renders a single lane * Renders a single lane
* *
* @param ShiftCalendarLane $lane * @param ShiftCalendarLane $lane The lane to render
* The lane to render * @return string
*/ */
private function renderLane(ShiftCalendarLane $lane) { private function renderLane(ShiftCalendarLane $lane)
{
global $user; global $user;
$shift_renderer = new ShiftCalendarShiftRenderer(); $shift_renderer = new ShiftCalendarShiftRenderer();
$html = ""; $html = '';
$rendered_until = $this->getFirstBlockStartTime(); $rendered_until = $this->getFirstBlockStartTime();
foreach ($lane->getShifts() as $shift) { foreach ($lane->getShifts() as $shift) {
@ -156,7 +188,12 @@ class ShiftCalendarRenderer {
$rendered_until += ShiftCalendarRenderer::SECONDS_PER_ROW; $rendered_until += ShiftCalendarRenderer::SECONDS_PER_ROW;
} }
list($shift_height, $shift_html) = $shift_renderer->render($shift, $this->needed_angeltypes[$shift['SID']], $this->shift_entries[$shift['SID']], $user); list ($shift_height, $shift_html) = $shift_renderer->render(
$shift,
$this->needed_angeltypes[$shift['SID']],
$this->shift_entries[$shift['SID']],
$user
);
$html .= $shift_html; $html .= $shift_html;
$rendered_until += $shift_height * ShiftCalendarRenderer::SECONDS_PER_ROW; $rendered_until += $shift_height * ShiftCalendarRenderer::SECONDS_PER_ROW;
} }
@ -175,22 +212,21 @@ class ShiftCalendarRenderer {
/** /**
* Renders a tick/block for given time * Renders a tick/block for given time
* *
* @param int $time * @param int $time unix timestamp
* unix timestamp * @param boolean $label Should time labels be generated?
* @param boolean $label * @return string rendered tick html
* Should time labels be generated?
* @return rendered tick html
*/ */
private function renderTick($time, $label = false) { private function renderTick($time, $label = false)
{
if ($time % (24 * 60 * 60) == 23 * 60 * 60) { if ($time % (24 * 60 * 60) == 23 * 60 * 60) {
if (! $label) { if (!$label) {
return div('tick day'); return div('tick day');
} }
return div('tick day', [ return div('tick day', [
date('m-d<b\r />H:i', $time) date('m-d<b\r />H:i', $time)
]); ]);
} elseif ($time % (60 * 60) == 0) { } elseif ($time % (60 * 60) == 0) {
if (! $label) { if (!$label) {
return div('tick hour'); return div('tick hour');
} }
return div('tick hour', [ return div('tick hour', [
@ -202,21 +238,29 @@ class ShiftCalendarRenderer {
/** /**
* Renders the left time lane including hour/day ticks * Renders the left time lane including hour/day ticks
*
* @return string
*/ */
private function renderTimeLane() { private function renderTimeLane()
{
$time_slot = [ $time_slot = [
div('header', [ div('header', [
_("Time") _('Time')
]) ])
]; ];
for ($block = 0; $block < $this->getBlocksPerSlot(); $block ++) { for ($block = 0; $block < $this->getBlocksPerSlot(); $block++) {
$thistime = $this->getFirstBlockStartTime() + ($block * ShiftCalendarRenderer::SECONDS_PER_ROW); $thistime = $this->getFirstBlockStartTime() + ($block * ShiftCalendarRenderer::SECONDS_PER_ROW);
$time_slot[] = $this->renderTick($thistime, true); $time_slot[] = $this->renderTick($thistime, true);
} }
return div('lane time', $time_slot); return div('lane time', $time_slot);
} }
private function calcFirstBlockStartTime($shifts) { /**
* @param array[] $shifts
* @return int
*/
private function calcFirstBlockStartTime($shifts)
{
$start_time = $this->shiftsFilter->getEndTime(); $start_time = $this->shiftsFilter->getEndTime();
foreach ($shifts as $shift) { foreach ($shifts as $shift) {
if ($shift['start'] < $start_time) { if ($shift['start'] < $start_time) {
@ -226,7 +270,12 @@ class ShiftCalendarRenderer {
return ShiftCalendarRenderer::SECONDS_PER_ROW * floor(($start_time - ShiftCalendarRenderer::TIME_MARGIN) / ShiftCalendarRenderer::SECONDS_PER_ROW); return ShiftCalendarRenderer::SECONDS_PER_ROW * floor(($start_time - ShiftCalendarRenderer::TIME_MARGIN) / ShiftCalendarRenderer::SECONDS_PER_ROW);
} }
private function calcLastBlockEndTime($shifts) { /**
* @param array[] $shifts
* @return int
*/
private function calcLastBlockEndTime($shifts)
{
$end_time = $this->shiftsFilter->getStartTime(); $end_time = $this->shiftsFilter->getStartTime();
foreach ($shifts as $shift) { foreach ($shifts as $shift) {
if ($shift['end'] > $end_time) { if ($shift['end'] > $end_time) {
@ -236,14 +285,21 @@ class ShiftCalendarRenderer {
return ShiftCalendarRenderer::SECONDS_PER_ROW * ceil(($end_time + ShiftCalendarRenderer::TIME_MARGIN) / ShiftCalendarRenderer::SECONDS_PER_ROW); return ShiftCalendarRenderer::SECONDS_PER_ROW * ceil(($end_time + ShiftCalendarRenderer::TIME_MARGIN) / ShiftCalendarRenderer::SECONDS_PER_ROW);
} }
private function calcBlocksPerSlot() { /**
* @return int
*/
private function calcBlocksPerSlot()
{
return ceil(($this->getLastBlockEndTime() - $this->getFirstBlockStartTime()) / ShiftCalendarRenderer::SECONDS_PER_ROW); return ceil(($this->getLastBlockEndTime() - $this->getFirstBlockStartTime()) / ShiftCalendarRenderer::SECONDS_PER_ROW);
} }
/** /**
* Renders a legend explaining the shift coloring * Renders a legend explaining the shift coloring
*
* @return string
*/ */
private function renderLegend() { private function renderLegend()
{
return div('legend', [ return div('legend', [
label(_('Your shift'), 'primary'), label(_('Your shift'), 'primary'),
label(_('Help needed'), 'danger'), label(_('Help needed'), 'danger'),
@ -253,5 +309,3 @@ class ShiftCalendarRenderer {
]); ]);
} }
} }
?>

View File

@ -5,30 +5,39 @@ namespace Engelsystem;
/** /**
* Renders a single shift for the shift calendar * Renders a single shift for the shift calendar
*/ */
class ShiftCalendarShiftRenderer { class ShiftCalendarShiftRenderer
{
/** /**
* Renders a shift * Renders a shift
* *
* @param Shift $shift * @param array $shift The shift to render
* The shift to render * @param array $needed_angeltypes
* @param User $user * @param array $shift_entries
* The user who is viewing the shift calendar * @param array $user The user who is viewing the shift calendar
* @return array
*/ */
public function render($shift, $needed_angeltypes, $shift_entries, $user) { public function render($shift, $needed_angeltypes, $shift_entries, $user)
$info_text = ""; {
$info_text = '';
if ($shift['title'] != '') { if ($shift['title'] != '') {
$info_text = glyph('info-sign') . $shift['title'] . '<br>'; $info_text = glyph('info-sign') . $shift['title'] . '<br>';
} }
list($shift_signup_state, $shifts_row) = $this->renderShiftNeededAngeltypes($shift, $needed_angeltypes, $shift_entries, $user); list($shift_signup_state, $shifts_row) = $this->renderShiftNeededAngeltypes(
$shift,
$needed_angeltypes,
$shift_entries,
$user
);
$class = $this->classForSignupState($shift_signup_state); $class = $this->classForSignupState($shift_signup_state);
$blocks = ceil(($shift["end"] - $shift["start"]) / ShiftCalendarRenderer::SECONDS_PER_ROW); $blocks = ceil(($shift['end'] - $shift['start']) / ShiftCalendarRenderer::SECONDS_PER_ROW);
$blocks = max(1, $blocks); $blocks = max(1, $blocks);
return [ return [
$blocks, $blocks,
div('shift panel panel-' . $class . '" style="height: ' . ($blocks * ShiftCalendarRenderer::BLOCK_HEIGHT - ShiftCalendarRenderer::MARGIN) . 'px"', [ div(
'shift panel panel-' . $class . '" style="height: ' . ($blocks * ShiftCalendarRenderer::BLOCK_HEIGHT - ShiftCalendarRenderer::MARGIN) . 'px"',
[
$this->renderShiftHead($shift), $this->renderShiftHead($shift),
div('panel-body', [ div('panel-body', [
$info_text, $info_text,
@ -39,11 +48,17 @@ class ShiftCalendarShiftRenderer {
]), ]),
$shifts_row, $shifts_row,
div('shift-spacer') div('shift-spacer')
]) ]
)
]; ];
} }
private function classForSignupState(ShiftSignupState $shiftSignupState) { /**
* @param ShiftSignupState $shiftSignupState
* @return string
*/
private function classForSignupState(ShiftSignupState $shiftSignupState)
{
switch ($shiftSignupState->getState()) { switch ($shiftSignupState->getState()) {
case ShiftSignupState::ADMIN: case ShiftSignupState::ADMIN:
case ShiftSignupState::OCCUPIED: case ShiftSignupState::OCCUPIED:
@ -61,10 +76,20 @@ class ShiftCalendarShiftRenderer {
case ShiftSignupState::FREE: case ShiftSignupState::FREE:
return 'danger'; return 'danger';
default:
return '';
} }
} }
private function renderShiftNeededAngeltypes($shift, $needed_angeltypes, $shift_entries, $user) { /**
* @param array $shift
* @param array[] $needed_angeltypes
* @param array[] $shift_entries
* @param array $user
* @return array
*/
private function renderShiftNeededAngeltypes($shift, $needed_angeltypes, $shift_entries, $user)
{
global $privileges; global $privileges;
$shift_entries_filtered = []; $shift_entries_filtered = [];
@ -75,11 +100,17 @@ class ShiftCalendarShiftRenderer {
$shift_entries_filtered[$shift_entry['TID']][] = $shift_entry; $shift_entries_filtered[$shift_entry['TID']][] = $shift_entry;
} }
$html = ""; $html = '';
/** @var ShiftSignupState $shift_signup_state */
$shift_signup_state = null; $shift_signup_state = null;
foreach ($needed_angeltypes as $angeltype) { foreach ($needed_angeltypes as $angeltype) {
if ($angeltype['count'] > 0 || count($shift_entries_filtered[$angeltype['id']]) > 0) { if ($angeltype['count'] > 0 || count($shift_entries_filtered[$angeltype['id']]) > 0) {
list($angeltype_signup_state, $angeltype_html) = $this->renderShiftNeededAngeltype($shift, $shift_entries_filtered[$angeltype['id']], $angeltype, $user); list($angeltype_signup_state, $angeltype_html) = $this->renderShiftNeededAngeltype(
$shift,
$shift_entries_filtered[$angeltype['id']],
$angeltype,
$user
);
if ($shift_signup_state == null) { if ($shift_signup_state == null) {
$shift_signup_state = $angeltype_signup_state; $shift_signup_state = $angeltype_signup_state;
} else { } else {
@ -93,7 +124,13 @@ class ShiftCalendarShiftRenderer {
} }
if (in_array('user_shifts_admin', $privileges)) { if (in_array('user_shifts_admin', $privileges)) {
$html .= '<li class="list-group-item">' . button(page_link_to('user_shifts') . '&amp;shift_id=' . $shift['SID'], _("Add more angels"), 'btn-xs') . '</li>'; $html .= '<li class="list-group-item">';
$html .= button(
page_link_to('user_shifts', ['shift_id' => $shift['SID']]),
glyph('plus') . _('Add more angels'),
'btn-xs'
);
$html .= '</li>';
} }
if ($html != '') { if ($html != '') {
return [ return [
@ -103,33 +140,46 @@ class ShiftCalendarShiftRenderer {
} }
return [ return [
$shift_signup_state, $shift_signup_state,
"" ''
]; ];
} }
/** /**
* Renders a list entry containing the needed angels for an angeltype * Renders a list entry containing the needed angels for an angeltype
* *
* @param Shift $shift * @param array $shift The shift which is rendered
* The shift which is rendered * @param array[] $shift_entries
* @param Angeltype $angeltype * @param array[] $angeltype The angeltype, containing informations about needed angeltypes
* The angeltype, containing informations about needed angeltypes and already signed up angels * and already signed up angels
* @param User $user * @param array $user The user who is viewing the shift calendar
* The user who is viewing the shift calendar * @return array
*/ */
private function renderShiftNeededAngeltype($shift, $shift_entries, $angeltype, $user) { private function renderShiftNeededAngeltype($shift, $shift_entries, $angeltype, $user)
{
$entry_list = []; $entry_list = [];
foreach ($shift_entries as $entry) { foreach ($shift_entries as $entry) {
$style = $entry['freeloaded'] ? " text-decoration: line-through;" : ''; $style = $entry['freeloaded'] ? ' text-decoration: line-through;' : '';
$entry_list[] = "<span style=\"$style\">" . User_Nick_render($entry) . "</span>"; $entry_list[] = '<span style="' . $style . '">' . User_Nick_render($entry) . '</span>';
} }
$shift_signup_state = Shift_signup_allowed($user, $shift, $angeltype, null, null, $angeltype, $shift_entries); $shift_signup_state = Shift_signup_allowed($user, $shift, $angeltype, null, null, $angeltype, $shift_entries);
$inner_text = sprintf(ngettext("%d helper needed", "%d helpers needed", $shift_signup_state->getFreeEntries()), $shift_signup_state->getFreeEntries()); $inner_text = sprintf(
ngettext('%d helper needed', '%d helpers needed', $shift_signup_state->getFreeEntries()),
$shift_signup_state->getFreeEntries()
);
switch ($shift_signup_state->getState()) { switch ($shift_signup_state->getState()) {
case ShiftSignupState::ADMIN: case ShiftSignupState::ADMIN:
case ShiftSignupState::FREE: case ShiftSignupState::FREE:
// When admin or free display a link + button for sign up // When admin or free display a link + button for sign up
$entry_list[] = '<a href="' . page_link_to('user_shifts') . '&amp;shift_id=' . $shift['SID'] . '&amp;type_id=' . $angeltype['id'] . '">' . $inner_text . '</a> ' . button(page_link_to('user_shifts') . '&amp;shift_id=' . $shift['SID'] . '&amp;type_id=' . $angeltype['id'], _('Sign up'), 'btn-xs btn-primary'); $entry_list[] = '<a href="'
. page_link_to('user_shifts', ['shift_id' => $shift['SID'], 'type_id' => $angeltype['id']])
. '">'
. $inner_text
. '</a> '
. button(
page_link_to('user_shifts', ['shift_id' => $shift['SID'], 'type_id' => $angeltype['id']]),
_('Sign up'), 'btn-xs btn-primary'
);
break; break;
case ShiftSignupState::SHIFT_ENDED: case ShiftSignupState::SHIFT_ENDED:
@ -143,7 +193,12 @@ class ShiftCalendarShiftRenderer {
$entry_list[] = $inner_text . glyph('lock'); $entry_list[] = $inner_text . glyph('lock');
} else { } else {
// Add link to join the angeltype first // Add link to join the angeltype first
$entry_list[] = $inner_text . '<br />' . button(page_link_to('user_angeltypes') . '&action=add&angeltype_id=' . $angeltype['id'], sprintf(_('Become %s'), $angeltype['name']), 'btn-xs'); $entry_list[] = $inner_text . '<br />'
. button(
page_link_to('user_angeltypes', ['action' => 'add', 'angeltype_id' => $angeltype['id']]),
sprintf(_('Become %s'), $angeltype['name']),
'btn-xs'
);
} }
break; break;
@ -160,7 +215,7 @@ class ShiftCalendarShiftRenderer {
$shifts_row = '<li class="list-group-item">'; $shifts_row = '<li class="list-group-item">';
$shifts_row .= '<strong>' . AngelType_name_render($angeltype) . ':</strong> '; $shifts_row .= '<strong>' . AngelType_name_render($angeltype) . ':</strong> ';
$shifts_row .= join(", ", $entry_list); $shifts_row .= join(', ', $entry_list);
$shifts_row .= '</li>'; $shifts_row .= '</li>';
return [ return [
$shift_signup_state, $shift_signup_state,
@ -171,25 +226,26 @@ class ShiftCalendarShiftRenderer {
/** /**
* Renders the shift header * Renders the shift header
* *
* @param Shift $shift * @param array $shift The shift
* The shift * @return string
*/ */
private function renderShiftHead($shift) { private function renderShiftHead($shift)
{
global $privileges; global $privileges;
$header_buttons = ""; $header_buttons = '';
if (in_array('admin_shifts', $privileges)) { if (in_array('admin_shifts', $privileges)) {
$header_buttons = '<div class="pull-right">' . table_buttons([ $header_buttons = '<div class="pull-right">' . table_buttons([
button(page_link_to('user_shifts') . '&edit_shift=' . $shift['SID'], glyph('edit'), 'btn-xs'), button(page_link_to('user_shifts', ['edit_shift' => $shift['SID']]), glyph('edit'), 'btn-xs'),
button(page_link_to('user_shifts') . '&delete_shift=' . $shift['SID'], glyph('trash'), 'btn-xs') button(page_link_to('user_shifts', ['delete_shift' => $shift['SID']]), glyph('trash'), 'btn-xs')
]) . '</div>'; ]) . '</div>';
} }
$shift_heading = date('H:i', $shift['start']) . ' &dash; ' . date('H:i', $shift['end']) . ' &mdash; ' . $shift['name']; $shift_heading = date('H:i', $shift['start']) . ' &dash; '
. date('H:i', $shift['end']) . ' &mdash; '
. $shift['name'];
return div('panel-heading', [ return div('panel-heading', [
'<a href="' . shift_link($shift) . '">' . $shift_heading . '</a>', '<a href="' . shift_link($shift) . '">' . $shift_heading . '</a>',
$header_buttons $header_buttons
]); ]);
} }
} }
?>

View File

@ -2,36 +2,47 @@
/** /**
* Display form for adding/editing a shift entry. * Display form for adding/editing a shift entry.
*
* @param string $angel * @param string $angel
* @param string $date * @param string $date
* @param string $location * @param string $location
* @param string $title * @param string $title
* @param string $type * @param string $type
* @param string $comment * @param string $comment
* * @param bool $freeloaded
* @param string $freeload_comment
* @param bool $user_admin_shifts
* @return string * @return string
*/ */
function ShiftEntry_edit_view($angel, $date, $location, $title, $type, $comment, $freeloaded, $freeload_comment, $user_admin_shifts = false) { function ShiftEntry_edit_view(
$angel,
$date,
$location,
$title,
$type,
$comment,
$freeloaded,
$freeload_comment,
$user_admin_shifts = false
) {
$freeload_form = []; $freeload_form = [];
if ($user_admin_shifts) { if ($user_admin_shifts) {
$freeload_form = [ $freeload_form = [
form_checkbox('freeloaded', _("Freeloaded"), $freeloaded), form_checkbox('freeloaded', _('Freeloaded'), $freeloaded),
form_textarea('freeload_comment', _("Freeload comment (Only for shift coordination):"), $freeload_comment) form_textarea('freeload_comment', _('Freeload comment (Only for shift coordination):'), $freeload_comment)
]; ];
} }
return page_with_title(_("Edit shift entry"), [ return page_with_title(_('Edit shift entry'), [
msg(), msg(),
form([ form([
form_info(_("Angel:"), $angel), form_info(_('Angel:'), $angel),
form_info(_("Date, Duration:"), $date), form_info(_('Date, Duration:'), $date),
form_info(_("Location:"), $location), form_info(_('Location:'), $location),
form_info(_("Title:"), $title), form_info(_('Title:'), $title),
form_info(_("Type:"), $type), form_info(_('Type:'), $type),
form_textarea('comment', _("Comment (for your eyes only):"), $comment), form_textarea('comment', _('Comment (for your eyes only):'), $comment),
join("", $freeload_form), join('', $freeload_form),
form_submit('submit', _("Save")) form_submit('submit', _('Save'))
]) ])
]); ]);
} }
?>

View File

@ -1,6 +1,11 @@
<?php <?php
function ShiftType_name_render($shifttype) { /**
* @param array $shifttype
* @return string
*/
function ShiftType_name_render($shifttype)
{
global $privileges; global $privileges;
if (in_array('shifttypes', $privileges)) { if (in_array('shifttypes', $privileges)) {
return '<a href="' . shifttype_link($shifttype) . '">' . $shifttype['name'] . '</a>'; return '<a href="' . shifttype_link($shifttype) . '">' . $shifttype['name'] . '</a>';
@ -8,17 +13,38 @@ function ShiftType_name_render($shifttype) {
return $shifttype['name']; return $shifttype['name'];
} }
function ShiftType_delete_view($shifttype) { /**
return page_with_title(sprintf(_("Delete shifttype %s"), $shifttype['name']), [ * @param array $shifttype
info(sprintf(_("Do you want to delete shifttype %s?"), $shifttype['name']), true), * @return string
*/
function ShiftType_delete_view($shifttype)
{
return page_with_title(sprintf(_('Delete shifttype %s'), $shifttype['name']), [
info(sprintf(_('Do you want to delete shifttype %s?'), $shifttype['name']), true),
buttons([ buttons([
button(page_link_to('shifttypes'), _("cancel"), 'cancel'), button(page_link_to('shifttypes'), _('cancel'), 'cancel'),
button(page_link_to('shifttypes') . '&action=delete&shifttype_id=' . $shifttype['id'] . '&confirmed', _("delete"), 'ok') button(
page_link_to(
'shifttypes',
['action' => 'delete', 'shifttype_id' => $shifttype['id'], 'confirmed' => 1]
),
_('delete'),
'ok btn-danger'
)
]) ])
]); ]);
} }
function ShiftType_edit_view($name, $angeltype_id, $angeltypes, $description, $shifttype_id) { /**
* @param string $name
* @param int $angeltype_id
* @param array[] $angeltypes
* @param string $description
* @param int|bool $shifttype_id
* @return string
*/
function ShiftType_edit_view($name, $angeltype_id, $angeltypes, $description, $shifttype_id)
{
$angeltypes_select = [ $angeltypes_select = [
'' => _('All') '' => _('All')
]; ];
@ -41,7 +67,13 @@ function ShiftType_edit_view($name, $angeltype_id, $angeltypes, $description, $s
]); ]);
} }
function ShiftType_view($shifttype, $angeltype) { /**
* @param array $shifttype
* @param array $angeltype
* @return string
*/
function ShiftType_view($shifttype, $angeltype)
{
$parsedown = new Parsedown(); $parsedown = new Parsedown();
$title = $shifttype['name']; $title = $shifttype['name'];
if ($angeltype) { if ($angeltype) {
@ -51,28 +83,59 @@ function ShiftType_view($shifttype, $angeltype) {
msg(), msg(),
buttons([ buttons([
button(page_link_to('shifttypes'), shifttypes_title(), 'back'), button(page_link_to('shifttypes'), shifttypes_title(), 'back'),
$angeltype ? button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], $angeltype['name']) : '', $angeltype ? button(
button(page_link_to('shifttypes') . '&action=edit&shifttype_id=' . $shifttype['id'], _('edit'), 'edit'), page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]),
button(page_link_to('shifttypes') . '&action=delete&shifttype_id=' . $shifttype['id'], _('delete'), 'delete') $angeltype['name']
) : '',
button(
page_link_to('shifttypes', ['action' => 'edit', 'shifttype_id' => $shifttype['id']]),
_('edit'),
'edit'
),
button(
page_link_to('shifttypes', ['action' => 'delete', 'shifttype_id' => $shifttype['id']]),
_('delete'),
'delete'
)
]), ]),
heading(_("Description"), 2), heading(_('Description'), 2),
$parsedown->parse($shifttype['description']) $parsedown->parse($shifttype['description'])
]); ]);
} }
function ShiftTypes_list_view($shifttypes) { /**
* @param array[] $shifttypes
* @return string
*/
function ShiftTypes_list_view($shifttypes)
{
foreach ($shifttypes as &$shifttype) { foreach ($shifttypes as &$shifttype) {
$shifttype['name'] = '<a href="' . page_link_to('shifttypes') . '&action=view&shifttype_id=' . $shifttype['id'] . '">' . $shifttype['name'] . '</a>'; $shifttype['name'] = '<a href="'
. page_link_to('shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype['id']])
. '">'
. $shifttype['name']
. '</a>';
$shifttype['actions'] = table_buttons([ $shifttype['actions'] = table_buttons([
button(page_link_to('shifttypes') . '&action=edit&shifttype_id=' . $shifttype['id'], _('edit'), 'btn-xs'), button(
button(page_link_to('shifttypes') . '&action=delete&shifttype_id=' . $shifttype['id'], _('delete'), 'btn-xs') page_link_to(
'shifttypes',
['action' => 'edit', 'shifttype_id' => $shifttype['id']]
),
_('edit'),
'btn-xs'
),
button(
page_link_to('shifttypes', ['action' => 'delete', 'shifttype_id' => $shifttype['id']]),
_('delete'),
'btn-xs'
)
]); ]);
} }
return page_with_title(shifttypes_title(), [ return page_with_title(shifttypes_title(), [
msg(), msg(),
buttons([ buttons([
button(page_link_to('shifttypes') . '&action=edit', _('New shifttype'), 'add') button(page_link_to('shifttypes', ['action' => 'edit']), _('New shifttype'), 'add')
]), ]),
table([ table([
'name' => _('Name'), 'name' => _('Name'),
@ -80,5 +143,3 @@ function ShiftTypes_list_view($shifttypes) {
], $shifttypes) ], $shifttypes)
]); ]);
} }
?>

View File

@ -2,8 +2,8 @@
namespace Engelsystem; namespace Engelsystem;
class ShiftsFilterRenderer { class ShiftsFilterRenderer
{
/** /**
* The shiftFilter to render. * The shiftFilter to render.
* *
@ -26,22 +26,31 @@ class ShiftsFilterRenderer {
*/ */
private $days = []; private $days = [];
public function __construct(ShiftsFilter $shiftsFilter) { /**
* ShiftsFilterRenderer constructor.
*
* @param ShiftsFilter $shiftsFilter
*/
public function __construct(ShiftsFilter $shiftsFilter)
{
$this->shiftsFilter = $shiftsFilter; $this->shiftsFilter = $shiftsFilter;
} }
/** /**
* Renders the filter. * Renders the filter.
* *
* @return Generated HTML * @param string $page_link Link pointing to the actual page.
* @return string Generated HTML
*/ */
public function render($link_base) { public function render($page_link)
{
$toolbar = []; $toolbar = [];
if ($this->daySelectionEnabled && ! empty($this->days)) { if ($this->daySelectionEnabled && !empty($this->days)) {
$selected_day = date("Y-m-d", $this->shiftsFilter->getStartTime()); $selected_day = date('Y-m-d', $this->shiftsFilter->getStartTime());
$day_dropdown_items = []; $day_dropdown_items = [];
foreach ($this->days as $day) { foreach ($this->days as $day) {
$day_dropdown_items[] = toolbar_item_link($link_base . '&shifts_filter_day=' . $day, '', $day); $link = $page_link . '&shifts_filter_day=' . $day;
$day_dropdown_items[] = toolbar_item_link($link, '', $day);
} }
$toolbar[] = toolbar_dropdown('', $selected_day, $day_dropdown_items, 'active'); $toolbar[] = toolbar_dropdown('', $selected_day, $day_dropdown_items, 'active');
} }
@ -52,18 +61,22 @@ class ShiftsFilterRenderer {
/** /**
* Should the filter display a day selection. * Should the filter display a day selection.
*
* @param string[] $days
*/ */
public function enableDaySelection($days) { public function enableDaySelection($days)
{
$this->daySelectionEnabled = true; $this->daySelectionEnabled = true;
$this->days = $days; $this->days = $days;
} }
/** /**
* Should the filter display a day selection. * Should the filter display a day selection.
*
* @return bool
*/ */
public function isDaySelectionEnabled() { public function isDaySelectionEnabled()
{
return $this->daySelectionEnabled; return $this->daySelectionEnabled;
} }
} }
?>

View File

@ -1,18 +1,39 @@
<?php <?php
use Engelsystem\ShiftSignupState; use Engelsystem\ShiftSignupState;
function Shift_editor_info_render($shift) { /**
* @param array $shift
* @return string
*/
function Shift_editor_info_render($shift)
{
$info = []; $info = [];
if ($shift['created_by_user_id'] != null) { if ($shift['created_by_user_id'] != null) {
$info[] = sprintf(glyph('plus') . _("created at %s by %s"), date('Y-m-d H:i', $shift['created_at_timestamp']), User_Nick_render(User($shift['created_by_user_id']))); $info[] = sprintf(
glyph('plus') . _('created at %s by %s'),
date('Y-m-d H:i', $shift['created_at_timestamp']),
User_Nick_render(User($shift['created_by_user_id']))
);
} }
if ($shift['edited_by_user_id'] != null) { if ($shift['edited_by_user_id'] != null) {
$info[] = sprintf(glyph('pencil') . _("edited at %s by %s"), date('Y-m-d H:i', $shift['edited_at_timestamp']), User_Nick_render(User($shift['edited_by_user_id']))); $info[] = sprintf(
glyph('pencil') . _('edited at %s by %s'),
date('Y-m-d H:i', $shift['edited_at_timestamp']),
User_Nick_render(User($shift['edited_by_user_id']))
);
} }
return join('<br />', $info); return join('<br />', $info);
} }
function Shift_signup_button_render($shift, $angeltype, $user_angeltype = null) { /**
* @param array $shift
* @param array $angeltype
* @param array $user_angeltype
* @return string
*/
function Shift_signup_button_render($shift, $angeltype, $user_angeltype = null)
{
global $user; global $user;
if ($user_angeltype == null) { if ($user_angeltype == null) {
@ -20,14 +41,30 @@ function Shift_signup_button_render($shift, $angeltype, $user_angeltype = null)
} }
if ($angeltype['shift_signup_state']->isSignupAllowed()) { if ($angeltype['shift_signup_state']->isSignupAllowed()) {
return button(page_link_to('user_shifts') . '&shift_id=' . $shift['SID'] . '&type_id=' . $angeltype['id'], _('Sign up')); return button(
page_link_to('user_shifts', ['shift_id' => $shift['SID'], 'type_id' => $angeltype['id']]),
_('Sign up')
);
} elseif ($user_angeltype == null) { } elseif ($user_angeltype == null) {
return button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], sprintf(_('Become %s'), $angeltype['name'])); return button(
page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]),
sprintf(_('Become %s'),
$angeltype['name'])
);
} }
return ''; return '';
} }
function Shift_view($shift, $shifttype, $room, $angeltypes_source, ShiftSignupState $shift_signup_state) { /**
* @param array $shift
* @param array $shifttype
* @param array $room
* @param array[] $angeltypes_source
* @param ShiftSignupState $shift_signup_state
* @return string
*/
function Shift_view($shift, $shifttype, $room, $angeltypes_source, ShiftSignupState $shift_signup_state)
{
global $privileges; global $privileges;
$shift_admin = in_array('admin_shifts', $privileges); $shift_admin = in_array('admin_shifts', $privileges);
@ -47,10 +84,16 @@ function Shift_view($shift, $shifttype, $room, $angeltypes_source, ShiftSignupSt
$needed_angels .= Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, $shift, $user_shift_admin); $needed_angels .= Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, $shift, $user_shift_admin);
} }
return page_with_title($shift['name'] . ' <small class="moment-countdown" data-timestamp="' . $shift['start'] . '">%c</small>', [ return page_with_title(
$shift['name'] . ' <small class="moment-countdown" data-timestamp="' . $shift['start'] . '">%c</small>',
[
msg(), msg(),
$shift_signup_state->getState() == ShiftSignupState::COLLIDES ? info(_('This shift collides with one of your shifts.'), true) : '', $shift_signup_state->getState() == ShiftSignupState::COLLIDES
$shift_signup_state->getState() == ShiftSignupState::SIGNED_UP ? info(_('You are signed up for this shift.'), true) : '', ? info(_('This shift collides with one of your shifts.'), true)
: '',
$shift_signup_state->getState() == ShiftSignupState::SIGNED_UP
? info(_('You are signed up for this shift.'), true)
: '',
($shift_admin || $admin_shifttypes || $admin_rooms) ? buttons([ ($shift_admin || $admin_shifttypes || $admin_rooms) ? buttons([
$shift_admin ? button(shift_edit_link($shift), glyph('pencil') . _('edit')) : '', $shift_admin ? button(shift_edit_link($shift), glyph('pencil') . _('edit')) : '',
$shift_admin ? button(shift_delete_link($shift), glyph('trash') . _('delete')) : '', $shift_admin ? button(shift_delete_link($shift), glyph('trash') . _('delete')) : '',
@ -94,10 +137,19 @@ function Shift_view($shift, $shifttype, $room, $angeltypes_source, ShiftSignupSt
]) ])
]), ]),
$shift_admin ? Shift_editor_info_render($shift) : '' $shift_admin ? Shift_editor_info_render($shift) : ''
]); ]
);
} }
function Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, $shift, $user_shift_admin) { /**
* @param array $needed_angeltype
* @param array $angeltypes
* @param array[] $shift
* @param bool $user_shift_admin
* @return string
*/
function Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, $shift, $user_shift_admin)
{
global $user; global $user;
$angeltype = $angeltypes[$needed_angeltype['TID']]; $angeltype = $angeltypes[$needed_angeltype['TID']];
@ -119,7 +171,13 @@ function Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, $shi
$needed_angels .= '<h3>' . AngelType_name_render($angeltype) . '</h3>'; $needed_angels .= '<h3>' . AngelType_name_render($angeltype) . '</h3>';
$bar_max = max($needed_angeltype['count'] * 10, $needed_angeltype['taken'] * 10, 10); $bar_max = max($needed_angeltype['count'] * 10, $needed_angeltype['taken'] * 10, 10);
$bar_value = max(1, $needed_angeltype['taken'] * 10); $bar_value = max(1, $needed_angeltype['taken'] * 10);
$needed_angels .= progress_bar(0, $bar_max, $bar_value, $class, $needed_angeltype['taken'] . ' / ' . $needed_angeltype['count']); $needed_angels .= progress_bar(
0,
$bar_max,
$bar_value,
$class,
$needed_angeltype['taken'] . ' / ' . $needed_angeltype['count']
);
$angels = []; $angels = [];
foreach ($shift['ShiftEntry'] as $shift_entry) { foreach ($shift['ShiftEntry'] as $shift_entry) {
@ -134,17 +192,28 @@ function Shift_view_render_needed_angeltype($needed_angeltype, $angeltypes, $shi
return $needed_angels; return $needed_angels;
} }
function Shift_view_render_shift_entry($shift_entry, $user_shift_admin, $angeltype_supporter) { /**
* @param array $shift_entry
* @param bool $user_shift_admin
* @param bool $angeltype_supporter
* @return string
*/
function Shift_view_render_shift_entry($shift_entry, $user_shift_admin, $angeltype_supporter)
{
$entry = User_Nick_render(User($shift_entry['UID'])); $entry = User_Nick_render(User($shift_entry['UID']));
if ($shift_entry['freeloaded']) { if ($shift_entry['freeloaded']) {
$entry = '<strike>' . $entry . '</strike>'; $entry = '<del>' . $entry . '</del>';
} }
if ($user_shift_admin || $angeltype_supporter) { if ($user_shift_admin || $angeltype_supporter) {
$entry .= ' <div class="btn-group">'; $entry .= ' <div class="btn-group">';
if ($user_shift_admin) { if ($user_shift_admin) {
$entry .= button_glyph(page_link_to('user_myshifts') . '&edit=' . $shift_entry['id'] . '&id=' . $shift_entry['UID'], 'pencil', 'btn-xs'); $entry .= button_glyph(
page_link_to('user_myshifts', ['edit' => $shift_entry['id'], 'id' => $shift_entry['UID']]),
'pencil',
'btn-xs'
);
} }
$entry .= button_glyph(page_link_to('user_shifts') . '&entry_id=' . $shift_entry['id'], 'trash', 'btn-xs'); $entry .= button_glyph(page_link_to('user_shifts', ['entry_id' => $shift_entry['id']]), 'trash', 'btn-xs');
$entry .= '</div>'; $entry .= '</div>';
} }
return $entry; return $entry;
@ -153,11 +222,12 @@ function Shift_view_render_shift_entry($shift_entry, $user_shift_admin, $angelty
/** /**
* Calc shift length in format 12:23h. * Calc shift length in format 12:23h.
* *
* @param Shift $shift * @param array $shift
* @return string
*/ */
function shift_length($shift) { function shift_length($shift)
$length = floor(($shift['end'] - $shift['start']) / (60 * 60)) . ":"; {
$length .= str_pad((($shift['end'] - $shift['start']) % (60 * 60)) / 60, 2, "0", STR_PAD_LEFT) . "h"; $length = floor(($shift['end'] - $shift['start']) / (60 * 60)) . ':';
$length .= str_pad((($shift['end'] - $shift['start']) % (60 * 60)) / 60, 2, '0', STR_PAD_LEFT) . 'h';
return $length; return $length;
} }
?>

View File

@ -1,88 +1,205 @@
<?php <?php
function UserAngelType_update_view($user_angeltype, $user, $angeltype, $supporter) { /**
return page_with_title($supporter ? _("Add supporter rights") : _("Remove supporter rights"), [ * @param array $user_angeltype
* @param array $user
* @param array $angeltype
* @param bool $supporter
* @return string
*/
function UserAngelType_update_view($user_angeltype, $user, $angeltype, $supporter)
{
return page_with_title($supporter ? _('Add supporter rights') : _('Remove supporter rights'), [
msg(), msg(),
info(sprintf($supporter ? _("Do you really want to add supporter rights for %s to %s?") : _("Do you really want to remove supporter rights for %s from %s?"), $angeltype['name'], User_Nick_render($user)), true), info(sprintf(
$supporter
? _('Do you really want to add supporter rights for %s to %s?')
: _('Do you really want to remove supporter rights for %s from %s?'),
$angeltype['name'],
User_Nick_render($user)
), true),
buttons([ buttons([
button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], _("cancel"), 'cancel'), button(
button(page_link_to('user_angeltypes') . '&action=update&user_angeltype_id=' . $user_angeltype['id'] . '&supporter=' . ($supporter ? '1' : '0') . '&confirmed', _("yes"), 'ok') page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]),
_('cancel'),
'cancel'
),
button(
page_link_to('user_angeltypes', [
'action' => 'update',
'user_angeltype_id' => $user_angeltype['id'],
'supporter' => ($supporter ? '1' : '0'),
'confirmed' => 1,
]),
_('yes'),
'ok'
)
]) ])
]); ]);
} }
function UserAngelTypes_delete_all_view($angeltype) { /**
return page_with_title(_("Deny all users"), [ * @param array $angeltype
* @return string
*/
function UserAngelTypes_delete_all_view($angeltype)
{
return page_with_title(_('Deny all users'), [
msg(), msg(),
info(sprintf(_("Do you really want to deny all users for %s?"), $angeltype['name']), true), info(sprintf(_('Do you really want to deny all users for %s?'), $angeltype['name']), true),
buttons([ buttons([
button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], _("cancel"), 'cancel'), button(
button(page_link_to('user_angeltypes') . '&action=delete_all&angeltype_id=' . $angeltype['id'] . '&confirmed', _("yes"), 'ok') 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' => 1]
),
_('yes'),
'ok'
)
]) ])
]); ]);
} }
function UserAngelTypes_confirm_all_view($angeltype) { /**
return page_with_title(_("Confirm all users"), [ * @param array $angeltype
* @return string
*/
function UserAngelTypes_confirm_all_view($angeltype)
{
return page_with_title(_('Confirm all users'), [
msg(), msg(),
info(sprintf(_("Do you really want to confirm all users for %s?"), $angeltype['name']), true), info(sprintf(_('Do you really want to confirm all users for %s?'), $angeltype['name']), true),
buttons([ buttons([
button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], _("cancel"), 'cancel'), button(page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]), _('cancel'),
button(page_link_to('user_angeltypes') . '&action=confirm_all&angeltype_id=' . $angeltype['id'] . '&confirmed', _("yes"), 'ok') 'cancel'),
button(
page_link_to('user_angeltypes',
['action' => 'confirm_all', 'angeltype_id' => $angeltype['id'], 'confirmed' => 1]),
_('yes'),
'ok'
)
]) ])
]); ]);
} }
function UserAngelType_confirm_view($user_angeltype, $user, $angeltype) { /**
return page_with_title(_("Confirm angeltype for user"), [ * @param array $user_angeltype
* @param array $user
* @param array $angeltype
* @return string
*/
function UserAngelType_confirm_view($user_angeltype, $user, $angeltype)
{
return page_with_title(_('Confirm angeltype for user'), [
msg(), msg(),
info(sprintf(_("Do you really want to confirm %s for %s?"), User_Nick_render($user), $angeltype['name']), true), info(sprintf(_('Do you really want to confirm %s for %s?'), User_Nick_render($user), $angeltype['name']), true),
buttons([ buttons([
button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], _("cancel"), 'cancel'), button(
button(page_link_to('user_angeltypes') . '&action=confirm&user_angeltype_id=' . $user_angeltype['id'] . '&confirmed', _("yes"), 'ok') 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' => 1]
),
_('yes'),
'ok'
)
]) ])
]); ]);
} }
function UserAngelType_delete_view($user_angeltype, $user, $angeltype) { /**
return page_with_title(_("Remove angeltype"), [ * @param array $user_angeltype
* @param array $user
* @param array $angeltype
* @return string
*/
function UserAngelType_delete_view($user_angeltype, $user, $angeltype)
{
return page_with_title(_('Remove angeltype'), [
msg(), msg(),
info(sprintf(_("Do you really want to delete %s from %s?"), User_Nick_render($user), $angeltype['name']), true), info(sprintf(_('Do you really want to delete %s from %s?'), User_Nick_render($user), $angeltype['name']), true),
buttons([ buttons([
button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], _("cancel"), 'cancel'), button(
button(page_link_to('user_angeltypes') . '&action=delete&user_angeltype_id=' . $user_angeltype['id'] . '&confirmed', _("yes"), 'ok') 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' => 1]),
_('yes'),
'ok'
)
]) ])
]); ]);
} }
function UserAngelType_add_view($angeltype, $users_source, $user_id) { /**
* @param array $angeltype
* @param array[] $users_source
* @param int $user_id
* @return string
*/
function UserAngelType_add_view($angeltype, $users_source, $user_id)
{
$users = []; $users = [];
foreach ($users_source as $user_source) { foreach ($users_source as $user_source) {
$users[$user_source['UID']] = User_Nick_render($user_source); $users[$user_source['UID']] = User_Nick_render($user_source);
} }
return page_with_title(_("Add user to angeltype"), [ return page_with_title(_('Add user to angeltype'), [
msg(), msg(),
buttons([ buttons([
button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], _("back"), 'back') button(
page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]),
_('back'),
'back'
)
]), ]),
form([ form([
form_info(_("Angeltype"), $angeltype['name']), form_info(_('Angeltype'), $angeltype['name']),
form_select('user_id', _("User"), $users, $user_id), form_select('user_id', _('User'), $users, $user_id),
form_submit('submit', _("Add")) form_submit('submit', _('Add'))
]) ])
]); ]);
} }
function UserAngelType_join_view($user, $angeltype) { /**
return page_with_title(sprintf(_("Become a %s"), $angeltype['name']), [ * @param array $user
* @param array $angeltype
* @return string
*/
function UserAngelType_join_view($user, $angeltype)
{
return page_with_title(sprintf(_('Become a %s'), $angeltype['name']), [
msg(), msg(),
info(sprintf(_("Do you really want to add %s to %s?"), User_Nick_render($user), $angeltype['name']), true), info(sprintf(_('Do you really want to add %s to %s?'), User_Nick_render($user), $angeltype['name']), true),
buttons([ buttons([
button(page_link_to('angeltypes') . '&action=view&angeltype_id=' . $angeltype['id'], _("cancel"), 'cancel'), button(
button(page_link_to('user_angeltypes') . '&action=add&angeltype_id=' . $angeltype['id'] . '&user_id=' . $user['UID'] . '&confirmed', _("save"), 'ok') 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' => 1]
),
_('save'),
'ok'
)
]) ])
]); ]);
} }
?>

View File

@ -3,45 +3,60 @@
/** /**
* Edit a user's driving license information. * Edit a user's driving license information.
* *
* @param User $user_source * @param array $user_source The user
* The user * @param bool $wants_to_drive true, if the user wants to drive
* @param bool $wants_to_drive * @param array $user_driver_license The user driver license
* true, if the user wants to drive
* @param UserDriverLicense $user_driver_license
* The user driver license
* @return string * @return string
*/ */
function UserDriverLicense_edit_view($user_source, $wants_to_drive, $user_driver_license) { function UserDriverLicense_edit_view($user_source, $wants_to_drive, $user_driver_license)
return page_with_title(sprintf(_("Edit %s driving license information"), User_Nick_render($user_source)), [ {
return page_with_title(sprintf(_('Edit %s driving license information'), User_Nick_render($user_source)), [
buttons([ buttons([
button(user_link($user_source), _("Back to profile"), 'back') button(user_link($user_source), _('Back to profile'), 'back')
]), ]),
msg(), msg(),
form([ form([
form_info(_("Privacy"), _("Your driving license information is only visible for supporters and admins.")), form_info(_('Privacy'), _('Your driving license information is only visible for supporters and admins.')),
form_checkbox('wants_to_drive', _("I am willing to drive a car for the event"), $wants_to_drive), form_checkbox('wants_to_drive', _('I am willing to drive a car for the event'), $wants_to_drive),
div('panel panel-default', [ div('panel panel-default', [
div('panel-body', [ div('panel-body', [
form_checkbox('has_car', _("I have my own car with me and am willing to use it for the event (You'll get reimbursed for fuel)"), $user_driver_license['has_car']), form_checkbox(
heading(_("Driver license"), 3), 'has_car',
form_checkbox('has_license_car', _("Car"), $user_driver_license['has_license_car']), _('I have my own car with me and am willing to use it for the event (You\'ll get reimbursed for fuel)'),
form_checkbox('has_license_3_5t_transporter', _("Transporter 3,5t"), $user_driver_license['has_license_3_5t_transporter']), $user_driver_license['has_car']
form_checkbox('has_license_7_5t_truck', _("Truck 7,5t"), $user_driver_license['has_license_7_5t_truck']), ),
form_checkbox('has_license_12_5t_truck', _("Truck 12,5t"), $user_driver_license['has_license_12_5t_truck']), heading(_('Driver license'), 3),
form_checkbox('has_license_forklift', _("Forklift"), $user_driver_license['has_license_forklift']) form_checkbox('has_license_car', _('Car'), $user_driver_license['has_license_car']),
form_checkbox(
'has_license_3_5t_transporter',
_('Transporter 3,5t'),
$user_driver_license['has_license_3_5t_transporter']
),
form_checkbox(
'has_license_7_5t_truck',
_('Truck 7,5t'),
$user_driver_license['has_license_7_5t_truck']
),
form_checkbox(
'has_license_12_5t_truck',
_('Truck 12,5t'),
$user_driver_license['has_license_12_5t_truck']
),
form_checkbox('has_license_forklift', _('Forklift'), $user_driver_license['has_license_forklift'])
]) ])
], 'driving_license'), ], 'driving_license'),
form_submit('submit', _("Save")) form_submit('submit', _('Save'))
]), ]),
'<script type="text/javascript"> '<script type="text/javascript">
$(function() { $(function() {
if($("#wants_to_drive").is(":checked")) var checkbox = $("#wants_to_drive");
if(checkbox.is(":checked"))
$("#driving_license").show(); $("#driving_license").show();
else else
$("#driving_license").hide(); $("#driving_license").hide();
$("#wants_to_drive").click( checkbox.click(
function(e) { function() {
if($("#wants_to_drive").is(":checked")) if($("#wants_to_drive").is(":checked"))
$("#driving_license").show(); $("#driving_license").show();
else else
@ -52,5 +67,3 @@ function UserDriverLicense_edit_view($user_source, $wants_to_drive, $user_driver
</script>' </script>'
]); ]);
} }
?>

View File

@ -2,16 +2,20 @@
namespace Engelsystem; namespace Engelsystem;
class UserHintsRenderer { class UserHintsRenderer
{
/** @var string[] */
private $hints = []; private $hints = [];
private $important = false; private $important = false;
/** /**
* Render the added hints to a popover for the toolbar. * Render the added hints to a popover for the toolbar.
*
* @return string
*/ */
public function render() { public function render()
{
if (count($this->hints) > 0) { if (count($this->hints) > 0) {
$hint_class = $this->important ? 'danger' : 'info'; $hint_class = $this->important ? 'danger' : 'info';
$glyphicon = $this->important ? 'warning-sign' : 'info-sign'; $glyphicon = $this->important ? 'warning-sign' : 'info-sign';
@ -25,12 +29,11 @@ class UserHintsRenderer {
/** /**
* Add a hint to the list, if its not null and a not empty string. * Add a hint to the list, if its not null and a not empty string.
* *
* @param string $hint * @param string $hint The hint
* The hint * @param boolean $important Is the hint important?
* @param boolean $important
* Is the hint important?
*/ */
public function addHint($hint, $important = false) { public function addHint($hint, $important = false)
{
if ($hint != null && $hint != '') { if ($hint != null && $hint != '') {
if ($important) { if ($important) {
$this->important = true; $this->important = true;
@ -43,17 +46,21 @@ class UserHintsRenderer {
/** /**
* Get all hints. * Get all hints.
*
* @return string[]
*/ */
public function getHints() { public function getHints()
{
return $this->hints; return $this->hints;
} }
/** /**
* Are there important hints? This leads to a more intensive icon. * Are there important hints? This leads to a more intensive icon.
*
* @return bool
*/ */
public function isImportant() { public function isImportant()
{
return $this->important; return $this->important;
} }
} }
?>

View File

@ -1,78 +1,94 @@
<?php <?php
/**
* Available T-Shirt sizes
*/
$tshirt_sizes = [
'' => _("Please select..."),
'S' => "S",
'M' => "M",
'L' => "L",
'XL' => "XL",
'2XL' => "2XL",
'3XL' => "3XL",
'4XL' => "4XL",
'5XL' => "5XL",
'S-G' => "S Girl",
'M-G' => "M Girl",
'L-G' => "L Girl",
'XL-G' => "XL Girl"
];
/** /**
* Renders user settings page * Renders user settings page
* *
* @param User $user_source * @param array $user_source The user
* The user * @param array $locales Available languages
* @param array<String> $locales * @param array $themes Available themes
* Available languages * @param int $buildup_start_date Unix timestamp
* @param array<String> $themes * @param int $teardown_end_date Unix timestamp
* Available themes * @param bool $enable_tshirt_size
* @param array $tshirt_sizes
* @return string
*/ */
function User_settings_view($user_source, $locales, $themes, $buildup_start_date, $teardown_end_date, $enable_tshirt_size, $tshirt_sizes) { function User_settings_view(
$user_source,
$locales,
$themes,
$buildup_start_date,
$teardown_end_date,
$enable_tshirt_size,
$tshirt_sizes
) {
return page_with_title(settings_title(), [ return page_with_title(settings_title(), [
msg(), msg(),
div('row', [ div('row', [
div('col-md-6', [ div('col-md-6', [
form([ form([
form_info('', _("Here you can change your user details.")), form_info('', _('Here you can change your user details.')),
form_info(entry_required() . ' = ' . _("Entry required!")), form_info(entry_required() . ' = ' . _('Entry required!')),
form_text('nick', _("Nick"), $user_source['Nick'], true), form_text('nick', _('Nick'), $user_source['Nick'], true),
form_text('lastname', _("Last name"), $user_source['Name']), form_text('lastname', _('Last name'), $user_source['Name']),
form_text('prename', _("First name"), $user_source['Vorname']), form_text('prename', _('First name'), $user_source['Vorname']),
form_date('planned_arrival_date', _("Planned date of arrival") . ' ' . entry_required(), $user_source['planned_arrival_date'], $buildup_start_date, $teardown_end_date), form_date(
form_date('planned_departure_date', _("Planned date of departure"), $user_source['planned_departure_date'], $buildup_start_date, $teardown_end_date), 'planned_arrival_date',
form_text('age', _("Age"), $user_source['Alter']), _('Planned date of arrival') . ' ' . entry_required(),
form_text('tel', _("Phone"), $user_source['Telefon']), $user_source['planned_arrival_date'],
form_text('dect', _("DECT"), $user_source['DECT']), $buildup_start_date,
form_text('mobile', _("Mobile"), $user_source['Handy']), $teardown_end_date
form_text('mail', _("E-Mail") . ' ' . entry_required(), $user_source['email']), ),
form_checkbox('email_shiftinfo', _("The engelsystem is allowed to send me an email (e.g. when my shifts change)"), $user_source['email_shiftinfo']), form_date(
form_checkbox('email_by_human_allowed', _("Humans are allowed to send me an email (e.g. for ticket vouchers)"), $user_source['email_by_human_allowed']), 'planned_departure_date',
form_text('jabber', _("Jabber"), $user_source['jabber']), _('Planned date of departure'),
form_text('hometown', _("Hometown"), $user_source['Hometown']), $user_source['planned_departure_date'],
$enable_tshirt_size ? form_select('tshirt_size', _("Shirt size"), $tshirt_sizes, $user_source['Size']) : '', $buildup_start_date,
$teardown_end_date
),
form_text('age', _('Age'), $user_source['Alter']),
form_text('tel', _('Phone'), $user_source['Telefon']),
form_text('dect', _('DECT'), $user_source['DECT']),
form_text('mobile', _('Mobile'), $user_source['Handy']),
form_text('mail', _('E-Mail') . ' ' . entry_required(), $user_source['email']),
form_checkbox(
'email_shiftinfo',
_('The engelsystem is allowed to send me an email (e.g. when my shifts change)'),
$user_source['email_shiftinfo']
),
form_checkbox(
'email_by_human_allowed',
_('Humans are allowed to send me an email (e.g. for ticket vouchers)'),
$user_source['email_by_human_allowed']
),
form_text('jabber', _('Jabber'), $user_source['jabber']),
form_text('hometown', _('Hometown'), $user_source['Hometown']),
$enable_tshirt_size ? form_select(
'tshirt_size',
_('Shirt size'),
$tshirt_sizes,
$user_source['Size']
) : '',
form_info('', _('Please visit the angeltypes page to manage your angeltypes.')), form_info('', _('Please visit the angeltypes page to manage your angeltypes.')),
form_submit('submit', _("Save")) form_submit('submit', _('Save'))
]) ])
]), ]),
div('col-md-6', [ div('col-md-6', [
form([ form([
form_info(_("Here you can change your password.")), form_info(_('Here you can change your password.')),
form_password('password', _("Old password:")), form_password('password', _('Old password:')),
form_password('new_password', _("New password:")), form_password('new_password', _('New password:')),
form_password('new_password2', _("Password confirmation:")), form_password('new_password2', _('Password confirmation:')),
form_submit('submit_password', _("Save")) form_submit('submit_password', _('Save'))
]), ]),
form([ form([
form_info(_("Here you can choose your color settings:")), form_info(_('Here you can choose your color settings:')),
form_select('theme', _("Color settings:"), $themes, $user_source['color']), form_select('theme', _('Color settings:'), $themes, $user_source['color']),
form_submit('submit_theme', _("Save")) form_submit('submit_theme', _('Save'))
]), ]),
form([ form([
form_info(_("Here you can choose your language:")), form_info(_('Here you can choose your language:')),
form_select('language', _("Language:"), $locales, $user_source['Sprache']), form_select('language', _('Language:'), $locales, $user_source['Sprache']),
form_submit('submit_language', _("Save")) form_submit('submit_language', _('Save'))
]) ])
]) ])
]) ])
@ -81,33 +97,37 @@ function User_settings_view($user_source, $locales, $themes, $buildup_start_date
/** /**
* Displays the welcome message to the user and shows a login form. * Displays the welcome message to the user and shows a login form.
*
* @param string $event_welcome_message
* @return string
*/ */
function User_registration_success_view($event_welcome_message) { function User_registration_success_view($event_welcome_message)
{
$parsedown = new Parsedown(); $parsedown = new Parsedown();
$event_welcome_message = $parsedown->text($event_welcome_message); $event_welcome_message = $parsedown->text($event_welcome_message);
return page_with_title(_("Registration successful"), [ return page_with_title(_('Registration successful'), [
msg(), msg(),
div('row', [ div('row', [
div('col-md-4', [ div('col-md-4', [
$event_welcome_message $event_welcome_message
]), ]),
div('col-md-4', [ div('col-md-4', [
'<h2>' . _("Login") . '</h2>', '<h2>' . _('Login') . '</h2>',
form([ form([
form_text('nick', _("Nick"), ""), form_text('nick', _('Nick'), ''),
form_password('password', _("Password")), form_password('password', _('Password')),
form_submit('submit', _("Login")), form_submit('submit', _('Login')),
buttons([ buttons([
button(page_link_to('user_password_recovery'), _("I forgot my password")) button(page_link_to('user_password_recovery'), _('I forgot my password'))
]), ]),
info(_("Please note: You have to activate cookies!"), true) info(_('Please note: You have to activate cookies!'), true)
], page_link_to('login')) ], page_link_to('login'))
]), ]),
div('col-md-4', [ div('col-md-4', [
'<h2>' . _("What can I do?") . '</h2>', '<h2>' . _('What can I do?') . '</h2>',
'<p>' . _("Please read about the jobs you can do to help us.") . '</p>', '<p>' . _('Please read about the jobs you can do to help us.') . '</p>',
buttons([ buttons([
button(page_link_to('angeltypes') . '&action=about', _("Teams/Job description") . ' &raquo;') button(page_link_to('angeltypes', ['action' => 'about']), _('Teams/Job description') . ' &raquo;')
]) ])
]) ])
]) ])
@ -116,49 +136,82 @@ function User_registration_success_view($event_welcome_message) {
/** /**
* Gui for deleting user with password field. * Gui for deleting user with password field.
*
* @param array $user
* @return string
*/ */
function User_delete_view($user) { function User_delete_view($user)
return page_with_title(sprintf(_("Delete %s"), User_Nick_render($user)), [ {
return page_with_title(sprintf(_('Delete %s'), User_Nick_render($user)), [
msg(), msg(),
buttons([ buttons([
button(user_edit_link($user), glyph('chevron-left') . _("back")) button(user_edit_link($user), glyph('chevron-left') . _('back'))
]), ]),
error(_("Do you really want to delete the user including all his shifts and every other piece of his data?"), true), error(
_('Do you really want to delete the user including all his shifts and every other piece of his data?'),
true
),
form([ form([
form_password('password', _("Your password")), form_password('password', _('Your password')),
form_submit('submit', _("Delete")) form_submit('submit', _('Delete'))
]) ])
]); ]);
} }
/** /**
* View for editing the number of given vouchers * View for editing the number of given vouchers
*
* @param array $user
* @return string
*/ */
function User_edit_vouchers_view($user) { function User_edit_vouchers_view($user)
return page_with_title(sprintf(_("%s's vouchers"), User_Nick_render($user)), [ {
return page_with_title(sprintf(_('%s\'s vouchers'), User_Nick_render($user)), [
msg(), msg(),
buttons([ buttons([
button(user_link($user), glyph('chevron-left') . _("back")) button(user_link($user), glyph('chevron-left') . _('back'))
]), ]),
info(sprintf(_("Angel should receive at least %d vouchers."), User_get_eligable_voucher_count($user)), true), info(sprintf(_('Angel should receive at least %d vouchers.'), User_get_eligable_voucher_count($user)), true),
form([ form(
form_spinner('vouchers', _("Number of vouchers given out"), $user['got_voucher']), [
form_submit('submit', _("Save")) form_spinner('vouchers', _('Number of vouchers given out'), $user['got_voucher']),
], page_link_to('users') . '&action=edit_vouchers&user_id=' . $user['UID']) form_submit('submit', _('Save'))
],
page_link_to('users', ['action' => 'edit_vouchers', 'user_id' => $user['UID']])
)
]); ]);
} }
function Users_view($users, $order_by, $arrived_count, $active_count, $force_active_count, $freeloads_count, $tshirts_count, $voucher_count) { /**
* @param array[] $users
* @param string $order_by
* @param int $arrived_count
* @param int $active_count
* @param int $force_active_count
* @param int $freeloads_count
* @param int $tshirts_count
* @param int $voucher_count
* @return string
*/
function Users_view(
$users,
$order_by,
$arrived_count,
$active_count,
$force_active_count,
$freeloads_count,
$tshirts_count,
$voucher_count
) {
foreach ($users as &$user) { foreach ($users as &$user) {
$user['Nick'] = User_Nick_render($user); $user['Nick'] = User_Nick_render($user);
$user['Gekommen'] = glyph_bool($user['Gekommen']); $user['Gekommen'] = glyph_bool($user['Gekommen']);
$user['got_voucher'] = $user['got_voucher'];
$user['Aktiv'] = glyph_bool($user['Aktiv']); $user['Aktiv'] = glyph_bool($user['Aktiv']);
$user['force_active'] = glyph_bool($user['force_active']); $user['force_active'] = glyph_bool($user['force_active']);
$user['Tshirt'] = glyph_bool($user['Tshirt']); $user['Tshirt'] = glyph_bool($user['Tshirt']);
$user['lastLogIn'] = date(_('m/d/Y h:i a'), $user['lastLogIn']); $user['lastLogIn'] = date(_('m/d/Y h:i a'), $user['lastLogIn']);
$user['actions'] = table_buttons([ $user['actions'] = table_buttons([
button_glyph(page_link_to('admin_user') . '&id=' . $user['UID'], 'edit', 'btn-xs') button_glyph(page_link_to('admin_user', ['id' => $user['UID']]), 'edit', 'btn-xs')
]); ]);
} }
$users[] = [ $users[] = [
@ -172,79 +225,105 @@ function Users_view($users, $order_by, $arrived_count, $active_count, $force_act
'actions' => '<strong>' . count($users) . '</strong>' 'actions' => '<strong>' . count($users) . '</strong>'
]; ];
return page_with_title(_("All users"), [ return page_with_title(_('All users'), [
msg(), msg(),
buttons([ buttons([
button(page_link_to('register'), glyph('plus') . _("New user")) button(page_link_to('register'), glyph('plus') . _('New user'))
]), ]),
table([ table([
'Nick' => Users_table_header_link('Nick', _("Nick"), $order_by), 'Nick' => Users_table_header_link('Nick', _('Nick'), $order_by),
'Vorname' => Users_table_header_link('Vorname', _("Prename"), $order_by), 'Vorname' => Users_table_header_link('Vorname', _('Prename'), $order_by),
'Name' => Users_table_header_link('Name', _("Name"), $order_by), 'Name' => Users_table_header_link('Name', _('Name'), $order_by),
'DECT' => Users_table_header_link('DECT', _("DECT"), $order_by), 'DECT' => Users_table_header_link('DECT', _('DECT'), $order_by),
'Gekommen' => Users_table_header_link('Gekommen', _("Arrived"), $order_by), 'Gekommen' => Users_table_header_link('Gekommen', _('Arrived'), $order_by),
'got_voucher' => Users_table_header_link('got_voucher', _("Voucher"), $order_by), 'got_voucher' => Users_table_header_link('got_voucher', _('Voucher'), $order_by),
'freeloads' => _('Freeloads'), 'freeloads' => _('Freeloads'),
'Aktiv' => Users_table_header_link('Aktiv', _("Active"), $order_by), 'Aktiv' => Users_table_header_link('Aktiv', _('Active'), $order_by),
'force_active' => Users_table_header_link('force_active', _("Forced"), $order_by), 'force_active' => Users_table_header_link('force_active', _('Forced'), $order_by),
'Tshirt' => Users_table_header_link('Tshirt', _("T-Shirt"), $order_by), 'Tshirt' => Users_table_header_link('Tshirt', _('T-Shirt'), $order_by),
'Size' => Users_table_header_link('Size', _("Size"), $order_by), 'Size' => Users_table_header_link('Size', _('Size'), $order_by),
'lastLogIn' => Users_table_header_link('lastLogIn', _("Last login"), $order_by), 'lastLogIn' => Users_table_header_link('lastLogIn', _('Last login'), $order_by),
'actions' => '' 'actions' => ''
], $users) ], $users)
]); ]);
} }
function Users_table_header_link($column, $label, $order_by) { /**
return '<a href="' . page_link_to('users') . '&OrderBy=' . $column . '">' . $label . ($order_by == $column ? ' <span class="caret"></span>' : '') . '</a>'; * @param string $column
* @param string $label
* @param string $order_by
* @return string
*/
function Users_table_header_link($column, $label, $order_by)
{
return '<a href="'
. page_link_to('users', ['OrderBy' => $column])
. '">'
. $label . ($order_by == $column ? ' <span class="caret"></span>' : '')
. '</a>';
} }
function User_shift_state_render($user) { /**
* @param array $user
* @return string|false
*/
function User_shift_state_render($user)
{
$upcoming_shifts = ShiftEntries_upcoming_for_user($user); $upcoming_shifts = ShiftEntries_upcoming_for_user($user);
if ($upcoming_shifts === false) {
return false; if (empty($upcoming_shifts)) {
return '<span class="text-success">' . _('Free') . '</span>';
} }
if (count($upcoming_shifts) == 0) { $nextShift = array_shift($upcoming_shifts);
return '<span class="text-success">' . _("Free") . '</span>';
}
if ($upcoming_shifts[0]['start'] > time()) { if ($nextShift['start'] > time()) {
if ($upcoming_shifts[0]['start'] - time() > 3600) { if ($nextShift['start'] - time() > 3600) {
return '<span class="text-success moment-countdown" data-timestamp="' . $upcoming_shifts[0]['start'] . '">' . _("Next shift %c") . '</span>'; return '<span class="text-success moment-countdown" data-timestamp="' . $nextShift['start'] . '">' . _('Next shift %c') . '</span>';
} }
return '<span class="text-warning moment-countdown" data-timestamp="' . $upcoming_shifts[0]['start'] . '">' . _("Next shift %c") . '</span>'; return '<span class="text-warning moment-countdown" data-timestamp="' . $nextShift['start'] . '">' . _('Next shift %c') . '</span>';
} }
$halfway = ($upcoming_shifts[0]['start'] + $upcoming_shifts[0]['end']) / 2; $halfway = ($nextShift['start'] + $nextShift['end']) / 2;
if (time() < $halfway) { if (time() < $halfway) {
return '<span class="text-danger moment-countdown" data-timestamp="' . $upcoming_shifts[0]['start'] . '">' . _("Shift starts %c") . '</span>'; return '<span class="text-danger moment-countdown" data-timestamp="' . $nextShift['start'] . '">' . _('Shift starts %c') . '</span>';
} }
return '<span class="text-danger moment-countdown" data-timestamp="' . $upcoming_shifts[0]['end'] . '">' . _("Shift ends %c") . '</span>'; return '<span class="text-danger moment-countdown" data-timestamp="' . $nextShift['end'] . '">' . _('Shift ends %c') . '</span>';
} }
function User_view_shiftentries($needed_angel_type) { /**
* @param array $needed_angel_type
* @return string
*/
function User_view_shiftentries($needed_angel_type)
{
$shift_info = '<br><b>' . $needed_angel_type['name'] . ':</b> '; $shift_info = '<br><b>' . $needed_angel_type['name'] . ':</b> ';
$shift_entries = []; $shift_entries = [];
foreach ($needed_angel_type['users'] as $user_shift) { foreach ($needed_angel_type['users'] as $user_shift) {
$member = User_Nick_render($user_shift); $member = User_Nick_render($user_shift);
if ($user_shift['freeloaded']) { if ($user_shift['freeloaded']) {
$member = '<strike>' . $member . '</strike>'; $member = '<del>' . $member . '</del>';
} }
$shift_entries[] = $member; $shift_entries[] = $member;
} }
$shift_info .= join(", ", $shift_entries); $shift_info .= join(', ', $shift_entries);
return $shift_info; return $shift_info;
} }
/** /**
* Helper that renders a shift line for user view * Helper that renders a shift line for user view
*
* @param array $shift
* @param array $user_source
* @param bool $its_me
* @return array
*/ */
function User_view_myshift($shift, $user_source, $its_me) { function User_view_myshift($shift, $user_source, $its_me)
global $LETZTES_AUSTRAGEN, $privileges; {
global $privileges;
$shift_info = '<a href="' . shift_link($shift) . '">' . $shift['name'] . '</a>'; $shift_info = '<a href="' . shift_link($shift) . '">' . $shift['name'] . '</a>';
if ($shift['title']) { if ($shift['title']) {
@ -255,18 +334,18 @@ function User_view_myshift($shift, $user_source, $its_me) {
} }
$myshift = [ $myshift = [
'date' => date("Y-m-d", $shift['start']), 'date' => date('Y-m-d', $shift['start']),
'time' => date("H:i", $shift['start']) . ' - ' . date("H:i", $shift['end']), 'time' => date('H:i', $shift['start']) . ' - ' . date('H:i', $shift['end']),
'room' => $shift['Name'], 'room' => $shift['Name'],
'shift_info' => $shift_info, 'shift_info' => $shift_info,
'comment' => $shift['Comment'] 'comment' => $shift['Comment']
]; ];
if ($shift['freeloaded']) { if ($shift['freeloaded']) {
if (in_array("user_shifts_admin", $privileges)) { if (in_array('user_shifts_admin', $privileges)) {
$myshift['comment'] .= '<br /><p class="error">' . _("Freeloaded") . ': ' . $shift['freeload_comment'] . '</p>'; $myshift['comment'] .= '<br /><p class="error">' . _('Freeloaded') . ': ' . $shift['freeload_comment'] . '</p>';
} else { } else {
$myshift['comment'] .= '<br /><p class="error">' . _("Freeloaded") . '</p>'; $myshift['comment'] .= '<br /><p class="error">' . _('Freeloaded') . '</p>';
} }
} }
@ -274,10 +353,28 @@ function User_view_myshift($shift, $user_source, $its_me) {
button(shift_link($shift), glyph('eye-open') . _('view'), 'btn-xs') button(shift_link($shift), glyph('eye-open') . _('view'), 'btn-xs')
]; ];
if ($its_me || in_array('user_shifts_admin', $privileges)) { if ($its_me || in_array('user_shifts_admin', $privileges)) {
$myshift['actions'][] = button(page_link_to('user_myshifts') . '&edit=' . $shift['id'] . '&id=' . $user_source['UID'], glyph('edit') . _('edit'), 'btn-xs'); $myshift['actions'][] = button(
page_link_to('user_myshifts', ['edit' => $shift['id'], 'id' => $user_source['UID']]),
glyph('edit') . _('edit'),
'btn-xs'
);
} }
if (($shift['start'] > time() + $LETZTES_AUSTRAGEN * 3600) || in_array('user_shifts_admin', $privileges)) { if (
$myshift['actions'][] = button(page_link_to('user_myshifts') . ((! $its_me) ? '&id=' . $user_source['UID'] : '') . '&cancel=' . $shift['id'], glyph('trash') . _('sign off'), 'btn-xs'); ($shift['start'] > time() + config('last_unsubscribe') * 3600)
|| in_array('user_shifts_admin', $privileges)
) {
$parameters = [
'cancel' => $shift['id'],
'id' => $user_source['UID'],
];
if ($its_me) {
$parameters['id'] = '';
}
$myshift['actions'][] = button(
page_link_to('user_myshifts', $parameters),
glyph('trash') . _('sign off'),
'btn-xs'
);
} }
$myshift['actions'] = table_buttons($myshift['actions']); $myshift['actions'] = table_buttons($myshift['actions']);
@ -286,15 +383,21 @@ function User_view_myshift($shift, $user_source, $its_me) {
/** /**
* Helper that prepares the shift table for user view * Helper that prepares the shift table for user view
*
* @param array[] $shifts
* @param array $user_source
* @param bool $its_me
* @return array
*/ */
function User_view_myshifts($shifts, $user_source, $its_me) { function User_view_myshifts($shifts, $user_source, $its_me)
{
$myshifts_table = []; $myshifts_table = [];
$timesum = 0; $timesum = 0;
foreach ($shifts as $shift) { foreach ($shifts as $shift) {
$myshifts_table[] = User_view_myshift($shift, $user_source, $its_me); $myshifts_table[] = User_view_myshift($shift, $user_source, $its_me);
if ($shift['freeloaded']) { if ($shift['freeloaded']) {
$timesum += (- 2 * ($shift['end'] - $shift['start'])); $timesum += (-2 * ($shift['end'] - $shift['start']));
} else { } else {
$timesum += ($shift['end'] - $shift['start']); $timesum += ($shift['end'] - $shift['start']);
} }
@ -302,12 +405,12 @@ function User_view_myshifts($shifts, $user_source, $its_me) {
if (count($myshifts_table) > 0) { if (count($myshifts_table) > 0) {
$myshifts_table[] = [ $myshifts_table[] = [
'date' => '<b>' . _("Sum:") . '</b>', 'date' => '<b>' . _('Sum:') . '</b>',
'time' => "<b>" . round($timesum / 3600, 1) . " h</b>", 'time' => '<b>' . round($timesum / 3600, 1) . ' h</b>',
'room' => "", 'room' => '',
'shift_info' => "", 'shift_info' => '',
'comment' => "", 'comment' => '',
'actions' => "" 'actions' => ''
]; ];
} }
return $myshifts_table; return $myshifts_table;
@ -315,24 +418,57 @@ function User_view_myshifts($shifts, $user_source, $its_me) {
/** /**
* Renders view for a single user * Renders view for a single user
*
* @param array $user_source
* @param bool $admin_user_privilege
* @param bool $freeloader
* @param array[] $user_angeltypes
* @param array[] $user_groups
* @param array[] $shifts
* @param bool $its_me
* @return string
*/ */
function User_view($user_source, $admin_user_privilege, $freeloader, $user_angeltypes, $user_groups, $shifts, $its_me) { function User_view($user_source, $admin_user_privilege, $freeloader, $user_angeltypes, $user_groups, $shifts, $its_me)
$user_name = htmlspecialchars($user_source['Vorname']) . " " . htmlspecialchars($user_source['Name']); {
$user_name = htmlspecialchars($user_source['Vorname']) . ' ' . htmlspecialchars($user_source['Name']);
$myshifts_table = User_view_myshifts($shifts, $user_source, $its_me); $myshifts_table = User_view_myshifts($shifts, $user_source, $its_me);
return page_with_title('<span class="icon-icon_angel"></span> ' . htmlspecialchars($user_source['Nick']) . ' <small>' . $user_name . '</small>', [ return page_with_title(
'<span class="icon-icon_angel"></span> ' . htmlspecialchars($user_source['Nick']) . ' <small>' . $user_name . '</small>',
[
msg(), msg(),
div('row space-top', [ div('row space-top', [
div('col-md-12', [ div('col-md-12', [
buttons([ buttons([
$admin_user_privilege ? button(page_link_to('admin_user') . '&id=' . $user_source['UID'], glyph("edit") . _("edit")) : '', $admin_user_privilege ? button(
$admin_user_privilege ? button(user_driver_license_edit_link($user_source), glyph("road") . _("driving license")) : '', page_link_to('admin_user', ['id' => $user_source['UID']]),
($admin_user_privilege && ! $user_source['Gekommen']) ? button(page_link_to('admin_arrive') . '&arrived=' . $user_source['UID'], _("arrived")) : '', glyph('edit') . _('edit')
$admin_user_privilege ? button(page_link_to('users') . '&action=edit_vouchers&user_id=' . $user_source['UID'], glyph('cutlery') . _('Edit vouchers')) : '', ) : '',
$its_me ? button(page_link_to('user_settings'), glyph('list-alt') . _("Settings")) : '', $admin_user_privilege ? button(
$its_me ? button(page_link_to('ical') . '&key=' . $user_source['api_key'], glyph('calendar') . _("iCal Export")) : '', user_driver_license_edit_link($user_source),
$its_me ? button(page_link_to('shifts_json_export') . '&key=' . $user_source['api_key'], glyph('export') . _("JSON Export")) : '', glyph('road') . _('driving license')
$its_me ? button(page_link_to('user_myshifts') . '&reset', glyph('repeat') . _('Reset API key')) : '' ) : '',
($admin_user_privilege && !$user_source['Gekommen']) ? button(
page_link_to('admin_arrive', ['arrived' => $user_source['UID']]),
_('arrived')
) : '',
$admin_user_privilege ? button(
page_link_to('users', ['action' => 'edit_vouchers', 'user_id' => $user_source['UID']]),
glyph('cutlery') . _('Edit vouchers')
) : '',
$its_me ? button(page_link_to('user_settings'), glyph('list-alt') . _('Settings')) : '',
$its_me ? button(
page_link_to('ical', ['key' => $user_source['api_key']]),
glyph('calendar') . _('iCal Export')
) : '',
$its_me ? button(
page_link_to('shifts_json_export', ['key' => $user_source['api_key']]),
glyph('export') . _('JSON Export')
) : '',
$its_me ? button(
page_link_to('user_myshifts', ['reset' => 1]),
glyph('repeat') . _('Reset API key')
) : ''
]) ])
]) ])
]), ]),
@ -344,85 +480,131 @@ function User_view($user_source, $admin_user_privilege, $freeloader, $user_angel
'</h1>' '</h1>'
]), ]),
div('col-md-3', [ div('col-md-3', [
'<h4>' . _("User state") . '</h4>', '<h4>' . _('User state') . '</h4>',
($admin_user_privilege && $freeloader) ? '<span class="text-danger"><span class="glyphicon glyphicon-exclamation-sign"></span> ' . _("Freeloader") . '</span><br />' : '', ($admin_user_privilege && $freeloader)
$user_source['Gekommen'] ? User_shift_state_render($user_source) . '<br />' : '', ? '<span class="text-danger"><span class="glyphicon glyphicon-exclamation-sign"></span> ' . _('Freeloader') . '</span><br />'
$admin_user_privilege || $its_me ? ($user_source['Gekommen'] ? '<span class="text-success"><span class="glyphicon glyphicon-home"></span> ' . sprintf(_("Arrived at %s"), date('Y-m-d', $user_source['arrival_date'])) . '</span>' : '<span class="text-danger">' . sprintf(_("Not arrived (Planned: %s)"), date('Y-m-d', $user_source['planned_arrival_date'])) . '</span>') : ($user_source['Gekommen'] ? '<span class="text-success"><span class="glyphicon glyphicon-home"></span> ' . _("Arrived") . '</span>' : '<span class="text-danger">' . _("Not arrived") . '</span>'), : '',
$admin_user_privilege ? ($user_source['got_voucher'] > 0 ? '<br /><span class="text-success">' . glyph('cutlery') . sprintf(ngettext("Got %s voucher", "Got %s vouchers", $user_source['got_voucher']), $user_source['got_voucher']) . '</span><br />' : '<br /><span class="text-danger">' . _("Got no vouchers") . '</span><br />') : '', $user_source['Gekommen']
($user_source['Gekommen'] && $admin_user_privilege && $user_source['Aktiv']) ? ' <span class="text-success">' . _("Active") . '</span>' : '', ? User_shift_state_render($user_source) . '<br />'
($user_source['Gekommen'] && $admin_user_privilege && $user_source['Tshirt']) ? ' <span class="text-success">' . _("T-Shirt") . '</span>' : '' : '',
$admin_user_privilege || $its_me
? (
$user_source['Gekommen']
? '<span class="text-success"><span class="glyphicon glyphicon-home"></span> '
. sprintf(_('Arrived at %s'), date('Y-m-d', $user_source['arrival_date']))
. '</span>'
: '<span class="text-danger">'
. sprintf(_('Not arrived (Planned: %s)'), date('Y-m-d', $user_source['planned_arrival_date']))
. '</span>'
)
: (
$user_source['Gekommen']
? '<span class="text-success"><span class="glyphicon glyphicon-home"></span> ' . _('Arrived') . '</span>'
: '<span class="text-danger">' . _('Not arrived') . '</span>'),
$admin_user_privilege
? (
$user_source['got_voucher'] > 0
? '<br /><span class="text-success">'
. glyph('cutlery')
. sprintf(
ngettext('Got %s voucher', 'Got %s vouchers', $user_source['got_voucher']),
$user_source['got_voucher']
)
. '</span><br />'
: '<br /><span class="text-danger">' . _('Got no vouchers') . '</span><br />')
: '',
($user_source['Gekommen'] && $admin_user_privilege && $user_source['Aktiv']) ? ' <span class="text-success">' . _('Active') . '</span>' : '',
($user_source['Gekommen'] && $admin_user_privilege && $user_source['Tshirt']) ? ' <span class="text-success">' . _('T-Shirt') . '</span>' : ''
]), ]),
div('col-md-3', [ div('col-md-3', [
'<h4>' . _("Angeltypes") . '</h4>', '<h4>' . _('Angeltypes') . '</h4>',
User_angeltypes_render($user_angeltypes) User_angeltypes_render($user_angeltypes)
]), ]),
div('col-md-3', [ div('col-md-3', [
'<h4>' . _("Rights") . '</h4>', '<h4>' . _('Rights') . '</h4>',
User_groups_render($user_groups) User_groups_render($user_groups)
]) ])
]), ]),
($its_me || $admin_user_privilege) ? '<h2>' . _("Shifts") . '</h2>' : '', ($its_me || $admin_user_privilege) ? '<h2>' . _('Shifts') . '</h2>' : '',
($its_me || $admin_user_privilege) ? table([ ($its_me || $admin_user_privilege) ? table([
'date' => _("Day"), 'date' => _('Day'),
'time' => _("Time"), 'time' => _('Time'),
'room' => _("Location"), 'room' => _('Location'),
'shift_info' => _("Name &amp; workmates"), 'shift_info' => _('Name &amp; workmates'),
'comment' => _("Comment"), 'comment' => _('Comment'),
'actions' => _("Action") 'actions' => _('Action')
], $myshifts_table) : '', ], $myshifts_table) : '',
$its_me ? info(glyph('info-sign') . _("Your night shifts between 2 and 8 am count twice."), true) : '', $its_me ? info(glyph('info-sign') . _('Your night shifts between 2 and 8 am count twice.'), true) : '',
$its_me && count($shifts) == 0 ? error(sprintf(_("Go to the <a href=\"%s\">shifts table</a> to sign yourself up for some shifts."), page_link_to('user_shifts')), true) : '' $its_me && count($shifts) == 0
]); ? error(sprintf(
_('Go to the <a href="%s">shifts table</a> to sign yourself up for some shifts.'),
page_link_to('user_shifts')
), true)
: ''
]
);
} }
/** /**
* View for password recovery step 1: E-Mail * View for password recovery step 1: E-Mail
*
* @return string
*/ */
function User_password_recovery_view() { function User_password_recovery_view()
{
return page_with_title(user_password_recovery_title(), [ return page_with_title(user_password_recovery_title(), [
msg(), msg(),
_("We will send you an e-mail with a password recovery link. Please use the email address you used for registration."), _('We will send you an e-mail with a password recovery link. Please use the email address you used for registration.'),
form([ form([
form_text('email', _("E-Mail"), ""), form_text('email', _('E-Mail'), ''),
form_submit('submit', _("Recover")) form_submit('submit', _('Recover'))
]) ])
]); ]);
} }
/** /**
* View for password recovery step 2: New password * View for password recovery step 2: New password
*
* @return string
*/ */
function User_password_set_view() { function User_password_set_view()
{
return page_with_title(user_password_recovery_title(), [ return page_with_title(user_password_recovery_title(), [
msg(), msg(),
_("Please enter a new password."), _('Please enter a new password.'),
form([ form([
form_password('password', _("Password")), form_password('password', _('Password')),
form_password('password2', _("Confirm password")), form_password('password2', _('Confirm password')),
form_submit('submit', _("Save")) form_submit('submit', _('Save'))
]) ])
]); ]);
} }
function User_angeltypes_render($user_angeltypes) { /**
* @param array[] $user_angeltypes
* @return string
*/
function User_angeltypes_render($user_angeltypes)
{
$output = []; $output = [];
foreach ($user_angeltypes as $angeltype) { foreach ($user_angeltypes as $angeltype) {
$class = "";
if ($angeltype['restricted'] == 1) {
if ($angeltype['confirm_user_id'] != null) {
$class = 'text-success'; $class = 'text-success';
} else { if ($angeltype['restricted'] == 1 && $angeltype['confirm_user_id'] == null) {
$class = 'text-warning'; $class = 'text-warning';
} }
} else { $output[] = '<a href="' . angeltype_link($angeltype['id']) . '" class="' . $class . '">'
$class = 'text-success'; . ($angeltype['supporter'] ? glyph('education') : '') . $angeltype['name']
} . '</a>';
$output[] = '<a href="' . angeltype_link($angeltype['id']) . '" class="' . $class . '">' . ($angeltype['supporter'] ? glyph('education') : '') . $angeltype['name'] . '</a>';
} }
return join('<br />', $output); return join('<br />', $output);
} }
function User_groups_render($user_groups) { /**
* @param array[] $user_groups
* @return string
*/
function User_groups_render($user_groups)
{
$output = []; $output = [];
foreach ($user_groups as $group) { foreach ($user_groups as $group) {
$output[] = substr($group['Name'], 2); $output[] = substr($group['Name'], 2);
@ -433,62 +615,113 @@ function User_groups_render($user_groups) {
/** /**
* Render a user nickname. * Render a user nickname.
* *
* @param User $user_source * @param array $user_source
* @return string * @return string
*/ */
function User_Nick_render($user_source) { function User_Nick_render($user_source)
return '<a class="' . ($user_source['Gekommen'] ? '' : 'text-muted') . '" href="' . page_link_to('users') . '&amp;action=view&amp;user_id=' . $user_source['UID'] . '"><span class="icon-icon_angel"></span> ' . htmlspecialchars($user_source['Nick']) . '</a>'; {
return render_profile_link(
'<span class="icon-icon_angel"></span> ' . htmlspecialchars($user_source['Nick']) . '</a>',
$user_source['UID'],
($user_source['Gekommen'] ? '' : 'text-muted')
);
} }
function render_user_departure_date_hint() { /**
* @param string $text
* @param int $user_id
* @param string $class
* @return string
*/
function render_profile_link($text, $user_id = null, $class = '')
{
$profile_link = page_link_to('user-settings');
if (!is_null($user_id)) {
$profile_link = page_link_to('users', ['action' => 'view', 'user_id' => $user_id]);
}
return sprintf(
'<a class="%s" href="%s">%s</a>',
$class,
$profile_link,
$text
);
}
/**
* @return string|null
*/
function render_user_departure_date_hint()
{
global $user; global $user;
if (! isset($user['planned_departure_date']) || $user['planned_departure_date'] == null) { if (!isset($user['planned_departure_date']) || $user['planned_departure_date'] == null) {
return _("Please enter your planned date of departure on your settings page to give us a feeling for teardown capacities."); $text = _('Please enter your planned date of departure on your settings page to give us a feeling for teardown capacities.');
return render_profile_link($text, null, 'alert-link');
} }
return null; return null;
} }
function render_user_freeloader_hint() { /**
global $user, $max_freeloadable_shifts; * @return string|null
*/
function render_user_freeloader_hint()
{
global $user;
if (User_is_freeloader($user)) { if (User_is_freeloader($user)) {
return sprintf(_("You freeloaded at least %s shifts. Shift signup is locked. Please go to heavens desk to be unlocked again."), $max_freeloadable_shifts); return sprintf(
_('You freeloaded at least %s shifts. Shift signup is locked. Please go to heavens desk to be unlocked again.'),
config('max_freeloadable_shifts')
);
} }
return null; return null;
} }
// Hinweis für Engel, die noch nicht angekommen sind /**
function render_user_arrived_hint() { * Hinweis für Engel, die noch nicht angekommen sind
*
* @return string|null
*/
function render_user_arrived_hint()
{
global $user; global $user;
if ($user['Gekommen'] == 0) { if ($user['Gekommen'] == 0) {
return _("You are not marked as arrived. Please go to heaven's desk, get your angel badge and/or tell them that you arrived already."); return _('You are not marked as arrived. Please go to heaven\'s desk, get your angel badge and/or tell them that you arrived already.');
} }
return null; return null;
} }
function render_user_tshirt_hint() { /**
global $enable_tshirt_size, $user; * @return string|null
*/
if ($enable_tshirt_size && $user['Size'] == "") { function render_user_tshirt_hint()
return _("You need to specify a tshirt size in your settings!"); {
}
return null;
}
function render_user_dect_hint() {
global $user; global $user;
if ($user['DECT'] == "") { if (config('enable_tshirt_size') && $user['Size'] == '') {
return _("You need to specify a DECT phone number in your settings! If you don't have a DECT phone, just enter \"-\"."); $text = _('You need to specify a tshirt size in your settings!');
return render_profile_link($text, null, 'alert-link');
} }
return null; return null;
} }
?> /**
* @return string|null
*/
function render_user_dect_hint()
{
global $user;
if ($user['DECT'] == '') {
$text = _('You need to specify a DECT phone number in your settings! If you don\'t have a DECT phone, just enter \'-\'.');
return render_profile_link($text, null, 'alert-link');
}
return null;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,19 @@
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.5/phpunit.xsd" bootstrap="./tests/autoload.php"
backupGlobals="false" xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.3/phpunit.xsd"
bootstrap="./includes/engelsystem_provider.php"
colors="true" colors="true"
convertErrorsToExceptions="true" >
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false">
<testsuites> <testsuites>
<testsuite name="Models"> <testsuite name="Feature">
<directory>./test/model/</directory> <directory>./tests/Feature</directory>
</testsuite>
<testsuite name="Unit">
<directory>./tests/Unit</directory>
</testsuite> </testsuite>
</testsuites> </testsuites>
<filter> <filter>
<whitelist> <whitelist>
<directory>./include/</directory> <directory>./src/</directory>
<directory>./public/</directory>
</whitelist> </whitelist>
</filter> </filter>
<php>
<const name="PHPUNIT_TESTSUITE" value="true" />
</php>
</phpunit> </phpunit>

8
public/.htaccess Normal file
View File

@ -0,0 +1,8 @@
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

View File

@ -1,6 +1,6 @@
/*! /*!
* Bootstrap v3.3.6 (http://getbootstrap.com) * Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc. * Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/ */
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
@ -1095,7 +1095,6 @@ a:focus {
text-decoration: underline; text-decoration: underline;
} }
a:focus { a:focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color; outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px; outline-offset: -2px;
} }
@ -2524,7 +2523,6 @@ select[size] {
input[type="file"]:focus, input[type="file"]:focus,
input[type="radio"]:focus, input[type="radio"]:focus,
input[type="checkbox"]:focus { input[type="checkbox"]:focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color; outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px; outline-offset: -2px;
} }
@ -3015,7 +3013,6 @@ select[multiple].input-lg {
.btn.focus, .btn.focus,
.btn:active.focus, .btn:active.focus,
.btn.active.focus { .btn.active.focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color; outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px; outline-offset: -2px;
} }

View File

@ -22,8 +22,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
*/ */
/*! /*!
* Bootstrap v3.3.6 (http://getbootstrap.com) * Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc. * Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/ */
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
@ -1118,7 +1118,6 @@ a:focus {
text-decoration: underline; text-decoration: underline;
} }
a:focus { a:focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color; outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px; outline-offset: -2px;
} }
@ -2547,7 +2546,6 @@ select[size] {
input[type="file"]:focus, input[type="file"]:focus,
input[type="radio"]:focus, input[type="radio"]:focus,
input[type="checkbox"]:focus { input[type="checkbox"]:focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color; outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px; outline-offset: -2px;
} }
@ -3038,7 +3036,6 @@ select[multiple].input-lg {
.btn.focus, .btn.focus,
.btn:active.focus, .btn:active.focus,
.btn.active.focus { .btn.active.focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color; outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px; outline-offset: -2px;
} }

View File

@ -1,6 +1,6 @@
/*! /*!
* Bootstrap v3.3.6 (http://getbootstrap.com) * Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc. * Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/ */
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
@ -1095,7 +1095,6 @@ a:focus {
text-decoration: underline; text-decoration: underline;
} }
a:focus { a:focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color; outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px; outline-offset: -2px;
} }
@ -2524,7 +2523,6 @@ select[size] {
input[type="file"]:focus, input[type="file"]:focus,
input[type="radio"]:focus, input[type="radio"]:focus,
input[type="checkbox"]:focus { input[type="checkbox"]:focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color; outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px; outline-offset: -2px;
} }
@ -3015,7 +3013,6 @@ select[multiple].input-lg {
.btn.focus, .btn.focus,
.btn:active.focus, .btn:active.focus,
.btn.active.focus { .btn.active.focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color; outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px; outline-offset: -2px;
} }

View File

@ -8,8 +8,8 @@
color: #000; color: #000;
} }
/*! /*!
* Bootstrap v3.3.6 (http://getbootstrap.com) * Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc. * Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/ */
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
@ -1104,7 +1104,6 @@ a:focus {
text-decoration: underline; text-decoration: underline;
} }
a:focus { a:focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color; outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px; outline-offset: -2px;
} }
@ -2533,7 +2532,6 @@ select[size] {
input[type="file"]:focus, input[type="file"]:focus,
input[type="radio"]:focus, input[type="radio"]:focus,
input[type="checkbox"]:focus { input[type="checkbox"]:focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color; outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px; outline-offset: -2px;
} }
@ -3024,7 +3022,6 @@ select[multiple].input-lg {
.btn.focus, .btn.focus,
.btn:active.focus, .btn:active.focus,
.btn.active.focus { .btn.active.focus {
outline: thin dotted;
outline: 5px auto -webkit-focus-ring-color; outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px; outline-offset: -2px;
} }

Some files were not shown because too many files have changed in this diff Show More