TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\CodeEditor;
|
||||
|
||||
use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
|
||||
|
||||
/**
|
||||
* Represents an addon for CodeMirror
|
||||
* @internal
|
||||
*/
|
||||
class Addon
|
||||
{
|
||||
protected string $identifier;
|
||||
|
||||
protected ?JavaScriptModuleInstruction $module = null;
|
||||
|
||||
protected ?JavaScriptModuleInstruction $keymap = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $modes = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $cssFiles = [];
|
||||
|
||||
public function __construct(
|
||||
string $identifier,
|
||||
?JavaScriptModuleInstruction $module = null,
|
||||
?JavaScriptModuleInstruction $keymap = null
|
||||
) {
|
||||
$this->identifier = $identifier;
|
||||
$this->module = $module;
|
||||
$this->keymap = $keymap;
|
||||
}
|
||||
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return $this->identifier;
|
||||
}
|
||||
|
||||
public function getModule(): ?JavaScriptModuleInstruction
|
||||
{
|
||||
return $this->module;
|
||||
}
|
||||
|
||||
public function getKeymap(): ?JavaScriptModuleInstruction
|
||||
{
|
||||
return $this->keymap;
|
||||
}
|
||||
|
||||
public function setOptions(array $options): Addon
|
||||
{
|
||||
$this->options = $options;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
public function setCssFiles(array $cssFiles): Addon
|
||||
{
|
||||
$this->cssFiles = $cssFiles;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCssFiles(): array
|
||||
{
|
||||
return $this->cssFiles;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\CodeEditor;
|
||||
|
||||
use TYPO3\CMS\Backend\CodeEditor\Registry\AddonRegistry;
|
||||
use TYPO3\CMS\Backend\CodeEditor\Registry\ModeRegistry;
|
||||
use TYPO3\CMS\Core\Cache\CacheManager;
|
||||
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
|
||||
use TYPO3\CMS\Core\Package\Cache\PackageDependentCacheIdentifier;
|
||||
use TYPO3\CMS\Core\Package\PackageManager;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Provides necessary code to set up a code editor instance in FormEngine
|
||||
* @internal
|
||||
* @todo: refactor to use DI
|
||||
*/
|
||||
class CodeEditor implements SingletonInterface
|
||||
{
|
||||
protected ?array $configuration = null;
|
||||
|
||||
/**
|
||||
* Registers the configuration and bootstraps the modes / addons.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function registerConfiguration(): void
|
||||
{
|
||||
$configuration = $this->buildConfiguration();
|
||||
|
||||
if (isset($configuration['modes'])) {
|
||||
$modeRegistry = GeneralUtility::makeInstance(ModeRegistry::class);
|
||||
foreach ($configuration['modes'] as $formatCode => $mode) {
|
||||
$modeInstance = GeneralUtility::makeInstance(Mode::class, $mode['module'])->setFormatCode($formatCode);
|
||||
|
||||
if (!empty($mode['extensions']) && is_array($mode['extensions'])) {
|
||||
$modeInstance->bindToFileExtensions($mode['extensions']);
|
||||
}
|
||||
|
||||
if (isset($mode['default']) && $mode['default'] === true) {
|
||||
$modeInstance->setAsDefault();
|
||||
}
|
||||
|
||||
$modeRegistry->register($modeInstance);
|
||||
}
|
||||
}
|
||||
|
||||
$addonRegistry = GeneralUtility::makeInstance(AddonRegistry::class);
|
||||
if (isset($configuration['addons'])) {
|
||||
foreach ($configuration['addons'] as $identifier => $addon) {
|
||||
$addonInstance = GeneralUtility::makeInstance(Addon::class, $identifier, $addon['module'] ?? null, $addon['keymap'] ?? null);
|
||||
|
||||
if (!empty($addon['cssFiles']) && is_array($addon['cssFiles'])) {
|
||||
$addonInstance->setCssFiles($addon['cssFiles']);
|
||||
}
|
||||
|
||||
if (!empty($addon['options']) && is_array($addon['options'])) {
|
||||
$addonInstance->setOptions($addon['options']);
|
||||
}
|
||||
|
||||
$addonRegistry->register($addonInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the configuration for code editor. Configuration is stored in caching framework.
|
||||
*
|
||||
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
|
||||
* @throws \TYPO3\CMS\Core\Cache\Exception\InvalidDataException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function buildConfiguration(): array
|
||||
{
|
||||
if ($this->configuration !== null) {
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
$this->configuration = [
|
||||
'modes' => [],
|
||||
'addons' => [],
|
||||
];
|
||||
|
||||
$cache = $this->getCache();
|
||||
$packageManager = GeneralUtility::makeInstance(PackageManager::class);
|
||||
$cacheIdentifier = $this->generateCacheIdentifier($packageManager);
|
||||
$configurationFromCache = $cache->get($cacheIdentifier);
|
||||
if ($configurationFromCache !== false) {
|
||||
$this->configuration = $configurationFromCache;
|
||||
} else {
|
||||
$packages = $packageManager->getActivePackages();
|
||||
|
||||
foreach ($packages as $package) {
|
||||
$configurationPath = $package->getPackagePath() . 'Configuration/Backend/T3editor';
|
||||
$modesFileNameForPackage = $configurationPath . '/Modes.php';
|
||||
if (is_file($modesFileNameForPackage)) {
|
||||
$definedModes = require $modesFileNameForPackage;
|
||||
if (is_array($definedModes)) {
|
||||
$this->configuration['modes'] = array_merge($this->configuration['modes'], $definedModes);
|
||||
}
|
||||
}
|
||||
|
||||
$addonsFileNameForPackage = $configurationPath . '/Addons.php';
|
||||
if (is_file($addonsFileNameForPackage)) {
|
||||
$definedAddons = require $addonsFileNameForPackage;
|
||||
if (is_array($definedAddons)) {
|
||||
$this->configuration['addons'] = array_merge($this->configuration['addons'], $definedAddons);
|
||||
}
|
||||
}
|
||||
}
|
||||
$cache->set($cacheIdentifier, $this->configuration);
|
||||
}
|
||||
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
protected function generateCacheIdentifier(PackageManager $packageManager): string
|
||||
{
|
||||
return (new PackageDependentCacheIdentifier($packageManager))->withPrefix('T3editorConfiguration')->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function getCache(): FrontendInterface
|
||||
{
|
||||
return GeneralUtility::makeInstance(CacheManager::class)->getCache('assets');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\CodeEditor\Exception;
|
||||
|
||||
use TYPO3\CMS\Core\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown for invalid modes
|
||||
* @internal
|
||||
*/
|
||||
class InvalidModeException extends Exception {}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\CodeEditor;
|
||||
|
||||
use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
|
||||
|
||||
/**
|
||||
* Represents a mode for CodeMirror
|
||||
* @internal
|
||||
*/
|
||||
class Mode
|
||||
{
|
||||
protected JavaScriptModuleInstruction $module;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $formatCode = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fileExtensions = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $isDefault = false;
|
||||
|
||||
public function __construct(JavaScriptModuleInstruction $module)
|
||||
{
|
||||
$this->module = $module;
|
||||
}
|
||||
|
||||
public function getModule(): JavaScriptModuleInstruction
|
||||
{
|
||||
return $this->module;
|
||||
}
|
||||
|
||||
public function getFormatCode(): string
|
||||
{
|
||||
return $this->formatCode;
|
||||
}
|
||||
|
||||
public function setFormatCode(string $formatCode): Mode
|
||||
{
|
||||
$this->formatCode = $formatCode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function bindToFileExtensions(array $fileExtensions): Mode
|
||||
{
|
||||
$this->fileExtensions = $fileExtensions;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBoundFileExtensions(): array
|
||||
{
|
||||
return $this->fileExtensions;
|
||||
}
|
||||
|
||||
public function setAsDefault(): Mode
|
||||
{
|
||||
$this->isDefault = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isDefault(): bool
|
||||
{
|
||||
return $this->isDefault;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\CodeEditor\Registry;
|
||||
|
||||
use TYPO3\CMS\Backend\CodeEditor\Addon;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
|
||||
/**
|
||||
* Registers and holds code editor modes
|
||||
* @internal
|
||||
*/
|
||||
class AddonRegistry implements SingletonInterface
|
||||
{
|
||||
/**
|
||||
* @var Addon[]
|
||||
*/
|
||||
protected $registeredAddons = [];
|
||||
|
||||
/**
|
||||
* Registers addons for global use in code editor
|
||||
*/
|
||||
public function register(Addon $addon): AddonRegistry
|
||||
{
|
||||
$this->registeredAddons[] = $addon;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAddons(): array
|
||||
{
|
||||
return $this->registeredAddons;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Addon[] $addons
|
||||
*/
|
||||
public function compileSettings(array $addons): array
|
||||
{
|
||||
$settings = [];
|
||||
foreach ($addons as $addon) {
|
||||
$settings = array_merge($settings, $addon->getOptions());
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\CodeEditor\Registry;
|
||||
|
||||
use TYPO3\CMS\Backend\CodeEditor\Exception\InvalidModeException;
|
||||
use TYPO3\CMS\Backend\CodeEditor\Mode;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
|
||||
/**
|
||||
* Registers and holds code editor modes
|
||||
* @internal
|
||||
*/
|
||||
class ModeRegistry implements SingletonInterface
|
||||
{
|
||||
/**
|
||||
* @var Mode[]
|
||||
*/
|
||||
protected array $registeredModes = [];
|
||||
|
||||
protected Mode $defaultMode;
|
||||
|
||||
/**
|
||||
* Registers modes for code editor
|
||||
*/
|
||||
public function register(Mode $mode): ModeRegistry
|
||||
{
|
||||
$this->registeredModes[$mode->getFormatCode()] = $mode;
|
||||
if ($mode->isDefault()) {
|
||||
$this->defaultMode = $mode;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes registered modes
|
||||
*/
|
||||
public function unregister(string $formatCode): ModeRegistry
|
||||
{
|
||||
if (isset($this->registeredModes[$formatCode])) {
|
||||
unset($this->registeredModes[$formatCode]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isRegistered(string $formatCode): bool
|
||||
{
|
||||
return isset($this->registeredModes[$formatCode]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidModeException
|
||||
*/
|
||||
public function getByFormatCode(string $formatCode): Mode
|
||||
{
|
||||
foreach ($this->registeredModes as $mode) {
|
||||
if ($mode->getFormatCode() === $formatCode) {
|
||||
return $mode;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidModeException('Tried to get unregistered code editor mode by format code "' . $formatCode . '"', 1499710203);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidModeException
|
||||
*/
|
||||
public function getByFileExtension(string $fileExtension): Mode
|
||||
{
|
||||
foreach ($this->registeredModes as $mode) {
|
||||
if (in_array($fileExtension, $mode->getBoundFileExtensions(), true)) {
|
||||
return $mode;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidModeException('Cannot find a registered mode for requested file extension "' . $fileExtension . '"', 1500306488);
|
||||
}
|
||||
|
||||
public function getDefaultMode(): Mode
|
||||
{
|
||||
return $this->defaultMode;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user