Dateien nach "/" hochladen

This commit is contained in:
2026-03-05 15:31:40 +01:00
parent 4de35c7d58
commit 776bff4347
3 changed files with 370 additions and 0 deletions
+370
View File
@@ -0,0 +1,370 @@
<?php
declare(strict_types=1);
include "functions.php";
include "header.php";
include "headerline.php";
include "nav.php";
?>
<!-- Banner -->
<section id="banner">
<div class="content">
<?php
if(checkKaffeelisteAccess($conn, $mailadress)){
echo "<h2>Kaffeeliste</h2>";
echo "Hallo " . getUserName($conn,$mailadress) . "!<br><br>";
// Annahme: $conn ist bereits vorhanden (sqlsrv_connect in deiner Infrastruktur)
if (!isset($conn)) {
die("DB Verbindung (\$conn) fehlt.");
}
function h($s): string {
return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8');
}
/**
* OPTIONAL: Admin-Schutz via Basic Auth (auskommentieren, wenn nicht gewünscht)
*/
/*
$ADMIN_USER = 'admin';
$ADMIN_PASS = 'changeme';
if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])
|| $_SERVER['PHP_AUTH_USER'] !== $ADMIN_USER || $_SERVER['PHP_AUTH_PW'] !== $ADMIN_PASS) {
header('WWW-Authenticate: Basic realm="Umfrage Admin"');
header('HTTP/1.0 401 Unauthorized');
echo "Unauthorized";
exit;
}
*/
$drinks = [
'espresso' => 'Espresso',
'crema' => 'Café Crema',
'cappuccino' => 'Cappuccino',
'latte' => 'Latte Macchiato',
'americano' => 'Americano',
'decaf' => 'Entkoffeiniert',
'other' => 'Andere',
];
$problems = [
'forget' => 'Vergesse Eintrag',
'empty' => 'Kaffee leer',
'water' => 'Wasser auffüllen',
'too_little' => 'zu wenig Kaffeeausgabe',
'too_much' => 'zu viel Kaffeeausgabe',
'none' => 'Kein Problem',
'other' => 'Sonstiges',
];
$improvements = [
'easier_entry' => 'Einfacherer Eintrag',
'overview' => 'Übersicht über Kosten/Verbrauch',
'more_mails' => 'Mehr Info-Mails',
'adjust_amount' => 'Menge der Kaffeeausgabe anpassen',
'other' => 'Sonstiges',
];
// Helper: SQL scalar
function sql_scalar($conn, string $sql, array $params = []) {
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) return null;
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_NUMERIC);
return $row ? $row[0] : null;
}
// Helper: SQL all rows
function sql_all($conn, string $sql, array $params = []): array {
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) return [];
$rows = [];
while ($r = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$rows[] = $r;
}
return $rows;
}
$errors = [];
$totalResponses = (int)(sql_scalar($conn, "SELECT COUNT(*) FROM dbo.CoffeeSurveyResponses") ?? 0);
$totalVotedEmails = (int)(sql_scalar($conn, "SELECT COUNT(*) FROM dbo.CoffeeSurveyVotedEmails") ?? 0);
// Skalen-Auswertung (Avg + Count pro Wert 1..5)
function scale_stats($conn, string $col): array {
$sql = "
SELECT
AVG(CAST([$col] AS FLOAT)) AS avgVal,
SUM(CASE WHEN [$col] = 1 THEN 1 ELSE 0 END) AS c1,
SUM(CASE WHEN [$col] = 2 THEN 1 ELSE 0 END) AS c2,
SUM(CASE WHEN [$col] = 3 THEN 1 ELSE 0 END) AS c3,
SUM(CASE WHEN [$col] = 4 THEN 1 ELSE 0 END) AS c4,
SUM(CASE WHEN [$col] = 5 THEN 1 ELSE 0 END) AS c5
FROM dbo.CoffeeSurveyResponses
";
$rows = sql_all($conn, $sql);
if (!$rows) return ['avg'=>null,'c'=>[0,0,0,0,0]];
$r = $rows[0];
return [
'avg' => $r['avgVal'] !== null ? (float)$r['avgVal'] : null,
'c' => [(int)$r['c1'], (int)$r['c2'], (int)$r['c3'], (int)$r['c4'], (int)$r['c5']]
];
}
$q1 = scale_stats($conn, 'Q1_ListEase');
$q2 = scale_stats($conn, 'Q2_ListSatisfaction');
$q3 = scale_stats($conn, 'Q3_CoffeeQuality');
$q4 = scale_stats($conn, 'Q4_WebsiteSatisfaction');
// Problem (Q7) Gruppiert
$q7Rows = sql_all($conn, "
SELECT Q7_ListProblem AS keyVal, COUNT(*) AS cnt
FROM dbo.CoffeeSurveyResponses
GROUP BY Q7_ListProblem
ORDER BY cnt DESC
");
// CSV-Felder + Freitext sammeln (limit)
$limit = 500; // genug für Auswertung, falls riesig: erhöhen oder paginieren
$dataRows = sql_all($conn, "
SELECT TOP ($limit)
CreatedAt,
Q5_Drinks, Q5_DrinksOther,
Q6_NewVarieties,
Q8_Improvements, Q8_ImprovementsOther,
Q9_BetterIdeas
FROM dbo.CoffeeSurveyResponses
ORDER BY CreatedAt DESC
");
// Aggregation in PHP für Mehrfachauswahl
$drinkCounts = array_fill_keys(array_keys($drinks), 0);
$drinkOtherTexts = [];
$impCounts = array_fill_keys(array_keys($improvements), 0);
$impOtherTexts = [];
$newVarietiesTexts = [];
$betterIdeasTexts = [];
foreach ($dataRows as $r) {
// Q5 drinks CSV
$csv = trim((string)($r['Q5_Drinks'] ?? ''));
if ($csv !== '') {
$parts = array_filter(array_map('trim', explode(',', $csv)));
foreach ($parts as $p) {
if (array_key_exists($p, $drinkCounts)) $drinkCounts[$p]++;
}
}
$ot = trim((string)($r['Q5_DrinksOther'] ?? ''));
if ($ot !== '') $drinkOtherTexts[] = $ot;
// Q8 improvements CSV
$csv2 = trim((string)($r['Q8_Improvements'] ?? ''));
if ($csv2 !== '') {
$parts2 = array_filter(array_map('trim', explode(',', $csv2)));
foreach ($parts2 as $p2) {
if (array_key_exists($p2, $impCounts)) $impCounts[$p2]++;
}
}
$ot2 = trim((string)($r['Q8_ImprovementsOther'] ?? ''));
if ($ot2 !== '') $impOtherTexts[] = $ot2;
// Q6 / Q9 Freitext
$t6 = trim((string)($r['Q6_NewVarieties'] ?? ''));
if ($t6 !== '') $newVarietiesTexts[] = $t6;
$t9 = trim((string)($r['Q9_BetterIdeas'] ?? ''));
if ($t9 !== '') $betterIdeasTexts[] = $t9;
}
// Hilfsfunktion Prozent
function pct(int $n, int $total): string {
if ($total <= 0) return "0%";
return round(($n / $total) * 100, 1) . "%";
}
?>
<h1>Umfrage Ergebnisse</h1>
<p class="muted">
Antworten: <b><?php echo (int)$totalResponses; ?></b>
<?php if ($limit && $totalResponses > $limit): ?>
&nbsp;|&nbsp; Auswertung basiert auf den letzten <?php echo (int)$limit; ?> Antworten
<?php endif; ?>
</p>
<div class="grid">
<div class="box">
<h3>1) Kaffeeliste benutzen (1 sehr einfach … 5 sehr schwierig)</h3>
<p class="small">Durchschnitt: <b><?php echo $q1['avg'] !== null ? number_format($q1['avg'], 2, ',', '.') : '-'; ?></b></p>
<table>
<tr><th>Wert</th><th>Anzahl</th><th>Anteil</th></tr>
<?php for ($i=1;$i<=5;$i++): ?>
<tr>
<td><?php echo $i; ?></td>
<td><?php echo $q1['c'][$i-1]; ?></td>
<td><?php echo pct($q1['c'][$i-1], $totalResponses); ?></td>
</tr>
<?php endfor; ?>
</table>
</div>
<div class="box">
<h3>2) Zufriedenheit Kaffeeliste (1 sehr zufrieden … 5 sehr unzufrieden)</h3>
<p class="small">Durchschnitt: <b><?php echo $q2['avg'] !== null ? number_format($q2['avg'], 2, ',', '.') : '-'; ?></b></p>
<table>
<tr><th>Wert</th><th>Anzahl</th><th>Anteil</th></tr>
<?php for ($i=1;$i<=5;$i++): ?>
<tr>
<td><?php echo $i; ?></td>
<td><?php echo $q2['c'][$i-1]; ?></td>
<td><?php echo pct($q2['c'][$i-1], $totalResponses); ?></td>
</tr>
<?php endfor; ?>
</table>
</div>
<div class="box">
<h3>3) Zufriedenheit Kaffeequalität (1 sehr zufrieden … 5 sehr unzufrieden)</h3>
<p class="small">Durchschnitt: <b><?php echo $q3['avg'] !== null ? number_format($q3['avg'], 2, ',', '.') : '-'; ?></b></p>
<table>
<tr><th>Wert</th><th>Anzahl</th><th>Anteil</th></tr>
<?php for ($i=1;$i<=5;$i++): ?>
<tr>
<td><?php echo $i; ?></td>
<td><?php echo $q3['c'][$i-1]; ?></td>
<td><?php echo pct($q3['c'][$i-1], $totalResponses); ?></td>
</tr>
<?php endfor; ?>
</table>
</div>
<div class="box">
<h3>4) Zufriedenheit Webseite (1 sehr zufrieden … 5 sehr unzufrieden)</h3>
<p class="small">Durchschnitt: <b><?php echo $q4['avg'] !== null ? number_format($q4['avg'], 2, ',', '.') : '-'; ?></b></p>
<table>
<tr><th>Wert</th><th>Anzahl</th><th>Anteil</th></tr>
<?php for ($i=1;$i<=5;$i++): ?>
<tr>
<td><?php echo $i; ?></td>
<td><?php echo $q4['c'][$i-1]; ?></td>
<td><?php echo pct($q4['c'][$i-1], $totalResponses); ?></td>
</tr>
<?php endfor; ?>
</table>
</div>
</div>
<div class="box">
<h3>5) Häufigste Kaffeearten (Mehrfachauswahl)</h3>
<table>
<tr><th>Sorte</th><th>Anzahl</th><th>Anteil (bezogen auf Antworten)</th></tr>
<?php foreach ($drinks as $key => $label): ?>
<tr>
<td><?php echo h($label); ?></td>
<td><?php echo (int)$drinkCounts[$key]; ?></td>
<td><?php echo pct((int)$drinkCounts[$key], $totalResponses); ?></td>
</tr>
<?php endforeach; ?>
</table>
<?php if (count($drinkOtherTexts) > 0): ?>
<p class="small"><b>„Andere“ Texte (letzte 30):</b></p>
<ul>
<?php foreach (array_slice($drinkOtherTexts, 0, 30) as $t): ?>
<li><?php echo h($t); ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
<div class="box">
<h3>7) Häufigstes Problem mit der Kaffeeliste</h3>
<table>
<tr><th>Problem</th><th>Anzahl</th><th>Anteil</th></tr>
<?php
// Map rows -> counts
$tmp = [];
foreach ($q7Rows as $r) $tmp[(string)$r['keyVal']] = (int)$r['cnt'];
foreach ($problems as $k => $label):
$c = $tmp[$k] ?? 0;
?>
<tr>
<td><?php echo h($label); ?></td>
<td><?php echo $c; ?></td>
<td><?php echo pct($c, $totalResponses); ?></td>
</tr>
<?php endforeach; ?>
</table>
</div>
<div class="box">
<h3>8) Gewünschte Verbesserungen (Mehrfachauswahl)</h3>
<table>
<tr><th>Verbesserung</th><th>Anzahl</th><th>Anteil (bezogen auf Antworten)</th></tr>
<?php foreach ($improvements as $key => $label): ?>
<tr>
<td><?php echo h($label); ?></td>
<td><?php echo (int)$impCounts[$key]; ?></td>
<td><?php echo pct((int)$impCounts[$key], $totalResponses); ?></td>
</tr>
<?php endforeach; ?>
</table>
<?php if (count($impOtherTexts) > 0): ?>
<p class="small"><b>„Sonstiges“ Texte (letzte 30):</b></p>
<ul>
<?php foreach (array_slice($impOtherTexts, 0, 30) as $t): ?>
<li><?php echo h($t); ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
<div class="grid">
<div class="box">
<h3>6) Zusätzliche Sorten (Freitext) letzte 30</h3>
<?php if (!$newVarietiesTexts): ?>
<p class="muted">Keine Einträge.</p>
<?php else: ?>
<ul>
<?php foreach (array_slice($newVarietiesTexts, 0, 30) as $t): ?>
<li><?php echo h($t); ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
<div class="box">
<h3>9) Was kann die Kaffeeliste noch besser machen? letzte 30</h3>
<?php if (!$betterIdeasTexts): ?>
<p class="muted">Keine Einträge.</p>
<?php else: ?>
<ul>
<?php foreach (array_slice($betterIdeasTexts, 0, 30) as $t): ?>
<li><?php echo h($t); ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
</div>
<?php
}else{
echo "<h2>Sie haben keine Zugang zu dieser Webseite</h2>";
}
?>
</div>
</section>
<?php include "footer.php";
?>