So. Ein paar kleine Änderungen:
define ('AnzahlPrevievTermine', 3); // Wie viele Termine pro Tag sollen angezeigt werden?
define ('TerminHoehe', '37px;' ); // Höhe des Termins???
define ('DEBUG', true ); // Kontrollausgaben?
if ( DEBUG ) {
error_reporting( E_ALL );
} else {
error_reporting( E_ALL & ~E_NOTICE );
}
$admin_kalenderarten = admin_kalenderarten($mysqli);
// Monate auf Deutsch
$monate = array(
1 => "Januar",
2 => "Februar",
3 => "März",
4 => "April",
5 => "Mai",
6 => "Juni",
7 => "Juli",
8 => "August",
9 => "September",
10 => "Oktober",
11 => "November",
12 => "Dezember"
);
// Anzuzeigenden Monat aus $_GET["ym"] laden und auf 1. des Monats einstellen
$timestamp = get_anzeigemonat_timestamp();
$showYear = date( 'Y', $timestamp );
$showMonth = date( 'm', $timestamp );
// H3 Title
$html_title = sprintf( "%04d / %02d", $showYear, $showMonth );
// Prev & Next / Monat Link
$nextMonth = date( 'Y-m', mktime( 0, 0, 0, $showMonth+1, 1, $showYear ) );
$prevMonth = date( 'Y-m', mktime( 0, 0, 0, $showMonth-1, 1, $showYear ) );
// <tr>...</tr> Zeilen für die Kalenderausgabe konstruieren
$weeks = erzeuge_kalenderwochen( $timestamp, $mysqli, $teile25 );
/**
* Ermittle den Timestamp für den 1. des anzuzeigenden Monats. Der Monat wird
* im Query-Parameter ym übergeben. Fehlt der oder hat falsches Format, wird
* der aktuelle Monat verwendet.
*
* @return int Unix-Timestamp des ersten Tages im Anzeigemonat
*/
function get_anzeigemonat_timestamp() {
$ym = filter_input(INPUT_GET, "ym",
FILTER_VALIDATE_REGEXP,
[ 'options' => [ 'regexp'=>'/\d{4}-\d{1,2}/' ] ]);
// Auf aktuellen Monat setzen wenn Parameter fehlt oder die gescheitert Validierung ist
if ( is_null( $ym ) || $ym === false ) {
$ym = date('Y-m');
}
// $ym ist jetzt immer im Format yyyy-mm.
// Entweder durch Regex bestätigt, oder von date geliefert.
$parts = explode( "-", $ym );
// Monat Jahr
return mktime( 0, 0, 0, intval( $parts[1] ), 1, intval($parts[0] ) );
}
/**
* Generiert Table Rows mit Kalendereinträgen. Daten werden automatisch beschafft.
*
* @return array Ein Array mit fertigen HTML Fragmenten pro Row
*/
function erzeuge_kalenderwochen( $firstOfMonth, $mysqli, $teile25 ) {
$thisMonth = date( "Y-m", $firstOfMonth );
$showYear = intval( date( 'Y', $firstOfMonth ) );
$showMonth = intval( date( 'm', $firstOfMonth ) );
// date('w') liefert 0:So 1:Mo 2:Di usw...
// Finde Wochentag des Monatsersten, +6, %7, ergibt Wochentag des Tages zuvor.
// Diese Tagesnummer ist die Anzahl von leeren Feldern vor dem 1. des Monats
// $day wird die auszugebende Tagesnummer sein, d.h. um N Felder leerzulassen,
// wird $day auf 1-N initialisiert.
$weekDayBeforeFirst = ( 6 + intval( date( 'w', $firstOfMonth ) ) ) % 7;
$day = 1 - $weekDayBeforeFirst;
// Kalender zusammenbauen
// Tagesdatum und YYYY-MM Form des aktuellen Monats ermitteln
$today = date( 'Y-m-d', time() );
// Anzahl der Tage im Anzeigemonat ermitteln
$day_count = intval( date( 't', $firstOfMonth ) );
// $weeks: Ein Eintrag pro Anzeigewoche
$weeks = array();
while ( $day <= $day_count ) {
// Negative Werte oder zu große Werte für $day sind kein Problem, die werden
// von mktime in den passenden Monat verschoben.
$weekParts = array();
$weekNr = date( 'W', mktime( 0, 0, 0, $showMonth, $day, $showYear ) );
$weekParts[] = "<td class='kw'>$weekNr</td>";
// Die 7 Tage einer Woche aufbereiten
for ( $i=0; $i<7; $i++ ) {
$weekParts[] = formatiere_tag( $thisMonth, $day_count, $day, $today, $mysqli, $teile25 );
$day++;
}
$weeks[] = "<tr>".implode( '', $weekParts )."</tr>";
}
return $weeks;
}
/**
* Formatiere das HTML Fragment für einen Kalendertag
*
* @param \mysqli $mysqli mysqli-Objekt für Datenbeschaffung
* @param string $date Anfragedatum, yyyy-mm-tt
* @param bool $aktuellerTag True um Tag als aktuelles Datum zu formatieren
* @return string
*/
function formatiere_tag( $thisMonth, $day_count, $day, $today, $mysqli, $teile25 )
{
if ( $day < 1 || $day > $day_count ) {
return "<td class='emptyDay'></td>";
}
$date = $thisMonth . sprintf( '-%02d', $day );
// Daten beschaffen
$datumTermine = kalender_termine( $mysqli, $date, $teile25 );
if ( DEBUG ) {
echo '<pre><hr>$datumTermine (' . $date . ') <hr>';
print_r ( $datumTermine );
echo '/<pre>';
}
$anzTermineGesamt = count($datumTermine );
$dayClasses = ( $date == $today ? "today " : "" );
$dayHtml = "<td class='$dayClasses calendarDay'>"
. formatiere_tag_header( $date, $day, $anzTermineGesamt );
// Begrenzen der Anzahl der gezeigten Termine auf höchstens "3" ( Konstante: AnzahlPrevievTermine)
$end = $anzTermineGesamt;
if ( $end > AnzahlPrevievTermine ) {
$end = AnzahlPrevievTermine;
}
for $i=0; $i < $end; $i++) {
$dayHtml .= formatiere_termin( $datumTermine[$i] );
}
return $dayHtml . '</td>';
}
/**
* Ermittle alle Kalendereinträge zu einem Datum und einer Liste von Empfängern
*
* @param \mysqli $mysqli Eine MySQLI Connection
* @param string $datum Das Abfragedatum im Format yyyy-mm-dd
* @param string[] $teile25 Komma-getrennte Liste der möglichen Kalenderarten (k_art)
*
* @return Array
*/
function kalender_termine( $mysqli, $datum, $teile25 ) {
$values = $teile25;
$empfaengerListe = '"' . implode( '", "', $values ) . '"';
$select = 'SELECT
kt_id,
kt_kalenderID,
kt_datum,
test,
k_code,
k_art,
k_jobNr,
k_bezeichnung,
k_auto,
k_farbe,
k_datum_von,
k_ganztags,
k_von,
k_bis,
f_bezeichnung,
f_kennzeichen,
ka_farbe,
kf_farbe,
kf_color
FROM kalender_termine
LEFT JOIN
kalender ON kalender.k_code = kalender_termine.kt_kalenderID
LEFT JOIN
fuhrpark ON fuhrpark.f_id = kalender.k_auto
LEFT JOIN
kalender_arten ON kalender_arten.ka_code = kalender.k_art
LEFT JOIN
kalender_terminfarbe ON kalender_terminfarbe.kf_farbe = kalender_arten.ka_farbe
WHERE
kt_datum=" . $datum . "
AND
k_art IN (' . $empfaengerListe . ')
ORDER by test ASC';
$stmt = $mysqli->prepare($select );
$stmt -> execute();
if ( $mysqli -> error ) {
if ( DEBUG ) {
echo "<pre>";
printf( "Errormessage: %s\n", $mysqli -> error );
echo "<hr>$select</hr>";
exit;
} else {
echo "<h1>Sorry</h1><p>Leider ist bei der Datenbankabfrage ein Fehler aufgtreten.</p>";
exit;
}
}
$stmt -> bind_result (
$kt_id,
$kt_kalenderID,
$kt_datum,
$test,
$k_code,
$k_art,
$k_jobNr,
$k_bezeichnung,
$k_auto,
$k_farbe,
$k_datum_von,
$k_ganztags,
$k_von,
$k_bis,
$f_bezeichnung,
$f_kennzeichen,
$ka_farbe,
$kf_farbe,
$kf_color
);
$Kalender_Termine = array();
if ( $stmt -> num_rows() > 0 ) {
while ( $stmt -> fetch() ) {
$arTemp = array();
$arTemp['kt_id'] => $kt_id;
$arTemp['kt_kalenderID'] => $kt_kalenderID;
$arTemp['kt_datum'] => $kt_datum;
$arTemp['test'] => $test;
$arTemp['k_code'] => $k_code;
$arTemp['k_art'] => $k_art;
$arTemp['k_jobNr'] => $k_jobNr;
$arTemp['k_bezeichnung'] => $k_bezeichnung;
$arTemp['k_auto'] => $k_auto;
$arTemp['k_farbe'] => $k_farbe;
$arTemp['k_datum_von'] => $k_datum_von;
$arTemp['k_ganztags'] => $k_ganztags;
$arTemp['k_von'] => $k_von;
$arTemp['k_bis'] => $k_bis;
$arTemp['f_bezeichnung'] => $f_bezeichnung;
$arTemp['f_kennzeichen'] => $f_kennzeichen;
$arTemp['ka_farbe'] => $ka_farbe;
$arTemp['kf_farbe'] => $kf_farbe;
$arTemp['kf_color'] => $kf_color
$Kalender_Termine[] = $arTemp;
}
}
$stmt -> close();
if ( DEBUG ) {
echo '<pre><hr>$Kalender_Termine vor Rückkgabe:<hr>';
print_r( $Kalender_Termine );
echo '<hr></pre>';
}
return $Kalender_Termine;
}
function formatiere_tag_header($date, $day, $anzTermine) {
$dailyLink = '<a href="tageskalender.php?date='.$date .'">';
if ( $anzTermine > 3 ) {
$header = "$day - {$dailyLink}Alle $anzTermine anzeigen</a>";
} else {
$header = $dailyLink.$day . "</a>";
}
return "<div class='dayHeader'>$header</div>";
}
function formatiere_termin($termin) {
// Formatiere_Datenblatt_Link wählt k/f-Bezeichnung automatisch aus.
// Formatiere_JobNr_und_Zeit gibt nur ein <span> aus wenn die JobNr
// gefüllt oder ein Zeitraum angefordert ist. Sonst kommt '' zurück.
if ( $termin["kt_datum"] == $termin["k_datum_von"] ) {
if ( $termin["k_ganztags"] == "0" ) {
$terminHoehe = '';
$terminInhalt = formatiere_datenblatt_link( $termin ) . formatiere_jobNr_und_zeit( $termin, true );
} else {
$terminHoehe = 'min-height: ' . TerminHoehe;
$terminInhalt = formatiere_datenblatt_link( $termin ) . formatiere_jobNr_und_zeit( $termin, false );
}
} else {
$terminHoehe = 'height: ' . TerminHoehe;
// Wochentag des Termindatums prüfen
$datum = getdate( strtotime( $termin["kt_datum"] ) );
// Montag = 1
if ( $datum['wday'] == 1 ) {
$terminInhalt = formatiere_datenblatt_link( $termin ) . formatiere_jobNr_und_zeit( $termin, false );
} else {
$terminInhalt = '';
}
}
return '<div style="background:' . $termin["ka_farbe"] . '; margin-bottom:5px; padding-left:8px;' . $terminHoehe . '">'
. $terminInhalt
. '</div>';
}
function Formatiere_Datenblatt_Link( $termin ) {
$text = ( $termin["k_auto"] == "" ) ? $termin["k_bezeichnung"] : $termin["f_bezeichnung"];
$url = '/kalender-datenblatt.php?code=' . $termin["k_code"];
$farbe = 'color:' . $termin["kf_color"];
return '<a href="' . $url . '" style="' . $farbe . '">' . shortText( $text, 15 ) . '</a>';
//return '<span style="color:' . $termin["kf_color"] . '"><a href="' . $url . '" style="' . $farbe . '">' . shortText( $text, 15 ) . '</a></span>';
}
/**
* Formatiere JobNr und Zeitraum eines Termineintrags.
*
* Ist die JobNr leer und kein Zeitraum gefordert, wird ein Leerstring zurückgegeben.
*
* Ist die JobNr bestückt und ein Zeitraum gefordert, werden beide durch " - " getrennt.
*
* Das Ergebnis wird in einen span mit style-Attribut eingehüllt, das die Farbe gemäß
* Datenbank setzt. TODO: Unnötige Styles ins CSS verlegen!
*
* @param array $termin Terminzeile aus dem SQL Ergebnis
* @param bool $mitZeitraum true übergeben um auch den Zeitraum auszugeben
*
* @return string HTML-Text mit span Element, das die Werte enthält
*/
function Formatiere_JobNr_und_Zeit( $termin, $mitZeitraum ) {
$parts = array();
if ( $termin['k_jobNr'] != '' ) {
$parts[] = $termin['k_jobNr'];
}
if ( $mitZeitraum ) {
$parts[] = $termin['k_von'] . ' bis '.$termin['k_bis'] . ' Uhr';
}
if ( count( $parts ) == 0 ) {
return '';
}
return '<span style="color:' . $termin["kf_color"] . '; font-size:10px; display: block; padding-bottom: 2px;">'
. implode( ' - ', $parts )
. '</span>';
}