Skip to content

Commit f144421

Browse files
committed
refactor(template-manager): Modernize template manager API
And correct openapi types for the size. Signed-off-by: Carl Schwan <[email protected]>
1 parent 52f99e6 commit f144421

File tree

6 files changed

+102
-74
lines changed

6 files changed

+102
-74
lines changed

apps/files/lib/ResponseDefinitions.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
* 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
},

lib/private/Files/Template/TemplateManager.php

Lines changed: 57 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -11,82 +11,70 @@
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;
32-
use OCP\IServerContainer;
3332
use OCP\IUserManager;
3433
use OCP\IUserSession;
3534
use OCP\L10N\IFactory;
35+
use Override;
36+
use Psr\Container\ContainerInterface;
3637
use Psr\Log\LoggerInterface;
3738

39+
/**
40+
* @psalm-import-type FilesTemplateFile from ResponseDefinitions
41+
*/
3842
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;
43+
/** @var list<callable(): TemplateFileCreator> */
44+
private array $registeredTypes = [];
45+
/** @var list<TemplateFileCreator> */
46+
private array $types = [];
47+
/** @var array<class-string<ICustomTemplateProvider>, ICustomTemplateProvider>|null */
48+
private ?array $providers = null;
49+
private IL10n $l10n;
50+
private ?string $userId;
5751

5852
public function __construct(
59-
IServerContainer $serverContainer,
60-
IEventDispatcher $eventDispatcher,
61-
Coordinator $coordinator,
62-
IRootFolder $rootFolder,
53+
private readonly ContainerInterface $serverContainer,
54+
private readonly IEventDispatcher $eventDispatcher,
55+
private readonly Coordinator $bootstrapCoordinator,
56+
private readonly IRootFolder $rootFolder,
6357
IUserSession $userSession,
64-
IUserManager $userManager,
65-
IPreview $previewManager,
66-
IConfig $config,
67-
IFactory $l10nFactory,
68-
LoggerInterface $logger,
69-
private IFilenameValidator $filenameValidator,
58+
private readonly IUserManager $userManager,
59+
private readonly IPreview $previewManager,
60+
private readonly IConfig $config,
61+
private readonly IFactory $l10nFactory,
62+
private readonly LoggerInterface $logger,
63+
private readonly IFilenameValidator $filenameValidator,
7064
) {
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;
7965
$this->l10n = $l10nFactory->get('lib');
80-
$this->logger = $logger;
81-
$user = $userSession->getUser();
82-
$this->userId = $user ? $user->getUID() : null;
66+
$this->userId = $userSession->getUser()?->getUID();
8367
}
8468

69+
#[Override]
8570
public function registerTemplateFileCreator(callable $callback): void {
8671
$this->registeredTypes[] = $callback;
8772
}
8873

89-
public function getRegisteredProviders(): array {
74+
/**
75+
* @return array<class-string<ICustomTemplateProvider>, ICustomTemplateProvider>
76+
*/
77+
private function getRegisteredProviders(): array {
9078
if ($this->providers !== null) {
9179
return $this->providers;
9280
}
@@ -101,7 +89,10 @@ public function getRegisteredProviders(): array {
10189
return $this->providers;
10290
}
10391

104-
public function getTypes(): array {
92+
/**
93+
* @return list<TemplateFileCreator>
94+
*/
95+
private function getTypes(): array {
10596
if (!empty($this->types)) {
10697
return $this->types;
10798
}
@@ -112,6 +103,7 @@ public function getTypes(): array {
112103
return $this->types;
113104
}
114105

106+
#[Override]
115107
public function listCreators(): array {
116108
$types = $this->getTypes();
117109
usort($types, function (TemplateFileCreator $a, TemplateFileCreator $b) {
@@ -120,6 +112,7 @@ public function listCreators(): array {
120112
return $types;
121113
}
122114

115+
#[Override]
123116
public function listTemplates(): array {
124117
return array_values(array_map(function (TemplateFileCreator $entry) {
125118
return array_merge($entry->jsonSerialize(), [
@@ -128,6 +121,7 @@ public function listTemplates(): array {
128121
}, $this->listCreators()));
129122
}
130123

124+
#[Override]
131125
public function listTemplateFields(int $fileId): array {
132126
foreach ($this->listCreators() as $creator) {
133127
$fields = $this->getTemplateFields($creator, $fileId);
@@ -141,13 +135,7 @@ public function listTemplateFields(int $fileId): array {
141135
return [];
142136
}
143137

144-
/**
145-
* @param string $filePath
146-
* @param string $templateId
147-
* @param array $templateFields
148-
* @return array
149-
* @throws GenericFileException
150-
*/
138+
#[Override]
151139
public function createFromTemplate(string $filePath, string $templateId = '', string $templateType = 'user', array $templateFields = []): array {
152140
$userFolder = $this->rootFolder->getUserFolder($this->userId);
153141
try {
@@ -159,6 +147,7 @@ public function createFromTemplate(string $filePath, string $templateId = '', st
159147
if (!$userFolder->nodeExists(dirname($filePath))) {
160148
throw new GenericFileException($this->l10n->t('Invalid path'));
161149
}
150+
/** @var Folder $folder */
162151
$folder = $userFolder->get(dirname($filePath));
163152
$template = null;
164153
if ($templateType === 'user' && $templateId !== '') {
@@ -178,15 +167,16 @@ public function createFromTemplate(string $filePath, string $templateId = '', st
178167
$targetFile = $folder->newFile($filename, ($template instanceof File ? $template->fopen('rb') : null));
179168

180169
$this->eventDispatcher->dispatchTyped(new FileCreatedFromTemplateEvent($template, $targetFile, $templateFields));
181-
return $this->formatFile($userFolder->get($filePath));
170+
/** @var File $file */
171+
$file = $userFolder->get($filePath);
172+
return $this->formatFile($file);
182173
} catch (\Exception $e) {
183174
$this->logger->error($e->getMessage(), ['exception' => $e]);
184175
throw new GenericFileException($this->l10n->t('Failed to create file from template'));
185176
}
186177
}
187178

188179
/**
189-
* @return Folder
190180
* @throws \OCP\Files\NotFoundException
191181
* @throws \OCP\Files\NotPermittedException
192182
* @throws \OC\User\NoUserException
@@ -245,6 +235,9 @@ private function getUserTemplates(TemplateFileCreator $type): array {
245235

246236
foreach ($type->getMimetypes() as $mimetype) {
247237
foreach ($userTemplateFolder->searchByMime($mimetype) as $templateFile) {
238+
if (!($templateFile instanceof File)) {
239+
continue;
240+
}
248241
$template = new Template(
249242
'user',
250243
$this->rootFolder->getUserFolder($this->userId)->getRelativePath($templateFile->getPath()),
@@ -267,32 +260,27 @@ private function getTemplateFields(TemplateFileCreator $type, int $fileId): arra
267260

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

274265
if (empty($matchedTemplates)) {
275266
return [];
276267
}
277268

278269
$this->eventDispatcher->dispatchTyped(new BeforeGetTemplatesEvent($matchedTemplates, true));
279270

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

285274
/**
286-
* @param Node|File $file
287-
* @return array
275+
* @return FilesTemplateFile
288276
* @throws NotFoundException
289277
* @throws \OCP\Files\InvalidPathException
290278
*/
291-
private function formatFile(Node $file): array {
279+
private function formatFile(File $file): array {
292280
return [
293281
'basename' => $file->getName(),
294282
'etag' => $file->getEtag(),
295-
'fileid' => $file->getId(),
283+
'fileid' => $file->getId() ?? -1,
296284
'filename' => $this->rootFolder->getUserFolder($this->userId)->getRelativePath($file->getPath()),
297285
'lastmod' => $file->getMTime(),
298286
'mime' => $file->getMimetype(),
@@ -312,14 +300,17 @@ public function hasTemplateDirectory(): bool {
312300
return false;
313301
}
314302

303+
#[Override]
315304
public function setTemplatePath(string $path): void {
316305
$this->config->setUserValue($this->userId, 'core', 'templateDirectory', $path);
317306
}
318307

308+
#[Override]
319309
public function getTemplatePath(): string {
320310
return $this->config->getUserValue($this->userId, 'core', 'templateDirectory', '');
321311
}
322312

313+
#[Override]
323314
public function initializeTemplateDirectory(?string $path = null, ?string $userId = null, $copyTemplates = true): string {
324315
if ($userId !== null) {
325316
$this->userId = $userId;
@@ -365,8 +356,10 @@ public function initializeTemplateDirectory(?string $path = null, ?string $userI
365356
}
366357

367358
try {
359+
/** @var Folder $folder */
368360
$folder = $userFolder->get($userTemplatePath);
369361
} catch (NotFoundException $e) {
362+
/** @var Folder $folder */
370363
$folder = $userFolder->get(dirname($userTemplatePath));
371364
$folder = $folder->newFolder(basename($userTemplatePath));
372365
}
@@ -407,7 +400,7 @@ public function initializeTemplateDirectory(?string $path = null, ?string $userI
407400
return $this->getTemplatePath();
408401
}
409402

410-
private function getLocalizedTemplatePath(string $skeletonTemplatePath, string $userLang) {
403+
private function getLocalizedTemplatePath(string $skeletonTemplatePath, string $userLang): string {
411404
$localizedSkeletonTemplatePath = str_replace('{lang}', $userLang, $skeletonTemplatePath);
412405

413406
if (!file_exists($localizedSkeletonTemplatePath)) {

lib/public/Files/Template/ITemplateManager.php

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

11+
use OCA\Files\ResponseDefinitions;
12+
use OCP\AppFramework\Attribute\Consumable;
1113
use OCP\Files\GenericFileException;
1214

1315
/**
1416
* @since 21.0.0
17+
* @psalm-import-type FilesTemplateFile from ResponseDefinitions
1518
*/
19+
#[Consumable(since: '21.0.0')]
1620
interface ITemplateManager {
1721
/**
1822
* Register a template type support
@@ -78,7 +82,7 @@ public function initializeTemplateDirectory(?string $path = null, ?string $userI
7882
* @param string $templateId
7983
* @param string $templateType
8084
* @param array $templateFields Since 30.0.0
81-
* @return array
85+
* @return FilesTemplateFile
8286
* @throws GenericFileException
8387
* @since 21.0.0
8488
*/

0 commit comments

Comments
 (0)