mirror of
https://github.com/nextcloud/server.git
synced 2026-04-21 14:23:17 -04:00
Merge pull request #58697 from nextcloud/feat/add-calendar-name-to-search-result
Some checks are pending
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Integration sqlite / changes (push) Waiting to run
Integration sqlite / integration-sqlite (master, 8.4, main, --tags ~@large files_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, capabilities_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, collaboration_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, comments_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, dav_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, federation_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, file_conversions) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, files_reminders) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, filesdrop_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, ldap_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, openldap_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, openldap_numerical_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, remoteapi_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, routing_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, setup_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, sharees_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, sharing_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, theming_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, videoverification_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite-summary (push) Blocked by required conditions
Psalm static code analysis / static-code-analysis (push) Waiting to run
Psalm static code analysis / static-code-analysis-security (push) Waiting to run
Psalm static code analysis / static-code-analysis-ocp (push) Waiting to run
Psalm static code analysis / static-code-analysis-ncu (push) Waiting to run
Psalm static code analysis / static-code-analysis-strict (push) Waiting to run
Some checks are pending
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Integration sqlite / changes (push) Waiting to run
Integration sqlite / integration-sqlite (master, 8.4, main, --tags ~@large files_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, capabilities_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, collaboration_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, comments_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, dav_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, federation_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, file_conversions) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, files_reminders) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, filesdrop_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, ldap_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, openldap_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, openldap_numerical_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, remoteapi_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, routing_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, setup_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, sharees_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, sharing_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, theming_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, videoverification_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite-summary (push) Blocked by required conditions
Psalm static code analysis / static-code-analysis (push) Waiting to run
Psalm static code analysis / static-code-analysis-security (push) Waiting to run
Psalm static code analysis / static-code-analysis-ocp (push) Waiting to run
Psalm static code analysis / static-code-analysis-ncu (push) Waiting to run
Psalm static code analysis / static-code-analysis-strict (push) Waiting to run
feat: add calendar name to search entries
This commit is contained in:
commit
142ddaf146
5 changed files with 60 additions and 49 deletions
|
|
@ -150,13 +150,13 @@ class EventsSearchProvider extends ACalendarSearchProvider implements IFiltering
|
|||
$formattedResults = \array_map(function (array $eventRow) use ($calendarsById, $subscriptionsById): SearchResultEntry {
|
||||
$component = $this->getPrimaryComponent($eventRow['calendardata'], self::$componentType);
|
||||
$title = (string)($component->SUMMARY ?? $this->l10n->t('Untitled event'));
|
||||
$subline = $this->generateSubline($component);
|
||||
|
||||
if ($eventRow['calendartype'] === CalDavBackend::CALENDAR_TYPE_CALENDAR) {
|
||||
$calendar = $calendarsById[$eventRow['calendarid']];
|
||||
} else {
|
||||
$calendar = $subscriptionsById[$eventRow['calendarid']];
|
||||
}
|
||||
$subline = $this->generateSubline($component, $calendar);
|
||||
$resourceUrl = $this->getDeepLinkToCalendarApp($calendar['principaluri'], $calendar['uri'], $eventRow['uri']);
|
||||
$result = new SearchResultEntry('', $title, $subline, $resourceUrl, 'icon-calendar-dark', false);
|
||||
|
||||
|
|
@ -204,7 +204,7 @@ class EventsSearchProvider extends ACalendarSearchProvider implements IFiltering
|
|||
. $calendarObjectUri;
|
||||
}
|
||||
|
||||
protected function generateSubline(Component $eventComponent): string {
|
||||
protected function generateSubline(Component $eventComponent, array $calendarInfo): string {
|
||||
$dtStart = $eventComponent->DTSTART;
|
||||
$dtEnd = $this->getDTEndForEvent($eventComponent);
|
||||
$isAllDayEvent = $dtStart instanceof Property\ICalendar\Date;
|
||||
|
|
@ -214,24 +214,31 @@ class EventsSearchProvider extends ACalendarSearchProvider implements IFiltering
|
|||
if ($isAllDayEvent) {
|
||||
$endDateTime->modify('-1 day');
|
||||
if ($this->isDayEqual($startDateTime, $endDateTime)) {
|
||||
return $this->l10n->l('date', $startDateTime, ['width' => 'medium']);
|
||||
$formattedSubline = $this->l10n->l('date', $startDateTime, ['width' => 'medium']);
|
||||
} else {
|
||||
$formattedStart = $this->l10n->l('date', $startDateTime, ['width' => 'medium']);
|
||||
$formattedEnd = $this->l10n->l('date', $endDateTime, ['width' => 'medium']);
|
||||
$formattedSubline = "$formattedStart - $formattedEnd";
|
||||
}
|
||||
} else {
|
||||
$formattedStartDate = $this->l10n->l('date', $startDateTime, ['width' => 'medium']);
|
||||
$formattedEndDate = $this->l10n->l('date', $endDateTime, ['width' => 'medium']);
|
||||
$formattedStartTime = $this->l10n->l('time', $startDateTime, ['width' => 'short']);
|
||||
$formattedEndTime = $this->l10n->l('time', $endDateTime, ['width' => 'short']);
|
||||
|
||||
$formattedStart = $this->l10n->l('date', $startDateTime, ['width' => 'medium']);
|
||||
$formattedEnd = $this->l10n->l('date', $endDateTime, ['width' => 'medium']);
|
||||
return "$formattedStart - $formattedEnd";
|
||||
if ($this->isDayEqual($startDateTime, $endDateTime)) {
|
||||
$formattedSubline = "$formattedStartDate $formattedStartTime - $formattedEndTime";
|
||||
} else {
|
||||
$formattedSubline = "$formattedStartDate $formattedStartTime - $formattedEndDate $formattedEndTime";
|
||||
}
|
||||
}
|
||||
|
||||
$formattedStartDate = $this->l10n->l('date', $startDateTime, ['width' => 'medium']);
|
||||
$formattedEndDate = $this->l10n->l('date', $endDateTime, ['width' => 'medium']);
|
||||
$formattedStartTime = $this->l10n->l('time', $startDateTime, ['width' => 'short']);
|
||||
$formattedEndTime = $this->l10n->l('time', $endDateTime, ['width' => 'short']);
|
||||
|
||||
if ($this->isDayEqual($startDateTime, $endDateTime)) {
|
||||
return "$formattedStartDate $formattedStartTime - $formattedEndTime";
|
||||
if (isset($calendarInfo['{DAV:}displayname']) && !empty($calendarInfo['{DAV:}displayname'])) {
|
||||
$formattedSubline = $formattedSubline . " ({$calendarInfo['{DAV:}displayname']})";
|
||||
}
|
||||
|
||||
return "$formattedStartDate $formattedStartTime - $formattedEndDate $formattedEndTime";
|
||||
// string cast is just to make psalm happy
|
||||
return (string)$formattedSubline;
|
||||
}
|
||||
|
||||
protected function getDTEndForEvent(Component $eventComponent):Property {
|
||||
|
|
|
|||
|
|
@ -96,13 +96,13 @@ class TasksSearchProvider extends ACalendarSearchProvider {
|
|||
$formattedResults = \array_map(function (array $taskRow) use ($calendarsById, $subscriptionsById):SearchResultEntry {
|
||||
$component = $this->getPrimaryComponent($taskRow['calendardata'], self::$componentType);
|
||||
$title = (string)($component->SUMMARY ?? $this->l10n->t('Untitled task'));
|
||||
$subline = $this->generateSubline($component);
|
||||
|
||||
if ($taskRow['calendartype'] === CalDavBackend::CALENDAR_TYPE_CALENDAR) {
|
||||
$calendar = $calendarsById[$taskRow['calendarid']];
|
||||
} else {
|
||||
$calendar = $subscriptionsById[$taskRow['calendarid']];
|
||||
}
|
||||
$subline = $this->generateSubline($component, $calendar);
|
||||
$resourceUrl = $this->getDeepLinkToTasksApp($calendar['uri'], $taskRow['uri']);
|
||||
|
||||
return new SearchResultEntry('', $title, $subline, $resourceUrl, 'icon-checkmark', false);
|
||||
|
|
@ -128,25 +128,29 @@ class TasksSearchProvider extends ACalendarSearchProvider {
|
|||
);
|
||||
}
|
||||
|
||||
protected function generateSubline(Component $taskComponent): string {
|
||||
protected function generateSubline(Component $taskComponent, array $calendarInfo): string {
|
||||
if ($taskComponent->COMPLETED) {
|
||||
$completedDateTime = new \DateTime($taskComponent->COMPLETED->getDateTime()->format(\DateTimeInterface::ATOM));
|
||||
$formattedDate = $this->l10n->l('date', $completedDateTime, ['width' => 'medium']);
|
||||
return $this->l10n->t('Completed on %s', [$formattedDate]);
|
||||
}
|
||||
|
||||
if ($taskComponent->DUE) {
|
||||
$formattedSubline = $this->l10n->t('Completed on %s', [$formattedDate]);
|
||||
} elseif ($taskComponent->DUE) {
|
||||
$dueDateTime = new \DateTime($taskComponent->DUE->getDateTime()->format(\DateTimeInterface::ATOM));
|
||||
$formattedDate = $this->l10n->l('date', $dueDateTime, ['width' => 'medium']);
|
||||
|
||||
if ($taskComponent->DUE->hasTime()) {
|
||||
$formattedTime = $this->l10n->l('time', $dueDateTime, ['width' => 'short']);
|
||||
return $this->l10n->t('Due on %s by %s', [$formattedDate, $formattedTime]);
|
||||
$formattedSubline = $this->l10n->t('Due on %s by %s', [$formattedDate, $formattedTime]);
|
||||
} else {
|
||||
$formattedSubline = $this->l10n->t('Due on %s', [$formattedDate]);
|
||||
}
|
||||
|
||||
return $this->l10n->t('Due on %s', [$formattedDate]);
|
||||
} else {
|
||||
$formattedSubline = '';
|
||||
}
|
||||
|
||||
return '';
|
||||
if (isset($calendarInfo['{DAV:}displayname']) && !empty($calendarInfo['{DAV:}displayname'])) {
|
||||
$formattedSubline = $formattedSubline . (!empty($formattedSubline) ? ' ' : '') . "({$calendarInfo['{DAV:}displayname']})";
|
||||
}
|
||||
|
||||
return $formattedSubline;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -436,7 +436,7 @@ class EventsSearchProviderTest extends TestCase {
|
|||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'generateSublineDataProvider')]
|
||||
public function testGenerateSubline(string $ics, string $expectedSubline): void {
|
||||
public function testGenerateSubline(string $ics, string $expectedSubline, array $calendarInfo = []): void {
|
||||
$vCalendar = Reader::read($ics, Reader::OPTION_FORGIVING);
|
||||
$eventComponent = $vCalendar->VEVENT;
|
||||
|
||||
|
|
@ -449,19 +449,23 @@ class EventsSearchProviderTest extends TestCase {
|
|||
return $date->format('m-d');
|
||||
});
|
||||
|
||||
$actual = self::invokePrivate($this->provider, 'generateSubline', [$eventComponent]);
|
||||
$actual = self::invokePrivate($this->provider, 'generateSubline', [$eventComponent, $calendarInfo]);
|
||||
$this->assertEquals($expectedSubline, $actual);
|
||||
}
|
||||
|
||||
public static function generateSublineDataProvider(): array {
|
||||
return [
|
||||
[self::$vEvent1, '08-16 09:00 - 10:00'],
|
||||
[self::$vEvent2, '08-16 09:00 - 08-17 10:00'],
|
||||
[self::$vEvent3, '10-05'],
|
||||
[self::$vEvent4, '10-05 - 10-07'],
|
||||
[self::$vEvent5, '10-05 - 10-09'],
|
||||
[self::$vEvent6, '10-05'],
|
||||
[self::$vEvent7, '08-16 09:00 - 09:00'],
|
||||
[self::$vEvent1, '08-16 09:00 - 10:00', []],
|
||||
[self::$vEvent2, '08-16 09:00 - 08-17 10:00', []],
|
||||
[self::$vEvent3, '10-05', []],
|
||||
[self::$vEvent4, '10-05 - 10-07', []],
|
||||
[self::$vEvent5, '10-05 - 10-09', []],
|
||||
[self::$vEvent6, '10-05', []],
|
||||
[self::$vEvent7, '08-16 09:00 - 09:00', []],
|
||||
[self::$vEvent1, '08-16 09:00 - 10:00 (My Calendar)', ['{DAV:}displayname' => 'My Calendar']],
|
||||
[self::$vEvent3, '10-05 (My Calendar)', ['{DAV:}displayname' => 'My Calendar']],
|
||||
[self::$vEvent2, '08-16 09:00 - 08-17 10:00 (My Calendar)', ['{DAV:}displayname' => 'My Calendar']],
|
||||
[self::$vEvent1, '08-16 09:00 - 10:00', ['{DAV:}displayname' => '']],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -290,24 +290,29 @@ class TasksSearchProviderTest extends TestCase {
|
|||
}
|
||||
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'generateSublineDataProvider')]
|
||||
public function testGenerateSubline(string $ics, string $expectedSubline): void {
|
||||
public function testGenerateSubline(string $ics, string $expectedSubline, array $calendarInfo = []): void {
|
||||
$vCalendar = Reader::read($ics, Reader::OPTION_FORGIVING);
|
||||
$taskComponent = $vCalendar->VTODO;
|
||||
|
||||
$this->l10n->method('t')->willReturnArgument(0);
|
||||
$this->l10n->method('l')->willReturnArgument(0);
|
||||
|
||||
$actual = self::invokePrivate($this->provider, 'generateSubline', [$taskComponent]);
|
||||
$actual = self::invokePrivate($this->provider, 'generateSubline', [$taskComponent, $calendarInfo]);
|
||||
$this->assertEquals($expectedSubline, $actual);
|
||||
}
|
||||
|
||||
public static function generateSublineDataProvider(): array {
|
||||
return [
|
||||
[self::$vTodo0, ''],
|
||||
[self::$vTodo1, 'Completed on %s'],
|
||||
[self::$vTodo2, 'Completed on %s'],
|
||||
[self::$vTodo3, 'Due on %s'],
|
||||
[self::$vTodo4, 'Due on %s by %s'],
|
||||
[self::$vTodo0, '', []],
|
||||
[self::$vTodo1, 'Completed on %s', []],
|
||||
[self::$vTodo2, 'Completed on %s', []],
|
||||
[self::$vTodo3, 'Due on %s', []],
|
||||
[self::$vTodo4, 'Due on %s by %s', []],
|
||||
[self::$vTodo0, '(My Tasks)', ['{DAV:}displayname' => 'My Tasks']],
|
||||
[self::$vTodo1, 'Completed on %s (My Tasks)', ['{DAV:}displayname' => 'My Tasks']],
|
||||
[self::$vTodo3, 'Due on %s (My Tasks)', ['{DAV:}displayname' => 'My Tasks']],
|
||||
[self::$vTodo4, 'Due on %s by %s (My Tasks)', ['{DAV:}displayname' => 'My Tasks']],
|
||||
[self::$vTodo1, 'Completed on %s', ['{DAV:}displayname' => '']],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -839,9 +839,6 @@
|
|||
</InvalidOperand>
|
||||
</file>
|
||||
<file src="apps/dav/lib/Search/EventsSearchProvider.php">
|
||||
<FalsableReturnStatement>
|
||||
<code><![CDATA[$this->l10n->l('date', $startDateTime, ['width' => 'medium'])]]></code>
|
||||
</FalsableReturnStatement>
|
||||
<InvalidOperand>
|
||||
<code><![CDATA[$query->getCursor()]]></code>
|
||||
</InvalidOperand>
|
||||
|
|
@ -851,12 +848,6 @@
|
|||
'ORGANIZER' => ['CN'],
|
||||
]]]></code>
|
||||
</InvalidPropertyAssignmentValue>
|
||||
<InvalidReturnStatement>
|
||||
<code><![CDATA[$this->l10n->l('date', $startDateTime, ['width' => 'medium'])]]></code>
|
||||
</InvalidReturnStatement>
|
||||
<InvalidReturnType>
|
||||
<code><![CDATA[string]]></code>
|
||||
</InvalidReturnType>
|
||||
<UndefinedMethod>
|
||||
<code><![CDATA[getDateTime]]></code>
|
||||
<code><![CDATA[getDateTime]]></code>
|
||||
|
|
|
|||
Loading…
Reference in a new issue