Download.php 19.6 KB
Newer Older
Carsten  Rose's avatar
Carsten Rose committed
1
2
3
4
5
6
<?php
/**
 * Created by PhpStorm.
 * User: crose
 * Date: 4/17/17
 * Time: 11:32 AM
Carsten  Rose's avatar
Carsten Rose committed
7
8
 *
 * Check: CODING.md > Download
Carsten  Rose's avatar
Carsten Rose committed
9
10
11
12
 */

namespace qfq;

13
//use TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException;
Carsten  Rose's avatar
Carsten Rose committed
14
15
16
17

require_once(__DIR__ . '/../Constants.php');
require_once(__DIR__ . '/../store/Session.php');
require_once(__DIR__ . '/../store/Store.php');
18
require_once(__DIR__ . '/../store/Sip.php');
Carsten  Rose's avatar
Carsten Rose committed
19
require_once(__DIR__ . '/../helper/OnArray.php');
20
require_once(__DIR__ . '/../helper/OnString.php');
21
require_once(__DIR__ . '/../helper/Logger.php');
22
require_once(__DIR__ . '/../helper/Sanitize.php');
23
require_once(__DIR__ . '/../helper/HelperFile.php');
Carsten  Rose's avatar
Carsten Rose committed
24
require_once(__DIR__ . '/../report/Html2Pdf.php');
25
require_once(__DIR__ . '/Thumbnail.php');
Carsten  Rose's avatar
Carsten Rose committed
26
require_once(__DIR__ . '/Monitor.php');
Carsten  Rose's avatar
Carsten Rose committed
27
require_once(__DIR__ . '/../exceptions/DownloadException.php');
28
29
require_once(__DIR__ . '/Excel.php');
require_once(__DIR__ . '/../helper/DownloadPage.php');
30
require_once(__DIR__ . '/../QuickFormQuery.php');
31

Carsten  Rose's avatar
Carsten Rose committed
32
33
34
35
36
37
38
//require_once(__DIR__ . '/../Evaluate.php');
//require_once(__DIR__ . '/../helper/KeyValueStringParser.php');
//

/**
 * Class Download
 *
39
40
 * Documentation: PROTOCOL.md >> Download
 *
Carsten  Rose's avatar
Carsten Rose committed
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
 * Param: i=1..n
 *   <i>_mode=direct | html2pdf
 *   <i>_id=<pageId>
 *   <i>_<key i>=<value i>
 *
 * @package qfq
 */
class Download {

    /**
     * @var Store
     */
    private $store = null;

    /**
     * @var Session
     */
    private $session = null;

    /**
     * @var Database
     */
    private $db = null;

    /**
     * @var Html2Pdf
     */
    private $html2pdf = null;

70
71
72
73
74
    /**
     * @var string Filename where to write download Information
     */
    private $downloadDebugLog = '';

75
76
77
78
79
    /**
     * @var string DOWNLOAD_OUTPUT_FORMAT_RAW | DOWNLOAD_OUTPUT_FORMAT_JSON
     */
    private $outputFormat = DOWNLOAD_OUTPUT_FORMAT_RAW;

Carsten  Rose's avatar
Carsten Rose committed
80
81
    /**
     * @param bool|false $phpUnit
82
     * @throws CodeException
83
     * @throws DbException
84
     * @throws UserFormException
Carsten  Rose's avatar
Carsten Rose committed
85
     * @throws UserReportException
Carsten  Rose's avatar
Carsten Rose committed
86
87
88
89
90
91
     */
    public function __construct($phpUnit = false) {

        $this->session = Session::getInstance($phpUnit);
        $this->store = Store::getInstance('', $phpUnit);
        $this->db = new Database();
92
        $this->html2pdf = new Html2Pdf($this->store->getStore(STORE_SYSTEM), $phpUnit);
93

94
        if (Support::findInSet(SYSTEM_SHOW_DEBUG_INFO_DOWNLOAD, $this->store->getVar(SYSTEM_SHOW_DEBUG_INFO, STORE_SYSTEM))) {
95
96
            $this->downloadDebugLog = $this->store->getVar(SYSTEM_SQL_LOG, STORE_SYSTEM);
        }
Carsten  Rose's avatar
Carsten Rose committed
97
98
99
100
101
102
    }

    /**
     * Concatenate all named files to one PDF file. Return name of new full PDF.
     *
     * @param array $files
Carsten  Rose's avatar
Carsten Rose committed
103
     *
Carsten  Rose's avatar
Carsten Rose committed
104
     * @return string  - fileName of concatenated file
105
     * @throws UserFormException
106
     * @throws DownloadException
Carsten  Rose's avatar
Carsten Rose committed
107
108
109
     */
    private function concatPdfFiles(array $files) {

110
111
112
        // Remove empty entries. Might happen if there was no upload
        $files = OnArray::removeEmptyElementsFromArray($files);

Carsten  Rose's avatar
Carsten Rose committed
113
        // Check that all files exist and are readable
114
        foreach ($files AS $filename) {
115
            if (!is_readable($filename)) {
116
                throw new DownloadException("Error reading file $filename. Not found or no permission", ERROR_DOWNLOAD_FILE_NOT_READABLE);
117
118
119
            }
        }

Carsten  Rose's avatar
Carsten Rose committed
120
121
122
        if (count($files) === 0) {
            return '';
        }
123

Carsten  Rose's avatar
Carsten Rose committed
124
125
126
127
        // Check that all files are of type 'application/pdf'
        foreach ($files AS $filename) {
            $mimetype = mime_content_type($filename);
            if ($mimetype != 'application/pdf') {
128
                throw new DownloadException("Error concat file $filename. Mimetype 'application/pdf' expected, got: $mimetype", ERROR_DOWNLOAD_UNEXPECTED_MIME_TYPE);
Carsten  Rose's avatar
Carsten Rose committed
129
130
131
            }
        }

Carsten  Rose's avatar
Carsten Rose committed
132
133
134
        if (count($files) == 1) {
            return $files[0];
        }
Carsten  Rose's avatar
Carsten Rose committed
135

Carsten  Rose's avatar
Carsten Rose committed
136
        $files = OnArray::arrayEscapeshellarg($files);
Carsten  Rose's avatar
Carsten Rose committed
137
138
139
140
141
        $inputFiles = implode(' ', $files);
        if (trim($inputFiles) == '') {
            throw new DownloadException('No files to concatenate.', ERROR_DOWNLOAD_NO_FILES);
        }

Carsten  Rose's avatar
Carsten Rose committed
142
143
144
145
146
147
        // Need to create a separate result file, even if it is just a single file (#6929)
        $concatFile = HelperFile::tempnam();
        if (false === $concatFile) {
            throw new DownloadException('Error creating output file.', ERROR_DOWNLOAD_CREATE_NEW_FILE);
        }

Carsten  Rose's avatar
Carsten Rose committed
148
149
        $cmd = "pdftk $inputFiles cat output $concatFile";

150
151
152
153
        if ($this->downloadDebugLog != '') {
            Logger::logMessage("Download: $cmd", $this->downloadDebugLog);
        }

Carsten  Rose's avatar
Carsten Rose committed
154
155
156
157
158
159
160
161
162
163
        exec($cmd, $output, $rc);

        if ($rc != 0) {
            throw new DownloadException ("<p>Failed: RC=$rc   $cmd</p>" . implode("<br>", $output));
        }

        return $concatFile;
    }

    /**
164
165
     * Get the mimetype of $filename and store them in $rcMimetype.
     * Checks if the extension of $outputFilename fit's to the mimetype. If not, append the mimetype extension.
Carsten  Rose's avatar
Carsten Rose committed
166
     *
167
168
169
     * @param string $filename
     * @param string $outputFilename
     * @param string $rcMimetype
Carsten  Rose's avatar
Carsten Rose committed
170
     *
171
     * @return string possible updated $outputFilename, according the mimetype.
Carsten  Rose's avatar
Carsten Rose committed
172
     */
173
    private function targetFilenameExtension($filename, $outputFilename, &$rcMimetype) {
Carsten  Rose's avatar
Carsten Rose committed
174

175
        $rcMimetype = mime_content_type($filename);
176

177
178
179
180
181
182
        return $outputFilename;
    }

    /**
     * Set header type and output $filename. Be careful not to send any additional characters.
     *
183
     * @param $file
184
     * @param $outputFilename
185
     * @throws DownloadException
186
     */
187
    private function outputFile($file, $outputFilename) {
188

189
190
        $json = '';
        $flagJson = ($this->getOutputFormat() === DOWNLOAD_OUTPUT_FORMAT_JSON);
191

192
        $outputFilename = $this->targetFilenameExtension($file, $outputFilename, $mimeType);
193
        $outputFilename = Sanitize::safeFilename($outputFilename); // be sure that there are no problematic chars in the filename. E.g. MacOS X don't like spaces for downloads.
194

195
196
197
198
        if ($flagJson) {
            if (false === ($json = json_encode([JSON_TEXT => file_get_contents($file)]))) {
                throw new DownloadException(json_encode(
                    [ERROR_MESSAGE_TO_USER => 'Error converting to JSON',
Marc Egger's avatar
Marc Egger committed
199
                        ERROR_MESSAGE_TO_DEVELOPER => "json_last_error()=" . json_last_error() . ", File=" . $file]), ERROR_DOWNLOAD_JSON_CONVERT);
200
201
202
203
204
205
206
207
208
            }
            $length = strlen($json);

            $mimeType = 'application/json';
        } else {
            $length = filesize($file);
        }

        header("Content-type: $mimeType");
Carsten  Rose's avatar
Carsten Rose committed
209
        header("Content-Length: $length");
210
        if (!$flagJson) {
211
212
213
214
            // If defined as 'attachment': PDFs are not shown inside the browser (if user configured that). Instead, always a 'save as'-dialog appears (Chrome, FF)
            // header("Content-Disposition: attachment; filename=$outputFilename");
            header("Content-Disposition: inline; filename=\"$outputFilename\"; name=\"$outputFilename\"");
        }
Carsten  Rose's avatar
Carsten Rose committed
215
216
        header("Pragma: no-cache");
        header("Expires: 0");
Carsten  Rose's avatar
Carsten Rose committed
217

218
219
        if ($flagJson) {
            print $json;
220
        } else {
221
            readfile($file);
222
        }
Carsten  Rose's avatar
Carsten Rose committed
223
224
225
    }

    /**
226
     * Interprets $element and fetches corresponding content, either as a file or the content in a variable.
Carsten  Rose's avatar
Carsten Rose committed
227
228
     *
     * @param string $element - U:id=myExport&r=12, u:http://www.nzz.ch/issue?nr=21, f:fileadmin/sample.pdf
Carsten  Rose's avatar
Carsten Rose committed
229
     *
230
     * @param string $downloadMode - DOWNLOAD_MODE_EXCEL | ....
231
     * @param string $rcData - With $downloadMode=DOWNLOAD_MODE_EXCEL, this contains the rendered code from the given T3 page.
Carsten  Rose's avatar
Carsten Rose committed
232
     * @return string filename - already ready or fresh exported. Fresh exported needs to be deleted later.
233
     * @throws CodeException
234
     * @throws DbException
Carsten  Rose's avatar
Carsten Rose committed
235
     * @throws DownloadException
236
     * @throws UserFormException
237
     * @throws UserReportException
238
239
240
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
Carsten  Rose's avatar
Carsten Rose committed
241
     */
242
    private function getElement($element, $downloadMode, &$rcData) {
Carsten  Rose's avatar
Carsten Rose committed
243

244
245
246
247
        $filename = '';
        $rcArgs = array();
        $rcSipEncode = false;

Carsten  Rose's avatar
Carsten Rose committed
248
249
        $arr = explode(':', $element, 2);
        if (count($arr) != 2) {
250
251
            $possibleReason = ($element === '') ? 'If this is a download link, did you forget to include s:1?' : '';
            throw new DownloadException("Missing parameter for '$element'. $possibleReason", ERROR_MISSING_REQUIRED_PARAMETER);
Carsten  Rose's avatar
Carsten Rose committed
252
        }
Carsten  Rose's avatar
Carsten Rose committed
253

Carsten  Rose's avatar
Carsten Rose committed
254
255
        $token = $arr[0];
        $value = $arr[1];
256
257
258
259
260
        if ($token === TOKEN_UID) { // extract uid
            $uidParamsArr = explode('&', $value, 2);
            $uid = $uidParamsArr[0];
            $value = $uidParamsArr[1] ?? ''; // additional params
        }
Carsten  Rose's avatar
Carsten Rose committed
261

Carsten  Rose's avatar
Carsten Rose committed
262
263
264
        switch ($token) {
            case TOKEN_URL:
            case TOKEN_URL_PARAM:
265
            case TOKEN_PAGE:
266
            case TOKEN_UID:
267
268
269
270
271
272
                $urlParam = OnString::splitParam($value, $rcArgs, $rcSipEncode);
                $urlParamString = KeyValueStringParser::unparse($urlParam, '=', '&');
                if ($rcSipEncode) {
                    $sip = new Sip();
                    $urlParamString = $sip->queryStringToSip($urlParamString, RETURN_URL);
                }
273

274
                if ($downloadMode == DOWNLOAD_MODE_EXCEL) {
275
                    if ($token === TOKEN_UID) {
276
                        $rcData = $this->getEvaluatedBodytext($uid, $urlParam);
277
278
279
280
                    } else {
                        $baseUrl = $this->store->getVar(SYSTEM_BASE_URL, STORE_SYSTEM);
                        $rcData = DownloadPage::getContent($urlParamString, $baseUrl);
                    }
281
                } else {
282
283
284
285
286
                    if ($token === TOKEN_UID) {
                        // create tmp html document with bodytext
                        $htmlText = $this->getEvaluatedBodytext($uid, $urlParam);
                        $tmpFilename = HelperFile::tempnam() . '.html';

287
                        $tmpFile = fopen($tmpFilename, "w") or die('Cannot create file:  ' . $tmpFilename);
288
289
290
291
292
                        fwrite($tmpFile, $htmlText);
                        fclose($tmpFile);

                        $rcArgsString = KeyValueStringParser::unparse($rcArgs, '=', '&');
                        $url = Support::mergeUrlComponents('', $tmpFilename, $rcArgsString);
293
294
295
                        $filename = $this->html2pdf->page2pdf($token, $url);
                        HelperFile::cleanTempFiles([$tmpFilename]);

296
                    } else {
297
                        $filename = $this->html2pdf->page2pdf($token, $value);
298
                    }
299
                }
Carsten  Rose's avatar
Carsten Rose committed
300
                break;
Carsten  Rose's avatar
Carsten Rose committed
301

Carsten  Rose's avatar
Carsten Rose committed
302
            case TOKEN_FILE:
303
            case TOKEN_FILE_DEPRECATED:
Carsten  Rose's avatar
Carsten Rose committed
304
305
306
307
308
                $filename = $value;
                break;
            default:
                throw new DownloadException('Unknown token: "' . $token . '"', ERROR_UNKNOWN_TOKEN);
                break;
Carsten  Rose's avatar
Carsten Rose committed
309
310
311
312
313
        }

        return $filename;
    }

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
    /**
     * @param $uid
     * @param array $urlParam
     *
     * @return string
     * @throws CodeException
     * @throws DbException
     * @throws DownloadException
     * @throws UserFormException
     * @throws UserReportException
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    private function getEvaluatedBodyText($uid, $urlParam) {
329
        foreach ($urlParam as $key => $paramValue) {
330
331
332
            $this->store->setVar($key, $paramValue, STORE_SIP);
        }

333
        $dbT3 = $this->store->getVar(SYSTEM_DB_NAME_T3, STORE_SYSTEM);
334
335
336
        $sql = "SELECT bodytext FROM $dbT3.tt_content WHERE uid = ?";
        $tt_content = $this->db->sql($sql, ROW_EXPECT_1, [$uid]);

337
        $qfq = new QuickFormQuery([T3DATA_BODYTEXT => $tt_content[T3DATA_BODYTEXT]], false, false);
338
339
340
341
        return $qfq->process();

    }

Carsten  Rose's avatar
Carsten Rose committed
342
343
344
345
346

    /**
     * Creates a ZIP Files of all given $files
     *
     * @param array $files
Carsten  Rose's avatar
Carsten Rose committed
347
     *
Carsten  Rose's avatar
Carsten Rose committed
348
349
350
351
352
     * @return string ZIP filename - has to be deleted later.
     * @throws DownloadException
     */
    private function zipFiles(array $files) {

353
        $zipFile = HelperFile::tempnam();
Carsten  Rose's avatar
Carsten Rose committed
354
355
356
357
358
359
        if (false === $zipFile) {
            throw new DownloadException("Error creating output file.", ERROR_DOWNLOAD_CREATE_NEW_FILE);
        }

        $zip = new \ZipArchive();

Carsten  Rose's avatar
Carsten Rose committed
360
        if ($zip->open($zipFile, \ZipArchive::CREATE) !== true) {
Carsten  Rose's avatar
Carsten Rose committed
361
362
363
            throw new DownloadException("Error creating/opening new empty zip file: $zipFile", ERROR_IO_OPEN);
        }

364
        $len = strlen(TMP_FILE_PREFIX);
365
        $ii = 1;
Carsten  Rose's avatar
Carsten Rose committed
366
        foreach ($files AS $filename) {
367
            $localName = substr($filename, strrpos($filename, '/') + 1);
368

369
370
            if (substr($localName, 0, $len) == TMP_FILE_PREFIX) {
                $localName = 'file-' . $ii;
371
372
373
                $ii++;
            }

374
            $zip->addFile($filename, $localName);
Carsten  Rose's avatar
Carsten Rose committed
375
376
377
378
379
380
        }
        $zip->close();

        return $zipFile;
    }

Carsten  Rose's avatar
Carsten Rose committed
381
    /**
382
383
     * $vars[DOWNLOAD_EXPORT_FILENAME] - Optional. '<new filename>'
     * $vars[DOWNLOAD_MODE] - Optional.  file | pdf | excel | thumbnail | monitor - default is a) 'file' in case of only one or b) 'pdf' in case of multiple sources.
Carsten  Rose's avatar
Carsten Rose committed
384
385
386
387
     * HTML to PDF | Excel
     *   <i>_id=<Typo3 pageId>
     *   <i>_<key>=<value i>
     * Direct
388
     *   <i>_file=<filename>
Carsten  Rose's avatar
Carsten Rose committed
389
     *
Carsten  Rose's avatar
Carsten Rose committed
390
     * @param array $vars [ DOWNLOAD_EXPORT_FILENAME, DOWNLOAD_MODE, SIP_DOWNLOAD_PARAMETER ]
Carsten  Rose's avatar
Carsten Rose committed
391
     *
Carsten  Rose's avatar
Carsten Rose committed
392
393
     * @param string $outputMode OUTPUT_MODE_DIRECT | OUTPUT_MODE_FILE | OUTPUT_MODE_COPY_TO_FILE
     * @return string            Filename of the generated file. The filename only points to a real existing filename with  $outputMode=OUTPUT_MODE_FILE | OUTPUT_MODE_COPY_TO_FILE
394
     * @throws CodeException
395
     * @throws DbException
Carsten  Rose's avatar
Carsten Rose committed
396
     * @throws DownloadException
397
398
     * @throws UserFormException
     * @throws UserReportException
399
400
401
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
Carsten  Rose's avatar
Carsten Rose committed
402
     */
403
    private function doElements(array $vars, $outputMode) {
Carsten  Rose's avatar
Carsten Rose committed
404
405
406
407

        $tmpFiles = array();

        $workDir = $this->store->getVar(SYSTEM_SITE_PATH, STORE_SYSTEM);
408
        HelperFile::chdir($workDir);
Carsten  Rose's avatar
Carsten Rose committed
409

Carsten  Rose's avatar
Carsten Rose committed
410
        $downloadMode = $vars[DOWNLOAD_MODE];
411

412
        if ($downloadMode == DOWNLOAD_MODE_MONITOR) {
413
            $monitor = new Monitor();
Carsten  Rose's avatar
Carsten Rose committed
414
415

            return $monitor->dump($vars[TOKEN_L_FILE], $vars[TOKEN_L_TAIL], $vars[TOKEN_L_APPEND]);
416
417
        }

418
419
420
421
422
423
424
        if ($downloadMode == DOWNLOAD_MODE_THUMBNAIL) {
            // Fake $vars control array.
            $pathFilenameThumbnail = $this->doThumbnail($vars[SIP_DOWNLOAD_PARAMETER]);
            $downloadMode = DOWNLOAD_MODE_FILE;
            $vars[SIP_DOWNLOAD_PARAMETER] = TOKEN_FILE . ':' . $pathFilenameThumbnail;
        }

Carsten  Rose's avatar
Carsten Rose committed
425
        $elements = explode(PARAM_DELIMITER, $vars[SIP_DOWNLOAD_PARAMETER]);
Carsten  Rose's avatar
Carsten Rose committed
426

427
        // Get all files / content
428
        $tmpData = array();
Carsten  Rose's avatar
Carsten Rose committed
429
        foreach ($elements as $element) {
430
            $data = '';
431
            $tmpFiles[] = $this->getElement($element, $downloadMode, $data);
432
433
            if (!empty($data)) {
                $tmpData[] = $data;
434
            }
Carsten  Rose's avatar
Carsten Rose committed
435
436
        }

Carsten  Rose's avatar
Carsten Rose committed
437
438
439
440
        // Export, Concat File(s)
        switch ($downloadMode) {
            case DOWNLOAD_MODE_ZIP:
                $filename = $this->zipFiles($tmpFiles);
441
442
443
                if (empty($vars[DOWNLOAD_EXPORT_FILENAME])) {
                    $vars[DOWNLOAD_EXPORT_FILENAME] = basename($filename);
                }
Carsten  Rose's avatar
Carsten Rose committed
444
445
446
                break;

            case DOWNLOAD_MODE_EXCEL:
447
448
449
450
451
452
453
454
455
                $excel = new Excel();
                $filename = $excel->process($tmpFiles, $tmpData);
                if (empty($vars[DOWNLOAD_EXPORT_FILENAME])) {
                    if (HelperFile::isQfqTemp($filename)) {
                        $vars[DOWNLOAD_EXPORT_FILENAME] = DOWNLOAD_OUTPUT_FILENAME . ".xlsx";
                    } else {
                        $vars[DOWNLOAD_EXPORT_FILENAME] = basename($filename);
                    }
                }
Carsten  Rose's avatar
Carsten Rose committed
456
457
                break;

Carsten  Rose's avatar
Carsten Rose committed
458
            case DOWNLOAD_MODE_FILE:
Carsten  Rose's avatar
Carsten Rose committed
459
                $filename = $tmpFiles[0];
460
                if (empty($vars[DOWNLOAD_EXPORT_FILENAME])) {
461
                    $vars[DOWNLOAD_EXPORT_FILENAME] = basename($filename);
462
                }
Carsten  Rose's avatar
Carsten Rose committed
463
                break;
Carsten  Rose's avatar
Carsten Rose committed
464
465

            case DOWNLOAD_MODE_PDF:
466

Carsten  Rose's avatar
Carsten Rose committed
467
                $filename = $this->concatPdfFiles($tmpFiles);
468

469
470
471
472
473
474
475
476
477
478
479
480
                // try to find a meaningful filename
                if (empty($vars[DOWNLOAD_EXPORT_FILENAME])) {
                    if (count($tmpFiles) > 1) {
                        $vars[DOWNLOAD_EXPORT_FILENAME] = DOWNLOAD_OUTPUT_FILENAME . ".pdf";
                    } else {
                        if (HelperFile::isQfqTemp($filename)) {
                            $vars[DOWNLOAD_EXPORT_FILENAME] = DOWNLOAD_OUTPUT_FILENAME . ".pdf";
                        } else {
                            $vars[DOWNLOAD_EXPORT_FILENAME] = basename($filename);
                        }
                    }
                }
Carsten  Rose's avatar
Carsten Rose committed
481
482
483
484
                break;

            default:
                throw new DownloadException("Unknown downloadMode: $downloadMode", ERROR_UNKNOWN_MODE);
Carsten  Rose's avatar
Carsten Rose committed
485
486
487
                break;
        }

488
489
490
        if ($filename != '' && !file_exists($filename)) {
            throw new DownloadException(json_encode(
                [ERROR_MESSAGE_TO_USER => 'Can\'t read file',
Marc Egger's avatar
Marc Egger committed
491
                    ERROR_MESSAGE_TO_DEVELOPER => "File: $filename"]), ERROR_IO_FILE_EXIST);
492
493
        }

494
495
496
497
498
        switch ($outputMode) {

            case OUTPUT_MODE_FILE:
                break;

Carsten  Rose's avatar
Carsten Rose committed
499
500
501
502
503
            case OUTPUT_MODE_COPY_TO_FILE:
                HelperFile::copy($filename, $vars[DOWNLOAD_EXPORT_FILENAME]);
                HelperFile::cleanTempFiles([$filename]);
                break;

504
            case OUTPUT_MODE_DIRECT:
505
                $this->outputFile($filename, $vars[DOWNLOAD_EXPORT_FILENAME]);
506
                HelperFile::cleanTempFiles([$filename]);
507
                $filename = '';
508
                break;
Carsten  Rose's avatar
Carsten Rose committed
509

510
511
512
513
514
            default:
                throw new CodeException('Unkown mode: ' . $outputMode, ERROR_UNKNOWN_MODE);
        }

        return $filename;
Carsten  Rose's avatar
Carsten Rose committed
515
516
    }

517
518
519
    /**
     * @param string $urlParam
     * @return string
Carsten  Rose's avatar
Carsten Rose committed
520
     * @throws CodeException
521
     * @throws UserFormException
522
523
524
525
526
527
528
529
530
531
     * @throws UserReportException
     */
    private function doThumbnail($urlParam) {

        $thumbnail = new Thumbnail();
        $pathFilenameThumbnail = $thumbnail->process($urlParam, THUMBNAIL_VIA_DOWNLOAD);

        return $pathFilenameThumbnail;
    }

Carsten  Rose's avatar
Carsten Rose committed
532
    /**
533
534
     * Process download as requested in $vars. Output is either directly send to the browser, or a file which has to be deleted later.
     *
535
     * @param string|array $vars - If $config is an array, take it, else get values from STORE_SIP
536
537
     * @param string $outputMode OUTPUT_MODE_DIRECT | OUTPUT_MODE_FILE
     *
Carsten  Rose's avatar
Carsten Rose committed
538
539
     * @return string
     * @throws CodeException
540
     * @throws DbException
541
     * @throws DownloadException
Carsten  Rose's avatar
Carsten Rose committed
542
     * @throws UserFormException
Carsten  Rose's avatar
Carsten Rose committed
543
     * @throws UserReportException
544
545
546
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
Carsten  Rose's avatar
Carsten Rose committed
547
     */
548
    public function process($vars, $outputMode = OUTPUT_MODE_DIRECT) {
Carsten  Rose's avatar
Carsten Rose committed
549

550
551
552
        if (!is_array($vars)) {
            $vars = $this->store->getStore(STORE_SIP);
        }
553

554
555
        $this->setOutputFormat(empty($vars[DOWNLOAD_OUTPUT_FORMAT]) ? DOWNLOAD_OUTPUT_FORMAT_RAW : $vars[DOWNLOAD_OUTPUT_FORMAT]);

556
        return $this->doElements($vars, $outputMode);
Carsten  Rose's avatar
Carsten Rose committed
557
558
    }

559
560
561
562
563
564
565
566
567
568
569
570
571
    /**
     * @param $outputFormat
     */
    private function setOutputFormat($outputFormat) {
        $this->outputFormat = $outputFormat;
    }

    /**
     * @return string - DOWNLOAD_OUTPUT_FORMAT_RAW | DOWNLOAD_OUTPUT_FORMAT_JSON
     */
    public function getOutputFormat() {
        return $this->outputFormat;
    }
572
}
Carsten  Rose's avatar
Carsten Rose committed
573