Files
kaffeeliste/umfrageergebnisse.php
T
2026-03-05 15:31:40 +01:00

370 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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";
?>