Initial commit - Typo3 11.5.41
This commit is contained in:
478
typo3conf/ext/lfeditor/Classes/Service/FileBackupService.php
Normal file
478
typo3conf/ext/lfeditor/Classes/Service/FileBackupService.php
Normal file
@@ -0,0 +1,478 @@
|
||||
<?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\LFException;
|
||||
use SGalinski\Lfeditor\Utility\SgLib;
|
||||
use SGalinski\Lfeditor\Utility\Typo3Lib;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
|
||||
|
||||
/**
|
||||
* backup class
|
||||
*/
|
||||
class FileBackupService extends FileService {
|
||||
/**
|
||||
* @var string $metaFile
|
||||
*/
|
||||
private $metaFile;
|
||||
|
||||
/**
|
||||
* @var array $metaArray
|
||||
*/
|
||||
private $metaArray = [];
|
||||
|
||||
/**
|
||||
* @var string $extName
|
||||
*/
|
||||
private $extName = '';
|
||||
|
||||
/**
|
||||
* @var string $extPath
|
||||
*/
|
||||
private $extPath = '';
|
||||
|
||||
/**
|
||||
* @var string $langFile
|
||||
*/
|
||||
private $langFile = '';
|
||||
|
||||
/**
|
||||
* extended init
|
||||
*
|
||||
* @throws LFException raised if the meta file cant be correctly read
|
||||
* @param string $file name of the file (can be a path, if you need this (no check))
|
||||
* @param string $path path to the file
|
||||
* @param string $metaFile absolute path to the meta file (includes filename)
|
||||
* @return void
|
||||
*/
|
||||
public function init($file, $path, $metaFile) {
|
||||
// init
|
||||
$this->setVar(['metaFile' => $metaFile]);
|
||||
parent::init($file, $path, $metaFile);
|
||||
|
||||
// read meta file
|
||||
try {
|
||||
if (is_file($this->metaFile)) {
|
||||
$this->readMetaFile();
|
||||
}
|
||||
} catch (LFException $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
#####################
|
||||
###### Set/Get ######
|
||||
#####################
|
||||
|
||||
/**
|
||||
* sets information
|
||||
*
|
||||
* structure:
|
||||
* $infos["metaFile"] = absolute path to the meta file (includes filename)
|
||||
* $infos["extPath"] = extension path
|
||||
* $infos["langFile"] = language file
|
||||
*
|
||||
* @param array $informations information (see above)
|
||||
* @return void
|
||||
*/
|
||||
public function setVar($informations) {
|
||||
if (!empty($informations['metaFile'])) {
|
||||
$this->metaFile = Typo3Lib::fixFilePath($informations['metaFile']);
|
||||
}
|
||||
|
||||
if (!empty($informations['extPath'])) {
|
||||
$this->extPath = Typo3Lib::fixFilePath($informations['extPath']);
|
||||
$this->extName = basename($informations['extPath']);
|
||||
}
|
||||
|
||||
if (!empty($informations['langFile'])) {
|
||||
$this->langFile = Typo3Lib::fixFilePath($informations['langFile']);
|
||||
}
|
||||
|
||||
parent::setVar($informations);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns requested information
|
||||
*
|
||||
* @param string $info
|
||||
* @return mixed
|
||||
*/
|
||||
public function getVar($info) {
|
||||
if ($info == 'metaFile') {
|
||||
return $this->metaFile;
|
||||
} elseif ($info == 'extName') {
|
||||
return $this->extName;
|
||||
} elseif ($info == 'extPath') {
|
||||
return $this->extPath;
|
||||
} elseif ($info == 'langFile') {
|
||||
return $this->langFile;
|
||||
} else {
|
||||
return parent::getVar($info);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns meta information about backup files
|
||||
*
|
||||
* Modes:
|
||||
* - 0 => full meta information (default)
|
||||
* - 1 => only meta information of given extension key
|
||||
* - 2 => only meta information of given extension key and workspace
|
||||
* - 3 => only meta information of given extension key, workspace and language file
|
||||
*
|
||||
* @param integer $mode
|
||||
* @param string $extName extension Name (default = $this->extName)
|
||||
* @param string $workspace (default = $this->workspace)
|
||||
* @param string $langFile language file (default = $this->langFile)
|
||||
* @return array
|
||||
*/
|
||||
public function getMetaInfos($mode = 0, $extName = '', $workspace = '', $langFile = '') {
|
||||
$extName = empty($extName) ? $this->extName : $extName;
|
||||
$langFile = empty($langFile) ? $this->langFile : $langFile;
|
||||
$workspace = empty($workspace) ? $this->workspace : $workspace;
|
||||
|
||||
// build return value
|
||||
if (!$mode) {
|
||||
return $this->metaArray;
|
||||
} elseif ($mode == 1) {
|
||||
return $this->metaArray[$extName] ?? [];
|
||||
} elseif ($mode == 2) {
|
||||
return $this->metaArray[$extName][$workspace] ?? [];
|
||||
} elseif ($mode == 3) {
|
||||
return $this->metaArray[$extName][$workspace][$langFile] ?? [];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rewrites current meta information array with the given equivalent
|
||||
*
|
||||
* Modes:
|
||||
* - 0 => full meta information (default)
|
||||
* - 1 => only meta information of given extension key
|
||||
* - 2 => only meta information of given extension key and workspace
|
||||
* - 3 => only meta information of given extension key, workspace and language file
|
||||
*
|
||||
* @param array $metaArray meta information
|
||||
* @param integer $mode
|
||||
* @param string $extName extension Name (default = $this->extName)
|
||||
* @param string $workspace (default = $this->workspace)
|
||||
* @param string $langFile language file (default = $this->langFile)
|
||||
* @return void
|
||||
*/
|
||||
private function setMetaInfos($metaArray, $mode = 0, $extName = '', $workspace = '', $langFile = '') {
|
||||
$extName = empty($extName) ? $this->extName : $extName;
|
||||
$langFile = empty($langFile) ? $this->langFile : $langFile;
|
||||
$workspace = empty($workspace) ? $this->workspace : $workspace;
|
||||
|
||||
// build new meta information array
|
||||
if (is_array($metaArray) && count($metaArray)) {
|
||||
if (!$mode) {
|
||||
$this->metaArray = $metaArray;
|
||||
} elseif ($mode == 1) {
|
||||
$this->metaArray[$extName] = $metaArray;
|
||||
} elseif ($mode == 2) {
|
||||
$this->metaArray[$extName][$workspace] = $metaArray;
|
||||
} elseif ($mode == 3) {
|
||||
$this->metaArray[$extName][$workspace][$langFile] = $metaArray;
|
||||
}
|
||||
} else {
|
||||
if (!$mode) {
|
||||
unset($this->metaArray);
|
||||
} elseif ($mode == 1) {
|
||||
unset($this->metaArray[$extName]);
|
||||
} elseif ($mode == 2) {
|
||||
unset($this->metaArray[$extName][$workspace]);
|
||||
} elseif ($mode == 3) {
|
||||
unset($this->metaArray[$extName][$workspace][$langFile]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
###############################
|
||||
###### Meta FileService Methods ######
|
||||
###############################
|
||||
|
||||
/**
|
||||
* reads the meta information file and parses the content into $this->metaArray
|
||||
*
|
||||
* @throws LFException raised if no meta content was generated
|
||||
* @return void
|
||||
*/
|
||||
private function readMetaFile() {
|
||||
// read file and parse xml to array
|
||||
$metaArray = GeneralUtility::xml2array(file_get_contents($this->metaFile));
|
||||
if (!is_array($metaArray)) {
|
||||
throw new LFException('failure.backup.metaFile.notRead');
|
||||
}
|
||||
|
||||
$this->metaArray = $metaArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate meta XML
|
||||
*
|
||||
* @return string meta information (xml)
|
||||
*/
|
||||
private function genMetaXML() {
|
||||
$options = [];
|
||||
// define assocTagNames
|
||||
$options['parentTagMap'] = [
|
||||
'' => 'extKey',
|
||||
'extKey' => 'workspace',
|
||||
'workspace' => 'langFile',
|
||||
'langFile' => 'file',
|
||||
];
|
||||
return GeneralUtility::array2xml($this->getMetaInfos(), '', 0, 'LFBackupMeta', 0, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the meta information file
|
||||
*
|
||||
* @throws LFException raised if the meta file cant be written
|
||||
* @return void
|
||||
*/
|
||||
private function writeMetaFile() {
|
||||
$metaXML = $this->genMetaXML();
|
||||
if (empty($metaXML)) {
|
||||
throw new LFException('failure.backup.metaFile.notWritten');
|
||||
}
|
||||
|
||||
if (!GeneralUtility::writeFile($this->metaFile, $this->getXMLHeader() . $metaXML)) {
|
||||
throw new LFException('failure.backup.metaFile.notWritten');
|
||||
}
|
||||
}
|
||||
|
||||
#################################
|
||||
###### Backup FileService Methods ######
|
||||
#################################
|
||||
|
||||
/**
|
||||
* generates the xml header
|
||||
*
|
||||
* @return string xml header
|
||||
*/
|
||||
private function getXMLHeader() {
|
||||
return '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>' . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* removes the meta information entry and the backup file
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $extName (default = $this->extName)
|
||||
* @param string $langFile (default = $this->langFile)
|
||||
* @throws Exception|LFException
|
||||
* @throws LFException
|
||||
* @return void
|
||||
*/
|
||||
public function deleteSpecFile($filename, $extName = '', $langFile = '') {
|
||||
// get needed meta information
|
||||
$extName = empty($extName) ? $this->extName : $extName;
|
||||
$langFile = empty($langFile) ? $this->langFile : $langFile;
|
||||
$metaArray = $this->getMetaInfos(3, $extName, '', $langFile);
|
||||
|
||||
// check backup file
|
||||
if (!isset($metaArray[$filename])) {
|
||||
throw new LFException('failure.backup.notDeleted');
|
||||
}
|
||||
|
||||
// get file
|
||||
$backupPath = $metaArray[$filename]['pathBackup'];
|
||||
$pathSite = Environment::getPublicPath() . '/';
|
||||
$file = GeneralUtility::fixWindowsFilePath($pathSite . $backupPath . '/' . $filename);
|
||||
|
||||
// build new meta information file
|
||||
unset($metaArray[$filename]);
|
||||
if (!count($metaArray)) {
|
||||
$metaArray = NULL;
|
||||
}
|
||||
$this->setMetaInfos($metaArray, 3, $extName, '', $langFile);
|
||||
|
||||
$extMetaArray = $this->getMetaInfos(2, $extName);
|
||||
if (!count($extMetaArray)) {
|
||||
$extMetaArray = NULL;
|
||||
}
|
||||
$this->setMetaInfos($extMetaArray, 2, $extName);
|
||||
|
||||
// write meta information
|
||||
try {
|
||||
$this->writeMetaFile();
|
||||
} catch (LFException $e) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// delete backup file
|
||||
try {
|
||||
SgLib::deleteFiles([$file]);
|
||||
} catch (Exception $e) {
|
||||
throw new LFException(
|
||||
'failure.backup.notDeleted',
|
||||
0,
|
||||
'(' . $e->getMessage() . ')',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for deleteSpecFile()
|
||||
*
|
||||
* @throws LFException raised if the backup or meta file cant be written
|
||||
* @return void
|
||||
*/
|
||||
public function deleteFile() {
|
||||
try {
|
||||
$this->deleteSpecFile($this->relFile);
|
||||
} catch (LFException $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* reads a backup file
|
||||
*
|
||||
* @throws LFException raised if the backup file can't be read
|
||||
* @return void
|
||||
*/
|
||||
public function readFile() {
|
||||
if (!is_file($this->absFile)) {
|
||||
throw new LFException('failure.backup.notRead');
|
||||
}
|
||||
|
||||
// read file and transform from xml to array
|
||||
$phpArray = GeneralUtility::xml2array(file_get_contents($this->absFile));
|
||||
if (!is_array($phpArray)) {
|
||||
throw new LFException('failure.backup.notRead');
|
||||
}
|
||||
|
||||
$pathSite = Environment::getPublicPath() . '/';
|
||||
// read array
|
||||
$localLang = $originLang = [];
|
||||
foreach ($phpArray['data'] as $langKey => $informations) {
|
||||
// read origin
|
||||
try {
|
||||
$originLang[$langKey] = Typo3Lib::transTypo3File($informations['meta']['origin'], TRUE);
|
||||
} catch (Exception $e) {
|
||||
$originLang[$langKey] = $pathSite . $informations['meta']['origin'];
|
||||
}
|
||||
|
||||
// read data
|
||||
if (is_array($informations['langData'])) {
|
||||
foreach ($informations['langData'] as $const => $value) {
|
||||
$localLang[$langKey][$const] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check
|
||||
if (!count($localLang) || !count($originLang)) {
|
||||
throw new LFException('failure.backup.notRead');
|
||||
}
|
||||
|
||||
$this->localLang = $localLang;
|
||||
$this->originLang = $originLang;
|
||||
$this->meta = $phpArray['meta'];
|
||||
}
|
||||
|
||||
/**
|
||||
* prepares the final Content
|
||||
*
|
||||
* @return string prepared content (xml)
|
||||
*/
|
||||
private function prepareBackupContent() {
|
||||
$phpArray = [];
|
||||
$options = [];
|
||||
// set meta
|
||||
$phpArray['meta'] = $this->meta;
|
||||
$pathSite = Environment::getPublicPath() . '/';
|
||||
// set array
|
||||
foreach ($this->originLang as $lang => $origin) {
|
||||
// set origin
|
||||
try {
|
||||
$phpArray['data'][$lang]['meta']['origin'] = Typo3Lib::transTypo3File($origin, FALSE);
|
||||
} catch (Exception $e) {
|
||||
$phpArray['data'][$lang]['meta']['origin'] = substr($origin, strlen($pathSite));
|
||||
}
|
||||
|
||||
// set data
|
||||
if (\array_key_exists($lang, $this->localLang) && \is_array($this->localLang[$lang])) {
|
||||
foreach ($this->localLang[$lang] as $labelKey => $labelVal) {
|
||||
$phpArray['data'][$lang]['langData'][$labelKey] = $labelVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// define assocTagNames
|
||||
$options['parentTagMap'] = [
|
||||
'data' => 'languageKey',
|
||||
'langData' => 'label'
|
||||
];
|
||||
|
||||
// get xml
|
||||
return GeneralUtility::array2xml($phpArray, '', 0, 'LFBackup', 0, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* prepares the backup file and writes the new meta information
|
||||
*
|
||||
* @param array | NULL $editedLanguages
|
||||
* @return array raised if meta file cant be written
|
||||
* @throws Exception
|
||||
* @throws LFException
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareFileContents($editedLanguages = NULL) {
|
||||
$backupFiles = [];
|
||||
// get content
|
||||
$xml = $this->prepareBackupContent();
|
||||
|
||||
// get and set name of backup
|
||||
$backupName = 'locallang_' . substr(md5(md5($xml)), 0, 10) . '.bak';
|
||||
$this->setVar(['relFile' => $backupName]);
|
||||
$pathSite = Environment::getPublicPath() . '/';
|
||||
// get new meta information
|
||||
$metaArray = $this->getMetaInfos(3);
|
||||
$metaArray[$this->relFile]['createdAt'] = time();
|
||||
$metaArray[$this->relFile]['pathBackup'] = str_replace($pathSite, '', $this->absPath);
|
||||
$this->setMetaInfos($metaArray, 3);
|
||||
|
||||
// write meta information file
|
||||
try {
|
||||
$this->writeMetaFile();
|
||||
} catch (LFException $e) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$backupFiles[$this->absPath . $this->relFile] = $this->getXMLHeader() . $xml;
|
||||
return $backupFiles;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user