Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions app/Domain/Tickets/Repositories/Tickets.php
Original file line number Diff line number Diff line change
Expand Up @@ -1884,6 +1884,26 @@ public function getStatusChangeEvents(array $ticketIds, string $fromDate, string
return $events;
}

/**
* Distinct ticket ids the given user COMMENTED on within [from, to]
* (inclusive, 'Y-m-d'). Access-agnostic on its own — callers must
* intersect the result with an access-scoped ticket set (e.g.
* simpleTicketQuery) before returning anything, so this never widens
* visibility. Used by getMyCommentedTicketsForRange for Progress "Supported".
*/
public function getTicketIdsCommentedByUser(int $userId, string $fromDate, string $toDate): array
{
$rows = $this->connection->table('zp_comment')
->select('moduleId')
->distinct()
->where('module', 'ticket')
->where('userId', $userId)
->whereBetween('date', [$fromDate.' 00:00:00', $toDate.' 23:59:59'])
->get();
Comment on lines +1942 to +1963
Comment on lines +1960 to +1963

return array_values(array_unique(array_map(fn ($row) => (int) $row->moduleId, $rows->all())));
}

/**
* Get all tasks (and optionally subtasks) that belong to a milestone
/**
Expand Down
64 changes: 64 additions & 0 deletions app/Domain/Tickets/Services/Tickets.php
Original file line number Diff line number Diff line change
Expand Up @@ -2457,6 +2457,70 @@ public function getMyClosedTicketsForDate(?int $userId = null, ?string $date = n
return array_values($closed);
}

/**
* @api
*
* Tickets the user COMMENTED on within [$from, $to] that they do NOT own
* (they're not the assignee/editor) — i.e. work they supported by weighing
* in on someone else's arc. Powers the mobile Progress "Supported" section
Comment on lines +2516 to +2518
* (presence counts as much as production).
*
* Access safety: the commented-ticket ids are intersected with the user's
* access-scoped ticket set (simpleTicketQuery applies the project-access +
* collaborator clause), so a comment can never surface a ticket the user
* can no longer see. Ownership filter drops tickets where the user IS the
* editor — those are "your work," not support. Defaults either bound to
* today.
*
* @return array<int, array<string, mixed>> ticket rows (id, headline,
* projectName, …), same shape as the other user-ticket queries.
*/
#[RequiresPermission(TicketsPermissions::VIEW)]
public function getMyCommentedTicketsForRange(?int $userId = null, ?string $from = null, ?string $to = null): array
{
Comment on lines +2542 to +2544
$userId = $userId ?? (int) session('userdata.id');
if ($userId === 0) {
return [];
}
$from = $from ?: date('Y-m-d');
$to = $to ?: date('Y-m-d');
if ($from > $to) {
[$from, $to] = [$to, $from];
}
Comment on lines +2542 to +2560

$commentedIds = $this->ticketRepository->getTicketIdsCommentedByUser($userId, $from, $to);
if (empty($commentedIds)) {
return [];
}

// Access-scoped universe — never returns a ticket outside the user's
// project access, so intersecting against it makes the comment lookup
// safe regardless of what was commented on historically.
$accessible = $this->ticketRepository->simpleTicketQuery($userId, null);
if (! is_array($accessible) || empty($accessible)) {
return [];
}
$byId = [];
foreach ($accessible as $ticket) {
$byId[(int) $ticket['id']] = $ticket;
}

$commentedLookup = array_flip($commentedIds);
$out = [];
foreach ($byId as $id => $ticket) {
if (! isset($commentedLookup[$id])) {
continue;
}
// "Supported", not "yours": drop tickets you're the editor of.
if ((string) ($ticket['editorId'] ?? '') === (string) $userId) {
continue;
}
$out[] = $ticket;
}

return array_values($out);
}

/**
* @api
*
Expand Down
Loading