Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions apps/systemtags/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
'OCA\\SystemTags\\Listeners\\LoadAdditionalScriptsListener' => $baseDir . '/../lib/Listeners/LoadAdditionalScriptsListener.php',
'OCA\\SystemTags\\Migration\\Version31000Date20241018063111' => $baseDir . '/../lib/Migration/Version31000Date20241018063111.php',
'OCA\\SystemTags\\Migration\\Version31000Date20241114171300' => $baseDir . '/../lib/Migration/Version31000Date20241114171300.php',
'OCA\\SystemTags\\Migration\\Version33000Date20251104171300' => $baseDir . '/../lib/Migration/Version33000Date20251104171300.php',
'OCA\\SystemTags\\Search\\TagSearchProvider' => $baseDir . '/../lib/Search/TagSearchProvider.php',
'OCA\\SystemTags\\Settings\\Admin' => $baseDir . '/../lib/Settings/Admin.php',
);
1 change: 1 addition & 0 deletions apps/systemtags/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class ComposerStaticInitSystemTags
'OCA\\SystemTags\\Listeners\\LoadAdditionalScriptsListener' => __DIR__ . '/..' . '/../lib/Listeners/LoadAdditionalScriptsListener.php',
'OCA\\SystemTags\\Migration\\Version31000Date20241018063111' => __DIR__ . '/..' . '/../lib/Migration/Version31000Date20241018063111.php',
'OCA\\SystemTags\\Migration\\Version31000Date20241114171300' => __DIR__ . '/..' . '/../lib/Migration/Version31000Date20241114171300.php',
'OCA\\SystemTags\\Migration\\Version33000Date20251104171300' => __DIR__ . '/..' . '/../lib/Migration/Version33000Date20251104171300.php',
'OCA\\SystemTags\\Search\\TagSearchProvider' => __DIR__ . '/..' . '/../lib/Search/TagSearchProvider.php',
'OCA\\SystemTags\\Settings\\Admin' => __DIR__ . '/..' . '/../lib/Settings/Admin.php',
);
Expand Down
5 changes: 2 additions & 3 deletions apps/systemtags/lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ class Capabilities implements ICapability {
/**
* @return array{systemtags: array{enabled: true}}
*/
public function getCapabilities() {
$capabilities = [
public function getCapabilities(): array {
return [
'systemtags' => [
'enabled' => true,
]
];
return $capabilities;
}
}
11 changes: 7 additions & 4 deletions apps/systemtags/lib/Command/Files/Add.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ISystemTagObjectMapper;
use OCP\SystemTag\TagAlreadyExistsException;
use Override;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
Expand All @@ -28,6 +29,7 @@ public function __construct(
parent::__construct();
}

#[Override]
protected function configure(): void {
$this->setName('tag:files:add')
->setDescription('Add a system-tag to a file or folder')
Expand All @@ -36,6 +38,7 @@ protected function configure(): void {
->addArgument('access', InputArgument::REQUIRED, 'access level of the tag (public, restricted or invisible)');
}

#[Override]
public function execute(InputInterface $input, OutputInterface $output): int {
$targetInput = $input->getArgument('target');
$tagsInput = $input->getArgument('tags');
Expand Down Expand Up @@ -63,14 +66,14 @@ public function execute(InputInterface $input, OutputInterface $output): int {
break;
default:
$output->writeln('<error>`access` property is invalid</error>');
return 1;
return Command::FAILURE;
}

$targetNode = $this->fileUtils->getNode($targetInput);

if (! $targetNode) {
if (!$targetNode) {
$output->writeln("<error>file $targetInput not found</error>");
return 1;
return Command::FAILURE;
}

foreach ($tagNameArray as $tagName) {
Expand All @@ -85,6 +88,6 @@ public function execute(InputInterface $input, OutputInterface $output): int {
$output->writeln("<info>$access</info> tag named <info>$tagName</info> added.");
}

return 0;
return Command::SUCCESS;
}
}
11 changes: 7 additions & 4 deletions apps/systemtags/lib/Command/Files/Delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ISystemTagObjectMapper;
use OCP\SystemTag\TagNotFoundException;
use Override;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
Expand All @@ -28,6 +29,7 @@ public function __construct(
parent::__construct();
}

#[Override]
protected function configure(): void {
$this->setName('tag:files:delete')
->setDescription('Delete a system-tag from a file or folder')
Expand All @@ -36,13 +38,14 @@ protected function configure(): void {
->addArgument('access', InputArgument::REQUIRED, 'access level of the tag (public, restricted or invisible)');
}

#[Override]
public function execute(InputInterface $input, OutputInterface $output): int {
$targetInput = $input->getArgument('target');
$tagsInput = $input->getArgument('tags');

if ($tagsInput === '') {
$output->writeln('<error>`tags` can\'t be empty</error>');
return 3;
return Command::INVALID;
}

$tagNameArray = explode(',', $tagsInput);
Expand All @@ -63,14 +66,14 @@ public function execute(InputInterface $input, OutputInterface $output): int {
break;
default:
$output->writeln('<error>`access` property is invalid</error>');
return 1;
return Command::FAILURE;
}

$targetNode = $this->fileUtils->getNode($targetInput);

if (! $targetNode) {
$output->writeln("<error>file $targetInput not found</error>");
return 1;
return Command::FAILURE;
}

foreach ($tagNameArray as $tagName) {
Expand All @@ -83,6 +86,6 @@ public function execute(InputInterface $input, OutputInterface $output): int {
}
}

return 0;
return Command::SUCCESS;
}
}
9 changes: 6 additions & 3 deletions apps/systemtags/lib/Command/Files/DeleteAll.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use OC\Core\Command\Info\FileUtils;
use OCP\SystemTag\ISystemTagObjectMapper;
use Override;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
Expand All @@ -25,25 +26,27 @@ public function __construct(
parent::__construct();
}

#[Override]
protected function configure(): void {
$this->setName('tag:files:delete-all')
->setDescription('Delete all system-tags from a file or folder')
->addArgument('target', InputArgument::REQUIRED, 'file id or path');
}

#[Override]
public function execute(InputInterface $input, OutputInterface $output): int {
$targetInput = $input->getArgument('target');
$targetNode = $this->fileUtils->getNode($targetInput);

if (! $targetNode) {
if (!$targetNode) {
$output->writeln("<error>file $targetInput not found</error>");
return 1;
return Command::FAILURE;
}

$tags = $this->systemTagObjectMapper->getTagIdsForObjects([$targetNode->getId()], 'files');
$this->systemTagObjectMapper->unassignTags((string)$targetNode->getId(), 'files', $tags[$targetNode->getId()]);
$output->writeln('<info>all tags removed.</info>');

return 0;
return Command::SUCCESS;
}
}
14 changes: 3 additions & 11 deletions apps/systemtags/lib/Controller/LastUsedController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,8 @@

class LastUsedController extends Controller {

/**
* @param string $appName
* @param IRequest $request
* @param IConfig $config
* @param IUserSession $userSession
*/
public function __construct(
$appName,
string $appName,
IRequest $request,
protected IConfig $config,
protected IUserSession $userSession,
Expand All @@ -31,11 +25,9 @@ public function __construct(
}

#[NoAdminRequired]
public function getLastUsedTagIds() {
public function getLastUsedTagIds(): DataResponse {
$lastUsed = $this->config->getUserValue($this->userSession->getUser()->getUID(), 'systemtags', 'last_used', '[]');
$tagIds = json_decode($lastUsed, true);
return new DataResponse(array_map(function ($id) {
return (string)$id;
}, $tagIds));
return new DataResponse(array_map(static fn ($id) => (string)$id, $tagIds));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\SystemTags\Migration;

use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\Attributes\ColumnType;
use OCP\Migration\Attributes\ModifyColumn;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;

/**
* Remove auto-increment to use snowflake ids
*/
#[ModifyColumn(table: 'systemtag', name: 'id', type: ColumnType::BIGINT, description: 'Remove auto-increment')]
class Version33000Date20251104171300 extends SimpleMigrationStep {

public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();

if ($schema->hasTable('systemtag')) {
$schema->dropAutoincrementColumn('systemtag', 'id');
}

return $schema;
}
}
9 changes: 3 additions & 6 deletions apps/systemtags/lib/Search/TagSearchProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,25 +88,22 @@ public function search(IUser $user, ISearchQuery $query): SearchResult {

// do search
$searchResults = $userFolder->search($fileQuery);
$resultIds = array_map(function (Node $node) {
return $node->getId();
}, $searchResults);
$resultIds = array_map(static fn (Node $node): int => $node->getId(), $searchResults);
$matchedTags = $this->objectMapper->getTagIdsForObjects($resultIds, 'files');

// prepare direct tag results
$tagResults = array_map(function (ISystemTag $tag) {
$tagResults = array_map(function (ISystemTag $tag): SearchResultEntry {
$thumbnailUrl = '';
$link = $this->urlGenerator->linkToRoute('files.view.indexView', [
'view' => 'tags',
]) . '?dir=' . $tag->getId();
$searchResultEntry = new SearchResultEntry(
return new SearchResultEntry(
$thumbnailUrl,
$this->l10n->t('All tagged %s …', [$tag->getName()]),
'',
$this->urlGenerator->getAbsoluteURL($link),
'icon-tag'
);
return $searchResultEntry;
}, $matchingTags);

// prepare files results
Expand Down
23 changes: 7 additions & 16 deletions apps/systemtags/lib/Settings/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use OCP\IAppConfig;
use OCP\Settings\ISettings;
use OCP\Util;
use Override;

class Admin implements ISettings {

Expand All @@ -21,32 +22,22 @@ public function __construct(
) {
}

/**
* @return TemplateResponse
*/
public function getForm() {
#[Override]
public function getForm(): TemplateResponse {
$restrictSystemTagsCreationToAdmin = $this->appConfig->getValueBool(Application::APP_ID, 'restrict_creation_to_admin', false);
$this->initialStateService->provideInitialState('restrictSystemTagsCreationToAdmin', $restrictSystemTagsCreationToAdmin);

Util::addScript('systemtags', 'admin');
return new TemplateResponse('systemtags', 'admin', [], '');
}

/**
* @return string the section ID, e.g. 'sharing'
*/
public function getSection() {
#[Override]
public function getSection(): string {
return 'server';
}

/**
* @return int whether the form should be rather on the top or bottom of
* the admin section. The forms are arranged in ascending order of the
* priority values. It is required to return a value between 0 and 100.
*
* E.g.: 70
*/
public function getPriority() {
#[Override]
public function getPriority(): int {
return 70;
}
}
4 changes: 2 additions & 2 deletions apps/systemtags/src/services/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export async function fetchTags(): Promise<TagWithId[]> {
*
* @param tagId
*/
export async function fetchTag(tagId: number): Promise<TagWithId> {
export async function fetchTag(tagId: string): Promise<TagWithId> {
const path = '/systemtags/' + tagId
try {
const { data: tag } = await davClient.stat(path, {
Expand Down Expand Up @@ -83,7 +83,7 @@ export async function fetchLastUsedTagIds(): Promise<number[]> {
*
* @param tag The tag to create
*/
export async function createTag(tag: Tag | ServerTag): Promise<number> {
export async function createTag(tag: Tag | ServerTag): Promise<string> {
const path = '/systemtags'
const tagToPost = formatTag(tag)
try {
Expand Down
6 changes: 3 additions & 3 deletions apps/systemtags/src/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ describe('systemtags - utils', () => {
describe('parseIdFromLocation', () => {
it('works with simple url', () => {
const url = 'http://some.domain/remote.php/dav/3'
expect(parseIdFromLocation(url)).toEqual(3)
expect(parseIdFromLocation(url)).toEqual('3')
})
it('works with trailing slash', () => {
const url = 'http://some.domain/remote.php/dav/3/'
expect(parseIdFromLocation(url)).toEqual(3)
expect(parseIdFromLocation(url)).toEqual('3')
})
it('works with query', () => {
const url = 'http://some.domain/remote.php/dav/3?some-value'
expect(parseIdFromLocation(url)).toEqual(3)
expect(parseIdFromLocation(url)).toEqual('3')
})
})

Expand Down
4 changes: 2 additions & 2 deletions apps/systemtags/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function parseTags(tags: { props: DAVResultResponseProps }[]): TagWithId[
*
* @param url URL to parse
*/
export function parseIdFromLocation(url: string): number {
export function parseIdFromLocation(url: string): string {
const queryPos = url.indexOf('?')
if (queryPos > 0) {
url = url.substring(0, queryPos)
Expand All @@ -45,7 +45,7 @@ export function parseIdFromLocation(url: string): number {
// so we take the part before that
} while (!result && parts.length > 0)

return Number(result)
return result
}

/**
Expand Down
4 changes: 2 additions & 2 deletions dist/files-sidebar.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files-sidebar.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/systemtags-admin.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/systemtags-admin.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/systemtags-init.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/systemtags-init.js.map

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions lib/private/SystemTag/ManagerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use OCP\IGroupManager;
use OCP\IServerContainer;
use OCP\IUserSession;
use OCP\Snowflake\IGenerator;
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ISystemTagManagerFactory;
use OCP\SystemTag\ISystemTagObjectMapper;
Expand Down Expand Up @@ -45,6 +46,7 @@ public function getManager(): ISystemTagManager {
$this->serverContainer->get(IEventDispatcher::class),
$this->serverContainer->get(IUserSession::class),
$this->serverContainer->get(IAppConfig::class),
$this->serverContainer->get(IGenerator::class),
);
}

Expand Down
Loading
Loading