diff options
author | Julius Härtl <jus@bitgrid.net> | 2020-09-23 18:48:48 +0300 |
---|---|---|
committer | Julius Härtl <jus@bitgrid.net> | 2020-09-24 09:22:07 +0300 |
commit | aa95b3d71bdf91d607f3a70f336db09312f2e1fe (patch) | |
tree | 2412618c68f17f78a1a532610da4cc3b6360e082 /apps | |
parent | f62e880a6cfc3d826f0c106fdd46bb801b847378 (diff) |
Add occ command to set theming values
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'apps')
-rw-r--r-- | apps/theming/appinfo/info.xml | 3 | ||||
-rw-r--r-- | apps/theming/lib/Command/UpdateConfig.php | 135 | ||||
-rw-r--r-- | apps/theming/lib/Controller/ThemingController.php | 64 | ||||
-rw-r--r-- | apps/theming/lib/ImageManager.php | 72 | ||||
-rw-r--r-- | apps/theming/lib/ThemingDefaults.php | 8 |
5 files changed, 210 insertions, 72 deletions
diff --git a/apps/theming/appinfo/info.xml b/apps/theming/appinfo/info.xml index f9c6b03dddb..575d06332a4 100644 --- a/apps/theming/appinfo/info.xml +++ b/apps/theming/appinfo/info.xml @@ -25,4 +25,7 @@ <admin>OCA\Theming\Settings\Admin</admin> <admin-section>OCA\Theming\Settings\Section</admin-section> </settings> + <commands> + <command>OCA\Theming\Command\UpdateConfig</command> + </commands> </info> diff --git a/apps/theming/lib/Command/UpdateConfig.php b/apps/theming/lib/Command/UpdateConfig.php new file mode 100644 index 00000000000..7d616879dc6 --- /dev/null +++ b/apps/theming/lib/Command/UpdateConfig.php @@ -0,0 +1,135 @@ +<?php +/** + * @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Theming\Command; + +use OCA\Theming\ImageManager; +use OCA\Theming\ThemingDefaults; +use OCP\IConfig; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class UpdateConfig extends Command { + public const SUPPORTED_KEYS = [ + 'name', 'url', 'imprintUrl', 'privacyUrl', 'slogan', 'color' + ]; + + public const SUPPORTED_IMAGE_KEYS = [ + 'background', 'logo', 'favicon', 'logoheader' + ]; + + private $themingDefaults; + private $imageManager; + private $config; + + public function __construct(ThemingDefaults $themingDefaults, ImageManager $imageManager, IConfig $config) { + parent::__construct(); + + $this->themingDefaults = $themingDefaults; + $this->imageManager = $imageManager; + $this->config = $config; + } + + protected function configure() { + $this + ->setName('theming:config') + ->setDescription('Set theming app config values') + ->addArgument( + 'key', + InputArgument::OPTIONAL, + 'Key to update the theming app configuration (leave empty to get a list of all configured values)' . PHP_EOL . + 'One of: ' . implode(', ', self::SUPPORTED_KEYS) + ) + ->addArgument( + 'value', + InputArgument::OPTIONAL, + 'Value to set (leave empty to obtain the current value)' + ) + ->addOption( + 'reset', + 'r', + InputOption::VALUE_NONE, + 'Reset the given config key to default' + ); + } + + + protected function execute(InputInterface $input, OutputInterface $output): int { + $key = $input->getArgument('key'); + $value = $input->getArgument('value'); + + if ($key === null) { + $output->writeln('Current theming config:'); + foreach (self::SUPPORTED_KEYS as $key) { + $value = $this->config->getAppValue('theming', $key, ''); + $output->writeln('- ' . $key . ': ' . $value . ''); + } + foreach (self::SUPPORTED_IMAGE_KEYS as $key) { + $value = $this->config->getAppValue('theming', $key . 'Mime', ''); + $output->writeln('- ' . $key . ': ' . $value . ''); + } + return 0; + } + + if (!in_array($key, self::SUPPORTED_KEYS, true)) { + $output->writeln('<error>Invalid config key provided</error>'); + return 1; + } + + if ($input->getOption('reset')) { + $defaultValue = $this->themingDefaults->undo($key); + $output->writeln('<info>Reset ' . $key . ' to ' . $defaultValue . '</info>'); + return 0; + } + + if ($value === null) { + $value = $this->config->getAppValue('theming', $key, ''); + if ($value !== '') { + $output->writeln('<info>' . $key . ' is currently set to ' . $value . '</info>'); + } else { + $output->writeln('<info>' . $key . ' is currently not set</info>'); + } + return 0; + } + + if (in_array($key, self::SUPPORTED_IMAGE_KEYS, true)) { + if (file_exists(__DIR__ . $value)) { + $value = __DIR__ . $value; + } + if (!file_exists($value)) { + $output->writeln('<error>File could not be found: ' . $value . '</error>'); + return 1; + } + $value = $this->imageManager->updateImage($key, $value); + $key = $key . 'Mime'; + } + + $this->themingDefaults->set($key, $value); + $output->writeln('<info>Updated ' . $key . ' to ' . $value . '</info>'); + + return 0; + } +} diff --git a/apps/theming/lib/Controller/ThemingController.php b/apps/theming/lib/Controller/ThemingController.php index 3ef5f0de506..56570794247 100644 --- a/apps/theming/lib/Controller/ThemingController.php +++ b/apps/theming/lib/Controller/ThemingController.php @@ -214,9 +214,6 @@ class ThemingController extends Controller { * @throws NotPermittedException */ public function uploadImage(): DataResponse { - // logo / background - // new: favicon logo-header - // $key = $this->request->getParam('key'); $image = $this->request->getUploadedFile('image'); $error = null; @@ -249,23 +246,14 @@ class ThemingController extends Controller { ); } - $name = ''; try { - $folder = $this->appData->getFolder('images'); - } catch (NotFoundException $e) { - $folder = $this->appData->newFolder('images'); - } - - $this->imageManager->delete($key); - - $target = $folder->newFile($key); - $supportedFormats = $this->getSupportedUploadImageFormats($key); - $detectedMimeType = mime_content_type($image['tmp_name']); - if (!in_array($image['type'], $supportedFormats) || !in_array($detectedMimeType, $supportedFormats)) { + $mime = $this->imageManager->updateImage($key, $image['tmp_name']); + $this->themingDefaults->set($key . 'Mime', $mime); + } catch (\Exception $e) { return new DataResponse( [ 'data' => [ - 'message' => $this->l10n->t('Unsupported image type'), + 'message' => $e->getMessage() ], 'status' => 'failure', ], @@ -273,28 +261,7 @@ class ThemingController extends Controller { ); } - if ($key === 'background' && strpos($detectedMimeType, 'image/svg') === false) { - // Optimize the image since some people may upload images that will be - // either to big or are not progressive rendering. - $newImage = @imagecreatefromstring(file_get_contents($image['tmp_name'], 'r')); - - $tmpFile = $this->tempManager->getTemporaryFile(); - $newWidth = imagesx($newImage) < 4096 ? imagesx($newImage) : 4096; - $newHeight = imagesy($newImage) / (imagesx($newImage) / $newWidth); - $outputImage = imagescale($newImage, $newWidth, $newHeight); - - imageinterlace($outputImage, 1); - imagejpeg($outputImage, $tmpFile, 75); - imagedestroy($outputImage); - - $target->putContent(file_get_contents($tmpFile, 'r')); - } else { - $target->putContent(file_get_contents($image['tmp_name'], 'r')); - } $name = $image['name']; - - $this->themingDefaults->set($key.'Mime', $image['type']); - $cssCached = $this->scssCacher->process(\OC::$SERVERROOT, 'core/css/css-variables.scss', 'core'); return new DataResponse( @@ -312,24 +279,6 @@ class ThemingController extends Controller { } /** - * Returns a list of supported mime types for image uploads. - * "favicon" images are only allowed to be SVG when imagemagick with SVG support is available. - * - * @param string $key The image key, e.g. "favicon" - * @return array - */ - private function getSupportedUploadImageFormats(string $key): array { - $supportedFormats = ['image/jpeg', 'image/png', 'image/gif',]; - - if ($key !== 'favicon' || $this->imageManager->shouldReplaceIcons() === true) { - $supportedFormats[] = 'image/svg+xml'; - $supportedFormats[] = 'image/svg'; - } - - return $supportedFormats; - } - - /** * Revert setting to default value * * @param string $setting setting which should be reverted @@ -341,11 +290,6 @@ class ThemingController extends Controller { // reprocess server scss for preview $cssCached = $this->scssCacher->process(\OC::$SERVERROOT, 'core/css/css-variables.scss', 'core'); - if (strpos($setting, 'Mime') !== -1) { - $imageKey = str_replace('Mime', '', $setting); - $this->imageManager->delete($imageKey); - } - return new DataResponse( [ 'data' => diff --git a/apps/theming/lib/ImageManager.php b/apps/theming/lib/ImageManager.php index bf52fd81762..3fe76899dcd 100644 --- a/apps/theming/lib/ImageManager.php +++ b/apps/theming/lib/ImageManager.php @@ -36,6 +36,7 @@ use OCP\Files\SimpleFS\ISimpleFolder; use OCP\ICacheFactory; use OCP\IConfig; use OCP\ILogger; +use OCP\ITempManager; use OCP\IURLGenerator; class ImageManager { @@ -52,27 +53,22 @@ class ImageManager { private $cacheFactory; /** @var ILogger */ private $logger; + /** @var ITempManager */ + private $tempManager; - /** - * ImageManager constructor. - * - * @param IConfig $config - * @param IAppData $appData - * @param IURLGenerator $urlGenerator - * @param ICacheFactory $cacheFactory - * @param ILogger $logger - */ public function __construct(IConfig $config, IAppData $appData, IURLGenerator $urlGenerator, ICacheFactory $cacheFactory, - ILogger $logger + ILogger $logger, + ITempManager $tempManager ) { $this->config = $config; $this->appData = $appData; $this->urlGenerator = $urlGenerator; $this->cacheFactory = $cacheFactory; $this->logger = $logger; + $this->tempManager = $tempManager; } public function getImageUrl(string $key, bool $useSvg = true): string { @@ -211,6 +207,62 @@ class ImageManager { } } + public function updateImage(string $key, string $tmpFile) { + $this->delete($key); + + try { + $folder = $this->appData->getFolder('images'); + } catch (NotFoundException $e) { + $folder = $this->appData->newFolder('images'); + } + + $target = $folder->newFile($key); + $supportedFormats = $this->getSupportedUploadImageFormats($key); + $detectedMimeType = mime_content_type($tmpFile); + if (!in_array($detectedMimeType, $supportedFormats, true)) { + throw new \Exception('Unsupported image type'); + } + + if ($key === 'background' && strpos($detectedMimeType, 'image/svg') === false) { + // Optimize the image since some people may upload images that will be + // either to big or are not progressive rendering. + $newImage = @imagecreatefromstring(file_get_contents($tmpFile)); + + $tmpFile = $this->tempManager->getTemporaryFile(); + $newWidth = (int)(imagesx($newImage) < 4096 ? imagesx($newImage) : 4096); + $newHeight = (int)(imagesy($newImage) / (imagesx($newImage) / $newWidth)); + $outputImage = imagescale($newImage, $newWidth, $newHeight); + + imageinterlace($outputImage, 1); + imagejpeg($outputImage, $tmpFile, 75); + imagedestroy($outputImage); + + $target->putContent(file_get_contents($tmpFile)); + } else { + $target->putContent(file_get_contents($tmpFile)); + } + + return $detectedMimeType; + } + + /** + * Returns a list of supported mime types for image uploads. + * "favicon" images are only allowed to be SVG when imagemagick with SVG support is available. + * + * @param string $key The image key, e.g. "favicon" + * @return array + */ + private function getSupportedUploadImageFormats(string $key): array { + $supportedFormats = ['image/jpeg', 'image/png', 'image/gif']; + + if ($key !== 'favicon' || $this->shouldReplaceIcons() === true) { + $supportedFormats[] = 'image/svg+xml'; + $supportedFormats[] = 'image/svg'; + } + + return $supportedFormats; + } + /** * remove cached files that are not required any longer * diff --git a/apps/theming/lib/ThemingDefaults.php b/apps/theming/lib/ThemingDefaults.php index e5680846627..3fdbc1a61ae 100644 --- a/apps/theming/lib/ThemingDefaults.php +++ b/apps/theming/lib/ThemingDefaults.php @@ -398,6 +398,7 @@ class ThemingDefaults extends \OC_Defaults { $this->config->deleteAppValue('theming', $setting); $this->increaseCacheBuster(); + $returnValue = ''; switch ($setting) { case 'name': $returnValue = $this->getEntity(); @@ -411,8 +412,11 @@ class ThemingDefaults extends \OC_Defaults { case 'color': $returnValue = $this->getColorPrimary(); break; - default: - $returnValue = ''; + case 'logo': + case 'logoheader': + case 'background': + case 'favicon': + $this->imageManager->delete($setting); break; } |