FileOverrideService.php 7.32 KB
Newer Older
1
2
3
4
5
6
7
<?php

namespace SGalinski\Lfeditor\Service;

/***************************************************************
 *  Copyright notice
 *
Stefan Galinski's avatar
Stefan Galinski committed
8
 *  (c) sgalinski Internet Services (https://www.sgalinski.de)
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 *
 *  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 SGalinski\Lfeditor\Exceptions\LFException;
use SGalinski\Lfeditor\Utility\SgLib;
use SGalinski\Lfeditor\Utility\Typo3Lib;

33
34
35
/**
 * FileOverrideService
 */
Damjan's avatar
Damjan committed
36
class FileOverrideService extends FileBaseXMLService {
37
38
39
40
41
42
43
44
45
46
47
48
49
	/**
	 * Object which represents original (overridden) language file.
	 *
	 * @var \SGalinski\Lfeditor\Service\FileService
	 */
	protected $originalFileObject;

	/**
	 * Initialises fileObject of override language file.
	 *
	 * @param FileService $originalFileObject
	 * @return void
	 */
50
	public function init($originalFileObject, $path, $metaFile) {
51
52
53
54
55
56
57
		try {
			$typo3ExtRelativeFilePath = Typo3Lib::transTypo3File($originalFileObject->getAbsFile(), FALSE);
		} catch (\Exception $e) {
			$typo3ExtRelativeFilePath = '';
		}
		$overrideFileAbsolutePath = Typo3Lib::fixFilePath(
			PATH_site . '/' .
Damjan's avatar
Damjan committed
58
			$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'][$typo3ExtRelativeFilePath][0]
59
60
61
62
		);

		if (!is_file($overrideFileAbsolutePath)) {
			$extRelativeFilePath = SgLib::trimPath('EXT:', $typo3ExtRelativeFilePath);
Damjan's avatar
Damjan committed
63
			$extRelativeFilePath = substr($extRelativeFilePath, 0, strrpos($extRelativeFilePath, '.')) . '.xml';
64
65
66

			/** @var ConfigurationService $configurationService */
			$configurationService = $this->objectManager->get('SGalinski\Lfeditor\Service\ConfigurationService');
Damjan's avatar
Damjan committed
67
68
			$extConfig = $configurationService->getExtConfig();
			$overrideFileAbsolutePath = $extConfig['pathOverrideFiles']
69
70
71
72
				. $extRelativeFilePath;
		}

		$this->originalFileObject = $originalFileObject;
73
		parent::init(basename($overrideFileAbsolutePath), dirname($overrideFileAbsolutePath), $metaFile);
74
75
76
77
78
79
80
81
82
83
	}

	/**
	 * Calls the parent function and convert all values from utf-8 to the original charset
	 *
	 * @throws LFException raised if the parent read file method fails
	 * @return void
	 */
	public function readFile() {
		if (is_file($this->absFile)) {
Damjan's avatar
Damjan committed
84
			parent::readFile();
85
			if (!Typo3Lib::isTypo3BackendInUtf8Mode()) {
86
				$this->localLang = Typo3Lib::utf8($this->localLang, FALSE, array('default'));
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
			}
		}

		$this->originalFileObject->readFile();
		$this->mergeOriginalWidthOverrideLangData();
	}

	/**
	 * Merges Language data from original and override files, so all data can e presented to user.
	 *
	 * @return void
	 */
	protected function mergeOriginalWidthOverrideLangData() {
		foreach ($this->originalFileObject->getLocalLang() as $lang => $langData) {
			if (empty($langData)) {
				continue;
			}
104

105
106
107
108
			foreach ($langData as $costKey => $constValue) {
				if (isset($this->localLang[$lang][$costKey]) && $this->localLang[$lang][$costKey] !== $constValue) {
					continue;
				}
109
110
111
112
113

				if (!is_array($this->localLang[$lang])) {
					$this->localLang[$lang] = [];
				}

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
				$this->localLang[$lang][$costKey] = $constValue;
			}
		}

		foreach ($this->originalFileObject->getMeta() as $metaTag => $metaTagValue) {
			if ($metaTag === '@attributes') {
				foreach ($metaTagValue as $attributeKey => $attributeValue) {
					if (isset($this->meta[$metaTag][$attributeKey])
						&& $this->meta[$metaTag][$attributeKey] !== $attributeValue
					) {
						continue;
					}
					$this->meta[$metaTag][$attributeKey] = $attributeValue;
				}
			} else {
				if (isset($this->meta[$metaTag]) && $this->meta[$metaTag] !== $metaTagValue) {
					continue;
				}
				$this->meta[$metaTag] = $metaTagValue;
			}
		}
	}

	/**
	 * Writes language override files.
	 *
140
	 * @param array|null $editedLanguages
141
	 * @throws LFException raised if a file cant be written
142
	 * @throws \Exception
143
144
	 * @return void
	 */
145
	public function writeFile($editedLanguages = NULL) {
146
147
148
149
150
151
152
		$this->deleteDuplicates();
		if (!$this->langDataExists() && !is_file($this->absFile)) {
			return;
		}

		try {
			SgLib::createDir($this->absPath, PATH_site);
153
154
		} catch (\Exception $exception) {
			throw new LFException('failure.failure', 0, '(' . $exception->getMessage() . ')');
155
156
157
		}

		parent::writeFile();
Damjan's avatar
Damjan committed
158

159
160
161
		// Set only new values in GlobalConfiguration if something changed
		$typo3ExtRelativeFilePath = Typo3Lib::transTypo3File($this->originalFileObject->getAbsFile(), FALSE);
		$relativeOverrideFilePath = SgLib::trimPath(PATH_site, $this->absFile);
Damjan's avatar
Damjan committed
162
163
		$locallangXMLOverride = &$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'];
		if ($locallangXMLOverride[$typo3ExtRelativeFilePath][0] === $relativeOverrideFilePath) {
164
165
166
167
168
169
170
171
172
			return;
		}

		try {
			$addLine = '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'locallangXMLOverride\'][\''
				. $typo3ExtRelativeFilePath . '\'][0] = \'' . $relativeOverrideFilePath . '\';';
			Typo3Lib::writeLineToAdditionalConfiguration($addLine);
			$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'][$typo3ExtRelativeFilePath][0]
				= $relativeOverrideFilePath;
173
174
		} catch (\Exception $exception) {
			throw new LFException('failure.failure', 0, '(' . $exception->getMessage() . ')');
175
176
177
178
179
180
181
182
183
184
		}
	}

	/**
	 * Deletes duplicated language data (data that exist in both files - original file and override file),
	 * so that only changed data will be saved in override file.
	 *
	 * @return void
	 */
	public function deleteDuplicates() {
185
186
187
188
189
190
		foreach ($this->localLang as $language => $languageData) {
			if (!is_array($languageData)) {
				continue;
			}
			foreach ($languageData as $constKey => $constValue) {
				$localLangData = $this->originalFileObject->getLocalLangData($language);
191
				if (SgLib::strCmpIgnoreCR($constValue, $localLangData[$constKey])) {
192
					unset($this->localLang[$language][$constKey]);
193
194
195
196
197
				}
			}
		}

		foreach ($this->meta as $metaTag => $metaValue) {
198
			if (SgLib::strCmpIgnoreCR($metaValue, $this->originalFileObject->getMetaData($metaTag))) {
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
				unset($this->meta[$metaTag]);
			}
		}
	}

	/**
	 * Checks is there any lang data (constants in $localLang and meta data).
	 *
	 * @return bool Returns true if any constant or meta data exist.
	 */
	protected function langDataExists() {
		foreach ($this->meta as $metaTag => $metaValue) {
			if (isset($this->meta[$metaTag]) && $metaTag !== '@attributes') {
				return TRUE;
			}
		}

216
217
218
219
220
221
		foreach ($this->localLang as $language => $languageData) {
			if (!is_array($languageData)) {
				continue;
			}
			foreach ($languageData as $constKey => $constValue) {
				if (isset($languageData[$constKey])) {
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
					return TRUE;
				}
			}
		}
		return FALSE;
	}

	/**
	 * Writes generator meta tag.
	 *
	 * @return void
	 */
	protected function addGeneratorString() {
		if ($this->originalFileObject->getMetaData('generator') !== 'LFEditor') {
			$this->meta['generator'] = 'LFEditor';
		}
	}
Stefan Galinski's avatar
Stefan Galinski committed
239
}