Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
exportpath.php
1<?php
3
7
12 extends ExportAction
14{
15 use Translate\Controller\Stepper;
16 use Translate\Controller\ProcessParams;
17
19 private array $pathList = [];
20
22 private array $codeList = [];
23
24 private int $seekOffset = 0;
25
26 private int $seekPathLangId = 0;
27
28 private string $seekLangFilePath = '';
29 private string $seekPhraseCode = '';
30
31
39 public function __construct($name, Main\Engine\Controller $controller, array $config = [])
40 {
41 $this->keepField(['pathList', 'codeList', 'seekOffset', 'seekPathLangId', 'seekPhraseCode', 'seekLangFilePath']);
42
43 Loc::loadLanguageFile(__DIR__ . '/exportaction.php');
44
45 parent::__construct($name, $controller, $config);
46 }
47
48
57 public function run(string $path = '', bool $runBefore = false): array
58 {
59 if ($runBefore)
60 {
61 $this->onBeforeRun();
62 }
63
64 if ($this->isNewProcess)
65 {
66 $pathList = $this->controller->getRequest()->get('pathList');
67
68 $pathList = \preg_split("/[\r\n]+/", $pathList);
69 \array_walk($pathList, 'trim');
70 $pathList = \array_unique(\array_filter($pathList));
71 if (empty($pathList))
72 {
73 $this->addError(new Main\Error(Loc::getMessage('TR_EXPORT_EMPTY_PATH_LIST')));
74
75 return [
76 'STATUS' => Translate\Controller\STATUS_COMPLETED,
77 ];
78 }
79
80 foreach ($pathList as $testPath)
81 {
82 if (Translate\IO\Path::isPhpFile($testPath))
83 {
84 if (Translate\IO\Path::isLangDir($testPath))
85 {
86 $this->pathList[] = $testPath;
87 }
88 }
89 else
90 {
91 $this->pathList[] = $testPath;
92 }
93 }
94
95 // phrase codes
96 $codeList = $this->controller->getRequest()->get('codeList');
97 if (!empty($codeList))
98 {
99 $codeList = \preg_split("/[\r\n]+/", $codeList);
100 \array_walk($codeList, 'trim');
101 $this->codeList = \array_unique(\array_filter($codeList));
102 }
103
104 $this->totalItems = \count($this->pathList);
105 $this->processedItems = 0;
106
107 if ($this->totalItems > 0)
108 {
109 $this->exportFileName = $this->generateExportFileName($path, $this->languages);
110 $csvFile = $this->createExportTempFile($this->exportFileName);
111 $this->exportFilePath = $csvFile->getPhysicalPath();
112 $this->exportFileSize = $csvFile->getSize();
113 }
114 if ($this->appendSamples)
115 {
116 $this->samplesFileName = $this->generateExportFileName($path.'-samples', $this->languages);
117 $sampleFile = $this->createExportTempFile($this->samplesFileName);
118 $this->samplesFilePath = $sampleFile->getPhysicalPath();
119 $this->samplesFileSize = $sampleFile->getSize();
120 }
121
122 $this->saveProgressParameters();
123
124 return [
125 'STATUS' => ($this->totalItems > 0 ? Translate\Controller\STATUS_PROGRESS : Translate\Controller\STATUS_COMPLETED),
126 'PROCESSED_ITEMS' => 0,
127 'TOTAL_ITEMS' => $this->totalItems,
128 ];
129 }
130
131 return $this->performStep('runExporting');
132 }
133
134
140 private function runExporting(): array
141 {
142 $csvFile = new Translate\IO\CsvFile($this->exportFilePath);
143 $this->configureExportCsvFile($csvFile);
144 $csvFile->openWrite( Main\IO\FileStreamOpenMode::APPEND);
145
146 if ($this->appendSamples)
147 {
148 $samplesFile = new Translate\IO\CsvFile($this->samplesFilePath);
149 $this->configureExportCsvFile($samplesFile);
150 $samplesFile->openWrite( Main\IO\FileStreamOpenMode::APPEND);
151 }
152
153 $processedItemCount = 0;
154
155 $filterCodeList = $this->codeList ?: [];
156 $fileCodeList = [];
157 foreach ($filterCodeList as $pathCode)
158 {
159 [$path, $code] = \explode('::', $pathCode);
160 if ($path && $code)
161 {
162 $langFilePath = Translate\IO\Path::replaceLangId($path, '#LANG_ID#');
163 if (!isset($fileCodeList[$langFilePath]))
164 {
165 $fileCodeList[$langFilePath] = [];
166 }
167 $fileCodeList[$langFilePath][] = $code;
168 }
169 }
170
171 $currentLangId = Loc::getCurrentLang();
172
173 for ($pos = ($this->seekOffset > 0 ? $this->seekOffset : 0), $total = \count($this->pathList); $pos < $total; $pos ++)
174 {
175 $exportingPath = $this->pathList[$pos];
176
177 // file
178 if (Translate\IO\Path::isPhpFile($exportingPath))
179 {
180 $langFilePath = Translate\IO\Path::replaceLangId($exportingPath, '#LANG_ID#');
181 if (!empty($this->seekLangFilePath))
182 {
183 if ($langFilePath == $this->seekLangFilePath)
184 {
185 $this->seekLangFilePath = '';
186 }
187 else
188 {
189 continue;
190 }
191 }
192
193 $fullPaths = [];
194 foreach ($this->languages as $langId)
195 {
196 $langRelPath = Translate\IO\Path::replaceLangId($exportingPath, $langId);
197 $langFullPath = Translate\IO\Path::tidy(self::$documentRoot.'/'.$langRelPath);
198
199 if (self::$useTranslationRepository && \in_array($langId, self::$translationRepositoryLanguages))
200 {
201 $langFullPath = Main\Localization\Translation::convertLangPath($langFullPath, $langId);
202 }
203
204 $fullPaths[$langId] = $langFullPath;
205 }
206
207 $rows = $this->mergeLangFiles($langFilePath, $fullPaths, $this->collectUntranslated, $fileCodeList[$langFilePath] ?? []);
208 foreach ($rows as $code => $row)
209 {
210 if (!empty($this->seekPhraseCode))
211 {
212 if ($code == $this->seekPhraseCode)
213 {
214 $this->seekPhraseCode = '';
215 }
216 continue;
217 }
218
219 $csvFile->put(\array_values($row));
220
221 if (
222 $this->appendSamples
223 && !empty($row[$currentLangId])
224 && mb_strlen($row[$currentLangId]) < $this->maxSampleSourceLength
225 )
226 {
227 $samples = $this->findSamples(
228 $row[$currentLangId],
229 $currentLangId,
230 $langFilePath,
231 $this->samplesCount,
232 $this->samplesRestriction
233 );
234 foreach ($samples as $sample)
235 {
236 $samplesFile->put(\array_values($sample));
237 $this->exportedSamplesCount ++;
238 }
239 }
240
241 $this->exportedPhraseCount ++;
242
243 if ($this->instanceTimer()->hasTimeLimitReached())
244 {
245 $this->seekPhraseCode = $code;
246 }
247 else
248 {
249 $this->seekPhraseCode = '';
250 }
251 }
252
253 if ($this->instanceTimer()->hasTimeLimitReached())
254 {
255 $this->seekLangFilePath = $langFilePath;
256 break;
257 }
258 else
259 {
260 $this->seekLangFilePath = '';
261 }
262 }
263
264 // folder
265 else
266 {
267 $exportingPath = Translate\IO\Path::tidy($exportingPath. '/');
268 if (\preg_match("#(.+/lang)(/?\w*)#", $exportingPath, $matches))
269 {
270 $lookForLangPath = $matches[1];
271 $lookForLangSubPath = '';
272 if (\preg_match("#(.+/lang/[^/]+/?)(.*)$#", $exportingPath, $subMatches))
273 {
274 $lookForLangSubPath = $subMatches[2];
275 }
276 }
277 else
278 {
279 $lookForLangPath = $exportingPath;
280 $lookForLangSubPath = '';
281 }
282 unset($matches, $subMatches);
283
284
285 // now let's find lang files
286 $pathFilter = [
287 '=%PATH' => $lookForLangPath.'%'
288 ];
289 if ($this->seekPathLangId > 0)
290 {
291 $pathFilter['>=ID'] = $this->seekPathLangId;
292 }
293
294 $cachePathLangRes = Translate\Index\Internals\PathLangTable::getList([
295 'filter' => $pathFilter,
296 'order' => ['ID' => 'ASC'],
297 'select' => ['ID', 'PATH'],
298 ]);
299 while ($pathLang = $cachePathLangRes->fetch())
300 {
301 $lookThroughPath = $pathLang['PATH']. '/#LANG_ID#';
302 if (!empty($lookForLangSubPath))
303 {
304 $lookThroughPath .= '/'. \trim($lookForLangSubPath, '/');
305 }
306 foreach ($this->lookThroughLangFolder($lookThroughPath) as $filePaths)
307 {
308 foreach ($filePaths as $langFilePath => $fullPaths)
309 {
310 if (!empty($this->seekLangFilePath))
311 {
312 if ($langFilePath == $this->seekLangFilePath)
313 {
314 $this->seekLangFilePath = '';
315 }
316 else
317 {
318 continue;
319 }
320 }
321
322 $rows = $this->mergeLangFiles($langFilePath, $fullPaths, $this->collectUntranslated, $fileCodeList[$langFilePath] ?? []);
323 foreach ($rows as $code => $row)
324 {
325 if (!empty($this->seekPhraseCode))
326 {
327 if ($code == $this->seekPhraseCode)
328 {
329 $this->seekPhraseCode = '';
330 }
331 continue;
332 }
333
334 $csvFile->put(\array_values($row));
335
336 if (
337 $this->appendSamples
338 && !empty($row[$currentLangId])
339 && mb_strlen($row[$currentLangId]) < $this->maxSampleSourceLength
340 )
341 {
342 $samples = $this->findSamples(
343 $row[$currentLangId],
344 $currentLangId,
345 $langFilePath,
346 $this->samplesCount,
347 $this->samplesRestriction
348 );
349 foreach ($samples as $sample)
350 {
351 $samplesFile->put(\array_values($sample));
352 $this->exportedSamplesCount ++;
353 }
354 }
355
356 $this->exportedPhraseCount ++;
357
358 if ($this->instanceTimer()->hasTimeLimitReached())
359 {
360 $this->seekPhraseCode = $code;
361 break;
362 }
363 else
364 {
365 $this->seekPhraseCode = '';
366 }
367 }
368
369 if ($this->instanceTimer()->hasTimeLimitReached())
370 {
371 $this->seekLangFilePath = $langFilePath;
372 break;
373 }
374 else
375 {
376 $this->seekLangFilePath = '';
377 }
378 }
379 }
380
381 if ($this->instanceTimer()->hasTimeLimitReached())
382 {
383 $this->seekPathLangId = (int)$pathLang['ID'];
384 break 2;
385 }
386 else
387 {
388 $this->seekPathLangId = 0;
389 }
390 }
391 }
392
393 $processedItemCount ++;
394
395 if (isset($this->pathList[$pos + 1]))
396 {
397 $this->seekOffset = $pos + 1;//next
398 }
399 else
400 {
401 $this->seekOffset = 0;
402 $this->declareAccomplishment();
404 }
405
406 if ($this->instanceTimer()->hasTimeLimitReached())
407 {
408 break;
409 }
410 }
411
412 $this->exportFileSize = $csvFile->getSize();
413
414 $csvFile->close();
415 if ($this->appendSamples)
416 {
417 $this->samplesFileSize = $samplesFile->getSize();
418 $samplesFile->close();
419 }
420
421 $this->processedItems += $processedItemCount;
422
423 if ($this->instanceTimer()->hasTimeLimitReached() !== true)
424 {
425 $this->declareAccomplishment();
427 }
428
429 $result = [
430 'PROCESSED_ITEMS' => $this->processedItems,
431 'TOTAL_ITEMS' => $this->totalItems,
432 'TOTAL_PHRASES' => $this->exportedPhraseCount,
433 'TOTAL_SAMPLES' => $this->exportedSamplesCount,
434 ];
435
436 if ($csvFile->hasErrors())
437 {
438 $errors = $csvFile->getErrors();
439 foreach ($errors as $err)
440 {
441 if ($err->getCode() == Translate\IO\CsvFile::ERROR_32K_FIELD_LENGTH)
442 {
443 $result['WARNING'] = Loc::getMessage('TR_EXPORT_ERROR_32K_LENGTH');
444 }
445 else
446 {
447 $this->addError($err);
448 }
449 }
450 }
451
452 return $result;
453 }
454}
static loadLanguageFile($file, $language=null, $normalize=true)
Definition loc.php:224
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
configureExportCsvFile(Translate\IO\CsvFile $csvFile)
generateExportFileName(string $path, array $languages)
mergeLangFiles(string $langFilePath, array $fullLangFilePaths, bool $collectUntranslated=false, array $filterByCodeList=[])
run(string $path='', bool $runBefore=false)
__construct($name, Main\Engine\Controller $controller, array $config=[])
performStep($action, array $params=[])
Definition stepper.php:75
declareAccomplishment(bool $flag=true)
Definition stepper.php:136
addError(Main\Error $error)
Definition error.php:22