Merge pull request #6743 from nextcloud/backport/6649/stable31

[stable31] fix: Adapt URLs generated in the backend to new routes
This commit is contained in:
Julius Knorr
2025-02-12 22:53:24 +01:00
committed by GitHub
23 changed files with 84 additions and 65 deletions

View File

@@ -131,7 +131,7 @@ class DeckProvider implements IProvider {
];
if (array_key_exists('board', $subjectParams)) {
$card['link'] = $this->cardService->getRedirectUrlForCard($event->getObjectId());
$card['link'] = $this->cardService->getCardUrl($event->getObjectId());
$event->setLink($card['link']);
}
$params['card'] = $card;
@@ -365,6 +365,6 @@ class DeckProvider implements IProvider {
}
public function deckUrl($endpoint) {
return $this->urlGenerator->linkToRouteAbsolute('deck.page.index') . '#' . $endpoint;
return $this->urlGenerator->linkToRouteAbsolute('deck.page.index') . trim($endpoint, '/');
}
}

View File

@@ -57,7 +57,7 @@ class ResourceProvider implements IProvider {
*/
public function getResourceRichObject(IResource $resource): array {
$board = $this->getBoard($resource);
$link = $this->urlGenerator->linkToRoute('deck.page.index') . '#/board/' . $resource->getId();
$link = $this->urlGenerator->linkToRoute('deck.page.indexBoard', ['boardId' => $resource->getId()]);
return [
'type' => self::RESOURCE_TYPE,

View File

@@ -66,7 +66,10 @@ class ResourceProviderCard implements IProvider {
throw new ResourceException('No unique card found for resource, this should never happen');
}
$link = $this->urlGenerator->linkToRoute('deck.page.index') . '#/board/' . $board->getId() . '/card/' . $resource->getId();
$link = $this->urlGenerator->linkToRoute('deck.page.indexCard', [
'boardId' => $board->getId(),
'cardId' => $card->getId()
]);
return [
'type' => self::RESOURCE_TYPE,

View File

@@ -85,9 +85,9 @@ class Notifier implements INotifier {
switch ($notification->getSubject()) {
case 'card-assigned':
$cardId = $notification->getObjectId();
$cardId = (int)$notification->getObjectId();
$stack = $this->stackMapper->findStackFromCardId($cardId);
$boardId = $stack ? $stack->getBoardId() : null;
$boardId = $stack ? (int)$stack->getBoardId() : null;
if (!$boardId) {
throw new AlreadyProcessedException();
}
@@ -110,13 +110,13 @@ class Notifier implements INotifier {
'name' => $params[0],
'boardname' => $params[1],
'stackname' => $stack->getTitle(),
'link' => $this->url->linkToRouteAbsolute('deck.page.index') . '#/board/' . $boardId . '/card/' . $cardId . '',
'link' => $this->getCardUrl($boardId, $cardId),
],
'deck-board' => [
'type' => 'deck-board',
'id' => $boardId,
'name' => $params[1],
'link' => $this->url->linkToRouteAbsolute('deck.page.index') . '#/board/' . $boardId,
'link' => $this->getBoardUrl($boardId),
],
'user' => [
'type' => 'user',
@@ -125,12 +125,12 @@ class Notifier implements INotifier {
]
]
);
$notification->setLink($this->url->linkToRouteAbsolute('deck.page.index') . '#/board/' . $boardId . '/card/' . $cardId . '');
$notification->setLink($this->getCardUrl($boardId, $cardId));
break;
case 'card-overdue':
$cardId = $notification->getObjectId();
$cardId = (int)$notification->getObjectId();
$stack = $this->stackMapper->findStackFromCardId($cardId);
$boardId = $stack ? $stack->getBoardId() : null;
$boardId = $stack ? (int)$stack->getBoardId() : null;
if (!$boardId) {
throw new AlreadyProcessedException();
}
@@ -147,22 +147,22 @@ class Notifier implements INotifier {
'name' => $params[0],
'boardname' => $params[1],
'stackname' => $stack->getTitle(),
'link' => $this->url->linkToRouteAbsolute('deck.page.index') . '#/board/' . $boardId . '/card/' . $cardId . '',
'link' => $this->getCardUrl($boardId, $cardId),
],
'deck-board' => [
'type' => 'deck-board',
'id' => $boardId,
'name' => $params[1],
'link' => $this->url->linkToRouteAbsolute('deck.page.index') . '#/board/' . $boardId,
'link' => $this->getBoardUrl($boardId),
],
]
);
$notification->setLink($this->url->linkToRouteAbsolute('deck.page.index') . '#/board/' . $boardId . '/card/' . $cardId . '');
$notification->setLink($this->getCardUrl($boardId, $cardId));
break;
case 'card-comment-mentioned':
$cardId = $notification->getObjectId();
$cardId = (int)$notification->getObjectId();
$stack = $this->stackMapper->findStackFromCardId($cardId);
$boardId = $stack ? $stack->getBoardId() : null;
$boardId = $stack ? (int)$stack->getBoardId() : null;
if (!$boardId) {
throw new AlreadyProcessedException();
}
@@ -185,7 +185,7 @@ class Notifier implements INotifier {
'name' => $params[0],
'boardname' => $params[1],
'stackname' => $stack->getTitle(),
'link' => $this->url->linkToRouteAbsolute('deck.page.index') . '#/board/' . $boardId . '/card/' . $cardId . '',
'link' => $this->getCardUrl($boardId, $cardId),
],
'user' => [
'type' => 'user',
@@ -197,10 +197,10 @@ class Notifier implements INotifier {
if ($notification->getMessage() === '{message}') {
$notification->setParsedMessage($notification->getMessageParameters()['message']);
}
$notification->setLink($this->url->linkToRouteAbsolute('deck.page.index') . '#/board/' . $boardId . '/card/' . $cardId . '');
$notification->setLink($this->getCardUrl($boardId, $cardId));
break;
case 'board-shared':
$boardId = $notification->getObjectId();
$boardId = (int)$notification->getObjectId();
if (!$boardId) {
throw new AlreadyProcessedException();
}
@@ -220,7 +220,7 @@ class Notifier implements INotifier {
'type' => 'deck-board',
'id' => $boardId,
'name' => $params[0],
'link' => $this->url->linkToRouteAbsolute('deck.page.index') . '#/board/' . $boardId,
'link' => $this->getBoardUrl($boardId),
],
'user' => [
'type' => 'user',
@@ -229,9 +229,17 @@ class Notifier implements INotifier {
]
]
);
$notification->setLink($this->url->linkToRouteAbsolute('deck.page.index') . '#/board/' . $boardId . '/');
$notification->setLink($this->getBoardUrl($boardId));
break;
}
return $notification;
}
private function getBoardUrl(int $boardId): string {
return $this->url->linkToRouteAbsolute('deck.page.indexBoard', ['boardId' => $boardId]);
}
private function getCardUrl(int $boardId, int $cardId): string {
return $this->url->linkToRouteAbsolute('deck.page.indexCard', ['boardId' => $boardId, 'cardId' => $cardId]);
}
}

View File

@@ -219,7 +219,7 @@ class DeckProvider implements IFullTextSearchProvider {
try {
$board =
$this->fullTextSearchService->getBoardFromCardId((int)$document->getId());
$path = '#/board/' . $board->getId() . '/card/' . $document->getId();
$path = '/board/' . $board->getId() . '/card/' . $document->getId();
$document->setLink($this->urlGenerator->linkToRoute('deck.page.index') . $path);
} catch (DoesNotExistException $e) {
} catch (MultipleObjectsReturnedException $e) {

View File

@@ -22,7 +22,7 @@ class BoardSearchResultEntry extends SearchResultEntry {
),
$board->getTitle(),
'',
$urlGenerator->linkToRouteAbsolute('deck.page.index') . '#/board/' . $board->getId(),
$urlGenerator->linkToRouteAbsolute('deck.page.indexBoard', ['boardId' => $board->getId()]),
'icon-deck');
}
}

View File

@@ -746,10 +746,6 @@ class BoardService {
$board->setUsers(array_values($boardUsers));
}
public function getBoardUrl($endpoint) {
return $this->urlGenerator->linkToRouteAbsolute('deck.page.index') . '#' . $endpoint;
}
/**
* Clean a given board data from the Cache
*/

View File

@@ -655,13 +655,13 @@ class CardService {
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
}
public function getCardUrl($cardId) {
public function getCardUrl(int $cardId): string {
$boardId = $this->cardMapper->findBoardId($cardId);
return $this->urlGenerator->linkToRouteAbsolute('deck.page.index') . "#/board/$boardId/card/$cardId";
return $this->urlGenerator->linkToRouteAbsolute('deck.page.indexCard', ['boardId' => $boardId, 'cardId' => $cardId]);
}
public function getRedirectUrlForCard($cardId) {
return $this->urlGenerator->linkToRouteAbsolute('deck.page.index') . "card/$cardId";
public function getRedirectUrlForCard(int $cardId): string {
return $this->urlGenerator->linkToRouteAbsolute('deck.page.redirectToCard', ['cardId' => $cardId]);
}
}

View File

@@ -47,7 +47,7 @@ class ShareAPIHelper {
$boardId = $this->cardMapper->findBoardId($card->getId());
$result['share_with'] = $share->getSharedWith();
$result['share_with_displayname'] = $card->getTitle();
$result['share_with_link'] = $this->urlGenerator->linkToRouteAbsolute('deck.page.index') . '#/board/' . $boardId . '/card/' . $card->getId();
$result['share_with_link'] = $this->urlGenerator->linkToRouteAbsolute('deck.page.indexCard', ['boardId' => $boardId, 'cardId' => $card->getId()]);
return $result;
}

View File

@@ -43,7 +43,7 @@ class DeckTeamResourceProvider implements \OCP\Teams\ITeamResourceProvider {
$this,
(string)$board->getId(),
$board->getTitle(),
$this->urlGenerator->linkToRouteAbsolute('deck.page.index') . '#/board/' . $board->getId(),
$this->urlGenerator->linkToRouteAbsolute('deck.page.indexBoard', ['boardId' => $board->getId()]),
$this->getBoardBulletIcon($board),
$this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('deck', 'deck-current.svg')),
);

View File

@@ -5,7 +5,7 @@
import Vue from 'vue'
import Router from 'vue-router'
import { generateUrl } from '@nextcloud/router'
import { generateUrl, getRootUrl } from '@nextcloud/router'
import { BOARD_FILTERS } from './store/main.js'
import Boards from './components/boards/Boards.vue'
import Board from './components/board/Board.vue'
@@ -16,9 +16,15 @@ import Overview from './components/overview/Overview.vue'
Vue.use(Router)
// We apply a dynamic base URL depending on the URL used in the browser
const baseUrl = generateUrl('/apps/deck/')
const webRootWithIndexPHP = getRootUrl() + '/index.php'
const doesURLContainIndexPHP = window.location.pathname.startsWith(webRootWithIndexPHP)
const currentBaseUrl = doesURLContainIndexPHP ? baseUrl : baseUrl.replace('/index.php/', '/')
const router = new Router({
mode: 'history',
base: generateUrl('/apps/deck/'),
base: currentBaseUrl,
linkActiveClass: 'active',
routes: [
{
@@ -144,8 +150,8 @@ const router = new Router({
router.beforeEach((to, from, next) => {
// Redirect if fullPath begins with a hash (ignore hashes later in path)
if (to.fullPath.substring(0, 2) === '/#') {
const path = to.fullPath.substring(2)
if (to.hash.substring(0, 2) === '#/') {
const path = to.fullPath.replace('/#/', '/').trimEnd('/')
next(path)
return
}

View File

@@ -1 +1 @@
71221
71780

View File

@@ -284,7 +284,7 @@ class ActivityManagerTest extends TestCase {
$this->assertEquals($event, $actual);
}
public function dataSendToUsers() {
public static function dataSendToUsers() {
return [
[ActivityManager::DECK_OBJECT_BOARD],
[ActivityManager::DECK_OBJECT_CARD],
@@ -344,7 +344,7 @@ class ActivityManagerTest extends TestCase {
$this->invokePrivate($this->activityManager, 'sendToUsers', [$event]);
}
public function dataFindObjectForEntity() {
public static function dataFindObjectForEntity() {
$board = new Board();
$board->setId(1);
$stack = new Stack();

View File

@@ -123,7 +123,7 @@ class DeckProviderTest extends TestCase {
$this->provider->parse('en_US', $event, $event);
}
public function dataEventIcons() {
public static function dataEventIcons() {
return [
[ActivityManager::SUBJECT_LABEL_ASSIGN, 'core', 'actions/tag.svg'],
[ActivityManager::SUBJECT_CARD_CREATE, 'files', 'add-color.svg'],
@@ -166,7 +166,7 @@ class DeckProviderTest extends TestCase {
->with('deck.page.index')
->willReturn('http://localhost/index.php/apps/deck/');
$this->assertEquals(
'http://localhost/index.php/apps/deck/#board/1/card/1',
'http://localhost/index.php/apps/deck/board/1/card/1',
$this->provider->deckUrl('board/1/card/1')
);
}
@@ -202,7 +202,7 @@ class DeckProviderTest extends TestCase {
'type' => 'highlight',
'id' => 1,
'name' => 'Board',
'link' => '#/board/1',
'link' => 'board/1',
],
'user' => [
'type' => 'user',
@@ -319,9 +319,9 @@ class DeckProviderTest extends TestCase {
$expected = [
'board' => [
'type' => 'highlight',
'id' => 1,
'id' => '1',
'name' => 'Board name',
'link' => '#/board/1/',
'link' => 'board/1',
],
];
$actual = $this->invokePrivate($this->provider, 'parseParamForBoard', ['board', $subjectParams, $params]);

View File

@@ -47,7 +47,7 @@ class CardTest extends TestCase {
return $card;
}
public function dataDuedate() {
public static function dataDuedate() {
return [
[(new DateTime()), Card::DUEDATE_NOW],
[(new DateTime())->sub(new DateInterval('P1D')), Card::DUEDATE_OVERDUE],

View File

@@ -58,7 +58,7 @@ class ExceptionMiddlewareTest extends \Test\TestCase {
}
public function dataAfterException() {
public static function dataAfterException() {
return [
[new NoPermissionException('No permission'), 403, 'No permission'],
[new NotFoundException('Not found'), 404, 'Not found']

View File

@@ -76,6 +76,15 @@ class NotifierTest extends \Test\TestCase {
$this->l10nFactory->expects($this->once())
->method('get')
->willReturn($this->l10n);
$this->url->expects($this->any())
->method('linkToRouteAbsolute')
->willReturnCallback(function ($route) {
return match ($route) {
'deck.page.indexBoard' => '/board/123',
'deck.page.indexCard' => '/board/123/card/234',
};
});
}
public function testPrepareWrongApp() {
@@ -178,7 +187,7 @@ class NotifierTest extends \Test\TestCase {
$this->assertEquals($notification, $actualNotification);
}
public function dataPrepareCardAssigned() {
public static function dataPrepareCardAssigned() {
return [
[true], [false]
];
@@ -239,13 +248,13 @@ class NotifierTest extends \Test\TestCase {
'name' => 'Card title',
'boardname' => 'Board title',
'stackname' => null,
'link' => '#/board/123/card/123',
'link' => '/board/123/card/234',
],
'deck-board' => [
'type' => 'deck-board',
'id' => 123,
'name' => 'Board title',
'link' => '#/board/123',
'link' => '/board/123',
]
]);
@@ -266,7 +275,7 @@ class NotifierTest extends \Test\TestCase {
$this->assertEquals($notification, $actualNotification);
}
public function dataPrepareBoardShared() {
public static function dataPrepareBoardShared() {
return [
[true], [false]
];
@@ -321,7 +330,7 @@ class NotifierTest extends \Test\TestCase {
'type' => 'deck-board',
'id' => 123,
'name' => 'Board title',
'link' => '#/board/123',
'link' => '/board/123',
]
]);
@@ -347,11 +356,8 @@ class NotifierTest extends \Test\TestCase {
* @return Stack|MockObject
*/
private function buildMockStack(int $boardId = 999) {
$mockStack = $this->getMockBuilder(Stack::class)
->addMethods(['getBoardId'])
->getMock();
$mockStack->method('getBoardId')->willReturn($boardId);
return $mockStack;
$stack = new Stack();
$stack->setBoardId($boardId);
return $stack;
}
}

View File

@@ -42,7 +42,7 @@ class CardReferenceProviderTest extends TestCase {
private $l10n;
private $userId;
private $provider;
public function setUp() : void {
parent::setUp();

View File

@@ -102,7 +102,7 @@ class FilterStringParserTest extends TestCase {
Assert::assertEquals($expected, $result);
}
public function dataParseDate() {
public static function dataParseDate() {
return [
['date:today', [new DateQueryParameter('date', SearchQuery::COMPARATOR_EQUAL, 'today')], []],
['date:>today', [new DateQueryParameter('date', SearchQuery::COMPARATOR_MORE, 'today')], []],

View File

@@ -29,7 +29,7 @@ namespace OCA\Deck\Search\Query;
use PHPUnit\Framework\TestCase;
class AQueryParameterTest extends TestCase {
public function dataValue() {
public static function dataValue() {
return [
['foo', 'foo'],
['spätial character', 'spätial character'],

View File

@@ -291,7 +291,7 @@ class BoardServiceTest extends TestCase {
));
}
public function dataAddAclExtendPermission() {
public static function dataAddAclExtendPermission() {
return [
[[false, false, false], [false, false, false], [false, false, false]],
[[false, false, false], [true, true, true], [false, false, false]],

View File

@@ -365,7 +365,7 @@ class CardServiceTest extends TestCase {
$this->cardService->rename(123, 'newtitle');
}
public function dataReorder() {
public static function dataReorder() {
return [
[0, 0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]],
[0, 9, [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]],

View File

@@ -151,7 +151,7 @@ class PermissionServiceTest extends \Test\TestCase {
$this->assertEquals(false, $this->service->userIsBoardOwner(123));
}
public function dataTestUserCan() {
public static function dataTestUserCan() {
return [
// participant permissions type
['admin', false, false, false, 'user', true, false, false, false],
@@ -183,7 +183,7 @@ class PermissionServiceTest extends \Test\TestCase {
$this->assertFalse($this->service->userCan([], Acl::PERMISSION_EDIT));
}
public function dataCheckPermission() {
public static function dataCheckPermission() {
return [
// see getAcls() for set permissions
[1, Acl::PERMISSION_READ, true],