diff --git a/appinfo/info.xml b/appinfo/info.xml index aa258af..7d582c8 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -7,11 +7,11 @@ While it is possible to manually change email templates within ownCloud, this ap AGPL Jörn Dreyer - 0.1 + 0.2 + TemplateEditor - + - true OCA\TemplateEditor\AdminPanel diff --git a/appinfo/routes.php b/appinfo/routes.php index e666e73..85ad0aa 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -1,10 +1,10 @@ + * @author Jörn Dreyer + * @copyright Copyright (c) 2017, ownCloud GmbH + * @license AGPL-3.0 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -21,15 +21,10 @@ * */ -$app = new \OCA\TemplateEditor\App\TemplateEditor(); - -$app->registerRoutes($this, array('routes' => array( - - // mailTemplate settings - array('name' => 'admin_settings#renderTemplate', 'url' => '/settings/mailtemplate', 'verb' => 'GET'), - - array('name' => 'admin_settings#updateTemplate', 'url' => '/settings/mailtemplate', 'verb' => 'POST'), - - array('name' => 'admin_settings#resetTemplate', 'url' => '/settings/mailtemplate', 'verb' => 'DELETE') - -))); +return [ + 'routes' => [ + ['name' => 'adminSettings#renderTemplate', 'url' => '/settings/mailtemplate', 'verb' => 'GET'], + ['name' => 'adminSettings#updateTemplate', 'url' => '/settings/mailtemplate', 'verb' => 'POST'], + ['name' => 'adminSettings#resetTemplate', 'url' => '/settings/mailtemplate', 'verb' => 'DELETE'], + ] +]; diff --git a/js/settings-admin.js b/js/settings-admin.js index 32e8c5d..70736b9 100644 --- a/js/settings-admin.js +++ b/js/settings-admin.js @@ -9,7 +9,7 @@ $(document).ready(function() { $( '#mailTemplateSettings .templateEditor + .actions:hidden').show(400); $.get( OC.generateUrl('apps/templateeditor/settings/mailtemplate'), - { theme: theme, template: template } + { themeName: theme, template: template } ).done(function( result ) { $( '#mailTemplateSettings textarea' ).val(result); }).fail(function( result ) { diff --git a/lib/AdminPanel.php b/lib/AdminPanel.php new file mode 100644 index 0000000..c8ea95b --- /dev/null +++ b/lib/AdminPanel.php @@ -0,0 +1,66 @@ + + * @copyright Copyright (c) 2017, ownCloud GmbH + * @license AGPL-3.0 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see . + * + */ + +namespace OCA\TemplateEditor; + +use OCP\Settings\ISettings; +use OCP\Template; + +class AdminPanel implements ISettings { + + /** + * @var TemplateEditor + */ + private $templateEditor; + + /** + * @param TemplateEditor $templateEditor + */ + public function __construct(TemplateEditor $templateEditor) { + $this->templateEditor = $templateEditor; + } + + /** + * @return Template + */ + public function getPanel() { + $template = new Template('templateeditor', 'settings-admin'); + $template->assign('themeNames', $this->templateEditor->getAllThemeNames()); + $template->assign('editableTemplates', $this->templateEditor->getEditableTemplates()); + return $template; + } + + /** + * @return string + */ + public function getSectionID() { + return 'general'; + } + + /** + * @return int + */ + public function getPriority() { + return 5; + } +} diff --git a/app/templateeditor.php b/lib/AppInfo/Application.php similarity index 61% rename from app/templateeditor.php rename to lib/AppInfo/Application.php index 89ca7f3..d7c2fe1 100644 --- a/app/templateeditor.php +++ b/lib/AppInfo/Application.php @@ -1,10 +1,10 @@ + * @author Jörn Dreyer + * @copyright Copyright (c) 2017, ownCloud GmbH + * @license AGPL-3.0 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -21,25 +21,32 @@ * */ -namespace OCA\TemplateEditor\App; +namespace OCA\TemplateEditor\AppInfo; -use OCP\AppFramework\App; use OCA\TemplateEditor\Controller\AdminSettingsController; +use OCA\TemplateEditor\TemplateEditor; +use OCP\AppFramework\App; +use OCP\AppFramework\IAppContainer; -class TemplateEditor extends App { +class Application extends App { - public function __construct(array $urlParams=array()){ + /** + * @param array $urlParams + */ + public function __construct(array $urlParams = []) { parent::__construct('templateeditor', $urlParams); $container = $this->getContainer(); - /** - * Controllers - */ - $container->registerService('AdminSettingsController', function($c) { + $container->registerService('TemplateEditor', function (IAppContainer $container) { + return new TemplateEditor($container->query('ThemeService')); + }); + + $container->registerService('AdminSettingsController', function(IAppContainer $container) { return new AdminSettingsController( - $c->query('AppName'), - $c->query('Request') + $container->query('AppName'), + $container->query('Request'), + $container->query('TemplateEditor') ); }); } diff --git a/controller/adminsettingscontroller.php b/lib/Controller/AdminSettingsController.php similarity index 59% rename from controller/adminsettingscontroller.php rename to lib/Controller/AdminSettingsController.php index b6a2214..bc724ef 100644 --- a/controller/adminsettingscontroller.php +++ b/lib/Controller/AdminSettingsController.php @@ -1,10 +1,10 @@ + * @author Jörn Dreyer + * @copyright Copyright (c) 2017, ownCloud GmbH + * @license AGPL-3.0 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -23,30 +23,41 @@ namespace OCA\TemplateEditor\Controller; -use OC\Theme\ThemeService; +use OCA\TemplateEditor\TemplateEditor; use OCP\AppFramework\ApiController; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; -use OCA\TemplateEditor\MailTemplate; class AdminSettingsController extends ApiController { - public function __construct($appName, IRequest $request) { + /** + * @var TemplateEditor + */ + private $templateEditor; + + /** + * @param string $appName + * @param IRequest $request + * @param TemplateEditor $templateEditor + */ + public function __construct($appName, IRequest $request, TemplateEditor $templateEditor) { parent::__construct($appName, $request); + + $this->templateEditor = $templateEditor; } /** - * @param string $theme + * @param string $themeName * @param string $template * @return \OCP\AppFramework\Http\Response */ - public function renderTemplate( $theme, $template ) { + public function renderTemplate($themeName, $template) { try { - $template = $this->getMailTemplate($theme, $template); + $template = $this->templateEditor->getMailTemplate($themeName, $template); return $template->getResponse(); } catch (\Exception $ex) { - return new JSONResponse(array('message' => $ex->getMessage()), $ex->getCode()); + return new JSONResponse(['message' => $ex->getMessage()], $ex->getCode()); } } @@ -56,13 +67,13 @@ public function renderTemplate( $theme, $template ) { * @param string $content * @return JSONResponse */ - public function updateTemplate( $theme, $template, $content ) { + public function updateTemplate($theme, $template, $content) { try { - $template = $this->getMailTemplate($theme, $template); - $template->setContent( $content ); + $template = $this->templateEditor->getMailTemplate($theme, $template); + $template->setContent($content); return new JSONResponse(); } catch (\Exception $ex) { - return new JSONResponse(array('message' => $ex->getMessage()), $ex->getCode()); + return new JSONResponse(['message' => $ex->getMessage()], $ex->getCode()); } } @@ -71,30 +82,16 @@ public function updateTemplate( $theme, $template, $content ) { * @param string $template * @return JSONResponse */ - public function resetTemplate( $theme, $template ) { + public function resetTemplate($theme, $template) { try { - $template = $this->getMailTemplate($theme, $template); + $template = $this->templateEditor->getMailTemplate($theme, $template); if ($template->reset()) { return new JSONResponse(); } else { return new JSONResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); } } catch (\Exception $ex) { - return new JSONResponse(array('message' => $ex->getMessage()), $ex->getCode()); + return new JSONResponse(['message' => $ex->getMessage()], $ex->getCode()); } } - - /** - * @param string $themeName - * @param string $template - * @return MailTemplate - */ - protected function getMailTemplate($themeName, $template){ - $themeService = new ThemeService($themeName); - return new MailTemplate( - $themeService->getTheme(), - $template - ); - } - } diff --git a/http/mailtemplateresponse.php b/lib/Http/MailTemplateResponse.php similarity index 93% rename from http/mailtemplateresponse.php rename to lib/Http/MailTemplateResponse.php index 16d4f98..fb389bf 100644 --- a/http/mailtemplateresponse.php +++ b/lib/Http/MailTemplateResponse.php @@ -3,8 +3,9 @@ /** * ownCloud - Template Editor * - * @author Jörn Dreyer - * @copyright 2014 Jörn Dreyer + * @author Jörn Dreyer + * @copyright Copyright (c) 2017, ownCloud GmbH + * @license AGPL-3.0 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -53,5 +54,4 @@ public function __construct($filename, $contentType = 'text/php') { public function render(){ return file_get_contents($this->filename); } - } diff --git a/lib/MailTemplate.php b/lib/MailTemplate.php new file mode 100644 index 0000000..e3bfe08 --- /dev/null +++ b/lib/MailTemplate.php @@ -0,0 +1,107 @@ + + * @copyright Copyright (c) 2017, ownCloud GmbH + * @license AGPL-3.0 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see . + * + */ + +namespace OCA\TemplateEditor; + +use OCP\Theme\ITheme; +use OCA\TemplateEditor\Http\MailTemplateResponse; + +class MailTemplate extends \OC_Template { + + /** @var string */ + private $path; + + /** + * @param ITheme $theme + * @param string $path + */ + public function __construct(ITheme $theme, $path) { + $this->theme = $theme; + $this->path = $path; + } + + /** + * @return \OCA\TemplateEditor\Http\MailTemplateResponse + */ + public function getResponse() { + $template = $this->getTemplateDetails(); + return new MailTemplateResponse($template); + } + + /** + * @return string + */ + protected function getTemplateDetails() { + list($app, $filename) = explode('/templates/', $this->path, 2); + $name = substr($filename, 0, -4); + $template = $this->findTemplate($this->theme, $app, $name); + return $template; + } + + /** + * @param string $content + * @return int|false + * @throws \Exception + */ + public function setContent($content) { + $absolutePath = $this->getAbsoluteTemplatePath(); + + // TODO: check what the minimum permissions are. + if (!is_dir(dirname($absolutePath)) ) { + if (!mkdir(dirname($absolutePath), 0777, true)){ + throw new \Exception('Could not create directory.', 500); + } + } + if (is_file($absolutePath) ) { + if (!copy($absolutePath, $absolutePath.'.bak')){ + throw new \Exception('Could not create template backup.', 500); + } + } + + return file_put_contents($absolutePath, $content); + } + + /** + * @return bool + */ + public function reset() { + $absolutePath = $this->getAbsoluteTemplatePath(); + + if (is_file($absolutePath . '.bak')) { + if (rename($absolutePath . '.bak', $absolutePath)) { + return true; + } + } else if (unlink($absolutePath)) { + return true; + } + + return !file_exists($absolutePath); + } + + /** + * @return string + */ + protected function getAbsoluteTemplatePath() { + return \OC::$SERVERROOT . '/' . $this->theme->getDirectory() . '/' . $this->path; + } +} diff --git a/lib/TemplateEditor.php b/lib/TemplateEditor.php new file mode 100644 index 0000000..85e6b1c --- /dev/null +++ b/lib/TemplateEditor.php @@ -0,0 +1,95 @@ + + * + * @copyright Copyright (c) 2017, ownCloud GmbH + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ +namespace OCA\TemplateEditor; + +use OCP\App; +use OCP\Theme\IThemeService; + +class TemplateEditor { + + /** + * @var IThemeService + */ + private $themeService; + + /** + * TemplateEditor constructor. + * + * @param IThemeService $themeService + */ + public function __construct(IThemeService $themeService) { + $this->themeService = $themeService; + } + + /** + * @return string[] + */ + public function getAllThemeNames() { + $themes = $this->themeService->getAllThemes(); + + $themeNames = []; + foreach ($themes as $theme) { + $themeName = $theme->getName(); + if (is_array(App::getAppInfo($themeName)) && !App::isEnabled($themeName)) { + continue; + } + $themeNames[] = $themeName; + } + return $themeNames; + } + + /** + * @return array + */ + public function getEditableTemplates() { + $l10n = \OC::$server->getL10NFactory()->get('templateeditor'); + $templates = [ + 'core/templates/mail.php' => $l10n->t('Sharing email - public link shares (HTML)'), + 'core/templates/altmail.php' => $l10n->t('Sharing email - public link shares (plain text fallback)'), + 'core/templates/internalmail.php' => $l10n->t('Sharing email (HTML)'), + 'core/templates/internalaltmail.php' => $l10n->t('Sharing email (plain text fallback)'), + 'core/templates/lostpassword/email.php' => $l10n->t('Lost password mail'), + 'settings/templates/email.new_user.php' => $l10n->t('New user email (HTML)'), + 'settings/templates/email.new_user_plain_text.php' => $l10n->t('New user email (plain text fallback)'), + ]; + + if (App::isEnabled('activity')) { + $tmplPath = \OC_App::getAppPath('activity') . '/templates/email.notification.php'; + $path = substr($tmplPath, strlen(\OC::$SERVERROOT) + 1); + $templates[$path] = $l10n->t('Activity notification mail'); + } + + return $templates; + } + + /** + * @param string $themeName + * @param string $template + * @return MailTemplate + */ + public function getMailTemplate($themeName, $template) { + return new MailTemplate( + $this->themeService->findTheme($themeName), + $template + ); + } + +} \ No newline at end of file diff --git a/lib/adminpanel.php b/lib/adminpanel.php deleted file mode 100644 index 11d3693..0000000 --- a/lib/adminpanel.php +++ /dev/null @@ -1,28 +0,0 @@ -assign('themes', $themes); - $tmpl->assign('editableTemplates', $editableTemplates); - return $tmpl; - } - - public function getPriority() { - return 5; - } - - -} \ No newline at end of file diff --git a/lib/mailtemplate.php b/lib/mailtemplate.php deleted file mode 100644 index 4366554..0000000 --- a/lib/mailtemplate.php +++ /dev/null @@ -1,195 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see . - * - */ - -namespace OCA\TemplateEditor; - -use OCP\App; -use OCP\Files\NotPermittedException; -use OC\AppFramework\Middleware\Security\Exceptions\SecurityException; -use OCA\TemplateEditor\Http\MailTemplateResponse; -use OC\Theme\Theme; - -class MailTemplate extends \OC_Template { - - /** @var array */ - private $editableThemes; - - /** @var array */ - private $editableTemplates; - - /** @var string */ - private $path; - - /** - * @param Theme $theme - * @param string $path - */ - public function __construct($theme, $path) { - $this->theme = $theme; - $this->path = $path; - - //determine valid theme names - $this->editableThemes = self::getEditableThemes(); - //for now hard code the valid mail template paths - $this->editableTemplates = self::getEditableTemplates(); - } - - /** - * @return \OCA\TemplateEditor\Http\MailTemplateResponse - * @throws SecurityException - */ - public function getResponse() { - if(!$this->isEditable()) { - throw new SecurityException('Template not editable.', 403); - } - $template = $this->getTemplateDetails(); - return new MailTemplateResponse($template); - } - - public function renderContent() { - if(!$this->isEditable()) { - throw new SecurityException('Template not editable.', 403); - } - $template = $this->getTemplateDetails(); - \OC_Response::sendFile($template); - } - - protected function getTemplateDetails(){ - list($app, $filename) = explode('/templates/', $this->path, 2); - $name = substr($filename, 0, -4); - $template = $this->findTemplate($this->theme, $app, $name); - return $template; - } - - /** - * @return string - */ - protected function getAbsoluteTemplatePath(){ - return \OC::$SERVERROOT . '/' . $this->theme->getDirectory() . $this->path; - } - - public function isEditable() { - $themeName = $this->theme->getName(); - if (isset($this->editableThemes[$themeName]) - && isset($this->editableTemplates[$this->path]) - ) { - return true; - } - return false; - } - - public function setContent($data) { - if($this->isEditable()) { - //save default templates in default folder to overwrite core template - $absolutePath = $this->getAbsoluteTemplatePath(); - $parent = dirname($absolutePath); - if ( ! is_dir($parent) ) { - if ( ! mkdir(dirname($absolutePath), 0777, true) ){ - throw new \Exception('Could not create directory.', 500); - } - } - if ( $this->theme->getName() !== 'default' && is_file($absolutePath) ) { - if ( ! copy($absolutePath, $absolutePath.'.bak') ){ - throw new \Exception('Could not overwrite template.', 500); - } - } - //overwrite theme templates? use versions? - return file_put_contents($absolutePath, $data); - } - throw new SecurityException('Template not editable.', 403); - } - - public function reset(){ - if($this->isEditable()) { - $absolutePath = $this->getAbsoluteTemplatePath(); - if ($this->theme->getName() === 'default') { - //templates can simply be deleted in the themes folder - if (unlink($absolutePath)) { - return true; - } - } else { - //if a bak file exists overwrite the template with it - if (is_file($absolutePath.'.bak')) { - if (rename($absolutePath.'.bak', $absolutePath)) { - return true; - } - } else if (unlink($absolutePath)) { - return true; - } - } - return !file_exists($absolutePath); - } - throw new NotPermittedException('Template not editable.', 403); - } - - /** - * @return array with available themes. consists of core and subfolders in the themes folder - */ - public static function getEditableThemes() { - $themes = []; - $theme = \OC::$server->getConfig()->getSystemValue('theme', null); - if (!empty($theme)) { - $themes[$theme] = true; - } - - if ($handle = opendir(\OC::$SERVERROOT.'/themes')) { - while (false !== ($entry = readdir($handle))) { - if ($entry === '.' || $entry === '..') { - continue; - } - if (!is_null($theme) && $entry === $theme) { - continue; - } - if (is_dir(\OC::$SERVERROOT.'/themes/'.$entry)) { - $themes[$entry] = true; - } - } - closedir($handle); - } - return $themes; - } - - /** - * @return array with keys containing the path and values containing the name of a template - */ - public static function getEditableTemplates() { - $l10n = \OC::$server->getL10NFactory()->get('templateeditor'); - $templates = [ - 'core/templates/mail.php' => $l10n->t('Sharing email - public link shares (HTML)'), - 'core/templates/altmail.php' => $l10n->t('Sharing email - public link shares (plain text fallback)'), - 'core/templates/internalmail.php' => $l10n->t('Sharing email (HTML)'), - 'core/templates/internalaltmail.php' => $l10n->t('Sharing email (plain text fallback)'), - 'core/templates/lostpassword/email.php' => $l10n->t('Lost password mail'), - 'settings/templates/email.new_user.php' => $l10n->t('New user email (HTML)'), - 'settings/templates/email.new_user_plain_text.php' => $l10n->t('New user email (plain text fallback)'), - ]; - - if (App::isEnabled('activity')) { - $tmplPath = \OC_App::getAppPath('activity') . '/templates/email.notification.php'; - $path = substr($tmplPath, strlen(\OC::$SERVERROOT) + 1); - $templates[$path] = $l10n->t('Activity notification mail'); - } - - return $templates; - } -} diff --git a/templates/settings-admin.php b/templates/settings-admin.php index 5113910..e317ff8 100644 --- a/templates/settings-admin.php +++ b/templates/settings-admin.php @@ -1,23 +1,20 @@

t('Mail Templates'));?>

-
-
-
-
-
-
- - - -
-