|
1
|
|
|
<?php |
|
2
|
|
|
namespace Fab\Vidi\ViewHelpers\Result; |
|
3
|
|
|
|
|
4
|
|
|
/* |
|
5
|
|
|
* This file is part of the Fab/Vidi project under GPLv2 or later. |
|
6
|
|
|
* |
|
7
|
|
|
* For the full copyright and license information, please read the |
|
8
|
|
|
* LICENSE.md file that was distributed with this source code. |
|
9
|
|
|
*/ |
|
10
|
|
|
|
|
11
|
|
|
use Fab\Vidi\Tca\FieldType; |
|
12
|
|
|
use Fab\Vidi\View\Grid\Rows; |
|
13
|
|
|
use TYPO3\CMS\Core\Resource\File; |
|
14
|
|
|
use TYPO3\CMS\Core\Utility\GeneralUtility; |
|
15
|
|
|
use Fab\Vidi\Domain\Model\Content; |
|
16
|
|
|
use Fab\Vidi\Service\FileReferenceService; |
|
17
|
|
|
use Fab\Vidi\Tca\Tca; |
|
18
|
|
|
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; |
|
19
|
|
|
|
|
20
|
|
|
/** |
|
21
|
|
|
* Abstract View helper for rendering an Export request. |
|
22
|
|
|
*/ |
|
23
|
|
|
abstract class AbstractToFormatViewHelper extends AbstractViewHelper |
|
24
|
|
|
{ |
|
25
|
|
|
|
|
26
|
|
|
/** |
|
27
|
|
|
* Store fields of type "file". |
|
28
|
|
|
* |
|
29
|
|
|
* @var array |
|
30
|
|
|
*/ |
|
31
|
|
|
protected $fileTypeProperties = []; |
|
32
|
|
|
|
|
33
|
|
|
/** |
|
34
|
|
|
* @var File[] |
|
35
|
|
|
*/ |
|
36
|
|
|
protected $collectedFiles = []; |
|
37
|
|
|
|
|
38
|
|
|
/** |
|
39
|
|
|
* @var string |
|
40
|
|
|
*/ |
|
41
|
|
|
protected $exportFileNameAndPath; |
|
42
|
|
|
|
|
43
|
|
|
/** |
|
44
|
|
|
* @var string |
|
45
|
|
|
*/ |
|
46
|
|
|
protected $zipFileNameAndPath; |
|
47
|
|
|
|
|
48
|
|
|
/** |
|
49
|
|
|
* @var string |
|
50
|
|
|
*/ |
|
51
|
|
|
protected $temporaryDirectory; |
|
52
|
|
|
|
|
53
|
|
|
|
|
54
|
|
|
/** |
|
55
|
|
|
* Write the zip file to a temporary location. |
|
56
|
|
|
* |
|
57
|
|
|
* @return void |
|
58
|
|
|
* @throws \RuntimeException |
|
59
|
|
|
*/ |
|
60
|
|
|
protected function writeZipFile() |
|
61
|
|
|
{ |
|
62
|
|
|
|
|
63
|
|
|
$zip = new \ZipArchive(); |
|
64
|
|
|
$zip->open($this->zipFileNameAndPath, \ZipArchive::CREATE); |
|
65
|
|
|
|
|
66
|
|
|
// Add the CSV content into the zipball. |
|
67
|
|
|
$zip->addFile($this->exportFileNameAndPath, basename($this->exportFileNameAndPath)); |
|
68
|
|
|
|
|
69
|
|
|
// Add the files into the zipball. |
|
70
|
|
|
foreach ($this->collectedFiles as $file) { |
|
71
|
|
|
$zip->addFile($file->getForLocalProcessing(false), $file->getIdentifier()); |
|
72
|
|
|
} |
|
73
|
|
|
|
|
74
|
|
|
$zip->close(); |
|
75
|
|
|
} |
|
76
|
|
|
|
|
77
|
|
|
/** |
|
78
|
|
|
* Initialize some properties |
|
79
|
|
|
* |
|
80
|
|
|
* @param array $objects |
|
81
|
|
|
* @return void |
|
82
|
|
|
*/ |
|
83
|
|
|
protected function initializeEnvironment(array $objects) |
|
84
|
|
|
{ |
|
85
|
|
|
|
|
86
|
|
|
/** @var \Fab\Vidi\Domain\Model\Content $object */ |
|
87
|
|
|
$object = reset($objects); |
|
88
|
|
|
|
|
89
|
|
|
$this->temporaryDirectory = PATH_site . 'typo3temp/' . uniqid() . '/'; |
|
90
|
|
|
GeneralUtility::mkdir($this->temporaryDirectory); |
|
91
|
|
|
|
|
92
|
|
|
// Compute file name and path variable |
|
93
|
|
|
$this->exportFileNameAndPath = $this->temporaryDirectory . $object->getDataType() . '-' . date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy']); |
|
94
|
|
|
|
|
95
|
|
|
// Compute file name and path variable for zip |
|
96
|
|
|
$zipFileName = $object->getDataType() . '-' . date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy']) . '.zip'; |
|
97
|
|
|
$this->zipFileNameAndPath = $this->temporaryDirectory . $zipFileName; |
|
98
|
|
|
} |
|
99
|
|
|
|
|
100
|
|
|
/** |
|
101
|
|
|
* Fetch the files given an object. |
|
102
|
|
|
* |
|
103
|
|
|
* @param \Fab\Vidi\Domain\Model\Content $object |
|
104
|
|
|
* @return void |
|
105
|
|
|
*/ |
|
106
|
|
|
protected function collectFiles(Content $object) |
|
107
|
|
|
{ |
|
108
|
|
|
foreach ($this->fileTypeProperties as $property) { |
|
109
|
|
|
$files = FileReferenceService::getInstance()->findReferencedBy($property, $object); |
|
110
|
|
|
foreach ($files as $file) { |
|
111
|
|
|
$this->collectedFiles[$file->getUid()] = $file; |
|
112
|
|
|
} |
|
113
|
|
|
} |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
/** |
|
117
|
|
|
* Tells whether the object has fields containing files. |
|
118
|
|
|
* |
|
119
|
|
|
* @return boolean |
|
120
|
|
|
*/ |
|
121
|
|
|
protected function hasCollectedFiles() |
|
122
|
|
|
{ |
|
123
|
|
|
return !empty($this->collectedFiles); |
|
124
|
|
|
} |
|
125
|
|
|
|
|
126
|
|
|
/** |
|
127
|
|
|
* Tells whether the object has fields containing files. |
|
128
|
|
|
* |
|
129
|
|
|
* @return boolean |
|
130
|
|
|
*/ |
|
131
|
|
|
protected function hasFileFields() |
|
132
|
|
|
{ |
|
133
|
|
|
return !empty($this->fileTypeProperties); |
|
134
|
|
|
} |
|
135
|
|
|
|
|
136
|
|
|
/** |
|
137
|
|
|
* Check whether the given object is meant to include files in some fields. |
|
138
|
|
|
* |
|
139
|
|
|
* @param Content $object |
|
140
|
|
|
* @return void |
|
141
|
|
|
* @throws \Fab\Vidi\Exception\NotExistingClassException |
|
142
|
|
|
*/ |
|
143
|
|
|
protected function checkWhetherObjectMayIncludeFiles(Content $object) |
|
144
|
|
|
{ |
|
145
|
|
|
if (Tca::grid($object->getDataType())->areFilesIncludedInExport()) { |
|
146
|
|
|
foreach ($object->toFields() as $fieldName) { |
|
147
|
|
|
$fieldType = Tca::table($object->getDataType())->field($fieldName)->getType(); |
|
148
|
|
|
|
|
149
|
|
|
if ($fieldType === FieldType::FILE) { |
|
150
|
|
|
$this->fileTypeProperties[] = GeneralUtility::camelCaseToLowerCaseUnderscored($fieldName); |
|
151
|
|
|
} |
|
152
|
|
|
} |
|
153
|
|
|
} |
|
154
|
|
|
} |
|
155
|
|
|
|
|
156
|
|
|
/** |
|
157
|
|
|
* @return void |
|
158
|
|
|
* @throws \InvalidArgumentException |
|
159
|
|
|
* @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception\InvalidVariableException |
|
160
|
|
|
*/ |
|
161
|
|
View Code Duplication |
protected function sendZipHttpHeaders() |
|
|
|
|
|
|
162
|
|
|
{ |
|
163
|
|
|
/** @var \TYPO3\CMS\Extbase\Mvc\Web\Response $response */ |
|
164
|
|
|
$response = $this->templateVariableContainer->get('response'); |
|
165
|
|
|
$response->setHeader('Pragma', 'public'); |
|
166
|
|
|
$response->setHeader('Expires', '0'); |
|
167
|
|
|
$response->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0'); |
|
168
|
|
|
$response->setHeader('Content-Type', 'application/zip'); |
|
169
|
|
|
$response->setHeader('Content-Disposition', 'attachment; filename="' . basename($this->zipFileNameAndPath) . '"'); |
|
170
|
|
|
$response->setHeader('Content-Length', filesize($this->zipFileNameAndPath)); |
|
171
|
|
|
$response->setHeader('Content-Description', 'File Transfer'); |
|
172
|
|
|
$response->setHeader('Content-Transfer-Encoding', 'binary'); |
|
173
|
|
|
|
|
174
|
|
|
$response->sendHeaders(); |
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
/** |
|
178
|
|
|
* @return Rows|object |
|
179
|
|
|
*/ |
|
180
|
|
|
protected function getRowsView() |
|
181
|
|
|
{ |
|
182
|
|
|
return GeneralUtility::makeInstance(Rows::class); |
|
183
|
|
|
} |
|
184
|
|
|
|
|
185
|
|
|
/** |
|
186
|
|
|
* Returns a pointer to the database. |
|
187
|
|
|
* |
|
188
|
|
|
* @return \Fab\Vidi\Database\DatabaseConnection |
|
189
|
|
|
*/ |
|
190
|
|
|
protected function getDatabaseConnection() |
|
191
|
|
|
{ |
|
192
|
|
|
return $GLOBALS['TYPO3_DB']; |
|
193
|
|
|
} |
|
194
|
|
|
} |
|
195
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.