Skip to content
Snippets Groups Projects
Commit b2656cae authored by Peter Thienel's avatar Peter Thienel
Browse files

StEP 1800 closes #1800

Closes #1800

Merge request !1185
parent fb9b5159
No related branches found
No related tags found
No related merge requests found
Showing
with 1468 additions and 0 deletions
<?php
/**
* extern.php - administration controller for system-wide external pages
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* @author Peter Thienel <thienel@data-quest.de>
* @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
* @category Stud.IP
* @package extern
* @since 5.5
*/
class Admin_ExternController extends AuthenticatedController
{
protected $range;
protected $template_path;
/**
* @see PluginController::before_filter()
*/
public function before_filter(&$action, &$args)
{
parent::before_filter($action, $args);
$this->checkPerm();
$this->init();
$this->setSidebar();
}
/**
* Initialize the controller.
*/
protected function init()
{
$this->range = 'studip';
$nav = Navigation::getItem('admin/locations/external');
if ($nav) {
$nav->setActive(true);
}
$this->getSystemWideConfigTypes();
$this->config_types['PersBrowse'] = [
'name' => _('Personen-Browser'),
'description' => _('Personal der Einrichtungen'),
'icon' => 'person',
'template' => 'admin/extern/extern_config/persbrowse'
];
$this->fetchPlugins(true);
PageLayout::setTitle(_('Externe Seiten (Systemweit)'));
}
/**
* Action to show index page.
*/
public function index_action()
{
$configs = [];
$count_not_migrated = 0;
ExternPageConfig::findEachBySQL(
function ($c) use (&$configs, &$count_not_migrated) {
$configs[$c->type][] = $c;
if (isset($c->conf['not_fixed_after_migration'])) {
$count_not_migrated++;
}
},
"range_id = ?", [$this->range]
);
$this->configs = $configs;
if ($count_not_migrated > 0) {
PageLayout::postInfo(
_('Die mit einem Ausrufezeichen versehenen Konfigurationen müssen eventuell überarbeitet werden.'),
[
_('Der Aufbau der Templates hat sich in der aktuellen Stud.IP-Version geändert.'),
_('Nach dem Speichern der gekennzeichneten Templates wird die Markierung entfernt.')
]
);
}
$actions_widget = Sidebar::get()->getWidget('actions');
$actions_widget->addLink(
_('Konfiguration hochladen'),
$this->uploadURL(),
Icon::create('upload'),
['data-dialog' => 'size=auto']
);
$this->render_template('institute/extern/index', $this->layout);
}
/**
* Shows dialog to select a new page configuration
*/
public function new_action()
{
PageLayout::setTitle(_('Neue externe Seite anlegen'));
$this->render_template('institute/extern/new', $this->layout);
}
/**
* Create a new configuration or edit an existing one.
*
* @param string $type_id The type of the configuration.
* @param string $config_id The id of the configuration.
* @throws AccessDeniedException
* @throws InvalidSecurityTokenException
* @throws MethodNotAllowedException
*/
public function edit_action(string $type_id, string $config_id = '')
{
$this->load($type_id, $config_id);
$actions_widget = Sidebar::get()->getWidget('actions');
$actions_widget->addLink(
_('Vorschau anzeigen'),
$this->url_for('extern/index', $this->config->id),
Icon::create('log'),
['target' => '_blank']
);
$actions_widget->addLink(
_('Informationen anzeigen'),
$this->infoURL($this->config->id),
Icon::create('infopage'),
['data-dialog' => 'size=auto']
);
$actions_widget->addLink(
_('Konfiguration herunterladen'),
$this->downloadURL($this->config->id),
Icon::create('download')
);
$actions_widget->addLink(
_('Konfiguration hochladen'),
$this->uploadURL($this->config->id),
Icon::create('upload'),
['data-dialog' => 'size=auto']
);
$this->render_template($this->config_types[$type_id]['template'], $this->layout);
}
/**
* Action to store an external page with configuration.
*
* @param string $type_id The type of the external page.
* @param string $config_id The id of the configuration.
* @throws AccessDeniedException
* @throws InvalidSecurityTokenException
* @throws MethodNotAllowedException
*/
public function store_action(string $type_id, string $config_id = '')
{
$this->load($type_id, $config_id);
if (Request::isPost()) {
CSRFProtection::verifyUnsafeRequest();
$this->page->conf = Request::extract(($this->page->getConfigFields()));
$this->page->name = Request::get('name');
$this->page->description = Request::get('description');
$this->page->template = Request::get('template');
if ($this->page->store()) {
if ($this->page->page_config->isNew()) {
PageLayout::postSuccess(sprintf(
_('Eine neue externe Seite "%$1s" vom Typ %$2s wurde angelegt.'),
htmlReady($this->page->name),
htmlReady($this->page->type)
));
} else {
PageLayout::postSuccess(
sprintf(_('Die Konfiguration der externen Seite "%s" wurde gespeichert.'),
htmlReady($this->page->name)
));
}
} else {
PageLayout::postInfo(_('Es wurden keine Änderungen vorgenommen'));
}
if (Request::submitted('store_cancel')) {
$this->redirect($this->indexURL(['open_type' => $type_id]));
return;
}
}
$this->redirect($this->editURL($type_id, $this->page->id));
}
/**
* Loads the configuration to edit or store.
*
* @param string $type_id The type of the external page.
* @param string $config_id The id of the external page.
* @throws AccessDeniedException
*/
protected function load(string $type_id, string $config_id = '')
{
if (!$config_id) {
if (!in_array($type_id, array_keys($this->config_types))) {
throw new AccessDeniedException();
}
$this->config = new ExternPageConfig();
$this->config->type = $type_id;
$this->config->range_id = $this->range;
} else {
$this->config = ExternPageConfig::find($config_id);
if ($this->config->range_id === 'studip') {
$GLOBALS['perm']->check('root');
$have_perm = true;
} else {
$have_perm = $GLOBALS['perm']->have_studip_perm('admin', $this->config->range_id);
}
if (!$this->config || !$have_perm) {
throw new AccessDeniedException();
}
}
$this->page = ExternPage::get($this->config);
}
/**
* Deletes a configuration.
*
* @param string $config_id The id of the configuration to delete.
* @throws AccessDeniedException
* @throws InvalidSecurityTokenException
* @throws MethodNotAllowedException
*/
public function delete_action(string $config_id)
{
$config_type = '';
if (Request::isPost()) {
CSRFProtection::verifyUnsafeRequest();
$config = ExternPageConfig::find($config_id);
if ($config->range_id === 'studip') {
$GLOBALS['perm']->check('root');
$have_perm = true;
} else {
$have_perm = $GLOBALS['perm']->have_studip_perm('admin', $config->range_id);
}
if (!$config || !$have_perm) {
throw new AccessDeniedException();
}
if ($config) {
$config_name = $config->name;
$config_type = $config->type;
if ($config->delete()) {
PageLayout::postSuccess(
sprintf(_('Die Konfiguration "%s" wurde gelöscht.'), htmlReady($config_name))
);
}
}
}
$this->redirect($this->indexURL(['open_type' => $config_type]));
}
/**
* Show dialog with information about the given configuration.
*
* @param $config_id
*/
public function info_action(string $config_id)
{
$this->page = ExternPage::get(ExternPageConfig::find($config_id));
if ($this->page->author) {
$this->author = '<a href="'
. URLHelper::getLink('dispatch.php/profile', ['username' => $this->page->author->username])
. '">'
. htmlReady($this->page->author)
. '</a>';
} else {
$this->author = _('unbekannt');
}
if ($this->page->editor) {
$this->editor = '<a href="'
. URLHelper::getLink('dispatch.php/profile', ['username' => $this->page->editor->username])
. '">'
. htmlReady($this->page->editor)
. '</a>';
} else {
$this->editor = _('unbekannt');
}
PageLayout::setHelpKeyword('Basis.ExterneSeiten' . $this->page->type);
$this->datafields = $this->page->getDataFields();
$this->render_template('institute/extern/info', $this->layout);
}
/**
* Action to download given configuration.
*
* @param $config_id
*/
public function download_action(string $config_id)
{
$config = ExternPageConfig::find($config_id);
$perm = $GLOBALS['perm']->have_studip_perm('admin', $config->range_id)
|| ($GLOBALS['perm']->have_perm('root') && $config->range_id === 'studip');
if (!$config || !$perm) {
throw new AccessDeniedException();
}
$this->response->add_header(
'Content-Disposition',
'attachment; ' . encode_header_parameter('filename', $config->name . '.cfg')
);
$this->render_json($config->toArray('type name description conf template'));
}
/**
* Action to create a new configuration from uploaded file.
*/
public function upload_action()
{
$this->render_template('institute/extern/upload', $this->layout);
}
/**
* Action to import a configuration as json file.
*
* @return void
* @throws InvalidSecurityTokenException
* @throws MethodNotAllowedException
*/
public function import_action()
{
if (Request::submitted('import')) {
$this->config_name = Request::get('config_name', '');
CSRFProtection::verifyUnsafeRequest();
$file = $_FILES['config_file'];
if (!$file) {
PageLayout::postError(_('Es wurde keine Datei ausgewählt!'));
$this->redirect($this->uploadURL());
return;
}
$config_data = json_decode(file_get_contents($file['tmp_name']));
if (!$config_data) {
PageLayout::postError(_('Die Datei hat ein ungültiges Format!'));
$this->redirect($this->uploadURL());
return;
}
$config = new ExternPageConfig();
$fields = [
'name',
'description',
'conf',
'template',
'type',
];
foreach ($fields as $field) {
if (isset($config_data->$field)) {
$config->$field = $config_data->$field;
} else {
PageLayout::postError(_('Die Datei kann nicht importiert werden!'));
$this->redirect($this->uploadURL());
return;
}
}
if (!in_array($config->type, array_keys($this->config_types))) {
PageLayout::postError(_('Der Typ der Konfiguration ist ungültig!'));
$this->redirect($this->uploadURL());
return;
}
if (trim($this->config_name)) {
$config->name = $this->config_name;
}
$config->range_id = $this->range;
$config->author_id = $config->editor_id = $GLOBALS['user']->id;
$config->store();
PageLayout::postSuccess(
sprintf(_('Die Konfiguration "%s" wurde erfolgreich importiert.'),
htmlReady($config->name)
));
}
$this->relocate($this->indexURL(['open_type' => $config->type]));
}
/**
* Action to get study areas by search term.
*
* @param string $search_term The search term.
* @return void
*/
public function search_studyareas_action(string $search_term = '')
{
$search_term = Request::get('term', $search_term);
$paths = [];
$study_areas = StudipStudyArea::search($search_term);
foreach ((array) $study_areas as $study_area) {
if ($study_area->isHidden()) {
continue;
}
$path = $study_area->getPath(' > ');
$paths[$path] = [
'id' => $study_area->id,
'text' => $path
];
}
ksort($paths, SORT_LOCALE_STRING);
$this->render_json([
'results' => array_values($paths)
]);
}
/**
* Checks for sufficient rights.
*
* @throws AccessDeniedException
*/
protected function checkPerm()
{
if (!$GLOBALS['perm']->have_perm('root')) {
throw new AccessDeniedException();
}
}
/**
* Creates the sidebar menu.
*/
protected function setSidebar()
{
if ($this->range) {
$actions_widget = new ActionsWidget();
$actions_widget->addLink(
_('Neue externe Seite anlegen'),
$this->newURL(),
Icon::create('settings'),
['data-dialog' => 'size=870x500']
);
Sidebar::Get()->addWidget($actions_widget);
}
}
/**
* Retrofits navigation with plugins.
*
* @param bool $is_system True to fetch system-wide external page plugins.
* @return void
*/
protected function fetchPlugins(bool $is_system): void
{
$plugins = PluginEngine::getPlugins('ExternPagePlugin');
foreach ($plugins as $plugin) {
if (
$is_system === $plugin->isSystemPage()
|| !$is_system === $plugin->isInstitutePage()
) {
$nav = $plugin->getConfigurationFormNavigation();
$this->config_types[$nav->name] = [
'name' => $nav->title,
'description' => $nav->description,
'icon' => $nav->image,
'template' => $plugin->getConfigurationFormTemplate(),
];
}
}
}
/**
* Sets data for system-wide external pages.
*
* @return void
*/
protected function getSystemWideConfigTypes(): void
{
$this->config_types = [
'PersonDetails' => [
'name' => _('Personen-Details'),
'description' => _('Details zu einer Person'),
'icon' => 'person2',
'template' => 'institute/extern/extern_config/persondetails'
],
'Courses' => [
'name' => _('Veranstaltungen'),
'description' => _('Liste der Veranstaltungen'),
'icon' => 'seminar',
'template' => 'institute/extern/extern_config/courses'
],
'CourseDetails' => [
'name' => _('Veranst.-Details'),
'description' => _('Details zu einer Veranstaltung'),
'icon' => 'seminar',
'template' => 'institute/extern/extern_config/coursedetails'
],
'Timetable' => [
'name' => _('Termine'),
'description' => _('Zeiten/Termine/Themen der Veranstaltungen'),
'icon' => 'date-cycle',
'template' => 'institute/extern/extern_config/timetable'
]
];
}
}
<?php
/**
* extern.php - Controller to provide content to external pages.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* @author Peter Thienel <thienel@data-quest.de>
* @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
* @category Stud.IP
* @since 5.4
*/
class ExternController extends StudipController
{
protected $with_session = true;
/**
* Action shows rendered external page.
*
* @param string $config_id The id of the configuration of the external page to show.
* @throws Trails_DoubleRenderError
*/
public function index_action(string $config_id)
{
$config = ExternPageConfig::find($config_id);
if (!$config) {
$this->render_text(
Config::get()->EXTERN_PAGES_ERROR_MESSAGE
);
return;
}
try {
$page = ExternPage::get($config);
$page->setRequestParams();
} catch (Exception $e) {
$this->render_text(
Config::get()->EXTERN_PAGES_ERROR_MESSAGE . '<br>' . $e->getMessage()
);
return;
}
$this->render_text($page->toString());
}
}
<?php
/**
* extern.php - administration controller for external pages for institutes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* @author Peter Thienel <thienel@data-quest.de>
* @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
* @category Stud.IP
* @package extern
* @since 5.4
*/
require_once 'app/controllers/admin/extern.php';
class Institute_ExternController extends Admin_ExternController
{
/**
* @see PluginController::before_filter()
*/
public function before_filter(&$action, &$args)
{
parent::before_filter($action, $args);
if (!Institute::findCurrent()) {
require_once 'lib/admin_search.inc.php';
// TODO: We don't seem to need this since admin_search will stop the script
PageLayout::postInfo(_('Sie müssen zunächst eine Einrichtung auswählen'));
$this->redirect('institute/basicdata/index?list=TRUE');
return;
}
}
/**
* Initialize the controller.
*/
protected function init()
{
$this->range = Context::getId();
$this->template_path = 'institute/extern/extern_config/';
$nav = Navigation::getItem('admin/institute/external');
if ($nav) {
$nav->setActive(true);
}
$this->getSystemWideConfigTypes();
$this->config_types['Persons'] = [
'name' => _('Personen'),
'description' => _('Liste der Personen an einer Einrichtung'),
'icon' => 'persons2',
'template' => 'institute/extern/extern_config/persons',
];
$this->config_types['Download'] = [
'name' => _('Dateien'),
'description' => _('Liste der Dateien zum Download'),
'icon' => 'files',
'template' => 'institute/extern/extern_config/download',
];
$this->fetchPlugins(false);
PageLayout::setTitle(_('Externe Seiten (Einrichtung)'));
}
protected function checkPerm()
{
if (Context::getId() && !$GLOBALS['perm']->have_studip_perm('admin', Context::getId())) {
throw new AccessDeniedException();
}
}
}
<?php
/**
* @var Admin_ExternController $controller
* @var ExternPagePersBrowse $page
* @var ExternPageConfig $config
*/
?>
<span class="content-title">
<?= _('Konfiguration für die Ausgabe von Veranstaltungen') ?>
</span>
<form method="post" action="<?= $controller->store('PersBrowse', $config->id) ?>" class="default collapsable">
<?= CSRFProtection::tokenTag() ?>
<?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
<fieldset>
<legend>
<?= _('Angaben zum Inhalt') ?>
</legend>
<label>
<?= _('Rechtestufe in Einrichtungen') ?>
<select name="instperms[]" class="nested-select" multiple>
<? foreach ($page->getInstitutePermissionOptions() as $instperm_id => $instperm_name) : ?>
<option
value="<?= $instperm_id ?>"
<?= in_array($instperm_id, $page->instperms ?? []) ? ' selected' : '' ?>>
<?= htmlReady($instperm_name) ?>
</option>
<? endforeach ?>
</select>
</label>
<label>
<input type="checkbox" name="onlylecturers" value="1"
<?= $page->onlylecturers ? 'checked' : '' ?>>
<?= _('Nur Lehrende anzeigen.') ?>
</label>
<?= $this->render_partial('institute/extern/extern_config/_institutes_selector') ?>
</fieldset>
<?= $this->render_partial('institute/extern/extern_config/_template') ?>
<footer data-dialog-button>
<?= Studip\Button::createAccept(_('Speichern')) ?>
<?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
<?= Studip\LinkButton::createCancel(
_('Abbrechen'), $controller->url_for('institute/extern/index')
) ?>
</footer>
</form>
<colgroup>
<col style="width: 20%">
<col>
<col style="width: 80px">
<col style="width: 25%">
<col style="width: 24px">
</colgroup>
<thead>
<tr class="sortable">
<th data-sort="text"><?= _('Name') ?></th>
<th data-sort="false"><?= _('Beschreibung') ?></th>
<th data-sort="htmldata"><?= _('Letzte Änderung') ?></th>
<th data-sort="text"><?= _('Erstellt von') ?></th>
<th data-sort="false"></th>
</tr>
</thead>
<?php
/**
* @var ExternController $controller
* @var ExternPageConfig $config
*/
?>
<tr>
<td>
<strong><a href="<?= $controller->link_for('/edit', $config->type, $config->id) ?>">
<?= htmlReady($config->name) ?>
<?= isset($config->conf['not_fixed_after_migration']) ? '(!)' : '' ?>
</a></strong>
</td>
<td>
<small><?= htmlReady($config->description) ?></small>
</td>
<td data-sort-value="<?= (int) $config->chdate ?>">
<?= date('d.m.Y G:H', $config->chdate) ?>
</td>
<td>
<? if ($config->author) : ?>
<a href="<?= URLHelper::getLink('dispatch.php/profile', ['username' => $config->author->username]) ?>">
<?= htmlReady($config->author->getFullName()) ?>
</a>
<? else : ?>
<?= _('unbekannt') ?>
<? endif ?>
</td>
<td class="actions">
<?= ActionMenu::get()->addLink(
$controller->editURL($config->type, $config->id),
_('Konfiguration bearbeiten'),
Icon::create('edit')
)->addLink(
$controller->infoURL($config->id),
_('Informationen anzeigen'),
Icon::create('infopage'),
['data-dialog' => '']
)->addLink(
$controller->downloadURL($config->id),
_('Konfiguration herunterladen'),
Icon::create('download')
)->addButton(
'delete',
_('Konfiguration löschen'),
Icon::create('trash'),
[
'formaction' => $controller->deleteURL($config->id),
'title' => _('Konfiguration löschen'),
'data-confirm' => sprintf(_('Soll die Konfiguration "%s" gelöscht werden?'), htmlReady($config->name)),
'form' => 'extern-page-index'
]
)->render()
?>
</td>
</tr>
<?php
/**
* @var ExternPageConfig $config
* @var ExternPage $page
*/
?>
<fieldset>
<legend>
<?= _('Allgemeine Daten') ?>
</legend>
<label class="studiprequired" for="external_page_config_name">
<span class="textlabel">
<?= _('Name der Konfiguration') ?>
</span>
<span class="asterisk" title="<?= _('Dies ist ein Pflichtfeld') ?>" aria-hidden="true">*</span>
<input type="text"
id="external_page_config_name"
value="<?= htmlReady($config->name) ?>"
required
name="name"
maxlength="255">
</label>
<label>
<?= _('Beschreibung') ?>
<textarea name="description"><?= htmlReady($config->description) ?></textarea>
</label>
<label>
<?= _('Ausgabesprache') ?>
<select name="language">
<? foreach (Config::get()->CONTENT_LANGUAGES as $language_id => $language_data) : ?>
<option value="<?= $language_id ?>"
<?= $page->language === $language_id ? ' selected' : '' ?>>
<?= htmlReady($language_data['name']) ?>
</option>
<? endforeach ?>
</select>
</label>
<label>
<?= _('Automatisches Umkodieren der Inhalte') ?>
<?
$escaping_types = [
_('Keine Umkodierung vornehmen') => '',
_('html-konform umkodieren') => 'htmlReady',
_('xml-konform umkodieren') => 'xml',
_('json-konform umkodieren') => 'json'
]
?>
<select name="escaping">
<? foreach ($escaping_types as $escaping_name => $escaping_type) : ?>
<option value="<?= $escaping_type ?>"
<?= $page->escaping === $escaping_type ? ' selected' : '' ?>>
<?= htmlReady($escaping_name) ?>
</option>
<? endforeach ?>
</select>
</label>
</fieldset>
<?php
/**
* @var ExternPageCourses $page
*/
?>
<? $institutes = $page->getInstitutes() ?>
<? if (count($institutes) > 1) : ?>
<label>
<?= _('Einrichtungen') ?>
<select name="institutes[]" class="nested-select" multiple>
<? foreach ($institutes as $institute) : ?>
<option
class="<?= $institute['is_fak'] ? 'nested-item-header' : 'nested-item' ?>"
value="<?= htmlReady($institute['Institut_id']) ?>"
<?= in_array($institute['Institut_id'], (array) $page->institutes) ? 'selected' : '' ?>>
<?= htmlReady($institute['Name']) ?>
</option>
<? endforeach ?>
</select>
</label>
<? endif ?>
<?php
/**
* @var ExternPageCourses $page
*/
?>
<label>
<?= _('Veranstaltungstypen') ?>
<select name="semtypes[]" class="nested-select" multiple>
<? foreach (ExternPage::getGroupedSemTypes() as $class) : ?>
<option class="nested-item-header" disabled><?= htmlReady($class['name']) ?></option>
<? foreach ($class['types'] as $type) : ?>
<option
class="nested-item"
value="<?= htmlReady($type['id']) ?>"
<?= in_array($type['id'], (array) $page->semtypes) ? ' selected' : '' ?>>
<?= htmlReady("{$type['name']} ({$class['name']})") ?>
</option>
<? endforeach ?>
<? endforeach ?>
</select>
</label>
<?php
/**
* @var ExternPageCourses $page
*/
?>
<fieldset>
<legend>
<?= _('Studienbereiche') ?>
</legend>
<label>
<?= _('Anzuzeigende Studienbereiche') ?>
<?= tooltipIcon(_('Wenn keine Studienbereiche ausgewählt werden, werden alle angezeigt.')) ?>
<? $study_area_paths = $page->getStudyAreaPaths() ?>
<select name="studyareas[]" class="nested-select" id="select-study-areas" multiple>
<? foreach ($study_area_paths as $area_id => $path) : ?>
<option
value="<?= htmlReady($area_id) ?>"
selected class="nested-item"><?= htmlReady($path) ?>
</option>
<? endforeach ?>
</select>
</label>
<label>
<input type="checkbox" name="scope_kids" value="1"
<?= $page->scope_kids ? 'checked' : '' ?>>
<?= _('Unterebenen anzeigen.') ?>
</label>
</fieldset>
<?php
/**
* @var ExternPage $page
*/
?>
<fieldset>
<legend>
<?= _('Template') ?>
</legend>
<label>
<textarea name="template" placeholder="<?= _('Geben Sie hier das Template ein.') ?>"
cols="80" rows="20"><?= htmlReady($page->template) ?></textarea>
</label>
</fieldset>
<?php
/**
* @var ExternController $controller
* @var ExternPageConfig $config
*/
?>
<span class="content-title">
<?= _('Konfiguration für die Detailansicht einer Veranstaltung') ?>
</span>
<form method="post" action="<?= $controller->store('CourseDetails', $config->id) ?>" class="default collapsable">
<?= CSRFProtection::tokenTag() ?>
<?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
<fieldset>
<legend>
<?= _('Angaben zum Inhalt') ?>
</legend>
<label>
<?= _('Bereichspfad ab Ebene') ?>
<?= tooltipIcon(_('Wählen Sie, ab welcher Ebene der Bereichspfad ausgegeben werden soll.')) ?>
<input min="1" max="10" type="number" name="rangepathlevel" value="<?= $page->rangepathlevel ?? 1 ?>">
</label>
</fieldset>
<?= $this->render_partial('institute/extern/extern_config/_template') ?>
<footer data-dialog-button>
<?= Studip\Button::createAccept(_('Speichern')) ?>
<?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
<?= Studip\LinkButton::createCancel(
_('Abbrechen'), $controller->indexURL()
) ?>
</footer>
</form>
<?php
/**
* @var ExternController $controller
* @var ExternPageConfig $config
* @var ExternPageCourses $page
*/
?>
<span class="content-title">
<?= _('Konfiguration für die Ausgabe von Veranstaltungen') ?>
</span>
<form method="post" action="<?= $controller->store('Courses', $config->id) ?>" class="default collapsable">
<?= CSRFProtection::tokenTag() ?>
<?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
<fieldset>
<legend>
<?= _('Angaben zum Inhalt') ?>
</legend>
<label class="col-3">
<?= _('Gruppierung') ?>
<select name="groupby">
<? foreach ($page->getGroupingOptions() as $id => $name) : ?>
<option value="<?= $id ?>"<?= $page->groupby == $id ? ' selected' : '' ?>><?= htmlReady($name) ?></option>
<? endforeach ?>
</select>
</label>
<label>
<?= _('Startsemester') ?>
<?= tooltipIcon(_('Geben Sie das erste anzuzeigende Semester an. '
. 'Die Angaben "Vorheriges", "Aktuelles" und "Nächstes" beziehen sich immer auf das laufende Semester '
. 'und werden automatisch angepasst.')) ?>
<select name="startsem">
<? foreach ($page->getSemesterOptions() as $semester) : ?>
<option
value="<?= htmlReady($semester['id']) ?>"
<?= $page->startsem === $semester['id'] ? ' selected' : '' ?>>
<?= htmlReady($semester['name']) ?>
</option>
<? endforeach ?>
</select>
</label>
<label>
<?= _('Anzahl der anzuzeigenden Semester') ?>
<?= tooltipIcon(_('Geben Sie an, wieviele Semester (ab o.a. Startsemester) angezeigt werden sollen.')) ?>
<input type="number" min="1" name="semcount" value="<?= htmlReady($page->semcount ?: '1') ?>">
</label>
<label>
<?= _('Umschalten des aktuellen Semesters') ?>
<?= tooltipIcon(_('Geben Sie an, wieviele Wochen vor Semesterende automatisch auf das nächste Semester '
. 'umgeschaltet werden soll.')) ?>
<select name="semswitch">
<option value="0"><?= _('Am Semesterende') ?></option>
<option value="-1">
<? printf(ngettext('%s Woche vor Semesterende (Systemkonfiguration)',
'%s Wochen vor Semesterende (Systemkonfiguration)',
Config::get()->SEMESTER_TIME_SWITCH),
Config::get()->SEMESTER_TIME_SWITCH) ?>
</option>
<? foreach (range(1, 12) as $weeks) : ?>
<option value="<? $weeks ?>">
<? printf(ngettext('%s Woche vor Semesterende',
'%s Wochen vor Semesterende', $weeks),
$weeks) ?>
</option>
<? endforeach ?>
</select>
</label>
<label>
<input type="checkbox" name="participating" value="1"
<?= $page->participating ? 'checked' : '' ?>>
<?= _('Veranstaltungen beteiligter Institute anzeigen.') ?>
</label>
<?= $this->render_partial('institute/extern/extern_config/_sem_types_selector') ?>
<?= $this->render_partial('institute/extern/extern_config/_institutes_selector') ?>
</fieldset>
<?= $this->render_partial('institute/extern/extern_config/_study_areas_selector') ?>
<?= $this->render_partial('institute/extern/extern_config/_template') ?>
<footer data-dialog-button>
<?= Studip\Button::createAccept(_('Speichern')) ?>
<?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
<?= Studip\LinkButton::createCancel(
_('Abbrechen'), $controller->indexURL()
) ?>
</footer>
</form>
<?php
/**
* @var ExternController $controller
* @var ExternPageDownload $page
* @var ExternPageConfig $config
*/
?>
<span class="content-title">
<?= _('Konfiguration für eine Liste von Dateien (Download)') ?>
</span>
<form method="post" action="<?= $controller->store('Download', $config->id) ?>" class="default collapsable">
<?= CSRFProtection::tokenTag() ?>
<?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
<fieldset>
<legend>
<?= _('Angaben zum Inhalt') ?>
</legend>
<label class="col-3">
<?= _('Sortierung') ?>
<select name="sort" id="data_sort">
<? foreach ($page->getSortFields() as $sort_field => $field_name) : ?>
<option value="<?= htmlReady($sort_field) ?>"
<? if ($sort_field === $page->sort) echo 'selected'; ?>>
<?= htmlReady($field_name) ?>
</option>
<? endforeach ?>
</select>
</label>
<label>
<?= _('Ordnerauswahl') ?>
<select class="nested-select" name="folder[]" multiple>
<? foreach ($page->get_concatenated_folders() as $folder_id => $folder_name) : ?>
<option value="<?= htmlReady($folder_id) ?>"
<?= in_array($folder_id, (array) $page->folder) ? 'selected' : '' ?>>
<?= htmlReady($folder_name) ?>
</option>
<? endforeach ?>
</select>
</label>
<label>
<input type="checkbox" name="subfolders" value="1"
<?= $page->subfolders ? 'checked' : '' ?>>
<?= _('Unterordner der ausgewählten Ordner anzeigen.') ?>
</label>
</fieldset>
<?= $this->render_partial('institute/extern/extern_config/_template') ?>
<footer data-dialog-button>
<?= Studip\Button::createAccept(_('Speichern')) ?>
<?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
<?= Studip\LinkButton::createCancel(
_('Abbrechen'), $controller->indexURL()
) ?>
</footer>
</form>
<?php
/**
* @var ExternController $controller
* @var ExternPageConfig $config
* @var ExternPagePersonDetails $page
*/
?>
<span class="content-title">
<?= _('Konfiguration für die Detailansicht von Mitarbeitenden (Personal)') ?>
</span>
<form method="post" action="<?= $controller->store('PersonDetails', $config->id) ?>" class="default collapsable">
<?= CSRFProtection::tokenTag() ?>
<?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
<fieldset>
<legend>
<?= _('Angaben zum Inhalt') ?>
</legend>
<label>
<input type="checkbox" name="defaultaddr" value="1"
<?= $page->defaultaddr ? 'checked' : '' ?>>
<?= _('Standard-Adresse') ?>
<?= tooltipIcon(_('Wenn Sie diese Option wählen, wird die Standard-Adresse ausgegeben, '
. 'die jede(r) Mitarbeiter(in) bei seinen universitären Daten auswählen kann. '
. 'Wählen Sie diese Option nicht, wenn immer die Adresse der Einrichtung ausgegeben werden soll.')) ?>
</label>
</fieldset>
<fieldset>
<legend>
<?= _('Persönliche Lehrveranstaltungen') ?>
</legend>
<label>
<?= _('Startsemester') ?>
<?= tooltipIcon(_('Geben Sie das erste anzuzeigende Semester an. '
. 'Die Angaben "vorheriges", "aktuelles" und "nächstes" beziehen sich immer auf das laufende Semester '
. 'und werden automatisch angepasst.')) ?>
<select name="startsem">
<option value="previous"<?= $page->startsem === 'previous' ? ' selected' : '' ?>>
<?= _('vorheriges') ?>
</option>
<option value="current"<?= $page->startsem === 'current' ? ' selected' : '' ?>>
<?= _('aktuelles') ?>
</option>
<option value="last"<?= $page->startsem === 'last' ? ' selected' : '' ?>>
<?= _('letztes') ?>
</option>
<? foreach (array_reverse(Semester::getAll()) as $semester) : ?>
<option value="<?= $semester->id ?>"<?= $page->startsem === $semester->id ? ' selected' : '' ?>>
<?= htmlReady($semester->name) ?>
</option>
<? endforeach ?>
</select>
</label>
<label>
<?= _('Anzahl der anzuzeigenden Semester') ?>
<?= tooltipIcon(_('Geben Sie an, wieviele Semester (ab o.a. Startsemester) angezeigt werden sollen.')) ?>
<input type="number" name="semcount" value="<?= (int) $page->semcount ?>">
</label>
<label>
<?= _('Umschalten des aktuellen Semesters') ?>
<?= tooltipIcon(_('Geben Sie an, wieviele Wochen vor Semesterende automatisch auf das nächste Semester '
. 'umgeschaltet werden soll.')) ?>
<select name="semswitch">
<option value="0"<?= $page->semswitch === 0 ? ' selected' : '' ?>><?= _('Am Semesterende') ?></option>
<option value="-1"<?= $page->semswitch === -1 ? ' selected' : '' ?>>
<? printf(ngettext('%s Woche vor Semesterende (Systemkonfiguration)',
'%s Wochen vor Semesterende (Systemkonfiguration)',
Config::get()->SEMESTER_TIME_SWITCH),
Config::get()->SEMESTER_TIME_SWITCH) ?>
</option>
<? foreach (range(1, 12) as $weeks) : ?>
<option value="<?= $weeks ?>"<?= $weeks === $page->semswitch ? ' selected' : '' ?>>
<? printf(ngettext('%s Woche vor Semesterende',
'%s Wochen vor Semesterende', $weeks),
$weeks) ?>
</option>
<? endforeach ?>
</select>
</label>
<label>
<?= _('Veranstaltungskategorien') ?>
<?= tooltipIcon(_('Wählen Sie aus, welche Veranstaltungskategorien angezeigt werden sollen.')) ?>
<select class="nested-select" name="semclass[]" multiple>
<? foreach ($GLOBALS['SEM_CLASS'] as $key => $sem_class) : ?>
<? if ($sem_class['show_browse']) : ?>
<option value="<?= $key ?>"<?= in_array($key, $page->semclass) ? ' selected' : '' ?>>
<?= htmlReady($sem_class['name']) ?>
</option>
<? endif ?>
<? endforeach ?>
</select>
</label>
</fieldset>
<?= $this->render_partial('institute/extern/extern_config/_template') ?>
<footer data-dialog-button>
<?= Studip\Button::createAccept(_('Speichern')) ?>
<?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
<?= Studip\LinkButton::createCancel(
_('Abbrechen'), $controller->indexURL()
) ?>
</footer>
</form>
<?php
/**
* @var ExternController $controller
* @var ExternPageConfig $config
* @var ExternPagePersons $page
*/
?>
<span class="content-title">
<?= _('Konfiguration für eine Liste der Mitarbeitenden (Personal)') ?>
</span>
<form method="post" action="<?= $controller->store('Persons', $config->id) ?>" class="default collapsable">
<?= CSRFProtection::tokenTag() ?>
<?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
<fieldset>
<legend>
<?= _('Angaben zum Inhalt') ?>
</legend>
<label class="col-3">
<?= _('Sortierung') ?>
<select name="sort" id="data_sort">
<? foreach ($page->getSortFields() as $sort_field => $field_name) : ?>
<option value="<?= htmlReady($sort_field) ?>"
<? if ($sort_field === $page->sort) echo 'selected'; ?>>
<?= htmlReady($field_name) ?>
</option>
<? endforeach; ?>
</select>
</label>
<label>
<input type="checkbox" name="grouping" value="1"
<?= $page->grouping ? 'checked' : '' ?>>
<?= _('Gruppierung nach Funktionen/Gruppen') ?>
</label>
</fieldset>
<fieldset>
<legend>
<?= _('Ausgabe der Funktionen / Gruppen (Sichtbarkeit, alternative Gruppennamen)') ?>
</legend>
<? $full_group_names = $page->getFullGroupNames() ?>
<? if (count($full_group_names)) : ?>
<? foreach ($full_group_names as $group_id => $group_name) : ?>
<label class="col-5">
<input type="checkbox" name="groupsvisible[<?= $group_id ?>]" value="1"
<?= $page->groupsvisible[$group_id] ? 'checked' : '' ?>>
<?= htmlReady($group_name) ?>
</label>
<label class="col-5" aria-label="<?= htmlReady($group_name) ?>">
<input type="text" name="groupsalias[<?= $group_id ?>]"
value="<?= htmlReady($page->groupsalias[$group_id]) ?>"
placeholder="<? printf(_('Alternativer Gruppenname (%s)'), htmlReady($group_name)) ?>">
</label>
<? endforeach ?>
<? else : ?>
<?= _('Keine Funktionen / Gruppen an dieser Einrichtung vorhanden.') ?>
<? endif ?>
</fieldset>
<?= $this->render_partial('institute/extern/extern_config/_template') ?>
<footer data-dialog-button>
<?= Studip\Button::createAccept(_('Speichern')) ?>
<?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
<?= Studip\LinkButton::createCancel(
_('Abbrechen'),
$controller->indexURL()
) ?>
</footer>
</form>
<?php
/**
* @var ExternController $controller
* @var ExternPageConfig $config
* @var ExternPageTimetable $page
*/
?>
<span class="content-title">
<?= _('Konfiguration für die Ausgabe Veranstaltungsterminen') ?>
</span>
<form method="post" action="<?= $controller->store('Timetable', $config->id) ?>" class="default collapsable">
<?= CSRFProtection::tokenTag() ?>
<?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
<fieldset>
<legend>
<?= _('Angaben zum Inhalt') ?>
</legend>
<label>
<?= _('Startdatum') ?>
<input type="text" name="date" class="size-s" data-date-picker="" value="<?= htmlReady($page->date) ?>">
</label>
<label>
<select name="date_offset">
<? foreach ($page->getDateOffsetOptions() as $offset_key => $offset_name) : ?>
<option value="<?= $offset_key ?>"<?= $offset_key === $page->date_offset ? ' selected' : '' ?>>
<?= htmlReady($offset_name) ?>
</option>
<? endforeach ?>
</select>
</label>
<label>
<?= _('Anzahl der Zeitbereiche') ?>
<?= tooltipIcon(_('Geben Sie an, wie viele der folgenden Zeitbereiche angezeigt werden sollen.')) ?>
<input type="number" min="1" name="range_count" value="<?= htmlReady($page->range_count ?: '1') ?>">
</label>
<label>
<?= _('Anzuzeigender Zeitbereich') ?>
<select name="time_range">
<? foreach ($page->getTimeRangeOptions() as $range_key => $range_name) : ?>
<option value="<?= $range_key ?>"<?= $range_key === $page->time_range ? ' selected' : '' ?>>
<?= htmlReady($range_name) ?>
</option>
<? endforeach ?>
</select>
</label>
<label>
<?= _('Anzuzeigende Termintypen') ?>
<select name="event_types[]" class="nested-select" multiple>
<? foreach (Config::get()->TERMIN_TYP as $type_id => $event_typ) : ?>
<option value="<?= $type_id ?>"<?= in_array($type_id, (array) $page->event_types) ? ' selected' : '' ?>>
<?= htmlReady($event_typ['name']) ?>
</option>
<? endforeach ?>
</select>
</label>
<label>
<input type="checkbox" name="participating" value="1"
<?= $page->participating ? 'checked' : '' ?>>
<?= _('Veranstaltungen beteiligter Institute anzeigen.') ?>
</label>
<?= $this->render_partial('institute/extern/extern_config/_sem_types_selector') ?>
<?= $this->render_partial('institute/extern/extern_config/_institutes_selector') ?>
</fieldset>
<?= $this->render_partial('institute/extern/extern_config/_study_areas_selector') ?>
<?= $this->render_partial('institute/extern/extern_config/_template') ?>
<footer data-dialog-button>
<?= Studip\Button::createAccept(_('Speichern')) ?>
<?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
<?= Studip\LinkButton::createCancel(
_('Abbrechen'), $controller->indexURL()
) ?>
</footer>
</form>
<?php
/**
* @var Institute_ExternController $controller
* @var array $config_types
* @var ExternPageConfig[] $configs
*/
if (count($configs) == 0) :
PageLayout::postInfo(_('Es wurde noch keine externe Seite angelegt.'),
[
sprintf(_('Um eine neue externe Seite anzulegen, klicken sie %shier%s.'),
'<a href="' . $controller->new() . '" data-dialog="size=870x500">',
'</a>')
]);
else : ?>
<form id="extern-page-index" action="#" method="post">
<?= CSRFProtection::tokenTag() ?>
<section class="contentbox">
<header>
<h1>
<?= _('Externe Seiten') ?>
</h1>
</header>
<? foreach ($config_types as $type_id => $config_type): ?>
<? if ($configs[$type_id]) : ?>
<article id="<?= $type_id ?>" <? if (Request::option('open_type') === $type_id) echo 'class="open"'; ?>>
<header>
<h1>
<a href="<?= URLHelper::getLink('?#' . $type_id)?>">
<?= htmlReady($config_type['name']) ?>
(<?= count($configs[$type_id]) ?>)
</a>
</h1>
</header>
<section>
<table class="default sortable-table">
<?= $this->render_partial('institute/extern/_table-header.php') ?>
<? foreach ($configs[$type_id] as $config) : ?>
<?= $this->render_partial('institute/extern/_table-row.php', ['config' => $config]) ?>
<? endforeach ?>
</table>
</section>
</article>
<? endif ?>
<? endforeach ?>
</section>
</form>
<?php endif ?>
<?php
/**
* @var ExternPageConfig $page
* @var DataField[] $datafields
* @var string $author
* @var string $editor
*/
?>
<section class="contentbox">
<header>
<h1><?= _('Allgemeine Informationen') ?></h1>
</header>
<section>
<dl>
<dt><?= _('Modultyp') ?></dt>
<dd><?= htmlReady($page->type) ?></dd>
<dt><?= _('Name der Konfiguration') ?></dt>
<dd><?= htmlReady($page->name) ?></dd>
<dt><?= _('Erstellt am') ?></dt>
<dd><?= date('d.m.Y H:m ', $page->mkdate) . sprintf(_('durch %s'), $author) ?></dd>
<dt><?= _('Bearbeitet am') ?></dt>
<dd><?= date('d.m.Y H:m ', $page->chdate) . sprintf(_('durch %s'), $editor) ?></dd>
<dt><?= _('Beschreibung') ?></dt>
<dd><?= htmlReady($page->description) ?></dd>
<dt><?= _('Zur Hilfeseite') ?></dt>
<dd><a class="link-extern" href="<?= htmlReady(format_help_url(PageLayout::getHelpKeyword())) ?>">
<?= sprintf(_('Hilfe zur Konfiguration des Moduls "%s".'), htmlReady($page->type)) ?>
</a>
</dd>
</dl>
</section>
</section>
<section class="contentbox">
<header>
<h1><?= _('Informationen zur Verlinkung') ?></h1>
</header>
<section>
<dl>
<dt><?= _('Direkter Link') ?></dt>
<dd>
<blockquote>
<? $link = htmlReady(URLHelper::getLink('dispatch.php/extern/index/' . $page->id, null,true)) ?>
<a href="<?= $link ?>" target="_blank"><?= $link ?></a>
</blockquote>
<span style="font-size: smaller;">
<?= _('Diese Adresse können Sie in einen Link auf Ihrer Website integrieren, um auf die Ausgabe des Moduls zu verweisen.') ?>
</span>
</dd>
<dt><?= _('Mögliche URL-Parameter') ?></dt>
<dd><?= htmlReady(implode(', ', $page->getAllowedRequestParams(true))) ?></dd>
</dl>
</section>
</section>
<? if (count($datafields)) : ?>
<? $classes = DataField::getDataClass() ?>
<section class="contentbox">
<header>
<h1><?= _('Datenfelder') ?></h1>
</header>
<section>
<dl>
<? foreach ($datafields as $class_name => $datafield_class) : ?>
<? foreach ($datafield_class as $datafield) : ?>
<dt><?= htmlReady($classes[$class_name] . ': ' . $datafield->name) ?></dt>
<dd>
<?= 'DATAFIELD_' . $datafield->id ?>
<span style="font-size: smaller;"><?= htmlReady($datafield->description) ?></span>
</dd>
<? endforeach ?>
<? endforeach ?>
</dl>
<p><?= _('Hinweis: Die gelisteten Datenfelder sind eventuell nicht für alle Objekte eines Typs verfügbar.') ?></p>
</section>
</section>
<? endif ?>
<?php
/**
* @var ExternController $controller
* @var array $config_types
*/
?>
<ul class="content-items" style="padding-top: 10px;">
<? foreach ($config_types as $type_id => $config_type) : ?>
<li class="content-item">
<a class="content-item-link" href="<?= $controller->edit($type_id) ?>">
<div class="content-item-img-wrapper">
<?= Icon::create($config_type['icon'])->asImg(64) ?>
</div>
<div class="content-item-text">
<p class="content-item-title">
<?= htmlReady($config_type['name']) ?>
</p>
<p class="content-item-description">
<?= htmlReady($config_type['description']) ?>
</p>
</div>
</a>
</li>
<? endforeach ?>
</ul>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment