Initial commit - Typo3 11.5.41
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace SGalinski\Lfeditor\Utility;
|
||||
|
||||
/***************************************************************
|
||||
* 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!
|
||||
***************************************************************/
|
||||
|
||||
/**
|
||||
* Class which adds CDATA support to SimpleXMLElement.
|
||||
*/
|
||||
class CdataSupportingSimpleXMLElement extends \SimpleXMLElement {
|
||||
/**
|
||||
* Add CDATA text in a node
|
||||
*
|
||||
* @param string $cdataText The CDATA value to add
|
||||
* @return void
|
||||
*/
|
||||
protected function addCData($cdataText) {
|
||||
$node = dom_import_simplexml($this);
|
||||
$no = $node->ownerDocument;
|
||||
$node->appendChild($no->createCDATASection($cdataText));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a child with CDATA value
|
||||
*
|
||||
* @param string $name The name of the child element to add.
|
||||
* @param string $cdataText The CDATA value of the child element.
|
||||
* @return CdataSupportingSimpleXMLElement
|
||||
*/
|
||||
public function addChildCData($name, $cdataText) {
|
||||
/** @var CdataSupportingSimpleXMLElement $child */
|
||||
$child = $this->addChild($name);
|
||||
if ($cdataText !== '') {
|
||||
$child->addCData($cdataText);
|
||||
}
|
||||
return $child;
|
||||
}
|
||||
}
|
||||
46
typo3conf/ext/lfeditor/Classes/Utility/ExtensionUtility.php
Normal file
46
typo3conf/ext/lfeditor/Classes/Utility/ExtensionUtility.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?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\Utility;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
|
||||
|
||||
/**
|
||||
* Class ExtensionUtility
|
||||
*
|
||||
* @package SGalinski\Lfeditor\Utility
|
||||
* @author Kevin Ditscheid <kevin.ditscheid@sgalinski.de>
|
||||
*/
|
||||
class ExtensionUtility {
|
||||
/**
|
||||
* Get the extension configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getExtensionConfiguration(): array {
|
||||
return $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['lfeditor'] ?? [];
|
||||
}
|
||||
}
|
||||
400
typo3conf/ext/lfeditor/Classes/Utility/Functions.php
Normal file
400
typo3conf/ext/lfeditor/Classes/Utility/Functions.php
Normal file
@@ -0,0 +1,400 @@
|
||||
<?php
|
||||
|
||||
namespace SGalinski\Lfeditor\Utility;
|
||||
|
||||
/***************************************************************
|
||||
* 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\Service\FileBasePHPService;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
|
||||
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
|
||||
|
||||
/**
|
||||
* contains functions for the 'lfeditor' extension
|
||||
*/
|
||||
class Functions {
|
||||
/**
|
||||
* Prepares the extension array.
|
||||
*
|
||||
* This function creates the surface of the select box and adds
|
||||
* some additional information to each entry.
|
||||
*
|
||||
* Structure of file array:
|
||||
* $fileArray[textHeader] = further arrays with extension paths
|
||||
*
|
||||
* @param array $fileArray see above
|
||||
* @return array prepared array
|
||||
*/
|
||||
public static function prepareExtList($fileArray) {
|
||||
$myArray = [];
|
||||
foreach ($fileArray as $header => $extPaths) {
|
||||
if (!is_array($extPaths) || !count($extPaths)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unset($prepArray);
|
||||
foreach ($extPaths as $extPath) {
|
||||
$prepArray[$extPath] = basename($extPath);
|
||||
}
|
||||
ksort($prepArray);
|
||||
$myArray = array_merge($myArray, ['###extensionGroup###' . $header => $header], $prepArray);
|
||||
}
|
||||
return $myArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* searches extensions in a given path
|
||||
*
|
||||
* Modes for $state:
|
||||
* 0 - loaded and unloaded
|
||||
* 1 - only loaded
|
||||
* 2 - only unloaded
|
||||
*
|
||||
* @param string $path path
|
||||
* @param integer $state optional: extension state to ignore (see above)
|
||||
* @param string $extIgnoreRegExp optional: directories to ignore (regular expression; pcre with slashes)
|
||||
* @param string $extWhitelistRegExp optional: keep only those directories (regular expression; pcre with slashes)
|
||||
* @return array result of the search
|
||||
* @throws Exception raised, if the given path cant be opened for reading
|
||||
*/
|
||||
public static function searchExtensions($path, $state = 0, $extIgnoreRegExp = '', $extWhitelistRegExp = '') {
|
||||
if (!@$fhd = opendir($path)) {
|
||||
throw new Exception('cant open "' . $path . '"');
|
||||
}
|
||||
|
||||
$path = rtrim($path, '/');
|
||||
$extArray = [];
|
||||
while ($extDir = readdir($fhd)) {
|
||||
$extDirPath = $path . '/' . $extDir;
|
||||
|
||||
// ignore all unless the file is a directory and no point dir
|
||||
if (!is_dir($extDirPath) || preg_match('/^\.{1,2}$/', $extDir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check, if the directory/extension should be saved
|
||||
if (preg_match($extIgnoreRegExp, $extDir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check, if the directory/extension should be saved
|
||||
if ($extWhitelistRegExp !== '' && !preg_match($extWhitelistRegExp, $extDir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// state filter
|
||||
if ($state) {
|
||||
$extState = (int) ExtensionManagementUtility::isLoaded($extDir);
|
||||
if (($extState && $state == 2) || (!$extState && $state == 1)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$extArray[] = $extDirPath;
|
||||
}
|
||||
closedir($fhd);
|
||||
|
||||
return $extArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* prepares a given language string for section output
|
||||
*
|
||||
* @param string $value language string
|
||||
* @return string prepared output in sections
|
||||
*/
|
||||
public static function prepareSectionName($value) {
|
||||
return html_entity_decode(LocalizationUtility::translate($value, 'lfeditor'));
|
||||
}
|
||||
|
||||
/**
|
||||
* checks and returns given languages or TYPO3 language list if the given content was empty
|
||||
*
|
||||
* @param array $languages optional: some language shortcuts
|
||||
* @return array language list
|
||||
*/
|
||||
public static function buildLangArray($languages = NULL) {
|
||||
if (!is_array($languages) || !count($languages)) {
|
||||
return SgLib::getSystemLanguages();
|
||||
} else {
|
||||
return $languages;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generates output for a diff between the backup and original file
|
||||
*
|
||||
* Note that the generated diff will be an array with a normal structure like
|
||||
* any language content array.
|
||||
*
|
||||
* Modes of diffType:
|
||||
* - all changes at the original since the backup was done (0)
|
||||
* - only changes at the original (1)
|
||||
* - only changes at the backup (2)
|
||||
*
|
||||
* @param integer $diffType see above for available modes
|
||||
* @param array $origLang original language data
|
||||
* @param array $backupLocalLang backup language data
|
||||
* @return mixed generated diff
|
||||
*/
|
||||
public static function getBackupDiff($diffType, $origLang, $backupLocalLang) {
|
||||
// get all languages and generate the diff
|
||||
$langKeys = array_merge(array_keys($origLang), array_keys($backupLocalLang));
|
||||
$diff = [];
|
||||
foreach ($langKeys as $langKey) {
|
||||
// prevent warnings
|
||||
if (!is_array($origLang[$langKey])) {
|
||||
$origLang[$langKey] = [];
|
||||
}
|
||||
if (!is_array($backupLocalLang[$langKey])) {
|
||||
$backupLocalLang[$langKey] = [];
|
||||
}
|
||||
$origDiff[$langKey] = [];
|
||||
$backupDiff[$langKey] = [];
|
||||
|
||||
// generate diff
|
||||
if (!$diffType || $diffType == 1) {
|
||||
$origDiff[$langKey] = array_diff_assoc($origLang[$langKey], $backupLocalLang[$langKey]);
|
||||
}
|
||||
if (!$diffType || $diffType == 2) {
|
||||
$backupDiff[$langKey] = array_diff_assoc(
|
||||
$backupLocalLang[$langKey],
|
||||
$origLang[$langKey]
|
||||
);
|
||||
}
|
||||
$diff[$langKey] = array_merge($origDiff[$langKey], $backupDiff[$langKey]);
|
||||
}
|
||||
return $diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* generates output for a meta diff between the backup and original file
|
||||
*
|
||||
* Note that the generated diff will be an array with a normal structure like
|
||||
* any meta content array.
|
||||
*
|
||||
* Modes of diffType:
|
||||
* - all changes at the original since the backup was done (0)
|
||||
* - only changes at the original (1)
|
||||
* - only changes at the backup (2)
|
||||
*
|
||||
* @param integer $diffType see above for available modes
|
||||
* @param array $origMeta original meta data
|
||||
* @param array $backupMeta backup meta data
|
||||
* @return mixed generated diff
|
||||
*/
|
||||
public static function getMetaDiff($diffType, $origMeta, $backupMeta) {
|
||||
$origDiff = [];
|
||||
$backupDiff = [];
|
||||
|
||||
if (!$diffType || $diffType == 1) {
|
||||
$origDiff = array_diff_assoc($origMeta, $backupMeta);
|
||||
}
|
||||
if (!$diffType || $diffType == 2) {
|
||||
$backupDiff = array_diff_assoc($backupMeta, $origMeta);
|
||||
}
|
||||
|
||||
if ($diffType == 1) {
|
||||
return $origDiff;
|
||||
} elseif ($diffType == 2) {
|
||||
return $backupDiff;
|
||||
} else {
|
||||
return array_merge($origDiff, $backupDiff);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generates a general information array
|
||||
*
|
||||
* @param string $refLang reference language
|
||||
* @param array $languages language key array
|
||||
* @param FileBasePHPService $fileObj file object
|
||||
* @return array general information array
|
||||
* @see outputGeneral()
|
||||
*/
|
||||
public static function genGeneralInfoArray($refLang, $languages, $fileObj) {
|
||||
$numTranslated = [];
|
||||
// reference language data information
|
||||
$localRefLangData = $fileObj->getLocalLangData($refLang);
|
||||
|
||||
// generate needed data
|
||||
$infos = [];
|
||||
foreach ($languages as $langKey) {
|
||||
// get origin data and meta information
|
||||
$origin = $fileObj->getOriginLangData($langKey);
|
||||
$infos['default']['meta'] = $fileObj->getMetaData();
|
||||
|
||||
// language data
|
||||
$localLangData = $fileObj->getLocalLangData($langKey);
|
||||
|
||||
// detailed constants information
|
||||
$infos[$langKey]['numUntranslated'] =
|
||||
count(array_diff_key($localRefLangData, $localLangData));
|
||||
$infos[$langKey]['numUnknown'] =
|
||||
count(array_diff_key($localLangData, $localRefLangData));
|
||||
$infos[$langKey]['numTranslated'] =
|
||||
count(array_intersect_key($localLangData, $localRefLangData));
|
||||
|
||||
// set origin
|
||||
try {
|
||||
$infos[$langKey]['origin'] = '[-]';
|
||||
if (!empty($origin)) {
|
||||
$infos[$langKey]['origin'] = Typo3Lib::transTypo3File($origin, FALSE);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$pathSite = Environment::getPublicPath() . '/';
|
||||
$infos[$langKey]['origin'] = SgLib::trimPath($pathSite, $origin);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by numTranslated DESC
|
||||
foreach ($infos as $key => $row) {
|
||||
$numTranslated[$key] = $row['numTranslated'];
|
||||
}
|
||||
array_multisort($numTranslated, SORT_DESC, $infos);
|
||||
|
||||
return $infos;
|
||||
}
|
||||
|
||||
/**
|
||||
* generates a tree information array
|
||||
*
|
||||
* structure:
|
||||
* tree[dimension][branch]['name'] = name of constant
|
||||
* tree[dimension][branch]['type'] = type of constant (0=>normal;1=>untranslated;2=>unknown)
|
||||
* tree[dimension][branch]['parent'] = parentOfBranch (absConstName)
|
||||
* tree[dimension][branch]['childs'] = amount of children
|
||||
*
|
||||
* @param array $langData language data (only one language)
|
||||
* @param array $refLang reference data (only reference language)
|
||||
* @param string $expToken explode token
|
||||
* @return array tree information array
|
||||
*/
|
||||
public static function genTreeInfoArray($langData, $refLang, $expToken) {
|
||||
// reference language
|
||||
$refConsts = [];
|
||||
if (is_array($refLang) && count($refLang)) {
|
||||
$refConsts = array_keys($refLang);
|
||||
}
|
||||
$langConsts = array_merge(array_keys($langData), $refConsts);
|
||||
|
||||
// generate tree information array
|
||||
$curAbsName = '';
|
||||
$tree = [];
|
||||
foreach ($langConsts as $constant) {
|
||||
// add root
|
||||
$tree[0]['Root']['name'] = 'Root';
|
||||
|
||||
// get type
|
||||
$type = 0; // normal
|
||||
if (!in_array($constant, $refConsts)) {
|
||||
$type = 2;
|
||||
} // unknown
|
||||
elseif (empty($langData[$constant])) {
|
||||
$type = 1;
|
||||
} // untranslated
|
||||
|
||||
$branches = explode($expToken, $constant);
|
||||
$numBranches = is_countable($branches) ? count($branches) : 0;
|
||||
for ($i = 0, $curDim = 1; $i < $numBranches; ++$i, ++$curDim) {
|
||||
// get current absolute constant name
|
||||
if (!$i) {
|
||||
$curAbsName = $branches[$i];
|
||||
} else {
|
||||
$curAbsName .= $expToken . $branches[$i];
|
||||
}
|
||||
|
||||
if (isset($tree[$curDim][$curAbsName]['name'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// add branch
|
||||
$tree[$curDim][$curAbsName]['name'] = $branches[$i];
|
||||
$tree[$curDim][$curAbsName]['type'] = $type;
|
||||
|
||||
// set parent
|
||||
if ($i > 0) {
|
||||
$parentAbsName = substr($curAbsName, 0, strrpos($curAbsName, (string) $expToken));
|
||||
} else {
|
||||
$parentAbsName = 'Root';
|
||||
}
|
||||
$tree[$curDim][$curAbsName]['parent'] = $parentAbsName;
|
||||
if (array_key_exists('childs', $tree[$curDim - 1][$parentAbsName])) {
|
||||
++$tree[$curDim - 1][$parentAbsName]['childs'];
|
||||
} else {
|
||||
$tree[$curDim - 1][$parentAbsName]['childs'] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* get best explode token of a given language data
|
||||
*
|
||||
* @param string $curToken current token
|
||||
* @param array $langData some test language data
|
||||
* @return string new token
|
||||
*/
|
||||
public static function getExplodeToken($curToken, $langData) {
|
||||
$ascii = [];
|
||||
// get current token
|
||||
if (!empty($curToken)) {
|
||||
return $curToken;
|
||||
}
|
||||
|
||||
// return default token, if no test data found
|
||||
if (!is_array($langData) || !count($langData)) {
|
||||
return '.';
|
||||
}
|
||||
|
||||
// get ascii codes (possible explode values)
|
||||
$ascii['.'] = ord('.');
|
||||
$ascii['_'] = ord('_');
|
||||
|
||||
// get best possible character of the default language
|
||||
$defKeys = array_keys($langData);
|
||||
$numKeys = count($defKeys);
|
||||
$maxTestCount = ($numKeys >= 10) ? 10 : $numKeys;
|
||||
$counts = [];
|
||||
for ($i = 0; $i < $maxTestCount; ++$i) {
|
||||
$curCounts = count_chars($defKeys[$i], 1);
|
||||
foreach ($ascii as $sign) {
|
||||
$counts[$sign] += $curCounts[$sign];
|
||||
}
|
||||
}
|
||||
|
||||
// get curToken
|
||||
foreach ($counts as $sign => $curCounts) {
|
||||
if ($curCounts > $counts[$curToken]) {
|
||||
$curToken = $sign;
|
||||
}
|
||||
}
|
||||
|
||||
return chr($curToken);
|
||||
}
|
||||
}
|
||||
349
typo3conf/ext/lfeditor/Classes/Utility/SgLib.php
Normal file
349
typo3conf/ext/lfeditor/Classes/Utility/SgLib.php
Normal file
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
|
||||
namespace SGalinski\Lfeditor\Utility;
|
||||
|
||||
/***************************************************************
|
||||
* 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 TYPO3\CMS\Core\Localization\Locales;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* personal library with lots of useful methods
|
||||
*/
|
||||
class SgLib {
|
||||
#################################
|
||||
######## string functions #######
|
||||
#################################
|
||||
|
||||
/**
|
||||
* trims some string from an given path
|
||||
*
|
||||
* @param string $replace string part to delete
|
||||
* @param string $path some path
|
||||
* @param string $prefix some prefix for the new path
|
||||
* @return string new path
|
||||
*/
|
||||
public static function trimPath($replace, $path, $prefix = '') {
|
||||
return trim(str_replace($replace, '', $path), '/') . $prefix;
|
||||
}
|
||||
|
||||
#####################################
|
||||
######## filesystem functions #######
|
||||
#####################################
|
||||
|
||||
/**
|
||||
* reads the extension of a given filename
|
||||
*
|
||||
* @param string $file filename
|
||||
* @return string extension of a given filename
|
||||
*/
|
||||
public static function getFileExtension($file) {
|
||||
return substr($file, strrpos($file, '.') + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* replaces the file extension in a given filename
|
||||
*
|
||||
* @param string $type new file extension
|
||||
* @param string $file filename
|
||||
* @return string new filename
|
||||
*/
|
||||
public static function setFileExtension($type, $file) {
|
||||
return substr($file, 0, strrpos($file, '.') + 1) . $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks write permission of a given file (checks directory permission if file does not exists)
|
||||
*
|
||||
* @param string $file file path
|
||||
* @return boolean true or false
|
||||
*/
|
||||
public static function checkWritePerms($file) {
|
||||
if (!is_file($file)) {
|
||||
$file = dirname($file);
|
||||
}
|
||||
|
||||
if (!is_writable($file)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes given files
|
||||
*
|
||||
* @param array $files files
|
||||
* @return void
|
||||
* @throws Exception raised, if some files cant be deleted (thrown after deletion of all)
|
||||
*/
|
||||
public static function deleteFiles($files) {
|
||||
// delete all old files
|
||||
$error = [];
|
||||
foreach ($files as $file) {
|
||||
if (is_file($file)) {
|
||||
if (!unlink($file)) {
|
||||
$error[] = $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($error)) {
|
||||
throw new Exception('following files cant be deleted: "' . implode(', ', $error) . '"');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a full path (all nonexistent directories will be created)
|
||||
*
|
||||
* @param string $path full path
|
||||
* @param string $protectArea protected path (i.e. /var/www -- needed for basedir restrictions)
|
||||
* @return void
|
||||
* @throws Exception raised if some path token cant be created
|
||||
*/
|
||||
public static function createDir($path, $protectArea) {
|
||||
[$extensionNameFromFile, $extPrefixedPath] = Typo3Lib::getExtNameFromOverrideFile($path);
|
||||
if (strpos($extensionNameFromFile, '-') !== FALSE) {
|
||||
$path = str_replace(
|
||||
$extensionNameFromFile,
|
||||
str_replace('-', '_', $extensionNameFromFile),
|
||||
$path
|
||||
);
|
||||
}
|
||||
if (!is_dir($path)) {
|
||||
$pathAsArray = explode('/', self::trimPath($protectArea, $path));
|
||||
$tmp = '';
|
||||
foreach ($pathAsArray as $dir) {
|
||||
$tmp .= $dir . '/';
|
||||
if (is_dir($protectArea . $tmp)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$concurrentDirectory = $protectArea . $tmp;
|
||||
GeneralUtility::mkdir_deep($concurrentDirectory);
|
||||
if (!is_dir($concurrentDirectory)) {
|
||||
throw new Exception('path "' . $protectArea . $tmp . '" can\'t be created.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes a directory (all subdirectories and files will be deleted)
|
||||
*
|
||||
* @param string $path full path
|
||||
* @return void
|
||||
* @throws Exception raised if a file or directory cant be deleted
|
||||
*/
|
||||
public static function deleteDir($path) {
|
||||
if (!$dh = @opendir($path)) {
|
||||
throw new Exception('directory "' . $path . '" cant be readed');
|
||||
}
|
||||
|
||||
while ($file = readdir($dh)) {
|
||||
$myFile = $path . '/' . $file;
|
||||
|
||||
// ignore links and point directories
|
||||
if (preg_match('/\.{1,2}/', $file) || is_link($myFile)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_file($myFile)) {
|
||||
if (!unlink($myFile)) {
|
||||
throw new Exception('file "' . $myFile . '" cant be deleted');
|
||||
}
|
||||
} elseif (is_dir($myFile)) {
|
||||
SgLib::deleteDir($myFile);
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
|
||||
if (!@rmdir($path)) {
|
||||
throw new Exception('directory "' . $path . '" cant be deleted');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* searches defined files in a given path recursively
|
||||
*
|
||||
* @param string $path search in this path
|
||||
* @param string $searchRegex optional: regular expression for files
|
||||
* @param integer $pathDepth optional: current path depth level (max 9)
|
||||
* @return array
|
||||
* @throws Exception raised if the search directory cant be read
|
||||
*/
|
||||
public static function searchFiles($path, $searchRegex = '', $pathDepth = 0) {
|
||||
// endless recursion protection
|
||||
$fileArray = [];
|
||||
if ($pathDepth >= 9) {
|
||||
return $fileArray;
|
||||
}
|
||||
|
||||
// open directory
|
||||
if (!$fhd = @opendir($path)) {
|
||||
throw new Exception('directory "' . $path . '" cant be read');
|
||||
}
|
||||
|
||||
// iterate through the directory entries
|
||||
while ($file = readdir($fhd)) {
|
||||
$filePath = $path . '/' . $file;
|
||||
|
||||
// ignore links and special directories (. and ..)
|
||||
if (preg_match('/^\.{1,2}$/', $file) || is_link($filePath)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if it's a file and not excluded by the search filter, we can add it
|
||||
// to the file array
|
||||
if (is_file($filePath)) {
|
||||
if ($searchRegex == '') {
|
||||
$fileArray[] = $filePath;
|
||||
} elseif (preg_match($searchRegex, $file)) {
|
||||
$fileArray[] = $filePath;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// next dir
|
||||
if (is_dir($filePath)) {
|
||||
$fileArray = array_merge(
|
||||
$fileArray,
|
||||
(array) SgLib::searchFiles($filePath, $searchRegex, $pathDepth + 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
closedir($fhd);
|
||||
|
||||
return $fileArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all available system languages defined in TYPO3
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getSystemLanguages() {
|
||||
/** @var Locales $locales */
|
||||
$locales = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Localization\Locales::class);
|
||||
$availableLanguageKeys = $locales->getLocales();
|
||||
|
||||
foreach ($availableLanguageKeys as $index => $language) {
|
||||
if ($language === 'default') {
|
||||
$availableLanguageKeys[$index] = 'default';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $availableLanguageKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert special HTML characters to HTML entities, but ignores CDATA section.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function htmlSpecialCharsIgnoringCdata($value) {
|
||||
$cdataStart = strpos($value, '<![CDATA[');
|
||||
$cdataEnd = strpos($value, ']]>');
|
||||
if ($cdataStart !== FALSE && $cdataEnd !== FALSE) {
|
||||
$cdataEnd += 3;
|
||||
$valueBefore = substr($value, 0, $cdataStart);
|
||||
$cdataValue = substr($value, $cdataStart, $cdataEnd - $cdataStart);
|
||||
$valueAfter = substr($value, $cdataEnd, strlen($value) - $cdataEnd);
|
||||
$value = htmlspecialchars($valueBefore) . '<![CDATA[' . $cdataValue . ']]>'
|
||||
. htmlspecialchars($valueAfter);
|
||||
} else {
|
||||
$value = htmlspecialchars($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if CDATA tag exists in string.
|
||||
*
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkForCdataInString($value) {
|
||||
$cdataStart = strpos($value, '<![CDATA[');
|
||||
$cdataEnd = strpos($value, ']]>');
|
||||
return ($cdataStart !== FALSE && $cdataEnd !== FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes at end of PHP file, just before php closing tag or at the end of file if php closing tag does not exist.
|
||||
* If specified file does not exist, it will be crated.
|
||||
*
|
||||
* @param string $filePath
|
||||
* @param string $lineToAdd
|
||||
* @return void
|
||||
*/
|
||||
public static function appendToPHPFile($filePath, $lineToAdd) {
|
||||
if (!is_file($filePath)) {
|
||||
$emptyPhpFileContent = '<?php' . chr(0x0A) . '?>';
|
||||
file_put_contents($filePath, $emptyPhpFileContent);
|
||||
}
|
||||
$configuration = file_get_contents($filePath);
|
||||
if ($configuration === FALSE) {
|
||||
return;
|
||||
}
|
||||
$phpEndTagPosition = strrpos($configuration, '?>');
|
||||
if ($phpEndTagPosition) {
|
||||
$configuration = substr($configuration, 0, $phpEndTagPosition);
|
||||
} else {
|
||||
$configuration .= chr(0x0A);
|
||||
}
|
||||
$configuration .= chr(0x09) . $lineToAdd;
|
||||
if ($phpEndTagPosition) {
|
||||
$configuration .= chr(0x0A) . '?>';
|
||||
}
|
||||
file_put_contents($filePath, $configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two strings ignoring \r character and seeing \n as <br /> in first string.
|
||||
*
|
||||
* @param array|string $string1
|
||||
* @param string $string2
|
||||
* @return bool
|
||||
*/
|
||||
public static function strCmpIgnoreCR($string1, $string2) {
|
||||
return is_string($string1) && str_replace("\r", '', $string1) === $string2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes meta tag '@attributes' to 'attributes', if it exists.
|
||||
*
|
||||
* @param array $origMeta
|
||||
*/
|
||||
public static function fixMetaAttributes(array &$origMeta) {
|
||||
if (isset($origMeta['@attributes'])) {
|
||||
$origMeta['attributes'] = $origMeta['@attributes'];
|
||||
unset($origMeta['@attributes']);
|
||||
}
|
||||
}
|
||||
}
|
||||
186
typo3conf/ext/lfeditor/Classes/Utility/Typo3Lib.php
Normal file
186
typo3conf/ext/lfeditor/Classes/Utility/Typo3Lib.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
namespace SGalinski\Lfeditor\Utility;
|
||||
|
||||
/***************************************************************
|
||||
* 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\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
|
||||
|
||||
/**
|
||||
* includes special typo3 methods
|
||||
*/
|
||||
class Typo3Lib {
|
||||
/**
|
||||
* @deprecated since version 5, will be removed as soon as TYPO3 8 support is dropped
|
||||
*/
|
||||
public const PATH_LOCAL_EXT = 'typo3conf/ext/';
|
||||
|
||||
/**
|
||||
* @deprecated since version 5, will be removed as soon as TYPO3 8 support is dropped
|
||||
*/
|
||||
public const PATH_GLOBAL_EXT = 'typo3/ext/';
|
||||
|
||||
/**
|
||||
* @deprecated since version 5, will be removed as soon as TYPO3 8 support is dropped
|
||||
*/
|
||||
public const PATH_SYS_EXT = 'typo3/sysext/';
|
||||
|
||||
/**
|
||||
* @deprecated since version 5, will be removed as soon as TYPO3 8 support is dropped
|
||||
*/
|
||||
public const PATH_L10N = 'typo3conf/l10n/';
|
||||
|
||||
/**
|
||||
* checks the file location type
|
||||
*
|
||||
* @param string $file
|
||||
* @return string
|
||||
*/
|
||||
public static function checkFileLocation($file) {
|
||||
$pathExtensions = Environment::getExtensionsPath() . '/';
|
||||
|
||||
if (strpos($file, $pathExtensions) !== FALSE) {
|
||||
return 'local';
|
||||
}
|
||||
|
||||
if (strpos($file, self::PATH_GLOBAL_EXT) !== FALSE) {
|
||||
trigger_error(
|
||||
'The typo3/ext folder does not exist anymore, so this functionality will be dropped',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
return 'global';
|
||||
}
|
||||
|
||||
$pathSysExtensions = Environment::getFrameworkBasePath() . '/';
|
||||
|
||||
if (strpos($file, $pathSysExtensions) !== FALSE) {
|
||||
return 'system';
|
||||
}
|
||||
|
||||
$pathL10N = Environment::getLabelsPath() . '/';
|
||||
|
||||
if (strpos($file, $pathL10N) !== FALSE) {
|
||||
return 'l10n';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileRef Absolute path of the language file
|
||||
* @return string Absolute prefix to the language file location
|
||||
*/
|
||||
public static function getLocalizedFilePrefix($fileRef) {
|
||||
// Analyze file reference
|
||||
if (GeneralUtility::isFirstPartOfStr($fileRef, Environment::getFrameworkBasePath() . '/')) {
|
||||
// Is system
|
||||
$validatedPrefix = Environment::getFrameworkBasePath() . '/';
|
||||
} elseif (GeneralUtility::isFirstPartOfStr($fileRef, Environment::getBackendPath() . '/ext/')) {
|
||||
// Is global
|
||||
$validatedPrefix = Environment::getBackendPath() . '/ext/';
|
||||
} elseif (GeneralUtility::isFirstPartOfStr($fileRef, Environment::getExtensionsPath() . '/')) {
|
||||
// Is local
|
||||
$validatedPrefix = Environment::getExtensionsPath() . '/';
|
||||
} else {
|
||||
$validatedPrefix = '';
|
||||
}
|
||||
|
||||
return $validatedPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Absolute path to the l10n directory
|
||||
*/
|
||||
public static function getLabelsPath() {
|
||||
return Environment::getLabelsPath() . '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* converts an absolute or relative typo3 style (EXT:) file path
|
||||
*
|
||||
* @param string $file absolute file or an typo3 relative file (EXT:)
|
||||
* @param boolean $absolute generate to relative(false) or absolute file
|
||||
* @return string converted file path
|
||||
*
|
||||
* @throws \Exception Conversion of file path failed
|
||||
*/
|
||||
public static function transTypo3File($file, $absolute) {
|
||||
$path = GeneralUtility::getFileAbsFileName($file);
|
||||
if (!$absolute) {
|
||||
$fileLocation = self::checkFileLocation($path);
|
||||
if ($fileLocation === 'local') {
|
||||
$pathToRemove = Environment::getExtensionsPath() . '/';
|
||||
} elseif ($fileLocation === 'system') {
|
||||
$pathToRemove = Environment::getFrameworkBasePath() . '/';
|
||||
} else {
|
||||
throw new \Exception('Can not convert absolute file "' . $file . '"');
|
||||
}
|
||||
|
||||
$path = 'EXT:' . SgLib::trimPath($pathToRemove, $path);
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* converts an absolute or relative typo3 style (EXT:) file path
|
||||
*
|
||||
* @param string $file absolute file or an typo3 relative file (EXT:)
|
||||
* @return array converted file path
|
||||
*
|
||||
* @throws \Exception Conversion of file path failed
|
||||
*/
|
||||
public static function getExtNameFromOverrideFile($file) {
|
||||
$absoluteWebPath = Environment::getPublicPath();
|
||||
$prefixedWithSettingsPath = str_replace($absoluteWebPath, '', $file);
|
||||
$alreadyExtPrefixedPath = str_replace('/typo3conf/LFEditor/OverrideFiles/', '', $prefixedWithSettingsPath);
|
||||
$extName = explode('/', $alreadyExtPrefixedPath)[0];
|
||||
return [$extName, 'EXT:' . $alreadyExtPrefixedPath];
|
||||
}
|
||||
|
||||
/**
|
||||
* generates portable file paths
|
||||
*
|
||||
* @param string $file file
|
||||
* @return string fixed file
|
||||
*/
|
||||
public static function fixFilePath($file) {
|
||||
return GeneralUtility::fixWindowsFilePath(str_replace('//', '/', $file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds configuration line to AdditionalConfiguration file.
|
||||
*
|
||||
* @param string $configLine line to be added.
|
||||
* @param string $additionalConfigurationFilePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function writeLineToAdditionalConfiguration($configLine, $additionalConfigurationFilePath) {
|
||||
SgLib::appendToPHPFile($additionalConfigurationFilePath, $configLine);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user