Skip to content

Commit

Permalink
Add templatedirectory config value to let admins have their custom te…
Browse files Browse the repository at this point in the history
…mplates by default

Signed-off-by: Julius Härtl <jus@bitgrid.net>
  • Loading branch information
juliusknorr committed Jan 20, 2021
1 parent 3bc7fbe commit 2c5a216
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 16 deletions.
15 changes: 15 additions & 0 deletions config/config.sample.php
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,21 @@
*/
'skeletondirectory' => '/path/to/nextcloud/core/skeleton',


/**
* The directory where the template files are located. These files will be
* copied to the template directory of new users. Leave empty to not copy any
* template files.
* ``{lang}`` can be used as a placeholder for the language of the user.
* If the directory does not exist, it falls back to non dialect (from ``de_DE``
* to ``de``). If that does not exist either, it falls back to ``default``
*
* If this is not set creating a template directory will only happen if no custom
* ``skeletondirectory`` is defined, otherwise the shipped templates will be used
* to create a template directory for the user.
*/
'templatesdirectory' => '/path/to/nextcloud/templates',

/**
* If your user backend does not allow password resets (e.g. when it's a
* read-only user backend like LDAP), you can specify a custom link, where the
Expand Down
73 changes: 64 additions & 9 deletions lib/private/Files/Template/TemplateManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

namespace OC\Files\Template;

use OC\Files\Cache\Scanner;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Folder;
use OCP\Files\File;
Expand Down Expand Up @@ -59,6 +60,7 @@ class TemplateManager implements ITemplateManager {
private $l10n;
private $logger;
private $userId;
private $l10nFactory;

public function __construct(
IServerContainer $serverContainer,
Expand All @@ -67,15 +69,16 @@ public function __construct(
IUserSession $userSession,
IPreview $previewManager,
IConfig $config,
IFactory $l10n,
IFactory $l10nFactory,
LoggerInterface $logger
) {
$this->serverContainer = $serverContainer;
$this->eventDispatcher = $eventDispatcher;
$this->rootFolder = $rootFolder;
$this->previewManager = $previewManager;
$this->config = $config;
$this->l10n = $l10n->get('lib');
$this->l10nFactory = $l10nFactory;
$this->l10n = $l10nFactory->get('lib');
$this->logger = $logger;
$user = $userSession->getUser();
$this->userId = $user ? $user->getUID() : null;
Expand Down Expand Up @@ -224,14 +227,66 @@ public function initializeTemplateDirectory(string $path = null, string $userId
if ($userId !== null) {
$this->userId = $userId;
}
$userFolder = $this->rootFolder->getUserFolder($this->userId);
$templateDirectoryPath = $path ?? $this->l10n->t('Templates') . '/';

$defaultSkeletonDirectory = \OC::$SERVERROOT . '/core/skeleton';
$defaultTemplateDirectory = \OC::$SERVERROOT . '/core/skeleton/Templates';
$skeletonPath = $this->config->getSystemValue('skeletondirectory', $defaultSkeletonDirectory);
$skeletonTemplatePath = $this->config->getSystemValue('templatedirectory', $defaultTemplateDirectory);
$userLang = $this->l10nFactory->getUserLanguage();

try {
$userFolder->get($templateDirectoryPath);
} catch (NotFoundException $e) {
$folder = $userFolder->newFolder($templateDirectoryPath);
$folder->newFile('Testtemplate.txt');
$l10n = $this->l10nFactory->get('lib', $userLang);
$userFolder = $this->rootFolder->getUserFolder($this->userId);
$userTemplatePath = $path ?? $l10n->t('Templates') . '/';

// All locations are default so we just need to rename the directory to the users language
if ($skeletonPath === $defaultSkeletonDirectory && $skeletonTemplatePath === $defaultTemplateDirectory && $userFolder->nodeExists('Templates')) {
$newPath = $userFolder->getPath() . '/' . $userTemplatePath;
if ($newPath !== $userFolder->get('Templates')->getPath()) {
$userFolder->get('Templates')->move($newPath);
}
$this->setTemplatePath($userTemplatePath);
return;
}

// A custom template directory is specified
if (!empty($skeletonTemplatePath) && $skeletonTemplatePath !== $defaultTemplateDirectory) {
// In case the shipped template files are in place we remove them
if ($skeletonPath === $defaultSkeletonDirectory && $userFolder->nodeExists('Templates')) {
$shippedSkeletonTemplates = $userFolder->get('Templates');
$shippedSkeletonTemplates->delete();
}
try {
$userFolder->get($userTemplatePath);
} catch (NotFoundException $e) {
$folder = $userFolder->newFolder($userTemplatePath);

$localizedSkeletonTemplatePath = $this->getLocalizedTemplatePath($skeletonTemplatePath, $userLang);
if (!empty($localizedSkeletonTemplatePath) && file_exists($localizedSkeletonTemplatePath)) {
\OC_Util::copyr($localizedSkeletonTemplatePath, $folder);
$userFolder->getStorage()->getScanner()->scan($userTemplatePath, Scanner::SCAN_RECURSIVE);
}
}
$this->setTemplatePath($userTemplatePath);
}
} catch (\Throwable $e) {
$this->logger->error('Failed to rename templates directory to user language ' . $userLang . ' for ' . $userId, ['app' => 'files_templates']);
}
$this->setTemplatePath($templateDirectoryPath);
}

private function getLocalizedTemplatePath(string $skeletonTemplatePath, string $userLang) {
$localizedSkeletonTemplatePath = str_replace('{lang}', $userLang, $skeletonTemplatePath);

if (!file_exists($localizedSkeletonTemplatePath)) {
$dialectStart = strpos($userLang, '_');
if ($dialectStart !== false) {
$localizedSkeletonTemplatePath = str_replace('{lang}', substr($userLang, 0, $dialectStart), $skeletonTemplatePath);
}
if ($dialectStart === false || !file_exists($localizedSkeletonTemplatePath)) {
$localizedSkeletonTemplatePath = str_replace('{lang}', 'default', $skeletonTemplatePath);
}
}

return $localizedSkeletonTemplatePath;
}
}
12 changes: 7 additions & 5 deletions lib/private/legacy/OC_Util.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
use OCP\ILogger;
use OCP\IUser;
use OCP\IUserSession;
use Psr\Log\LoggerInterface;

class OC_Util {
public static $scripts = [];
Expand Down Expand Up @@ -412,6 +413,9 @@ public static function getUserQuota(?IUser $user) {
* @suppress PhanDeprecatedFunction
*/
public static function copySkeleton($userId, \OCP\Files\Folder $userDirectory) {
/** @var LoggerInterface $logger */
$logger = \OC::$server->get(LoggerInterface::class);

$plainSkeletonDirectory = \OC::$server->getConfig()->getSystemValue('skeletondirectory', \OC::$SERVERROOT . '/core/skeleton');
$userLang = \OC::$server->getL10NFactory()->findLanguage();
$skeletonDirectory = str_replace('{lang}', $userLang, $plainSkeletonDirectory);
Expand Down Expand Up @@ -440,14 +444,12 @@ public static function copySkeleton($userId, \OCP\Files\Folder $userDirectory) {
}

if (!empty($skeletonDirectory)) {
\OCP\Util::writeLog(
'files_skeleton',
'copying skeleton for '.$userId.' from '.$skeletonDirectory.' to '.$userDirectory->getFullPath('/'),
ILogger::DEBUG
);
$logger->debug('copying skeleton for '.$userId.' from '.$skeletonDirectory.' to '.$userDirectory->getFullPath('/'), ['app' => 'files_skeleton']);
self::copyr($skeletonDirectory, $userDirectory);
// update the file cache
$userDirectory->getStorage()->getScanner()->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE);

/** @var ITemplateManager $templateManaer */
$templateManaer = \OC::$server->get(ITemplateManager::class);
$templateManaer->initializeTemplateDirectory(null, $userId);
}
Expand Down
5 changes: 3 additions & 2 deletions lib/public/Files/Template/ITemplateManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,11 @@ public function setTemplatePath(string $path): void;
public function getTemplatePath(): string;

/**
* @param string $path
* @param string|null $path
* @param string|null $userId
* @since 21.0.0
*/
public function initializeTemplateDirectory(string $path): void;
public function initializeTemplateDirectory(string $path = null, string $userId = null): void;

/**
* @param string $filePath
Expand Down

0 comments on commit 2c5a216

Please sign in to comment.