2 namespace TYPO3\CMS\Extensionmanager\Utility
;
4 /***************************************************************
7 * (c) 2012 Susanne Moog <susanne.moog@typo3.org>
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
30 * Utility for dealing with files and folders
32 * @author Susanne Moog <susanne.moog@typo3.org>
33 * @package Extension Manager
36 class FileHandlingUtility
implements \TYPO3\CMS\Core\SingletonInterface
{
39 * @var \TYPO3\CMS\Extensionmanager\Utility\EmConfUtility
41 protected $emConfUtility;
44 * Injector for Tx_Extensionmanager_Utility_EmConf
46 * @param \TYPO3\CMS\Extensionmanager\Utility\EmConfUtility $emConfUtility
49 public function injectEmConfUtility(\TYPO3\CMS\Extensionmanager\Utility\EmConfUtility
$emConfUtility) {
50 $this->emConfUtility
= $emConfUtility;
54 * @var \TYPO3\CMS\Extensionmanager\Utility\InstallUtility
56 protected $installUtility;
59 * Injector for Tx_Extensionmanager_Utility_Install
61 * @param \TYPO3\CMS\Extensionmanager\Utility\InstallUtility $installUtility
64 public function injectInstallUtility(\TYPO3\CMS\Extensionmanager\Utility\InstallUtility
$installUtility) {
65 $this->installUtility
= $installUtility;
69 * Unpack an extension in t3x data format and write files
71 * @param array $extensionData
72 * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension
73 * @param string $pathType
76 public function unpackExtensionFromExtensionDataArray(array $extensionData, \TYPO3\CMS\Extensionmanager\Domain\Model\Extension
$extension = NULL, $pathType = 'Local') {
77 $extensionDir = $this->makeAndClearExtensionDir($extensionData['extKey'], $pathType);
78 $files = $this->extractFilesArrayFromExtensionData($extensionData);
79 $directories = $this->extractDirectoriesFromExtensionData($files);
80 $this->createDirectoriesForExtensionFiles($directories, $extensionDir);
81 $this->writeExtensionFiles($files, $extensionDir);
82 $this->writeEmConfToFile($extensionData, $extensionDir, $extension);
86 * Extract needed directories from given extensionDataFilesArray
91 protected function extractDirectoriesFromExtensionData(array $files) {
92 $directories = array();
93 foreach ($files as $filePath => $file) {
94 preg_match('/(.*)\\//', $filePath, $matches);
95 $directories[] = $matches[0];
101 * Returns the "FILES" part from the data array
103 * @param array $extensionData
106 protected function extractFilesArrayFromExtensionData(array $extensionData) {
107 return $extensionData['FILES'];
111 * Loops over an array of directories and creates them in the given root path
112 * It also creates nested directory structures
114 * @param array $directories
115 * @param string $rootPath
118 protected function createDirectoriesForExtensionFiles(array $directories, $rootPath) {
119 foreach ($directories as $directory) {
120 \TYPO3\CMS\Core\Utility\GeneralUtility
::mkdir_deep($rootPath . $directory);
125 * Loops over an array of files and writes them to the given rootPath
127 * @param array $files
128 * @param string $rootPath
131 protected function writeExtensionFiles(array $files, $rootPath) {
132 foreach ($files as $file) {
133 \TYPO3\CMS\Core\Utility\GeneralUtility
::writeFile($rootPath . $file['name'], $file['content']);
138 * Removes the current extension of $type and creates the base folder for
139 * the new one (which is going to be imported)
141 * @param string $extensionkey
142 * @param string $pathType Extension installation scope (Local,Global,System)
143 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
146 protected function makeAndClearExtensionDir($extensionkey, $pathType = 'Local') {
147 $paths = \TYPO3\CMS\Extensionmanager\Domain\Model\Extension
::returnInstallPaths();
148 $path = $paths[$pathType];
149 if (!$path ||
!is_dir($path) ||
!$extensionkey) {
150 throw new \TYPO3\CMS\Extensionmanager\Exception\
ExtensionManagerException(sprintf('ERROR: The extension install path "%s" was no directory!', $path), 1337280417);
152 $extDirPath = $path . $extensionkey . '/';
153 if (is_dir($extDirPath)) {
154 $this->removeDirectory($extDirPath);
156 $this->addDirectory($extDirPath);
162 * Add specified directory
164 * @param string $extDirPath
165 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
168 protected function addDirectory($extDirPath) {
169 \TYPO3\CMS\Core\Utility\GeneralUtility
::mkdir($extDirPath);
170 if (!is_dir($extDirPath)) {
171 throw new \TYPO3\CMS\Extensionmanager\Exception\
ExtensionManagerException(sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_could_not_create_dir'), $extDirPath), 1337280416);
176 * Remove specified directory
178 * @param string $extDirPath
179 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
182 public function removeDirectory($extDirPath) {
183 $res = \TYPO3\CMS\Core\Utility\GeneralUtility
::rmdir($extDirPath, TRUE);
184 if ($res === FALSE) {
185 throw new \TYPO3\CMS\Extensionmanager\Exception\
ExtensionManagerException(sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_could_not_remove_dir'), $extDirPath), 1337280415);
190 * Constructs emConf and writes it to corresponding file
192 * @param array $extensionData
193 * @param string $rootPath
194 * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension
197 protected function writeEmConfToFile(array $extensionData, $rootPath, \TYPO3\CMS\Extensionmanager\Domain\Model\Extension
$extension = NULL) {
198 $emConfContent = $this->emConfUtility
->constructEmConf($extensionData, $extension);
199 \TYPO3\CMS\Core\Utility\GeneralUtility
::writeFile($rootPath . 'ext_emconf.php', $emConfContent);
203 * Is the given path a valid path for extension installation
205 * @param string $path the absolute (!) path in question
208 public function isValidExtensionPath($path) {
209 $allowedPaths = \TYPO3\CMS\Extensionmanager\Domain\Model\Extension
::returnAllowedInstallPaths();
210 foreach ($allowedPaths as $allowedPath) {
211 if (\TYPO3\CMS\Core\Utility\GeneralUtility
::isFirstPartOfStr($path, $allowedPath)) {
219 * Returns absolute path
221 * @param string $relativePath
224 public function returnAbsolutePath($relativePath) {
225 return \TYPO3\CMS\Core\Utility\GeneralUtility
::resolveBackPath(PATH_site
. $relativePath);
229 * Get extension path for an available or installed extension
231 * @param string $extension
234 public function getAbsoluteExtensionPath($extension) {
235 $extension = $this->installUtility
->enrichExtensionWithDetails($extension);
236 $absolutePath = $this->returnAbsolutePath($extension['siteRelPath']);
237 return $absolutePath;
241 * Create a zip file from an extension
243 * @param array $extension
246 public function createZipFileFromExtension($extension) {
247 $extensionPath = $this->getAbsoluteExtensionPath($extension);
248 $fileName = PATH_site
. 'typo3temp/' . $extension . '.zip';
249 $zip = new \
ZipArchive();
250 $zip->open($fileName, \ZipArchive
::CREATE
);
251 $iterator = new \
RecursiveIteratorIterator(new \
RecursiveDirectoryIterator($extensionPath));
252 foreach ($iterator as $key => $value) {
253 $archiveName = str_replace($extensionPath, '', $key);
254 if (\TYPO3\CMS\Core\Utility\StringUtility
::isLastPartOfString($key, '.')) {
257 $zip->addFile($key, $archiveName);
265 * Unzip an extension.zip.
267 * @param string $file path to zip file
268 * @param string $fileName file name
269 * @param string $pathType path type (Local, Global, System)
270 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
273 public function unzipExtensionFromFile($file, $fileName, $pathType = 'Local') {
274 $extensionDir = $this->makeAndClearExtensionDir($fileName, $pathType);
275 $zip = zip_open($file);
276 if (is_resource($zip)) {
277 while (($zipEntry = zip_read($zip)) !== FALSE) {
278 if (strpos(zip_entry_name($zipEntry), DIRECTORY_SEPARATOR
) !== FALSE) {
279 $last = strrpos(zip_entry_name($zipEntry), DIRECTORY_SEPARATOR
);
280 $dir = substr(zip_entry_name($zipEntry), 0, $last);
281 $file = substr(zip_entry_name($zipEntry), strrpos(zip_entry_name($zipEntry), DIRECTORY_SEPARATOR
) +
1);
283 \TYPO3\CMS\Core\Utility\GeneralUtility
::mkdir_deep($extensionDir . $dir);
285 if (strlen(trim($file)) > 0) {
286 $return = \TYPO3\CMS\Core\Utility\GeneralUtility
::writeFile($extensionDir . $dir . '/' . $file, zip_entry_read($zipEntry, zip_entry_filesize($zipEntry)));
287 if ($return === FALSE) {
288 throw new \TYPO3\CMS\Extensionmanager\Exception\
ExtensionManagerException('Could not write file ' . $file, 1344691048);
292 \TYPO3\CMS\Core\Utility\GeneralUtility
::writeFile($extensionDir . zip_entry_name($zipEntry), zip_entry_read($zipEntry, zip_entry_filesize($zipEntry)));
296 throw new \TYPO3\CMS\Extensionmanager\Exception\
ExtensionManagerException('Unable to open zip file ' . $file, 1344691049);
301 * Sends a zip file to the browser and deletes it afterwards
303 * @param string $fileName
304 * @param string $downloadName
307 public function sendZipFileToBrowserAndDelete($fileName, $downloadName = '') {
308 if ($downloadName === '') {
309 $downloadName = basename($fileName, '.zip');
311 header('Content-Type: application/zip');
312 header('Content-Length: ' . filesize($fileName));
313 header('Content-Disposition: attachment; filename="' . $downloadName . '.zip"');
320 * Sends the sql dump file to the browser and deletes it afterwards
322 * @param string $fileName
323 * @param string $downloadName
326 public function sendSqlDumpFileToBrowserAndDelete($fileName, $downloadName = '') {
327 if ($downloadName === '') {
328 $downloadName = basename($fileName, '.sql');
330 $downloadName = basename($downloadName, '.sql');
332 header('Content-Type: text');
333 header('Content-Length: ' . filesize($fileName));
334 header('Content-Disposition: attachment; filename="' . $downloadName . '.sql"');