844 lines
25 KiB
PHP
844 lines
25 KiB
PHP
<?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;
|
|
}
|
|
}
|