255 lines
6.8 KiB
PHP
255 lines
6.8 KiB
PHP
<?php
|
|
// API Tester Service - Als Modul für index.php
|
|
// Dieser Service dient zum manuellen Testen der API-Endpunkte.
|
|
|
|
// Basis-Verzeichnisse scannen (Pfad relativ zur index.php)
|
|
$apiDir = __DIR__ . '/../api/';
|
|
$apiFiles = glob($apiDir . '*.php');
|
|
$apiOptions = [];
|
|
foreach ($apiFiles as $file) {
|
|
$apiOptions[] = 'api/' . basename($file);
|
|
}
|
|
|
|
// Token aus deiner get.php entnommen
|
|
$defaultToken = "15a437d128c918633e57dc7d18118a073b807644f21731ed5a7ebcf3eca9e242";
|
|
?>
|
|
|
|
<style>
|
|
/* Spezifische Styles für den API Tester innerhalb des Content-Bereichs */
|
|
.api-tester-container {
|
|
width: 100%;
|
|
max-width: 900px;
|
|
margin: 0 auto;
|
|
background-color: var(--card-bg);
|
|
padding: 25px;
|
|
border-radius: 10px;
|
|
border: 1px solid var(--card-border);
|
|
}
|
|
|
|
.api-tester-container h2 {
|
|
margin-top: 0;
|
|
margin-bottom: 20px;
|
|
color: var(--btn-bg);
|
|
border-bottom: 1px solid var(--card-border);
|
|
padding-bottom: 10px;
|
|
display: block;
|
|
/* style.css h2 hat flex, wir wollen hier einfaches block */
|
|
}
|
|
|
|
.tester-form-group {
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.tester-form-group label {
|
|
display: block;
|
|
margin-bottom: 5px;
|
|
font-weight: bold;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.tester-input {
|
|
width: 100%;
|
|
padding: 10px;
|
|
background-color: var(--input-bg);
|
|
border: 1px solid var(--input-border);
|
|
color: var(--input-text);
|
|
border-radius: 5px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.tester-btn-send {
|
|
background-color: var(--btn-bg);
|
|
color: white;
|
|
padding: 12px 20px;
|
|
border: none;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
font-weight: bold;
|
|
width: 100%;
|
|
margin-top: 10px;
|
|
}
|
|
|
|
.tester-btn-send:hover {
|
|
opacity: 0.9;
|
|
}
|
|
|
|
#tester-response-container {
|
|
margin-top: 25px;
|
|
background-color: var(--input-bg);
|
|
padding: 15px;
|
|
border-radius: 8px;
|
|
border: 1px solid var(--card-border);
|
|
min-height: 80px;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
#tester-output-content {
|
|
white-space: pre-wrap;
|
|
font-family: 'Consolas', 'Monaco', monospace;
|
|
font-size: 0.85rem;
|
|
margin: 0;
|
|
color: var(--text);
|
|
}
|
|
|
|
.tester-badge {
|
|
display: inline-block;
|
|
padding: 3px 8px;
|
|
border-radius: 4px;
|
|
font-size: 0.8rem;
|
|
font-weight: bold;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.tester-status-200 {
|
|
background-color: var(--status-bg);
|
|
color: var(--status-text);
|
|
}
|
|
|
|
.tester-status-error {
|
|
background-color: #dc3545;
|
|
color: white;
|
|
}
|
|
|
|
.tester-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 15px;
|
|
}
|
|
|
|
@media (max-width: 600px) {
|
|
.tester-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
|
|
.hidden {
|
|
display: none !important;
|
|
}
|
|
</style>
|
|
|
|
<div class="api-tester-container">
|
|
<h2>🛠️ API Tester</h2>
|
|
|
|
<div class="tester-form-group">
|
|
<label for="endpoint">API Endpunkt</label>
|
|
<select id="endpoint" class="tester-input" onchange="checkEndpoint()">
|
|
<?php foreach ($apiOptions as $opt): ?>
|
|
<option value="<?= $opt ?>"><?= $opt ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="tester-grid">
|
|
<div class="tester-form-group">
|
|
<label for="method">HTTP Methode</label>
|
|
<select id="method" class="tester-input">
|
|
<option value="GET">GET</option>
|
|
<option value="POST">POST</option>
|
|
<option value="OPTIONS">OPTIONS</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="tester-form-group" id="function-group">
|
|
<label for="function-header">Function Header</label>
|
|
<input type="text" id="function-header" class="tester-input" placeholder="z.B. IPs, Ueberstunden">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="tester-form-group">
|
|
<label for="token">Authorization Token</label>
|
|
<input type="text" id="token" class="tester-input" value="<?= $defaultToken ?>">
|
|
</div>
|
|
|
|
<div class="tester-form-group hidden" id="file-group">
|
|
<label for="files">Dateien (files)</label>
|
|
<input type="file" id="files" class="tester-input" multiple>
|
|
</div>
|
|
|
|
<button class="tester-btn-send" onclick="sendApiRequest()">Anfrage senden 🚀</button>
|
|
|
|
<div id="tester-response-container">
|
|
<div style="text-align: center; color: #888; padding: 10px;">Bereit für Anfragen.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function checkEndpoint() {
|
|
const endpoint = document.getElementById('endpoint').value;
|
|
const fileGroup = document.getElementById('file-group');
|
|
const functionGroup = document.getElementById('function-group');
|
|
const methodSelect = document.getElementById('method');
|
|
|
|
// Standard: alles ausblenden
|
|
fileGroup.classList.add('hidden');
|
|
functionGroup.classList.remove('hidden');
|
|
|
|
if (endpoint === 'api/upload.php') {
|
|
// Nur bei exakt api/upload.php Dateien anzeigen
|
|
fileGroup.classList.remove('hidden');
|
|
functionGroup.classList.add('hidden');
|
|
methodSelect.value = 'POST';
|
|
}
|
|
|
|
if (endpoint === 'api/get.php') {
|
|
methodSelect.value = 'GET';
|
|
}
|
|
}
|
|
|
|
async function sendApiRequest() {
|
|
const endpoint = document.getElementById('endpoint').value;
|
|
const method = document.getElementById('method').value;
|
|
const token = document.getElementById('token').value;
|
|
const functionHeader = document.getElementById('function-header').value;
|
|
const fileInput = document.getElementById('files');
|
|
const responseContainer = document.getElementById('tester-response-container');
|
|
|
|
responseContainer.innerHTML = '<div style="text-align: center; padding: 10px;">Lade...</div>';
|
|
|
|
let headers = {
|
|
'Authorization': token
|
|
};
|
|
|
|
if (endpoint.includes('get.php') && functionHeader) {
|
|
headers['Function'] = functionHeader;
|
|
}
|
|
|
|
let options = {
|
|
method: method,
|
|
headers: headers
|
|
};
|
|
|
|
if (endpoint.includes('upload.php') && fileInput.files.length > 0) {
|
|
const formData = new FormData();
|
|
for (let i = 0; i < fileInput.files.length; i++) {
|
|
formData.append('files[]', fileInput.files[i]);
|
|
}
|
|
options.body = formData;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(endpoint, options);
|
|
const status = response.status;
|
|
const rawText = await response.text();
|
|
let resultText = rawText;
|
|
|
|
try {
|
|
const json = JSON.parse(rawText);
|
|
resultText = JSON.stringify(json, null, 2);
|
|
} catch (e) {}
|
|
|
|
const badgeClass = status >= 200 && status < 300 ? 'tester-status-200' : 'tester-status-error';
|
|
|
|
responseContainer.innerHTML = `
|
|
<div class="tester-badge ${badgeClass}">Status: ${status}</div>
|
|
<pre id="tester-output-content"></pre>
|
|
`;
|
|
document.getElementById('tester-output-content').textContent = resultText;
|
|
|
|
} catch (error) {
|
|
responseContainer.innerHTML = `<div style="color:#dc3545; padding: 10px;">Fehler: ${error.message}</div>`;
|
|
}
|
|
}
|
|
|
|
// Initial check
|
|
checkEndpoint();
|
|
</script>
|