TYPO3 CMS  TYPO3_6-2
FileHandlingUtility.php
Go to the documentation of this file.
1 <?php
3 
22 
29 
34  protected $emConfUtility;
35 
40  protected $installUtility;
41 
45  public function initializeObject() {
46  $this->getLanguageService()->includeLLFile('EXT:lang/locallang_mod_tools_em.xlf');
47  }
48 
57  public function unpackExtensionFromExtensionDataArray(array $extensionData, Extension $extension = NULL, $pathType = 'Local') {
58  $extensionDir = $this->makeAndClearExtensionDir($extensionData['extKey'], $pathType);
59  $files = $this->extractFilesArrayFromExtensionData($extensionData);
60  $directories = $this->extractDirectoriesFromExtensionData($files);
61  $files = array_diff_key($files, array_flip($directories));
62  $this->createDirectoriesForExtensionFiles($directories, $extensionDir);
63  $this->writeExtensionFiles($files, $extensionDir);
64  $this->writeEmConfToFile($extensionData, $extensionDir, $extension);
65  }
66 
73  protected function extractDirectoriesFromExtensionData(array $files) {
74  $directories = array();
75  foreach ($files as $filePath => $file) {
76  preg_match('/(.*)\\//', $filePath, $matches);
77  if (!empty($matches[0])) {
78  $directories[] = $matches[0];
79  }
80  }
81  return array_unique($directories);
82  }
83 
90  protected function extractFilesArrayFromExtensionData(array $extensionData) {
91  return $extensionData['FILES'];
92  }
93 
102  protected function createDirectoriesForExtensionFiles(array $directories, $rootPath) {
103  foreach ($directories as $directory) {
104  $this->createNestedDirectory($rootPath . $directory);
105  }
106  }
107 
114  protected function createNestedDirectory($directory) {
115  try {
116  GeneralUtility::mkdir_deep($directory);
117  } catch(\RuntimeException $exception) {
118  throw new ExtensionManagerException(
119  sprintf($this->getLanguageService()->getLL('clearMakeExtDir_could_not_create_dir'), $this->getRelativePath($directory)),
120  1337280416
121  );
122  }
123 
124  }
125 
133  protected function writeExtensionFiles(array $files, $rootPath) {
134  foreach ($files as $file) {
135  GeneralUtility::writeFile($rootPath . $file['name'], $file['content']);
136  }
137  }
138 
148  protected function makeAndClearExtensionDir($extensionKey, $pathType = 'Local') {
149  $extDirPath = $this->getExtensionDir($extensionKey, $pathType);
150  if (is_dir($extDirPath)) {
151  $this->removeDirectory($extDirPath);
152  }
153  $this->addDirectory($extDirPath);
154 
155  return $extDirPath;
156  }
157 
166  public function getExtensionDir($extensionKey, $pathType = 'Local') {
168  $path = $paths[$pathType];
169  if (!$path || !is_dir($path) || !$extensionKey) {
170  throw new ExtensionManagerException(sprintf('ERROR: The extension install path "%s" was no directory!', $this->getRelativePath($path)), 1337280417);
171  }
172 
173  return $path . $extensionKey . '/';
174  }
175 
183  protected function addDirectory($extDirPath) {
184  GeneralUtility::mkdir($extDirPath);
185  if (!is_dir($extDirPath)) {
186  throw new ExtensionManagerException(
187  sprintf($this->getLanguageService()->getLL('clearMakeExtDir_could_not_create_dir'), $this->getRelativePath($extDirPath)),
188  1337280418
189  );
190  }
191  }
192 
198  public function ensureConfiguredDirectoriesExist(array $extension) {
199  foreach ($this->getAbsolutePathsToConfiguredDirectories($extension) as $directory) {
200  if (!$this->directoryExists($directory)) {
201  $this->createNestedDirectory($directory);
202  }
203  }
204  }
205 
212  protected function directoryExists($directory) {
213  return is_dir($directory);
214  }
215 
222  protected function getAbsolutePathsToConfiguredDirectories(array $extension) {
223  $requestedDirectories = array();
224  $requestUploadFolder = isset($extension['uploadfolder']) ? (boolean)$extension['uploadfolder'] : FALSE;
225  if ($requestUploadFolder) {
226  $requestedDirectories[] = $this->getAbsolutePath($this->getPathToUploadFolder($extension));
227  }
228 
229  $requestCreateDirectories = empty($extension['createDirs']) ? FALSE : (string)$extension['createDirs'];
230  if ($requestCreateDirectories) {
231  foreach (GeneralUtility::trimExplode(',', $extension['createDirs']) as $directoryToCreate) {
232  $requestedDirectories[] = $this->getAbsolutePath($directoryToCreate);
233  }
234  }
235 
236  return $requestedDirectories;
237  }
238 
245  protected function getPathToUploadFolder($extension) {
246  return 'uploads/tx_' . str_replace('_', '', $extension['key']) . '/';
247  }
248 
256  public function removeDirectory($extDirPath) {
257  $extDirPath = GeneralUtility::fixWindowsFilePath($extDirPath);
258  $extensionPathWithoutTrailingSlash = rtrim($extDirPath, '/');
259  if (is_link($extensionPathWithoutTrailingSlash) && TYPO3_OS !== 'WIN') {
260  $result = unlink($extensionPathWithoutTrailingSlash);
261  } else {
262  $result = GeneralUtility::rmdir($extDirPath, TRUE);
263  }
264  if ($result === FALSE) {
265  throw new ExtensionManagerException(
266  sprintf($this->getLanguageService()->getLL('clearMakeExtDir_could_not_remove_dir'), $this->getRelativePath($extDirPath)),
267  1337280415
268  );
269  }
270  }
271 
281  protected function writeEmConfToFile(array $extensionData, $rootPath, Extension $extension = NULL) {
282  $emConfFileData = array();
283  if (file_exists($rootPath . 'ext_emconf.php')) {
284  $emConfFileData = $this->emConfUtility->includeEmConf(
285  array(
286  'key' => $extensionData['extKey'],
287  'siteRelPath' => PathUtility::stripPathSitePrefix($rootPath)
288  )
289  );
290  }
291  $extensionData['EM_CONF'] = array_replace_recursive($emConfFileData, $extensionData['EM_CONF']);
292  $emConfContent = $this->emConfUtility->constructEmConf($extensionData, $extension);
293  GeneralUtility::writeFile($rootPath . 'ext_emconf.php', $emConfContent);
294  }
295 
302  public function isValidExtensionPath($path) {
303  $allowedPaths = Extension::returnAllowedInstallPaths();
304  foreach ($allowedPaths as $allowedPath) {
305  if (GeneralUtility::isFirstPartOfStr($path, $allowedPath)) {
306  return TRUE;
307  }
308  }
309  return FALSE;
310  }
311 
319  protected function getAbsolutePath($relativePath) {
320  $absolutePath = GeneralUtility::getFileAbsFileName(GeneralUtility::resolveBackPath(PATH_site . $relativePath));
321  if (empty($absolutePath)) {
322  throw new ExtensionManagerException('Illegal relative path given', 1350742864);
323  }
324  return $absolutePath;
325  }
326 
333  protected function getRelativePath($absolutePath) {
334  return PathUtility::stripPathSitePrefix($absolutePath);
335  }
336 
343  public function getAbsoluteExtensionPath($extension) {
344  $extension = $this->installUtility->enrichExtensionWithDetails($extension);
345  $absolutePath = $this->getAbsolutePath($extension['siteRelPath']);
346  return $absolutePath;
347  }
348 
355  public function getExtensionVersion($extension) {
356  $extensionData = $this->installUtility->enrichExtensionWithDetails($extension);
357  $version = $extensionData['version'];
358  return $version;
359  }
360 
367  public function createZipFileFromExtension($extension) {
368 
369  $extensionPath = $this->getAbsoluteExtensionPath($extension);
370 
371  // Add trailing slash to the extension path, getAllFilesAndFoldersInPath explicitly requires that.
372  $extensionPath = PathUtility::sanitizeTrailingSeparator($extensionPath);
373 
374  $version = $this->getExtensionVersion($extension);
375  if (empty($version)) {
376  $version = '0.0.0';
377  }
378 
379  $fileName = $this->getAbsolutePath('typo3temp/' . $extension . '_' . $version . '_' . date('YmdHi') . '.zip');
380 
381  $zip = new \ZipArchive();
382  $zip->open($fileName, \ZipArchive::CREATE);
383 
384  $excludePattern = $GLOBALS['TYPO3_CONF_VARS']['EXT']['excludeForPackaging'];
385 
386  // Get all the files of the extension, but exclude the ones specified in the excludePattern
388  array(), // No files pre-added
389  $extensionPath, // Start from here
390  '', // Do not filter files by extension
391  TRUE, // Include subdirectories
392  PHP_INT_MAX, // Recursion level
393  $excludePattern // Files and directories to exclude.
394  );
395 
396  // Make paths relative to extension root directory.
397  $files = GeneralUtility::removePrefixPathFromList($files, $extensionPath);
398 
399  // Remove the one empty path that is the extension dir itself.
400  $files = array_filter($files);
401 
402  foreach ($files as $file) {
403  $fullPath = $extensionPath . $file;
404  // Distinguish between files and directories, as creation of the archive
405  // fails on Windows when trying to add a directory with "addFile".
406  if (is_dir($fullPath)) {
407  $zip->addEmptyDir($file);
408  } else {
409  $zip->addFile($fullPath, $file);
410  }
411  }
412 
413  $zip->close();
414  return $fileName;
415  }
416 
426  public function unzipExtensionFromFile($file, $fileName, $pathType = 'Local') {
427  $extensionDir = $this->makeAndClearExtensionDir($fileName, $pathType);
428  $zip = zip_open($file);
429  if (is_resource($zip)) {
430  while (($zipEntry = zip_read($zip)) !== FALSE) {
431  if (strpos(zip_entry_name($zipEntry), '/') !== FALSE) {
432  $last = strrpos(zip_entry_name($zipEntry), '/');
433  $dir = substr(zip_entry_name($zipEntry), 0, $last);
434  $file = substr(zip_entry_name($zipEntry), strrpos(zip_entry_name($zipEntry), '/') + 1);
435  if (!is_dir($extensionDir . $dir)) {
436  GeneralUtility::mkdir_deep($extensionDir . $dir);
437  }
438  if (strlen(trim($file)) > 0) {
439  $return = GeneralUtility::writeFile($extensionDir . $dir . '/' . $file, zip_entry_read($zipEntry, zip_entry_filesize($zipEntry)));
440  if ($return === FALSE) {
441  throw new ExtensionManagerException('Could not write file ' . $this->getRelativePath($file), 1344691048);
442  }
443  }
444  } else {
445  GeneralUtility::writeFile($extensionDir . zip_entry_name($zipEntry), zip_entry_read($zipEntry, zip_entry_filesize($zipEntry)));
446  }
447  }
448  } else {
449  throw new ExtensionManagerException('Unable to open zip file ' . $this->getRelativePath($file), 1344691049);
450  }
451  }
452 
460  public function sendZipFileToBrowserAndDelete($fileName, $downloadName = '') {
461  if ($downloadName === '') {
462  $downloadName = basename($fileName, '.zip');
463  }
464  header('Content-Type: application/zip');
465  header('Content-Length: ' . filesize($fileName));
466  header('Content-Disposition: attachment; filename="' . $downloadName . '.zip"');
467  readfile($fileName);
468  unlink($fileName);
469  die;
470  }
471 
479  public function sendSqlDumpFileToBrowserAndDelete($fileName, $downloadName = '') {
480  if ($downloadName === '') {
481  $downloadName = basename($fileName, '.sql');
482  } else {
483  $downloadName = basename($downloadName, '.sql');
484  }
485  header('Content-Type: text');
486  header('Content-Length: ' . filesize($fileName));
487  header('Content-Disposition: attachment; filename="' . $downloadName . '.sql"');
488  readfile($fileName);
489  unlink($fileName);
490  die;
491  }
492 
496  protected function getLanguageService() {
497  return $GLOBALS['LANG'];
498  }
499 
500 }
static mkdir_deep($directory, $deepDirectory='')
static getAllFilesAndFoldersInPath(array $fileArr, $path, $extList='', $regDirs=FALSE, $recursivityLevels=99, $excludePattern='')
static writeFile($file, $content, $changePermissions=FALSE)
writeEmConfToFile(array $extensionData, $rootPath, Extension $extension=NULL)
static isFirstPartOfStr($str, $partStr)
unpackExtensionFromExtensionDataArray(array $extensionData, Extension $extension=NULL, $pathType='Local')
static rmdir($path, $removeNonEmpty=FALSE)
unzipExtensionFromFile($file, $fileName, $pathType='Local')
die
Definition: index.php:6
static trimExplode($delim, $string, $removeEmptyValues=FALSE, $limit=0)
if($list_of_literals) if(!empty($literals)) if(!empty($literals)) $result
Analyse literals to prepend the N char to them if their contents aren&#39;t numeric.
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
static getFileAbsFileName($filename, $onlyRelative=TRUE, $relToTYPO3_mainDir=FALSE)
static removePrefixPathFromList(array $fileArr, $prefixToRemove)
static sanitizeTrailingSeparator($path, $separator='/')