370 lines
11 KiB
PHP
370 lines
11 KiB
PHP
<?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): ?>
|
||
| 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";
|
||
|
||
?>
|