Skip to content
Snippets Groups Projects
Commit bca46363 authored by Jan-Hendrik Willms's avatar Jan-Hendrik Willms Committed by David Siegfried
Browse files

fixes #132

parent 0fe45573
No related branches found
No related tags found
No related merge requests found
Showing
with 703 additions and 296 deletions
...@@ -140,11 +140,11 @@ class Consultation_AdminController extends ConsultationController ...@@ -140,11 +140,11 @@ class Consultation_AdminController extends ConsultationController
$block = new ConsultationBlock(); $block = new ConsultationBlock();
$block->range = $this->range; $block->range = $this->range;
$this->responsible = $block->responsible_persons; $this->responsible = $block->getPossibleResponsibilites();
} elseif ($this->range instanceof Institute) { } elseif ($this->range instanceof Institute) {
$block = new ConsultationBlock(); $block = new ConsultationBlock();
$block->range = $this->range; $block->range = $this->range;
$this->responsible = $block->responsible_persons; $this->responsible = $block->getPossibleResponsibilites();
} }
} }
...@@ -182,10 +182,20 @@ class Consultation_AdminController extends ConsultationController ...@@ -182,10 +182,20 @@ class Consultation_AdminController extends ConsultationController
$block->confirmation_text = trim(Request::get('confirmation-text')) ?: null; $block->confirmation_text = trim(Request::get('confirmation-text')) ?: null;
$block->note = Request::get('note'); $block->note = Request::get('note');
$block->size = Request::int('size', 1); $block->size = Request::int('size', 1);
$block->teacher_id = Request::option('teacher_id') ?: null;
$block->createSlots(Request::int('duration')); $block->createSlots(Request::int('duration'));
$stored += $block->store(); $stored += $block->store();
// Store block responsibilites
foreach (Request::getArray('responsibilities') as $type => $ids) {
foreach ($ids as $id) {
ConsultationResponsibility::create([
'block_id' => $block->id,
'range_id' => $id,
'range_type' => $type,
]);
}
}
} }
} catch (OverlapException $e) { } catch (OverlapException $e) {
$this->keepRequest(); $this->keepRequest();
...@@ -211,13 +221,9 @@ class Consultation_AdminController extends ConsultationController ...@@ -211,13 +221,9 @@ class Consultation_AdminController extends ConsultationController
$this->relocate('consultation/admin'); $this->relocate('consultation/admin');
} }
public function note_action($block_id, $slot_id = null, $page = 0) public function note_action($block_id, $slot_id, $page = 0)
{ {
if ($slot_id) {
PageLayout::setTitle(_('Anmerkung zu diesem Termin bearbeiten')); PageLayout::setTitle(_('Anmerkung zu diesem Termin bearbeiten'));
} else {
PageLayout::setTitle(_('Anmerkung zu diesem Block bearbeiten'));
}
$this->block = $this->loadBlock($block_id); $this->block = $this->loadBlock($block_id);
$this->slot_id = $slot_id; $this->slot_id = $slot_id;
...@@ -228,20 +234,10 @@ class Consultation_AdminController extends ConsultationController ...@@ -228,20 +234,10 @@ class Consultation_AdminController extends ConsultationController
$note = trim(Request::get('note')); $note = trim(Request::get('note'));
$changed = false;
if ($slot_id) {
$slot = $this->block->slots->find($slot_id); $slot = $this->block->slots->find($slot_id);
$slot->note = $note; $slot->note = $note;
$changed = $slot->store(); if ($slot->store()) {
} else { PageLayout::postSuccess(_('Die Anmerkung wurde bearbeitet'));
$this->block->note = $note;
foreach ($this->block->slots as $slot) {
$slot->note = '';
}
$changed = $this->block->store();
}
if ($changed) {
PageLayout::postSuccess(_('Der Block wurde bearbeitet'));
} }
if ($this->block->is_expired) { if ($this->block->is_expired) {
...@@ -344,20 +340,60 @@ class Consultation_AdminController extends ConsultationController ...@@ -344,20 +340,60 @@ class Consultation_AdminController extends ConsultationController
} }
} }
public function edit_room_action($block_id, $page = 0) public function edit_action($block_id, $page = 0)
{ {
PageLayout::setTitle(_('Ort des Blocks bearbeiten')); PageLayout::setTitle(_('Block bearbeiten'));
$this->block = $this->loadBlock($block_id); $this->block = $this->loadBlock($block_id);
$this->page = $page; $this->page = $page;
$this->responsible = false;
if ($this->block->range instanceof Course || $this->block->range instanceof Institute) {
$this->responsible = $this->block->getPossibleResponsibilites();
}
} }
public function store_room_action($block_id, $page = 0) public function store_edited_action($block_id, $page = 0)
{ {
CSRFProtection::verifyUnsafeRequest(); CSRFProtection::verifyUnsafeRequest();
$this->block = $this->loadBlock($block_id); $this->block = $this->loadBlock($block_id);
$this->block->room = Request::get('room'); $this->block->room = trim(Request::get('room'));
$this->block->note = trim(Request::get('note'));
foreach ($this->block->slots as $slot) {
$slot->note = '';
}
// Store block responsibilites
$responsibilities = array_merge(
['user' => [], 'statusgroup' => [], 'institute' => []],
Request::getArray('responsibilities')
);
foreach ($responsibilities as $type => $ids) {
$of_type = $this->block->responsibilities->filter(function ($responsibility) use ($type) {
return $responsibility->range_type === $type;
});
// Delete removed responsibilites
$of_type->each(function ($responsibility) use ($ids) {
if (!in_array($responsibility->range_id, $ids)) {
$responsibility->delete();
}
});
// Add new responsibilities
foreach ($ids as $id) {
if (!$of_type->findOneBy('range_id', $id)) {
ConsultationResponsibility::create([
'block_id' => $this->block->id,
'range_id' => $id,
'range_type' => $type,
]);
}
}
}
$this->block->store(); $this->block->store();
PageLayout::postSuccess(_('Der Block wurde gespeichert.')); PageLayout::postSuccess(_('Der Block wurde gespeichert.'));
...@@ -577,7 +613,6 @@ class Consultation_AdminController extends ConsultationController ...@@ -577,7 +613,6 @@ class Consultation_AdminController extends ConsultationController
function ($slot) use (&$deleted) { function ($slot) use (&$deleted) {
$index = $slot->is_expired ? 'expired' : 'current'; $index = $slot->is_expired ? 'expired' : 'current';
$slot->removeEvent();
$deleted[$index] += $slot->delete(); $deleted[$index] += $slot->delete();
}, },
"JOIN consultation_blocks USING (block_id) WHERE range_id = ? AND range_type = ?", "JOIN consultation_blocks USING (block_id) WHERE range_id = ? AND range_type = ?",
......
...@@ -77,6 +77,12 @@ abstract class ConsultationController extends AuthenticatedController ...@@ -77,6 +77,12 @@ abstract class ConsultationController extends AuthenticatedController
$this->flash['request'] = Request::getInstance()->getIterator()->getArrayCopy(); $this->flash['request'] = Request::getInstance()->getIterator()->getArrayCopy();
} }
/**
* @param $block_id
*
* @return ConsultationBlock|ConsultationBlock[]
* @throws AccessDeniedException
*/
protected function loadBlock($block_id) protected function loadBlock($block_id)
{ {
if (is_array($block_id)) { if (is_array($block_id)) {
......
<?php
$block = $block ?? false;
$selected = function ($type, $id) use ($block) {
if (!$block ) {
return '';
}
$matched = $block->responsibilities->filter(function ($responsibility) use ($type, $id) {
return $responsibility->range_type === $type && $responsibility->range_id === $id;
});
return count($matched) > 0 ? 'selected' : '';
}
?>
<? if (!empty($responsible['users'])): ?>
<label>
<?= _('Durchführende Person(en)') ?>
<select name="responsibilities[user][]" multiple class="nested-select">
<? foreach ($responsible['users'] as $user): ?>
<option value="<?= htmlReady($user->id) ?>" <?= $selected('user', $user->id) ?>>
<?= htmlReady($user->getFullName()) ?>
</option>
<? endforeach; ?>
</select>
</label>
<? endif; ?>
<? if (!empty($responsible['groups'])): ?>
<label>
<?= _('Durchführende Gruppe(n)') ?>
<select name="responsibilities[statusgroup][]" multiple class="nested-select">
<? foreach ($responsible['groups'] as $group): ?>
<option value="<?= htmlReady($group->id) ?>" <?= $selected('statusgroup', $group->id) ?>>
<?= htmlReady($group->getName()) ?>
</option>
<? endforeach; ?>
</select>
</label>
<? endif; ?>
<? if (!empty($responsible['institutes'])): ?>
<label>
<?= _('Durchführende Einrichtung(en)') ?>
<select name="responsibilities[institute][]" multiple class="nested-select">
<? foreach ($responsible['institutes'] as $institute): ?>
<option value="<?= htmlReady($institute->id) ?>" <?= $selected('institute', $institute->id) ?>>
<?= htmlReady($institute->getFullname()) ?>
</option>
<? endforeach; ?>
</select>
</label>
<? endif; ?>
...@@ -36,7 +36,7 @@ $intervals = [ ...@@ -36,7 +36,7 @@ $intervals = [
<fieldset> <fieldset>
<legend> <legend>
<?= _('Neue Terminblöcke anlegen') ?> <?= _('Ort und Zeit') ?>
</legend> </legend>
<label> <label>
...@@ -119,20 +119,19 @@ $intervals = [ ...@@ -119,20 +119,19 @@ $intervals = [
<input required type="text" name="size" id="size" <input required type="text" name="size" id="size"
min="1" max="50" value="<?= Request::int('size', 1) ?>"> min="1" max="50" value="<?= Request::int('size', 1) ?>">
</label> </label>
</fieldset>
<? if ($responsible): ?> <? if ($responsible): ?>
<label> <fieldset>
<?= _('Durchführende Person') ?> <legend><?= _('Durchführende Person(en), Gruppe(n) oder Einrichtung(en)') ?></legend>
<select name="teacher_id">
<option value=""></option> <?= $this->render_partial('consultation/admin/block-responsibilities.php', compact('responsible')) ?>
<? foreach ($responsible as $user): ?> </fieldset>
<option value="<?= htmlReady($user->id) ?>">
<?= htmlReady($user->getFullName()) ?>
</option>
<? endforeach; ?>
</select>
<? endif; ?> <? endif; ?>
<fieldset>
<legend><?= _('Weitere Einstellungen') ?></legend>
<label> <label>
<?= _('Information zu den Terminen in diesem Block') ?> <?= _('Information zu den Terminen in diesem Block') ?>
<textarea name="note"><?= htmlReady(Request::get('note')) ?></textarea> <textarea name="note"><?= htmlReady(Request::get('note')) ?></textarea>
......
<form action="<?= $controller->store_edited($block, $page) ?>" method="post" class="default">
<?= CSRFProtection::tokenTag() ?>
<?= MessageBox::info(
_('Das Ändern der Informationen wird auch alle Termine dieses Blocks ändern.')
)->hideClose() ?>
<fieldset>
<legend><?= _('Terminblock bearbeiten') ?></legend>
<label>
<span class="required"><?= _('Ort') ?></span>
<input required type="text" name="room" placeholder="<?= _('Ort') ?>"
value="<?= htmlReady($block->room) ?>">
</label>
<label>
<?=_('Information zu den Terminen in diesem Block') ?> (<?= _('Öffentlich einsehbar') ?>)
<textarea name="note"><?= htmlReady($block->note ) ?></textarea>
</label>
<? if ($responsible): ?>
<?= $this->render_partial('consultation/admin/block-responsibilities.php', compact('responsible', 'block')) ?>
<? endif; ?>
</fieldset>
<footer data-dialog-button>
<?= Studip\Button::createAccept(_('Speichern')) ?>
<?= Studip\LinkButton::createCancel(
_('Abbrechen'),
$controller->indexURL($page)
) ?>
</footer>
</form>
<form action="<?= $controller->store_room($block, $page) ?>" method="post" class="default">
<?= CSRFProtection::tokenTag() ?>
<fieldset>
<legend><?= _('Ort des Terminblocks bearbeiten') ?></legend>
<label>
<span class="required"><?= _('Ort') ?></span>
<input required type="text" name="room" placeholder="<?= _('Ort') ?>"
value="<?= htmlReady($block->room) ?>">
</label>
</fieldset>
<footer data-dialog-button>
<?= Studip\Button::createAccept(_('Speichern')) ?>
<?= Studip\LinkButton::createCancel(
_('Abbrechen'),
$controller->indexURL($page)
) ?>
</footer>
</form>
...@@ -45,13 +45,8 @@ ...@@ -45,13 +45,8 @@
</th> </th>
<th class="actions"> <th class="actions">
<?= ActionMenu::get()->addLink( <?= ActionMenu::get()->addLink(
$controller->edit_roomURL($block['block'], $page), $controller->editURL($block['block'], 0, $page),
_('Raum bearbeiten'), _('Bearbeiten'),
Icon::create('edit'),
['data-dialog' => 'size=auto']
)->addLink(
$controller->noteURL($block['block'], 0, $page),
_('Information bearbeiten'),
Icon::create('edit'), Icon::create('edit'),
['data-dialog' => 'size=auto'] ['data-dialog' => 'size=auto']
)->addLink( )->addLink(
......
...@@ -6,13 +6,6 @@ ...@@ -6,13 +6,6 @@
date('H:i', $block->end) date('H:i', $block->end)
) ?> ) ?>
<? if ($block->teacher): ?>
/
<a href="<?= URLHelper::getLink('dispatch.php/profile', ['username' => $block->teacher->username]) ?>">
<?= htmlReady($block->teacher->getFullName()) ?>
</a>
<? endif; ?>
(<?= formatLinks($block->room) ?>) (<?= formatLinks($block->room) ?>)
<? if ($block->show_participants): ?> <? if ($block->show_participants): ?>
...@@ -20,6 +13,19 @@ ...@@ -20,6 +13,19 @@
<?= tooltipIcon(_('Die Namen der buchenden Person sind sichtbar')) ?> <?= tooltipIcon(_('Die Namen der buchenden Person sind sichtbar')) ?>
<? endif; ?> <? endif; ?>
<? if (count($block->responsibilities) > 0): ?>
<br>
<ul class="narrow list-csv">
<? foreach ($block->responsibilities as $responsibility): ?>
<li>
<a href="<?= URLHelper::getLink($responsibility->getURL(), [], true) ?>">
<?= htmlReady($responsibility->getName()) ?>
</a>
</li>
<? endforeach; ?>
</ul>
<? endif; ?>
<? if ($block->note): ?> <? if ($block->note): ?>
<br> <br>
<small> <small>
......
...@@ -26,7 +26,7 @@ class FixMissingConsultationEvents extends Migration ...@@ -26,7 +26,7 @@ class FixMissingConsultationEvents extends Migration
// has code changes for Stud.IP 5.0 this will fail but we can neglect // has code changes for Stud.IP 5.0 this will fail but we can neglect
// that since the event is already updated. // that since the event is already updated.
try { try {
$slot->updateEvent(); $slot->updateEvents();
} catch (Exception $e) { } catch (Exception $e) {
} }
}, },
...@@ -41,10 +41,11 @@ class LegacyConsultationSlot extends ConsultationSlot ...@@ -41,10 +41,11 @@ class LegacyConsultationSlot extends ConsultationSlot
* Updates the teacher event that belongs to the slot. This will either be * Updates the teacher event that belongs to the slot. This will either be
* set to be unoccupied, occupied by only one user or by a group of user. * set to be unoccupied, occupied by only one user or by a group of user.
*/ */
public function updateEvent() public function updateEvents()
{ {
if (count($this->bookings) === 0 && !$this->block->calendar_events) { if (count($this->bookings) === 0 && !$this->block->calendar_events) {
return $this->removeEvent(); $this->events->delete();
return;
} }
$teacher = User::find($this->block->teacher_id); $teacher = User::find($this->block->teacher_id);
......
<?php
/**
* @see https://gitlab.studip.de/studip/studip/-/issues/132
*/
final class ConsultationMultipleResponsibleRanges extends Migration
{
public function description()
{
return 'Adjust database to allow multiple responsible ranges for consultations';
}
protected function up()
{
$query = "CREATE TABLE IF NOT EXISTS `consultation_responsibilities` (
`block_id` INT(11) UNSIGNED NOT NULL,
`range_id` CHAR(32) CHARSET latin1 COLLATE latin1_bin NOT NULL,
`range_type` ENUM('user', 'institute', 'statusgroup') CHARSET latin1 COLLATE latin1_bin NOT NULL,
`mkdate` INT(11) UNSIGNED NOT NULL,
PRIMARY KEY (`block_id`, `range_id`, `range_type`)
)";
DBManager::get()->exec($query);
$query = "CREATE TABLE IF NOT EXISTS `consultation_events` (
`slot_id` INT(11) UNSIGNED NOT NULL,
`user_id` CHAR(32) CHARSET latin1 COLLATE latin1_bin NOT NULL,
`mkdate` INT(11) UNSIGNED NOT NULL,
PRIMARY KEY (`slot_id`, `user_id`)
)";
DBManager::get()->exec($query);
$query = "INSERT IGNORE INTO `consultation_responsibilities` (
`block_id`, `range_id`, `range_type`, `mkdate`
)
SELECT `block_id`, `teacher_id`, 'user', UNIX_TIMESTAMP()
FROM `consultation_blocks`
WHERE `teacher_id` IS NOT NULL";
DBManager::get()->exec($query);
$query = "INSERT IGNORE INTO `consultation_events` (
`slot_id`, `user_id`, `event_id`, `mkdate`
)
SELECT `slot_id`, `teacher_id`, `teacher_event_id`, UNIX_TIMESTAMP()
FROM `consultation_blocks`
JOIN `consultation_slots` USING (`block_id`)
WHERE `teacher_event_id` IS NOT NULL";
DBManager::get()->exec($query);
$query = "ALTER TABLE `consultation_blocks`
DROP COLUMN `teacher_id`";
DBManager::get()->exec($query);
$query = "ALTER TABLE `consultation_slots`
DROP COLUMN `teacher_event_id`";
DBManager::get()->exec($query);
}
protected function down()
{
$query = "ALTER TABLE `consultation_slots`
ADD COLUMN `teacher_event_id` CHAR(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL AFTER `note`";
DBManager::get()->exec($query);
$query = "ALTER TABLE `consultation_blocks`
ADD COLUMN `teacher_id` CHAR(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL";
DBManager::get()->exec($query);
$query = "UPDATE `consultation_slots` AS cs
JOIN `consultation_events` AS ce USING (`slot_id`)
JOIN `consultation_blocks` AS cb USING (`block_id`)
SET cs.`teacher_event_id` = ce.`event_id`
WHERE cb.`range_type` = 'user'
AND cs.`slot_id` IN (
SELECT `slot_id`
FROM `consultation_events`
GROUP BY `slot_id`
HAVING COUNT(*) = 1
)";
DBManager::get()->exec($query);
$query = "UPDATE `consultation_blocks` AS cb
JOIN `consultation_responsibilities` AS cr USING (`block_id`)
SET cb.`teacher_id` = cr.`range_id`
WHERE cb.`block_id` IN (
SELECT `block_id`
FROM `consultation_responsibilities` AS cr2
JOIN `consultation_blocks` AS cb USING (`block_id`)
WHERE cr2.`range_type` = 'user'
GROUP BY `block_id`
HAVING COUNT(DISTINCT cr.`range_id`) = 1
)";
DBManager::get()->exec($query);
$query = "DROP TABLE IF EXISTS `consultation_events`";
DBManager::get()->exec($query);
$query = "DROP TABLE IF EXISTS `consultation_responsibilities`";
DBManager::get()->exec($query);
}
}
...@@ -54,9 +54,13 @@ class ConsultationMailer ...@@ -54,9 +54,13 @@ class ConsultationMailer
* *
* @param ConsultationBooking $booking The booking * @param ConsultationBooking $booking The booking
*/ */
public static function sendBookingMessageToTeacher(ConsultationBooking $booking) public static function sendBookingMessageToResponsibilities(ConsultationBooking $booking)
{ {
foreach ($booking->slot->block->responsible_persons as $user) { foreach ($booking->slot->block->responsible_persons as $user) {
if ($user->id === $GLOBALS['user']->id) {
continue;
}
self::sendMessage( self::sendMessage(
$user, $user,
$booking, $booking,
...@@ -94,7 +98,7 @@ class ConsultationMailer ...@@ -94,7 +98,7 @@ class ConsultationMailer
self::sendMessage( self::sendMessage(
$receiver, $receiver,
$booking->slot, $booking->slot,
sprintf(_('Grund des Termins bei bearbeitet'), $booking->slot->block->range_display), sprintf(_('Grund des Termins bei %s bearbeitet'), $booking->slot->block->range_display),
$booking->reason $booking->reason
); );
} }
...@@ -105,9 +109,13 @@ class ConsultationMailer ...@@ -105,9 +109,13 @@ class ConsultationMailer
* @param ConsultationBooking $booking The booking * @param ConsultationBooking $booking The booking
* @param String $reason Reason of the cancelation * @param String $reason Reason of the cancelation
*/ */
public static function sendCancelMessageToTeacher(ConsultationBooking $booking, $reason = '') public static function sendCancelMessageToResponsibilities(ConsultationBooking $booking, $reason = '')
{ {
foreach ($booking->slot->block->responsible_persons as $user) { foreach ($booking->slot->block->responsible_persons as $user) {
if ($user->id === $GLOBALS['user']->id) {
continue;
}
self::sendMessage( self::sendMessage(
$user, $user,
$booking, $booking,
......
...@@ -69,10 +69,10 @@ class CalendarEvent extends SimpleORMap implements Event, PrivacyObject ...@@ -69,10 +69,10 @@ class CalendarEvent extends SimpleORMap implements Event, PrivacyObject
'foreign_key' => 'event_id', 'foreign_key' => 'event_id',
'assoc_foreign_key' => 'student_event_id', 'assoc_foreign_key' => 'student_event_id',
]; ];
$config['belongs_to']['consultation_slot'] = [ $config['has_many']['consultation_events'] = [
'class_name' => ConsultationSlot::class, 'class_name' => ConsultationEvent::class,
'foreign_key' => 'event_id', 'foreign_key' => 'event_id',
'assoc_foreign_key' => 'teacher_event_id', 'assoc_foreign_key' => 'event_id',
]; ];
$config['additional_fields']['type'] = true; $config['additional_fields']['type'] = true;
$config['additional_fields']['name'] = true; $config['additional_fields']['name'] = true;
...@@ -88,10 +88,7 @@ class CalendarEvent extends SimpleORMap implements Event, PrivacyObject ...@@ -88,10 +88,7 @@ class CalendarEvent extends SimpleORMap implements Event, PrivacyObject
$event->consultation_booking->student_event_id = null; $event->consultation_booking->student_event_id = null;
$event->consultation_booking->store(); $event->consultation_booking->store();
} }
if ($event->consultation_slot) { $event->consultation_events->delete();
$event->consultation_slot->teacher_event_id = null;
$event->consultation_slot->store();
}
}; };
parent::configure($config); parent::configure($config);
...@@ -1018,21 +1015,18 @@ class CalendarEvent extends SimpleORMap implements Event, PrivacyObject ...@@ -1018,21 +1015,18 @@ class CalendarEvent extends SimpleORMap implements Event, PrivacyObject
} }
/** /**
* * @return string
* TODO remove! not used?
*
* @return type
*/ */
public function getName() public function getName()
{ {
switch ($this->type) { switch ($this->type) {
case 'user': case 'user':
return $this->user->getFullname(); return (string) $this->user->getFullname();
case 'sem': case 'sem':
return $this->course->name; return (string) $this->course->name;
case 'inst': case 'inst':
case 'fak': case 'fak':
return $this->institute->name; return (string) $this->institute->name;
} }
} }
......
...@@ -24,7 +24,8 @@ ...@@ -24,7 +24,8 @@
* @property bool has_bookings computed column * @property bool has_bookings computed column
* @property Range range computed column * @property Range range computed column
* @property SimpleORMapCollection slots has_many ConsultationSlot * @property SimpleORMapCollection slots has_many ConsultationSlot
* @property User teacher belongs_to User * @property ConsultationResponsibility[] responsibilities has_many ConsultationResponsibility
* @property User[] responsible_persons
*/ */
class ConsultationBlock extends SimpleORMap implements PrivacyObject class ConsultationBlock extends SimpleORMap implements PrivacyObject
{ {
...@@ -36,16 +37,18 @@ class ConsultationBlock extends SimpleORMap implements PrivacyObject ...@@ -36,16 +37,18 @@ class ConsultationBlock extends SimpleORMap implements PrivacyObject
{ {
$config['db_table'] = 'consultation_blocks'; $config['db_table'] = 'consultation_blocks';
$config['belongs_to']['teacher'] = [
'class_name' => User::class,
'foreign_key' => 'teacher_id',
];
$config['has_many']['slots'] = [ $config['has_many']['slots'] = [
'class_name' => ConsultationSlot::class, 'class_name' => ConsultationSlot::class,
'assoc_foreign_key' => 'block_id', 'assoc_foreign_key' => 'block_id',
'on_store' => 'store', 'on_store' => 'store',
'on_delete' => 'delete', 'on_delete' => 'delete',
]; ];
$config['has_many']['responsibilities'] = [
'class_name' => ConsultationResponsibility::class,
'assoc_foreign_key' => 'block_id',
'on_delete' => 'delete',
'order_by' => "ORDER BY range_type = 'user' DESC, range_type = 'statusgroup' DESC",
];
$config['additional_fields']['range'] = [ $config['additional_fields']['range'] = [
'set' => function ($block, $field, Range $range) { 'set' => function ($block, $field, Range $range) {
...@@ -61,31 +64,11 @@ class ConsultationBlock extends SimpleORMap implements PrivacyObject ...@@ -61,31 +64,11 @@ class ConsultationBlock extends SimpleORMap implements PrivacyObject
return $block->range->getFullName() . ' <' . $block->range->email . '>'; return $block->range->getFullName() . ' <' . $block->range->email . '>';
} }
if ($block->range instanceof Course || $block->range instanceof Institute) { if ($block->range instanceof Course || $block->range instanceof Institute) {
$display = $block->range->getFullName(); return sprintf(_('Veranstaltung: %s'), $block->range->getFullName());
if ($block->teacher) {
$display .= ' (' . $block->teacher->getFullName() . ')';
}
return $display;
}
throw new Exception('Not implemented yet');
};
$config['additional_fields']['responsible_persons']['get'] = function ($block) {
if ($block->range instanceof User) {
return [$block->range];
}
if ($block->range instanceof Course && $block->teacher) {
return [$block->teacher];
}
if ($block->range instanceof Course) {
return $block->range->getMembersWithStatus('tutor dozent', true)->pluck('user');
} }
if ($block->range instanceof Institute) { if ($block->range instanceof Institute) {
return $block->range->members->filter(function ($member) { return sprintf(_('Einrichtung: %s'), $block->range->getFullname());
return in_array($member->inst_perms, ['tutor', 'dozent']);
})->pluck('user');
} }
throw new Exception('Not implemented yet'); throw new Exception('Not implemented yet');
...@@ -103,6 +86,32 @@ class ConsultationBlock extends SimpleORMap implements PrivacyObject ...@@ -103,6 +86,32 @@ class ConsultationBlock extends SimpleORMap implements PrivacyObject
}); });
}; };
$config['additional_fields']['responsible_persons']['get'] = function (ConsultationBlock $block) {
if (count($block->responsibilities) !== 0) {
$result = [];
foreach (array_merge(...$block->responsibilities->getUsers()) as $user) {
$result[$user->id] = $user;
}
return array_values($result);
}
if ($block->range instanceof User) {
return [$block->range];
}
if ($block->range instanceof Course) {
return ConsultationResponsibility::getCourseResponsibilities($block->range);
}
if ($block->range instanceof Institute) {
return ConsultationResponsibility::getInstituteResponsibilites($block->range);
}
throw new Exception('Unknown range type');
};
$config['registered_callbacks']['after_store'][] = function (ConsultationBlock $block) {
$block->slots->updateEvents();
};
parent::configure($config); parent::configure($config);
} }
...@@ -273,6 +282,37 @@ class ConsultationBlock extends SimpleORMap implements PrivacyObject ...@@ -273,6 +282,37 @@ class ConsultationBlock extends SimpleORMap implements PrivacyObject
return $this->range->isAccessibleToUser(); return $this->range->isAccessibleToUser();
} }
/**
*
*/
public function getPossibleResponsibilites()
{
if ($this->range instanceof User) {
return [
'users' => [$this->range]
];
}
if ($this->range instanceof Course) {
return [
'users' => $this->range->getMembersWithStatus('tutor dozent', true)->pluck('user'),
];
}
if ($this->range instanceof Institute) {
$users = $this->range->members->filter(function ($member) {
return in_array($member->inst_perms, ['tutor', 'dozent']);
})->pluck('user');
$groups = $this->range->status_groups;
$institutes = $this->range->sub_institutes;
return compact('users', 'groups', 'institutes');
}
throw new Exception('Not implemented yet');
}
/** /**
* Export available data of a given user into a storage object * Export available data of a given user into a storage object
* (an instance of the StoredUserData class) for that user. * (an instance of the StoredUserData class) for that user.
......
...@@ -40,7 +40,8 @@ class ConsultationBooking extends SimpleORMap implements PrivacyObject ...@@ -40,7 +40,8 @@ class ConsultationBooking extends SimpleORMap implements PrivacyObject
'on_delete' => 'delete', 'on_delete' => 'delete',
]; ];
$config['registered_callbacks']['before_create'][] = function ($booking) { // Create student event
$config['registered_callbacks']['before_create'][] = function (ConsultationBooking $booking) {
setTempLanguage($booking->user_id); setTempLanguage($booking->user_id);
$event = $booking->slot->createEvent($booking->user); $event = $booking->slot->createEvent($booking->user);
...@@ -57,41 +58,37 @@ class ConsultationBooking extends SimpleORMap implements PrivacyObject ...@@ -57,41 +58,37 @@ class ConsultationBooking extends SimpleORMap implements PrivacyObject
$booking->student_event_id = $event->id; $booking->student_event_id = $event->id;
}; };
$config['registered_callbacks']['after_create'][] = function ($booking) { $config['registered_callbacks']['after_create'][] = function (ConsultationBooking $booking) {
ConsultationMailer::sendBookingMessageToUser($booking); ConsultationMailer::sendBookingMessageToUser($booking);
ConsultationMailer::sendBookingMessageToResponsibilities($booking);
$responsible_persons = $booking->slot->block->responsible_persons;
if (!in_array($GLOBALS['user']->id, $responsible_persons)) {
ConsultationMailer::sendBookingMessageToTeacher($booking);
}
}; };
$config['registered_callbacks']['before_store'][] = function ($booking) { $config['registered_callbacks']['before_store'][] = function (ConsultationBooking $booking) {
if (!$booking->isNew() && $booking->isFieldDirty('reason')) { if (!$booking->isNew() && $booking->isFieldDirty('reason')) {
if ($GLOBALS['user']->id !== $booking->user_id) { if ($GLOBALS['user']->id !== $booking->user_id) {
ConsultationMailer::sendReasonMessage($booking,$booking->user); ConsultationMailer::sendReasonMessage($booking,$booking->user);
} }
$responsible_persons = $booking->slot->block->responsible_persons; $responsible_persons = $booking->slot->block->responsible_persons;
if (!in_array($GLOBALS['user']->id, $responsible_persons)) {
foreach ($responsible_persons as $user) { foreach ($responsible_persons as $user) {
if ($GLOBALS['user']->id !== $user->id) {
ConsultationMailer::sendReasonMessage($booking, $user); ConsultationMailer::sendReasonMessage($booking, $user);
} }
} }
} }
}; };
$config['registered_callbacks']['after_store'][] = function ($booking) { $config['registered_callbacks']['after_store'][] = function (ConsultationBooking $booking) {
if ($booking->event) { if ($booking->event) {
$booking->event->description = $booking->reason; $booking->event->description = $booking->reason;
$booking->event->store(); $booking->event->store();
} }
$booking->slot->updateEvent(); $booking->slot->updateEvents();
}; };
$config['registered_callbacks']['after_delete'][] = function ($booking) { $config['registered_callbacks']['after_delete'][] = function (ConsultationBooking $booking) {
$booking->slot->updateEvent(); $booking->slot->updateEvents();
}; };
parent::configure($config); parent::configure($config);
...@@ -103,9 +100,7 @@ class ConsultationBooking extends SimpleORMap implements PrivacyObject ...@@ -103,9 +100,7 @@ class ConsultationBooking extends SimpleORMap implements PrivacyObject
ConsultationMailer::sendCancelMessageToUser($this, $reason); ConsultationMailer::sendCancelMessageToUser($this, $reason);
} }
if (!in_array($GLOBALS['user']->id, $this->slot->block->responsible_persons)) { ConsultationMailer::sendCancelMessageToResponsibilities($this, $reason);
ConsultationMailer::sendCancelMessageToTeacher($this, $reason);
}
return $this->delete() ? 1 : 0; return $this->delete() ? 1 : 0;
} }
......
<?php
/**
* @author Jan-Hendrik Willms <tleilax+studip@gmail.com>
* @license GPL2 or any later version
* @since Stud.IP 5.1
*
* @property int slot_id database column
* @property int id alias column for slot_id
* @property string user_id database column
* @property string event_id database column
* @property int mkdate database column
* @property ConsultationSlot slot belongs_to ConsultationSlot
* @property EventData event belongs_to Event
*/
class ConsultationEvent extends SimpleORMap
{
protected static function configure($config = [])
{
$config['db_table'] = 'consultation_events';
$config['belongs_to']['slot'] = [
'class_name' => ConsultationSlot::class,
'foreign_key' => 'slot_id',
];
$config['belongs_to']['event'] = [
'class_name' => EventData::class,
'foreign_key' => 'event_id',
'assoc_foreign_key' => 'event_id',
'on_delete' => 'delete',
];
parent::configure($config);
}
}
<?php
/**
* @author Jan-Hendrik Willms <tleilax+studip@gmail.com>
* @license GPL2 or any later version
* @since Stud.IP 5.1
*
* @property int block_id database column
* @property int id alias column for block_id
* @property string range_id database column
* @property string range_type database column
* @property int mkdate database column
*/
class ConsultationResponsibility extends SimpleORMap
{
protected static function configure($config = [])
{
$config['db_table'] = 'consultation_responsibilities';
$config['belongs_to']['block'] = [
'class_name' => ConsultationBlock::class,
'foreign_key' => 'block_id',
];
parent::configure($config);
}
/**
* Returns the name of the associated responsibility.
*
* @return string
* @throws Exception
*/
public function getName()
{
if ($this->range_type === 'user') {
return User::find($this->range_id)->getFullName();
}
if ($this->range_type === 'statusgroup') {
return Statusgruppen::find($this->range_id)->getName();
}
if ($this->range_type === 'institute') {
return Institute::find($this->range_id)->getFullName();
}
throw new Exception('Unknown range type');
}
/**
* Returns an url to the associated responsibility.
*
* @return string
* @throws Exception
*/
public function getURL()
{
if ($this->range_type === 'user') {
$user = User::find($this->range_id);
return URLHelper::getURL('dispatch.php/profile', ['username' => $user->username], true);
}
// TODO: Check if staff tab is activated and link to that
if ($this->range_type === 'statusgroup') {
$institute = Statusgruppen::find($this->range_id)->institute;
return URLHelper::getURL('dispatch.php/institute/overview', ['auswahl' => $institute->id], true);
}
if ($this->range_type === 'institute') {
return URLHelper::getURL('dispatch.php/institute/overview', ['auswahl' => $this->range_id], true);
}
throw new Exception('Unknown range type');
}
/**
* Returns all users belonging to the associated responsibility.
*
* @return array
* @throws Exception
*/
public function getUsers()
{
if ($this->range_type === 'user') {
return [User::find($this->range_id)];
}
if ($this->range_type === 'statusgroup') {
$group = Statusgruppen::find($this->range_id);
return self::getStatusgroupResponsibilities($group);
}
if ($this->range_type === 'institute') {
$institute = Institute::find($this->range_id);
return self::getInstituteResponsibilites($institute);
}
throw new Exception('Unknown range type');
}
/**
* Returns all responsible users for a course.
*
* @param Course $course
* @return array
*/
public static function getCourseResponsibilities(Course $course)
{
return $course->getMembersWithStatus('tutor dozent', true)->pluck('user');
}
/**
* Returns all responsible users for a status group.
*
* @param Statusgruppen $group
* @return array
*/
public static function getStatusgroupResponsibilities(Statusgruppen $group)
{
return $group->members->pluck('user');
}
/**
* Returns all responsible users for an institute.
*
* @param Institute $institute
* @return array
*/
public static function getInstituteResponsibilites(Institute $institute)
{
return $institute->members->filter(function (InstituteMember $member) {
return in_array($member->inst_perms, ['tutor', 'dozent']);
})->pluck('user');
}
}
...@@ -11,10 +11,9 @@ ...@@ -11,10 +11,9 @@
* @property string start_time database column * @property string start_time database column
* @property string end_time database column * @property string end_time database column
* @property string note database column * @property string note database column
* @property string teacher_event_id database column
* @property SimpleORMapCollection bookings has_many ConsultationBooking * @property SimpleORMapCollection bookings has_many ConsultationBooking
* @property ConsultationBlock block belongs_to ConsultationBlock * @property ConsultationBlock block belongs_to ConsultationBlock
* @property EventData event has_one EventData * @property SimpleORMapCollection events has_many EventData
*/ */
class ConsultationSlot extends SimpleORMap class ConsultationSlot extends SimpleORMap
{ {
...@@ -30,24 +29,20 @@ class ConsultationSlot extends SimpleORMap ...@@ -30,24 +29,20 @@ class ConsultationSlot extends SimpleORMap
'class_name' => ConsultationBlock::class, 'class_name' => ConsultationBlock::class,
'foreign_key' => 'block_id', 'foreign_key' => 'block_id',
]; ];
$config['has_one']['event'] = [
'class_name' => EventData::class,
'foreign_key' => 'teacher_event_id',
'assoc_foreign_key' => 'event_id',
'on_delete' => 'delete',
];
$config['has_many']['bookings'] = [ $config['has_many']['bookings'] = [
'class_name' => ConsultationBooking::class, 'class_name' => ConsultationBooking::class,
'assoc_foreign_key' => 'slot_id', 'assoc_foreign_key' => 'slot_id',
'on_store' => 'store', 'on_store' => 'store',
'on_delete' => 'delete', 'on_delete' => 'delete',
]; ];
$config['has_many']['events'] = [
'class_name' => ConsultationEvent::class,
'assoc_foreign_key' => 'slot_id',
'on_delete' => 'delete',
];
$config['registered_callbacks']['before_create'][] = function ($slot) { $config['registered_callbacks']['before_create'][] = function (ConsultationSlot $slot) {
if ($slot->block->calendar_events && $slot->block->range_type === 'user') { $slot->updateEvents();
$slot->teacher_event_id = $slot->createEvent($slot->block->range)->id;
$slot->updateEvent();
}
}; };
$config['registered_callbacks']['after_delete'][] = function ($slot) { $config['registered_callbacks']['after_delete'][] = function ($slot) {
$block = $slot->block; $block = $slot->block;
...@@ -196,69 +191,81 @@ class ConsultationSlot extends SimpleORMap ...@@ -196,69 +191,81 @@ class ConsultationSlot extends SimpleORMap
* Updates the teacher event that belongs to the slot. This will either be * Updates the teacher event that belongs to the slot. This will either be
* set to be unoccupied, occupied by only one user or by a group of user. * set to be unoccupied, occupied by only one user or by a group of user.
*/ */
public function updateEvent() public function updateEvents()
{ {
if ($this->block->range_type !== 'user') {
return;
}
// If no range is associated, remove the event // If no range is associated, remove the event
if (!$this->block->range) { if (!$this->block->range) {
return $this->removeEvent(); $this->events->delete();
return;
} }
if (count($this->bookings) === 0 && !$this->block->calendar_events) { if (count($this->bookings) === 0 && !$this->block->calendar_events) {
return $this->removeEvent(); $this->events->delete();
return;
} }
$event = $this->event; // Get responsible user ids
if (!$event) { $responsible_ids = array_map(
$event = $this->createEvent($this->block->range); function (User $user) {
return $user->id;
},
$this->block->responsible_persons
);
$this->teacher_event_id = $event->id; // Remove events for no longer responsible users
$this->store(); foreach ($this->events as $event) {
if (!in_array($event->user_id, $responsible_ids)) {
$event->delete();
} }
}
// Add events for missing responsible users
$missing = array_diff($responsible_ids, $this->events->pluck('user_id'));
foreach ($missing as $user_id) {
$event = $this->createEvent(User::find($user_id));
ConsultationEvent::create([
'slot_id' => $this->id,
'user_id' => $user_id,
'event_id' => $event->id,
]);
}
// Reset relation in order to account to the above changes
$this->resetRelation('events');
setTempLanguage($this->block->range_id); foreach ($this->events as $event) {
setTempLanguage($event->user_id);
if (count($this->bookings) > 0) { if (count($this->bookings) > 0) {
$event->category_intern = 1; $event->event->category_intern = 1;
if (count($this->bookings) === 1) { if (count($this->bookings) === 1) {
$booking = $this->bookings->first(); $booking = $this->bookings->first();
$event->summary = sprintf( $event->event->summary = sprintf(
_('Termin mit %s'), _('Termin mit %s'),
$booking->user->getFullName() $booking->user->getFullName()
); );
$event->description = $booking->reason; $event->event->description = $booking->reason;
} else { } else {
$event->summary = sprintf( $event->event->summary = sprintf(
_('Termin mit %u Personen'), _('Termin mit %u Personen'),
count($this->bookings) count($this->bookings)
); );
$event->description = implode("\n\n----\n\n", $this->bookings->map(function ($booking) { $event->event->description = implode("\n\n----\n\n", $this->bookings->map(function ($booking) {
return "- {$booking->user->getFullName()}:\n{$booking->reason}"; return "- {$booking->user->getFullName()}:\n{$booking->reason}";
})); }));
} }
} else { } else {
$event->category_intern = 9; $event->event->category_intern = 9;
$event->summary = _('Freier Termin'); $event->event->summary = _('Freier Termin');
$event->description = _('Dieser Termin ist noch nicht belegt.'); $event->event->description = _('Dieser Termin ist noch nicht belegt.');
} }
restoreLanguage(); $event->event->store();
$event->store(); restoreLanguage();
}
public function removeEvent()
{
if ($this->event) {
$this->event->delete();
$this->teacher_event_id = null;
$this->store();
} }
} }
} }
...@@ -449,7 +449,7 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe ...@@ -449,7 +449,7 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe
* *
* @param String|Array $status the status to filter with * @param String|Array $status the status to filter with
* @param bool $as_collection return collection instead of array? * @param bool $as_collection return collection instead of array?
* @return Array an array of all those members. * @return Array|SimpleCollection an array of all those members.
*/ */
public function getMembersWithStatus($status, $as_collection = false) public function getMembersWithStatus($status, $as_collection = false)
{ {
......
...@@ -41,6 +41,87 @@ ...@@ -41,6 +41,87 @@
class Institute extends SimpleORMap implements Range class Institute extends SimpleORMap implements Range
{ {
protected static function configure($config = [])
{
$config['db_table'] = 'Institute';
$config['additional_fields']['is_fak']['get'] = 'isFaculty';
$config['has_many']['members'] = [
'class_name' => InstituteMember::class,
'assoc_func' => 'findByInstitute',
'on_delete' => 'delete',
'on_store' => 'store',
];
$config['has_many']['home_courses'] = [
'class_name' => Course::class,
'on_delete' => 'delete',
'on_store' => 'store',
];
$config['has_many']['sub_institutes'] = [
'class_name' => Institute::class,
'assoc_foreign_key' => 'fakultaets_id',
'assoc_func' => 'findByFaculty',
'on_delete' => 'delete',
'on_store' => 'store',
];
$config['has_many']['datafields'] = [
'class_name' => DatafieldEntryModel::class,
'assoc_foreign_key' =>
function($model,$params) {
$model->setValue('range_id', $params[0]->id);
},
'assoc_func' => 'findByModel',
'on_delete' => 'delete',
'on_store' => 'store',
'foreign_key' =>
function($i) {
return [$i];
}
];
$config['belongs_to']['faculty'] = [
'class_name' => Institute::class,
'foreign_key' => 'fakultaets_id',
];
$config['has_and_belongs_to_many']['courses'] = [
'class_name' => Course::class,
'thru_table' => 'seminar_inst',
'on_delete' => 'delete',
'on_store' => 'store',
];
$config['has_many']['scm'] = [
'class_name' => StudipScmEntry::class,
'assoc_foreign_key' => 'range_id',
'on_delete' => 'delete',
'on_store' => 'store',
];
$config['has_many']['status_groups'] = [
'class_name' => Statusgruppen::class,
'assoc_foreign_key' => 'range_id',
'on_delete' => 'delete',
'on_store' => 'store',
'order_by' => 'ORDER BY position ASC',
];
$config['has_many']['blubberthreads'] = [
'class_name' => BlubberThread::class,
'assoc_func' => 'findByInstitut',
'on_delete' => 'delete',
'on_store' => 'store',
];
$config['has_many']['tools'] = [
'class_name' => ToolActivation::class,
'assoc_foreign_key' => 'range_id',
'order_by' => 'ORDER BY position',
'on_delete' => 'delete',
];
$config['additional_fields']['all_status_groups']['get'] = function ($institute) {
return Statusgruppen::findAllByRangeId($institute->id, true);
};
$config['i18n_fields']['name'] = true;
$config['registered_callbacks']['after_create'][] = 'setDefaultTools';
parent::configure($config);
}
/** /**
* Returns the currently active course or false if none is active. * Returns the currently active course or false if none is active.
...@@ -60,7 +141,7 @@ class Institute extends SimpleORMap implements Range ...@@ -60,7 +141,7 @@ class Institute extends SimpleORMap implements Range
* @param string $fakultaets_id * @param string $fakultaets_id
* @return array * @return array
*/ */
static function findByFaculty($fakultaets_id) public static function findByFaculty($fakultaets_id)
{ {
return self::findBySQL("fakultaets_id=? AND fakultaets_id <> institut_id ORDER BY Name ASC", [$fakultaets_id]); return self::findBySQL("fakultaets_id=? AND fakultaets_id <> institut_id ORDER BY Name ASC", [$fakultaets_id]);
} }
...@@ -69,7 +150,7 @@ class Institute extends SimpleORMap implements Range ...@@ -69,7 +150,7 @@ class Institute extends SimpleORMap implements Range
* returns an array of all institutes ordered by faculties and name * returns an array of all institutes ordered by faculties and name
* @return array * @return array
*/ */
static function getInstitutes() public static function getInstitutes()
{ {
$db = DBManager::get(); $db = DBManager::get();
$result = $db->query("SELECT Institute.Institut_id, Institute.Name, IF(Institute.Institut_id=Institute.fakultaets_id,1,0) AS is_fak " . $result = $db->query("SELECT Institute.Institut_id, Institute.Name, IF(Institute.Institut_id=Institute.fakultaets_id,1,0) AS is_fak " .
...@@ -82,10 +163,12 @@ class Institute extends SimpleORMap implements Range ...@@ -82,10 +163,12 @@ class Institute extends SimpleORMap implements Range
/** /**
* returns an array of all institutes to which the given user belongs, * returns an array of all institutes to which the given user belongs,
* ordered by faculties and name. The user role for each institute is included * ordered by faculties and name. The user role for each institute is included
*
* @param string $user_id if omitted, the current user is used * @param string $user_id if omitted, the current user is used
*
* @return array * @return array
*/ */
static function getMyInstitutes($user_id = NULL) public static function getMyInstitutes($user_id = NULL)
{ {
global $perm, $user; global $perm, $user;
if (!$user_id) { if (!$user_id) {
...@@ -125,94 +208,9 @@ class Institute extends SimpleORMap implements Range ...@@ -125,94 +208,9 @@ class Institute extends SimpleORMap implements Range
return $result; return $result;
} }
/** public function isFaculty()
*
*/
protected static function configure($config = [])
{
$config['db_table'] = 'Institute';
$config['additional_fields']['is_fak']['get'] = 'isFaculty';
$config['has_many']['members'] = [
'class_name' => 'InstituteMember',
'assoc_func' => 'findByInstitute',
'on_delete' => 'delete',
'on_store' => 'store',
];
$config['has_many']['home_courses'] = [
'class_name' => 'Course',
'on_delete' => 'delete',
'on_store' => 'store',
];
$config['has_many']['sub_institutes'] = [
'class_name' => 'Institute',
'assoc_foreign_key' => 'fakultaets_id',
'assoc_func' => 'findByFaculty',
'on_delete' => 'delete',
'on_store' => 'store',
];
$config['has_many']['datafields'] = [
'class_name' => 'DatafieldEntryModel',
'assoc_foreign_key' =>
function($model,$params) {
$model->setValue('range_id', $params[0]->id);
},
'assoc_func' => 'findByModel',
'on_delete' => 'delete',
'on_store' => 'store',
'foreign_key' =>
function($i) {
return [$i];
}
];
$config['belongs_to']['faculty'] = [
'class_name' => 'Institute',
'foreign_key' => 'fakultaets_id',
];
$config['has_and_belongs_to_many']['courses'] = [
'class_name' => 'Course',
'thru_table' => 'seminar_inst',
'on_delete' => 'delete',
'on_store' => 'store',
];
$config['has_many']['scm'] = [
'class_name' => 'StudipScmEntry',
'assoc_foreign_key' => 'range_id',
'on_delete' => 'delete',
'on_store' => 'store',
];
$config['has_many']['status_groups'] = [
'class_name' => 'Statusgruppen',
'assoc_foreign_key' => 'range_id',
'on_delete' => 'delete',
'on_store' => 'store',
'order_by' => 'ORDER BY position ASC',
];
$config['has_many']['blubberthreads'] = [
'class_name' => 'BlubberThread',
'assoc_func' => 'findByInstitut',
'on_delete' => 'delete',
'on_store' => 'store',
];
$config['has_many']['tools'] = [
'class_name' => 'ToolActivation',
'assoc_foreign_key' => 'range_id',
'order_by' => 'ORDER BY position',
'on_delete' => 'delete'
];
$config['additional_fields']['all_status_groups']['get'] = function ($institute) {
return Statusgruppen::findAllByRangeId($institute->id, true);
};
$config['i18n_fields']['name'] = true;
$config['registered_callbacks']['after_create'][] = 'setDefaultTools';
parent::configure($config);
}
function isFaculty()
{ {
return $this->fakultaets_id == $this->institut_id; return $this->fakultaets_id === $this->institut_id;
} }
/** /**
...@@ -221,7 +219,8 @@ class Institute extends SimpleORMap implements Range ...@@ -221,7 +219,8 @@ class Institute extends SimpleORMap implements Range
* @param string formatting template name * @param string formatting template name
* @return string Fullname * @return string Fullname
*/ */
public function getFullname($format = 'default') { public function getFullname($format = 'default'): string
{
$template['type-name'] = '%2$s: %1$s'; $template['type-name'] = '%2$s: %1$s';
if ($format === 'default' || !isset($template[$format])) { if ($format === 'default' || !isset($template[$format])) {
$format = 'type-name'; $format = 'type-name';
...@@ -240,7 +239,7 @@ class Institute extends SimpleORMap implements Range ...@@ -240,7 +239,7 @@ class Institute extends SimpleORMap implements Range
* *
* @return string * @return string
*/ */
public function describeRange() public function describeRange(): string
{ {
return _('Einrichtung'); return _('Einrichtung');
} }
...@@ -250,7 +249,7 @@ class Institute extends SimpleORMap implements Range ...@@ -250,7 +249,7 @@ class Institute extends SimpleORMap implements Range
* *
* @return string * @return string
*/ */
public function getRangeType() public function getRangeType(): string
{ {
return 'institute'; return 'institute';
} }
...@@ -280,7 +279,7 @@ class Institute extends SimpleORMap implements Range ...@@ -280,7 +279,7 @@ class Institute extends SimpleORMap implements Range
* @return bool * @return bool
* @todo Check permissions * @todo Check permissions
*/ */
public function isAccessibleToUser($user_id = null) public function isAccessibleToUser($user_id = null): bool
{ {
return true; return true;
} }
...@@ -292,7 +291,7 @@ class Institute extends SimpleORMap implements Range ...@@ -292,7 +291,7 @@ class Institute extends SimpleORMap implements Range
* @return bool * @return bool
* @todo Check permissions * @todo Check permissions
*/ */
public function isEditableByUser($user_id = null) public function isEditableByUser($user_id = null): bool
{ {
if ($user_id === null) { if ($user_id === null) {
$user_id = $GLOBALS['user']->id; $user_id = $GLOBALS['user']->id;
...@@ -332,7 +331,7 @@ class Institute extends SimpleORMap implements Range ...@@ -332,7 +331,7 @@ class Institute extends SimpleORMap implements Range
* @param $name string name of tool / plugin * @param $name string name of tool / plugin
* @return bool * @return bool
*/ */
public function isToolActive($name) public function isToolActive($name): bool
{ {
$plugin = PluginEngine::getPlugin($name); $plugin = PluginEngine::getPlugin($name);
return $plugin && $this->tools->findOneby('plugin_id', $plugin->getPluginId()); return $plugin && $this->tools->findOneby('plugin_id', $plugin->getPluginId());
......
...@@ -30,11 +30,11 @@ class StatusgruppeUser extends SimpleORMap implements PrivacyObject ...@@ -30,11 +30,11 @@ class StatusgruppeUser extends SimpleORMap implements PrivacyObject
{ {
$config['db_table'] = 'statusgruppe_user'; $config['db_table'] = 'statusgruppe_user';
$config['belongs_to']['group'] = [ $config['belongs_to']['group'] = [
'class_name' => 'Statusgruppen', 'class_name' => Statusgruppen::class,
'foreign_key' => 'statusgruppe_id', 'foreign_key' => 'statusgruppe_id',
]; ];
$config['belongs_to']['user'] = [ $config['belongs_to']['user'] = [
'class_name' => 'User', 'class_name' => User::class,
'foreign_key' => 'user_id', 'foreign_key' => 'user_id',
]; ];
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment