Initial commit - Typo3 11.5.41
This commit is contained in:
843
typo3conf/ext/lfeditor/Classes/Service/ConfigurationService.php
Normal file
843
typo3conf/ext/lfeditor/Classes/Service/ConfigurationService.php
Normal file
@@ -0,0 +1,843 @@
|
||||
<?php
|
||||
|
||||
namespace SGalinski\Lfeditor\Service;
|
||||
|
||||
/***************************************************************
|
||||
* 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 Exception;
|
||||
use SGalinski\Lfeditor\Exceptions\DirectoryAccessRightsException;
|
||||
use SGalinski\Lfeditor\Exceptions\LFException;
|
||||
use SGalinski\Lfeditor\Utility\ExtensionUtility;
|
||||
use SGalinski\Lfeditor\Utility\Functions;
|
||||
use SGalinski\Lfeditor\Utility\SgLib;
|
||||
use SGalinski\Lfeditor\Utility\Typo3Lib;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Cache\CacheManager;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Localization\Locales;
|
||||
use TYPO3\CMS\Core\Package\PackageInterface;
|
||||
use TYPO3\CMS\Core\Package\PackageManager;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
|
||||
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
|
||||
|
||||
/**
|
||||
* Class ConfigurationService
|
||||
*/
|
||||
class ConfigurationService extends AbstractService {
|
||||
/**
|
||||
* @var array extension configuration
|
||||
* @see prepareConfig()
|
||||
*/
|
||||
protected $extConfig = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $invalidLanguages = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $langArray = [];
|
||||
|
||||
/**
|
||||
* Available editing modes based on extension configuration
|
||||
*
|
||||
* @var array
|
||||
* @see prepareConfig()
|
||||
*/
|
||||
protected $availabledEditingModes = [];
|
||||
|
||||
/**
|
||||
* @var \SGalinski\Lfeditor\Service\FileBaseService
|
||||
*/
|
||||
protected $fileObj;
|
||||
|
||||
/**
|
||||
* @var \SGalinski\Lfeditor\Service\FileBaseService
|
||||
*/
|
||||
protected $convObj;
|
||||
|
||||
/**
|
||||
* @var PackageManager $packageManager
|
||||
*/
|
||||
private $packageManager;
|
||||
|
||||
public function __construct(PackageManager $packageManager) {
|
||||
parent::__construct();
|
||||
$this->packageManager = $packageManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* preparation and check of the configuration
|
||||
*
|
||||
* Note that the default value will be set, if a option check fails.
|
||||
*
|
||||
* @return array
|
||||
* @throws DirectoryAccessRightsException
|
||||
*/
|
||||
public function prepareConfig() {
|
||||
if (!empty($this->extConfig)) {
|
||||
return $this->extConfig;
|
||||
}
|
||||
$this->extConfig = ExtensionUtility::getExtensionConfiguration();
|
||||
|
||||
// regular expressions
|
||||
if (!array_key_exists('searchRegex', $this->extConfig)) {
|
||||
$this->extConfig['searchRegex'] = '/^([a-z0-9_]*locallang[a-z0-9_-]*\.(php|xml)|[^\.]*\.xlf)$/i';
|
||||
} elseif (!\preg_match('/^\/.*\/.*$/', $this->extConfig['searchRegex'])) {
|
||||
$this->extConfig['searchRegex'] = '/^([a-z0-9_]*locallang[a-z0-9_-]*\.(php|xml)|[^\.]*\.xlf)$/i';
|
||||
}
|
||||
|
||||
if (!array_key_exists('searchRegex', $this->extConfig)) {
|
||||
$this->extConfig['extIgnore'] = '/^csh_.*$/';
|
||||
} elseif (!\preg_match('/^\/.*\/.*$/', $this->extConfig['extIgnore'])) {
|
||||
$this->extConfig['extIgnore'] = '/^csh_.*$/';
|
||||
}
|
||||
|
||||
if (!array_key_exists('extWhitelist', $this->extConfig)) {
|
||||
$this->extConfig['extWhitelist'] = '';
|
||||
} elseif (!\preg_match('/^\/.*\/.*$/', $this->extConfig['extWhitelist'])) {
|
||||
$this->extConfig['extWhitelist'] = '';
|
||||
}
|
||||
|
||||
$this->extConfig['execBackup'] = TRUE;
|
||||
$this->extConfig['viewSysExt'] = TRUE;
|
||||
$this->extConfig['viewGlobalExt'] = TRUE;
|
||||
$this->extConfig['viewLocalExt'] = TRUE;
|
||||
$this->extConfig['treeHide'] = TRUE;
|
||||
|
||||
$this->extConfig['viewStateExt'] = 1;
|
||||
$this->extConfig['numTextAreaRows'] = 5;
|
||||
$this->extConfig['numSiteConsts'] = 6;
|
||||
$this->extConfig['anzBackup'] = 5;
|
||||
// Options for number of constants presented on EditFile page
|
||||
$this->extConfig['numSiteConstsOptions']
|
||||
= ['100' => 100, '200' => 200, '500' => 500, '1000' => 1000, '1500' => 1500, '2000' => 2000];
|
||||
|
||||
$pathSite = Environment::getPublicPath() . '/';
|
||||
// paths and files (don't need to exist)
|
||||
$this->extConfig['pathBackup'] = Typo3Lib::fixFilePath(
|
||||
$pathSite . '/typo3temp/LFEditor/Backup/'
|
||||
) . '/';
|
||||
$this->extConfig['metaFile'] = Typo3Lib::fixFilePath(
|
||||
$pathSite . '/typo3temp/LFEditor/Backup/Meta.xml'
|
||||
);
|
||||
$this->extConfig['pathOverrideFiles'] = Typo3Lib::fixFilePath(
|
||||
$pathSite . '/typo3conf/LFEditor/OverrideFiles/'
|
||||
);
|
||||
|
||||
// files
|
||||
$this->extConfig['pathCSS'] = 'Resources/Public/StyleSheets/Lfeditor.css';
|
||||
|
||||
// languages (default is forbidden)
|
||||
if (!empty($this->extConfig['viewLanguages'])) {
|
||||
$langs = GeneralUtility::trimExplode(',', $this->extConfig['viewLanguages'], TRUE);
|
||||
unset($this->extConfig['viewLanguages']);
|
||||
|
||||
$availableLanguageKeys = [];
|
||||
$locales = GeneralUtility::makeInstance(Locales::class);
|
||||
$languages = $locales->getLocales();
|
||||
|
||||
foreach ($languages as $language) {
|
||||
$availableLanguageKeys[$language] = TRUE;
|
||||
}
|
||||
|
||||
foreach ($langs as $lang) {
|
||||
if (!isset($availableLanguageKeys[$lang])) {
|
||||
if ($this->invalidLanguages === '') {
|
||||
$this->invalidLanguages = $lang;
|
||||
} else {
|
||||
$this->invalidLanguages .= ', ' . $lang;
|
||||
}
|
||||
}
|
||||
|
||||
if ($lang !== 'default') {
|
||||
$this->extConfig['viewLanguages'][] = $lang;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->extConfig['defaultLanguage'])) {
|
||||
$this->extConfig['defaultLanguage'] = 'default';
|
||||
} else {
|
||||
/** @var Locales $locales */
|
||||
$locales = GeneralUtility::makeInstance(Locales::class);
|
||||
$availableLanguageKeys = $locales->getLanguages();
|
||||
if (!isset($availableLanguageKeys[$this->extConfig['defaultLanguage']])) {
|
||||
$this->extConfig['defaultLanguage'] = 'default';
|
||||
}
|
||||
}
|
||||
|
||||
// editing modes
|
||||
$this->availabledEditingModes = [
|
||||
'extension' => LocalizationUtility::translate('select.editingMode.extension', 'lfeditor'),
|
||||
// The l10n mode does not work for TYPO3 9 and the var folder and we do not want to fix this, yet
|
||||
//'l10n' => LocalizationUtility::translate('select.editingMode.l10n', 'lfeditor'),
|
||||
// Note: override should be always available because it is the fallback mode for editors
|
||||
'override' => LocalizationUtility::translate('select.editingMode.override', 'lfeditor'),
|
||||
];
|
||||
|
||||
if (isset($this->extConfig['editModeExtension']) && ((int) $this->extConfig['editModeExtension']) === 0) {
|
||||
unset($this->availabledEditingModes['extension']);
|
||||
}
|
||||
if (isset($this->extConfig['editModeL10n']) && ((int) $this->extConfig['editModeL10n']) === 0) {
|
||||
unset($this->availabledEditingModes['l10n']);
|
||||
}
|
||||
|
||||
if (isset($this->extConfig['pathAdditionalConfiguration']) && $this->extConfig['pathAdditionalConfiguration']) {
|
||||
$pathAdditionalConfiguration = Typo3Lib::fixFilePath($this->extConfig['pathAdditionalConfiguration']);
|
||||
$this->extConfig['pathAdditionalConfiguration'] = $pathSite . $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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds extensions for the extension menu selector.
|
||||
*
|
||||
* Note: $this->extConfig must be initialized before call of this method (method prepareConfig() must be executed before this method).
|
||||
*
|
||||
* @return array
|
||||
* @throws LFException raised if no extensions are found
|
||||
*/
|
||||
public function menuExtList() {
|
||||
// search extensions
|
||||
$tmpExtList = [];
|
||||
$pathSite = Environment::getPublicPath() . '/';
|
||||
try {
|
||||
// local extensions
|
||||
|
||||
$labelLocal = LocalizationUtility::translate('ext.local', 'lfeditor');
|
||||
$labelSystem = LocalizationUtility::translate('ext.system', 'lfeditor');
|
||||
$tmpExtList[$labelLocal] = [];
|
||||
$tmpExtList[$labelSystem] = [];
|
||||
foreach ($this->packageManager->getAvailablePackages() as $package) {
|
||||
if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '11.0.0', '<')) {
|
||||
// local extensions
|
||||
if ($this->extConfig['viewLocalExt'] && \count(
|
||||
$content = Functions::searchExtensions(
|
||||
$pathSite . Typo3Lib::PATH_LOCAL_EXT,
|
||||
$this->extConfig['viewStateExt'],
|
||||
$this->extConfig['extIgnore'],
|
||||
$this->extConfig['extWhitelist']
|
||||
)
|
||||
)
|
||||
) {
|
||||
$tmpExtList[LocalizationUtility::translate('ext.local', 'lfeditor')] = $content;
|
||||
}
|
||||
|
||||
// global extensions
|
||||
if ($this->extConfig['viewGlobalExt'] && \is_dir(Typo3Lib::PATH_GLOBAL_EXT) && \count(
|
||||
$content = Functions::searchExtensions(
|
||||
$pathSite . Typo3Lib::PATH_GLOBAL_EXT,
|
||||
$this->extConfig['viewStateExt'],
|
||||
$this->extConfig['extIgnore'],
|
||||
$this->extConfig['extWhitelist']
|
||||
)
|
||||
)
|
||||
) {
|
||||
$tmpExtList[LocalizationUtility::translate('ext.global', 'lfeditor')] = $content;
|
||||
}
|
||||
|
||||
// system extensions
|
||||
if ($this->extConfig['viewSysExt'] && \count(
|
||||
$content = Functions::searchExtensions(
|
||||
$pathSite . Typo3Lib::PATH_SYS_EXT,
|
||||
$this->extConfig['viewStateExt'],
|
||||
$this->extConfig['extIgnore'],
|
||||
$this->extConfig['extWhitelist']
|
||||
)
|
||||
)
|
||||
) {
|
||||
$tmpExtList[LocalizationUtility::translate('ext.system', 'lfeditor')] = $content;
|
||||
}
|
||||
} else {
|
||||
// check, if the directory/extension should be saved
|
||||
if ($this->extConfig['extWhitelist'] !== ''
|
||||
&& !preg_match($this->extConfig['extWhitelist'], $package->getPackageKey())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->extConfig['viewLocalExt'] && $this->isPackageLocal($package)) {
|
||||
$tmpExtList[$labelLocal][] = $package->getPackagePath();
|
||||
}
|
||||
|
||||
if ($this->extConfig['viewSysExt'] && $this->isPackageSystemPackage($package)) {
|
||||
$tmpExtList[$labelSystem][] = $package->getPackagePath();
|
||||
}
|
||||
}
|
||||
}
|
||||
sort($tmpExtList[$labelLocal]);
|
||||
sort($tmpExtList[$labelSystem]);
|
||||
} catch (Exception $e) {
|
||||
throw new LFException('failure.failure', 0, '(' . $e->getMessage() . ')');
|
||||
}
|
||||
|
||||
// check extension array
|
||||
if (!\count($tmpExtList)) {
|
||||
throw new LFException('failure.search.noExtension');
|
||||
}
|
||||
|
||||
// create list
|
||||
$extList = Functions::prepareExtList($tmpExtList);
|
||||
$extList = \array_merge([$pathSite . 'fileadmin' => 'fileadmin/', ''], $extList);
|
||||
|
||||
foreach ($extList as $extAddress => $extLabel) {
|
||||
unset($extList[$extAddress]);
|
||||
$fixedExtAddress = Typo3Lib::fixFilePath($extAddress);
|
||||
$extList[$fixedExtAddress] = $extLabel;
|
||||
}
|
||||
return $extList;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if package is system package
|
||||
*
|
||||
* @param PackageInterface $package
|
||||
* @return bool
|
||||
*/
|
||||
private function isPackageLocal(PackageInterface $package): bool {
|
||||
return $package->getPackageMetaData()->getPackageType() === 'typo3-cms-extension';
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if package is system package
|
||||
*
|
||||
* @param PackageInterface $package
|
||||
* @return bool
|
||||
*/
|
||||
private function isPackageSystemPackage(PackageInterface $package): bool {
|
||||
return $package->getPackageMetaData()->isFrameworkType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds language files of extension which address is passed as $extensionAddress parameter.
|
||||
*
|
||||
* @param string $extensionAddress
|
||||
* @return array
|
||||
* @throws LFException
|
||||
*/
|
||||
public function menuLangFileList($extensionAddress) {
|
||||
// check
|
||||
if (empty($extensionAddress)) {
|
||||
throw new LFException('failure.search.noLangFile', 1);
|
||||
}
|
||||
|
||||
// search and prepare files
|
||||
try {
|
||||
/** @var array $files */
|
||||
$files = SgLib::searchFiles(
|
||||
$extensionAddress,
|
||||
$this->extConfig['searchRegex']
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
throw new LFException(
|
||||
'failure.search.noLangFile',
|
||||
1,
|
||||
'(' . $e->getMessage() . ')'
|
||||
);
|
||||
}
|
||||
|
||||
$fileArray = [];
|
||||
if (\count($files)) {
|
||||
foreach ($files as $file) {
|
||||
$filename = \substr($file, \strlen($extensionAddress) + 1);
|
||||
$fileArray[$filename] = $filename;
|
||||
}
|
||||
} else {
|
||||
throw new LFException('failure.search.noLangFile', 1);
|
||||
}
|
||||
|
||||
return $fileArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for the language menu selector
|
||||
*
|
||||
* @param array $langData language data
|
||||
* @param string $default optional default value (if you dont want a default let it empty)
|
||||
* @param BackendUserAuthentication $backendUser
|
||||
* @param bool $translatedLanguagesOnly looks only for translated languages
|
||||
* @return array
|
||||
* @throws LFException
|
||||
*/
|
||||
public function menuLangList(
|
||||
$langData,
|
||||
$default = '',
|
||||
BackendUserAuthentication $backendUser = NULL,
|
||||
$translatedLanguagesOnly = FALSE
|
||||
) {
|
||||
// build languages
|
||||
$languageArray = $this->getLangArray($backendUser);
|
||||
$languageList = [];
|
||||
foreach ($languageArray as $language) {
|
||||
$constCount = 0;
|
||||
if (array_key_exists($language, $langData) && \is_array($langData[$language])) {
|
||||
$constCount = \count($langData[$language]);
|
||||
}
|
||||
if ($translatedLanguagesOnly && $constCount <= 0) {
|
||||
continue;
|
||||
}
|
||||
$languageLabel = $language;
|
||||
if ($language === 'default') {
|
||||
$languageLabel = 'en';
|
||||
}
|
||||
$languageList[$language] = $languageLabel . ' (' . $constCount . ' ' .
|
||||
LocalizationUtility::translate('const.consts', 'lfeditor') . ')';
|
||||
}
|
||||
|
||||
// add default value
|
||||
if (!empty($default)) {
|
||||
$languageList = \array_merge(['###default###' => $default], $languageList);
|
||||
}
|
||||
return $languageList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list (array) of constants.
|
||||
*
|
||||
* @param array $langData language data
|
||||
* @param string $default name of default entry
|
||||
* @return array
|
||||
*/
|
||||
public function menuConstList($langData, $default) {
|
||||
// generate constant list
|
||||
$constList = [];
|
||||
$languages = Functions::buildLangArray();
|
||||
foreach ($languages as $language) {
|
||||
if (!\array_key_exists($language, $langData) || !\is_array($langData[$language]) || !\count(
|
||||
$langData[$language]
|
||||
)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @var array $constants */
|
||||
$constants = \array_keys($langData[$language]);
|
||||
foreach ($constants as $constant) {
|
||||
$constList[\str_replace('#', '$*-*$', $constant)] = $constant;
|
||||
}
|
||||
}
|
||||
|
||||
// sorting and default entry
|
||||
\asort($constList);
|
||||
$constList = \array_merge(['###default###' => $default], $constList);
|
||||
return $constList;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates and instantiates a file object
|
||||
*
|
||||
* Naming Convention:
|
||||
* File<workspace><filetype>Service
|
||||
*
|
||||
*
|
||||
* @param string $langFile
|
||||
* @param string $extPath
|
||||
* @param bool $flagReadFile
|
||||
* @return void
|
||||
* @throws LFException
|
||||
*/
|
||||
public function initFileObject($langFile, $extPath, $flagReadFile = TRUE) {
|
||||
$fileType = SgLib::getFileExtension($langFile);
|
||||
$className = __NAMESPACE__ . '\FileBase' . \strtoupper($fileType) . 'Service';
|
||||
if (!\class_exists($className)) {
|
||||
throw new LFException('failure.langfile.unknownType');
|
||||
}
|
||||
/** @var \SGalinski\Lfeditor\Service\FileService $originalFileObject */
|
||||
$originalFileObject = GeneralUtility::makeInstance($className);
|
||||
$originalFileObject->init($langFile, $extPath, '');
|
||||
|
||||
try {
|
||||
if ($this->session->getDataByKey('editingMode') === 'override') {
|
||||
/** @var FileOverrideService $overrideFileObj */
|
||||
$overrideFileObj = GeneralUtility::makeInstance(FileOverrideService::class);
|
||||
$overrideFileObj->init($originalFileObject, '', '');
|
||||
$this->fileObj = $overrideFileObj;
|
||||
} else {
|
||||
$this->fileObj = $originalFileObject;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw new LFException('failure.failure', 0, '(' . $e->getMessage() . ')');
|
||||
}
|
||||
|
||||
if ($flagReadFile) {
|
||||
$this->fileObj->readFile();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes writing of language files
|
||||
*
|
||||
*
|
||||
* @param array $modArray changes (constants with empty values will be deleted)
|
||||
* @param array $modMetaArray meta changes (indexes with empty values will be deleted)
|
||||
* @param boolean $forceDel set to true if you want delete default constants
|
||||
* @param array|NULL $editedLanguages
|
||||
* @return void
|
||||
* @throws LFException if file could not be written or some param criteria is not correct
|
||||
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execWrite($modArray, $modMetaArray = [], $forceDel = FALSE, $editedLanguages = NULL) {
|
||||
// checks
|
||||
if (!\is_array($modArray)) {
|
||||
throw new LFException('failure.file.notWritten');
|
||||
}
|
||||
|
||||
$fileObject = $this->getFileObj();
|
||||
if ($fileObject === NULL) {
|
||||
$this->initFileObject(
|
||||
$this->session->getDataByKey('languageFileSelection'),
|
||||
$this->session->getDataByKey('extensionSelection')
|
||||
);
|
||||
$fileObject = $this->getFileObj();
|
||||
}
|
||||
|
||||
// execute backup
|
||||
$extConfig = $this->getExtConfig();
|
||||
if ($extConfig['execBackup'] && $this->session->getDataByKey('editingMode') === 'extension') {
|
||||
/** @var BackupService $backupService */
|
||||
$backupService = GeneralUtility::makeInstance(BackupService::class);
|
||||
$backupService->execBackup();
|
||||
}
|
||||
|
||||
if (!$this->session->getDataByKey('defaultLanguagePermission')) {
|
||||
unset($modArray[$this->extConfig['defaultLanguage']]);
|
||||
}
|
||||
// set new language data
|
||||
foreach ($modArray as $langKey => $data) {
|
||||
if (\is_array($data)) {
|
||||
foreach ($data as $const => $value) {
|
||||
$fileObject->setLocalLangData($const, $value, $langKey, $forceDel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set changed meta data
|
||||
foreach ($modMetaArray as $metaIndex => $metaValue) {
|
||||
$fileObject->setMetaData($metaIndex, $metaValue);
|
||||
}
|
||||
|
||||
// write new language data
|
||||
$fileObject->writeFile($editedLanguages);
|
||||
|
||||
// delete possible language files
|
||||
$absFile = $fileObject->getVar('absFile');
|
||||
$originLang = $fileObject->getOriginLangData();
|
||||
$emptyFiles = [];
|
||||
foreach ($originLang as $lang => $origin) {
|
||||
if ($origin === $absFile || !\is_file($origin)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$langData = $fileObject->getLocalLangData($lang);
|
||||
if (\is_array($langData) && !\count($langData)) {
|
||||
$emptyFiles[] = $origin;
|
||||
}
|
||||
}
|
||||
|
||||
// delete all empty language files
|
||||
try {
|
||||
if (\count($emptyFiles)) {
|
||||
SgLib::deleteFiles($emptyFiles);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw new LFException('failure.langfile.notDeleted', 0, '(' . $e->getMessage() . ')');
|
||||
}
|
||||
|
||||
/** @var CacheManager $cacheManager */
|
||||
$cacheManager = GeneralUtility::makeInstance(CacheManager::class);
|
||||
$cacheManager->getCache('l10n')->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits or merges a language file
|
||||
*
|
||||
* @param array $langModes language shortcuts and their mode (1 = splitNormal, 2 = merge)
|
||||
* @return void
|
||||
* @throws LFException raised if file could not be split or merged (i.e. empty langModes)
|
||||
* @throws Exception|LFException
|
||||
*/
|
||||
public function execSplitFile(array $langModes) {
|
||||
// check
|
||||
if (!\is_array($langModes) || !\count($langModes)) {
|
||||
throw new LFException('failure.langfile.notSplittedOrMerged');
|
||||
}
|
||||
|
||||
// rewrite originLang array
|
||||
$delLangFiles = [];
|
||||
foreach ($langModes as $langKey => $mode) {
|
||||
if ($langKey === 'default') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// get origin of this language
|
||||
$origin = $this->fileObj->getOriginLangData($langKey);
|
||||
|
||||
// split or merge
|
||||
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)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// delete file if was it a l10n file
|
||||
if ($this->fileObj->checkLocalizedFile(\basename($origin), $langKey)) {
|
||||
$delLangFiles[] = $origin;
|
||||
}
|
||||
|
||||
$origin = Typo3Lib::fixFilePath(
|
||||
\dirname($this->fileObj->getVar('absFile')) .
|
||||
'/' . $this->fileObj->nameLocalizedFile($langKey)
|
||||
);
|
||||
} elseif ($mode === 2) {
|
||||
if ($this->fileObj->checkLocalizedFile(\basename($origin), $langKey)) {
|
||||
$delLangFiles[] = $origin;
|
||||
}
|
||||
$origin = $this->fileObj->getVar('absFile');
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
$this->fileObj->setOriginLangData($origin, $langKey);
|
||||
}
|
||||
|
||||
// write new language file
|
||||
$this->execWrite([]);
|
||||
|
||||
// delete old localized files, if single mode was selected
|
||||
try {
|
||||
if (\count($delLangFiles)) {
|
||||
SgLib::deleteFiles($delLangFiles);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw new LFException(
|
||||
'failure.langfile.notDeleted',
|
||||
0,
|
||||
'(' . $e->getMessage() . ')'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* converts language files between different formats
|
||||
*
|
||||
* @param string $type new file format
|
||||
* @param string $newFile new relative file
|
||||
* @return void
|
||||
* @throws Exception|LFException
|
||||
* @throws LFException raised if transforming or deletion of old files failed
|
||||
*/
|
||||
public function execTransform($type, $newFile) {
|
||||
// copy current object to convObj
|
||||
$this->convObj = clone $this->fileObj;
|
||||
unset($this->fileObj);
|
||||
|
||||
// init new language file object (dont try to read file)
|
||||
$this->initFileObject($newFile, $this->convObj->getVar('absPath'), FALSE);
|
||||
|
||||
// recreate originLang
|
||||
$origins = $this->convObj->getOriginLangData();
|
||||
foreach ($origins as $langKey => $file) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
$this->fileObj->setOriginLangData(Typo3Lib::fixFilePath($newFile), $langKey);
|
||||
}
|
||||
|
||||
// recreate meta data
|
||||
$meta = $this->convObj->getMetaData();
|
||||
foreach ($meta as $metaIndex => $metaValue) {
|
||||
$this->fileObj->setMetaData($metaIndex, $metaValue);
|
||||
}
|
||||
|
||||
// write new language file
|
||||
$this->extConfig['execBackup'] = 0;
|
||||
$this->execWrite($this->convObj->getLocalLangData());
|
||||
|
||||
// delete all old files
|
||||
try {
|
||||
$delFiles = $this->convObj->getOriginLangData();
|
||||
if (\is_array($delFiles) && \count($delFiles)) {
|
||||
SgLib::deleteFiles($delFiles);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw new LFException(
|
||||
'failure.langfile.notDeleted',
|
||||
0,
|
||||
'(' . $e->getMessage() . ')'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************
|
||||
* Getters and setters *
|
||||
*************************/
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExtConfig() {
|
||||
return $this->extConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets 'execBackup' parameter of extension configuration.
|
||||
*
|
||||
* @param int $execBackup
|
||||
*/
|
||||
public function setExecBackup($execBackup) {
|
||||
$this->extConfig['execBackup'] = $execBackup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $extConfig
|
||||
*/
|
||||
public function setExtConfig($extConfig) {
|
||||
$this->extConfig = $extConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getInvalidLanguages() {
|
||||
return $this->invalidLanguages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $invalidLanguages
|
||||
*/
|
||||
public function setInvalidLanguages($invalidLanguages) {
|
||||
$this->invalidLanguages = $invalidLanguages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAvailableEditingModes() {
|
||||
return $this->availabledEditingModes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FileBaseService
|
||||
*/
|
||||
public function getFileObj() {
|
||||
return $this->fileObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FileBasePHPService $fileObj
|
||||
*/
|
||||
public function setFileObj($fileObj) {
|
||||
$this->fileObj = $fileObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of system languages.
|
||||
*
|
||||
* @param BackendUserAuthentication $backendUser
|
||||
* @return array
|
||||
* @throws LFException
|
||||
*/
|
||||
public function getLangArray(BackendUserAuthentication $backendUser = NULL) {
|
||||
if ($this->invalidLanguages !== '') {
|
||||
throw new LFException('failure.config.invalidLanguage', 0, $this->invalidLanguages);
|
||||
}
|
||||
|
||||
if (empty($this->langArray)) {
|
||||
$languages = Functions::buildLangArray($this->extConfig['viewLanguages']);
|
||||
$languages = $this->narrowToUserLanguages($languages, $backendUser);
|
||||
|
||||
if (!\in_array('default', $languages, TRUE)) {
|
||||
$languages = \array_merge(['default'], $languages);
|
||||
}
|
||||
if (!\in_array($this->extConfig['defaultLanguage'], $languages, TRUE)) {
|
||||
$languages = \array_merge([$this->extConfig['defaultLanguage']], $languages);
|
||||
}
|
||||
$this->langArray = $languages;
|
||||
}
|
||||
return $this->langArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $langArray
|
||||
*/
|
||||
public function setLangArray($langArray) {
|
||||
$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.
|
||||
*
|
||||
* @param array $languages
|
||||
* @param BackendUserAuthentication $backendUser
|
||||
* @return array
|
||||
*/
|
||||
protected function narrowToUserLanguages(array $languages, BackendUserAuthentication $backendUser) {
|
||||
if ($backendUser !== NULL && !$backendUser->isAdmin()) {
|
||||
$sysLanguageService = GeneralUtility::makeInstance(SysLanguageService::class);
|
||||
foreach ($languages as $index => $languageFlag) {
|
||||
$sysLanguageId = $sysLanguageService->getSysLanguageIdByFlag($languageFlag);
|
||||
if ($languageFlag === 'default'
|
||||
|| ($sysLanguageId !== NULL && $backendUser->checkLanguageAccess($sysLanguageId))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
unset($languages[$index]);
|
||||
}
|
||||
}
|
||||
return $languages;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user