KW als Spalte einfügen
bearbeitet von Rolf BHallo Barksalot,
weiter geht's. Als nächstes kommt die Datenbeschaffung. Die habe ich fast unverändert gelassen. Die Frage nach der Güte deines SQL habe ich nicht betrachtet. Es fehlte ein $stmt->close(), um das verarbeitete Resultset freizugeben und Speicher zu sparen.
Was auf jeden Fall noch passieren müsste, ist eine Trennung von Prepare und Execute. Ein prepared statement nur einmal auszuführen lohnt nicht. Das wird aber nur durch Klassen-Techniken sinnvoll (die binds müssten an Properties der Klasse erfolgen, damit die gebundenen Variablen ihren Scope behalten, und die RÜckgabe wäre vielleicht besser mit get_result und fetch_assoc zu handlen). Darum lasse ich das erstmal so stehen.
Die Story mit dem LIMIT ist so eine Sache. Du rufst das Statement zweimal auf. Einmal mit Limit 3, einmal ohne Limit. Nur um festzustellen wieviele Termine es am Tag gibt. Das ist ineffektiv. Eigentlich müsstest Du für diesen Zählvorgang ein eigenes Statement preparen und ausführe, das nur COUNT(*) zurückliefert. Und bei der Gelegenheit schauen, ob Du alle Joins für den Zählvorgang brauchst. Das Statement, das Du jetzt verwendest, kann dann konstant mit Limit 3 laufen.
Ohne dieses Statement bleibt zum Zählen nur der Aufruf ohne Limit, den habe ich in der count_alle_kalender_termine gekapselt. Aber eigentlich gehört da ein anderes Statement hin.
~~~php
/**
* 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, $limit = false) {
$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=?
AND k_art IN (" . $empfaengerListe . ")
ORDER by test ASC";
if ($limit != false) {
$stmt = $mysqli->prepare($select . " LIMIT ?" );
$stmt->bind_param("ss", $datum, $limit);
} else {
$stmt = $mysqli->prepare($select );
$stmt->bind_param("s", $datum);
}
$stmt->execute();
$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()) {
$Kalender_Termine[] = array(
'kt_id' => $kt_id,
'kt_kalenderID' => $kt_kalenderID,
'kt_datum' => $kt_datum,
'test' => $test,
'k_code' => $k_code,
'k_art' => $k_art,
'k_jobNr' => $k_jobNr,
'k_bezeichnung' => $k_bezeichnung,
'k_auto' => $k_auto,
'k_farbe' => $k_farbe,
'k_datum_von' => $k_datum_von,
'k_ganztags' => $k_ganztags,
'k_von' => $k_von,
'k_bis' => $k_bis,
'f_bezeichnung' => $f_bezeichnung,
'f_kennzeichen' => $f_kennzeichen,
'ka_farbe' => $ka_farbe,
'kf_farbe' => $kf_farbe,
'kf_color' => $kf_color
);
}
}
$stmt->close();
return $Kalender_Termine;
}
/**
* Zähle die Kalendereinträge zu einem Datum und einer Liste von Kalenderarten
*
* @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 int Anzahl Einträge
*/
function Count_Alle_Kalender_Termine($mysqli, $datum, $teile25) {
// Bis eine bessere Abfrage bereitstelt, auf die alte Technik der unlimitierten
// Abfrage zurückfallen
$termine = Kalender_Termine($mysqli, $datum, $teile25);
return count($termine);
}
~~~
Ansonsten brauchst Du in `formatiere_tag` noch die Funktionen zum Aufbereiten des Tages-Headers und der Termine selbst:
~~~php
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>";
}
~~~
und
~~~php
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: 37px;';
$terminInhalt = formatiere_datenblatt_link($termin) . formatiere_jobNr_und_zeit($termin, false);
}
}
else
{
$terminHoehe = 'height: 37px;';
// Wochentag des Termindatums prüfen
$datum = getdate(strtotime($termin["kt_datum"]));
if ($datum['wday'] == 1) // Montag
{
$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>';
}
~~~
Hier müsstest Du dein HTML besser aufräumen, dann könnten Fallunterscheidungen möglicherweise entfallen. Die Zweige werden eigentlich nur gebildet um die unterschiedlichen Höhen zu setzen, und wegen dieser Montagslogik, die ich nicht verstanden habe.
Die Formatierer sehen so aus:
~~~php
unction 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 = [];
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>';
}
~~~
Tja. Das war's. Bei mir in NetBeans sind es 50 Zeilen mehr als Dein Code, aber es sind viel mehr Kommentare drin. Ohne die würde es ein gutes Stück kürzer.
_Rolf_
--
sumpsi - posui - clusi