Passed
Push — master ( 037411...507fac )
by Roeland
28:26 queued 12:26
created
lib/private/Files/Template/TemplateManager.php 1 patch
Indentation   +306 added lines, -306 removed lines patch added patch discarded remove patch
@@ -50,310 +50,310 @@
 block discarded – undo
50 50
 use Psr\Log\LoggerInterface;
51 51
 
52 52
 class TemplateManager implements ITemplateManager {
53
-	private $registeredTypes = [];
54
-	private $types = [];
55
-
56
-	/** @var array|null */
57
-	private $providers = null;
58
-
59
-	private $serverContainer;
60
-	private $eventDispatcher;
61
-	private $rootFolder;
62
-	private $userManager;
63
-	private $previewManager;
64
-	private $config;
65
-	private $l10n;
66
-	private $logger;
67
-	private $userId;
68
-	private $l10nFactory;
69
-	/** @var Coordinator */
70
-	private $bootstrapCoordinator;
71
-
72
-	public function __construct(
73
-		IServerContainer $serverContainer,
74
-		IEventDispatcher $eventDispatcher,
75
-		Coordinator $coordinator,
76
-		IRootFolder $rootFolder,
77
-		IUserSession $userSession,
78
-		IUserManager $userManager,
79
-		IPreview $previewManager,
80
-		IConfig $config,
81
-		IFactory $l10nFactory,
82
-		LoggerInterface $logger
83
-	) {
84
-		$this->serverContainer = $serverContainer;
85
-		$this->eventDispatcher = $eventDispatcher;
86
-		$this->bootstrapCoordinator = $coordinator;
87
-		$this->rootFolder = $rootFolder;
88
-		$this->userManager = $userManager;
89
-		$this->previewManager = $previewManager;
90
-		$this->config = $config;
91
-		$this->l10nFactory = $l10nFactory;
92
-		$this->l10n = $l10nFactory->get('lib');
93
-		$this->logger = $logger;
94
-		$user = $userSession->getUser();
95
-		$this->userId = $user ? $user->getUID() : null;
96
-	}
97
-
98
-	public function registerTemplateFileCreator(callable $callback): void {
99
-		$this->registeredTypes[] = $callback;
100
-	}
101
-
102
-	public function getRegisteredProviders(): array {
103
-		if ($this->providers !== null) {
104
-			return $this->providers;
105
-		}
106
-
107
-		$context = $this->bootstrapCoordinator->getRegistrationContext();
108
-
109
-		$this->providers = [];
110
-		foreach ($context->getTemplateProviders() as $provider) {
111
-			$class = $provider->getService();
112
-			$this->providers[$class] = $this->serverContainer->get($class);
113
-		}
114
-		return $this->providers;
115
-	}
116
-
117
-	public function getTypes(): array {
118
-		if (!empty($this->types)) {
119
-			return $this->types;
120
-		}
121
-		foreach ($this->registeredTypes as $registeredType) {
122
-			$this->types[] = $registeredType();
123
-		}
124
-		return $this->types;
125
-	}
126
-
127
-	public function listCreators(): array {
128
-		$types = $this->getTypes();
129
-		usort($types, function (TemplateFileCreator $a, TemplateFileCreator $b) {
130
-			return $a->getOrder() - $b->getOrder();
131
-		});
132
-		return $types;
133
-	}
134
-
135
-	public function listTemplates(): array {
136
-		return array_map(function (TemplateFileCreator $entry) {
137
-			return array_merge($entry->jsonSerialize(), [
138
-				'templates' => $this->getTemplateFiles($entry)
139
-			]);
140
-		}, $this->listCreators());
141
-	}
142
-
143
-	/**
144
-	 * @param string $filePath
145
-	 * @param string $templateId
146
-	 * @return array
147
-	 * @throws GenericFileException
148
-	 */
149
-	public function createFromTemplate(string $filePath, string $templateId = '', string $templateType = 'user'): array {
150
-		$userFolder = $this->rootFolder->getUserFolder($this->userId);
151
-		try {
152
-			$userFolder->get($filePath);
153
-			throw new GenericFileException($this->l10n->t('File already exists'));
154
-		} catch (NotFoundException $e) {
155
-		}
156
-		try {
157
-			if (!$userFolder->nodeExists(dirname($filePath))) {
158
-				throw new GenericFileException($this->l10n->t('Invalid path'));
159
-			}
160
-			$folder = $userFolder->get(dirname($filePath));
161
-			$targetFile = $folder->newFile(basename($filePath));
162
-			if ($templateType === 'user' && $templateId !== '') {
163
-				$template = $userFolder->get($templateId);
164
-				$template->copy($targetFile->getPath());
165
-			} else {
166
-				$matchingProvider = array_filter($this->getRegisteredProviders(), function (ICustomTemplateProvider $provider) use ($templateType) {
167
-					return $templateType === get_class($provider);
168
-				});
169
-				$provider = array_shift($matchingProvider);
170
-				if ($provider) {
171
-					$template = $provider->getCustomTemplate($templateId);
172
-					$template->copy($targetFile->getPath());
173
-				}
174
-			}
175
-			$this->eventDispatcher->dispatchTyped(new FileCreatedFromTemplateEvent($template, $targetFile));
176
-			return $this->formatFile($userFolder->get($filePath));
177
-		} catch (\Exception $e) {
178
-			$this->logger->error($e->getMessage(), ['exception' => $e]);
179
-			throw new GenericFileException($this->l10n->t('Failed to create file from template'));
180
-		}
181
-	}
182
-
183
-	/**
184
-	 * @return Folder
185
-	 * @throws \OCP\Files\NotFoundException
186
-	 * @throws \OCP\Files\NotPermittedException
187
-	 * @throws \OC\User\NoUserException
188
-	 */
189
-	private function getTemplateFolder(): Node {
190
-		if ($this->getTemplatePath() !== '') {
191
-			return $this->rootFolder->getUserFolder($this->userId)->get($this->getTemplatePath());
192
-		}
193
-		throw new NotFoundException();
194
-	}
195
-
196
-	private function getTemplateFiles(TemplateFileCreator $type): array {
197
-		$templates = [];
198
-		foreach ($this->getRegisteredProviders() as $provider) {
199
-			foreach ($type->getMimetypes() as $mimetype) {
200
-				foreach ($provider->getCustomTemplates($mimetype) as $template) {
201
-					$templates[] = $template;
202
-				}
203
-			}
204
-		}
205
-		try {
206
-			$userTemplateFolder = $this->getTemplateFolder();
207
-		} catch (\Exception $e) {
208
-			return $templates;
209
-		}
210
-		foreach ($type->getMimetypes() as $mimetype) {
211
-			foreach ($userTemplateFolder->searchByMime($mimetype) as $templateFile) {
212
-				$template = new Template(
213
-					'user',
214
-					$this->rootFolder->getUserFolder($this->userId)->getRelativePath($templateFile->getPath()),
215
-					$templateFile
216
-				);
217
-				$template->setHasPreview($this->previewManager->isAvailable($templateFile));
218
-				$templates[] = $template;
219
-			}
220
-		}
221
-
222
-		return $templates;
223
-	}
224
-
225
-	/**
226
-	 * @param Node|File $file
227
-	 * @return array
228
-	 * @throws NotFoundException
229
-	 * @throws \OCP\Files\InvalidPathException
230
-	 */
231
-	private function formatFile(Node $file): array {
232
-		return [
233
-			'basename' => $file->getName(),
234
-			'etag' => $file->getEtag(),
235
-			'fileid' => $file->getId(),
236
-			'filename' => $this->rootFolder->getUserFolder($this->userId)->getRelativePath($file->getPath()),
237
-			'lastmod' => $file->getMTime(),
238
-			'mime' => $file->getMimetype(),
239
-			'size' => $file->getSize(),
240
-			'type' => $file->getType(),
241
-			'hasPreview' => $this->previewManager->isAvailable($file)
242
-		];
243
-	}
244
-
245
-	public function hasTemplateDirectory(): bool {
246
-		try {
247
-			$this->getTemplateFolder();
248
-			return true;
249
-		} catch (\Exception $e) {
250
-		}
251
-		return false;
252
-	}
253
-
254
-	public function setTemplatePath(string $path): void {
255
-		$this->config->setUserValue($this->userId, 'core', 'templateDirectory', $path);
256
-	}
257
-
258
-	public function getTemplatePath(): string {
259
-		return $this->config->getUserValue($this->userId, 'core', 'templateDirectory', '');
260
-	}
261
-
262
-	public function initializeTemplateDirectory(string $path = null, string $userId = null, $copyTemplates = true): string {
263
-		if ($userId !== null) {
264
-			$this->userId = $userId;
265
-		}
266
-
267
-		$defaultSkeletonDirectory = \OC::$SERVERROOT . '/core/skeleton';
268
-		$defaultTemplateDirectory = \OC::$SERVERROOT . '/core/skeleton/Templates';
269
-		$skeletonPath = $this->config->getSystemValue('skeletondirectory', $defaultSkeletonDirectory);
270
-		$skeletonTemplatePath = $this->config->getSystemValue('templatedirectory', $defaultTemplateDirectory);
271
-		$isDefaultSkeleton = $skeletonPath === $defaultSkeletonDirectory;
272
-		$isDefaultTemplates = $skeletonTemplatePath === $defaultTemplateDirectory;
273
-		$userLang = $this->l10nFactory->getUserLanguage($this->userManager->get($this->userId));
274
-
275
-		try {
276
-			$l10n = $this->l10nFactory->get('lib', $userLang);
277
-			$userFolder = $this->rootFolder->getUserFolder($this->userId);
278
-			$userTemplatePath = $path ?? $l10n->t('Templates') . '/';
279
-
280
-			// Initial user setup without a provided path
281
-			if ($path === null) {
282
-				// All locations are default so we just need to rename the directory to the users language
283
-				if ($isDefaultSkeleton && $isDefaultTemplates) {
284
-					if (!$userFolder->nodeExists('Templates')) {
285
-						return '';
286
-					}
287
-					$newPath = Filesystem::normalizePath($userFolder->getPath() . '/' . $userTemplatePath);
288
-					if ($newPath !== $userFolder->get('Templates')->getPath()) {
289
-						$userFolder->get('Templates')->move($newPath);
290
-					}
291
-					$this->setTemplatePath($userTemplatePath);
292
-					return $userTemplatePath;
293
-				}
294
-
295
-				if ($isDefaultSkeleton && !empty($skeletonTemplatePath) && !$isDefaultTemplates && $userFolder->nodeExists('Templates')) {
296
-					$shippedSkeletonTemplates = $userFolder->get('Templates');
297
-					$shippedSkeletonTemplates->delete();
298
-				}
299
-			}
300
-
301
-			try {
302
-				$folder = $userFolder->get($userTemplatePath);
303
-			} catch (NotFoundException $e) {
304
-				$folder = $userFolder->get(dirname($userTemplatePath));
305
-				$folder = $folder->newFolder(basename($userTemplatePath));
306
-			}
307
-
308
-			$folderIsEmpty = count($folder->getDirectoryListing()) === 0;
309
-
310
-			if (!$copyTemplates) {
311
-				$this->setTemplatePath($userTemplatePath);
312
-				return $userTemplatePath;
313
-			}
314
-
315
-			if (!$isDefaultTemplates && $folderIsEmpty) {
316
-				$localizedSkeletonTemplatePath = $this->getLocalizedTemplatePath($skeletonTemplatePath, $userLang);
317
-				if (!empty($localizedSkeletonTemplatePath) && file_exists($localizedSkeletonTemplatePath)) {
318
-					\OC_Util::copyr($localizedSkeletonTemplatePath, $folder);
319
-					$userFolder->getStorage()->getScanner()->scan($folder->getInternalPath(), Scanner::SCAN_RECURSIVE);
320
-					$this->setTemplatePath($userTemplatePath);
321
-					return $userTemplatePath;
322
-				}
323
-			}
324
-
325
-			if ($path !== null && $isDefaultSkeleton && $isDefaultTemplates && $folderIsEmpty) {
326
-				$localizedSkeletonPath = $this->getLocalizedTemplatePath($skeletonPath . '/Templates', $userLang);
327
-				if (!empty($localizedSkeletonPath) && file_exists($localizedSkeletonPath)) {
328
-					\OC_Util::copyr($localizedSkeletonPath, $folder);
329
-					$userFolder->getStorage()->getScanner()->scan($folder->getInternalPath(), Scanner::SCAN_RECURSIVE);
330
-					$this->setTemplatePath($userTemplatePath);
331
-					return $userTemplatePath;
332
-				}
333
-			}
334
-
335
-			$this->setTemplatePath($path ?? '');
336
-			return $this->getTemplatePath();
337
-		} catch (\Throwable $e) {
338
-			$this->logger->error('Failed to initialize templates directory to user language ' . $userLang . ' for ' . $userId, ['app' => 'files_templates', 'exception' => $e]);
339
-		}
340
-		$this->setTemplatePath('');
341
-		return $this->getTemplatePath();
342
-	}
343
-
344
-	private function getLocalizedTemplatePath(string $skeletonTemplatePath, string $userLang) {
345
-		$localizedSkeletonTemplatePath = str_replace('{lang}', $userLang, $skeletonTemplatePath);
346
-
347
-		if (!file_exists($localizedSkeletonTemplatePath)) {
348
-			$dialectStart = strpos($userLang, '_');
349
-			if ($dialectStart !== false) {
350
-				$localizedSkeletonTemplatePath = str_replace('{lang}', substr($userLang, 0, $dialectStart), $skeletonTemplatePath);
351
-			}
352
-			if ($dialectStart === false || !file_exists($localizedSkeletonTemplatePath)) {
353
-				$localizedSkeletonTemplatePath = str_replace('{lang}', 'default', $skeletonTemplatePath);
354
-			}
355
-		}
356
-
357
-		return $localizedSkeletonTemplatePath;
358
-	}
53
+    private $registeredTypes = [];
54
+    private $types = [];
55
+
56
+    /** @var array|null */
57
+    private $providers = null;
58
+
59
+    private $serverContainer;
60
+    private $eventDispatcher;
61
+    private $rootFolder;
62
+    private $userManager;
63
+    private $previewManager;
64
+    private $config;
65
+    private $l10n;
66
+    private $logger;
67
+    private $userId;
68
+    private $l10nFactory;
69
+    /** @var Coordinator */
70
+    private $bootstrapCoordinator;
71
+
72
+    public function __construct(
73
+        IServerContainer $serverContainer,
74
+        IEventDispatcher $eventDispatcher,
75
+        Coordinator $coordinator,
76
+        IRootFolder $rootFolder,
77
+        IUserSession $userSession,
78
+        IUserManager $userManager,
79
+        IPreview $previewManager,
80
+        IConfig $config,
81
+        IFactory $l10nFactory,
82
+        LoggerInterface $logger
83
+    ) {
84
+        $this->serverContainer = $serverContainer;
85
+        $this->eventDispatcher = $eventDispatcher;
86
+        $this->bootstrapCoordinator = $coordinator;
87
+        $this->rootFolder = $rootFolder;
88
+        $this->userManager = $userManager;
89
+        $this->previewManager = $previewManager;
90
+        $this->config = $config;
91
+        $this->l10nFactory = $l10nFactory;
92
+        $this->l10n = $l10nFactory->get('lib');
93
+        $this->logger = $logger;
94
+        $user = $userSession->getUser();
95
+        $this->userId = $user ? $user->getUID() : null;
96
+    }
97
+
98
+    public function registerTemplateFileCreator(callable $callback): void {
99
+        $this->registeredTypes[] = $callback;
100
+    }
101
+
102
+    public function getRegisteredProviders(): array {
103
+        if ($this->providers !== null) {
104
+            return $this->providers;
105
+        }
106
+
107
+        $context = $this->bootstrapCoordinator->getRegistrationContext();
108
+
109
+        $this->providers = [];
110
+        foreach ($context->getTemplateProviders() as $provider) {
111
+            $class = $provider->getService();
112
+            $this->providers[$class] = $this->serverContainer->get($class);
113
+        }
114
+        return $this->providers;
115
+    }
116
+
117
+    public function getTypes(): array {
118
+        if (!empty($this->types)) {
119
+            return $this->types;
120
+        }
121
+        foreach ($this->registeredTypes as $registeredType) {
122
+            $this->types[] = $registeredType();
123
+        }
124
+        return $this->types;
125
+    }
126
+
127
+    public function listCreators(): array {
128
+        $types = $this->getTypes();
129
+        usort($types, function (TemplateFileCreator $a, TemplateFileCreator $b) {
130
+            return $a->getOrder() - $b->getOrder();
131
+        });
132
+        return $types;
133
+    }
134
+
135
+    public function listTemplates(): array {
136
+        return array_map(function (TemplateFileCreator $entry) {
137
+            return array_merge($entry->jsonSerialize(), [
138
+                'templates' => $this->getTemplateFiles($entry)
139
+            ]);
140
+        }, $this->listCreators());
141
+    }
142
+
143
+    /**
144
+     * @param string $filePath
145
+     * @param string $templateId
146
+     * @return array
147
+     * @throws GenericFileException
148
+     */
149
+    public function createFromTemplate(string $filePath, string $templateId = '', string $templateType = 'user'): array {
150
+        $userFolder = $this->rootFolder->getUserFolder($this->userId);
151
+        try {
152
+            $userFolder->get($filePath);
153
+            throw new GenericFileException($this->l10n->t('File already exists'));
154
+        } catch (NotFoundException $e) {
155
+        }
156
+        try {
157
+            if (!$userFolder->nodeExists(dirname($filePath))) {
158
+                throw new GenericFileException($this->l10n->t('Invalid path'));
159
+            }
160
+            $folder = $userFolder->get(dirname($filePath));
161
+            $targetFile = $folder->newFile(basename($filePath));
162
+            if ($templateType === 'user' && $templateId !== '') {
163
+                $template = $userFolder->get($templateId);
164
+                $template->copy($targetFile->getPath());
165
+            } else {
166
+                $matchingProvider = array_filter($this->getRegisteredProviders(), function (ICustomTemplateProvider $provider) use ($templateType) {
167
+                    return $templateType === get_class($provider);
168
+                });
169
+                $provider = array_shift($matchingProvider);
170
+                if ($provider) {
171
+                    $template = $provider->getCustomTemplate($templateId);
172
+                    $template->copy($targetFile->getPath());
173
+                }
174
+            }
175
+            $this->eventDispatcher->dispatchTyped(new FileCreatedFromTemplateEvent($template, $targetFile));
176
+            return $this->formatFile($userFolder->get($filePath));
177
+        } catch (\Exception $e) {
178
+            $this->logger->error($e->getMessage(), ['exception' => $e]);
179
+            throw new GenericFileException($this->l10n->t('Failed to create file from template'));
180
+        }
181
+    }
182
+
183
+    /**
184
+     * @return Folder
185
+     * @throws \OCP\Files\NotFoundException
186
+     * @throws \OCP\Files\NotPermittedException
187
+     * @throws \OC\User\NoUserException
188
+     */
189
+    private function getTemplateFolder(): Node {
190
+        if ($this->getTemplatePath() !== '') {
191
+            return $this->rootFolder->getUserFolder($this->userId)->get($this->getTemplatePath());
192
+        }
193
+        throw new NotFoundException();
194
+    }
195
+
196
+    private function getTemplateFiles(TemplateFileCreator $type): array {
197
+        $templates = [];
198
+        foreach ($this->getRegisteredProviders() as $provider) {
199
+            foreach ($type->getMimetypes() as $mimetype) {
200
+                foreach ($provider->getCustomTemplates($mimetype) as $template) {
201
+                    $templates[] = $template;
202
+                }
203
+            }
204
+        }
205
+        try {
206
+            $userTemplateFolder = $this->getTemplateFolder();
207
+        } catch (\Exception $e) {
208
+            return $templates;
209
+        }
210
+        foreach ($type->getMimetypes() as $mimetype) {
211
+            foreach ($userTemplateFolder->searchByMime($mimetype) as $templateFile) {
212
+                $template = new Template(
213
+                    'user',
214
+                    $this->rootFolder->getUserFolder($this->userId)->getRelativePath($templateFile->getPath()),
215
+                    $templateFile
216
+                );
217
+                $template->setHasPreview($this->previewManager->isAvailable($templateFile));
218
+                $templates[] = $template;
219
+            }
220
+        }
221
+
222
+        return $templates;
223
+    }
224
+
225
+    /**
226
+     * @param Node|File $file
227
+     * @return array
228
+     * @throws NotFoundException
229
+     * @throws \OCP\Files\InvalidPathException
230
+     */
231
+    private function formatFile(Node $file): array {
232
+        return [
233
+            'basename' => $file->getName(),
234
+            'etag' => $file->getEtag(),
235
+            'fileid' => $file->getId(),
236
+            'filename' => $this->rootFolder->getUserFolder($this->userId)->getRelativePath($file->getPath()),
237
+            'lastmod' => $file->getMTime(),
238
+            'mime' => $file->getMimetype(),
239
+            'size' => $file->getSize(),
240
+            'type' => $file->getType(),
241
+            'hasPreview' => $this->previewManager->isAvailable($file)
242
+        ];
243
+    }
244
+
245
+    public function hasTemplateDirectory(): bool {
246
+        try {
247
+            $this->getTemplateFolder();
248
+            return true;
249
+        } catch (\Exception $e) {
250
+        }
251
+        return false;
252
+    }
253
+
254
+    public function setTemplatePath(string $path): void {
255
+        $this->config->setUserValue($this->userId, 'core', 'templateDirectory', $path);
256
+    }
257
+
258
+    public function getTemplatePath(): string {
259
+        return $this->config->getUserValue($this->userId, 'core', 'templateDirectory', '');
260
+    }
261
+
262
+    public function initializeTemplateDirectory(string $path = null, string $userId = null, $copyTemplates = true): string {
263
+        if ($userId !== null) {
264
+            $this->userId = $userId;
265
+        }
266
+
267
+        $defaultSkeletonDirectory = \OC::$SERVERROOT . '/core/skeleton';
268
+        $defaultTemplateDirectory = \OC::$SERVERROOT . '/core/skeleton/Templates';
269
+        $skeletonPath = $this->config->getSystemValue('skeletondirectory', $defaultSkeletonDirectory);
270
+        $skeletonTemplatePath = $this->config->getSystemValue('templatedirectory', $defaultTemplateDirectory);
271
+        $isDefaultSkeleton = $skeletonPath === $defaultSkeletonDirectory;
272
+        $isDefaultTemplates = $skeletonTemplatePath === $defaultTemplateDirectory;
273
+        $userLang = $this->l10nFactory->getUserLanguage($this->userManager->get($this->userId));
274
+
275
+        try {
276
+            $l10n = $this->l10nFactory->get('lib', $userLang);
277
+            $userFolder = $this->rootFolder->getUserFolder($this->userId);
278
+            $userTemplatePath = $path ?? $l10n->t('Templates') . '/';
279
+
280
+            // Initial user setup without a provided path
281
+            if ($path === null) {
282
+                // All locations are default so we just need to rename the directory to the users language
283
+                if ($isDefaultSkeleton && $isDefaultTemplates) {
284
+                    if (!$userFolder->nodeExists('Templates')) {
285
+                        return '';
286
+                    }
287
+                    $newPath = Filesystem::normalizePath($userFolder->getPath() . '/' . $userTemplatePath);
288
+                    if ($newPath !== $userFolder->get('Templates')->getPath()) {
289
+                        $userFolder->get('Templates')->move($newPath);
290
+                    }
291
+                    $this->setTemplatePath($userTemplatePath);
292
+                    return $userTemplatePath;
293
+                }
294
+
295
+                if ($isDefaultSkeleton && !empty($skeletonTemplatePath) && !$isDefaultTemplates && $userFolder->nodeExists('Templates')) {
296
+                    $shippedSkeletonTemplates = $userFolder->get('Templates');
297
+                    $shippedSkeletonTemplates->delete();
298
+                }
299
+            }
300
+
301
+            try {
302
+                $folder = $userFolder->get($userTemplatePath);
303
+            } catch (NotFoundException $e) {
304
+                $folder = $userFolder->get(dirname($userTemplatePath));
305
+                $folder = $folder->newFolder(basename($userTemplatePath));
306
+            }
307
+
308
+            $folderIsEmpty = count($folder->getDirectoryListing()) === 0;
309
+
310
+            if (!$copyTemplates) {
311
+                $this->setTemplatePath($userTemplatePath);
312
+                return $userTemplatePath;
313
+            }
314
+
315
+            if (!$isDefaultTemplates && $folderIsEmpty) {
316
+                $localizedSkeletonTemplatePath = $this->getLocalizedTemplatePath($skeletonTemplatePath, $userLang);
317
+                if (!empty($localizedSkeletonTemplatePath) && file_exists($localizedSkeletonTemplatePath)) {
318
+                    \OC_Util::copyr($localizedSkeletonTemplatePath, $folder);
319
+                    $userFolder->getStorage()->getScanner()->scan($folder->getInternalPath(), Scanner::SCAN_RECURSIVE);
320
+                    $this->setTemplatePath($userTemplatePath);
321
+                    return $userTemplatePath;
322
+                }
323
+            }
324
+
325
+            if ($path !== null && $isDefaultSkeleton && $isDefaultTemplates && $folderIsEmpty) {
326
+                $localizedSkeletonPath = $this->getLocalizedTemplatePath($skeletonPath . '/Templates', $userLang);
327
+                if (!empty($localizedSkeletonPath) && file_exists($localizedSkeletonPath)) {
328
+                    \OC_Util::copyr($localizedSkeletonPath, $folder);
329
+                    $userFolder->getStorage()->getScanner()->scan($folder->getInternalPath(), Scanner::SCAN_RECURSIVE);
330
+                    $this->setTemplatePath($userTemplatePath);
331
+                    return $userTemplatePath;
332
+                }
333
+            }
334
+
335
+            $this->setTemplatePath($path ?? '');
336
+            return $this->getTemplatePath();
337
+        } catch (\Throwable $e) {
338
+            $this->logger->error('Failed to initialize templates directory to user language ' . $userLang . ' for ' . $userId, ['app' => 'files_templates', 'exception' => $e]);
339
+        }
340
+        $this->setTemplatePath('');
341
+        return $this->getTemplatePath();
342
+    }
343
+
344
+    private function getLocalizedTemplatePath(string $skeletonTemplatePath, string $userLang) {
345
+        $localizedSkeletonTemplatePath = str_replace('{lang}', $userLang, $skeletonTemplatePath);
346
+
347
+        if (!file_exists($localizedSkeletonTemplatePath)) {
348
+            $dialectStart = strpos($userLang, '_');
349
+            if ($dialectStart !== false) {
350
+                $localizedSkeletonTemplatePath = str_replace('{lang}', substr($userLang, 0, $dialectStart), $skeletonTemplatePath);
351
+            }
352
+            if ($dialectStart === false || !file_exists($localizedSkeletonTemplatePath)) {
353
+                $localizedSkeletonTemplatePath = str_replace('{lang}', 'default', $skeletonTemplatePath);
354
+            }
355
+        }
356
+
357
+        return $localizedSkeletonTemplatePath;
358
+    }
359 359
 }
Please login to merge, or discard this patch.
lib/private/DirectEditing/Manager.php 1 patch
Indentation   +224 added lines, -224 removed lines patch added patch discarded remove patch
@@ -52,256 +52,256 @@
 block discarded – undo
52 52
 use function in_array;
53 53
 
54 54
 class Manager implements IManager {
55
-	private const TOKEN_CLEANUP_TIME = 12 * 60 * 60 ;
55
+    private const TOKEN_CLEANUP_TIME = 12 * 60 * 60 ;
56 56
 
57
-	public const TABLE_TOKENS = 'direct_edit';
57
+    public const TABLE_TOKENS = 'direct_edit';
58 58
 
59
-	/** @var IEditor[] */
60
-	private $editors = [];
61
-	/** @var IDBConnection */
62
-	private $connection;
63
-	/** @var ISecureRandom */
64
-	private $random;
65
-	/** @var string|null */
66
-	private $userId;
67
-	/** @var IRootFolder */
68
-	private $rootFolder;
69
-	/** @var IL10N */
70
-	private $l10n;
71
-	/** @var EncryptionManager */
72
-	private $encryptionManager;
59
+    /** @var IEditor[] */
60
+    private $editors = [];
61
+    /** @var IDBConnection */
62
+    private $connection;
63
+    /** @var ISecureRandom */
64
+    private $random;
65
+    /** @var string|null */
66
+    private $userId;
67
+    /** @var IRootFolder */
68
+    private $rootFolder;
69
+    /** @var IL10N */
70
+    private $l10n;
71
+    /** @var EncryptionManager */
72
+    private $encryptionManager;
73 73
 
74
-	public function __construct(
75
-		ISecureRandom $random,
76
-		IDBConnection $connection,
77
-		IUserSession $userSession,
78
-		IRootFolder $rootFolder,
79
-		IFactory $l10nFactory,
80
-		EncryptionManager $encryptionManager
81
-	) {
82
-		$this->random = $random;
83
-		$this->connection = $connection;
84
-		$this->userId = $userSession->getUser() ? $userSession->getUser()->getUID() : null;
85
-		$this->rootFolder = $rootFolder;
86
-		$this->l10n = $l10nFactory->get('core');
87
-		$this->encryptionManager = $encryptionManager;
88
-	}
74
+    public function __construct(
75
+        ISecureRandom $random,
76
+        IDBConnection $connection,
77
+        IUserSession $userSession,
78
+        IRootFolder $rootFolder,
79
+        IFactory $l10nFactory,
80
+        EncryptionManager $encryptionManager
81
+    ) {
82
+        $this->random = $random;
83
+        $this->connection = $connection;
84
+        $this->userId = $userSession->getUser() ? $userSession->getUser()->getUID() : null;
85
+        $this->rootFolder = $rootFolder;
86
+        $this->l10n = $l10nFactory->get('core');
87
+        $this->encryptionManager = $encryptionManager;
88
+    }
89 89
 
90
-	public function registerDirectEditor(IEditor $directEditor): void {
91
-		$this->editors[$directEditor->getId()] = $directEditor;
92
-	}
90
+    public function registerDirectEditor(IEditor $directEditor): void {
91
+        $this->editors[$directEditor->getId()] = $directEditor;
92
+    }
93 93
 
94
-	public function getEditors(): array {
95
-		return $this->editors;
96
-	}
94
+    public function getEditors(): array {
95
+        return $this->editors;
96
+    }
97 97
 
98
-	public function getTemplates(string $editor, string $type): array {
99
-		if (!array_key_exists($editor, $this->editors)) {
100
-			throw new \RuntimeException('No matching editor found');
101
-		}
102
-		$templates = [];
103
-		foreach ($this->editors[$editor]->getCreators() as $creator) {
104
-			if ($creator->getId() === $type) {
105
-				$templates = [
106
-					'empty' => [
107
-						'id' => 'empty',
108
-						'title' => $this->l10n->t('Empty file'),
109
-						'preview' => null
110
-					]
111
-				];
98
+    public function getTemplates(string $editor, string $type): array {
99
+        if (!array_key_exists($editor, $this->editors)) {
100
+            throw new \RuntimeException('No matching editor found');
101
+        }
102
+        $templates = [];
103
+        foreach ($this->editors[$editor]->getCreators() as $creator) {
104
+            if ($creator->getId() === $type) {
105
+                $templates = [
106
+                    'empty' => [
107
+                        'id' => 'empty',
108
+                        'title' => $this->l10n->t('Empty file'),
109
+                        'preview' => null
110
+                    ]
111
+                ];
112 112
 
113
-				if ($creator instanceof ACreateFromTemplate) {
114
-					$templates = $creator->getTemplates();
115
-				}
113
+                if ($creator instanceof ACreateFromTemplate) {
114
+                    $templates = $creator->getTemplates();
115
+                }
116 116
 
117
-				$templates = array_map(function ($template) use ($creator) {
118
-					$template['extension'] = $creator->getExtension();
119
-					$template['mimetype'] = $creator->getMimetype();
120
-					return $template;
121
-				}, $templates);
122
-			}
123
-		}
124
-		$return = [];
125
-		$return['templates'] = $templates;
126
-		return $return;
127
-	}
117
+                $templates = array_map(function ($template) use ($creator) {
118
+                    $template['extension'] = $creator->getExtension();
119
+                    $template['mimetype'] = $creator->getMimetype();
120
+                    return $template;
121
+                }, $templates);
122
+            }
123
+        }
124
+        $return = [];
125
+        $return['templates'] = $templates;
126
+        return $return;
127
+    }
128 128
 
129
-	public function create(string $path, string $editorId, string $creatorId, $templateId = null): string {
130
-		$userFolder = $this->rootFolder->getUserFolder($this->userId);
131
-		if ($userFolder->nodeExists($path)) {
132
-			throw new \RuntimeException('File already exists');
133
-		} else {
134
-			if (!$userFolder->nodeExists(dirname($path))) {
135
-				throw new \RuntimeException('Invalid path');
136
-			}
137
-			/** @var Folder $folder */
138
-			$folder = $userFolder->get(dirname($path));
139
-			$file = $folder->newFile(basename($path));
140
-			$editor = $this->getEditor($editorId);
141
-			$creators = $editor->getCreators();
142
-			foreach ($creators as $creator) {
143
-				if ($creator->getId() === $creatorId) {
144
-					$creator->create($file, $creatorId, $templateId);
145
-					return $this->createToken($editorId, $file, $path);
146
-				}
147
-			}
148
-		}
129
+    public function create(string $path, string $editorId, string $creatorId, $templateId = null): string {
130
+        $userFolder = $this->rootFolder->getUserFolder($this->userId);
131
+        if ($userFolder->nodeExists($path)) {
132
+            throw new \RuntimeException('File already exists');
133
+        } else {
134
+            if (!$userFolder->nodeExists(dirname($path))) {
135
+                throw new \RuntimeException('Invalid path');
136
+            }
137
+            /** @var Folder $folder */
138
+            $folder = $userFolder->get(dirname($path));
139
+            $file = $folder->newFile(basename($path));
140
+            $editor = $this->getEditor($editorId);
141
+            $creators = $editor->getCreators();
142
+            foreach ($creators as $creator) {
143
+                if ($creator->getId() === $creatorId) {
144
+                    $creator->create($file, $creatorId, $templateId);
145
+                    return $this->createToken($editorId, $file, $path);
146
+                }
147
+            }
148
+        }
149 149
 
150
-		throw new \RuntimeException('No creator found');
151
-	}
150
+        throw new \RuntimeException('No creator found');
151
+    }
152 152
 
153
-	public function open(string $filePath, string $editorId = null): string {
154
-		/** @var File $file */
155
-		$file = $this->rootFolder->getUserFolder($this->userId)->get($filePath);
153
+    public function open(string $filePath, string $editorId = null): string {
154
+        /** @var File $file */
155
+        $file = $this->rootFolder->getUserFolder($this->userId)->get($filePath);
156 156
 
157
-		if ($editorId === null) {
158
-			$editorId = $this->findEditorForFile($file);
159
-		}
160
-		if (!array_key_exists($editorId, $this->editors)) {
161
-			throw new \RuntimeException("Editor $editorId is unknown");
162
-		}
157
+        if ($editorId === null) {
158
+            $editorId = $this->findEditorForFile($file);
159
+        }
160
+        if (!array_key_exists($editorId, $this->editors)) {
161
+            throw new \RuntimeException("Editor $editorId is unknown");
162
+        }
163 163
 
164
-		return $this->createToken($editorId, $file, $filePath);
165
-	}
164
+        return $this->createToken($editorId, $file, $filePath);
165
+    }
166 166
 
167
-	private function findEditorForFile(File $file) {
168
-		foreach ($this->editors as $editor) {
169
-			if (in_array($file->getMimeType(), $editor->getMimetypes())) {
170
-				return $editor->getId();
171
-			}
172
-		}
173
-		throw new \RuntimeException('No default editor found for files mimetype');
174
-	}
167
+    private function findEditorForFile(File $file) {
168
+        foreach ($this->editors as $editor) {
169
+            if (in_array($file->getMimeType(), $editor->getMimetypes())) {
170
+                return $editor->getId();
171
+            }
172
+        }
173
+        throw new \RuntimeException('No default editor found for files mimetype');
174
+    }
175 175
 
176
-	public function edit(string $token): Response {
177
-		try {
178
-			/** @var IEditor $editor */
179
-			$tokenObject = $this->getToken($token);
180
-			if ($tokenObject->hasBeenAccessed()) {
181
-				throw new \RuntimeException('Token has already been used and can only be used for followup requests');
182
-			}
183
-			$editor = $this->getEditor($tokenObject->getEditor());
184
-			$this->accessToken($token);
185
-		} catch (Throwable $throwable) {
186
-			$this->invalidateToken($token);
187
-			return new NotFoundResponse();
188
-		}
189
-		return $editor->open($tokenObject);
190
-	}
176
+    public function edit(string $token): Response {
177
+        try {
178
+            /** @var IEditor $editor */
179
+            $tokenObject = $this->getToken($token);
180
+            if ($tokenObject->hasBeenAccessed()) {
181
+                throw new \RuntimeException('Token has already been used and can only be used for followup requests');
182
+            }
183
+            $editor = $this->getEditor($tokenObject->getEditor());
184
+            $this->accessToken($token);
185
+        } catch (Throwable $throwable) {
186
+            $this->invalidateToken($token);
187
+            return new NotFoundResponse();
188
+        }
189
+        return $editor->open($tokenObject);
190
+    }
191 191
 
192
-	public function editSecure(File $file, string $editorId): TemplateResponse {
193
-		// TODO: Implementation in follow up
194
-	}
192
+    public function editSecure(File $file, string $editorId): TemplateResponse {
193
+        // TODO: Implementation in follow up
194
+    }
195 195
 
196
-	private function getEditor($editorId): IEditor {
197
-		if (!array_key_exists($editorId, $this->editors)) {
198
-			throw new \RuntimeException('No editor found');
199
-		}
200
-		return $this->editors[$editorId];
201
-	}
196
+    private function getEditor($editorId): IEditor {
197
+        if (!array_key_exists($editorId, $this->editors)) {
198
+            throw new \RuntimeException('No editor found');
199
+        }
200
+        return $this->editors[$editorId];
201
+    }
202 202
 
203
-	public function getToken(string $token): IToken {
204
-		$query = $this->connection->getQueryBuilder();
205
-		$query->select('*')->from(self::TABLE_TOKENS)
206
-			->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR)));
207
-		$result = $query->execute();
208
-		if ($tokenRow = $result->fetch(FetchMode::ASSOCIATIVE)) {
209
-			return new Token($this, $tokenRow);
210
-		}
211
-		throw new \RuntimeException('Failed to validate the token');
212
-	}
203
+    public function getToken(string $token): IToken {
204
+        $query = $this->connection->getQueryBuilder();
205
+        $query->select('*')->from(self::TABLE_TOKENS)
206
+            ->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR)));
207
+        $result = $query->execute();
208
+        if ($tokenRow = $result->fetch(FetchMode::ASSOCIATIVE)) {
209
+            return new Token($this, $tokenRow);
210
+        }
211
+        throw new \RuntimeException('Failed to validate the token');
212
+    }
213 213
 
214
-	public function cleanup(): int {
215
-		$query = $this->connection->getQueryBuilder();
216
-		$query->delete(self::TABLE_TOKENS)
217
-			->where($query->expr()->lt('timestamp', $query->createNamedParameter(time() - self::TOKEN_CLEANUP_TIME)));
218
-		return $query->execute();
219
-	}
214
+    public function cleanup(): int {
215
+        $query = $this->connection->getQueryBuilder();
216
+        $query->delete(self::TABLE_TOKENS)
217
+            ->where($query->expr()->lt('timestamp', $query->createNamedParameter(time() - self::TOKEN_CLEANUP_TIME)));
218
+        return $query->execute();
219
+    }
220 220
 
221
-	public function refreshToken(string $token): bool {
222
-		$query = $this->connection->getQueryBuilder();
223
-		$query->update(self::TABLE_TOKENS)
224
-			->set('timestamp', $query->createNamedParameter(time(), IQueryBuilder::PARAM_INT))
225
-			->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR)));
226
-		$result = $query->execute();
227
-		return $result !== 0;
228
-	}
221
+    public function refreshToken(string $token): bool {
222
+        $query = $this->connection->getQueryBuilder();
223
+        $query->update(self::TABLE_TOKENS)
224
+            ->set('timestamp', $query->createNamedParameter(time(), IQueryBuilder::PARAM_INT))
225
+            ->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR)));
226
+        $result = $query->execute();
227
+        return $result !== 0;
228
+    }
229 229
 
230 230
 
231
-	public function invalidateToken(string $token): bool {
232
-		$query = $this->connection->getQueryBuilder();
233
-		$query->delete(self::TABLE_TOKENS)
234
-			->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR)));
235
-		$result = $query->execute();
236
-		return $result !== 0;
237
-	}
231
+    public function invalidateToken(string $token): bool {
232
+        $query = $this->connection->getQueryBuilder();
233
+        $query->delete(self::TABLE_TOKENS)
234
+            ->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR)));
235
+        $result = $query->execute();
236
+        return $result !== 0;
237
+    }
238 238
 
239
-	public function accessToken(string $token): bool {
240
-		$query = $this->connection->getQueryBuilder();
241
-		$query->update(self::TABLE_TOKENS)
242
-			->set('accessed', $query->createNamedParameter(true, IQueryBuilder::PARAM_BOOL))
243
-			->set('timestamp', $query->createNamedParameter(time(), IQueryBuilder::PARAM_INT))
244
-			->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR)));
245
-		$result = $query->execute();
246
-		return $result !== 0;
247
-	}
239
+    public function accessToken(string $token): bool {
240
+        $query = $this->connection->getQueryBuilder();
241
+        $query->update(self::TABLE_TOKENS)
242
+            ->set('accessed', $query->createNamedParameter(true, IQueryBuilder::PARAM_BOOL))
243
+            ->set('timestamp', $query->createNamedParameter(time(), IQueryBuilder::PARAM_INT))
244
+            ->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR)));
245
+        $result = $query->execute();
246
+        return $result !== 0;
247
+    }
248 248
 
249
-	public function invokeTokenScope($userId): void {
250
-		\OC_User::setIncognitoMode(true);
251
-		\OC_User::setUserId($userId);
252
-	}
249
+    public function invokeTokenScope($userId): void {
250
+        \OC_User::setIncognitoMode(true);
251
+        \OC_User::setUserId($userId);
252
+    }
253 253
 
254
-	public function createToken($editorId, File $file, string $filePath, IShare $share = null): string {
255
-		$token = $this->random->generate(64, ISecureRandom::CHAR_HUMAN_READABLE);
256
-		$query = $this->connection->getQueryBuilder();
257
-		$query->insert(self::TABLE_TOKENS)
258
-			->values([
259
-				'token' => $query->createNamedParameter($token),
260
-				'editor_id' => $query->createNamedParameter($editorId),
261
-				'file_id' => $query->createNamedParameter($file->getId()),
262
-				'file_path' => $query->createNamedParameter($filePath),
263
-				'user_id' => $query->createNamedParameter($this->userId),
264
-				'share_id' => $query->createNamedParameter($share !== null ? $share->getId(): null),
265
-				'timestamp' => $query->createNamedParameter(time())
266
-			]);
267
-		$query->execute();
268
-		return $token;
269
-	}
254
+    public function createToken($editorId, File $file, string $filePath, IShare $share = null): string {
255
+        $token = $this->random->generate(64, ISecureRandom::CHAR_HUMAN_READABLE);
256
+        $query = $this->connection->getQueryBuilder();
257
+        $query->insert(self::TABLE_TOKENS)
258
+            ->values([
259
+                'token' => $query->createNamedParameter($token),
260
+                'editor_id' => $query->createNamedParameter($editorId),
261
+                'file_id' => $query->createNamedParameter($file->getId()),
262
+                'file_path' => $query->createNamedParameter($filePath),
263
+                'user_id' => $query->createNamedParameter($this->userId),
264
+                'share_id' => $query->createNamedParameter($share !== null ? $share->getId(): null),
265
+                'timestamp' => $query->createNamedParameter(time())
266
+            ]);
267
+        $query->execute();
268
+        return $token;
269
+    }
270 270
 
271
-	/**
272
-	 * @param $userId
273
-	 * @param $fileId
274
-	 * @param null $filePath
275
-	 * @return Node
276
-	 * @throws NotFoundException
277
-	 */
278
-	public function getFileForToken($userId, $fileId, $filePath = null): Node {
279
-		$userFolder = $this->rootFolder->getUserFolder($userId);
280
-		if ($filePath !== null) {
281
-			return $userFolder->get($filePath);
282
-		}
283
-		$files = $userFolder->getById($fileId);
284
-		if (count($files) === 0) {
285
-			throw new NotFoundException('File nound found by id ' . $fileId);
286
-		}
287
-		return $files[0];
288
-	}
271
+    /**
272
+     * @param $userId
273
+     * @param $fileId
274
+     * @param null $filePath
275
+     * @return Node
276
+     * @throws NotFoundException
277
+     */
278
+    public function getFileForToken($userId, $fileId, $filePath = null): Node {
279
+        $userFolder = $this->rootFolder->getUserFolder($userId);
280
+        if ($filePath !== null) {
281
+            return $userFolder->get($filePath);
282
+        }
283
+        $files = $userFolder->getById($fileId);
284
+        if (count($files) === 0) {
285
+            throw new NotFoundException('File nound found by id ' . $fileId);
286
+        }
287
+        return $files[0];
288
+    }
289 289
 
290
-	public function isEnabled(): bool {
291
-		if (!$this->encryptionManager->isEnabled()) {
292
-			return true;
293
-		}
290
+    public function isEnabled(): bool {
291
+        if (!$this->encryptionManager->isEnabled()) {
292
+            return true;
293
+        }
294 294
 
295
-		try {
296
-			$moduleId = $this->encryptionManager->getDefaultEncryptionModuleId();
297
-			$module = $this->encryptionManager->getEncryptionModule($moduleId);
298
-			/** @var \OCA\Encryption\Util $util */
299
-			$util = \OC::$server->get(\OCA\Encryption\Util::class);
300
-			if ($module->isReadyForUser($this->userId) && $util->isMasterKeyEnabled()) {
301
-				return true;
302
-			}
303
-		} catch (Throwable $e) {
304
-		}
305
-		return false;
306
-	}
295
+        try {
296
+            $moduleId = $this->encryptionManager->getDefaultEncryptionModuleId();
297
+            $module = $this->encryptionManager->getEncryptionModule($moduleId);
298
+            /** @var \OCA\Encryption\Util $util */
299
+            $util = \OC::$server->get(\OCA\Encryption\Util::class);
300
+            if ($module->isReadyForUser($this->userId) && $util->isMasterKeyEnabled()) {
301
+                return true;
302
+            }
303
+        } catch (Throwable $e) {
304
+        }
305
+        return false;
306
+    }
307 307
 }
Please login to merge, or discard this patch.