summaryrefslogtreecommitdiff
path: root/includes/model/Shifts_model.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/model/Shifts_model.php')
-rw-r--r--includes/model/Shifts_model.php280
1 files changed, 166 insertions, 114 deletions
diff --git a/includes/model/Shifts_model.php b/includes/model/Shifts_model.php
index a827c6b5..2db0a3d3 100644
--- a/includes/model/Shifts_model.php
+++ b/includes/model/Shifts_model.php
@@ -1,9 +1,83 @@
<?php
+use Engelsystem\ShiftsFilter;
+use Engelsystem\ShiftSignupState;
+
+function Shifts_by_room($room) {
+ $result = sql_select("SELECT * FROM `Shifts` WHERE `RID`=" . sql_escape($room['RID']) . " ORDER BY `start`");
+ if ($result === false) {
+ engelsystem_error("Unable to load shifts.");
+ }
+ return $result;
+}
+
+function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter, $user) {
+ $SQL = "SELECT DISTINCT `Shifts`.*, `ShiftTypes`.`name`, `Room`.`Name` as `room_name`, nat2.`special_needs` > 0 AS 'has_special_needs'
+ FROM `Shifts`
+ INNER JOIN `Room` USING (`RID`)
+ INNER JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`)
+ LEFT JOIN (
+ SELECT COUNT(*) AS special_needs , nat3.`shift_id`
+ FROM `NeededAngelTypes` AS nat3
+ WHERE `shift_id` IS NOT NULL
+ GROUP BY nat3.`shift_id`
+ ) AS nat2 ON nat2.`shift_id` = `Shifts`.`SID`
+ INNER JOIN `NeededAngelTypes` AS nat
+ ON nat.`count` != 0
+ AND nat.`angel_type_id` IN (" . implode(',', $shiftsFilter->getTypes()) . ")
+ AND (
+ (nat2.`special_needs` > 0 AND nat.`shift_id` = `Shifts`.`SID`)
+ OR
+ (
+ (nat2.`special_needs` = 0 OR nat2.`special_needs` IS NULL)
+ AND nat.`room_id` = `RID`)
+ )
+ LEFT JOIN (
+ SELECT se.`SID`, se.`TID`, COUNT(*) as count
+ FROM `ShiftEntry` AS se GROUP BY se.`SID`, se.`TID`
+ ) AS entries ON entries.`SID` = `Shifts`.`SID` AND entries.`TID` = nat.`angel_type_id`
+ WHERE `Shifts`.`RID` IN (" . implode(',', $shiftsFilter->getRooms()) . ")
+ AND `start` BETWEEN " . $shiftsFilter->getStartTime() . " AND " . $shiftsFilter->getEndTime();
+
+ if (count($shiftsFilter->getFilled()) == 1) {
+ if ($shiftsFilter->getFilled()[0] == ShiftsFilter::FILLED_FREE) {
+ $SQL .= "
+ AND (
+ nat.`count` > entries.`count` OR entries.`count` IS NULL
+ OR EXISTS (
+ SELECT `SID`
+ FROM `ShiftEntry`
+ WHERE `UID` = '" . sql_escape($user['UID']) . "'
+ AND `ShiftEntry`.`SID` = `Shifts`.`SID`
+ )
+ )";
+ } elseif ($_SESSION['user_shifts']['filled'][0] == ShiftsFilter::FILLED_FILLED) {
+ $SQL .= "
+ AND (
+ nat.`count` <= entries.`count`
+ OR EXISTS (
+ SELECT `SID`
+ FROM `ShiftEntry`
+ WHERE `UID` = '" . sql_escape($user['UID']) . "'
+ AND `ShiftEntry`.`SID` = `Shifts`.`SID`
+ )
+ )";
+ }
+ }
+ $SQL .= "
+ ORDER BY `start`";
+
+ $result = sql_select($SQL);
+ if ($result === false) {
+ engelsystem_error("Unable to load shifts by filter.");
+ }
+ return $result;
+}
/**
* Check if a shift collides with other shifts (in time).
- * @param Shift $shift
- * @param array<Shift> $shifts
+ *
+ * @param Shift $shift
+ * @param array<Shift> $shifts
*/
function Shift_collides($shift, $shifts) {
foreach ($shifts as $other_shift) {
@@ -17,29 +91,51 @@ function Shift_collides($shift, $shifts) {
}
/**
- * Check if an angel can sign up for given shift.
+ * Returns the number of needed angels/free shift entries for an angeltype.
*
- * @param Shift $shift
- * @param AngelType $angeltype
- * @param array<Shift> $user_shifts
+ * @param int $shift_id
+ * ID of the shift to check
+ * @param int $angeltype_id
+ * ID of the angeltype that should be checked
*/
-function Shift_signup_allowed($shift, $angeltype, $user_angeltype = null, $user_shifts = null) {
- global $user, $privileges;
+function Shift_free_entries($shift_id, $angeltype_id) {
+ $needed_angeltypes = NeededAngelTypes_by_shift($shift_id);
- if ($user_shifts == null) {
- $user_shifts = Shifts_by_user($user);
- if ($user_shifts === false) {
- engelsystem_error('Unable to load users shifts.');
+ foreach ($needed_angeltypes as $needed_angeltype) {
+ if ($needed_angeltype['angel_type_id'] == $angeltype_id) {
+ return max(0, $needed_angeltype['count'] - $needed_angeltype['taken']);
}
}
- $collides = Shift_collides($shift, $user_shifts);
+ return 0;
+}
+
+/**
+ * Check if an angel can sign up for given shift.
+ *
+ * @param Shift $shift
+ * The shift
+ * @param AngelType $angeltype
+ * The angeltype to which the user wants to sign up
+ * @param array<Shift> $user_shifts
+ * List of the users shifts
+ */
+function Shift_signup_allowed($user, $shift, $angeltype, $user_angeltype = null, $user_shifts = null) {
+ global $privileges;
- if ($user_angeltype == null) {
- $user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype);
- if ($user_angeltype === false) {
- engelsystem_error('Unable to load user angeltype.');
+ $free_entries = Shift_free_entries($shift['SID'], $angeltype['id']);
+
+ if (in_array('user_shifts_admin', $privileges)) {
+ if ($free_entries == 0) {
+ // User shift admins may join anybody in every shift
+ return new ShiftSignupState(ShiftSignupState::ADMIN, $free_entries);
}
+
+ return new ShiftSignupState(ShiftSignupState::FREE, $free_entries);
+ }
+
+ if ($user_shifts == null) {
+ $user_shifts = Shifts_by_user($user);
}
$signed_up = false;
@@ -50,45 +146,37 @@ function Shift_signup_allowed($shift, $angeltype, $user_angeltype = null, $user_
}
}
- $needed_angeltypes = NeededAngelTypes_by_shift($shift['SID']);
- if ($needed_angeltypes === false) {
- engelsystem_error('Unable to load needed angel types.');
+ if ($signed_up) {
+ // you cannot join if you already singed up for this shift
+ return new ShiftSignupState(ShiftSignupState::SIGNED_UP, $free_entries);
}
- // is the shift still running or alternatively is the user shift admin?
- $user_may_join_shift = true;
-
- // you canot join if shift is full
- foreach ($needed_angeltypes as $needed_angeltype) {
- if ($needed_angeltype['angel_type_id'] == $angeltype['id']) {
- if ($needed_angeltype['taken'] >= $needed_angeltype['count']) {
- $user_may_join_shift = false;
- }
- break;
- }
+ if (time() > $shift['start']) {
+ // you can only join if the shift is in future
+ return new ShiftSignupState(ShiftSignupState::SHIFT_ENDED, $free_entries);
+ }
+ if ($free_entries == 0) {
+ // you cannot join if shift is full
+ return new ShiftSignupState(ShiftSignupState::OCCUPIED, $free_entries);
}
- // you cannot join if user alread joined a parallel or this shift
- $user_may_join_shift &= ! $collides;
-
- // you cannot join if you already singed up for this shift
- $user_may_join_shift &= ! $signed_up;
-
- // you cannot join if user is not of this angel type
- $user_may_join_shift &= $user_angeltype != null;
-
- // you cannot join if you are not confirmed
- if ($angeltype['restricted'] == 1 && $user_angeltype != null) {
- $user_may_join_shift &= isset($user_angeltype['confirm_user_id']);
+ if ($user_angeltype == null) {
+ $user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype);
}
- // you can only join if the shift is in future
- $user_may_join_shift &= time() < $shift['start'];
+ if ($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 you are not confirmed
+ return new ShiftSignupState(ShiftSignupState::ANGELTYPE, $free_entries);
+ }
- // User shift admins may join anybody in every shift
- $user_may_join_shift |= in_array('user_shifts_admin', $privileges);
+ if (Shift_collides($shift, $user_shifts)) {
+ // you cannot join if user alread joined a parallel or this shift
+ return new ShiftSignupState(ShiftSignupState::COLLIDES, $free_entries);
+ }
- return $user_may_join_shift;
+ // Hooray, shift is free for you!
+ return new ShiftSignupState(ShiftSignupState::FREE, $free_entries);
}
/**
@@ -104,7 +192,11 @@ function Shift_delete_by_psid($shift_psid) {
function Shift_delete($shift_id) {
mail_shift_delete(Shift($shift_id));
- return sql_query("DELETE FROM `Shifts` WHERE `SID`='" . sql_escape($shift_id) . "'");
+ $result = sql_query("DELETE FROM `Shifts` WHERE `SID`='" . sql_escape($shift_id) . "'");
+ if ($result === false) {
+ engelsystem_error('Unable to delete shift.');
+ }
+ return $result;
}
/**
@@ -170,7 +262,7 @@ function Shift_create($shift) {
* Return users shifts.
*/
function Shifts_by_user($user) {
- return sql_select("
+ $result = sql_select("
SELECT `ShiftTypes`.`id` as `shifttype_id`, `ShiftTypes`.`name`, `ShiftEntry`.*, `Shifts`.*, `Room`.*
FROM `ShiftEntry`
JOIN `Shifts` ON (`ShiftEntry`.`SID` = `Shifts`.`SID`)
@@ -179,52 +271,10 @@ function Shifts_by_user($user) {
WHERE `UID`='" . sql_escape($user['UID']) . "'
ORDER BY `start`
");
-}
-
-/**
- * TODO: $_REQUEST is not allowed in model!
- * Returns Shift id array
- */
-function Shifts_filtered() {
- global $_REQUEST;
- $filter = "";
-
- // filterRoom (Array of integer) - Array of Room IDs (optional, for list request)
- if (isset($_REQUEST['filterRoom']) && is_array($_REQUEST['filterRoom'])) {
- foreach ($_REQUEST['filterRoom'] as $key => $value) {
- $filter .= ", `RID`='" . sql_escape($value) . "' ";
- }
- }
-
- // filterTask (Array of integer) - Array if Task (optional, for list request)
- if (isset($_REQUEST['filterTask']) && is_array($_REQUEST['filterTask'])) {
- foreach ($_REQUEST['filterTask'] as $key => $value) {
- // TODO $filter .= ", `RID`=" . sql_escape($value) . " ";
- }
- }
-
- // filterOccupancy (integer) - Occupancy state: (optional, for list request)
- // 1 occupied, 2 free, 3 occupied and free
- if (isset($_REQUEST['filterOccupancy']) && is_array($_REQUEST['filterOccupancy'])) {
- foreach ($_REQUEST['filterOccupancy'] as $key => $value) {
- // TODO $filter .= ", `RID`=" . sql_escape($value) . " ";
- }
- }
-
- // format filter
- if ($filter != "") {
- $filter = ' WHERE ' . substr($filter, 1);
- }
-
- // real request
- $shifts_source = sql_select("SELECT `SID` FROM `Shifts`" . $filter);
- if ($shifts_source === false) {
- return false;
- }
- if (count($shifts_source) > 0) {
- return $shifts_source;
+ if ($result === false) {
+ engelsystem_error('Unable to load users shifts.');
}
- return null;
+ return $result;
}
/**
@@ -242,27 +292,29 @@ function Shift($shift_id) {
$shiftsEntry_source = sql_select("SELECT `id`, `TID` , `UID` , `freeloaded` FROM `ShiftEntry` WHERE `SID`='" . sql_escape($shift_id) . "'");
if ($shifts_source === false) {
- return false;
+ engelsystem_error('Unable to load shift.');
}
- if (count($shifts_source) > 0) {
- $result = $shifts_source[0];
-
- $result['ShiftEntry'] = $shiftsEntry_source;
- $result['NeedAngels'] = [];
-
- $temp = NeededAngelTypes_by_shift($shift_id);
- foreach ($temp as $e) {
- $result['NeedAngels'][] = [
- 'TID' => $e['angel_type_id'],
- 'count' => $e['count'],
- 'restricted' => $e['restricted'],
- 'taken' => $e['taken']
- ];
- }
-
- return $result;
+
+ if (empty($shifts_source)) {
+ return null;
}
- return null;
+
+ $result = $shifts_source[0];
+
+ $result['ShiftEntry'] = $shiftsEntry_source;
+ $result['NeedAngels'] = [];
+
+ $temp = NeededAngelTypes_by_shift($shift_id);
+ foreach ($temp as $e) {
+ $result['NeedAngels'][] = [
+ 'TID' => $e['angel_type_id'],
+ 'count' => $e['count'],
+ 'restricted' => $e['restricted'],
+ 'taken' => $e['taken']
+ ];
+ }
+
+ return $result;
}
/**