load(); header('Content-Type: application/json'); // Authentication check if (!isLoggedIn()) { http_response_code(401); echo json_encode(['success' => false, 'error' => 'Niet geautoriseerd. Log eerst in.']); exit; } // Authorization check - admin only if (!canEdit()) { http_response_code(403); echo json_encode(['success' => false, 'error' => 'Geen toegang. Alleen admins kunnen uitzendingen bijwerken.']); exit; } try { $db = getDbConnection(); // Get POST data $input = json_decode(file_get_contents('php://input'), true); if (!$input) { $input = $_POST; } // Validate required fields if (empty($input['id'])) { jsonResponse([ 'success' => false, 'error' => 'Missing transmission ID' ], 400); } // Get existing transmission $stmt = $db->prepare(" SELECT t.*, c.duration FROM transmissions t JOIN infomercials c ON t.infomercial_id = c.id WHERE t.id = ? "); $stmt->execute([$input['id']]); $transmission = $stmt->fetch(); if (!$transmission) { jsonResponse([ 'success' => false, 'error' => 'Transmission not found' ], 404); } // Prepare update data $updates = []; $params = []; if (isset($input['start_date']) && isValidDate($input['start_date'])) { $updates[] = 'start_date = ?'; $params[] = $input['start_date']; } else { $params[] = $transmission['start_date']; } if (isset($input['start_time']) && isValidTime($input['start_time'])) { $updates[] = 'start_time = ?'; $params[] = $input['start_time']; } else { $params[] = $transmission['start_time']; } if (isset($input['channel'])) { $updates[] = 'channel = ?'; $params[] = $input['channel']; } else { $params[] = $transmission['channel']; } // Check for overlaps with new position $checkDate = $params[0]; $checkTime = $params[1]; $checkChannel = $params[2]; $endTime = addTimeToTime($checkTime, $transmission['duration']); // Validate that transmission falls within a block (inline to avoid curl issues) ensureDailyBlocks($db, $checkDate, $checkDate); $stmt = $db->prepare(" SELECT * FROM daily_blocks WHERE block_date = ? AND channel = ? ORDER BY actual_start_time "); $stmt->execute([$checkDate, $checkChannel]); $blocks = $stmt->fetchAll(); $withinBlock = false; foreach ($blocks as $block) { $blockStart = $block['actual_start_time']; $blockEnd = $block['actual_end_time'] ?? '23:59:59'; // Handle overnight blocks $isOvernight = $blockEnd < $blockStart; if ($isOvernight) { if ($checkTime >= $blockStart || $checkTime < $blockEnd) { if ($endTime <= $blockEnd || $endTime >= $blockStart) { $withinBlock = true; break; } } } else { if ($checkTime >= $blockStart && $endTime <= $blockEnd) { $withinBlock = true; break; } } } if (!$withinBlock) { $errorMessage = "Uitzending valt buiten blok tijden. "; if (!empty($blocks)) { $errorMessage .= "Beschikbare blokken: "; foreach ($blocks as $block) { $blockStart = substr($block['actual_start_time'], 0, 5); $blockEnd = $block['actual_end_time'] ? substr($block['actual_end_time'], 0, 5) : '∞'; $errorMessage .= "{$blockStart}-{$blockEnd}, "; } $errorMessage = rtrim($errorMessage, ', '); } jsonResponse([ 'success' => false, 'error' => $errorMessage, 'attempted_time' => $checkTime . ' - ' . $endTime ], 400); } $stmt = $db->prepare(" SELECT t.id, t.start_time, t.duration, c.title FROM transmissions t JOIN infomercials c ON t.infomercial_id = c.id WHERE t.start_date = ? AND t.channel = ? AND t.id != ? "); $stmt->execute([$checkDate, $checkChannel, $input['id']]); $existing = $stmt->fetchAll(); foreach ($existing as $tx) { $txEnd = addTimeToTime($tx['start_time'], $tx['duration']); if (timeRangesOverlap($checkTime, $endTime, $tx['start_time'], $txEnd)) { jsonResponse([ 'success' => false, 'error' => "Overlap detected with: {$tx['title']} ({$tx['start_time']} - {$txEnd})", 'overlap' => true ], 409); } } // Build and execute update query if (!empty($updates)) { $sql = "UPDATE transmissions SET " . implode(', ', $updates) . " WHERE id = ?"; $params[] = $input['id']; $stmt = $db->prepare($sql); $stmt->execute($params); } // Get updated transmission with all details including content_id $stmt = $db->prepare(" SELECT t.*, c.title, c.color_code, c.series_code, c.content_id FROM transmissions t JOIN infomercials c ON t.infomercial_id = c.id WHERE t.id = ? "); $stmt->execute([$input['id']]); $updated = $stmt->fetch(); // Sync to Talpa if transmission has talpa_transmission_id $talpaResult = null; if (!empty($updated['talpa_transmission_id'])) { $api = new TalpaApi(); $talpaResult = syncTransmissionToTalpa($db, $api, $updated); // If sync failed, log it but don't fail the request if (!$talpaResult['success']) { error_log("Talpa sync failed for transmission {$updated['id']}: " . $talpaResult['error']); } } // Determine which block this transmission belongs to $stmt = $db->prepare(" SELECT id FROM daily_blocks WHERE block_date = ? AND channel = ? AND actual_start_time <= ? AND (actual_end_time IS NULL OR actual_end_time > ?) LIMIT 1 "); $stmt->execute([ $updated['start_date'], $updated['channel'], $updated['start_time'], $updated['start_time'] ]); $block = $stmt->fetch(); // Update all other transmissions in the same block $blockUpdateResult = null; if ($block && !empty($updated['talpa_transmission_id'])) { $api = new TalpaApi(); $blockUpdateResult = updateBlockTransmissionsToTalpa( $db, $api, $updated['start_date'], $updated['channel'], $block['id'] ); } jsonResponse([ 'success' => true, 'message' => 'Transmission updated successfully', 'transmission' => $updated, 'talpa_sync' => $talpaResult, 'block_update' => $blockUpdateResult ]); } catch (Exception $e) { jsonResponse([ 'success' => false, 'error' => $e->getMessage() ], 500); }