Commit 74b4f85e authored by Rémy DANIEL's avatar Rémy DANIEL Committed by Kevin Ditscheid

[FEATURE] Add option for configuration file location

This commit adds the possibilty to set a different path than
AdditionalConfiguration.php to store the lfeditor language file
overrides.
parent 170f1c69
Pipeline #16 canceled with stages
<?php
/**
*
* 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!
*/
namespace SGalinski\Lfeditor\Exceptions;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* DirectoryAccessRightsException can be thrown for exceptions relating to file access and write permissions
* in directories
*
* @package SGalinski\Lfeditor\Exceptions
* @author Kevin Ditscheid <kevin.ditscheid@sgalinski.de>
*/
class DirectoryAccessRightsException extends \Exception {
/**
* DirectoryAccessRightsException constructor.
*
* @param string $message
* @param int $code
* @param \Exception|NULL $previous
*/
public function __construct($message = '', $code = 0, $previous = NULL) {
if (\strpos($message, 'LLL:') === 0) {
$locallizedMessage = LocalizationUtility::translate($message, 'lfeditor');
$message = $locallizedMessage !== NULL ? $locallizedMessage : $message;
}
if ($message === '') {
$message = 'LFExeption: no error message given !!!';
}
parent::__construct($message, $code, $previous);
}
}
......@@ -27,6 +27,7 @@ namespace SGalinski\Lfeditor\Service;
***************************************************************/
use Exception;
use SGalinski\Lfeditor\Exceptions\DirectoryAccessRightsException;
use SGalinski\Lfeditor\Exceptions\LFException;
use SGalinski\Lfeditor\Utility\Functions;
use SGalinski\Lfeditor\Utility\SgLib;
......@@ -82,20 +83,20 @@ class ConfigurationService extends AbstractService {
* Note that the default value will be set, if a option check fails.
*
* @return array
* @throws \InvalidArgumentException
* @throws DirectoryAccessRightsException
*/
public function prepareConfig() {
if (!empty($this->extConfig)) {
return $this->extConfig;
}
$this->extConfig = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['lfeditor'], []);
$this->extConfig = \unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['lfeditor'], []);
// regular expressions
if (!preg_match('/^\/.*\/.*$/', $this->extConfig['searchRegex'])) {
if (!\preg_match('/^\/.*\/.*$/', $this->extConfig['searchRegex'])) {
$this->extConfig['searchRegex'] = '/^([a-z0-9_]*locallang[a-z0-9_-]*\.(php|xml)|[^\.]*\.xlf)$/i';
}
if (!preg_match('/^\/.*\/.*$/', $this->extConfig['extIgnore'])) {
if (!\preg_match('/^\/.*\/.*$/', $this->extConfig['extIgnore'])) {
$this->extConfig['extIgnore'] = '/^csh_.*$/';
}
......@@ -183,6 +184,22 @@ class ConfigurationService extends AbstractService {
unset($this->availabledEditingModes['l10n']);
}
if (isset($this->extConfig['pathAdditionalConfiguration']) && $this->extConfig['pathAdditionalConfiguration']) {
$pathAdditionalConfiguration = Typo3Lib::fixFilePath($this->extConfig['pathAdditionalConfiguration']);
$this->extConfig['pathAdditionalConfiguration'] = \realpath(PATH_site . $pathAdditionalConfiguration);
$additionalConfigurationDirectory = \dirname($this->extConfig['pathAdditionalConfiguration']);
if (!\is_writable($additionalConfigurationDirectory)) {
$message = 'Directory ' . $additionalConfigurationDirectory . ' is not writable.'
. 'This directory should be writable in order to write the language override configuration '
. 'file ' . $pathAdditionalConfiguration;
throw new DirectoryAccessRightsException($message);
}
} else {
/** @var \TYPO3\CMS\Core\Configuration\ConfigurationManager $configurationManager */
$configurationManager = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
$this->extConfig['pathAdditionalConfiguration'] = $configurationManager->getAdditionalConfigurationFileLocation();
}
return $this->extConfig;
}
......@@ -212,7 +229,7 @@ class ConfigurationService extends AbstractService {
}
// global extensions
if ($this->extConfig['viewGlobalExt'] && is_dir(Typo3Lib::PATH_GLOBAL_EXT)) {
if ($this->extConfig['viewGlobalExt'] && \is_dir(Typo3Lib::PATH_GLOBAL_EXT)) {
if (\count(
$content = Functions::searchExtensions(
PATH_site . Typo3Lib::PATH_GLOBAL_EXT, $this->extConfig['viewStateExt'],
......@@ -248,7 +265,7 @@ class ConfigurationService extends AbstractService {
// create list
/** @var array $extList */
$extList = Functions::prepareExtList($tmpExtList);
$extList = array_merge([PATH_site . 'fileadmin' => 'fileadmin/', ''], $extList);
$extList = \array_merge([PATH_site . 'fileadmin' => 'fileadmin/', ''], $extList);
foreach ($extList as $extAddress => $extLabel) {
unset ($extList[$extAddress]);
......@@ -286,9 +303,9 @@ class ConfigurationService extends AbstractService {
}
$fileArray = [];
if (count($files)) {
if (\count($files)) {
foreach ($files as $file) {
$filename = substr($file, strlen($extensionAddress) + 1);
$filename = \substr($file, \strlen($extensionAddress) + 1);
$fileArray[$filename] = $filename;
}
} else {
......@@ -316,8 +333,8 @@ class ConfigurationService extends AbstractService {
$languageList = [];
foreach ($languageArray as $language) {
$constCount = 0;
if (is_array($langData[$language])) {
$constCount = count($langData[$language]);
if (\is_array($langData[$language])) {
$constCount = \count($langData[$language]);
}
if ($translatedLanguagesOnly && $constCount <= 0) {
continue;
......@@ -332,7 +349,7 @@ class ConfigurationService extends AbstractService {
// add default value
if (!empty($default)) {
$languageList = array_merge(['###default###' => $default], $languageList);
$languageList = \array_merge(['###default###' => $default], $languageList);
}
return $languageList;
}
......@@ -349,20 +366,20 @@ class ConfigurationService extends AbstractService {
$constList = [];
$languages = Functions::buildLangArray();
foreach ($languages as $language) {
if (!is_array($langData[$language]) || !count($langData[$language])) {
if (!\is_array($langData[$language]) || !\count($langData[$language])) {
continue;
}
/** @var array $constants */
$constants = array_keys($langData[$language]);
$constants = \array_keys($langData[$language]);
foreach ($constants as $constant) {
$constList[str_replace('#', '$*-*$', $constant)] = $constant;
$constList[\str_replace('#', '$*-*$', $constant)] = $constant;
}
}
// sorting and default entry
asort($constList);
$constList = array_merge(['###default###' => $default], $constList);
\asort($constList);
$constList = \array_merge(['###default###' => $default], $constList);
return $constList;
}
......@@ -381,8 +398,8 @@ class ConfigurationService extends AbstractService {
*/
public function initFileObject($langFile, $extPath, $flagReadFile = TRUE) {
$fileType = SgLib::getFileExtension($langFile);
$className = __NAMESPACE__ . '\FileBase' . strtoupper($fileType) . 'Service';
if (!class_exists($className)) {
$className = __NAMESPACE__ . '\FileBase' . \strtoupper($fileType) . 'Service';
if (!\class_exists($className)) {
throw new LFException('failure.langfile.unknownType');
}
/** @var \SGalinski\Lfeditor\Service\FileService $originalFileObject */
......@@ -422,7 +439,7 @@ class ConfigurationService extends AbstractService {
*/
public function execWrite($modArray, $modMetaArray = [], $forceDel = FALSE, $editedLanguages = NULL) {
// checks
if (!is_array($modArray)) {
if (!\is_array($modArray)) {
throw new LFException('failure.file.notWritten');
}
......@@ -448,7 +465,7 @@ class ConfigurationService extends AbstractService {
}
// set new language data
foreach ($modArray as $langKey => $data) {
if (is_array($data)) {
if (\is_array($data)) {
foreach ($data as $const => $value) {
$fileObject->setLocalLangData($const, $value, $langKey, $forceDel);
}
......@@ -468,19 +485,19 @@ class ConfigurationService extends AbstractService {
$originLang = $fileObject->getOriginLangData();
$emptyFiles = [];
foreach ($originLang as $lang => $origin) {
if ($origin == $absFile || !is_file($origin)) {
if ($origin == $absFile || !\is_file($origin)) {
continue;
}
$langData = $fileObject->getLocalLangData($lang);
if (is_array($langData) && !count($langData)) {
if (\is_array($langData) && !\count($langData)) {
$emptyFiles[] = $origin;
}
}
// delete all empty language files
try {
if (count($emptyFiles)) {
if (\count($emptyFiles)) {
SgLib::deleteFiles($emptyFiles);
}
} catch (Exception $e) {
......@@ -502,7 +519,7 @@ class ConfigurationService extends AbstractService {
*/
public function execSplitFile(array $langModes) {
// check
if (!is_array($langModes) || !count($langModes)) {
if (!\is_array($langModes) || !\count($langModes)) {
throw new LFException('failure.langfile.notSplittedOrMerged');
}
......@@ -520,22 +537,22 @@ class ConfigurationService extends AbstractService {
if ($mode === 1) {
// nothing to do if the file is already a normal splitted file
if (Typo3Lib::checkFileLocation($origin) != 'l10n') {
if ($this->fileObj->checkLocalizedFile(basename($origin), $langKey)) {
if ($this->fileObj->checkLocalizedFile(\basename($origin), $langKey)) {
continue;
}
}
// delete file if was it a l10n file
if ($this->fileObj->checkLocalizedFile(basename($origin), $langKey)) {
if ($this->fileObj->checkLocalizedFile(\basename($origin), $langKey)) {
$delLangFiles[] = $origin;
}
$origin = Typo3Lib::fixFilePath(
dirname($this->fileObj->getVar('absFile')) .
\dirname($this->fileObj->getVar('absFile')) .
'/' . $this->fileObj->nameLocalizedFile($langKey)
);
} elseif ($mode === 2) {
if ($this->fileObj->checkLocalizedFile(basename($origin), $langKey)) {
if ($this->fileObj->checkLocalizedFile(\basename($origin), $langKey)) {
$delLangFiles[] = $origin;
}
$origin = $this->fileObj->getVar('absFile');
......@@ -550,7 +567,7 @@ class ConfigurationService extends AbstractService {
// delete old localized files, if single mode was selected
try {
if (count($delLangFiles)) {
if (\count($delLangFiles)) {
SgLib::deleteFiles($delLangFiles);
}
} catch (Exception $e) {
......@@ -584,8 +601,8 @@ class ConfigurationService extends AbstractService {
// localized or merged language origin
$newFile = SgLib::setFileExtension($type, $file);
if ($this->convObj->getVar('workspace') == 'base') {
if ($this->convObj->checkLocalizedFile(basename($file), $langKey)) {
$newFile = dirname($file) . '/' . $this->fileObj->nameLocalizedFile($langKey);
if ($this->convObj->checkLocalizedFile(\basename($file), $langKey)) {
$newFile = \dirname($file) . '/' . $this->fileObj->nameLocalizedFile($langKey);
}
}
$this->fileObj->setOriginLangData(Typo3Lib::fixFilePath($newFile), $langKey);
......@@ -604,7 +621,7 @@ class ConfigurationService extends AbstractService {
// delete all old files
try {
$delFiles = $this->convObj->getOriginLangData();
if (is_array($delFiles) && count($delFiles)) {
if (\is_array($delFiles) && \count($delFiles)) {
SgLib::deleteFiles($delFiles);
}
} catch (Exception $e) {
......@@ -707,11 +724,11 @@ class ConfigurationService extends AbstractService {
$languages = Functions::buildLangArray($this->extConfig['viewLanguages']);
$languages = $this->narrowToUserLanguages($languages, $backendUser);
if (!in_array('default', $languages)) {
$languages = array_merge(['default'], $languages);
if (!\in_array('default', $languages)) {
$languages = \array_merge(['default'], $languages);
}
if (!in_array($this->extConfig['defaultLanguage'], $languages)) {
$languages = array_merge([$this->extConfig['defaultLanguage']], $languages);
if (!\in_array($this->extConfig['defaultLanguage'], $languages)) {
$languages = \array_merge([$this->extConfig['defaultLanguage']], $languages);
}
$this->langArray = $languages;
}
......@@ -725,6 +742,15 @@ class ConfigurationService extends AbstractService {
$this->langArray = $langArray;
}
/**
* Return the path to the configured AdditionalConfiguration.php file
*
* @return string
*/
public function getAdditionalConfigurationFilePath() {
return $this->extConfig['pathAdditionalConfiguration'];
}
/**
* Narrows $languages to user languages if user is not admin.
*
......
......@@ -161,10 +161,14 @@ class FileOverrideService extends FileBaseXMLService {
return;
}
/** @var ConfigurationService $configurationService */
$configurationService = $this->objectManager->get( ConfigurationService::class );
$additionalConfigurationFilePath = $configurationService->getAdditionalConfigurationFilePath();
try {
$addLine = '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'locallangXMLOverride\'][\''
. $typo3ExtRelativeFilePath . '\'][0] = \'' . $relativeOverrideFilePath . '\';';
Typo3Lib::writeLineToAdditionalConfiguration($addLine);
Typo3Lib::writeLineToAdditionalConfiguration( $addLine, $additionalConfigurationFilePath );
$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'][$typo3ExtRelativeFilePath][0]
= $relativeOverrideFilePath;
} catch (\Exception $exception) {
......
......@@ -124,16 +124,14 @@ class Typo3Lib {
}
/**
* Adds configuration line to AdditionalConfiguration.php.
* Adds configuration line to AdditionalConfiguration file.
*
* @param string $configLine line to be added.
* @param string $additionalConfigurationFilePath
*
* @return void
* @throws \InvalidArgumentException
*/
public static function writeLineToAdditionalConfiguration($configLine) {
/** @var ConfigurationManager $configurationManager */
$configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class);
$additionalConfigurationFilePath = $configurationManager->getAdditionalConfigurationFileLocation();
public static function writeLineToAdditionalConfiguration($configLine, $additionalConfigurationFilePath) {
SgLib::appendToPHPFile($additionalConfigurationFilePath, $configLine);
}
}
......@@ -20,3 +20,6 @@ editModeExtension = 1
# cat=basic; type=boolean; label=Allow edit mode "l10n"
editModeL10n = 1
# cat=basic; type=string; label=Path to AdditionalConfiguration.php file: It is possible to change the file where locallangXMLOverride will be declared. Relative to the document root. If modified, don't forget then to include the custom file path from the AdditionalConfiguration.php.
pathAdditionalConfiguration = typo3conf/AdditionalConfiguration.php
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment