load(); header('Content-Type: application/json'); 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 commercials c ON t.commercial_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 commercials c ON t.commercial_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); } } // Mark as pending sync if changed $updates[] = "api_status = 'pending'"; // 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 $stmt = $db->prepare(" SELECT t.*, c.title, c.color_code, c.series_code FROM transmissions t JOIN commercials c ON t.commercial_id = c.id WHERE t.id = ? "); $stmt->execute([$input['id']]); $updated = $stmt->fetch(); jsonResponse([ 'success' => true, 'message' => 'Transmission updated successfully', 'transmission' => $updated ]); } catch (Exception $e) { jsonResponse([ 'success' => false, 'error' => $e->getMessage() ], 500); }