Jira 26
This commit is contained in:
+2
-2
@@ -972,7 +972,7 @@ function get_logged_in_user(): ?array {
|
||||
return null;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare("SELECT id, name, email, role, two_factor_enabled, avatar_url, theme, notification_settings, default_jira_filter_code, fociz_widget_layout, created_at FROM users WHERE id = ?");
|
||||
$stmt = $db->prepare("SELECT id, name, email, role, two_factor_enabled, avatar_url, theme, notification_settings, default_jira_filter_code, default_jira_filter_codes, fociz_widget_layout, created_at FROM users WHERE id = ?");
|
||||
$stmt->execute([$_SESSION['user_id']]);
|
||||
$user = $stmt->fetch();
|
||||
if ($user) {
|
||||
@@ -1022,7 +1022,7 @@ function get_logged_in_user(): ?array {
|
||||
// 3. Fallback dagsessie-token: herstelt sessie na browserherstart (uitsluitend vandaag én mits niet inactief!)
|
||||
$dayToken = $_COOKIE['fociz_day_session'] ?? ($_COOKIE['fociz_remember'] ?? null);
|
||||
if (!empty($dayToken) && is_string($dayToken)) {
|
||||
$stmt = $db->prepare("SELECT id, name, email, role, two_factor_enabled, avatar_url, theme, notification_settings, default_jira_filter_code, fociz_widget_layout, last_activity_at, last_login_at, created_at FROM users WHERE remember_token = ? AND remember_token_expires_at >= NOW() AND DATE(remember_token_expires_at) = ?");
|
||||
$stmt = $db->prepare("SELECT id, name, email, role, two_factor_enabled, avatar_url, theme, notification_settings, default_jira_filter_code, default_jira_filter_codes, fociz_widget_layout, last_activity_at, last_login_at, created_at FROM users WHERE remember_token = ? AND remember_token_expires_at >= NOW() AND DATE(remember_token_expires_at) = ?");
|
||||
$stmt->execute([$dayToken, $today]);
|
||||
$user = $stmt->fetch();
|
||||
if ($user) {
|
||||
|
||||
+170
-68
@@ -435,71 +435,136 @@ function jira_fetch_issues(string $domain, string $email, string $apiToken, stri
|
||||
'customfield_10028', // Story Points (alternatief veld sommige instanties)
|
||||
];
|
||||
|
||||
// 1. Moderne Atlassian Jira Cloud endpoint (/rest/api/3/search/jql) conform CHANGE-2046 via POST
|
||||
$url = $cleanDomain . '/rest/api/3/search/jql';
|
||||
$payload = [
|
||||
'jql' => $jql,
|
||||
'maxResults' => min($maxResults, 100),
|
||||
'fields' => $fieldsList,
|
||||
];
|
||||
$allRawIssues = [];
|
||||
$nextPageToken = null;
|
||||
$startAt = 0;
|
||||
$pageSize = 100;
|
||||
$maxPages = (int)ceil($maxResults / $pageSize);
|
||||
$useMethod = 'v3_post'; // 'v3_post', 'v3_get', 'v2_get'
|
||||
|
||||
$response = fociz_http_request($url, [
|
||||
'method' => 'POST',
|
||||
'headers' => [
|
||||
'Authorization' => $authHeader,
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
'body' => $payload,
|
||||
'timeout' => 12,
|
||||
]);
|
||||
for ($page = 0; $page < $maxPages; $page++) {
|
||||
$needed = $maxResults - count($allRawIssues);
|
||||
if ($needed <= 0) break;
|
||||
$currentPageSize = min($pageSize, $needed);
|
||||
|
||||
// 2. Fallback: GET /rest/api/3/search/jql met query parameters indien de instantie GET vereist
|
||||
if ($response['status'] === 405 || $response['status'] === 400) {
|
||||
$getParams = [
|
||||
'jql' => $jql,
|
||||
'maxResults' => min($maxResults, 100),
|
||||
'fields' => implode(',', $fieldsList),
|
||||
];
|
||||
$urlGet = $cleanDomain . '/rest/api/3/search/jql?' . http_build_query($getParams);
|
||||
$response = fociz_http_request($urlGet, [
|
||||
'method' => 'GET',
|
||||
'headers' => [
|
||||
'Authorization' => $authHeader,
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
'timeout' => 12,
|
||||
]);
|
||||
$response = null;
|
||||
|
||||
// 1. Moderne Atlassian Jira Cloud endpoint (/rest/api/3/search/jql) conform CHANGE-2046 via POST
|
||||
if ($useMethod === 'v3_post') {
|
||||
$url = $cleanDomain . '/rest/api/3/search/jql';
|
||||
$payload = [
|
||||
'jql' => $jql,
|
||||
'maxResults' => $currentPageSize,
|
||||
'fields' => $fieldsList,
|
||||
];
|
||||
if (!empty($nextPageToken)) {
|
||||
$payload['nextPageToken'] = $nextPageToken;
|
||||
}
|
||||
|
||||
$response = fociz_http_request($url, [
|
||||
'method' => 'POST',
|
||||
'headers' => [
|
||||
'Authorization' => $authHeader,
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
'body' => $payload,
|
||||
'timeout' => 12,
|
||||
]);
|
||||
|
||||
if ($response['status'] === 405 || $response['status'] === 400) {
|
||||
$useMethod = 'v3_get';
|
||||
} elseif ($response['status'] === 404) {
|
||||
$useMethod = 'v2_get';
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Fallback: GET /rest/api/3/search/jql met query parameters indien de instantie GET vereist
|
||||
if ($useMethod === 'v3_get') {
|
||||
$getParams = [
|
||||
'jql' => $jql,
|
||||
'maxResults' => $currentPageSize,
|
||||
'fields' => implode(',', $fieldsList),
|
||||
];
|
||||
if (!empty($nextPageToken)) {
|
||||
$getParams['nextPageToken'] = $nextPageToken;
|
||||
} elseif ($startAt > 0) {
|
||||
$getParams['startAt'] = $startAt;
|
||||
}
|
||||
$urlGet = $cleanDomain . '/rest/api/3/search/jql?' . http_build_query($getParams);
|
||||
$response = fociz_http_request($urlGet, [
|
||||
'method' => 'GET',
|
||||
'headers' => [
|
||||
'Authorization' => $authHeader,
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
'timeout' => 12,
|
||||
]);
|
||||
|
||||
if ($response['status'] === 404) {
|
||||
$useMethod = 'v2_get';
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Fallback naar API v2 voor on-premise Jira Server / Data Center installaties
|
||||
if ($useMethod === 'v2_get') {
|
||||
$getParams = [
|
||||
'jql' => $jql,
|
||||
'maxResults' => $currentPageSize,
|
||||
'startAt' => $startAt,
|
||||
'fields' => implode(',', $fieldsList),
|
||||
];
|
||||
$urlV2 = $cleanDomain . '/rest/api/2/search?' . http_build_query($getParams);
|
||||
$response = fociz_http_request($urlV2, [
|
||||
'method' => 'GET',
|
||||
'headers' => [
|
||||
'Authorization' => $authHeader,
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
'timeout' => 12,
|
||||
]);
|
||||
}
|
||||
|
||||
if (!$response || $response['status'] !== 200 || !isset($response['json']['issues']) || !is_array($response['json']['issues'])) {
|
||||
if ($page === 0) {
|
||||
$errorMsg = $response['json']['errorMessages'][0] ?? ($response['json']['message'] ?? ($response['error'] ?? 'Kan Jira tickets niet ophalen'));
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => $errorMsg,
|
||||
'issues' => [],
|
||||
];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$pageIssues = $response['json']['issues'];
|
||||
if (empty($pageIssues)) {
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($pageIssues as $pi) {
|
||||
$allRawIssues[] = $pi;
|
||||
}
|
||||
|
||||
$nextPageToken = $response['json']['nextPageToken'] ?? null;
|
||||
$totalInApi = (int)($response['json']['total'] ?? 0);
|
||||
$startAt += count($pageIssues);
|
||||
|
||||
// Geen volgende pagina meer
|
||||
if (empty($nextPageToken)) {
|
||||
if ($totalInApi > 0 && $startAt >= $totalInApi) {
|
||||
break;
|
||||
}
|
||||
if ($useMethod === 'v3_post') {
|
||||
break;
|
||||
}
|
||||
if (count($pageIssues) < $currentPageSize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Fallback naar API v2 voor on-premise Jira Server / Data Center installaties (waar /rest/api/2/search actief is)
|
||||
if ($response['status'] === 404) {
|
||||
$getParams = [
|
||||
'jql' => $jql,
|
||||
'maxResults' => min($maxResults, 100),
|
||||
'fields' => implode(',', $fieldsList),
|
||||
];
|
||||
$urlV2 = $cleanDomain . '/rest/api/2/search?' . http_build_query($getParams);
|
||||
$response = fociz_http_request($urlV2, [
|
||||
'method' => 'GET',
|
||||
'headers' => [
|
||||
'Authorization' => $authHeader,
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
'timeout' => 12,
|
||||
]);
|
||||
}
|
||||
|
||||
if ($response['status'] !== 200 || !isset($response['json']['issues'])) {
|
||||
$errorMsg = $response['json']['errorMessages'][0] ?? ($response['json']['message'] ?? ($response['error'] ?? 'Kan Jira tickets niet ophalen'));
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => $errorMsg,
|
||||
'issues' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$rawIssues = $response['json']['issues'];
|
||||
$rawIssues = $allRawIssues;
|
||||
$issues = [];
|
||||
|
||||
foreach ($rawIssues as $item) {
|
||||
@@ -631,7 +696,7 @@ function jira_fetch_issues(string $domain, string $email, string $apiToken, stri
|
||||
/**
|
||||
* Haalt alle actieve issues op die zijn toegewezen aan de ingelogde Jira gebruiker
|
||||
*/
|
||||
function jira_fetch_assigned_issues(string $domain, string $email, string $apiToken, int $maxResults = 100): array {
|
||||
function jira_fetch_assigned_issues(string $domain, string $email, string $apiToken, int $maxResults = 250): array {
|
||||
$jql = 'assignee = currentUser() ORDER BY updated DESC';
|
||||
return jira_fetch_issues($domain, $email, $apiToken, $jql, $maxResults);
|
||||
}
|
||||
@@ -639,8 +704,18 @@ function jira_fetch_assigned_issues(string $domain, string $email, string $apiTo
|
||||
/**
|
||||
* Haalt openstaande team issues op die horen bij de projecten van de gebruiker
|
||||
*/
|
||||
function jira_fetch_team_issues(string $domain, string $email, string $apiToken, int $maxResults = 100): array {
|
||||
$jql = 'assignee != currentUser() AND statusCategory != Done ORDER BY updated DESC';
|
||||
function jira_fetch_team_issues(string $domain, string $email, string $apiToken, $projectKeys = [], int $maxResults = 500): array {
|
||||
if (is_int($projectKeys)) {
|
||||
$maxResults = $projectKeys;
|
||||
$projectKeys = [];
|
||||
}
|
||||
$cleanKeys = array_values(array_filter(array_map('strtoupper', array_map('trim', (array)$projectKeys))));
|
||||
$projClause = '';
|
||||
if (!empty($cleanKeys)) {
|
||||
$escaped = array_map(function($k) { return '"' . addslashes($k) . '"'; }, $cleanKeys);
|
||||
$projClause = 'project in (' . implode(', ', $escaped) . ') AND ';
|
||||
}
|
||||
$jql = $projClause . 'statusCategory != Done ORDER BY updated DESC';
|
||||
return jira_fetch_issues($domain, $email, $apiToken, $jql, $maxResults);
|
||||
}
|
||||
|
||||
@@ -1126,10 +1201,37 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
|
||||
}
|
||||
}
|
||||
|
||||
// Ophalen van toegewezen taken (max 100)
|
||||
$assignedRes = jira_fetch_assigned_issues($domain, $email, $apiToken, 100);
|
||||
// Ophalen van teamtaken (max 100)
|
||||
$teamRes = jira_fetch_team_issues($domain, $email, $apiToken, 100);
|
||||
// Ophalen van toegewezen taken (max 250)
|
||||
$assignedRes = jira_fetch_assigned_issues($domain, $email, $apiToken, 250);
|
||||
|
||||
// Bepaal de relevante projecten van de gebruiker om gericht en compleet op te halen
|
||||
$targetProjKeys = [];
|
||||
if (!empty($userQueuePrefs)) {
|
||||
foreach ($userQueuePrefs as $code) {
|
||||
$c = strtoupper(trim($code));
|
||||
if ($c === 'DX') {
|
||||
$targetProjKeys['SD'] = true;
|
||||
} elseif (!in_array($c, ['MY_QUEUES'], true)) {
|
||||
$foundProj = false;
|
||||
foreach ($queueFilters as $qf) {
|
||||
if (strtoupper(trim($qf['filter_code'] ?? '')) === $c && !empty($qf['project_key'])) {
|
||||
$targetProjKeys[strtoupper(trim($qf['project_key']))] = true;
|
||||
$foundProj = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$foundProj && strlen($c) <= 10) {
|
||||
$targetProjKeys[$c] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($targetProjKeys)) {
|
||||
$targetProjKeys = array_fill_keys(['SD', 'IN', 'AAN', 'GEN'], true);
|
||||
}
|
||||
|
||||
// Ophalen van teamtaken binnen de relevante projecten (met paginatie tot max 500)
|
||||
$teamRes = jira_fetch_team_issues($domain, $email, $apiToken, array_keys($targetProjKeys), 500);
|
||||
// Ophalen van Jira statussen
|
||||
$availableStatuses = jira_fetch_statuses($domain, $email, $apiToken);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user