Quellcode: VLVZ-Modul
<?php
/* Modul zur Ausgabe der Lehrveranstaltungen
 * -----------------------------------------
 * Version : 3.5 / 05.03.2021
 * Autor   : Sandra Kahl (sandra.kahl@hrz.tu-chemnitz.de)
 *
 * BESCHREIBUNG:
 *
 * Diese Funktion gibt eine Tabelle mit den Lehrveranstaltungen aus, welche
 * ALLEN Suchkriterien entsprechen. Dabei wird standardmäßig das aktuell gültige
 * Semester aufgerufen, bei Angabe eines Semesters werden ggf. die Daten aus dem
 * Archiv des Vorlesungsverzeichnisses angezeigt. Die Funktion gibt dabei einen
 * HTML-formatierten String zurück, welcher UTF-8 kodiert ist.
 *
 * Diese Funktion verwendet direkt die API des Vorlesungsverzeichnisses und
 * die Ausgabe sollte äquivalent der Suche sein:
 * http://www.tu-chemnitz.de/verwaltung/vlvz/search/
 *
 * AUFRUF:
 * zeigeLehrveranstaltungen() ($param)
 *
 * PARAMETER UND VERWENDUNG:
 * siehe https://www.tu-chemnitz.de/verwaltung/vlvz/modul/verwendung.php
 *
 * VERSIONSGESCHICHTE
 * siehe https://www.tu-chemnitz.de/verwaltung/vlvz/modul/version.php
 */

define('VLVZ_API''https://www.tu-chemnitz.de/verwaltung/vlvz/api/v1/');
define('LIB_ROOT''/afs/tu-chemnitz.de/www/root/tu/inc/lib/');
define('TPL_ROOT''/afs/tu-chemnitz.de/www/root/tu/inc/lib/templates/');
define('APP_BASE''www.tu-chemnitz.de/verwaltung/vlvz/');

/**
 * zeigeLehrveranstaltungen()
 *
 * Ruft eine Liste mit zu den Suchparametern passenden Lehrveranstaltungen ab,
 * und zeigt diese direkt an.
 *
 * @param      $param  Assoziativer Array mit den Anzeigeparametern
 *               'name'            - Name oder Nummer der Lehrveranstaltung
 *               'dozent'          - Name des Dozenten
 *               'fakult'          - Kurzname der Fakultät
 *               'semester'        - Semester in der Kurzform (z.B. "ss19" oder "ws1819")
 *                                   zur Abfrage von LV aus vergangenen Semestern
 *                                   (default = leer, Anzeige des aktuellen Semesters)
 *                                   Für die Archivanzeige entfallen die folgenden Parameter:
 *                                   'enable_meinplan', 'disable_js', 'sort',
 *                                   'detail_in_table', 'use_vlvz_style'
 *               'enable_meinplan' - "Mein Stundenplan"-Unterstützung
 *                                   (default = false)
 *               'disable_js'      - Javascript-Unterstützung deaktivieren
 *                                   (default = false)
 *               'css_class'       - CSS-Klasse für die Tabelle
 *                                   (default = "horizontal grey")
 *               'sort'            - Sortierungsoption (default = 0)
 *                                   0 - Nach Nummer
 *                                   1 - Nach Tag und Zeit
 *               'not_found_text'  - Gibt den Text an, der bei erfolgloser Suche angezeigt wird
 *                                   (default = "Keine Lehrveranstaltung gefunden.")
 *               'detail_in_table' - Zeigt die Details direkt in der Tabelle an, ohne Detail-Link
 *                                   (default = false -> Anzeige mit Link im Overlay)
 *               'use_vlvz_style'  - Verwendet die gleichen CSS-Klassen wie das zentrale VLVZ
 *                                   falls true -> zentrales Stylesheet im Seitenkopf einbinden
 *                                   (default = false)
 *               'room_in_table' - Zeigt den Raum direkt in der Tabelle an
 *                                   (default = true)
 *               'joined_time_room' - Stellt Zeit und Raum zusammen in einer Tabellenzelle dar
 *                                   (default = false)
 *
 * @param $cacheDir Cache-Verzeichnis zum schnelleren Rendern der Veranstaltungsliste
 *
 * @return String HTMl-Ausgabe der Veranstaltungen, UTF-8 kodiert
 */
function zeigeLehrveranstaltungen($param$cacheDir '')
{
    
// TWIG-Bibliothek laden
    
if(! @include_once("Twig/autoload.php")){ require_once(LIB_ROOT 'twig/3/vendor/autoload.php'); };

    
$loader = new \Twig\Loader\FilesystemLoader(TPL_ROOT);
    
$options = array();
    if (
trim($cacheDir) !== '') {
        
$options['cache'] = trim($cacheDir);
    }
    
$twig = new \Twig\Environment($loader$options);

    
// TWIG-Filter anlegen
    
$twig_filter = new \Twig\TwigFilter('tucal_hs_detailview', function ($vnummer) {
        require_once(
'php/hs.inc');
        
$linkicon '<div style="display: block; background-image: url(\'https://' APP_BASE 'app/static/css/img/details.png\'); background-repeat: no-repeat; width: 40px; height: 40px; margin: 0; padding: 0;" title="Detailansicht öffnen"><span class="sr-only">Detailansicht öffnen</span></div>';

        return 
hs_url($linkicon'https://' APP_BASE 'veranstaltung/' $vnummer '/appview?content''Veranstaltungsdetails ' $vnummer, array('w' => '700'));
    });
    
$twig->addFilter($twig_filter);

    
// APP-BASE https bestimmen
    
$app_base 'https://' APP_BASE;

    
// Suchparameter für API vorbereiten
    
$supported_keys = array('name''dozent''fakult''sort');
    foreach (
$supported_keys as $key) {
        if (
array_key_exists($key$param)) {
            
$search_parameter[$key] = $param[$key];
        }
    }
    
$api_params '?';
    foreach (
$search_parameter as $k => $v) {
        if (
$v != '') {
            
$api_params .= $k '=' urlencode($v) . '&';
        }
    }

    
// Ggf. CSS-Klasse der Tabelle übernehmen
    
if (isset($param['css_class'])
     && !empty(
$param['name'])
    ) {
        
$css htmlentities($param['css_class']);
    } else {
        
$css 'horizontal grey';
    }

    
// Soll JS-Skript geladen werden?
    
if (isset($param['disable_js'])
     && 
$param['disable_js'] === TRUE
    
) {
        
$load_js FALSE;
    } else {
        
$load_js TRUE;
    }

    
// Soll "MeinPlan" unterstützt werden?
    
if (isset($param['enable_meinplan'])
     && 
$param['enable_meinplan'] === TRUE
    
) {
        
$load_mp TRUE;
    } else {
        
$load_mp FALSE;
    }

    
// Soll der Raum angezeigt werden?
    
if (isset($param['room_in_table'])
     && 
$param['room_in_table'] === FALSE
    
) {
        
$room_in_table FALSE;
    } else {
        
$room_in_table TRUE;
    }
    
// Ggf. angepassten "Nicht gefunden"-Text anzeigen
    
if (isset($param['not_found_text'])
     && !empty(
$param['not_found_text'])
    ) {
        
$not_found_text $param['not_found_text'];
    } else {
        
$not_found_text 'Keine Lehrveranstaltung gefunden.';
    }

    
// Sollen die Details direkt in der Tabelle angezeigt werden?
    
if (isset($param['detail_in_table'])
     && 
$param['detail_in_table'] === TRUE
    
) {
        
$detail_in_table TRUE;
    } else {
        
$detail_in_table FALSE;
    }

    
// Sollen die CSS-Klassen aus dem zentralen VLVZ verwendet werden?
    
if (isset($param['use_vlvz_style'])
     && 
$param['use_vlvz_style'] === TRUE
    
) {
        
$use_vlvz_style TRUE;
    } else {
        
$use_vlvz_style FALSE;
    }

    
// Sollen Zeit und Raum zusammen in einer Tabellenzelle dargestellt werden?
    
if (isset($param['joined_time_room'])
     && 
$param['joined_time_room'] === TRUE
     
&& $room_in_table === TRUE
    
) {
        
$joined_time_room TRUE;
    } else {
        
$joined_time_room FALSE;
    }

    
// Anzeige-Option: Aktuelles Semester / Archivsuche
    // Standard: LV aus aktuellem Semester
    
$api_endpoint 'activity';
    
$vlvz_template 'vlvz-list.twig';
    
$semestername '';
    
$semesterkurz '';
    if (isset(
$param['semester'])
     && !empty(
$param['semester'])
    ) {
        
// Prüfen, ob das angegebene Semester bereits archiviert ist
        
$current_semester '';
        
$context_cs stream_context_create(array('http' => array('header' => 'Connection: close\r\n')));
        
$result_cs file_get_contents(VLVZ_API 'semester/current'false$context_cs);
        if (empty(
$result_cs)) {
            
$error error_get_last();
            return 
'VLVZ-API ist nicht erreichbar: ' $error['message'];
        }
        
$response_cs json_decode($result_cs1);
        if (!
is_array($response_cs)) {
            return 
'Fehler beim Abruf der Daten: ' VLVZ_API 'semester/current';
        } else {
            
$current_semester $response_cs['kurz'];
        }

        if (
$param['semester'] != $current_semester) {
            
// Sollen LV aus dem Archiv angezeigt werden?
            
$api_endpoint 'archive';

            
// Semester-Name aufbereiten
            
if ($param['semester'] == 'all') {
                
$param['semester'] = '';
                
$semestername 'alle Semester';
                
$semesterkurz '';
            } else if (
$param['semester'] == 'ws%') {
                
$semestername 'alle Wintersemester';
                
$semesterkurz '';
            } else if (
$param['semester'] == 'ss%') {
                
$semestername 'alle Sommersemester';
                
$semesterkurz '';
            } else if (
substr($param['semester'], 02) == 'ss') {
                
$semestername 'Sommersemester 20' substr($param['semester'], 22);
                
$semesterkurz 'SS20' substr($param['semester'], 22);
            } else if (
substr($param['semester'], 02) == 'ws') {
                
$semestername 'Wintersemester 20' substr($param['semester'], 22) . '/' substr($param['semester'], 42);
                
$semesterkurz 'WS20' substr($param['semester'], 22) . '/' substr($param['semester'], 42);
            }

            
$api_params .= 'sem=' urlencode($param['semester']) . '&';
            
$vlvz_template 'vlvz-list-archive.twig';
            
// Parameter entsprechend fuer Archiv-Anzeige zuruecksetzen
            
$load_js FALSE;
            
$load_mp FALSE;
            
$detail_in_table TRUE;
            
$room_in_table TRUE;
            
$use_vlvz_style FALSE;
        }
    }

    
// Veranstaltungen über API abrufen
    
$context stream_context_create(array('http' => array('header' => 'Connection: close\r\n')));
    
$result file_get_contents(VLVZ_API $api_endpoint $api_paramsfalse$context);
    foreach (
$http_response_header as &$headervalue)
    {
        
$h explode(":"$headervalue2);
        
$h_name trim($h[0]);
        if( 
$h_name == "Retry-After" )
        {
            
$header_RetryAfter trim($h[1]);
            
$vorlDatum = (new DateTimeImmutable($header_RetryAfter))->setTimezone(new DateTimeZone('Europe/Berlin'))->format("d.m.Y H:i");
            
$not_found_text "Das Vorlesungsverzeichnis wird momentan überarbeitet. ";
            
$not_found_text .= "(Freischaltung ".$vorlDatum." Uhr)";
            break;
        }
    }
    if (!
$result) {
        
$error error_get_last();
        return 
'VLVZ-API ist nicht erreichbar: ' $error['message'];
    }
    
$response json_decode($result);
    if (!
is_array($response)) {
        return 
'Fehler beim Abruf der Daten: ' VLVZ_API $api_endpoint $api_params;
    }

    
// Ausgabe der Veranstaltungen
    
$template $twig->load($vlvz_template);
    return 
$template->render(array(
                
'veranstaltungen' => $response,
                
'suche' => $search_parameter,
                
'archivsemester' => $semestername,
                
'archivsemesterkurz' => $semesterkurz,
                
'css_class' => $css,
                
'load_js' => $load_js,
                
'load_mp' => $load_mp,
                
'not_found_text' => $not_found_text,
                
'detail_in_table' => $detail_in_table,
                
'room_in_table' => $room_in_table,
                
'use_vlvz_style' => $use_vlvz_style,
                
'joined_time_room' => $joined_time_room,
                
'app_base' => $app_base,
                )
            );
}