Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
csv.php
1<?php
3
10
11
12class Csv
15{
16 use Translate\Controller\ProcessParams;
17
18 public const SETTING_ID = 'TRANSLATE_EXPORT';
19
20 public const ACTION_EXPORT = 'export';
21 public const ACTION_EXPORT_PATH = 'exportPath';
22 public const ACTION_EXPORT_FILE = 'exportFile';
23 public const ACTION_EXPORT_FILE_LIST = 'exportFileList';
24 public const ACTION_EXPORT_FILE_SEARCH = 'exportFileSearch';
25 public const ACTION_EXPORT_PHRASE_SEARCH = 'exportPhraseSearch';
26 public const ACTION_PURGE = 'purge';
27 public const ACTION_CANCEL = 'cancel';
28 public const ACTION_DOWNLOAD = 'download';
29 public const ACTION_CLEAR = 'clear';
30
32 private int $tabId = 0;
33
34 private Translate\Filter $filter;
35
36 private bool $convertEncoding;
37
38 private string $encodingOut;
39
40 private bool $collectUntranslated;
41
42 private bool $appendSamples;
43 private int $samplesCount = 10;
44 private array $samplesRestriction = [];
45
47 private array $languages;
48
50 private array $export;
51 private array $samples;
52
58 public function configureActions()
59 {
60 $configureActions = parent::configureActions();
61 $permission = new Translate\Controller\CheckPermission(Translate\Permission::READ);
62
63 $configureActions[self::ACTION_EXPORT] = [
64 '+prefilters' => [
65 $permission
66 ],
67 ];
68 $configureActions[self::ACTION_EXPORT_PATH] = [
69 'class' => Translate\Controller\Export\ExportPath::class,
70 '+prefilters' => [
71 $permission
72 ],
73 ];
74 $configureActions[self::ACTION_EXPORT_FILE] = [
75 'class' => Translate\Controller\Export\ExportFile::class,
76 '+prefilters' => [
77 $permission
78 ],
79 ];
80 $configureActions[self::ACTION_EXPORT_FILE_LIST] = [
81 'class' => Translate\Controller\Export\ExportFileList::class,
82 '+prefilters' => [
83 $permission
84 ],
85 ];
86 $configureActions[self::ACTION_EXPORT_FILE_SEARCH] = [
87 '+prefilters' => [
88 $permission
89 ],
90 ];
91 $configureActions[self::ACTION_EXPORT_PHRASE_SEARCH] = [
92 '+prefilters' => [
93 $permission
94 ],
95 ];
96
97 $configureActions[self::ACTION_PURGE] = [
98 '+prefilters' => [
99 $permission
100 ],
101 ];
102 $configureActions[self::ACTION_CANCEL] = [
103 '+prefilters' => [
104 $permission
105 ],
106 ];
107 $configureActions[self::ACTION_CLEAR] = [
108 '+prefilters' => [
109 $permission
110 ],
111 ];
112
113 $configureActions[self::ACTION_DOWNLOAD] = [
114 '-prefilters' => [
115 Main\Engine\ActionFilter\Csrf::class,
116 ],
117 '+prefilters' => [
118 $permission
119 ],
120 ];
121
122 return $configureActions;
123 }
124
125
131 protected function init()
132 {
133 parent::init();
134
135 if ($this->request->get('tabId') !== null)
136 {
137 $this->tabId = (int)$this->request->get('tabId');
138 $this->filter = new Translate\Filter($this->tabId);
139 }
140
141 // untranslated only
142 $this->collectUntranslated = ($this->request->get('collectUntranslated') === 'Y');
143
144 // with samples
145 $this->appendSamples = ($this->request->get('appendSamples') === 'Y');
146 $this->samplesCount = (int)$this->request->get('samplesCount') ?: 10;
147
148 $this->samplesRestriction = [];
149 if (!empty($this->request->get('samplesRestriction')))
150 {
151 $this->samplesRestriction = array_filter($this->request->get('samplesRestriction'), 'intVal');
152 }
153
154 // encoding
155 $this->convertEncoding = ($this->request->get('convertEncoding') === 'Y');
156
157 $this->encodingOut = '';
158 if ($this->convertEncoding)
159 {
160 $this->encodingOut = 'utf-8';
161 }
162
163 // languages
164 $enabledLanguages = Translate\Config::getEnabledLanguages();
165 $languages = $this->request->get('languages');
166 if (\is_array($languages) && !\in_array('all', $languages))
167 {
168 $languages = \array_intersect($languages, $enabledLanguages);
169 $sortLang = \array_flip($enabledLanguages);
170 \usort(
171 $languages,
172 function ($a, $b) use ($sortLang)
173 {
174 $a = $sortLang[$a];
175 $b = $sortLang[$b];
176 return (($a == $b) ? 1 : ($a < $b ? -1 : 1));
177 }
178 );
179 }
180 else
181 {
182 $languages = $enabledLanguages;
183 }
184 $this->languages = $languages;
185 }
186
187
197 public function exportAction($tabId, $path = ''): array
198 {
199 if (empty($tabId) || (int)$tabId <= 0)
200 {
201 throw new Main\ArgumentException("Missing 'tabId' parameter");
202 }
203 if (empty($path))
204 {
205 $path = Translate\Config::getDefaultPath();
206 }
207
209 $action = $this->detectAction($path);
210
211 $result = $action->run($path, true);
212
213 if (\count($action->getErrors()) > 0)
214 {
215 $this->addErrors($action->getErrors());
216 }
217
218 if ($action->hasProcessCompleted() && $result['TOTAL_ITEMS'] == 0)
219 {
220 $result['SUMMARY'] = Loc::getMessage('TR_EXPORT_VOID');
221 }
222 elseif ($action->hasProcessCompleted())
223 {
224 $fileProperties = $action->getDownloadingParameters();
225 $result['FILE_NAME'] = $fileProperties['fileName'];
226 $result['DOWNLOAD_LINK'] = $this->generateDownloadLink($fileProperties, 'export');
227
228 $messagePlaceholders = [
229 '#TOTAL_PHRASES#' => $result['TOTAL_PHRASES'],
230 '#FILE_SIZE_FORMAT#' => \CFile::formatSize($fileProperties['fileSize']),
231 '#FILE_NAME#' => $result['FILE_NAME'],
232 '#FILE_LINK#' => $result['DOWNLOAD_LINK'],
233 ];
234 $result['SUMMARY'] =
235 Loc::getMessage('TR_EXPORT_COMPLETED')
236 . "\n". Loc::getMessage('TR_EXPORT_ACTION_EXPORT', $messagePlaceholders)
237 . " ". Loc::getMessage('TR_EXPORT_DOWNLOAD', $messagePlaceholders)
238 ;
239
240 if ($this->appendSamples)
241 {
242 if ($result['TOTAL_SAMPLES'] > 0)
243 {
244 $fileSamplesProperties = $action->getDownloadingSamplesParameters();
245 $result['SAMPLES_LINK'] = $this->generateDownloadLink($fileSamplesProperties, 'samples');
246 $result['SAMPLES_FILE'] = $fileSamplesProperties['fileName'];
247
248 $messagePlaceholders = [
249 '#TOTAL_SAMPLES#' => $result['TOTAL_SAMPLES'],
250 '#FILE_SIZE_FORMAT#' => \CFile::formatSize($fileSamplesProperties['fileSize']),
251 '#FILE_NAME#' => $result['SAMPLES_FILE'],
252 '#FILE_LINK#' => $result['SAMPLES_LINK'],
253 ];
254 $result['SUMMARY'] .= "\n" . Loc::getMessage('TR_EXPORT_SAMPLES', $messagePlaceholders);
255 $result['SUMMARY'] .= " " . Loc::getMessage('TR_EXPORT_DOWNLOAD', $messagePlaceholders);
256 }
257 else
258 {
259 $result['SUMMARY'] .= "\n" . Loc::getMessage('TR_EXPORT_SAMPLES_NOT_FOUND');
260 }
261 }
262 }
263
264 return $result;
265 }
266
267
275 private function detectAction($path): ExportAction
276 {
277 // I. Based on pure file list.
278 $nextAction = self::ACTION_EXPORT_FILE_LIST;
279 $exporterClass = ExportFileList::class;
280
281 // II. Based on file search.
282 if (
283 !empty($this->filter['FILE_NAME'])
284 || !empty($this->filter['FOLDER_NAME'])
285 || !empty($this->filter['INCLUDE_PATHS'])
286 || !empty($this->filter['EXCLUDE_PATHS'])
287 )
288 {
290 $exporterClass = ExportFileSearch::class;
291 }
292
293 // III. List of files and folders
294 $pathList = $this->request->get('pathList');
295 if (!empty($pathList))
296 {
297 $nextAction = self::ACTION_EXPORT_PATH;
298 $exporterClass = ExportPath::class;
299 }
300
301 // IV. Based on phrase search.
302 if (
303 !empty($this->filter['PHRASE_CODE'])
304 || !empty($this->filter['INCLUDE_PHRASE_CODES'])
305 || !empty($this->filter['EXCLUDE_PHRASE_CODES'])
306 || !empty($this->filter['PHRASE_TEXT'])
307 )
308 {
310 $exporterClass = ExportPhraseSearch::class;
311
312 // V. List of files with codes
313 $codeList = $this->request->get('codeList');
314 if (!empty($pathList) && !empty($codeList))
315 {
316 $nextAction = self::ACTION_EXPORT_PATH;
317 $exporterClass = ExportPath::class;
318 }
319 }
320
321 // VI. Single file
322 if (\preg_match("/\.php$/", $path))
323 {
324 $nextAction = self::ACTION_EXPORT_FILE;
325 $exporterClass = ExportFile::class;
326 }
327
328
330 $action = new $exporterClass(
331 $nextAction,
332 $this,
333 [
334 'tabId' => $this->tabId,
335 'collectUntranslated' => $this->collectUntranslated,
336 'appendSamples' => $this->appendSamples,
337 'samplesCount' => $this->samplesCount,
338 'samplesRestriction' => $this->samplesRestriction,
339 'convertEncoding' => $this->convertEncoding,
340 'encodingOut' => $this->encodingOut,
341 'languages' => $this->languages,
342 'filter' => $this->filter,
343 ]
344 );
345
346 return $action;
347 }
348
349
358 public function clearAction($tabId): array
359 {
360 return $this->purgeAction($tabId);
361 }
362
363
372 public function purgeAction($tabId): array
373 {
374 $result = $this->cancelAction($tabId);
375
376 $result['SUMMARY'] = Loc::getMessage('TR_EXPORT_FILE_DROPPED');
377
378 return $result;
379 }
380
381
390 public function cancelAction($tabId): array
391 {
392 if (empty($tabId))
393 {
394 throw new Main\ArgumentException("Missing 'tabId' parameter");
395 }
396
397 $this
398 ->keepField('export')
399 ->keepField('samples')
400 ->restoreProgressParameters();
401
402 foreach (['export', 'samples'] as $type)
403 {
404 if (!empty($this->{$type}['filePath']))
405 {
406 $path = new Main\IO\File($this->{$type}['filePath']);
407 if ($path->isExists())
408 {
409 $path->delete();
410 }
411 }
412 }
413
415
416 return [
417 'SUMMARY' => Loc::getMessage('TR_EXPORT_ACTION_CANCEL'),
418 'STATUS' => Translate\Controller\STATUS_COMPLETED
419 ];
420 }
421
422
430 private function generateDownloadLink(array $params, string $type): string
431 {
432 $this->{$type} = $params;
433 $this->keepField($type)->saveProgressParameters();
434
435 return $this->getActionUri(self::ACTION_DOWNLOAD, ['tabId' => $this->tabId, 'type' => $type])->getUri();
436 }
437
446 public function downloadAction(int $tabId, string $type)
447 {
448 if ($tabId <= 0)
449 {
450 throw new Main\ArgumentException("Missing 'tabId' parameter");
451 }
452 if (empty($type) || !in_array($type, ['export', 'samples'], true))
453 {
454 throw new Main\ArgumentException("Missing 'type' parameter");
455 }
456
457 $this->keepField($type)->restoreProgressParameters();
458
459 if (!empty($this->{$type}['filePath']) && !empty($this->{$type}['fileName']))
460 {
461 $path = new Main\IO\File($this->{$type}['filePath']);
462 if ($path->isExists())
463 {
464 $response = new Main\Engine\Response\File(
465 $path->getPath(),
466 $this->{$type}['fileName'],
467 $this->{$type}['fileType']
468 );
469
470 return $response;
471 }
472 }
473
474 $this->addError(new Error('File not found'));
475 }
476}
getActionUri(string $actionName, array $params=[], bool $absolute=false)
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
downloadAction(int $tabId, string $type)
Definition csv.php:446