Skip to content

Commit 0cecb7a

Browse files
committed
fix(templatemanager): Fix and cleanup template manager
Now getUserFolder required the userId to be non nullable, so fix the test and cleanup the types in TemplateManager. Signed-off-by: Carl Schwan <[email protected]>
1 parent 9acff3e commit 0cecb7a

File tree

7 files changed

+87
-81
lines changed

7 files changed

+87
-81
lines changed

apps/files/lib/ResponseDefinitions.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
* basename: string,
1515
* etag: string,
1616
* fileid: int,
17-
* filename: ?string,
17+
* filename: string,
1818
* lastmod: int,
1919
* mime: string,
20-
* size: int,
20+
* size: int|float,
2121
* type: string,
2222
* hasPreview: bool,
23+
* permissions: int,
2324
* }
2425
*
2526
* @psalm-type FilesTemplateField = array{

apps/files/openapi.json

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,8 @@
323323
"mime",
324324
"size",
325325
"type",
326-
"hasPreview"
326+
"hasPreview",
327+
"permissions"
327328
],
328329
"properties": {
329330
"basename": {
@@ -337,8 +338,7 @@
337338
"format": "int64"
338339
},
339340
"filename": {
340-
"type": "string",
341-
"nullable": true
341+
"type": "string"
342342
},
343343
"lastmod": {
344344
"type": "integer",
@@ -348,14 +348,26 @@
348348
"type": "string"
349349
},
350350
"size": {
351-
"type": "integer",
352-
"format": "int64"
351+
"anyOf": [
352+
{
353+
"type": "integer",
354+
"format": "int64"
355+
},
356+
{
357+
"type": "number",
358+
"format": "double"
359+
}
360+
]
353361
},
354362
"type": {
355363
"type": "string"
356364
},
357365
"hasPreview": {
358366
"type": "boolean"
367+
},
368+
"permissions": {
369+
"type": "integer",
370+
"format": "int64"
359371
}
360372
}
361373
},

build/psalm-baseline.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2443,7 +2443,6 @@
24432443
</DeprecatedConstant>
24442444
<InvalidArgument>
24452445
<code><![CDATA[$event->getObjectId()]]></code>
2446-
<code><![CDATA[$event->getObjectId()]]></code>
24472446
</InvalidArgument>
24482447
</file>
24492448
<file src="apps/systemtags/lib/AppInfo/Application.php">

lib/private/Files/Template/TemplateManager.php

Lines changed: 45 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -11,77 +11,59 @@
1111
use OC\AppFramework\Bootstrap\Coordinator;
1212
use OC\Files\Cache\Scanner;
1313
use OC\Files\Filesystem;
14+
use OCA\Files\ResponseDefinitions;
1415
use OCP\EventDispatcher\IEventDispatcher;
1516
use OCP\Files\File;
1617
use OCP\Files\Folder;
1718
use OCP\Files\GenericFileException;
1819
use OCP\Files\IFilenameValidator;
1920
use OCP\Files\IRootFolder;
20-
use OCP\Files\Node;
2121
use OCP\Files\NotFoundException;
2222
use OCP\Files\Template\BeforeGetTemplatesEvent;
23-
use OCP\Files\Template\Field;
2423
use OCP\Files\Template\FileCreatedFromTemplateEvent;
2524
use OCP\Files\Template\ICustomTemplateProvider;
2625
use OCP\Files\Template\ITemplateManager;
2726
use OCP\Files\Template\RegisterTemplateCreatorEvent;
2827
use OCP\Files\Template\Template;
2928
use OCP\Files\Template\TemplateFileCreator;
3029
use OCP\IConfig;
30+
use OCP\IL10N;
3131
use OCP\IPreview;
3232
use OCP\IServerContainer;
3333
use OCP\IUserManager;
34-
use OCP\IUserSession;
3534
use OCP\L10N\IFactory;
35+
use Override;
3636
use Psr\Log\LoggerInterface;
3737

38+
/**
39+
* @psalm-import-type FilesTemplateFile from ResponseDefinitions
40+
*/
3841
class TemplateManager implements ITemplateManager {
39-
private $registeredTypes = [];
40-
private $types = [];
41-
42-
/** @var array|null */
43-
private $providers = null;
44-
45-
private $serverContainer;
46-
private $eventDispatcher;
47-
private $rootFolder;
48-
private $userManager;
49-
private $previewManager;
50-
private $config;
51-
private $l10n;
52-
private $logger;
53-
private $userId;
54-
private $l10nFactory;
55-
/** @var Coordinator */
56-
private $bootstrapCoordinator;
42+
/** @var list<callable(): TemplateFileCreator> */
43+
private array $registeredTypes = [];
44+
/** @var list<TemplateFileCreator> */
45+
private array $types = [];
46+
/** @var array<class-string<ICustomTemplateProvider>, ICustomTemplateProvider>|null */
47+
private ?array $providers = null;
48+
private IL10n $l10n;
5749

5850
public function __construct(
59-
IServerContainer $serverContainer,
60-
IEventDispatcher $eventDispatcher,
61-
Coordinator $coordinator,
62-
IRootFolder $rootFolder,
63-
IUserSession $userSession,
64-
IUserManager $userManager,
65-
IPreview $previewManager,
66-
IConfig $config,
67-
IFactory $l10nFactory,
68-
LoggerInterface $logger,
69-
private IFilenameValidator $filenameValidator,
51+
private readonly IServerContainer $serverContainer,
52+
private readonly IEventDispatcher $eventDispatcher,
53+
private readonly Coordinator $bootstrapCoordinator,
54+
private readonly IRootFolder $rootFolder,
55+
private readonly IUserManager $userManager,
56+
private readonly IPreview $previewManager,
57+
private readonly IConfig $config,
58+
private readonly IFactory $l10nFactory,
59+
private readonly LoggerInterface $logger,
60+
private readonly IFilenameValidator $filenameValidator,
61+
private ?string $userId,
7062
) {
71-
$this->serverContainer = $serverContainer;
72-
$this->eventDispatcher = $eventDispatcher;
73-
$this->bootstrapCoordinator = $coordinator;
74-
$this->rootFolder = $rootFolder;
75-
$this->userManager = $userManager;
76-
$this->previewManager = $previewManager;
77-
$this->config = $config;
78-
$this->l10nFactory = $l10nFactory;
7963
$this->l10n = $l10nFactory->get('lib');
80-
$this->logger = $logger;
81-
$user = $userSession->getUser();
82-
$this->userId = $user ? $user->getUID() : null;
8364
}
8465

66+
#[Override]
8567
public function registerTemplateFileCreator(callable $callback): void {
8668
$this->registeredTypes[] = $callback;
8769
}
@@ -112,6 +94,7 @@ public function getTypes(): array {
11294
return $this->types;
11395
}
11496

97+
#[Override]
11598
public function listCreators(): array {
11699
$types = $this->getTypes();
117100
usort($types, function (TemplateFileCreator $a, TemplateFileCreator $b) {
@@ -120,6 +103,7 @@ public function listCreators(): array {
120103
return $types;
121104
}
122105

106+
#[Override]
123107
public function listTemplates(): array {
124108
return array_values(array_map(function (TemplateFileCreator $entry) {
125109
return array_merge($entry->jsonSerialize(), [
@@ -128,6 +112,7 @@ public function listTemplates(): array {
128112
}, $this->listCreators()));
129113
}
130114

115+
#[Override]
131116
public function listTemplateFields(int $fileId): array {
132117
foreach ($this->listCreators() as $creator) {
133118
$fields = $this->getTemplateFields($creator, $fileId);
@@ -141,13 +126,7 @@ public function listTemplateFields(int $fileId): array {
141126
return [];
142127
}
143128

144-
/**
145-
* @param string $filePath
146-
* @param string $templateId
147-
* @param array $templateFields
148-
* @return array
149-
* @throws GenericFileException
150-
*/
129+
#[Override]
151130
public function createFromTemplate(string $filePath, string $templateId = '', string $templateType = 'user', array $templateFields = []): array {
152131
$userFolder = $this->rootFolder->getUserFolder($this->userId);
153132
try {
@@ -159,6 +138,7 @@ public function createFromTemplate(string $filePath, string $templateId = '', st
159138
if (!$userFolder->nodeExists(dirname($filePath))) {
160139
throw new GenericFileException($this->l10n->t('Invalid path'));
161140
}
141+
/** @var Folder $folder */
162142
$folder = $userFolder->get(dirname($filePath));
163143
$template = null;
164144
if ($templateType === 'user' && $templateId !== '') {
@@ -178,15 +158,16 @@ public function createFromTemplate(string $filePath, string $templateId = '', st
178158
$targetFile = $folder->newFile($filename, ($template instanceof File ? $template->fopen('rb') : null));
179159

180160
$this->eventDispatcher->dispatchTyped(new FileCreatedFromTemplateEvent($template, $targetFile, $templateFields));
181-
return $this->formatFile($userFolder->get($filePath));
161+
/** @var File $file */
162+
$file = $userFolder->get($filePath);
163+
return $this->formatFile($file);
182164
} catch (\Exception $e) {
183165
$this->logger->error($e->getMessage(), ['exception' => $e]);
184166
throw new GenericFileException($this->l10n->t('Failed to create file from template'));
185167
}
186168
}
187169

188170
/**
189-
* @return Folder
190171
* @throws \OCP\Files\NotFoundException
191172
* @throws \OCP\Files\NotPermittedException
192173
* @throws \OC\User\NoUserException
@@ -245,6 +226,9 @@ private function getUserTemplates(TemplateFileCreator $type): array {
245226

246227
foreach ($type->getMimetypes() as $mimetype) {
247228
foreach ($userTemplateFolder->searchByMime($mimetype) as $templateFile) {
229+
if (!($templateFile instanceof File)) {
230+
continue;
231+
}
248232
$template = new Template(
249233
'user',
250234
$this->rootFolder->getUserFolder($this->userId)->getRelativePath($templateFile->getPath()),
@@ -267,33 +251,28 @@ private function getTemplateFields(TemplateFileCreator $type, int $fileId): arra
267251

268252
$matchedTemplates = array_filter(
269253
array_merge($providerTemplates, $userTemplates),
270-
function (Template $template) use ($fileId) {
271-
return $template->jsonSerialize()['fileid'] === $fileId;
272-
});
254+
fn (Template $template): bool => $template->jsonSerialize()['fileid'] === $fileId);
273255

274256
if (empty($matchedTemplates)) {
275257
return [];
276258
}
277259

278260
$this->eventDispatcher->dispatchTyped(new BeforeGetTemplatesEvent($matchedTemplates, true));
279261

280-
return array_values(array_map(function (Template $template) {
281-
return $template->jsonSerialize()['fields'] ?? [];
282-
}, $matchedTemplates));
262+
return array_values(array_map(static fn (Template $template): array => $template->jsonSerialize()['fields'] ?? [], $matchedTemplates));
283263
}
284264

285265
/**
286-
* @param Node|File $file
287-
* @return array
266+
* @return FilesTemplateFile
288267
* @throws NotFoundException
289268
* @throws \OCP\Files\InvalidPathException
290269
*/
291-
private function formatFile(Node $file): array {
270+
private function formatFile(File $file): array {
292271
return [
293272
'basename' => $file->getName(),
294273
'etag' => $file->getEtag(),
295-
'fileid' => $file->getId(),
296-
'filename' => $this->rootFolder->getUserFolder($this->userId)->getRelativePath($file->getPath()),
274+
'fileid' => $file->getId() ?? -1,
275+
'filename' => $this->rootFolder->getUserFolder($this->userId)->getRelativePath($file->getPath()) ?? '',
297276
'lastmod' => $file->getMTime(),
298277
'mime' => $file->getMimetype(),
299278
'size' => $file->getSize(),
@@ -365,8 +344,10 @@ public function initializeTemplateDirectory(?string $path = null, ?string $userI
365344
}
366345

367346
try {
347+
/** @var Folder $folder */
368348
$folder = $userFolder->get($userTemplatePath);
369349
} catch (NotFoundException $e) {
350+
/** @var Folder $folder */
370351
$folder = $userFolder->get(dirname($userTemplatePath));
371352
$folder = $folder->newFolder(basename($userTemplatePath));
372353
}
@@ -407,7 +388,7 @@ public function initializeTemplateDirectory(?string $path = null, ?string $userI
407388
return $this->getTemplatePath();
408389
}
409390

410-
private function getLocalizedTemplatePath(string $skeletonTemplatePath, string $userLang) {
391+
private function getLocalizedTemplatePath(string $skeletonTemplatePath, string $userLang): string {
411392
$localizedSkeletonTemplatePath = str_replace('{lang}', $userLang, $skeletonTemplatePath);
412393

413394
if (!file_exists($localizedSkeletonTemplatePath)) {

lib/public/Files/Template/ITemplateManager.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
*/
99
namespace OCP\Files\Template;
1010

11+
use OCA\Files\ResponseDefinitions;
1112
use OCP\Files\GenericFileException;
1213

1314
/**
1415
* @since 21.0.0
16+
* @psalm-import-type FilesTemplateFile from ResponseDefinitions
1517
*/
1618
interface ITemplateManager {
1719
/**
@@ -78,7 +80,7 @@ public function initializeTemplateDirectory(?string $path = null, ?string $userI
7880
* @param string $templateId
7981
* @param string $templateType
8082
* @param array $templateFields Since 30.0.0
81-
* @return array
83+
* @return FilesTemplateFile
8284
* @throws GenericFileException
8385
* @since 21.0.0
8486
*/

openapi.json

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,7 +1908,8 @@
19081908
"mime",
19091909
"size",
19101910
"type",
1911-
"hasPreview"
1911+
"hasPreview",
1912+
"permissions"
19121913
],
19131914
"properties": {
19141915
"basename": {
@@ -1922,8 +1923,7 @@
19221923
"format": "int64"
19231924
},
19241925
"filename": {
1925-
"type": "string",
1926-
"nullable": true
1926+
"type": "string"
19271927
},
19281928
"lastmod": {
19291929
"type": "integer",
@@ -1933,14 +1933,26 @@
19331933
"type": "string"
19341934
},
19351935
"size": {
1936-
"type": "integer",
1937-
"format": "int64"
1936+
"anyOf": [
1937+
{
1938+
"type": "integer",
1939+
"format": "int64"
1940+
},
1941+
{
1942+
"type": "number",
1943+
"format": "double"
1944+
}
1945+
]
19381946
},
19391947
"type": {
19401948
"type": "string"
19411949
},
19421950
"hasPreview": {
19431951
"type": "boolean"
1952+
},
1953+
"permissions": {
1954+
"type": "integer",
1955+
"format": "int64"
19441956
}
19451957
}
19461958
},

0 commit comments

Comments
 (0)