Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
collect.php
1<?php
3
9
10
17{
18 use Translate\Controller\Stepper;
19 use Translate\Controller\ProcessParams;
20
22 private $seekPathLangId;
23
25 private $languageId;
26
28 private $convertEncoding;
29
31 private $encoding;
32
34 private $assemblyDate;
35
37 private $packFile;
38
40 private $tmpFolderPath;
41
43 private $totalFileCount;
44
46 public static $documentRoot;
50 public static $enabledLanguages;
52 public static $allowedEncodings;
55
56
64 public function __construct($name, Main\Engine\Controller $controller, array $config = [])
65 {
66 $this->keepField([
67 'seekPathLangId', 'convertEncoding', 'encoding', 'assemblyDate',
68 'languageId', 'packFile', 'tmpFolderPath', 'totalFileCount'
69 ]);
70
71 parent::__construct($name, $controller, $config);
72
73 self::$useTranslationRepository = Main\Localization\Translation::useTranslationRepository();
74 self::$enabledLanguages = Translate\Config::getEnabledLanguages();
75 self::$allowedEncodings = Translate\Config::getAllowedEncodings();
76 self::$documentRoot = rtrim(Translate\IO\Path::tidy(Main\Application::getDocumentRoot()), '/');
77
78 if (self::$useTranslationRepository)
79 {
80 self::$translationRepositoryLanguages = Translate\Config::getTranslationRepositoryLanguages();
81 }
82 }
83
91 public function run($path = '', $runBefore = false)
92 {
93 if ($runBefore)
94 {
95 $this->onBeforeRun();
96 }
97
98 if (empty($path))
99 {
100 $path = Grabber::START_PATH;
101 }
102
103 $path = '/'. trim($path, '/.\\');
104
105 if ($this->isNewProcess)
106 {
108 $this->totalItems = 0;
109 $this->processedItems = 0;
110 $this->totalFileCount = 0;
111
112 // language
113 $languageId = $this->controller->getRequest()->get('languageId');
114 if (empty($languageId))
115 {
116 $this->addError(new Main\Error(Loc::getMessage('TR_ERROR_SELECT_LANGUAGE')));
117 }
118 if (!in_array($languageId, self::$enabledLanguages))
119 {
120 $this->addError(new Main\Error(Loc::getMessage('TR_ERROR_LANGUAGE_ID')));
121 }
122 else
123 {
124 $this->languageId = $languageId;
125 }
126
127 // convert encoding
128 $this->convertEncoding = ($this->controller->getRequest()->get('convertEncoding') === 'Y');
129
130 // encoding
131 $encoding = $this->controller->getRequest()->get('encoding');
132 if ($encoding !== null && in_array($encoding, self::$allowedEncodings))
133 {
134 $this->encoding = $encoding;
135 }
136 elseif ($this->convertEncoding)
137 {
138 $this->addError(new Main\Error(Loc::getMessage('TR_ERROR_ENCODING')));
139 }
140
141 if ($this->convertEncoding)
142 {
143 if (self::$useTranslationRepository)
144 {
145 $encodingIn = Main\Localization\Translation::getSourceEncoding($this->languageId);
146 $encodingOut = $this->encoding;
147 if ($encodingIn === 'utf-8' && $encodingOut !== 'utf-8')
148 {
149 $this->addError(new Error(Loc::getMessage('TR_ERROR_LANGUAGE_CHARSET_NON_UTF')));
150 }
151 }
152 elseif (Translate\Config::isUtfMode())
153 {
154 $encodingIn = 'utf-8';
155 $encodingOut = $this->encoding;
156 if (Translate\Config::getCultureEncoding($this->languageId) !== 'utf-8')
157 {
158 $this->addError(new Error(Loc::getMessage('TR_ERROR_LANGUAGE_CHARSET_NON_UTF')));
159 }
160 }
161 else
162 {
163 $encodingIn = Translate\Config::getCultureEncoding($this->languageId);
164 if (!$encodingIn)
165 {
166 $encodingIn = Main\Localization\Translation::getCurrentEncoding();
167 }
168 $this->encoding = $encodingOut = 'utf-8';
169 }
170
171 $this->convertEncoding = (\mb_strtolower($encodingIn) !== \mb_strtolower($encodingOut));
172 }
173
174 // assembly date
175 $assemblyDate = $this->controller->getRequest()->get('assemblyDate');
176 if ($assemblyDate !== null && \preg_replace("/[\D]+/", "", $assemblyDate) && \mb_strlen($assemblyDate) == 8)
177 {
178 $this->assemblyDate = $assemblyDate;
179 }
180 else
181 {
182 $this->addError(new Main\Error(Loc::getMessage('TR_ERROR_LANGUAGE_DATE')));
183 }
184
185
186 // pack
187 $this->packFile = ($this->controller->getRequest()->get('packFile') === 'Y');
188
189
190 if (!$this->hasErrors())
191 {
192 $exportFolder = Translate\Config::getExportFolder();
193 if (!empty($exportFolder))
194 {
195 $tempDir = new Translate\IO\Directory($exportFolder.'/'.$this->languageId);
196 if ($tempDir->isExists())
197 {
198 $tempDir->wipe();
199 }
200 else
201 {
202 $tempDir->create();
203 }
204 }
205 else
206 {
207 $tempDir = Translate\IO\Directory::generateTemporalDirectory('translate');
208 $tempDir = $tempDir->createSubdirectory($this->languageId);
209 }
210 $this->tmpFolderPath = $tempDir->getPhysicalPath(). '/';
211 if (!$tempDir->isExists())
212 {
213 $this->addError(
214 new Error(Loc::getMessage('TR_ERROR_CREATE_TEMP_FOLDER', ['#PATH#' => $this->tmpFolderPath]))
215 );
216 }
217 }
218
219 if (!$this->hasErrors())
220 {
221 $fileDateMarkFullPath = $this->tmpFolderPath.
222 \str_replace('#LANG_ID#', $this->languageId, Translate\SUPD_LANG_DATE_MARK);
223
224 Translate\IO\Path::checkCreatePath(\dirname($fileDateMarkFullPath));
225
226 $fileDateMark = new Main\IO\File($fileDateMarkFullPath);
227 if ($fileDateMark->putContents($assemblyDate) === false)
228 {
229 $this->addError(
230 new Error(Loc::getMessage('TR_ERROR_OPEN_FILE', ['#FILE#' => $fileDateMarkFullPath]))
231 );
232 }
233 }
234
235 $this->totalItems = (int)Index\Internals\PathLangTable::getCount(['=%PATH' => $path.'%']);
236 $this->processedItems = 0;
237
238 $this->saveProgressParameters();
239
240 return [
241 'STATUS' => ($this->totalItems > 0 ? Translate\Controller\STATUS_PROGRESS : Translate\Controller\STATUS_COMPLETED),
242 'PROCESSED_ITEMS' => 0,
243 'TOTAL_ITEMS' => $this->totalItems,
244 ];
245 }
246
247 $progressParams = $this->getProgressParameters();
248
249 $this->languageId = $progressParams['languageId'];
250 $this->convertEncoding = $progressParams['convertEncoding'];
251 $this->encoding = $progressParams['encoding'];
252 $this->assemblyDate = $progressParams['assemblyDate'];
253 $this->packFile = $progressParams['packFile'];
254 $this->tmpFolderPath = $progressParams['tmpFolderPath'];
255
256 if (isset($progressParams['totalItems']) && (int)$progressParams['totalItems'] > 0)
257 {
258 $this->totalItems = (int)$progressParams['totalItems'];
259 $this->processedItems = (int)$progressParams['processedItems'];
260 $this->totalFileCount = (int)$progressParams['totalFileCount'];
261 }
262
263 if (isset($progressParams['seekPathLangId']))
264 {
265 $this->seekPathLangId = $progressParams['seekPathLangId'];
266 }
267
268 return $this->performStep('runCollecting', ['path' => $path]);
269 }
270
271
278 private function runCollecting(array $params = [])
279 {
280 if ($this->convertEncoding)
281 {
282 $sourceEncoding = Main\Localization\Translation::getSourceEncoding($this->languageId);
283 }
284
285 if (isset($params['path']))
286 {
287 $path = $params['path'];
288 }
289 else
290 {
291 $path = Grabber::START_PATH;
292 }
293
294 $pathFilter = [
295 '=%PATH' => $path.'%'
296 ];
297 if (!empty($this->seekPathLangId))
298 {
299 $pathFilter['>ID'] = $this->seekPathLangId;
300 }
301
302 $cachePathLangRes = Index\Internals\PathLangTable::getList([
303 'filter' => $pathFilter,
304 'order' => ['ID' => 'ASC'],
305 'select' => ['ID', 'PATH'],
306 ]);
307 $processedItemCount = 0;
308 while ($pathLang = $cachePathLangRes->fetch())
309 {
310 foreach ($this->lookThroughLangFolder($pathLang['PATH']. '/'.$this->languageId) as $filePaths)
311 {
312 foreach ($filePaths as $langFilePath => $fullPath)
313 {
314 $targetFolder = new Main\IO\Directory($this->tmpFolderPath. \dirname($langFilePath));
315 if (!$targetFolder->isExists())
316 {
317 $targetFolder->create();
318 }
319
320 $source = new Main\IO\File($fullPath);
321 $target = new Main\IO\File($targetFolder->getPhysicalPath(). '/'. \basename($langFilePath));
322
323 try
324 {
325 $content = $source->getContents();
326 $content = \str_replace(["\r\n", "\r"], ["\n", "\n"], $content);
327
328 if ($this->convertEncoding)
329 {
330 $content = Main\Text\Encoding::convertEncoding($content, $sourceEncoding, $this->encoding);
331 }
332
333 $target->putContents($content);
334 $this->totalFileCount ++;
335 }
336 catch (Main\IO\IoException $exception)
337 {
338 $this->addError(new Main\Error($exception->getMessage()));
339 }
340
341 // check user abortion
342 if (\connection_status() !== \CONNECTION_NORMAL)
343 {
344 throw new Main\SystemException('Process has been broken course user aborted connection.');
345 }
346 }
347 }
348
349 $processedItemCount ++;
350
351 if ($this->instanceTimer()->hasTimeLimitReached())
352 {
353 $this->seekPathLangId = (int)$pathLang['ID'];
354 break;
355 }
356 }
357
358 $this->processedItems += $processedItemCount;
359
360 $result = [
361 'PROCESSED_ITEMS' => $this->processedItems,
362 'TOTAL_ITEMS' => $this->totalItems,
363 ];
364
365 if ($this->instanceTimer()->hasTimeLimitReached() !== true)
366 {
367 $this->declareAccomplishment();
368
369 // we have to continue process in next action
370 $this->processToken = null;
371 $this->seekPathLangId = null;
372 $this->saveProgressParameters();
373
374 $messagePlaceholders = [
375 '#TOTAL_FILES#' => $this->totalFileCount,
376 '#LANG#' => \mb_strtoupper($this->languageId),
377 '#PATH#' => '~tmp~',
378 ];
379 $result['SUMMARY'] = Loc::getMessage('TR_LANGUAGE_COLLECTED_FOLDER', $messagePlaceholders);
380 }
381
382 return $result;
383 }
384
385
393 private function lookThroughLangFolder($langFolderRelPath)
394 {
395 $files = [];
396 $folders = [];
397
398 $langFolderFullPath = Translate\IO\Path::tidy(self::$documentRoot.'/'.$langFolderRelPath);
399
400 $storeFolderRelPath = \str_replace(Grabber::START_PATH, '', $langFolderRelPath);
401
402 if (self::$useTranslationRepository && \in_array($this->languageId, self::$translationRepositoryLanguages))
403 {
404 $langFolderFullPath = Main\Localization\Translation::convertLangPath($langFolderFullPath, $this->languageId);
405 }
406
407 $childrenList = Translate\IO\FileSystemHelper::getFileList($langFolderFullPath);
408 if (!empty($childrenList))
409 {
410 foreach ($childrenList as $fullPath)
411 {
412 $name = \basename($fullPath);
413 if (\in_array($name, Translate\IGNORE_FS_NAMES))
414 {
415 continue;
416 }
417
418 if (Translate\IO\Path::isPhpFile($fullPath, true))
419 {
420 $files[$storeFolderRelPath.'/'.$name] = $fullPath;
421 }
422 }
423 }
424
425 // dir only
426 $childrenList = Translate\IO\FileSystemHelper::getFolderList($langFolderFullPath);
427 if (!empty($childrenList))
428 {
429 $ignoreDev = \implode('|', Translate\IGNORE_MODULE_NAMES);
430 foreach ($childrenList as $fullPath)
431 {
432 $name = \basename($fullPath);
433 if (\in_array($name, Translate\IGNORE_FS_NAMES))
434 {
435 continue;
436 }
437
438 $relPath = $langFolderRelPath.'/'.$name;
439
440 if (!\is_dir($fullPath))
441 {
442 continue;
443 }
444
445 if (\in_array($relPath, Translate\IGNORE_BX_NAMES))
446 {
447 continue;
448 }
449
450 // /bitrix/modules/[smth]/dev/
451 if (\preg_match("#^bitrix/modules/[^/]+/({$ignoreDev})#", \trim($relPath, '/')))
452 {
453 continue;
454 }
455
456 if (\in_array($name, Translate\IGNORE_LANG_NAMES))
457 {
458 continue;
459 }
460
461 $folders[$langFolderRelPath.'/'.$name] = $langFolderRelPath.'/'.$name;
462 }
463 }
464
465 if (\count($files) > 0)
466 {
467 yield $files;
468 }
469
470 if (\count($folders) > 0)
471 {
472 foreach ($folders as $subFolderPath)
473 {
474 foreach ($this->lookThroughLangFolder($subFolderPath) as $subFiles)// go deeper
475 {
476 yield $subFiles;
477 }
478 }
479 }
480 }
481
482
489 {
490 $controller = $this->getController();
491 return $controller::SETTING_ID;
492 }
493}
addError(Error $error)
Definition action.php:200
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
run($path='', $runBefore=false)
Definition collect.php:91
__construct($name, Main\Engine\Controller $controller, array $config=[])
Definition collect.php:64
performStep($action, array $params=[])
Definition stepper.php:75
declareAccomplishment(bool $flag=true)
Definition stepper.php:136