Initial commit - Typo3 11.5.41

This commit is contained in:
Matteo Gallo
2026-07-03 17:53:31 +02:00
commit 5ca4743197
6811 changed files with 568848 additions and 0 deletions

View File

@@ -0,0 +1,236 @@
<?php
namespace SGalinski\Lfeditor\Controller;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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 General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use TYPO3\CMS\Backend\Template\ModuleTemplate;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* Abstract Backend Controller
*/
abstract class AbstractBackendController extends AbstractController {
/**
* @var BackendUserAuthentication
*/
protected $backendUser;
/**
* @var ?ModuleTemplate
*/
protected $moduleTemplate = NULL;
/**
* Initializes any action
*
* @return void
* @throws \SGalinski\Lfeditor\Exceptions\DirectoryAccessRightsException
*/
public function initializeAction() {
parent::initializeAction();
if (\TYPO3\CMS\Core\Http\ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isBackend()) {
$this->backendUser = $GLOBALS['BE_USER'];
}
$editingMode = $this->session->getDataByKey('editingMode');
$availableEditingModes = $this->configurationService->getAvailableEditingModes();
if ($this->backendUser->isAdmin()) {
if (!\array_key_exists($editingMode, $availableEditingModes)) {
$firstAvailableEditMode = \key($availableEditingModes);
$this->session->setDataByKey('editingMode', $firstAvailableEditMode);
}
$canChangeEditingModes = \count($availableEditingModes) > 0;
} else {
$canChangeEditingModes = \count($availableEditingModes) > 0
&& $this->backendUser->user['lfeditor_change_editing_modes'] !== 0;
if (!$canChangeEditingModes || !\array_key_exists($editingMode, $availableEditingModes)) {
$lastAvailableEditMode = array_key_last($availableEditingModes);
$this->session->setDataByKey('editingMode', $lastAvailableEditMode);
}
}
$this->session->setDataByKey('defaultLanguagePermission', $this->backendUser->checkLanguageAccess(0));
$this->session->setDataByKey('canChangeEditingModes', $canChangeEditingModes);
}
/**
* Saves the the last called controller/action pair into the backend user
* configuration if available
*
* @param bool $saveWithRedirectPair
* @return void
*/
protected function setLastCalledControllerActionPair($saveWithRedirectPair = TRUE) {
if (!$this->backendUser) {
return;
}
$extensionKey = $this->request->getControllerExtensionKey();
$pair = [
'action' => $this->request->getControllerActionName(),
'controller' => $this->request->getControllerName(),
];
$this->backendUser->uc[$extensionKey . 'State']['LastActionControllerPair'] = $pair;
if ($saveWithRedirectPair) {
$this->backendUser->uc[$extensionKey . 'State']['LastActionControllerPairForRedirect'] = $pair;
}
$this->backendUser->writeUC($this->backendUser->uc);
}
/**
* Resets the last called controller/action pair combination from the
* backend user session
*
* @return void
*/
protected function resetLastCalledControllerActionPair() {
if (!$this->backendUser) {
return;
}
$extensionKey = $this->request->getControllerExtensionKey();
$this->backendUser->uc[$extensionKey . 'State']['LastActionControllerPair'] = [];
$this->backendUser->uc[$extensionKey . 'State']['LastActionControllerPairForRedirect'] = [];
$this->backendUser->writeUC($this->backendUser->uc);
if ($this->view instanceof ViewInterface) {
$this->view->assign('lastCalledControllerActionPair', NULL);
}
}
/**
* Returns the last called controller/action pair from the backend user session
*
* @return array
*/
protected function getLastCalledControllerActionPair() {
if (!$this->backendUser) {
return [];
}
$extensionKey = $this->request->getControllerExtensionKey();
$state = $this->backendUser->uc[$extensionKey . 'State']['LastActionControllerPair'];
return (!\is_array($state) ? [] : $state);
}
/**
* Returns the last called controller/action pair from the backend user session
*
* @return array
*/
protected function getLastCalledControllerActionPairForRedirect() {
if (!$this->backendUser) {
return [];
}
$extensionKey = $this->request->getControllerExtensionKey();
return $this->backendUser->uc[$extensionKey . 'State']['LastActionControllerPairForRedirect'] ?? [];
}
/**
* Redirects to the last called controller/action pair saved inside the
* backend user session
*
* @return \TYPO3\CMS\Extbase\Http\ForwardResponse|null
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
protected function redirectToLastCalledControllerActionPair(): ?\TYPO3\CMS\Extbase\Http\ForwardResponse {
$state = $this->getLastCalledControllerActionPairForRedirect();
if (\count($state) && \trim($state['action']) !== '' && \trim($state['controller']) !== '') {
$currentAction = $this->request->getControllerActionName();
$currentController = $this->request->getControllerName();
if (!($currentController === $state['controller'] && $currentAction === $state['action'])) {
$extensionName = $this->request->getControllerExtensionName();
$moduleSignature = $this->request->getPluginName();
$extensionConfig = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName];
$availableControllers = $extensionConfig['modules'][$moduleSignature]['controllers'];
$controllerExists = isset($availableControllers[$state['controller']]);
if ($controllerExists) {
$actionExists = \in_array(
$state['action'],
$availableControllers[$state['controller']]['actions'],
TRUE
);
if ($actionExists) {
if (version_compare(
\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(),
'11.0.0',
'<'
)) {
$this->forward($state['action'], $state['controller']);
}
return (new \TYPO3\CMS\Extbase\Http\ForwardResponse($state['action']))->withControllerName(
$state['controller']
);
}
}
}
}
return NULL;
}
/**
* Sets last called controller-action pair and assigns common view variables.
* This function should be called at the end of actions which render view
* (and does not do redirection or forwarding at the end)
*/
protected function commonViewRenderingActionSettings() {
$this->setLastCalledControllerActionPair();
$this->view->assign('editingMode', $this->session->getDataByKey('editingMode'));
$this->view->assign('editingModeOptions', $this->configurationService->getAvailableEditingModes());
$this->view->assign('adminUser', $this->backendUser->isAdmin());
$this->view->assign('defaultLanguagePermission', $this->session->getDataByKey('defaultLanguagePermission'));
$this->view->assign('canChangeEditingModes', $this->session->getDataByKey('canChangeEditingModes'));
}
/**
* Since we cannot use constructor Injection, we do have to get one dynamically. If we want to use
* our ModuleTemplate, call GetModuleTemplate before, which will init one if there is none for some reason
*/
protected function getModuleTemplate() {
if ($this->moduleTemplate === NULL) {
$moduleTemplateFactory = GeneralUtility::makeInstance(
\TYPO3\CMS\Backend\Template\ModuleTemplateFactory::class
);
$this->moduleTemplate = $moduleTemplateFactory->create($this->request);
}
}
/**
* Use the ModuleTemplateResponse to create a response object for the backend
*
* @return \Psr\Http\Message\ResponseInterface
*/
protected function createBackendResponse(): \Psr\Http\Message\ResponseInterface {
return $this->htmlResponse($this->view->render());
}
}

View File

@@ -0,0 +1,317 @@
<?php
namespace SGalinski\Lfeditor\Controller;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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 General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\Lfeditor\Exceptions\LFException;
use SGalinski\Lfeditor\Service\BackupService;
use SGalinski\Lfeditor\Service\ConfigurationService;
use SGalinski\Lfeditor\Session\PhpSession;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Messaging\AbstractMessage;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* Abstract Controller
*/
abstract class AbstractController extends ActionController {
/**
* @var \SGalinski\Lfeditor\Session\PhpSession
*/
protected $session;
/**
*
* @var ConfigurationService
*/
protected $configurationService;
/**
* Inject the ConfigurationService
*
* @param ConfigurationService $configurationService
*/
public function injectConfigurationService(ConfigurationService $configurationService) {
$this->configurationService = $configurationService;
}
/**
*
* @var BackupService
*/
protected $backupService;
/**
* Inject the BackupService
*
* @param BackupService $backupService
*/
public function injectBackupService(BackupService $backupService) {
$this->backupService = $backupService;
}
/**
* Initializes the actions.
* - Initializes the session object.
* - Fetches configuration.
*
* @return void
* @throws \SGalinski\Lfeditor\Exceptions\DirectoryAccessRightsException
*/
public function initializeAction() {
parent::initializeAction();
if (!($this->session instanceof PhpSession)) {
$this->session = GeneralUtility::makeInstance(PhpSession::class);
$this->session->setSessionKey('tx_lfeditor_sessionVariables');
}
$this->configurationService->prepareConfig();
}
/**
* Saves in session currently selected values of select tags.
*
* @param string $extensionSelection
* @param string $languageFileSelection
* @param string $referenceLanguageSelection
* @param string $constantSelection
* @param string $languageSelection
* @param string $constantTypeSelection
* @param string $bottomReferenceLanguageSelection
* @param string $numSiteConstsSelection
* @param string $extkey
* @return void
*/
protected function saveSelectionsInSession(
$extensionSelection = NULL,
$languageFileSelection = NULL,
$referenceLanguageSelection = NULL,
$constantSelection = NULL,
$languageSelection = NULL,
$constantTypeSelection = NULL,
$bottomReferenceLanguageSelection = NULL,
$numSiteConstsSelection = NULL,
$extkey = NULL
) {
/* Extension/language file select box can't be unselected.
Only situation when $extensionSelection === NULL is when the form is submitted by
selection change of some other box. That is because <f:be.menus.actionMenu> with 'optgroup' tags is used */
if ($extensionSelection) {
$this->session->setDataByKey('extensionSelection', $extensionSelection);
}
if ($languageFileSelection) {
$this->session->setDataByKey('languageFileSelection', $languageFileSelection);
}
if ($referenceLanguageSelection) {
$this->session->setDataByKey('referenceLanguageSelection', $referenceLanguageSelection);
}
if ($constantSelection) {
$this->session->setDataByKey('constantSelection', $constantSelection);
}
if ($languageSelection) {
$this->session->setDataByKey('languageSelection', $languageSelection);
}
if ($constantTypeSelection) {
$this->session->setDataByKey('constantTypeSelection', $constantTypeSelection);
}
if ($bottomReferenceLanguageSelection) {
$this->session->setDataByKey('bottomReferenceLanguageSelection', $bottomReferenceLanguageSelection);
}
if ($numSiteConstsSelection) {
$this->session->setDataByKey('numSiteConstsSelection', $numSiteConstsSelection);
}
if ($extkey) {
$this->session->setDataByKey('extkey', $extkey);
}
}
/**
* Assigns view width menu options and default menu selection which is fetched from session.
*
* @param string $menuName Name of the menu, which will be used as prefix of view keys for menu options and menu selection.
* Example: menuName 'extension' will produce view keys 'extensionOptions' and 'extensionSelection'
* @param array $options menu options to be assigned to view
* @return void
*/
protected function assignViewWidthMenuVariables($menuName, $options) {
$this->view->assign($menuName . 'Options', $options);
$selection = $this->checkMenuSelection($menuName, $options);
$this->view->assign($menuName . 'Selection', $selection);
}
/**
* Checks does selection exists in session or among menu options and if it does not,
* first option becomes selected.
*
* @param string $menuName Name of the menu, which will be used as prefix of view keys for menu options and menu selection.
* Example: menuName 'extension' will produce view keys 'extensionOptions' and 'extensionSelection'
* @param array $options menu options to be checked upon.
* @return string
*/
protected function checkMenuSelection($menuName, array $options) {
$selection = $this->session->getDataByKey($menuName . 'Selection');
if (!\array_key_exists($selection, $options)) {
$selection = NULL;
}
if ($selection === NULL && !empty($options)) {
$selection = array_key_first($options);
$this->session->setDataByKey($menuName . 'Selection', $selection);
return $selection;
}
return $selection;
}
/**
* Sets FlashMessage from LFException.
*
* @param LFException $lFException
* @return void
*/
public function addLFEFlashMessage(LFException $lFException) {
if ($lFException->getCode() === 0) {
$this->addFlashMessage(
$lFException->getMessage(),
LocalizationUtility::translate('failure.failure', 'lfeditor'),
AbstractMessage::ERROR
);
} elseif ($lFException->getCode() === 1) {
$this->addFlashMessage(
$lFException->getMessage(),
'',
AbstractMessage::NOTICE
);
}
}
/**
* Prepares language file select options for each extension and sets combined data in view.
*
* @return void
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws LFException
*/
protected function prepareExtensionAndLangFileOptions() {
/** @var CacheManager $cacheManager */
$cacheManager = GeneralUtility::makeInstance(CacheManager::class);
$extensions = $cacheManager->getCache('lfeditor_select_options_cache')->get('extensionAndLangFileOptions');
if (!is_array($extensions)) {
$extensions = [];
$extensionOptions = $this->configurationService->menuExtList();
$extensionGroupCount = 0;
foreach ($extensionOptions as $extAddress => $extLabel) {
$extension['extKey'] = $extLabel;
((int) ExtensionManagementUtility::isLoaded(basename($extLabel))) ?
$state = LocalizationUtility::translate('ext.loaded', 'lfeditor') :
$state = LocalizationUtility::translate('ext.notLoaded', 'lfeditor');
$extension['extLabel'] = $extLabel . ' [' . $state . ']';
$extension['languageFileOptions'] = [];
$isExtensionGroupStart = $extAddress === '###extensionGroup###' . $extLabel;
try {
if (!$isExtensionGroupStart) {
$extension['languageFileOptions'] = $this->configurationService->menuLangFileList($extAddress);
if (empty($extension['languageFileOptions'])) {
continue;
}
} elseif (++$extensionGroupCount > 1) {
$extensions[$extAddress . 'EmptySpaceBefore'] = [
'extLabel' => '',
'languageFileOptions' => [],
];
}
} catch (LFException $e) {
continue;
}
$extensions[$extAddress] = $extension;
if ($isExtensionGroupStart) {
$extensions[$extAddress . 'DelimiterAfter'] = [
'extLabel' => '======',
'languageFileOptions' => [],
];
}
}
$cacheManager->getCache('lfeditor_select_options_cache')->set('extensionAndLangFileOptions', $extensions);
}
$this->checkExtensionAndLangFileSelection($extensions);
$extensionSelection = $this->session->getDataByKey('extensionSelection');
$this->view->assign('extensions', $extensions);
$this->view->assign('extensionSelection', $extensionSelection);
$this->view->assign('extensionLabel', $extensions[$extensionSelection]['extLabel'] ?? '');
$this->view->assign('languageFileSelection', $this->session->getDataByKey('languageFileSelection'));
}
/**
* Checks do extensionSelection and languageFileSelection exist in session or among menu options and if it does not,
* first language file and belonging extension become selected and saved to session.
*
* @param array $extensions
* @return void
*/
protected function checkExtensionAndLangFileSelection(array $extensions) {
$extensionSelection = $this->session->getDataByKey('extensionSelection');
$languageFileSelection = $this->session->getDataByKey('languageFileSelection');
$selectFirstLanguageFileAndBelongingExtension = !$extensionSelection || !$languageFileSelection ||
!(array_key_exists($extensionSelection, $extensions) && array_key_exists(
$languageFileSelection,
$extensions[$extensionSelection]['languageFileOptions']
));
if ($selectFirstLanguageFileAndBelongingExtension) {
foreach ($extensions as $extAddress => $extension) {
if (empty($extension['languageFileOptions'])) {
continue;
}
$languageFileSelection = array_key_first($extension['languageFileOptions']);
$this->session->setDataByKey('languageFileSelection', $languageFileSelection);
$this->session->setDataByKey('extensionSelection', $extAddress);
break;
}
}
}
/**
* Clears cache used for storing select options.
* If $identifier is set, it clears only that entry in cache,
* otherwise it clears whole select options cache.
*
* @param string $identifier
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
protected function clearSelectOptionsCache($identifier = NULL) {
/** @var CacheManager $cacheManager */
$cacheManager = GeneralUtility::makeInstance(CacheManager::class);
if ($identifier !== NULL) {
$cacheManager->getCache('lfeditor_select_options_cache')->set($identifier, NULL);
} else {
$cacheManager->getCache('lfeditor_select_options_cache')->flush();
}
}
}

View File

@@ -0,0 +1,176 @@
<?php
namespace SGalinski\Lfeditor\Controller;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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 General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\Lfeditor\Exceptions\LFException;
use TYPO3\CMS\Core\Messaging\AbstractMessage;
use TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* AddConstant controller. It contains extbase actions for AddConstant page.
*/
class AddConstantController extends AbstractBackendController {
/**
* Opens addConstant view.
* It is called in 2 cases:
* - on selection of addConstant option in main menu,
* - after redirection from action which must not change the view.
*
*/
public function addConstantAction(): ?\Psr\Http\Message\ResponseInterface {
try {
$this->view->assign('controllerName', 'AddConstant');
$this->prepareExtensionAndLangFileOptions();
$this->prepareAddConstantViewMainSectionContent();
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
$this->commonViewRenderingActionSettings();
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->view->assign('V11', FALSE);
return NULL;
} else {
$this->view->assign('V11', TRUE);
return $this->createBackendResponse();
}
}
/**
* This action saves in session currently selected options from selection menus in addConstant view.
* It is called on change of selection of any select menu in addConstant view.
*
* @param string $extensionSelection
* @param string $languageFileSelection
* @param string $extKey
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function changeSelectionAction($extensionSelection = NULL, $languageFileSelection = NULL, $extKey = ''): ?\Psr\Http\Message\ResponseInterface {
$this->saveSelectionsInSession(
$extensionSelection,
$languageFileSelection,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
$extKey
);
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('addConstant');
return NULL;
} else {
return $this->redirect('addConstant');
}
}
/**
* Saves the changes made in main section of addConstant view.
*
* @param string $nameOfConstant
* @param array $addConstTextArea
* @return \Psr\Http\Message\ResponseInterface|null
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function addConstantSaveAction($nameOfConstant, array $addConstTextArea): ?\Psr\Http\Message\ResponseInterface {
try {
if (empty($nameOfConstant)) {
throw new LFException('failure.select.noConstDefined');
}
$extConfig = $this->configurationService->getExtConfig();
$this->configurationService->initFileObject(
$this->session->getDataByKey('languageFileSelection'),
$this->session->getDataByKey('extensionSelection')
);
$langData = $this->configurationService->getFileObj()->getLocalLangData();
$constExists = !empty($langData['default'][$nameOfConstant])
|| !empty($langData[$extConfig['defaultLanguage']][$nameOfConstant]);
if ($constExists) {
throw new LFException('failure.langfile.constExists');
}
$newConstLanguages = [];
foreach ($addConstTextArea as $lang => $value) {
$newConstLanguages[$lang][$nameOfConstant] = $value;
}
$this->configurationService->execWrite($newConstLanguages);
$this->session->setDataByKey('constantSelection', $nameOfConstant);
$this->addFlashMessage(
LocalizationUtility::translate('lang.file.write.success', 'lfeditor'),
'',
$severity = AbstractMessage::OK,
$storeInSession = TRUE
);
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('addConstant');
return NULL;
} else {
return $this->redirect('addConstant');
}
}
/**
* Clears extensionAndLangFileOptions cache, and in that way refreshes list of language file options in select box.
*
*/
public function refreshLanguageFileListAction(): ?\Psr\Http\Message\ResponseInterface {
$this->clearSelectOptionsCache('extensionAndLangFileOptions');
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('addConstant');
return NULL;
} else {
return $this->redirect('addConstant');
}
}
/**
* Prepares main section content of addConstant view.
*
* @throws LFException
* @return void
*/
protected function prepareAddConstantViewMainSectionContent() {
$extConfig = $this->configurationService->getExtConfig();
$langArray = $this->configurationService->getLangArray($this->backendUser);
$this->view->assign('languages', $langArray);
$this->view->assign('numTextAreaRows', $extConfig['numTextAreaRows']);
}
}

View File

@@ -0,0 +1,189 @@
<?php
namespace SGalinski\Lfeditor\Controller;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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 General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\Lfeditor\Exceptions\LFException;
use SGalinski\Lfeditor\Service\FileOverrideService;
use SGalinski\Lfeditor\Utility\Functions;
use TYPO3\CMS\Core\Messaging\AbstractMessage;
use TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* DeleteConstant controller. It contains extbase actions for DeleteConstant page.
*/
class DeleteConstantController extends AbstractBackendController {
/**
* Opens deleteConstant view.
* It is called in 2 cases:
* - on selection of deleteConstant option in main menu,
* - after redirection from action which must not change the view.
*
*/
public function deleteConstantAction(): ?\Psr\Http\Message\ResponseInterface {
try {
$this->view->assign('controllerName', 'DeleteConstant');
$this->prepareExtensionAndLangFileOptions();
$this->configurationService->initFileObject(
$this->session->getDataByKey('languageFileSelection'),
$this->session->getDataByKey('extensionSelection')
);
$fileObject = $this->configurationService->getFileObj();
if ($this->session->getDataByKey('editingMode') === 'override') {
/** @var FileOverrideService $overrideFileObject */
$overrideFileObject = $fileObject;
$overrideFileObject->deleteDuplicates();
}
$langData = $fileObject->getLocalLangData();
$constantOptions = $this->configurationService->menuConstList(
$langData,
LocalizationUtility::translate('select.nothing', 'lfeditor')
);
$this->assignViewWidthMenuVariables('constant', $constantOptions);
$this->prepareDeleteConstantViewMainSectionContent();
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
$this->commonViewRenderingActionSettings();
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->view->assign('V11', FALSE);
return NULL;
} else {
$this->view->assign('V11', TRUE);
return $this->createBackendResponse();
}
}
/**
* This action saves in session currently selected options from selection menus in deleteConstant view.
* It is called on change of selection of any select menu in deleteConstant view.
*
* @param string $extensionSelection
* @param string $languageFileSelection
* @param string $constantSelection
* @param string $extKey
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function changeSelectionAction(
$extensionSelection = NULL,
$languageFileSelection = NULL,
$constantSelection = NULL,
$extKey = ''
): ?\Psr\Http\Message\ResponseInterface {
$this->saveSelectionsInSession(
$extensionSelection,
$languageFileSelection,
NULL,
$constantSelection,
NULL,
NULL,
NULL,
NULL,
$extKey
);
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('deleteConstant');
return NULL;
} else {
return $this->redirect('deleteConstant');
}
}
/**
* Saves the changes made in main section of deleteConstant view.
*
* @return \Psr\Http\Message\ResponseInterface|null
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function deleteConstantSaveAction(): ?\Psr\Http\Message\ResponseInterface {
try {
$constantSelection = $this->session->getDataByKey('constantSelection');
$langArray = Functions::buildLangArray();
// build modArray
$newLang = [];
foreach ($langArray as $lang) {
$newLang[$lang][$constantSelection] = '';
}
$this->configurationService->execWrite($newLang, [], TRUE);
$this->addFlashMessage(
LocalizationUtility::translate('lang.file.write.success', 'lfeditor'),
'',
$severity = AbstractMessage::OK,
$storeInSession = TRUE
);
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('deleteConstant');
return NULL;
} else {
return $this->redirect('deleteConstant');
}
}
/**
* Clears extensionAndLangFileOptions cache, and in that way refreshes list of language file options in select box.
*
* @return \Psr\Http\Message\ResponseInterface|null
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function refreshLanguageFileListAction(): ?\Psr\Http\Message\ResponseInterface {
$this->clearSelectOptionsCache('extensionAndLangFileOptions');
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('deleteConstant');
return NULL;
} else {
return $this->redirect('deleteConstant');
}
}
/**
* Prepares main section content of deleteConstant view.
*
* @throws LFException
* @return void
*/
protected function prepareDeleteConstantViewMainSectionContent() {
$constantSelection = $this->session->getDataByKey('constantSelection');
if (empty($constantSelection) || $constantSelection == '###default###') {
throw new LFException('failure.select.noConst', 1);
}
$this->view->assign('constantSelection', $constantSelection);
}
}

View File

@@ -0,0 +1,204 @@
<?php
namespace SGalinski\Lfeditor\Controller;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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 General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\Lfeditor\Exceptions\LFException;
use TYPO3\CMS\Core\Messaging\AbstractMessage;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* EditConstant controller. It contains extbase actions for EditConstant page.
*/
class EditConstantController extends AbstractBackendController {
/**
* Opens editConstant view.
* It is called in 2 cases:
* - on selection of editConstant option in main menu,
* - after redirection from action which must not change the view.
*
* @return \Psr\Http\Message\ResponseInterface|null
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
public function editConstantAction(): ?\Psr\Http\Message\ResponseInterface {
try {
$this->view->assign('controllerName', 'EditConstant');
$this->prepareExtensionAndLangFileOptions();
$this->configurationService->initFileObject(
$this->session->getDataByKey('languageFileSelection'),
$this->session->getDataByKey('extensionSelection')
);
$langData = $this->configurationService->getFileObj()->getLocalLangData();
$constantOptions = $this->configurationService->menuConstList(
$langData,
LocalizationUtility::translate('select.nothing', 'lfeditor')
);
$this->assignViewWidthMenuVariables('constant', $constantOptions);
$this->prepareEditConstantViewMainSectionContent($langData);
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
$this->commonViewRenderingActionSettings();
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->view->assign('V11', FALSE);
return NULL;
} else {
$this->view->assign('V11', TRUE);
return $this->createBackendResponse();
}
}
/**
* This action saves in session currently selected options from selection menus in editConstant view.
* It is called on change of selection of any select menu in editConstant view.
*
* @param string $extensionSelection
* @param string $languageFileSelection
* @param string $constantSelection
* @param string $extKey
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function changeSelectionAction(
$extensionSelection = NULL,
$languageFileSelection = NULL,
$constantSelection = NULL,
$extKey = ''
): ?\Psr\Http\Message\ResponseInterface {
$this->saveSelectionsInSession(
$extensionSelection,
$languageFileSelection,
NULL,
$constantSelection,
NULL,
NULL,
NULL,
NULL,
$extKey
);
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('editConstant');
return NULL;
} else {
return $this->redirect('editConstant');
}
}
/**
* Saves the changes made in main section of editConstant view.
*
* @param array $editConstTextArea
* @return \Psr\Http\Message\ResponseInterface|null
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function editConstantSaveAction(array $editConstTextArea): ?\Psr\Http\Message\ResponseInterface {
try {
$this->configurationService->execWrite($editConstTextArea);
$this->addFlashMessage(
LocalizationUtility::translate('lang.file.write.success', 'lfeditor'),
'',
$severity = AbstractMessage::OK,
$storeInSession = TRUE
);
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('editConstant');
return NULL;
} else {
return $this->redirect('editConstant');
}
}
/**
* Clears extensionAndLangFileOptions cache, and in that way refreshes list of language file options in select box.
*
* @return \Psr\Http\Message\ResponseInterface|null
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function refreshLanguageFileListAction(): ?\Psr\Http\Message\ResponseInterface {
$this->clearSelectOptionsCache('extensionAndLangFileOptions');
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('editConstant');
return NULL;
} else {
return $this->redirect('editConstant');
}
}
/**
* Prepares main section content of editConstant view.
*
* @param array $langData
* @throws LFException
* @return void
*/
protected function prepareEditConstantViewMainSectionContent(array $langData = NULL) {
$extConfig = $this->configurationService->getExtConfig();
$langArray = $this->configurationService->getLangArray($this->backendUser);
$constantSelection = $this->session->getDataByKey('constantSelection');
if (empty($constantSelection) || $constantSelection == '###default###') {
throw new LFException('failure.select.noConst', 1);
}
$languages = [];
foreach ($langArray as $lang) {
if (array_key_exists($lang, $langData) && array_key_exists($constantSelection, $langData[$lang])) {
$languages[$lang] = $langData[$lang][$constantSelection];
} else {
$languages[$lang] = '';
}
}
$this->view->assign('constantSelection', $constantSelection);
$this->view->assign('languages', $languages);
$this->view->assign('numTextAreaRows', $extConfig['numTextAreaRows']);
$this->view->assign('defaultLanguage', $extConfig['defaultLanguage']);
}
/**
* Sets chosen constant and redirects to editConstant view.
*
* @param string $constantKey
* @return void
*/
protected function prepareEditConstantAction($constantKey) {
$this->session->setDataByKey('constantSelection', $constantKey);
$this->redirect('editConstant', 'EditConstant');
}
}

View File

@@ -0,0 +1,365 @@
<?php
namespace SGalinski\Lfeditor\Controller;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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 General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\Lfeditor\Exceptions\LFException;
use TYPO3\CMS\Core\Messaging\AbstractMessage;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* EditFile controller. It contains extbase actions of EditFile page.
*/
class EditFileController extends AbstractBackendController {
/**
* Opens editFile view.
* It is called in 2 cases:
* - on selection of editFile option in main menu,
* - after redirection from action which must not change the view.
*
* @param integer $buttonType :
* -1 - cancel,
* 0 - no button clicked,
* 1 - back,
* 2 - next,
* 3 - save.
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
public function editFileAction(int $buttonType = 0): ?\Psr\Http\Message\ResponseInterface {
try {
$this->view->assign('controllerName', 'EditFile');
$this->prepareExtensionAndLangFileOptions();
$this->configurationService->initFileObject(
$this->session->getDataByKey('languageFileSelection'),
$this->session->getDataByKey('extensionSelection')
);
$langData = $this->configurationService->getFileObj()->getLocalLangData();
$languageOptions = $this->configurationService->menuLangList($langData, '', $this->backendUser);
$this->assignViewWidthMenuVariables('language', $languageOptions);
$referenceLanguageOptions = $this->configurationService->menuLangList(
$langData,
LocalizationUtility::translate('select.nothing', 'lfeditor'),
$this->backendUser
);
$this->assignViewWidthMenuVariables('referenceLanguage', $referenceLanguageOptions);
$bottomReferenceLanguageOptions = $this->configurationService->menuLangList(
$langData,
'',
$this->backendUser,
TRUE
);
$this->assignViewWidthMenuVariables('bottomReferenceLanguage', $bottomReferenceLanguageOptions);
$constantTypeOptions = $this->getConstantTypeOptions();
$this->assignViewWidthMenuVariables('constantType', $constantTypeOptions);
$extConfig = $this->configurationService->getExtConfig();
$this->assignViewWidthMenuVariables('numSiteConsts', $extConfig['numSiteConstsOptions']);
$this->prepareEditFileViewMainSectionContent($langData, $buttonType);
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
$this->commonViewRenderingActionSettings();
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->view->assign('V11', FALSE);
return NULL;
} else {
$this->view->assign('V11', TRUE);
return $this->createBackendResponse();
}
}
/**
* This action saves in session currently selected options from selection menus in editFile view.
* It is called on change of selection of any select menu in editFile view.
*
* @param string $extensionSelection
* @param string $languageFileSelection
* @param string $languageSelection
* @param string $referenceLanguageSelection
* @param string $constantTypeSelection
* @param string $bottomReferenceLanguageSelection
* @param string $numSiteConstsSelection
* @param string $extKey
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function changeSelectionAction(
$extensionSelection = NULL,
$languageFileSelection = NULL,
$languageSelection = NULL,
$referenceLanguageSelection = NULL,
$constantTypeSelection = NULL,
$bottomReferenceLanguageSelection = NULL,
$numSiteConstsSelection = NULL,
$extKey = ''
): ?\Psr\Http\Message\ResponseInterface {
$this->saveSelectionsInSession(
$extensionSelection,
$languageFileSelection,
$referenceLanguageSelection,
NULL,
$languageSelection,
$constantTypeSelection,
$bottomReferenceLanguageSelection,
$numSiteConstsSelection,
$extKey
);
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('editFile', NULL, NULL, ['buttonType' => 0]);
return NULL;
} else {
return $this->redirect('editFile', NULL, NULL, ['buttonType' => 0]);
}
}
/**
* Clears extensionAndLangFileOptions cache, and in that way refreshes list of language file options in select box.
*
*/
public function refreshLanguageFileListAction(): ?\Psr\Http\Message\ResponseInterface {
$this->clearSelectOptionsCache('extensionAndLangFileOptions');
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('editFile', NULL, NULL, ['buttonType' => 0]);
return NULL;
} else {
return $this->redirect('editFile', NULL, NULL, ['buttonType' => 0]);
}
}
/**
* Prepares main section content of editFile view.
* Structure of the content:
* $constValues[$constant]['edit'],
* $constValues[$constant]['pattern'],
* $constValues[$constant][$extConfig['defaultLanguage']].
*
* @param array $langData
* @param integer $buttonType :
* -1 - cancel,
* 0 - no button clicked,
* 1 - back,
* 2 - next,
* 3 - save.
* @throws LFException
* @return void
*/
protected function prepareEditFileViewMainSectionContent(array $langData, int $buttonType) {
$extConfig = $this->configurationService->getExtConfig();
$numConstantsPerPage = $this->session->getDataByKey('numSiteConstsSelection');
$langList = $this->session->getDataByKey('languageSelection');
$patternList = $this->session->getDataByKey('referenceLanguageSelection');
$constTypeList = $this->session->getDataByKey('constantTypeSelection');
$parallelEdit = $patternList !== '###default###' && $patternList != $langList;
$langEdit = (array_key_exists($langList, $langData) && is_array($langData[$langList])) ? $langData[$langList] : [];
$langPattern = (array_key_exists($patternList, $langData) && is_array($langData[$patternList])) ? $langData[$patternList] : [];
$bottomReferenceLanguageSelection = $this->session->getDataByKey('bottomReferenceLanguageSelection');
$bottomReferenceLanguage = is_array($langData[$bottomReferenceLanguageSelection])
? $langData[$bottomReferenceLanguageSelection] : [];
if (empty($bottomReferenceLanguage)) {
$bottomReferenceLanguage = is_array($langData['default']) ? $langData['default'] : [];
}
$langDataSessionContinued = $buttonType !== 3;
if ($buttonType === 0) {
$this->session->setDataByKey('sessionLangDataConstantsIterator', 0);
$this->session->setDataByKey('numberLastPageConstants', 0);
}
$sessionLangDataConstantsIterator = $this->session->getDataByKey('sessionLangDataConstantsIterator');
$numberLastPageConstants = $this->session->getDataByKey('numberLastPageConstants');
// new translation
if (!$langDataSessionContinued || $buttonType <= 0) {
// adjust number of session constants
if ($constTypeList === 'untranslated' || $constTypeList === 'translated' ||
$constTypeList === 'unknown' || $buttonType <= 0
) {
$sessionLangDataConstantsIterator = 0;
} elseif (!$langDataSessionContinued) { // session written to file
$sessionLangDataConstantsIterator -= $numberLastPageConstants;
}
// delete old data in session
$this->session->setDataByKey('langfileEditNewLangData', NULL);
$this->session->setDataByKey('langfileEditConstantsList', NULL);
// get language data
if ($constTypeList === 'untranslated') {
$myLangData = array_diff_key($bottomReferenceLanguage, $langEdit);
} elseif ($constTypeList === 'unknown') {
$myLangData = array_diff_key($langEdit, $bottomReferenceLanguage);
} elseif ($constTypeList === 'translated') {
$myLangData = array_intersect_key($bottomReferenceLanguage, $langEdit);
} else {
$myLangData = $bottomReferenceLanguage;
}
$this->session->setDataByKey('langfileEditConstantsList', array_keys($myLangData));
} elseif ($buttonType === 1) { // back button
$sessionLangDataConstantsIterator -= ($numConstantsPerPage + $numberLastPageConstants);
}
// get language constants
$langData = $this->session->getDataByKey('langfileEditConstantsList');
$numConsts = is_countable($langData) ? count($langData) : 0;
if (!(is_countable($langData) ? count($langData) : 0)) {
throw new LFException('failure.select.emptyLangDataArray', 1);
}
$langfileEditNewLangData = $this->session->getDataByKey('langfileEditNewLangData');
if ($langfileEditNewLangData === '') {
$langfileEditNewLangData = [];
}
// prepare constant list for this page
$numberLastPageConstants = 0;
$constValues = [];
do {
// check number of session constants
if ($sessionLangDataConstantsIterator >= $numConsts) {
break;
}
++$numberLastPageConstants;
// set constant value (maybe already changed in this session)
$constant = $langData[$sessionLangDataConstantsIterator];
$editLangVal = $langEdit[$constant] ?? '';
if (!isset($langfileEditNewLangData[$langList][$constant])) {
$langfileEditNewLangData[$langList][$constant] = $editLangVal;
} else {
$editLangVal = $langfileEditNewLangData[$langList][$constant];
}
// set constant value (maybe already changed in this session)
$editPatternVal = $langPattern[$constant] ?? '';
if (!isset($langfileEditNewLangData[$patternList][$constant])) {
$langfileEditNewLangData[$patternList][$constant] = $editPatternVal;
} else {
$editPatternVal =
$langfileEditNewLangData[$patternList][$constant];
}
// save information about the constant
$constValues[$constant]['edit'] = $editLangVal;
$constValues[$constant]['pattern'] = $editPatternVal;
$constValues[$constant]['default'] = $bottomReferenceLanguage[$constant];
} while (++$sessionLangDataConstantsIterator % $numConstantsPerPage);
$this->session->setDataByKey('langfileEditNewLangData', $langfileEditNewLangData);
$this->session->setDataByKey('sessionLangDataConstantsIterator', $sessionLangDataConstantsIterator);
$this->session->setDataByKey('numberLastPageConstants', $numberLastPageConstants);
$this->view->assign('numTextAreaRows', $extConfig['numTextAreaRows']);
$this->view->assign('defaultLanguage', $extConfig['defaultLanguage']);
$this->view->assign('parallelEdit', $parallelEdit);
$this->view->assign('displayBackButton', $sessionLangDataConstantsIterator > $numConstantsPerPage);
$this->view->assign('displayNextButton', $sessionLangDataConstantsIterator < $numConsts);
$this->view->assign('constValues', $constValues);
$this->view->assign('curConsts', $sessionLangDataConstantsIterator);
$this->view->assign('totalConsts', $numConsts);
$this->view->assign('numSiteConstsSelection', $numConstantsPerPage);
}
/**
* Used for the constant type selector
*
* @return array
*/
private function getConstantTypeOptions(): array {
$constantTypeOptions = [];
$constantTypeOptions['all'] = LocalizationUtility::translate('const.type.all', 'lfeditor');
$constantTypeOptions['translated'] = LocalizationUtility::translate('const.type.translated', 'lfeditor');
$constantTypeOptions['unknown'] = LocalizationUtility::translate('const.type.unknown', 'lfeditor');
$constantTypeOptions['untranslated'] = LocalizationUtility::translate('const.type.untranslated', 'lfeditor');
return $constantTypeOptions;
}
/**
* Saves the changes made in main section of editFile view.
*
* @param integer $buttonType
* @param array $editFileTextArea editFileTextArea[{languageSelection}][{constKey}]
* @return \Psr\Http\Message\ResponseInterface|null
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function editFileSaveAction(int $buttonType, array $editFileTextArea): ?\Psr\Http\Message\ResponseInterface {
try {
$languageSelection = $this->session->getDataByKey('languageSelection');
$referenceLanguageSelection = $this->session->getDataByKey('referenceLanguageSelection');
$langDataSessionContinued = $buttonType !== 3;
$langfileEditNewLangData = $this->session->getDataByKey('langfileEditNewLangData');
$langfileEditNewLangData[$languageSelection] =
array_merge(
$langfileEditNewLangData[$languageSelection],
$editFileTextArea[$languageSelection]
);
// parallel edit mode?
if ($referenceLanguageSelection !== '###default###' && $referenceLanguageSelection != $languageSelection) {
$langfileEditNewLangData[$referenceLanguageSelection] =
array_merge(
$langfileEditNewLangData[$referenceLanguageSelection],
$editFileTextArea[$referenceLanguageSelection] ?? []
);
}
$this->session->setDataByKey('langfileEditNewLangData', $langfileEditNewLangData);
// write if no session continued
if (!$langDataSessionContinued) {
// Making array of languages that were changed, so only that language files will be edited.
$editedLanguages = [$languageSelection];
if ($languageSelection !== $referenceLanguageSelection) {
$editedLanguages[] = $referenceLanguageSelection;
}
$this->configurationService->execWrite($langfileEditNewLangData, [], FALSE, $editedLanguages);
$this->addFlashMessage(
LocalizationUtility::translate('lang.file.write.success', 'lfeditor'),
'',
$severity = AbstractMessage::OK,
$storeInSession = TRUE
);
}
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('editFile', NULL, NULL, ['buttonType' => $buttonType]);
return NULL;
} else {
return $this->redirect('editFile', NULL, NULL, ['buttonType' => $buttonType]);
}
}
}

View File

@@ -0,0 +1,302 @@
<?php
namespace SGalinski\Lfeditor\Controller;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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 General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\Lfeditor\Exceptions\LFException;
use SGalinski\Lfeditor\Utility\Functions;
use SGalinski\Lfeditor\Utility\SgLib;
use TYPO3\CMS\Core\Messaging\AbstractMessage;
use TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* General controller. It contains extbase actions for general page.
*/
class GeneralController extends AbstractBackendController {
/** Code for normal split operation */
public const NORMAL_SPLIT = 1;
/** Code for merge operation */
public const MERGE = 2;
/**
* Renders last-opened page. This action ai called upon opening LFEditor.
*
* @param bool $doStateRedirect
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function indexAction($doStateRedirect = TRUE): ?\Psr\Http\Message\ResponseInterface {
if ($doStateRedirect) {
$this->redirectToLastCalledControllerActionPair();
}
$this->resetLastCalledControllerActionPair();
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('general', 'General');
return NULL;
} else {
return $this->redirect('general', 'General');
}
}
/**
* Opens general view.
* It is called in 2 cases:
* - on selection of general option in main menu,
* - after redirection from action which must not change the view.
*
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
public function generalAction(): ?\Psr\Http\Message\ResponseInterface {
try {
$this->view->assign('controllerName', 'General');
$this->prepareExtensionAndLangFileOptions();
if (!$this->session->getDataByKey('languageFileSelection')) {
throw new LFException('failure.select.noLangfile', 1);
}
$this->prepareGeneralViewMainSectionContent();
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
$this->commonViewRenderingActionSettings();
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->view->assign('V11', FALSE);
return NULL;
} else {
$this->view->assign('V11', TRUE);
return $this->createBackendResponse();
}
}
/**
* This action saves in session currently selected options from selection menus in general view.
* It is called on change of selection of any select menu in general view.
*
* @param string $extensionSelection
* @param string $languageFileSelection
* @param string $extKey
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*
*/
public function changeSelectionAction($extensionSelection = NULL, $languageFileSelection = NULL, $extKey = ''): ?\Psr\Http\Message\ResponseInterface {
$this->saveSelectionsInSession(
$extensionSelection,
$languageFileSelection,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
$extKey
);
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('general');
return NULL;
} else {
return $this->redirect('general');
}
}
/**
* Saves the changes made in main section of general view.
*
* @param string $authorName
* @param string $authorEmail
* @param string $metaDescription
* @param string $transformFile
* @param integer $splitFile
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function generalSaveAction(
$authorName = NULL,
$authorEmail = NULL,
$metaDescription = NULL,
$transformFile = NULL,
$splitFile = NULL
): ?\Psr\Http\Message\ResponseInterface {
try {
$metaArray = [
'authorName' => $authorName,
'authorEmail' => $authorEmail,
'description' => $metaDescription
];
$this->configurationService->execWrite([], $metaArray);
// split or merge
if ($transformFile === 'xlf') {
$splitFile = self::NORMAL_SPLIT;
}
if (($splitFile == self::NORMAL_SPLIT || $splitFile == self::MERGE)) {
$langModes = [];
// set vars
if ($splitFile != self::NORMAL_SPLIT && $splitFile != self::MERGE) {
$splitFile = 0;
}
$langKeys = Functions::buildLangArray();
// generate langModes
foreach ($langKeys as $langKey) {
if (!isset($langModes[$langKey])) {
$langModes[$langKey] = $splitFile;
}
}
// exec split or merge
$this->configurationService->execSplitFile($langModes);
// reinitialize file object
$this->configurationService->initFileObject(
$this->session->getDataByKey('languageFileSelection'),
$this->session->getDataByKey('extensionSelection')
);
}
if (!empty($transformFile)
&& $this->configurationService->getFileObj()->getVar('fileType') != $transformFile
) {
$newFile = SgLib::setFileExtension(
$transformFile,
$this->configurationService->getFileObj()->getVar('relFile')
);
$this->configurationService->execTransform($transformFile, $newFile);
$this->clearSelectOptionsCache('extensionAndLangFileOptions');
}
$this->addFlashMessage(
LocalizationUtility::translate('lang.file.write.success', 'lfeditor'),
'',
$severity = AbstractMessage::OK,
$storeInSession = TRUE
);
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('general');
return NULL;
} else {
return $this->redirect('general');
}
}
/**
* Clears extensionAndLangFileOptions cache, and in that way refreshes list of language file options in select box.
*
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function refreshLanguageFileListAction(): ?\Psr\Http\Message\ResponseInterface {
$this->clearSelectOptionsCache('extensionAndLangFileOptions');
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('general');
return NULL;
} else {
return $this->redirect('general');
}
}
/**
* Prepares main section content of general view.
*
* @return void
* @throws LFException
*/
protected function prepareGeneralViewMainSectionContent() {
$this->configurationService->initFileObject(
$this->session->getDataByKey('languageFileSelection'),
$this->session->getDataByKey('extensionSelection')
);
$extConfig = $this->configurationService->getExtConfig();
$referenceLanguageSelection = $extConfig['defaultLanguage'];
$langArray = $this->configurationService->getLangArray($this->backendUser);
$infoArray = Functions::genGeneralInfoArray(
$referenceLanguageSelection,
$langArray,
$this->configurationService->getFileObj()
);
$description = $infoArray['default']['meta']['description'] ?? '';
$langFileExtension = $this->configurationService->getFileObj()->getVar('fileType');
$preselectMerge = $this->isOriginSameForAllLanguages($infoArray);
$this->view->assign('infos', $infoArray);
$this->view->assign('refLangNumTranslated', $infoArray[$referenceLanguageSelection]['numTranslated']);
$this->view->assign('numTextAreaRows', $extConfig['numTextAreaRows']);
$this->view->assign('metaDescription', $description);
$this->view->assign('langFileExtension', $langFileExtension);
$this->view->assign('preselectMerge', $preselectMerge);
}
/**
* Prepares parameters for redirection to viewTreeAction.
*
* @param string $language
* @return \Psr\Http\Message\ResponseInterface|null
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function goToEditFileAction($language): ?\Psr\Http\Message\ResponseInterface {
$this->session->setDataByKey('languageSelection', $language);
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('editFile', 'EditFile');
return NULL;
} else {
return $this->redirect('editFile', 'EditFile');
}
}
/**
* Switches between override mode and normal mode.
*
* @param string $editingMode 'extension', 'l10n', 'override'.
* @return void
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function switchEditingModeAction($editingMode = 'extension') {
$this->session->setDataByKey('editingMode', $editingMode);
$this->indexAction();
}
/**
* Checks do all language translations originate from same file.
*
* @param array $infoArray
* @return bool
*/
private function isOriginSameForAllLanguages(array $infoArray) {
foreach ($infoArray as $langInfo) {
if ($infoArray['default']['origin'] !== $langInfo['origin']) {
return FALSE;
}
}
return TRUE;
}
}

View File

@@ -0,0 +1,500 @@
<?php
namespace SGalinski\Lfeditor\Controller;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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 General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\Lfeditor\Exceptions\LFException;
use SGalinski\Lfeditor\Utility\Functions;
use SGalinski\Lfeditor\Utility\SgLib;
use SGalinski\Lfeditor\Utility\Typo3Lib;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Messaging\AbstractMessage;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* ManageBackups controller. It contains extbase actions for ManageBackups page.
*/
class ManageBackupsController extends AbstractBackendController {
/**
* A constant which is used in backup feature to indicate that
* language constant is added after backup file was made.
*/
public const LANG_CONST_ADDED = 2;
/**
* A constant which is used in backup feature to indicate that
* language constant is deleted after backup file was made.
*/
public const LANG_CONST_DELETED = 1;
/**
* A constant which is used in backup feature to indicate that
* language constant isn't deleted nor added after backup file was made. It was just changed.
*/
public const LANG_CONST_NORMAL = 0;
/**
* Opens manageBackups view.
* It is called in 2 cases:
* - on selection of manageBackups option in main menu,
* - after redirection from action which must not change the view.
*
* @param string $fileName
* @param string $langFile language file which was altered.
* @param bool $showDiff
* @throws \Exception
*/
public function manageBackupsAction($fileName = '', $langFile = '', $showDiff = FALSE): ?\Psr\Http\Message\ResponseInterface {
try {
$this->view->assign('controllerName', 'ManageBackups');
$extensionOptions = $this->configurationService->menuExtList();
$this->assignViewWidthMenuVariables('extension', $extensionOptions);
$this->initializeBackupObject($langFile);
$this->prepareManageBackupsViewMainSectionContent();
if ($showDiff) {
$this->generateDiffContent($fileName);
}
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
$this->commonViewRenderingActionSettings();
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->view->assign('V11', FALSE);
return NULL;
} else {
$this->view->assign('V11', TRUE);
return $this->createBackendResponse();
}
}
/**
* This action saves in session currently selected options from selection menus in manageBackups view.
* It is called on change of selection of any select menu in searchConstant view.
*
* @param string $extensionSelection
* @param string $extKey
*/
public function changeSelectionAction($extensionSelection = NULL, $extKey = ''): ?\Psr\Http\Message\ResponseInterface {
$this->saveSelectionsInSession(
$extensionSelection,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
$extKey
);
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('manageBackups');
return NULL;
} else {
return $this->redirect('manageBackups');
}
}
/**
* Clears extensionAndLangFileOptions cache, and in that way refreshes list of language file options in select box.
*
*/
public function refreshLanguageFileListAction(): ?\Psr\Http\Message\ResponseInterface {
$this->clearSelectOptionsCache('extensionAndLangFileOptions');
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('manageBackups');
return NULL;
} else {
return $this->redirect('manageBackups');
}
}
/**
* Prepares main section content of manageBackupsConstant view.
*
* @throws LFException
*/
protected function prepareManageBackupsViewMainSectionContent() {
$backups = $this->makeBackupsList();
if (empty($backups)) {
$this->addFlashMessage(
LocalizationUtility::translate('failure.backup.noFiles', 'lfeditor'),
'',
$severity = AbstractMessage::NOTICE,
$storeInSession = TRUE
);
return;
}
$recoverLabelThead = strtoupper(
substr(LocalizationUtility::translate('function.backupMgr.recover', 'lfeditor'), 0, 1)
);
$differenceLabelThead = strtoupper(
substr(LocalizationUtility::translate('function.backupMgr.diff.diff', 'lfeditor'), 0, 1)
);
$this->view->assign('backups', $backups);
$this->view->assign('recoverLabelThead', $recoverLabelThead);
$this->view->assign('differenceLabelThead', $differenceLabelThead);
}
/**
* Makes list of backups for use in fluid page.
*
* @return array
*/
protected function makeBackupsList() {
$backups = [];
$metaArray = $this->backupService->getBackupObj()->getMetaInfos(2);
if (is_array($metaArray)) {
$keys = array_keys($metaArray);
foreach ($keys as $langFile) {
foreach ($metaArray[$langFile] as $fileName => $informations) {
$backup = [];
// get path to filename
$backupPath = $informations['pathBackup'];
$pathSite = Environment::getPublicPath() . '/';
$file = Typo3Lib::fixFilePath($pathSite . '/' . $backupPath . '/' . $fileName);
$origFile = Typo3Lib::fixFilePath(
$this->session->getDataByKey('extensionSelection') . '/' . $langFile
);
// check state
if (!is_file($file)) {
$backup['state'] = 'function.backupMgr.missing';
} elseif (!is_file($origFile)) {
$backup['state'] = 'lang.file.missing';
} else {
$backup['state'] = 'function.backupMgr.ok';
}
$backup['date'] = date('Y-m-d H:i:s', $informations['createdAt']);
$backup['langFile'] = $langFile;
$backup['fileName'] = $fileName;
$backups[] = $backup;
}
}
}
return $backups;
}
/**
* Deletes all backups.
*
*/
public function deleteAllBackupAction(): ?\Psr\Http\Message\ResponseInterface {
try {
$this->initializeBackupObject();
$delFiles = [];
$metaArray = $this->backupService->getBackupObj()->getMetaInfos(2);
foreach ($metaArray as $langFile => $metaPiece) {
$files = array_keys($metaPiece);
foreach ($files as $filename) {
$delFiles[$filename] = $langFile;
}
}
$this->backupService->execBackupDelete($delFiles);
$this->addFlashMessage(
LocalizationUtility::translate('function.backupMgr.success.deleteAll', 'lfeditor'),
'',
$severity = AbstractMessage::OK,
$storeInSession = TRUE
);
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('manageBackups');
return NULL;
} else {
return $this->redirect('manageBackups');
}
}
/**
* Deletes backup.
*
* @param string $fileName
* @param string $langFile
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function deleteBackupAction($fileName, $langFile): ?\Psr\Http\Message\ResponseInterface {
try {
$this->initializeBackupObject($langFile);
$delFiles = [];
$delFiles[$fileName] = '';
$this->backupService->execBackupDelete($delFiles);
$this->addFlashMessage(
LocalizationUtility::translate('function.backupMgr.success.delete', 'lfeditor'),
'',
$severity = AbstractMessage::OK,
$storeInSession = TRUE
);
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
$this->redirect('manageBackups');
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('manageBackups');
return NULL;
} else {
return $this->redirect('manageBackups');
}
}
/**
* Uses backup to recover changes.
*
* @param string $fileName
* @param string $langFile
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function recoverBackupAction($fileName, $langFile): ?\Psr\Http\Message\ResponseInterface {
try {
$this->initializeBackupObject($langFile);
// set backup file
$metaArray = $this->backupService->getBackupObj()->getMetaInfos(3);
$pathSite = Environment::getPublicPath() . '/';
$information = [
'absPath' => $pathSite . $metaArray[$fileName]['pathBackup'],
'relFile' => $fileName,
];
$this->backupService->getBackupObj()->setVar($information);
$this->backupService->getBackupObj()->readFile();
// read original file
$this->configurationService->initFileObject(
$this->backupService->getBackupObj()->getVar('langFile'),
Typo3Lib::fixFilePath($pathSite . '/' . $this->backupService->getBackupObj()->getVar('extPath'))
);
// restore
$this->backupService->execBackupRestore();
$this->addFlashMessage(
LocalizationUtility::translate('function.backupMgr.success.restore', 'lfeditor'),
'',
$severity = AbstractMessage::OK,
$storeInSession = TRUE
);
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('manageBackups');
return NULL;
} else {
return $this->redirect('manageBackups');
}
}
/**
* Shows differences between backup and original.
*
* @param string $fileName
* @param string $langFile
* @return \Psr\Http\Message\ResponseInterface|null
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function showDifferenceBackupAction($fileName, $langFile): ?\Psr\Http\Message\ResponseInterface {
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect(
'manageBackups',
NULL,
NULL,
['fileName' => $fileName, 'langFile' => $langFile, 'showDiff' => TRUE]
);
return NULL;
} else {
return $this->redirect(
'manageBackups',
NULL,
NULL,
['fileName' => $fileName, 'langFile' => $langFile, 'showDiff' => TRUE]
);
}
}
/**
* Initializes backup object.
*
* @param string $langFile
* @throws LFException
* @throws \Exception
* @return void
*/
protected function initializeBackupObject($langFile = '') {
$pathSite = Environment::getPublicPath() . '/';
$information = [
'extPath' => SgLib::trimPath($pathSite, $this->session->getDataByKey('extensionSelection')),
'langFile' => $langFile,
];
$this->backupService->initBackupObject('base', $information);
}
/**
* Generates content which illustrates differences between backup and current state.
*
* @param string $fileName
* @return void
*/
protected function generateDiffContent($fileName) {
$localLangDiff = NULL;
$metaDiff = NULL;
$pathSite = Environment::getPublicPath() . '/';
// set backup file
$metaArray = $this->backupService->getBackupObj()->getMetaInfos(3);
$informations = [
'absPath' => Typo3Lib::fixFilePath(
$pathSite . '/' .
$metaArray[$fileName]['pathBackup']
),
'relFile' => $fileName,
];
$this->backupService->getBackupObj()->setVar($informations);
// exec diff
// read original file
$this->configurationService->initFileObject(
$this->backupService->getBackupObj()->getVar('langFile'),
Typo3Lib::fixFilePath($pathSite . '/' . $this->backupService->getBackupObj()->getVar('extPath'))
);
// read backup file
$this->backupService->getBackupObj()->readFile();
// get language data
$originalLocalLang = $this->configurationService->getFileObj()->getLocalLangData();
$backupLocalLang = $this->backupService->getBackupObj()->getLocalLangData();
// get meta data
$origMeta = $this->configurationService->getFileObj()->getMetaData();
$backupMeta = $this->backupService->getBackupObj()->getMetaData();
SgLib::fixMetaAttributes($origMeta);
unset($originalLocalLang['trans-unit']);
$localLangDiff = Functions::getBackupDiff(0, $originalLocalLang, $backupLocalLang);
$metaDiff = Functions::getMetaDiff(0, $origMeta, $backupMeta);
// generate diff
if (is_countable($localLangDiff) ? count($localLangDiff) : 0) {
$this->outputManageBackupsDiff(
$localLangDiff,
$metaDiff,
$originalLocalLang,
$backupLocalLang,
$this->configurationService->getFileObj()->getOriginLangData(),
$this->backupService->getBackupObj()->getOriginLangData(),
$origMeta,
$backupMeta
);
}
}
/**
* Generates output of difference between backup and original.
*
* @param array $diff language content (difference between backup and origin)
* @param array $metaDiff meta content (difference between backup and origin)
* @param array $origLang original language content
* @param array $backupLang backup language content
* @param array $origOriginLang original origins of each language
* @param array $backupOriginLang backup origins of each language
* @param array $origMeta original meta content
* @param array $backupMeta backup meta content
* @return void
*/
protected function outputManageBackupsDiff(
$diff,
$metaDiff,
$origLang,
$backupLang,
$origOriginLang,
$backupOriginLang,
$origMeta,
$backupMeta
) {
$differences = [];
// meta entry
if (count($metaDiff)) {
$difference = [];
$difference['legend'] = LocalizationUtility::translate('function.backupMgr.diff.meta', 'lfeditor');
$difference['constants'] = [];
foreach ($metaDiff as $label => $value) {
$constant = [];
$constant['value'] = $value;
$constant['label'] = $label;
if (!isset($backupMeta[$label])) {
$constant['state'] = self::LANG_CONST_ADDED;
} elseif (!isset($origMeta[$label])) {
$constant['state'] = self::LANG_CONST_DELETED;
} else {
$constant['state'] = self::LANG_CONST_NORMAL;
}
$difference['constants'][] = $constant;
}
$differences[] = $difference;
}
// loop each language entry
foreach ($diff as $langKey => $data) {
$difference = [];
if (!(is_countable($data) ? count($data) : 0) && ($origOriginLang[$langKey] == $backupOriginLang[$langKey])) {
continue;
}
try {
$languageFile = Typo3Lib::transTypo3File($backupOriginLang[$langKey], FALSE);
} catch (\Exception $e) {
$languageFile = $backupOriginLang[$langKey];
}
$difference['legend'] = $langKey . ' (' . $languageFile . ')';
$difference['constants'] = [];
foreach ($data as $label => $value) {
$constant = [];
$constant['value'] = $value;
$constant['label'] = $label;
if (!isset($backupLang[$langKey][$label])) {
$constant['state'] = self::LANG_CONST_ADDED;
} elseif (!isset($origLang[$langKey][$label])) {
$constant['state'] = self::LANG_CONST_DELETED;
} else {
$constant['state'] = self::LANG_CONST_NORMAL;
}
$difference['constants'][] = $constant;
}
$differences[] = $difference;
}
$this->view->assign('differences', $differences);
}
}

View File

@@ -0,0 +1,198 @@
<?php
namespace SGalinski\Lfeditor\Controller;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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 General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\Lfeditor\Exceptions\LFException;
use SGalinski\Lfeditor\Utility\Functions;
use TYPO3\CMS\Core\Messaging\AbstractMessage;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* RenameConstant controller. It contains extbase actions for RenameConstant page.
*/
class RenameConstantController extends AbstractBackendController {
/**
* Opens renameConstant view.
* It is called in 2 cases:
* - on selection of renameConstant option in main menu,
* - after redirection from action which must not change the view.
*
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
public function renameConstantAction(): ?\Psr\Http\Message\ResponseInterface {
try {
$this->view->assign('controllerName', 'RenameConstant');
$this->prepareExtensionAndLangFileOptions();
$this->configurationService->initFileObject(
$this->session->getDataByKey('languageFileSelection'),
$this->session->getDataByKey('extensionSelection')
);
$langData = $this->configurationService->getFileObj()->getLocalLangData();
$constantOptions = $this->configurationService->menuConstList(
$langData,
LocalizationUtility::translate('select.nothing', 'lfeditor')
);
$this->assignViewWidthMenuVariables('constant', $constantOptions);
$this->prepareRenameConstantViewMainSectionContent();
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
$this->commonViewRenderingActionSettings();
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->view->assign('V11', FALSE);
return NULL;
} else {
$this->view->assign('V11', TRUE);
return $this->createBackendResponse();
}
}
/**
* This action saves in session currently selected options from selection menus in renameConstant view.
* It is called on change of selection of any select menu in renameConstant view.
*
* @param string $extensionSelection
* @param string $languageFileSelection
* @param string $constantSelection
* @param string $extKey
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function changeSelectionAction(
$extensionSelection = NULL,
$languageFileSelection = NULL,
$constantSelection = NULL,
$extKey = ''
): ?\Psr\Http\Message\ResponseInterface {
$this->saveSelectionsInSession(
$extensionSelection,
$languageFileSelection,
NULL,
$constantSelection,
NULL,
NULL,
NULL,
NULL,
$extKey
);
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('renameConstant');
return NULL;
} else {
return $this->redirect('renameConstant');
}
}
/**
* Saves the changes made in main section of renameConstant view.
*
* @param string $newConstantName
*/
public function renameConstantSaveAction($newConstantName): ?\Psr\Http\Message\ResponseInterface {
try {
$oldConstantName = $this->session->getDataByKey('constantSelection');
$extConfig = $this->configurationService->getExtConfig();
if ($oldConstantName === $newConstantName) {
throw new LFException('failure.langfile.noChange');
}
$this->configurationService->initFileObject(
$this->session->getDataByKey('languageFileSelection'),
$this->session->getDataByKey('extensionSelection')
);
$langData = $this->configurationService->getFileObj()->getLocalLangData();
$constExists = !empty($langData['default'][$newConstantName])
|| !empty($langData[$extConfig['defaultLanguage']][$newConstantName]);
if ($constExists) {
throw new LFException('failure.langfile.constExists');
}
$langArray = Functions::buildLangArray();
$newLang = [];
foreach ($langArray as $lang) {
if (isset($langData[$lang][$oldConstantName])) {
$newLang[$lang][$newConstantName] = $langData[$lang][$oldConstantName];
}
$newLang[$lang][$oldConstantName] = '';
}
$this->configurationService->execWrite($newLang, [], TRUE);
$this->addFlashMessage(
LocalizationUtility::translate('lang.file.write.success', 'lfeditor'),
'',
$severity = AbstractMessage::OK,
$storeInSession = TRUE
);
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('renameConstant');
return NULL;
} else {
return $this->redirect('renameConstant');
}
}
/**
* Clears extensionAndLangFileOptions cache, and in that way refreshes list of language file options in select box.
*
* @return \Psr\Http\Message\ResponseInterface|null
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function refreshLanguageFileListAction(): ?\Psr\Http\Message\ResponseInterface {
$this->clearSelectOptionsCache('extensionAndLangFileOptions');
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('renameConstant');
return NULL;
} else {
return $this->redirect('renameConstant');
}
}
/**
* Prepares main section content of deleteConstant view.
*
* @throws LFException
* @return void
*/
protected function prepareRenameConstantViewMainSectionContent() {
$constantSelection = $this->session->getDataByKey('constantSelection');
if (empty($constantSelection) || $constantSelection === '###default###') {
throw new LFException('failure.select.noConst', 1);
}
$this->view->assign('constantSelection', $constantSelection);
}
}

View File

@@ -0,0 +1,182 @@
<?php
namespace SGalinski\Lfeditor\Controller;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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 General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\Lfeditor\Exceptions\LFException;
use TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException;
/**
* SearchConstant controller. It contains extbase actions for SearchConstant page.
*/
class SearchConstantController extends AbstractBackendController {
/**
* Opens searchConstant view.
* It is called in 2 cases:
* - on selection of searchConstant option in main menu,
* - after redirection from action which must not change the view.
*
* @param bool $searchDone
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
public function searchConstantAction($searchDone = FALSE): ?\Psr\Http\Message\ResponseInterface {
try {
$this->view->assign('controllerName', 'SearchConstant');
$this->prepareExtensionAndLangFileOptions();
$this->prepareSearchConstantViewMainSectionContent($searchDone);
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
$this->commonViewRenderingActionSettings();
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->view->assign('V11', FALSE);
return NULL;
} else {
$this->view->assign('V11', TRUE);
return $this->createBackendResponse();
}
}
/**
* This action saves in session currently selected options from selection menus in searchConstant view.
* It is called on change of selection of any select menu in searchConstant view.
*
* @param string $extensionSelection
* @param string $languageFileSelection
* @param string $extKey
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function changeSelectionAction($extensionSelection = NULL, $languageFileSelection = NULL, $extKey = ''): ?\Psr\Http\Message\ResponseInterface {
$this->saveSelectionsInSession(
$extensionSelection,
$languageFileSelection,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
$extKey
);
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('searchConstant');
return NULL;
} else {
return $this->redirect('searchConstant');
}
}
/**
* Saves the changes made in main section of searchConstant view.
*
* @param boolean $caseSensitive
* @param string $searchStr
*/
public function searchConstantSearchAction($caseSensitive, $searchStr): ?\Psr\Http\Message\ResponseInterface {
$searchResultArray = [];
try {
$this->configurationService->initFileObject(
$this->session->getDataByKey('languageFileSelection'),
$this->session->getDataByKey('extensionSelection')
);
$langData = $this->configurationService->getFileObj()->getLocalLangData();
$viewLanguages = $this->configurationService->getLangArray($this->backendUser);
$searchOptions = $caseSensitive ? '' : 'i';
if (!preg_match('/^\/.*\/.*$/', $searchStr) && !empty($searchStr)) {
foreach ($viewLanguages as $langKey) {
if (!array_key_exists($langKey, $langData) || !is_array($langData[$langKey])) {
continue;
}
foreach ($langData[$langKey] as $labelKey => $labelValue) {
$labelKeyOrValueContainSearchStr = preg_match(
'/' . $searchStr . '/' . $searchOptions,
$labelKey
) || preg_match('/' . $searchStr . '/' . $searchOptions, $labelValue);
if ($labelKeyOrValueContainSearchStr) {
$searchResultArray[$langKey][$labelKey] = $labelValue;
}
}
}
if (!count($searchResultArray)) {
throw new LFException('failure.search.noConstants', 1);
}
} else {
throw new LFException('function.const.search.enterSearchStr', 1);
}
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
$this->session->setDataByKey('searchResultArray', $searchResultArray);
$this->session->setDataByKey('searchString', $searchStr);
$this->session->setDataByKey('searchCaseSensitive', $caseSensitive);
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('searchConstant', NULL, NULL, ['searchDone' => TRUE]);
return NULL;
} else {
return $this->redirect('searchConstant', NULL, NULL, ['searchDone' => TRUE]);
}
}
/**
* Clears extensionAndLangFileOptions cache, and in that way refreshes list of language file options in select box.
*
*/
public function refreshLanguageFileListAction(): ?\Psr\Http\Message\ResponseInterface {
$this->clearSelectOptionsCache('extensionAndLangFileOptions');
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('searchConstant', NULL, NULL, ['searchDone' => TRUE]);
return NULL;
} else {
return $this->redirect('searchConstant', NULL, NULL, ['searchDone' => TRUE]);
}
}
/**
* Prepares main section content of searchConstant view.
*
* @param bool $searchDone
* @return void
*/
protected function prepareSearchConstantViewMainSectionContent($searchDone) {
$searchResultArray = [];
if ($searchDone) {
$searchResultArray = $this->session->getDataByKey('searchResultArray');
} else {
$this->session->setDataByKey('searchResultArray', []);
}
$searchString = $this->session->getDataByKey('searchString');
$searchCaseSensitive = $this->session->getDataByKey('searchCaseSensitive');
$this->view->assign('searchResultArray', $searchResultArray);
$this->view->assign('searchString', $searchString);
$this->view->assign('searchCaseSensitive', $searchCaseSensitive);
}
}

View File

@@ -0,0 +1,283 @@
<?php
namespace SGalinski\Lfeditor\Controller;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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 General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\Lfeditor\Exceptions\LFException;
use SGalinski\Lfeditor\Utility\Functions;
use TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* ViewTree controller. It contains extbase actions for ViewTree page.
*/
class ViewTreeController extends AbstractBackendController {
/*********************************************
* Actions called from viewTree view *
*********************************************/
/**
* Opens viewTree view.
* It is called in 2 cases:
* - on selection of viewTree option in main menu,
* - after redirection from action which must not change the view.
*
*/
public function viewTreeAction(): ?\Psr\Http\Message\ResponseInterface {
try {
$this->view->assign('controllerName', 'ViewTree');
$this->prepareExtensionAndLangFileOptions();
$this->configurationService->initFileObject(
$this->session->getDataByKey('languageFileSelection'),
$this->session->getDataByKey('extensionSelection')
);
$languageOptions = $this->configurationService->menuLangList(
$this->configurationService->getFileObj()->getLocalLangData(),
'',
$this->backendUser
);
$this->assignViewWidthMenuVariables('language', $languageOptions);
$referenceLanguageOptions = $this->configurationService->menuLangList(
$this->configurationService->getFileObj()->getLocalLangData(),
LocalizationUtility::translate('select.nothing', 'lfeditor'),
$this->backendUser
);
$this->assignViewWidthMenuVariables('referenceLanguage', $referenceLanguageOptions);
$this->prepareViewTreeViewMainSectionContent();
} catch (LFException $e) {
$this->addLFEFlashMessage($e);
}
$this->commonViewRenderingActionSettings();
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->view->assign('V11', FALSE);
return NULL;
} else {
$this->view->assign('V11', TRUE);
return $this->createBackendResponse();
}
}
/**
* This action saves in session currently selected options from selection menus in viewTree view.
* It is called on change of selection of any select menu in viewTree view.
*
* @param string $extensionSelection
* @param string $languageFileSelection
* @param string $languageSelection
* @param string $referenceLanguageSelection
* @param string $extKey
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function changeSelectionAction(
$extensionSelection = NULL,
$languageFileSelection = NULL,
$languageSelection = NULL,
$referenceLanguageSelection = NULL,
$extKey = ''
): ?\Psr\Http\Message\ResponseInterface {
$this->saveSelectionsInSession(
$extensionSelection,
$languageFileSelection,
$referenceLanguageSelection,
NULL,
NULL,
$languageSelection,
NULL,
NULL,
$extKey
);
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('viewTree');
return NULL;
} else {
return $this->redirect('viewTree');
}
}
/**
* Selects explodeToken.
*
* @param string $explodeToken
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
*/
public function selectExplodeTokenAction($explodeToken): ?\Psr\Http\Message\ResponseInterface {
$this->session->setDataByKey('explodeToken', $explodeToken);
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('viewTree');
return NULL;
} else {
return $this->redirect('viewTree');
}
}
/**
* Clears extensionAndLangFileOptions cache, and in that way refreshes list of language file options in select box.
*
*/
public function refreshLanguageFileListAction(): ?\Psr\Http\Message\ResponseInterface {
$this->clearSelectOptionsCache('extensionAndLangFileOptions');
if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
$this->redirect('viewTree');
return NULL;
} else {
return $this->redirect('viewTree');
}
}
/**
* Prepares main section content of viewTree view.
*
*/
protected function prepareViewTreeViewMainSectionContent(): void {
$explodeToken = $this->session->getDataByKey('explodeToken');
if ($explodeToken === "") {
$explodeToken = '.';
}
$langData = $this->configurationService->getFileObj()->getLocalLangData();
$refLangSelection = $this->session->getDataByKey('referenceLanguageSelection');
$languageSelection = $this->session->getDataByKey('languageSelection');
$tree = Functions::genTreeInfoArray($langData[$languageSelection] ?? [], $langData[$refLangSelection] ?? [], $explodeToken);
$extConfig = $this->configurationService->getExtConfig();
$treeHide = $extConfig['treeHide'];
$fluidTree = [];
$levelIndex = 0;
$this->addLevelElementsToFluidTree($tree, $levelIndex, NULL, $fluidTree, $treeHide);
$this->view->assign('fluidTree', $fluidTree);
$this->view->assign('treeHide', $treeHide);
$this->view->assign('explodeToken', $explodeToken);
}
/**
* @var integer Width of margin which is added if a branch is missing.
*/
protected $marginLeftSpaceUnit = 18;
/**
* Makes tree structure which contains constants. The structure is optimised for recursive use on fluid pages.
*
* @param array $sourceTree
* @param int $level
* @param string $parentKey
* @param array $fluidTree This structure is used for setting tree-data for use in fluid.
* @param boolean $treeHide Default state of tree (TRUE - hidden, FALSE - opened)
* @throws LFException
* @return void
*/
protected function addLevelElementsToFluidTree(
array $sourceTree,
int $level,
$parentKey,
array &$fluidTree,
$treeHide
) {
if (empty($sourceTree)) {
throw new LFException('failure.select.emptyLanguage', 1);
}
$constKeys = array_keys($sourceTree[$level]);
$index = 0;
foreach ($sourceTree[$level] as $constKey => $treeNode) {
if ($level === 0 || $treeNode['parent'] === $parentKey) {
$fluidTreeElem = [];
$fluidTreeElem['label'] = $treeNode['name'];
$fluidTreeElem['parent'] = $fluidTree; //$treeNode['parent'];//; //
$fluidTreeElem['type'] = $treeNode['type'] ?? '';
$fluidTreeElem['isBottom'] = (!array_key_exists($index + 1, $constKeys) ||
$sourceTree[$level][$constKeys[$index + 1]]['parent'] !== $treeNode['parent']) ? 1 : 0;
$icons = $this->prepareTreeIcons($level, $treeHide, $fluidTreeElem, isset($treeNode['childs']));
$fluidTreeElem['icons'] = $icons;
if (array_key_exists($level + 1, $sourceTree)) {
$this->addLevelElementsToFluidTree(
$sourceTree,
$level + 1,
$constKey,
$fluidTreeElem,
$treeHide
);
}
if ($level > 0) {
$fluidTree['children'][$constKey] = $fluidTreeElem;
} else {
$fluidTree[$constKey] = $fluidTreeElem;
}
}
$index++;
}
}
/**
* Sorts and adds icons in tree structure.
*
* @param int $level Tree level of constant.
* @param boolean $treeHide Indicator which shows should all tree elements be closed (hidden) by default.
* @param array $fluidTreeElem Element of tree which is built for use on fluid page.
* @param boolean $hasChildren Indicator does this tree element have children
* @return array
*/
protected function prepareTreeIcons(int $level, $treeHide, array $fluidTreeElem, $hasChildren): array {
$icons = [];
$leftMargins = [];
$marginLeftSpaceCounter = 0;
for ($iconLevel = $level, $currentFluidTreeElem = $fluidTreeElem;
$currentFluidTreeElem;
$iconLevel--, $currentFluidTreeElem = $currentFluidTreeElem['parent']) {
$iconName = '.png';
if ($iconLevel === $level) {
if ($currentFluidTreeElem['isBottom']) {
$iconName = 'Bottom' . $iconName;
}
if ($hasChildren) {
$iconName = 'tree' . ($treeHide && $level != 0 ? 'Plus' : 'Minus') . $iconName;
} else {
$iconName = 'join' . $iconName;
}
} else {
if (!$currentFluidTreeElem['isBottom']) {
$iconName = 'line' . $iconName;
$leftMargins[] = $marginLeftSpaceCounter;
$marginLeftSpaceCounter = 0;
} else {
$marginLeftSpaceCounter += $this->marginLeftSpaceUnit;
continue;
}
}
$icons[] = ['name' => $iconName];
}
$leftMargins[] = $marginLeftSpaceCounter;
for ($iterator = 0, $iconsSize = count($icons); $iterator < $iconsSize; $iterator++) {
$icons[$iterator]['marginLeft'] = $leftMargins[$iterator];
}
return $icons;
}
}