161 lines
6.0 KiB
PHP
161 lines
6.0 KiB
PHP
<?php
|
|
/**
|
|
* Fociz Board & Timeline Integratie Helper
|
|
* Biedt functies om taken / e-mails / Jira tickets direct als kaarten toe te voegen aan Kanban-borden en Project Tijdlijnen.
|
|
*/
|
|
|
|
require_once __DIR__ . '/auth.php';
|
|
|
|
/**
|
|
* Haalt alle actieve borden op waar de gebruiker toegang toe heeft, inclusief kolommen (lanes).
|
|
*/
|
|
function fociz_get_user_boards_with_lanes(PDO $db, int $userId, bool $isAdmin): array {
|
|
if ($isAdmin) {
|
|
$stmt = $db->query("
|
|
SELECT b.id, b.title, b.description, b.created_by_id
|
|
FROM boards b
|
|
WHERE b.is_archived = 0
|
|
ORDER BY b.id ASC
|
|
");
|
|
$boards = $stmt->fetchAll();
|
|
} else {
|
|
$stmt = $db->prepare("
|
|
SELECT b.id, b.title, b.description, b.created_by_id
|
|
FROM boards b
|
|
JOIN board_members bm ON b.id = bm.board_id
|
|
WHERE bm.user_id = ? AND b.is_archived = 0
|
|
ORDER BY b.id ASC
|
|
");
|
|
$stmt->execute([$userId]);
|
|
$boards = $stmt->fetchAll();
|
|
}
|
|
|
|
if (empty($boards)) {
|
|
return [];
|
|
}
|
|
|
|
$boardIds = array_map(fn($b) => (int)$b['id'], $boards);
|
|
$placeholders = implode(',', array_fill(0, count($boardIds), '?'));
|
|
|
|
$laneStmt = $db->prepare("
|
|
SELECT id, board_id, title, color, position
|
|
FROM board_lanes
|
|
WHERE board_id IN ({$placeholders})
|
|
ORDER BY position ASC, id ASC
|
|
");
|
|
$laneStmt->execute($boardIds);
|
|
$lanes = $laneStmt->fetchAll();
|
|
|
|
$lanesByBoard = [];
|
|
foreach ($lanes as $lane) {
|
|
$bId = (int)$lane['board_id'];
|
|
$lanesByBoard[$bId][] = $lane;
|
|
}
|
|
|
|
foreach ($boards as &$b) {
|
|
$bId = (int)$b['id'];
|
|
$b['lanes'] = $lanesByBoard[$bId] ?? [];
|
|
}
|
|
unset($b);
|
|
|
|
return $boards;
|
|
}
|
|
|
|
/**
|
|
* Voegt een item toe aan een Kanban bord en optioneel aan de Project Tijdlijn.
|
|
*
|
|
* @param PDO $db Database verbinding
|
|
* @param int $userId ID van de gebruiker
|
|
* @param bool $isAdmin Is gebruiker admin
|
|
* @param array $data Data array met:
|
|
* - board_id (int)
|
|
* - lane_id (int, optioneel - defaults naar 1e lane)
|
|
* - title (string)
|
|
* - description (string, optioneel)
|
|
* - priority ('P1'|'P2'|'P3', optioneel)
|
|
* - color (string, optioneel)
|
|
* - schedule_on_timeline (bool, optioneel)
|
|
* - start_date (string 'YYYY-MM-DD', optioneel)
|
|
* - end_date (string 'YYYY-MM-DD', optioneel)
|
|
* - start_time (string 'HH:MM', optioneel)
|
|
* - end_time (string 'HH:MM', optioneel)
|
|
* - sync_outlook (bool, optioneel)
|
|
* @return array ['success' => bool, 'card_id' => int, 'message' => string]
|
|
*/
|
|
function fociz_add_item_to_board_and_timeline(PDO $db, int $userId, bool $isAdmin, array $data): array {
|
|
$boardId = (int)($data['board_id'] ?? 0);
|
|
$title = trim($data['title'] ?? '');
|
|
if ($boardId <= 0 || empty($title)) {
|
|
return ['success' => false, 'error' => 'Geldig bord en titel zijn verplicht.'];
|
|
}
|
|
|
|
// Autorisatiecheck
|
|
if (!$isAdmin) {
|
|
$stmtCheck = $db->prepare("SELECT COUNT(*) FROM board_members WHERE board_id = ? AND user_id = ?");
|
|
$stmtCheck->execute([$boardId, $userId]);
|
|
if ((int)$stmtCheck->fetchColumn() === 0) {
|
|
return ['success' => false, 'error' => 'Geen toegang tot dit bord.'];
|
|
}
|
|
}
|
|
|
|
$laneId = (int)($data['lane_id'] ?? 0);
|
|
if ($laneId <= 0) {
|
|
$stmtLane = $db->prepare("SELECT id FROM board_lanes WHERE board_id = ? ORDER BY position ASC, id ASC LIMIT 1");
|
|
$stmtLane->execute([$boardId]);
|
|
$laneId = (int)$stmtLane->fetchColumn();
|
|
}
|
|
|
|
if ($laneId <= 0) {
|
|
return ['success' => false, 'error' => 'Het geselecteerde bord heeft geen kolommen.'];
|
|
}
|
|
|
|
$description = trim($data['description'] ?? '');
|
|
$priority = in_array($data['priority'] ?? '', ['P1', 'P2', 'P3']) ? $data['priority'] : 'P2';
|
|
$color = in_array($data['color'] ?? '', ['yellow', 'blue', 'green', 'purple', 'pink', 'orange', 'slate', 'indigo']) ? $data['color'] : 'blue';
|
|
|
|
$stmtMax = $db->prepare("SELECT COALESCE(MAX(position), -1) FROM board_cards WHERE lane_id = ?");
|
|
$stmtMax->execute([$laneId]);
|
|
$maxPos = (int)$stmtMax->fetchColumn();
|
|
|
|
$stmtInsert = $db->prepare("
|
|
INSERT INTO board_cards (board_id, lane_id, title, description, assignee_id, priority, color, position, created_by_id)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
");
|
|
$stmtInsert->execute([$boardId, $laneId, $title, $description, $userId, $priority, $color, $maxPos + 1, $userId]);
|
|
$cardId = (int)$db->lastInsertId();
|
|
|
|
// Optioneel inplannen op Tijdlijn / Gantt
|
|
$scheduleOnTimeline = !empty($data['schedule_on_timeline']);
|
|
if ($scheduleOnTimeline && $cardId > 0) {
|
|
$startDate = !empty($data['start_date']) ? trim($data['start_date']) : date('Y-m-d');
|
|
$endDate = !empty($data['end_date']) ? trim($data['end_date']) : $startDate;
|
|
$startTime = !empty($data['start_time']) ? trim($data['start_time']) : '09:00';
|
|
$endTime = !empty($data['end_time']) ? trim($data['end_time']) : '17:00';
|
|
$daysOfWeek = trim($data['days_of_week'] ?? '1,2,3,4,5');
|
|
|
|
$stmtSched = $db->prepare("
|
|
INSERT INTO board_card_schedules (card_id, schedule_type, start_date, end_date, start_time, end_time, days_of_week)
|
|
VALUES (?, 'DAILY_RANGE', ?, ?, ?, ?, ?)
|
|
ON DUPLICATE KEY UPDATE
|
|
start_date = VALUES(start_date),
|
|
end_date = VALUES(end_date),
|
|
start_time = VALUES(start_time),
|
|
end_time = VALUES(end_time),
|
|
days_of_week = VALUES(days_of_week)
|
|
");
|
|
$stmtSched->execute([$cardId, $startDate, $endDate, $startTime, $endTime, $daysOfWeek]);
|
|
}
|
|
|
|
return [
|
|
'success' => true,
|
|
'card_id' => $cardId,
|
|
'board_id' => $boardId,
|
|
'lane_id' => $laneId,
|
|
'scheduled_on_timeline' => $scheduleOnTimeline,
|
|
'message' => $scheduleOnTimeline
|
|
? 'Item succesvol toegevoegd aan het Bord en ingepland op de Tijdlijn!'
|
|
: 'Item succesvol toegevoegd aan het Bord!'
|
|
];
|
|
}
|
|
|