shift view performance improvements
This commit is contained in:
parent
ffc33993d4
commit
46528fe1d8
|
@ -44,10 +44,12 @@ function room_controller() {
|
||||||
$shiftsFilterRenderer->enableDaySelection($days);
|
$shiftsFilterRenderer->enableDaySelection($days);
|
||||||
|
|
||||||
$shifts = Shifts_by_ShiftsFilter($shiftsFilter, $user);
|
$shifts = Shifts_by_ShiftsFilter($shiftsFilter, $user);
|
||||||
|
$needed_angeltypes = NeededAngeltypes_by_ShiftsFilter($shiftsFilter, $user);
|
||||||
|
$shift_entries = ShiftEntries_by_ShiftsFilter($shiftsFilter, $user);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
$room['Name'],
|
$room['Name'],
|
||||||
Room_view($room, $shiftsFilterRenderer, new ShiftCalendarRenderer($shifts, $shiftsFilter))
|
Room_view($room, $shiftsFilterRenderer, new ShiftCalendarRenderer($shifts, $needed_angeltypes, $shift_entries, $shiftsFilter))
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,10 @@ function shift_entry_add_controller() {
|
||||||
$user_id = $user['UID'];
|
$user_id = $user['UID'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$shift_signup_allowed = Shift_signup_allowed(User($user_id), $shift, $type);
|
$needed_angeltype = NeededAngeltype_by_Shift_and_Angeltype($shift, $type);
|
||||||
|
$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);
|
||||||
if (! $shift_signup_allowed->isSignupAllowed()) {
|
if (! $shift_signup_allowed->isSignupAllowed()) {
|
||||||
error(_("You are not allowed to sign up for this shift. Maybe shift is full or already running."));
|
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));
|
||||||
|
|
|
@ -202,13 +202,17 @@ function shift_controller() {
|
||||||
$user_shifts = Shifts_by_user($user);
|
$user_shifts = Shifts_by_user($user);
|
||||||
|
|
||||||
$shift_signup_state = new ShiftSignupState(ShiftSignupState::OCCUPIED, 0);
|
$shift_signup_state = new ShiftSignupState(ShiftSignupState::OCCUPIED, 0);
|
||||||
foreach ($angeltypes as $angeltype) {
|
foreach ($angeltypes as &$angeltype) {
|
||||||
$angeltype_signup_state = Shift_signup_allowed($user, $shift, $angeltype, null, $user_shifts);
|
$needed_angeltype = NeededAngeltype_by_Shift_and_Angeltype($shift, $angeltype);
|
||||||
|
$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);
|
||||||
if ($shift_signup_state == null) {
|
if ($shift_signup_state == null) {
|
||||||
$shift_signup_state = $angeltype_signup_state;
|
$shift_signup_state = $angeltype_signup_state;
|
||||||
} else {
|
} else {
|
||||||
$shift_signup_state->combineWith($angeltype_signup_state);
|
$shift_signup_state->combineWith($angeltype_signup_state);
|
||||||
}
|
}
|
||||||
|
$angeltype['shift_signup_state'] = $angeltype_signup_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -11,7 +11,7 @@ function Shifts_by_room($room) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter, $user) {
|
function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter, $user) {
|
||||||
$SQL="SELECT `Shifts`.*, `ShiftTypes`.`name`, `Room`.`Name` as `room_name`
|
$SQL = "SELECT `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`
|
||||||
|
@ -19,48 +19,48 @@ function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter, $user) {
|
||||||
AND `start` BETWEEN " . $shiftsFilter->getStartTime() . " AND " . $shiftsFilter->getEndTime() . "
|
AND `start` BETWEEN " . $shiftsFilter->getStartTime() . " AND " . $shiftsFilter->getEndTime() . "
|
||||||
ORDER BY `Shifts`.`start`";
|
ORDER BY `Shifts`.`start`";
|
||||||
/**
|
/**
|
||||||
$SQL = "SELECT DISTINCT `Shifts`.*, `ShiftTypes`.`name`, `Room`.`Name` as `room_name`
|
* $SQL = "SELECT DISTINCT `Shifts`.*, `ShiftTypes`.`name`, `Room`.`Name` as `room_name`
|
||||||
FROM `Shifts`
|
* FROM `Shifts`
|
||||||
INNER JOIN `Room` USING (`RID`)
|
* INNER JOIN `Room` USING (`RID`)
|
||||||
INNER JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`)
|
* INNER JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`)
|
||||||
LEFT JOIN (
|
* LEFT JOIN (
|
||||||
SELECT COUNT(*) AS special_needs , nat3.`shift_id`
|
* SELECT COUNT(*) AS special_needs , nat3.`shift_id`
|
||||||
FROM `NeededAngelTypes` AS nat3
|
* FROM `NeededAngelTypes` AS nat3
|
||||||
WHERE `shift_id` IS NOT NULL
|
* WHERE `shift_id` IS NOT NULL
|
||||||
GROUP BY nat3.`shift_id`
|
* GROUP BY nat3.`shift_id`
|
||||||
) AS nat2 ON nat2.`shift_id` = `Shifts`.`SID`
|
* ) AS nat2 ON nat2.`shift_id` = `Shifts`.`SID`
|
||||||
INNER JOIN `NeededAngelTypes` AS nat
|
* INNER JOIN `NeededAngelTypes` AS nat
|
||||||
ON nat.`count` != 0
|
* ON nat.`count` != 0
|
||||||
AND nat.`angel_type_id` IN (" . implode(',', $shiftsFilter->getTypes()) . ")
|
* AND nat.`angel_type_id` IN (" . implode(',', $shiftsFilter->getTypes()) . ")
|
||||||
AND (
|
* AND (
|
||||||
(nat2.`special_needs` > 0 AND nat.`shift_id` = `Shifts`.`SID`)
|
* (nat2.`special_needs` > 0 AND nat.`shift_id` = `Shifts`.`SID`)
|
||||||
OR
|
* OR
|
||||||
(
|
* (
|
||||||
(nat2.`special_needs` = 0 OR nat2.`special_needs` IS NULL)
|
* (nat2.`special_needs` = 0 OR nat2.`special_needs` IS NULL)
|
||||||
AND nat.`room_id` = `RID`)
|
* AND nat.`room_id` = `RID`)
|
||||||
)
|
* )
|
||||||
LEFT JOIN (
|
* LEFT JOIN (
|
||||||
SELECT se.`SID`, se.`TID`, COUNT(*) as count
|
* SELECT se.`SID`, se.`TID`, COUNT(*) as count
|
||||||
FROM `ShiftEntry` AS se GROUP BY se.`SID`, se.`TID`
|
* FROM `ShiftEntry` AS se GROUP BY se.`SID`, se.`TID`
|
||||||
) AS entries ON entries.`SID` = `Shifts`.`SID` AND entries.`TID` = nat.`angel_type_id`
|
* ) AS entries ON entries.`SID` = `Shifts`.`SID` AND entries.`TID` = nat.`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 " . $shiftsFilter->getStartTime() . " AND " . $shiftsFilter->getEndTime();
|
||||||
|
*
|
||||||
if (count($shiftsFilter->getFilled()) == 1) {
|
* if (count($shiftsFilter->getFilled()) == 1) {
|
||||||
if ($shiftsFilter->getFilled()[0] == ShiftsFilter::FILLED_FREE) {
|
* if ($shiftsFilter->getFilled()[0] == ShiftsFilter::FILLED_FREE) {
|
||||||
$SQL .= "
|
* $SQL .= "
|
||||||
AND (
|
* AND (
|
||||||
nat.`count` > entries.`count` OR entries.`count` IS NULL
|
* nat.`count` > entries.`count` OR entries.`count` IS NULL
|
||||||
)";
|
* )";
|
||||||
} elseif ($_SESSION['user_shifts']['filled'][0] == ShiftsFilter::FILLED_FILLED) {
|
* } elseif ($_SESSION['user_shifts']['filled'][0] == ShiftsFilter::FILLED_FILLED) {
|
||||||
$SQL .= "
|
* $SQL .= "
|
||||||
AND (
|
* AND (
|
||||||
nat.`count` <= entries.`count`
|
* nat.`count` <= entries.`count`
|
||||||
)";
|
* )";
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
$SQL .= "
|
* $SQL .= "
|
||||||
ORDER BY `start`";
|
* ORDER BY `start`";
|
||||||
*/
|
*/
|
||||||
$result = sql_select($SQL);
|
$result = sql_select($SQL);
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
|
@ -69,6 +69,56 @@ function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter, $user) {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function NeededAngeltypes_by_ShiftsFilter(ShiftsFilter $shiftsFilter, $user) {
|
||||||
|
$SQL = "SELECT `NeededAngelTypes`.*, `AngelTypes`.`id`, `AngelTypes`.`name`, `AngelTypes`.`restricted`, `AngelTypes`.`no_self_signup`
|
||||||
|
FROM `Shifts`
|
||||||
|
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`
|
||||||
|
JOIN `AngelTypes` ON `AngelTypes`.`id`= `NeededAngelTypes`.`angel_type_id`
|
||||||
|
WHERE `Shifts`.`RID` IN (" . implode(',', $shiftsFilter->getRooms()) . ")
|
||||||
|
AND `start` BETWEEN " . $shiftsFilter->getStartTime() . " AND " . $shiftsFilter->getEndTime() . "
|
||||||
|
ORDER BY `Shifts`.`start`";
|
||||||
|
// FIXME: Use needed angeltypes on rooms!
|
||||||
|
$result = sql_select($SQL);
|
||||||
|
if ($result === false) {
|
||||||
|
engelsystem_error("Unable to load needed angeltypes by filter.");
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function NeededAngeltype_by_Shift_and_Angeltype($shift, $angeltype) {
|
||||||
|
$SQL = "SELECT `NeededAngelTypes`.*, `AngelTypes`.`id`, `AngelTypes`.`name`, `AngelTypes`.`restricted`, `AngelTypes`.`no_self_signup`
|
||||||
|
FROM `Shifts`
|
||||||
|
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`
|
||||||
|
JOIN `AngelTypes` ON `AngelTypes`.`id`= `NeededAngelTypes`.`angel_type_id`
|
||||||
|
WHERE `Shifts`.`SID`=" . sql_escape($shift['SID']) . "
|
||||||
|
AND `AngelTypes`.`id`=" . sql_escape($angeltype['id']) . "
|
||||||
|
ORDER BY `Shifts`.`start`";
|
||||||
|
// FIXME: Use needed angeltypes on rooms!
|
||||||
|
$result = sql_select($SQL);
|
||||||
|
if ($result === false) {
|
||||||
|
engelsystem_error("Unable to load needed angeltypes by filter.");
|
||||||
|
}
|
||||||
|
if (count($result) == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return $result[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function ShiftEntries_by_ShiftsFilter(ShiftsFilter $shiftsFilter, $user) {
|
||||||
|
$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`
|
||||||
|
JOIN `ShiftEntry` ON `ShiftEntry`.`SID`=`Shifts`.`SID`
|
||||||
|
JOIN `User` ON `ShiftEntry`.`UID`=`User`.`UID`
|
||||||
|
WHERE `Shifts`.`RID` IN (" . implode(',', $shiftsFilter->getRooms()) . ")
|
||||||
|
AND `start` BETWEEN " . $shiftsFilter->getStartTime() . " AND " . $shiftsFilter->getEndTime() . "
|
||||||
|
ORDER BY `Shifts`.`start`";
|
||||||
|
$result = sql_select($SQL);
|
||||||
|
if ($result === false) {
|
||||||
|
engelsystem_error("Unable to load shift entries by filter.");
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a shift collides with other shifts (in time).
|
* Check if a shift collides with other shifts (in time).
|
||||||
*
|
*
|
||||||
|
@ -88,22 +138,15 @@ 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 int $shift_id
|
|
||||||
* ID of the shift to check
|
|
||||||
* @param int $angeltype_id
|
|
||||||
* ID of the angeltype that should be checked
|
|
||||||
*/
|
*/
|
||||||
function Shift_free_entries($shift_id, $angeltype_id) {
|
function Shift_free_entries($needed_angeltype, $shift_entries) {
|
||||||
$needed_angeltypes = NeededAngelTypes_by_shift($shift_id);
|
$taken = 0;
|
||||||
|
foreach ($shift_entries as $shift_entry) {
|
||||||
foreach ($needed_angeltypes as $needed_angeltype) {
|
if ($shift_entry['freeloaded'] == 0) {
|
||||||
if ($needed_angeltype['angel_type_id'] == $angeltype_id) {
|
$taken ++;
|
||||||
return max(0, $needed_angeltype['count'] - $needed_angeltype['taken']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return max(0, $needed_angeltype['count'] - $taken);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,10 +161,10 @@ function Shift_free_entries($shift_id, $angeltype_id) {
|
||||||
* @param boolean $angeltype_supporter
|
* @param boolean $angeltype_supporter
|
||||||
* True, if the user has angeltype supporter rights for the angeltype, which enables him to sign somebody up for the shift.
|
* True, if the user has angeltype supporter rights for the angeltype, which enables him to sign somebody up for the shift.
|
||||||
*/
|
*/
|
||||||
function Shift_signup_allowed_angel($user, $shift, $angeltype, $user_angeltype, $user_shifts, $angeltype_supporter = false) {
|
function Shift_signup_allowed_angel($user, $shift, $angeltype, $user_angeltype, $user_shifts, $needed_angeltype, $shift_entries) {
|
||||||
$free_entries = Shift_free_entries($shift['SID'], $angeltype['id']);
|
$free_entries = Shift_free_entries($needed_angeltype, $shift_entries);
|
||||||
|
|
||||||
if($user['Gekommen'] == 0) {
|
if ($user['Gekommen'] == 0) {
|
||||||
return new ShiftSignupState(ShiftSignupState::SHIFT_ENDED, $free_entries);
|
return new ShiftSignupState(ShiftSignupState::SHIFT_ENDED, $free_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +198,7 @@ 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_supporter === false) || ($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
|
||||||
|
@ -175,8 +218,8 @@ 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.
|
||||||
*/
|
*/
|
||||||
function Shift_signup_allowed_angeltype_supporter($shift, $angeltype) {
|
function Shift_signup_allowed_angeltype_supporter($shift, $angeltype, $needed_angeltype, $shift_entries) {
|
||||||
$free_entries = Shift_free_entries($shift['SID'], $angeltype['id']);
|
$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);
|
||||||
}
|
}
|
||||||
|
@ -192,8 +235,8 @@ function Shift_signup_allowed_angeltype_supporter($shift, $angeltype) {
|
||||||
* @param AngelType $angeltype
|
* @param AngelType $angeltype
|
||||||
* The angeltype to which the user wants to sign up
|
* The angeltype to which the user wants to sign up
|
||||||
*/
|
*/
|
||||||
function Shift_signup_allowed_admin($shift, $angeltype) {
|
function Shift_signup_allowed_admin($shift, $angeltype, $needed_angeltype, $shift_entries) {
|
||||||
$free_entries = Shift_free_entries($shift['SID'], $angeltype['id']);
|
$free_entries = Shift_free_entries($needed_angeltype, $shift_entries);
|
||||||
if ($free_entries == 0) {
|
if ($free_entries == 0) {
|
||||||
// User shift admins may join anybody in every shift
|
// User shift admins may join anybody in every shift
|
||||||
return new ShiftSignupState(ShiftSignupState::ADMIN, $free_entries);
|
return new ShiftSignupState(ShiftSignupState::ADMIN, $free_entries);
|
||||||
|
@ -212,18 +255,18 @@ function Shift_signup_allowed_admin($shift, $angeltype) {
|
||||||
* @param array<Shift> $user_shifts
|
* @param array<Shift> $user_shifts
|
||||||
* List of the users shifts
|
* List of the users shifts
|
||||||
*/
|
*/
|
||||||
function Shift_signup_allowed($signup_user, $shift, $angeltype, $user_angeltype = null, $user_shifts = null) {
|
function Shift_signup_allowed($signup_user, $shift, $angeltype, $user_angeltype = null, $user_shifts = null, $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($shift, $angeltype);
|
return Shift_signup_allowed_admin($shift, $angeltype, $needed_angeltype, $shift_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array('shiftentry_edit_angeltype_supporter', $privileges) && User_is_AngelType_supporter($user, $angeltype)) {
|
if (in_array('shiftentry_edit_angeltype_supporter', $privileges) && User_is_AngelType_supporter($user, $angeltype)) {
|
||||||
return Shift_signup_allowed_angeltype_supporter($shift, $angeltype);
|
return Shift_signup_allowed_angeltype_supporter($shift, $angeltype, $needed_angeltype, $shift_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Shift_signup_allowed_angel($signup_user, $shift, $angeltype, $user_angeltype, $user_shifts, false);
|
return Shift_signup_allowed_angel($signup_user, $shift, $angeltype, $user_angeltype, $user_shifts, $needed_angeltype, $shift_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -73,14 +73,17 @@ function User_unconfirmed_AngelTypes($user) {
|
||||||
* @param User $user
|
* @param User $user
|
||||||
* @param AngelType $angeltype
|
* @param AngelType $angeltype
|
||||||
*/
|
*/
|
||||||
function User_is_AngelType_supporter($user, $angeltype) {
|
function User_is_AngelType_supporter(&$user, $angeltype) {
|
||||||
|
if(!isset($user['privileges'])) {
|
||||||
|
$user['privileges'] = privileges_for_user($user['UID']);
|
||||||
|
}
|
||||||
return (sql_num_query("
|
return (sql_num_query("
|
||||||
SELECT `id`
|
SELECT `id`
|
||||||
FROM `UserAngelTypes`
|
FROM `UserAngelTypes`
|
||||||
WHERE `user_id`='" . sql_escape($user['UID']) . "'
|
WHERE `user_id`='" . sql_escape($user['UID']) . "'
|
||||||
AND `angeltype_id`='" . sql_escape($angeltype['id']) . "'
|
AND `angeltype_id`='" . sql_escape($angeltype['id']) . "'
|
||||||
AND `supporter`=TRUE
|
AND `supporter`=TRUE
|
||||||
LIMIT 1") > 0) || in_array('admin_user_angeltypes', privileges_for_user($user['UID']));
|
LIMIT 1") > 0) || in_array('admin_user_angeltypes', $user['privileges']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -131,6 +131,9 @@ function sql_select_db($db_name) {
|
||||||
function sql_select($query) {
|
function sql_select($query) {
|
||||||
global $sql_connection, $query_count;
|
global $sql_connection, $query_count;
|
||||||
|
|
||||||
|
// echo $query . ";\n";
|
||||||
|
// echo debug_string_backtrace() . "\n";
|
||||||
|
|
||||||
$result = $sql_connection->query($query);
|
$result = $sql_connection->query($query);
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$data = [];
|
$data = [];
|
||||||
|
|
|
@ -130,19 +130,8 @@ function view_user_shifts() {
|
||||||
$shiftsFilter = $_SESSION['ShiftsFilter'];
|
$shiftsFilter = $_SESSION['ShiftsFilter'];
|
||||||
|
|
||||||
$shifts = Shifts_by_ShiftsFilter($shiftsFilter, $user);
|
$shifts = Shifts_by_ShiftsFilter($shiftsFilter, $user);
|
||||||
|
$needed_angeltypes = NeededAngeltypes_by_ShiftsFilter($shiftsFilter, $user);
|
||||||
$ownshifts_source = sql_select("
|
$shift_entries = ShiftEntries_by_ShiftsFilter($shiftsFilter, $user);
|
||||||
SELECT `ShiftTypes`.`name`, `Shifts`.*
|
|
||||||
FROM `Shifts`
|
|
||||||
INNER JOIN `ShiftTypes` ON (`ShiftTypes`.`id` = `Shifts`.`shifttype_id`)
|
|
||||||
INNER JOIN `ShiftEntry` ON (`Shifts`.`SID` = `ShiftEntry`.`SID` AND `ShiftEntry`.`UID` = '" . sql_escape($user['UID']) . "')
|
|
||||||
WHERE `Shifts`.`RID` IN (" . implode(',', $shiftsFilter->getRooms()) . ")
|
|
||||||
AND `start` BETWEEN " . $shiftsFilter->getStartTime() . " AND " . $shiftsFilter->getEndTime());
|
|
||||||
$ownshifts = [];
|
|
||||||
foreach ($ownshifts_source as $ownshift) {
|
|
||||||
$ownshifts[$ownshift['SID']] = $ownshift;
|
|
||||||
}
|
|
||||||
unset($ownshifts_source);
|
|
||||||
|
|
||||||
if ($user['api_key'] == "") {
|
if ($user['api_key'] == "") {
|
||||||
User_reset_api_key($user, false);
|
User_reset_api_key($user, false);
|
||||||
|
@ -163,7 +152,7 @@ function view_user_shifts() {
|
||||||
$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());
|
||||||
|
|
||||||
$shiftCalendarRenderer = new ShiftCalendarRenderer($shifts, $shiftsFilter);
|
$shiftCalendarRenderer = new ShiftCalendarRenderer($shifts, $needed_angeltypes, $shift_entries, $shiftsFilter);
|
||||||
return page([
|
return page([
|
||||||
div('col-md-12', [
|
div('col-md-12', [
|
||||||
msg(),
|
msg(),
|
||||||
|
|
|
@ -35,11 +35,17 @@ class ShiftCalendarRenderer {
|
||||||
|
|
||||||
private $blocksPerSlot = null;
|
private $blocksPerSlot = null;
|
||||||
|
|
||||||
public function __construct($shifts, ShiftsFilter $shiftsFilter) {
|
private $needed_angeltypes = null;
|
||||||
|
|
||||||
|
private $shift_entries = null;
|
||||||
|
|
||||||
|
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);
|
||||||
$this->lanes = $this->assignShiftsToLanes($shifts);
|
$this->lanes = $this->assignShiftsToLanes($shifts);
|
||||||
|
$this->needed_angeltypes = $needed_angeltypes;
|
||||||
|
$this->shift_entries = $shift_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -127,6 +133,7 @@ class ShiftCalendarRenderer {
|
||||||
$html .= $this->renderLane($lane);
|
$html .= $this->renderLane($lane);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,16 +149,31 @@ class ShiftCalendarRenderer {
|
||||||
$shift_renderer = new ShiftCalendarShiftRenderer();
|
$shift_renderer = new ShiftCalendarShiftRenderer();
|
||||||
$html = "";
|
$html = "";
|
||||||
$rendered_until = $this->getFirstBlockStartTime();
|
$rendered_until = $this->getFirstBlockStartTime();
|
||||||
|
|
||||||
|
$needed_angeltypes = [];
|
||||||
|
$shift_entries = [];
|
||||||
|
foreach ($lane->getShifts() as $shift) {
|
||||||
|
$needed_angeltypes[$shift['SID']] = [];
|
||||||
|
$shift_entries[$shift['SID']] = [];
|
||||||
|
}
|
||||||
|
foreach ($this->needed_angeltypes as $needed_angeltype) {
|
||||||
|
$needed_angeltypes[$needed_angeltype['shift_id']][] = $needed_angeltype;
|
||||||
|
}
|
||||||
|
foreach ($this->shift_entries as $shift_entry) {
|
||||||
|
$shift_entries[$shift_entry['SID']][] = $shift_entry;
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($lane->getShifts() as $shift) {
|
foreach ($lane->getShifts() as $shift) {
|
||||||
while ($rendered_until + ShiftCalendarRenderer::SECONDS_PER_ROW <= $shift['start']) {
|
while ($rendered_until + ShiftCalendarRenderer::SECONDS_PER_ROW <= $shift['start']) {
|
||||||
$html .= $this->renderTick($rendered_until);
|
$html .= $this->renderTick($rendered_until);
|
||||||
$rendered_until += ShiftCalendarRenderer::SECONDS_PER_ROW;
|
$rendered_until += ShiftCalendarRenderer::SECONDS_PER_ROW;
|
||||||
}
|
}
|
||||||
|
|
||||||
list($shift_height, $shift_html) = $shift_renderer->render($shift, $user);
|
list($shift_height, $shift_html) = $shift_renderer->render($shift, $needed_angeltypes[$shift['SID']], $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;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($rendered_until < $this->getLastBlockEndTime()) {
|
while ($rendered_until < $this->getLastBlockEndTime()) {
|
||||||
$html .= $this->renderTick($rendered_until);
|
$html .= $this->renderTick($rendered_until);
|
||||||
$rendered_until += ShiftCalendarRenderer::SECONDS_PER_ROW;
|
$rendered_until += ShiftCalendarRenderer::SECONDS_PER_ROW;
|
||||||
|
|
|
@ -15,19 +15,19 @@ class ShiftCalendarShiftRenderer {
|
||||||
* @param User $user
|
* @param User $user
|
||||||
* The user who is viewing the shift calendar
|
* The user who is viewing the shift calendar
|
||||||
*/
|
*/
|
||||||
public function render($shift, $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, $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,
|
||||||
'<td class="shift" rowspan="' . $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,
|
||||||
|
@ -38,7 +38,7 @@ class ShiftCalendarShiftRenderer {
|
||||||
]),
|
]),
|
||||||
$shifts_row,
|
$shifts_row,
|
||||||
div('shift-spacer')
|
div('shift-spacer')
|
||||||
]) . '</td>'
|
])
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,14 +63,22 @@ class ShiftCalendarShiftRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderShiftNeededAngeltypes($shift, $user) {
|
private function renderShiftNeededAngeltypes($shift, $needed_angeltypes, $shift_entries, $user) {
|
||||||
global $privileges;
|
global $privileges;
|
||||||
|
|
||||||
|
$shift_entries_filtered = [];
|
||||||
|
foreach ($needed_angeltypes as $needed_angeltype) {
|
||||||
|
$shift_entries_filtered[$needed_angeltype['id']] = [];
|
||||||
|
}
|
||||||
|
foreach ($shift_entries as $shift_entry) {
|
||||||
|
$shift_entries_filtered[$shift_entry['TID']][] = $shift_entry;
|
||||||
|
}
|
||||||
|
|
||||||
$html = "";
|
$html = "";
|
||||||
$shift_signup_state = null;
|
$shift_signup_state = null;
|
||||||
$angeltypes = NeededAngelTypes_by_shift($shift['SID']);
|
foreach ($needed_angeltypes as $angeltype) {
|
||||||
foreach ($angeltypes as $angeltype) {
|
if ($angeltype['count'] > 0 || count($shift_entries_filtered[$angeltype['id']]) > 0) {
|
||||||
list($angeltype_signup_state, $angeltype_html) = $this->renderShiftNeededAngeltype($shift, $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 {
|
||||||
|
@ -78,12 +86,13 @@ class ShiftCalendarShiftRenderer {
|
||||||
}
|
}
|
||||||
$html .= $angeltype_html;
|
$html .= $angeltype_html;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ($shift_signup_state == null) {
|
if ($shift_signup_state == null) {
|
||||||
$shift_signup_state = new ShiftSignupState(ShiftSignupState::SHIFT_ENDED, 0);
|
$shift_signup_state = new ShiftSignupState(ShiftSignupState::SHIFT_ENDED, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
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') . '&shift_id=' . $shift['SID'] . '&type_id=' . $angeltype['id'], _("Add more angels"), 'btn-xs') . '</li>';
|
$html .= '<li class="list-group-item">' . button(page_link_to('user_shifts') . '&shift_id=' . $shift['SID'], _("Add more angels"), 'btn-xs') . '</li>';
|
||||||
}
|
}
|
||||||
if ($html != '') {
|
if ($html != '') {
|
||||||
return [
|
return [
|
||||||
|
@ -107,13 +116,13 @@ class ShiftCalendarShiftRenderer {
|
||||||
* @param User $user
|
* @param User $user
|
||||||
* The user who is viewing the shift calendar
|
* The user who is viewing the shift calendar
|
||||||
*/
|
*/
|
||||||
private function renderShiftNeededAngeltype($shift, $angeltype, $user) {
|
private function renderShiftNeededAngeltype($shift, $shift_entries, $angeltype, $user) {
|
||||||
$entry_list = [];
|
$entry_list = [];
|
||||||
foreach ($angeltype['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);
|
$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:
|
||||||
|
@ -174,7 +183,7 @@ class ShiftCalendarShiftRenderer {
|
||||||
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']) . ' ‐ ' . date('H:i', $shift['end']) . ' — ' . ShiftType($shift['shifttype_id'])['name'];
|
$shift_heading = date('H:i', $shift['start']) . ' ‐ ' . date('H:i', $shift['end']) . ' — ' . $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
|
||||||
|
|
|
@ -19,8 +19,7 @@ function Shift_signup_button_render($shift, $angeltype, $user_angeltype = null,
|
||||||
$user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype);
|
$user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype);
|
||||||
}
|
}
|
||||||
|
|
||||||
$shift_signup_state = Shift_signup_allowed($user, $shift, $angeltype, $user_angeltype, $user_shifts);
|
if ($angeltype['shift_signup_state']->isSignupAllowed()) {
|
||||||
if ($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']));
|
||||||
|
|
Loading…
Reference in New Issue