telvero_whatson_talpa/infomercials.php

660 lines
34 KiB
PHP

<?php
/**
* Infomercial Management
* Enhanced version of infomercial registration with color management
*/
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/TalpaAPI.php';
require_once __DIR__ . '/helpers.php';
use Dotenv\Dotenv;
$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();
$api = new TalpaApi();
$db = getDbConnection();
$apiLogs = [];
// Retrieve and clear refresh logs from session
session_start();
$refreshLogs = $_SESSION['refresh_logs'] ?? null;
if ($refreshLogs) {
unset($_SESSION['refresh_logs']);
}
// Handle infomercial registration
if (isset($_POST['add_commercial'])) {
$apiLogs[] = ['step' => 'Start registration', 'input' => $_POST];
$ep = $api->createEpisode($_POST['title'], $_POST['duration'], $_POST['season_id']);
$apiLogs[] = ['call' => 'Create Episode', 'request' => [
'title' => $_POST['title'],
'duration' => $_POST['duration'],
'season_id' => $_POST['season_id']
], 'response' => $api->lastResponse];
if (isset($ep['id'])) {
$apiLogs[] = ['step' => 'Episode created', 'episode_id' => $ep['id']];
$asset = $api->createMediaAsset($ep['id']);
$apiLogs[] = ['call' => 'Create Media Asset', 'request' => [
'content_id' => $ep['id']
], 'response' => $api->lastResponse];
if (isset($asset['id'])) {
$apiLogs[] = ['step' => 'Media asset created', 'asset_id' => $asset['id']];
$details = $api->getMediaAssetDetails($asset['id']);
$apiLogs[] = ['call' => 'Get Media Asset Details', 'request' => [
'asset_id' => $asset['id']
], 'response' => $api->lastResponse];
$label = $details['mediaAssetLabel'] ?? 'Pending';
$apiLogs[] = ['step' => 'Media asset label', 'label' => $label];
// Auto-generate color
$stmt = $db->query("SELECT color_code FROM infomercials WHERE color_code IS NOT NULL");
$existingColors = $stmt->fetchAll(PDO::FETCH_COLUMN);
$colorCode = generateDistinctColor($existingColors);
$apiLogs[] = ['step' => 'Color generated', 'color' => $colorCode];
$stmt = $db->prepare("
INSERT INTO infomercials
(title, duration, season_id, content_id, media_asset_id, media_asset_label, upload_status, color_code, series_code)
VALUES (?, ?, ?, ?, ?, ?, 'pending', ?, ?)
");
$stmt->execute([
$_POST['title'],
$_POST['duration'],
$_POST['season_id'],
$ep['id'],
$asset['id'],
$label,
$colorCode,
$_POST['series_code'] ?? null
]);
$apiLogs[] = ['step' => 'Database insert', 'success' => true];
header('Location: infomercials.php?success=created');
exit;
} else {
$apiLogs[] = ['step' => 'Media asset creation failed', 'response' => $asset];
}
} else {
$apiLogs[] = ['step' => 'Episode creation failed', 'response' => $ep];
}
}
// Handle infomercial update (sync to Talpa)
if (isset($_POST['update_infomercial'])) {
// Get current infomercial data
$stmt = $db->prepare("SELECT content_id, title, duration FROM infomercials WHERE id = ?");
$stmt->execute([$_POST['infomercial_id']]);
$current = $stmt->fetch();
if ($current && $current['content_id']) {
// Update in Talpa if title or duration changed
$titleChanged = $current['title'] !== $_POST['title'];
$durationChanged = $current['duration'] !== $_POST['duration'];
if ($titleChanged || $durationChanged) {
$result = $api->updateEpisode(
$current['content_id'],
$_POST['title'],
$_POST['duration']
);
$apiLogs[] = ['call' => 'Update Episode', 'request' => [
'content_id' => $current['content_id'],
'title' => $_POST['title'],
'duration' => $_POST['duration']
], 'response' => $api->lastResponse];
}
// Update in local database
$stmt = $db->prepare("
UPDATE infomercials
SET title = ?, duration = ?, upload_status = ?, series_code = ?, color_code = ?
WHERE id = ?
");
$stmt->execute([
$_POST['title'],
$_POST['duration'],
$_POST['upload_status'],
$_POST['series_code'] ?? null,
$_POST['color_code'],
$_POST['infomercial_id']
]);
header('Location: infomercials.php?success=updated');
exit;
}
}
// Handle refresh single infomercial from Talpa
if (isset($_POST['refresh_infomercial'])) {
$stmt = $db->prepare("SELECT title, media_asset_id FROM infomercials WHERE id = ?");
$stmt->execute([$_POST['infomercial_id']]);
$infomercial = $stmt->fetch();
if ($infomercial && $infomercial['media_asset_id']) {
$details = $api->getMediaAssetDetails($infomercial['media_asset_id']);
$apiLogs[] = ['call' => 'Refresh Media Asset Details', 'request' => [
'asset_id' => $infomercial['media_asset_id']
], 'response' => $api->lastResponse];
if (isset($details['mediaAssetLabel'])) {
$stmt = $db->prepare("
UPDATE infomercials
SET media_asset_label = ?
WHERE id = ?
");
$stmt->execute([
$details['mediaAssetLabel'],
$_POST['infomercial_id']
]);
header('Location: infomercials.php?success=refreshed');
exit;
} else {
// Store failed refresh log
session_start();
$_SESSION['refresh_logs'] = [[
'status' => 'failed',
'title' => $infomercial['title'],
'asset_id' => $infomercial['media_asset_id'],
'error' => $api->lastResponse['message'] ?? 'Geen mediaAssetLabel gevonden in response'
]];
}
}
header('Location: infomercials.php?error=refresh_failed');
exit;
}
// Handle refresh all infomercials from Talpa
if (isset($_POST['refresh_all'])) {
$stmt = $db->query("SELECT id, title, media_asset_id FROM infomercials WHERE media_asset_id IS NOT NULL");
$infomercials_to_refresh = $stmt->fetchAll();
$refreshed = 0;
$failed = 0;
$refreshLogs = [];
foreach ($infomercials_to_refresh as $inf) {
$details = $api->getMediaAssetDetails($inf['media_asset_id']);
$apiLogs[] = ['call' => 'Refresh All - Media Asset Details', 'request' => [
'asset_id' => $inf['media_asset_id']
], 'response' => $api->lastResponse];
if (isset($details['mediaAssetLabel'])) {
$stmt = $db->prepare("
UPDATE infomercials
SET media_asset_label = ?
WHERE id = ?
");
$stmt->execute([
$details['mediaAssetLabel'],
$inf['id']
]);
$refreshed++;
} else {
$failed++;
// Only log failures
$refreshLogs[] = [
'status' => 'failed',
'title' => $inf['title'],
'asset_id' => $inf['media_asset_id'],
'error' => $api->lastResponse['message'] ?? 'Geen mediaAssetLabel gevonden in response'
];
}
}
// Store logs in session for display
session_start();
$_SESSION['refresh_logs'] = $refreshLogs;
header("Location: infomercials.php?success=refreshed_all&count=$refreshed&failed=$failed");
exit;
}
// Handle delete
if (isset($_POST['delete_commercial'])) {
// Check if infomercial is used in transmissions
$stmt = $db->prepare("SELECT COUNT(*) FROM transmissions WHERE infomercial_id = ?");
$stmt->execute([$_POST['infomercial_id']]);
$count = $stmt->fetchColumn();
if ($count > 0) {
header('Location: infomercials.php?error=in_use');
exit;
}
// Get infomercial details before deletion
$stmt = $db->prepare("SELECT content_id, media_asset_id FROM infomercials WHERE id = ?");
$stmt->execute([$_POST['infomercial_id']]);
$infomercial = $stmt->fetch();
// Delete from Talpa API if content_id exists
if ($infomercial && $infomercial['content_id']) {
try {
$api->deleteEpisode($infomercial['content_id']);
$apiLogs[] = ['call' => 'Delete Episode', 'response' => $api->lastResponse];
} catch (Exception $e) {
// Log error but continue with local deletion
error_log("Failed to delete episode from Talpa: " . $e->getMessage());
}
}
// Delete from local database
$stmt = $db->prepare("DELETE FROM infomercials WHERE id = ?");
$stmt->execute([$_POST['infomercial_id']]);
header('Location: infomercials.php?success=deleted');
exit;
}
// Get all infomercials
$infomercials = $db->query("
SELECT c.*,
(SELECT COUNT(*) FROM transmissions WHERE infomercial_id = c.id) as usage_count
FROM infomercials c
ORDER BY c.created_at DESC
")->fetchAll();
?>
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Infomercials - Telvero Talpa</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body class="bg-light">
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<i class="bi bi-tv"></i> Telvero Talpa Planner
</a>
<div class="navbar-nav">
<a class="nav-link" href="index.php">Dashboard</a>
<a class="nav-link" href="planner.php">Excel Planner</a>
<a class="nav-link" href="calendar.php">Kalender</a>
<a class="nav-link" href="blocks.php">Blokken</a>
<a class="nav-link active" href="infomercials.php">Infomercials</a>
</div>
</div>
</nav>
<div class="container mt-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1><i class="bi bi-collection-play"></i> Infomercial Management</h1>
<a href="calendar.php" class="btn btn-primary">
<i class="bi bi-calendar-week"></i> Naar Kalender
</a>
</div>
<?php if (isset($_GET['success'])): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<?php
$messages = [
'created' => 'Infomercial succesvol aangemaakt en geregistreerd bij Talpa!',
'updated' => 'Infomercial succesvol bijgewerkt en gesynchroniseerd naar Talpa!',
'deleted' => 'Infomercial succesvol verwijderd!',
'refreshed' => 'Infomercial succesvol ververst vanuit Talpa!',
'refreshed_all' => 'Alle infomercials succesvol ververst! (' . ($_GET['count'] ?? 0) . ' gelukt' . (($_GET['failed'] ?? 0) > 0 ? ', ' . $_GET['failed'] . ' mislukt' : '') . ')'
];
echo $messages[$_GET['success']] ?? 'Actie succesvol uitgevoerd!';
?>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<?php if (isset($_GET['error'])): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<?php
$messages = [
'in_use' => 'Deze infomercial kan niet verwijderd worden omdat deze nog in gebruik is in de planning!',
'refresh_failed' => 'Kon infomercial niet verversen vanuit Talpa!'
];
echo $messages[$_GET['error']] ?? 'Er is een fout opgetreden!';
?>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<?php if ($refreshLogs && count($refreshLogs) > 0): ?>
<div class="card shadow-sm mb-4 border-danger">
<div class="card-header bg-danger text-white">
<h5 class="mb-0">
<i class="bi bi-exclamation-triangle"></i> Refresh Fouten
</h5>
</div>
<div class="card-body">
<div class="alert alert-warning mb-3">
<i class="bi bi-info-circle"></i>
De volgende infomercials konden niet worden ververst vanuit Talpa:
</div>
<div class="table-responsive">
<table class="table table-sm mb-0">
<thead>
<tr>
<th>Infomercial</th>
<th>Asset ID</th>
<th>Foutmelding</th>
</tr>
</thead>
<tbody>
<?php foreach ($refreshLogs as $log): ?>
<tr class="table-danger">
<td><strong><?= htmlspecialchars($log['title']) ?></strong></td>
<td><code class="small"><?= htmlspecialchars($log['asset_id']) ?></code></td>
<td>
<span class="text-danger">
<i class="bi bi-exclamation-triangle"></i>
<?= htmlspecialchars($log['error']) ?>
</span>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="mt-3">
<button type="button" class="btn btn-sm btn-secondary" onclick="this.closest('.card').remove()">
<i class="bi bi-x"></i> Sluiten
</button>
</div>
</div>
</div>
<?php endif; ?>
<div class="row">
<!-- Registration Form -->
<div class="col-md-4">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h5 class="mb-0">
<i class="bi bi-plus-circle"></i> Nieuwe Infomercial Registreren
</h5>
</div>
<div class="card-body">
<form method="POST">
<div class="mb-3">
<label class="form-label">Product Naam</label>
<input type="text" name="title" class="form-control"
placeholder="bijv. Clever Cane" required>
</div>
<div class="mb-3">
<label class="form-label">Duur (HH:MM:SS)</label>
<input type="text" name="duration" class="form-control"
placeholder="00:30:00" pattern="[0-9]{2}:[0-9]{2}:[0-9]{2}" required>
<small class="text-muted">Formaat: UU:MM:SS</small>
</div>
<div class="mb-3">
<label class="form-label">Series Code (optioneel)</label>
<input type="text" name="series_code" class="form-control"
placeholder="bijv. 006a">
<small class="text-muted">Voor groepering in kalender</small>
</div>
<input type="hidden" name="season_id" value="<?= $_ENV['TV_SEASON_ID'] ?>">
<div class="d-grid">
<button type="submit" name="add_commercial" class="btn btn-primary">
<i class="bi bi-cloud-upload"></i> Registreren bij Talpa
</button>
</div>
</form>
<div class="mt-3 p-2 bg-light rounded">
<small class="text-muted">
<i class="bi bi-info-circle"></i>
Dit registreert de infomercial bij Talpa en maakt automatisch een media asset aan.
</small>
</div>
</div>
</div>
</div>
<!-- Infomercial List -->
<div class="col-md-8">
<div class="card shadow-sm">
<div class="card-header bg-secondary text-white d-flex justify-content-between align-items-center">
<h5 class="mb-0"><i class="bi bi-list-ul"></i> Geregistreerde Infomercials</h5>
<?php if (!empty($infomercials)): ?>
<form method="POST" style="display:inline;"
onsubmit="return confirm('Weet je zeker dat je alle infomercials wilt verversen vanuit Talpa?');">
<button type="submit" name="refresh_all" class="btn btn-sm btn-light" title="Ververs alle infomercials vanuit Talpa">
<i class="bi bi-arrow-clockwise"></i> Check Alles
</button>
</form>
<?php endif; ?>
</div>
<div class="card-body p-0">
<?php if (empty($infomercials)): ?>
<div class="p-4 text-center text-muted">
<i class="bi bi-inbox" style="font-size: 3rem;"></i>
<p class="mt-2">Nog geen infomercials geregistreerd</p>
</div>
<?php else: ?>
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead class="table-light">
<tr>
<th>Kleur</th>
<th>Titel</th>
<th>Duur</th>
<th>Series</th>
<th>Label</th>
<th>Status</th>
<th>Gebruik</th>
<th>Acties</th>
</tr>
</thead>
<tbody>
<?php foreach ($infomercials as $c): ?>
<tr>
<td>
<div class="color-preview"
style="background-color: <?= htmlspecialchars($c['color_code'] ?? '#cccccc') ?>;"
title="<?= htmlspecialchars($c['color_code'] ?? '#cccccc') ?>">
</div>
</td>
<td>
<strong><?= htmlspecialchars($c['title']) ?></strong>
<br>
<small class="text-muted">ID: <?= htmlspecialchars($c['content_id']) ?></small>
</td>
<td>
<span class="badge bg-info"><?= $c['duration'] ?></span>
</td>
<td>
<?= $c['series_code'] ? '<span class="badge bg-secondary">' . htmlspecialchars($c['series_code']) . '</span>' : '-' ?>
</td>
<td>
<code class="small"><?= htmlspecialchars($c['media_asset_label']) ?></code>
</td>
<td>
<?php if ($c['upload_status'] == 'uploaded'): ?>
<span class="badge bg-success">Uploaded</span>
<?php else: ?>
<span class="badge bg-warning text-dark">Pending</span>
<?php endif; ?>
</td>
<td>
<span class="badge bg-<?= $c['usage_count'] > 0 ? 'primary' : 'secondary' ?>">
<?= $c['usage_count'] ?>x
</span>
</td>
<td>
<div class="btn-group btn-group-sm">
<form method="POST" style="display:inline;">
<input type="hidden" name="infomercial_id" value="<?= $c['id'] ?>">
<button type="submit" name="refresh_infomercial"
class="btn btn-outline-info"
title="Ververs vanuit Talpa">
<i class="bi bi-arrow-clockwise"></i>
</button>
</form>
<button type="button"
class="btn btn-outline-primary"
data-bs-toggle="modal"
data-bs-target="#editModal<?= $c['id'] ?>"
title="Bewerken">
<i class="bi bi-pencil"></i>
</button>
<?php if ($c['usage_count'] == 0): ?>
<form method="POST" style="display:inline;"
onsubmit="return confirm('Weet je zeker dat je deze infomercial wilt verwijderen?');">
<input type="hidden" name="infomercial_id" value="<?= $c['id'] ?>">
<button type="submit" name="delete_commercial"
class="btn btn-outline-danger" title="Verwijderen">
<i class="bi bi-trash"></i>
</button>
</form>
<?php endif; ?>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
<!-- Edit Modals (outside the table loop) -->
<?php foreach ($infomercials as $c): ?>
<div class="modal fade" id="editModal<?= $c['id'] ?>" tabindex="-1" aria-labelledby="editModalLabel<?= $c['id'] ?>" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form method="POST">
<input type="hidden" name="infomercial_id" value="<?= $c['id'] ?>">
<div class="modal-header">
<h5 class="modal-title">Bewerk: <?= htmlspecialchars($c['title']) ?></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Titel</label>
<input type="text" name="title" class="form-control"
value="<?= htmlspecialchars($c['title']) ?>" required
id="title_<?= $c['id'] ?>">
<small class="text-muted">
<i class="bi bi-cloud-arrow-up"></i> Wordt gesynchroniseerd naar Talpa
</small>
</div>
<div class="mb-3">
<label class="form-label">Duur (HH:MM:SS)</label>
<input type="text" name="duration" class="form-control"
value="<?= htmlspecialchars($c['duration']) ?>"
pattern="[0-9]{2}:[0-9]{2}:[0-9]{2}" required>
<small class="text-muted">
<i class="bi bi-cloud-arrow-up"></i> Wordt gesynchroniseerd naar Talpa
</small>
</div>
<div class="mb-3">
<label class="form-label">Upload Status</label>
<select name="upload_status" class="form-select">
<option value="pending" <?= $c['upload_status'] == 'pending' ? 'selected' : '' ?>>Pending</option>
<option value="uploaded" <?= $c['upload_status'] == 'uploaded' ? 'selected' : '' ?>>Uploaded</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Series Code</label>
<input type="text" name="series_code" class="form-control"
value="<?= htmlspecialchars($c['series_code'] ?? '') ?>"
placeholder="bijv. 006a">
</div>
<div class="mb-3">
<label class="form-label">Kleurcode</label>
<input type="color" name="color_code" class="form-control form-control-color"
value="<?= htmlspecialchars($c['color_code'] ?? '#cccccc') ?>">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuleren</button>
<button type="submit" name="update_infomercial" class="btn btn-primary">
<i class="bi bi-cloud-arrow-up"></i> Opslaan & Sync naar Talpa
</button>
</div>
</form>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Debug: Log modal open events and check if title field is editable
document.addEventListener('DOMContentLoaded', function() {
const modals = document.querySelectorAll('[id^="editModal"]');
modals.forEach(modal => {
modal.addEventListener('shown.bs.modal', function() {
const titleInput = this.querySelector('input[name="title"]');
console.log('Modal opened:', {
modalId: this.id,
titleInput: titleInput,
isDisabled: titleInput?.disabled,
isReadonly: titleInput?.readOnly,
value: titleInput?.value
});
// Force enable the title field if it's disabled
if (titleInput) {
titleInput.disabled = false;
titleInput.readOnly = false;
console.log('Title field enabled for editing');
}
});
});
});
// API Logs to console with enhanced debugging
const apiLogs = <?= json_encode($apiLogs) ?>;
if (apiLogs.length > 0) {
console.group("🔍 Talpa API Debug Logs - Infomercial Registration");
apiLogs.forEach((log, index) => {
if (log.call) {
console.group(`${index + 1}. ${log.call}`);
if (log.request) {
console.log("%cRequest:", "color: #3498db; font-weight: bold;", log.request);
}
console.log("%cResponse:", "color: #2ecc71; font-weight: bold;", log.response);
console.groupEnd();
} else if (log.step) {
console.log(`%c${log.step}`, "color: #9b59b6; font-weight: bold;", log);
}
});
console.groupEnd();
// Show summary
const hasErrors = apiLogs.some(log =>
(log.step && log.step.includes('failed')) ||
(log.response && log.response.error)
);
if (hasErrors) {
console.warn("⚠️ Er zijn fouten opgetreden tijdens de registratie. Zie bovenstaande logs voor details.");
} else {
console.log("✅ Infomercial registratie succesvol voltooid");
}
}
</script>
</body>
</html>