Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
apply.php
1<?php
3
8
9
13class Apply
16{
17 use Translate\Controller\Stepper;
18 use Translate\Controller\ProcessParams;
19
21 private $languageId;
22
24 private $convertEncoding;
25
27 private $encoding;
28
30 private $encodingIn;
31
33 private $encodingOut;
34
36 private $tmpFolderPath;
37
39 private $targetFolderPath;
40
42 private $sourceFolderPath;
43
45 private $totalFileCount;
46
50 public static $enabledLanguages;
52 public static $allowedEncodings;
55
56
58 private $seekPath;
60 private $seekAncestors;
61
62
70 public function __construct($name, Main\Engine\Controller $controller, array $config = [])
71 {
72 $this->keepField([
73 'languageId', 'convertEncoding', 'encoding', 'encodingIn', 'encodingOut',
74 'tmpFolderPath', 'totalFileCount', 'sourceFolderPath', 'targetFolderPath', 'seekPath'
75 ]);
76
77 parent::__construct($name, $controller, $config);
78
79
80 self::$useTranslationRepository = Main\Localization\Translation::useTranslationRepository();
81 self::$enabledLanguages = Translate\Config::getEnabledLanguages();
82 self::$allowedEncodings = Translate\Config::getAllowedEncodings();
83
84 if (self::$useTranslationRepository)
85 {
86 self::$translationRepositoryRoot = Main\Localization\Translation::getTranslationRepositoryPath();
87 }
88 }
89
95 public function run()
96 {
97 // continue previous process
98 $progressParams = $this->getProgressParameters();
99
100 $this->languageId = $progressParams['languageId'];
101 $this->tmpFolderPath = $progressParams['tmpFolderPath'];
102 $this->totalFileCount = $progressParams['totalFileCount'];
103
104
105 if ($this->isNewProcess)
106 {
107 $this->totalItems = $this->totalFileCount;
108 $this->processedItems = 0;
109
110 // language
111 $languageId = $this->controller->getRequest()->get('languageId');
112 if (empty($languageId))
113 {
114 $this->addError(new Main\Error(Loc::getMessage('TR_ERROR_SELECT_LANGUAGE')));
115 }
116 if (!in_array($languageId, self::$enabledLanguages))
117 {
118 $this->addError(new Main\Error(Loc::getMessage('TR_ERROR_LANGUAGE_ID')));
119 }
120 else
121 {
122 $this->languageId = $languageId;
123 }
124
125 // convert encoding
126 $this->convertEncoding = ($this->controller->getRequest()->get('localizeEncoding') === 'Y');
127
128 // encoding
129 $encoding = $this->controller->getRequest()->get('encoding');
130 if ($encoding !== null && \in_array($encoding, self::$allowedEncodings))
131 {
132 $this->encoding = $encoding;
133 }
134 elseif ($this->convertEncoding)
135 {
136 $this->addError(new Main\Error(Loc::getMessage('TR_ERROR_ENCODING')));
137 }
138
139 if ($this->convertEncoding)
140 {
141 if (self::$useTranslationRepository)
142 {
143 $encodingIn = $this->encoding;
144 $encodingOut = Main\Localization\Translation::getSourceEncoding($this->languageId);
145 }
146 elseif (Translate\Config::isUtfMode())
147 {
148 $encodingIn = $this->encoding;
149 $encodingOut = 'utf-8';
150 }
151 else
152 {
153 $encodingIn = 'utf-8';
154 $encodingOut = Translate\Config::getCultureEncoding($this->languageId);
155 if (!$encodingOut)
156 {
157 $encodingOut = Main\Localization\Translation::getCurrentEncoding();
158 }
159 }
160 $this->convertEncoding = (\mb_strtolower($encodingIn) !== \mb_strtolower($encodingOut));
161 $this->encodingIn = $encodingIn;
162 $this->encodingOut = $encodingOut;
163 }
164
165 $this->sourceFolderPath = Translate\IO\Path::tidy($this->tmpFolderPath .'/'. $this->languageId. '/');
166
167 $sourceDirectory = new Translate\IO\Directory($this->sourceFolderPath);
168 if (!$sourceDirectory->isExists())
169 {
170 $this->addError(
171 new Error(Loc::getMessage('TR_ERROR_CREATE_TARGET_FOLDER', ['#PATH#' => $this->sourceFolderPath]))
172 );
173 }
174
175 if (
176 self::$useTranslationRepository &&
177 Main\Localization\Translation::isDefaultTranslationLang($this->languageId) !== true
178 )
179 {
180 $this->targetFolderPath = Translate\IO\Path::tidy(self::$translationRepositoryRoot. '/'. $this->languageId.'/');
181 $targetFolder = new Translate\IO\Directory($this->targetFolderPath);
182 if (!$targetFolder->isExists())
183 {
184 $targetFolder->create();
185 }
186 }
187 else
188 {
189 $this->targetFolderPath = Main\Application::getDocumentRoot().'/bitrix/modules/';
190 }
191
192 $this->saveProgressParameters();
193
194 return [
195 'STATUS' => ($this->totalItems > 0 ? Translate\Controller\STATUS_PROGRESS : Translate\Controller\STATUS_COMPLETED),
196 'PROCESSED_ITEMS' => 0,
197 'TOTAL_ITEMS' => $this->totalItems,
198 ];
199 }
200
201 $this->targetFolderPath = $progressParams['targetFolderPath'];
202 $this->convertEncoding = $progressParams['convertEncoding'];
203 $this->encodingIn = $progressParams['encodingIn'];
204 $this->encodingOut = $progressParams['encodingOut'];
205 $this->seekPath = $progressParams['seekPath'];
206
207 return $this->performStep('runApplying');
208 }
209
210
216 private function runApplying(): array
217 {
218 $processedItemCount = 0;
219
220 if (!empty($this->seekPath))
221 {
222 $this->seekAncestors = [];
223 $arr = \explode('/', \str_replace($this->sourceFolderPath, '', $this->seekPath));
224 \array_pop($arr);//last file
225 $parts = [];
226 foreach ($arr as $part)
227 {
228 $parts[] = $part;
229 $this->seekAncestors[] = $this->sourceFolderPath. \implode('/', $parts);
230 }
231 }
232
233 foreach ($this->lookThroughTmpFolder($this->sourceFolderPath) as $filePaths)
234 {
235 foreach ($filePaths as $langFilePath => $fullPath)
236 {
237 $targetFolder = new Main\IO\Directory($this->targetFolderPath. \dirname($langFilePath));
238 if (!$targetFolder->isExists())
239 {
240 $targetFolder->create();
241 }
242
243 $source = new Main\IO\File($fullPath);
244 $target = new Main\IO\File($targetFolder->getPhysicalPath(). '/'. \basename($langFilePath));
245 if ($target->isExists())
246 {
247 $target->markWritable();
248 }
249
250 try
251 {
252 if ($this->convertEncoding)
253 {
254 $content = $source->getContents();
255 $content = \str_replace(["\r\n", "\r"], ["\n", "\n"], $content);
256
257 $content = Main\Text\Encoding::convertEncoding($content, $this->encodingIn, $this->encodingOut);
258 $target->putContents($content);
259 }
260 else
261 {
262 if (\function_exists('error_clear_last'))
263 {
264 \error_clear_last();
265 }
266 if (\copy($source->getPhysicalPath(), $target->getPhysicalPath()) !== true)
267 {
268 $error = \error_get_last();
269 $this->addError(new Main\Error($error['message'], $error['type']));
270 continue;
271 }
272 }
273
274 $processedItemCount ++;
275 }
276 catch (Main\IO\IoException $exception)
277 {
278 $this->addError(new Main\Error($exception->getMessage()));
279 }
280
281 // check user abortion
282 if (\connection_status() !== \CONNECTION_NORMAL)
283 {
284 throw new Main\SystemException('Process has been broken course user aborted connection.');
285 }
286 }
287
288 if ($this->instanceTimer()->hasTimeLimitReached())
289 {
290 $this->seekPath = $fullPath;
291 break;
292 }
293 }
294
295 $this->processedItems += $processedItemCount;
296
297 $result = [
298 'PROCESSED_ITEMS' => $this->processedItems,
299 'TOTAL_ITEMS' => $this->totalItems,
300 ];
301
302 if ($this->instanceTimer()->hasTimeLimitReached() !== true)
303 {
304 $this->declareAccomplishment();
305
306 $updatePublic = $this->controller->getRequest()->get('updatePublic');
307 if ($updatePublic === 'Y')
308 {
309 // we have to continue process in next action
310 $this->processToken = null;
311 }
312 else
313 {
315 }
316
317 $result['SUMMARY'] = Loc::getMessage('TR_LANGUAGE_DOWNLOADED');
318 }
319
320 return $result;
321 }
322
323
331 private function lookThroughTmpFolder($tmpFolderFullPath): iterable
332 {
333 $files = [];
334 $folders = [];
335
336 $tmpFolderFullPath = Translate\IO\Path::tidy(\rtrim($tmpFolderFullPath, '/'));
337 $langFolderRelPath = \str_replace($this->sourceFolderPath, '', $tmpFolderFullPath);
338
339 $childrenList = Translate\IO\FileSystemHelper::getFileList($tmpFolderFullPath);
340 if (!empty($childrenList))
341 {
342 foreach ($childrenList as $fullPath)
343 {
344 if (!empty($this->seekPath))
345 {
346 if ($this->seekPath != $fullPath)
347 {
348 continue;
349 }
350
351 $this->seekPath = null;
352 $this->seekAncestors = null;
353 }
354
355 $name = \basename($fullPath);
356 if (\in_array($name, Translate\IGNORE_FS_NAMES))
357 {
358 continue;
359 }
360
361 if (Translate\IO\Path::isPhpFile($fullPath, true))
362 {
363 $files[$langFolderRelPath.'/'.$name] = $fullPath;
364 }
365 }
366 }
367
368 // dir only
369 $childrenList = Translate\IO\FileSystemHelper::getFolderList($tmpFolderFullPath);
370 if (!empty($childrenList))
371 {
372 foreach ($childrenList as $fullPath)
373 {
374 $name = \basename($fullPath);
375 if (\in_array($name, Translate\IGNORE_FS_NAMES))
376 {
377 continue;
378 }
379
380 if (!empty($this->seekPath))
381 {
382 if (\in_array($fullPath, $this->seekAncestors))
383 {
384 foreach ($this->lookThroughTmpFolder($fullPath) as $subFiles)// go deeper
385 {
386 yield $subFiles;
387 }
388 }
389 continue;
390 }
391
392 if (!\is_dir($fullPath))
393 {
394 continue;
395 }
396
397 $relPath = $langFolderRelPath.'/'.$name;
398
399 if (\in_array($relPath, Translate\IGNORE_BX_NAMES))
400 {
401 continue;
402 }
403
404 $folders[$relPath] = $fullPath;
405 }
406 }
407
408 if (\count($files) > 0)
409 {
410 yield $files;
411 }
412
413 if (\count($folders) > 0)
414 {
415 foreach ($folders as $subFolderPath)
416 {
417 foreach ($this->lookThroughTmpFolder($subFolderPath) as $subFiles)// go deeper
418 {
419 yield $subFiles;
420 }
421 }
422 }
423 }
424
425
432 {
433 $controller = $this->getController();
434 return $controller::SETTING_ID;
435 }
436}
addError(Error $error)
Definition action.php:200
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
__construct($name, Main\Engine\Controller $controller, array $config=[])
Definition apply.php:70
performStep($action, array $params=[])
Definition stepper.php:75
declareAccomplishment(bool $flag=true)
Definition stepper.php:136