TYPO3 CMS  TYPO3_7-6
ExtendedFileUtility.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
42 
70 {
78  public $unzipPath = '';
79 
86  public $dontCheckForUnique = 0;
87 
95 
103  public $actionPerms = [
104  // File permissions
105  'addFile' => false,
106  'readFile' => false,
107  'writeFile' => false,
108  'copyFile' => false,
109  'moveFile' => false,
110  'renameFile' => false,
111  'unzipFile' => false,
112  'deleteFile' => false,
113  // Folder permissions
114  'addFolder' => false,
115  'readFolder' => false,
116  'writeFolder' => false,
117  'copyFolder' => false,
118  'moveFolder' => false,
119  'renameFolder' => false,
120  'deleteFolder' => false,
121  'recursivedeleteFolder' => false
122  ];
123 
129  public $recyclerFN = '_recycler_';
130 
136  public $internalUploadMap = [];
137 
141  public $lastError = '';
142 
148  protected $errorMessages = [];
149 
155  protected $flashMessages = [];
156 
160  protected $fileCmdMap;
161 
167  protected $fileFactory;
168 
175  {
176  return (string)$this->existingFilesConflictMode;
177  }
178 
187  {
188  try {
189  $this->existingFilesConflictMode = DuplicationBehavior::cast($existingFilesConflictMode);
190  } catch (InvalidEnumerationValueException $e) {
191  throw new Exception(
192  sprintf(
193  'Invalid argument, received: "%s", expected a value from enumeration \TYPO3\CMS\Core\Resource\DuplicationBehavior (%s)',
195  implode(', ', DuplicationBehavior::getConstants())
196  )
197  );
198  }
199  }
200 
207  public function start($fileCmds)
208  {
209  $unzipPath = trim($GLOBALS['TYPO3_CONF_VARS']['BE']['unzip_path']);
210  if (substr($unzipPath, -1) !== '/' && is_dir($unzipPath)) {
211  // Make sure the path ends with a slash
212  $unzipPath .= '/';
213  }
214  $this->unzipPath = $unzipPath;
215  // Initialize Object Factory
216  $this->fileFactory = ResourceFactory::getInstance();
217  // Initializing file processing commands:
218  $this->fileCmdMap = $fileCmds;
219  }
220 
228  public function setActionPermissions(array $permissions = [])
229  {
230  if (empty($permissions)) {
231  $permissions = $this->getBackendUser()->getFilePermissions();
232  }
233  $this->actionPerms = $permissions;
234  }
235 
242  public function processData()
243  {
244  $result = [];
245  if (!$this->isInit) {
246  return false;
247  }
248  if (is_array($this->fileCmdMap)) {
249  // Check if there were uploads expected, but no one made
250  if ($this->fileCmdMap['upload']) {
251  $uploads = $this->fileCmdMap['upload'];
252  foreach ($uploads as $upload) {
253  if (empty($_FILES['upload_' . $upload['data']]['name'])
254  || (is_array($_FILES['upload_' . $upload['data']]['name'])
255  && empty($_FILES['upload_' . $upload['data']]['name'][0])
256  )
257  ) {
258  unset($this->fileCmdMap['upload'][$upload['data']]);
259  }
260  }
261  if (empty($this->fileCmdMap['upload'])) {
262  $this->writeLog(1, 1, 108, 'No file was uploaded!', []);
263  $this->addMessageToFlashMessageQueue('FileUtility.NoFileWasUploaded');
264  }
265  }
266 
267  // Check if there were new folder names expected, but non given
268  if ($this->fileCmdMap['newfolder']) {
269  foreach ($this->fileCmdMap['newfolder'] as $key => $cmdArr) {
270  if (empty($cmdArr['data'])) {
271  unset($this->fileCmdMap['newfolder'][$key]);
272  }
273  }
274  if (empty($this->fileCmdMap['newfolder'])) {
275  $this->writeLog(6, 1, 108, 'No name for new folder given!', []);
276  $this->addMessageToFlashMessageQueue('FileUtility.NoNameForNewFolderGiven');
277  }
278  }
279 
280  // Traverse each set of actions
281  foreach ($this->fileCmdMap as $action => $actionData) {
282  // Traverse all action data. More than one file might be affected at the same time.
283  if (is_array($actionData)) {
284  $result[$action] = [];
285  foreach ($actionData as $cmdArr) {
286  // Clear file stats
287  clearstatcache();
288  // Branch out based on command:
289  switch ($action) {
290  case 'delete':
291  $result[$action][] = $this->func_delete($cmdArr);
292  break;
293  case 'copy':
294  $result[$action][] = $this->func_copy($cmdArr);
295  break;
296  case 'move':
297  $result[$action][] = $this->func_move($cmdArr);
298  break;
299  case 'rename':
300  $result[$action][] = $this->func_rename($cmdArr);
301  break;
302  case 'newfolder':
303  $result[$action][] = $this->func_newfolder($cmdArr);
304  break;
305  case 'newfile':
306  $result[$action][] = $this->func_newfile($cmdArr);
307  break;
308  case 'editfile':
309  $result[$action][] = $this->func_edit($cmdArr);
310  break;
311  case 'upload':
312  $result[$action][] = $this->func_upload($cmdArr);
313  break;
314  case 'replace':
315  $result[$action][] = $this->replaceFile($cmdArr);
316  break;
317  case 'unzip':
318  $result[$action][] = $this->func_unzip($cmdArr);
319  break;
320  }
321  // Hook for post-processing the action
322  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_extfilefunc.php']['processData'])) {
323  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_extfilefunc.php']['processData'] as $classRef) {
324  $hookObject = GeneralUtility::getUserObj($classRef);
325  if (!$hookObject instanceof ExtendedFileUtilityProcessDataHookInterface) {
326  throw new \UnexpectedValueException($classRef . ' must implement interface ' . ExtendedFileUtilityProcessDataHookInterface::class, 1279719168);
327  }
328  $hookObject->processData_postProcessAction($action, $cmdArr, $result[$action], $this);
329  }
330  }
331  }
332  }
333  }
334  }
335  return $result;
336  }
337 
344  {
345  foreach ($this->getErrorMessages() as $msg) {
346  $flashMessage = GeneralUtility::makeInstance(
347  FlashMessage::class,
348  $msg,
349  '',
351  true
352  );
353  $this->addFlashMessage($flashMessage);
354  }
355  }
356 
362  public function getErrorMessages()
363  {
364  return $this->errorMessages;
365  }
366 
375  public function writeLog($action, $error, $details_nr, $details, $data)
376  {
377  // Type value for tce_file.php
378  $type = 2;
379  if (is_object($this->getBackendUser())) {
380  $this->getBackendUser()->writelog($type, $action, $error, $details_nr, $details, $data);
381  }
382  if ($error > 0) {
383  $this->lastError = vsprintf($details, $data);
384  $this->errorMessages[] = $this->lastError;
385  }
386  }
387 
397  protected function addMessageToFlashMessageQueue($localizationKey, array $replaceMarkers = [], $severity = FlashMessage::ERROR)
398  {
399  if (TYPO3_MODE !== 'BE') {
400  return;
401  }
402  $label = $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/fileMessages.xlf:' . $localizationKey);
403  $message = vsprintf($label, $replaceMarkers);
404  $flashMessage = GeneralUtility::makeInstance(
405  FlashMessage::class,
406  $message,
407  '',
408  $severity,
409  true
410  );
411  $this->addFlashMessage($flashMessage);
412  }
413 
414  /*************************************
415  *
416  * File operation functions
417  *
418  **************************************/
425  public function func_delete(array $cmds)
426  {
427  $result = false;
428  if (!$this->isInit) {
429  return $result;
430  }
431  // Example indentifier for $cmds['data'] => "4:mypath/tomyfolder/myfile.jpg"
432  // for backwards compatibility: the combined file identifier was the path+filename
433  try {
434  $fileObject = $this->getFileObject($cmds['data']);
435  } catch (ResourceDoesNotExistException $e) {
436  $flashMessage = GeneralUtility::makeInstance(
437  FlashMessage::class,
438  sprintf(
439  $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:message.description.fileNotFound'),
440  $cmds['data']
441  ),
442  $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:message.header.fileNotFound'),
444  true
445  );
446  $this->addFlashMessage($flashMessage);
447 
448  return false;
449  }
450  // @todo implement the recycler feature which has been removed from the original implementation
451  // checks to delete the file
452  if ($fileObject instanceof File) {
453  // check if the file still has references
454  // Exclude sys_file_metadata records as these are no use references
455  $databaseConnection = $this->getDatabaseConnection();
456  $table = 'sys_refindex';
457  $refIndexRecords = $databaseConnection->exec_SELECTgetRows(
458  '*',
459  $table,
460  'deleted=0 AND ref_table=' . $databaseConnection->fullQuoteStr('sys_file', $table)
461  . ' AND ref_uid=' . (int)$fileObject->getUid()
462  . ' AND tablename != ' . $databaseConnection->fullQuoteStr('sys_file_metadata', $table)
463  );
464  $deleteFile = true;
465  if (!empty($refIndexRecords)) {
466  $shortcutContent = [];
467  $brokenReferences = [];
468 
469  foreach ($refIndexRecords as $fileReferenceRow) {
470  if ($fileReferenceRow['tablename'] === 'sys_file_reference') {
471  $row = $this->transformFileReferenceToRecordReference($fileReferenceRow);
472  $shortcutRecord = BackendUtility::getRecord($row['tablename'], $row['recuid']);
473 
474  if ($shortcutRecord) {
475  $shortcutContent[] = '[record:' . $row['tablename'] . ':' . $row['recuid'] . ']';
476  } else {
477  $brokenReferences[] = $fileReferenceRow['ref_uid'];
478  }
479  }
480  }
481  if (!empty($brokenReferences)) {
482  // render a message that the file has broken references
483  $flashMessage = GeneralUtility::makeInstance(
484  FlashMessage::class,
485  sprintf($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:message.description.fileHasBrokenReferences'), count($brokenReferences)),
486  $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:message.header.fileHasBrokenReferences'),
488  true
489  );
490  $this->addFlashMessage($flashMessage);
491  }
492  if (!empty($shortcutContent)) {
493  // render a message that the file could not be deleted
494  $flashMessage = GeneralUtility::makeInstance(
495  FlashMessage::class,
496  sprintf($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:message.description.fileNotDeletedHasReferences'), $fileObject->getName()) . ' ' . implode(', ', $shortcutContent),
497  $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:message.header.fileNotDeletedHasReferences'),
499  true
500  );
501  $this->addFlashMessage($flashMessage);
502  $deleteFile = false;
503  }
504  }
505 
506  if ($deleteFile) {
507  try {
508  $result = $fileObject->delete();
509 
510  // show the user that the file was deleted
511  $flashMessage = GeneralUtility::makeInstance(
512  FlashMessage::class,
513  sprintf($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:message.description.fileDeleted'), $fileObject->getName()),
514  $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:message.header.fileDeleted'),
516  true
517  );
518  $this->addFlashMessage($flashMessage);
519  // Log success
520  $this->writeLog(4, 0, 1, 'File "%s" deleted', [$fileObject->getIdentifier()]);
521  } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException $e) {
522  $this->writeLog(4, 1, 112, 'You are not allowed to access the file', [$fileObject->getIdentifier()]);
523  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToAccessTheFile', [$fileObject->getIdentifier()]);
524  } catch (NotInMountPointException $e) {
525  $this->writeLog(4, 1, 111, 'Target was not within your mountpoints! T="%s"', [$fileObject->getIdentifier()]);
526  $this->addMessageToFlashMessageQueue('FileUtility.TargetWasNotWithinYourMountpoints', [$fileObject->getIdentifier()]);
527  } catch (\RuntimeException $e) {
528  $this->writeLog(4, 1, 110, 'Could not delete file "%s". Write-permission problem?', [$fileObject->getIdentifier()]);
529  $this->addMessageToFlashMessageQueue('FileUtility.CouldNotDeleteFile', [$fileObject->getIdentifier()]);
530  }
531  }
532  } else {
534  if (!$this->folderHasFilesInUse($fileObject)) {
535  try {
536  $result = $fileObject->delete(true);
537  if ($result) {
538  // notify the user that the folder was deleted
540  $flashMessage = GeneralUtility::makeInstance(
541  FlashMessage::class,
542  sprintf($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:message.description.folderDeleted'), $fileObject->getName()),
543  $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:message.header.folderDeleted'),
545  true
546  );
547  $this->addFlashMessage($flashMessage);
548  // Log success
549  $this->writeLog(4, 0, 3, 'Directory "%s" deleted', [$fileObject->getIdentifier()]);
550  }
552  $this->writeLog(4, 1, 120, 'Could not delete directory! Is directory "%s" empty? (You are not allowed to delete directories recursively).', [$fileObject->getIdentifier()]);
553  $this->addMessageToFlashMessageQueue('FileUtility.CouldNotDeleteDirectory', [$fileObject->getIdentifier()]);
555  $this->writeLog(4, 1, 123, 'You are not allowed to access the directory', [$fileObject->getIdentifier()]);
556  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToAccessTheDirectory', [$fileObject->getIdentifier()]);
557  } catch (NotInMountPointException $e) {
558  $this->writeLog(4, 1, 121, 'Target was not within your mountpoints! T="%s"', [$fileObject->getIdentifier()]);
559  $this->addMessageToFlashMessageQueue('FileUtility.TargetWasNotWithinYourMountpoints', [$fileObject->getIdentifier()]);
560  } catch (\TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException $e) {
561  $this->writeLog(4, 1, 120, 'Could not delete directory "%s"! Write-permission problem?', [$fileObject->getIdentifier()]);
562  $this->addMessageToFlashMessageQueue('FileUtility.CouldNotDeleteDirectory', [$fileObject->getIdentifier()]);
563  }
564  }
565  }
566 
567  return $result;
568  }
569 
578  public function folderHasFilesInUse(Folder $folder)
579  {
580  $files = $folder->getFiles(0, 0, Folder::FILTER_MODE_USE_OWN_AND_STORAGE_FILTERS, true);
581  if (empty($files)) {
582  return false;
583  }
584 
586  $fileUids = [];
587  foreach ($files as $file) {
588  $fileUids[] = $file->getUid();
589  }
590  $numberOfReferences = $this->getDatabaseConnection()->exec_SELECTcountRows(
591  '*',
592  'sys_refindex',
593  'deleted=0 AND ref_table="sys_file" AND ref_uid IN (' . implode(',', $fileUids) . ') AND tablename<>"sys_file_metadata"'
594  );
595 
596  $hasReferences = $numberOfReferences > 0;
597  if ($hasReferences) {
599  $flashMessage = GeneralUtility::makeInstance(
600  FlashMessage::class,
601  $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:message.description.folderNotDeletedHasFilesWithReferences'),
602  $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:message.header.folderNotDeletedHasFilesWithReferences'),
604  true
605  );
606  $this->addFlashMessage($flashMessage);
607  }
608 
609  return $hasReferences;
610  }
611 
619  protected function transformFileReferenceToRecordReference(array $referenceRecord)
620  {
621  $fileReference = $this->getDatabaseConnection()->exec_SELECTgetSingleRow(
622  '*',
623  'sys_file_reference',
624  'uid=' . (int)$referenceRecord['recuid']
625  );
626  return [
627  'recuid' => $fileReference['uid_foreign'],
628  'tablename' => $fileReference['tablenames'],
629  'field' => $fileReference['fieldname'],
630  'flexpointer' => '',
631  'softref_key' => '',
632  'sorting' => $fileReference['sorting_foreign']
633  ];
634  }
635 
644  protected function getFileObject($identifier)
645  {
646  $object = $this->fileFactory->retrieveFileOrFolderObject($identifier);
647  if (!is_object($object)) {
648  throw new \TYPO3\CMS\Core\Resource\Exception\InvalidFileException('The item ' . $identifier . ' was not a file or directory!!', 1320122453);
649  }
650  if ($object->getStorage()->getUid() === 0) {
651  throw new \TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException('You are not allowed to access files outside your storages', 1375889830);
652  }
653  return $object;
654  }
655 
669  protected function func_copy($cmds)
670  {
671  if (!$this->isInit) {
672  return false;
673  }
674  $sourceFileObject = $this->getFileObject($cmds['data']);
676  $targetFolderObject = $this->getFileObject($cmds['target']);
677  // Basic check
678  if (!$targetFolderObject instanceof Folder) {
679  $this->writeLog(2, 2, 100, 'Destination "%s" was not a directory', [$cmds['target']]);
680  $this->addMessageToFlashMessageQueue('FileUtility.DestinationWasNotADirectory', [$cmds['target']]);
681  return false;
682  }
683  // If this is TRUE, we append _XX to the file name if
684  $appendSuffixOnConflict = (string)$cmds['altName'];
685  $resultObject = null;
686  $conflictMode = $appendSuffixOnConflict !== '' ? DuplicationBehavior::RENAME : DuplicationBehavior::CANCEL;
687  // Copying the file
688  if ($sourceFileObject instanceof File) {
689  try {
690  $resultObject = $sourceFileObject->copyTo($targetFolderObject, null, $conflictMode);
692  $this->writeLog(2, 1, 114, 'You are not allowed to copy files', []);
693  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToCopyFiles');
694  } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException $e) {
695  $this->writeLog(2, 1, 110, 'Could not access all necessary resources. Source file or destination maybe was not within your mountpoints? T="%s", D="%s"', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
696  $this->addMessageToFlashMessageQueue('FileUtility.CouldNotAccessAllNecessaryResources', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
697  } catch (IllegalFileExtensionException $e) {
698  $this->writeLog(2, 1, 111, 'Extension of file name "%s" is not allowed in "%s"!', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
699  $this->addMessageToFlashMessageQueue('FileUtility.ExtensionOfFileNameIsNotAllowedIn', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
700  } catch (ExistingTargetFileNameException $e) {
701  $this->writeLog(2, 1, 112, 'File "%s" already exists in folder "%s"!', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
702  $this->addMessageToFlashMessageQueue('FileUtility.FileAlreadyExistsInFolder', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
703  } catch (\BadMethodCallException $e) {
704  $this->writeLog(3, 1, 128, 'The function to copy a file between storages is not yet implemented', []);
705  $this->addMessageToFlashMessageQueue('FileUtility.TheFunctionToCopyAFileBetweenStoragesIsNotYetImplemented');
706  } catch (\RuntimeException $e) {
707  $this->writeLog(2, 2, 109, 'File "%s" WAS NOT copied to "%s"! Write-permission problem?', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
708  $this->addMessageToFlashMessageQueue('FileUtility.FileWasNotCopiedTo', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
709  }
710  if ($resultObject) {
711  $this->writeLog(2, 0, 1, 'File "%s" copied to "%s"', [$sourceFileObject->getIdentifier(), $resultObject->getIdentifier()]);
712  $this->addMessageToFlashMessageQueue('FileUtility.FileCopiedTo', [$sourceFileObject->getIdentifier(), $resultObject->getIdentifier()], FlashMessage::OK);
713  }
714  } else {
715  // Else means this is a Folder
716  $sourceFolderObject = $sourceFileObject;
717  try {
718  $resultObject = $sourceFolderObject->copyTo($targetFolderObject, null, $conflictMode);
720  $this->writeLog(2, 1, 125, 'You are not allowed to copy directories', []);
721  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToCopyDirectories');
722  } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException $e) {
723  $this->writeLog(2, 1, 110, 'Could not access all necessary resources. Source file or destination maybe was not within your mountpoints? T="%s", D="%s"', [$sourceFolderObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
724  $this->addMessageToFlashMessageQueue('FileUtility.CouldNotAccessAllNecessaryResources', [$sourceFolderObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
726  $this->writeLog(2, 1, 121, 'You don\'t have full access to the destination directory "%s"!', [$targetFolderObject->getIdentifier()]);
727  $this->addMessageToFlashMessageQueue('FileUtility.YouDontHaveFullAccessToTheDestinationDirectory', [$targetFolderObject->getIdentifier()]);
728  } catch (\TYPO3\CMS\Core\Resource\Exception\InvalidTargetFolderException $e) {
729  $this->writeLog(2, 1, 122, 'Cannot copy folder "%s" into target folder "%s", because the target folder is already within the folder to be copied!', [$sourceFolderObject->getName(), $targetFolderObject->getName()]);
730  $this->addMessageToFlashMessageQueue('FileUtility.CannotCopyFolderIntoTargetFolderBecauseTheTargetFolderIsAlreadyWithinTheFolderToBeCopied', [$sourceFolderObject->getName(), $targetFolderObject->getName()]);
731  } catch (ExistingTargetFolderException $e) {
732  $this->writeLog(2, 1, 123, 'Target "%s" already exists!', [$targetFolderObject->getIdentifier()]);
733  $this->addMessageToFlashMessageQueue('FileUtility.TargetAlreadyExists', [$targetFolderObject->getIdentifier()]);
734  } catch (\BadMethodCallException $e) {
735  $this->writeLog(3, 1, 129, 'The function to copy a folder between storages is not yet implemented', []);
736  $this->addMessageToFlashMessageQueue('FileUtility.TheFunctionToCopyAFolderBetweenStoragesIsNotYetImplemented');
737  } catch (\RuntimeException $e) {
738  $this->writeLog(2, 2, 119, 'Directory "%s" WAS NOT copied to "%s"! Write-permission problem?', [$sourceFolderObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
739  $this->addMessageToFlashMessageQueue('FileUtility.DirectoryWasNotCopiedTo', [$sourceFolderObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
740  }
741  if ($resultObject) {
742  $this->writeLog(2, 0, 2, 'Directory "%s" copied to "%s"', [$sourceFolderObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
743  $this->addMessageToFlashMessageQueue('FileUtility.DirectoryCopiedTo', [$sourceFolderObject->getIdentifier(), $targetFolderObject->getIdentifier()], FlashMessage::OK);
744  }
745  }
746  return $resultObject;
747  }
748 
762  protected function func_move($cmds)
763  {
764  if (!$this->isInit) {
765  return false;
766  }
767  $sourceFileObject = $this->getFileObject($cmds['data']);
768  $targetFolderObject = $this->getFileObject($cmds['target']);
769  // Basic check
770  if (!$targetFolderObject instanceof Folder) {
771  $this->writeLog(3, 2, 100, 'Destination "%s" was not a directory', [$cmds['target']]);
772  $this->addMessageToFlashMessageQueue('FileUtility.DestinationWasNotADirectory', [$cmds['target']]);
773  return false;
774  }
775  $alternativeName = (string)$cmds['altName'];
776  $resultObject = null;
777  // Moving the file
778  if ($sourceFileObject instanceof File) {
779  try {
780  if ($alternativeName !== '') {
781  // Don't allow overwriting existing files, but find a new name
782  $resultObject = $sourceFileObject->moveTo($targetFolderObject, $alternativeName, DuplicationBehavior::RENAME);
783  } else {
784  // Don't allow overwriting existing files
785  $resultObject = $sourceFileObject->moveTo($targetFolderObject, null, DuplicationBehavior::CANCEL);
786  }
787  $this->writeLog(3, 0, 1, 'File "%s" moved to "%s"', [$sourceFileObject->getIdentifier(), $resultObject->getIdentifier()]);
788  $this->addMessageToFlashMessageQueue('FileUtility.FileMovedTo', [$sourceFileObject->getIdentifier(), $resultObject->getIdentifier()], FlashMessage::OK);
790  $this->writeLog(3, 1, 114, 'You are not allowed to move files', []);
791  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToMoveFiles');
792  } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException $e) {
793  $this->writeLog(3, 1, 110, 'Could not access all necessary resources. Source file or destination maybe was not within your mountpoints? T="%s", D="%s"', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
794  $this->addMessageToFlashMessageQueue('FileUtility.CouldNotAccessAllNecessaryResources', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
795  } catch (IllegalFileExtensionException $e) {
796  $this->writeLog(3, 1, 111, 'Extension of file name "%s" is not allowed in "%s"!', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
797  $this->addMessageToFlashMessageQueue('FileUtility.ExtensionOfFileNameIsNotAllowedIn', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
798  } catch (ExistingTargetFileNameException $e) {
799  $this->writeLog(3, 1, 112, 'File "%s" already exists in folder "%s"!', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
800  $this->addMessageToFlashMessageQueue('FileUtility.FileAlreadyExistsInFolder', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
801  } catch (\BadMethodCallException $e) {
802  $this->writeLog(3, 1, 126, 'The function to move a file between storages is not yet implemented', []);
803  $this->addMessageToFlashMessageQueue('FileUtility.TheFunctionToMoveAFileBetweenStoragesIsNotYetImplemented');
804  } catch (\RuntimeException $e) {
805  $this->writeLog(3, 2, 109, 'File "%s" WAS NOT copied to "%s"! Write-permission problem?', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
806  $this->addMessageToFlashMessageQueue('FileUtility.FileWasNotCopiedTo', [$sourceFileObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
807  }
808  } else {
809  // Else means this is a Folder
810  $sourceFolderObject = $sourceFileObject;
811  try {
812  if ($alternativeName !== '') {
813  // Don't allow overwriting existing files, but find a new name
814  $resultObject = $sourceFolderObject->moveTo($targetFolderObject, $alternativeName, DuplicationBehavior::RENAME);
815  } else {
816  // Don't allow overwriting existing files
817  $resultObject = $sourceFolderObject->moveTo($targetFolderObject, null, DuplicationBehavior::RENAME);
818  }
819  $this->writeLog(3, 0, 2, 'Directory "%s" moved to "%s"', [$sourceFolderObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
820  $this->addMessageToFlashMessageQueue('FileUtility.DirectoryMovedTo', [$sourceFolderObject->getIdentifier(), $targetFolderObject->getIdentifier()], FlashMessage::OK);
822  $this->writeLog(3, 1, 125, 'You are not allowed to move directories', []);
823  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToMoveDirectories');
824  } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException $e) {
825  $this->writeLog(3, 1, 110, 'Could not access all necessary resources. Source file or destination maybe was not within your mountpoints? T="%s", D="%s"', [$sourceFolderObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
826  $this->addMessageToFlashMessageQueue('FileUtility.CouldNotAccessAllNecessaryResources', [$sourceFolderObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
828  $this->writeLog(3, 1, 121, 'You don\'t have full access to the destination directory "%s"!', [$targetFolderObject->getIdentifier()]);
829  $this->addMessageToFlashMessageQueue('FileUtility.YouDontHaveFullAccessToTheDestinationDirectory', [$targetFolderObject->getIdentifier()]);
830  } catch (\TYPO3\CMS\Core\Resource\Exception\InvalidTargetFolderException $e) {
831  $this->writeLog(3, 1, 122, 'Cannot move folder "%s" into target folder "%s", because the target folder is already within the folder to be moved!', [$sourceFolderObject->getName(), $targetFolderObject->getName()]);
832  $this->addMessageToFlashMessageQueue('FileUtility.CannotMoveFolderIntoTargetFolderBecauseTheTargetFolderIsAlreadyWithinTheFolderToBeMoved', [$sourceFolderObject->getName(), $targetFolderObject->getName()]);
833  } catch (ExistingTargetFolderException $e) {
834  $this->writeLog(3, 1, 123, 'Target "%s" already exists!', [$targetFolderObject->getIdentifier()]);
835  $this->addMessageToFlashMessageQueue('FileUtility.TargetAlreadyExists', [$targetFolderObject->getIdentifier()]);
836  } catch (\BadMethodCallException $e) {
837  $this->writeLog(3, 1, 127, 'The function to move a folder between storages is not yet implemented', []);
838  $this->addMessageToFlashMessageQueue('FileUtility.TheFunctionToMoveAFolderBetweenStoragesIsNotYetImplemented', []);
839  } catch (\RuntimeException $e) {
840  $this->writeLog(3, 2, 119, 'Directory "%s" WAS NOT moved to "%s"! Write-permission problem?', [$sourceFolderObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
841  $this->addMessageToFlashMessageQueue('FileUtility.DirectoryWasNotMovedTo', [$sourceFolderObject->getIdentifier(), $targetFolderObject->getIdentifier()]);
842  }
843  }
844  return $resultObject;
845  }
846 
858  public function func_rename($cmds)
859  {
860  if (!$this->isInit) {
861  return false;
862  }
863  $sourceFileObject = $this->getFileObject($cmds['data']);
864  $sourceFile = $sourceFileObject->getName();
865  $targetFile = $cmds['target'];
866  $resultObject = null;
867  if ($sourceFileObject instanceof File) {
868  try {
869  // Try to rename the File
870  $resultObject = $sourceFileObject->rename($targetFile);
871  $this->writeLog(5, 0, 1, 'File renamed from "%s" to "%s"', [$sourceFile, $targetFile]);
872  $this->addMessageToFlashMessageQueue('FileUtility.FileRenamedFromTo', [$sourceFile, $targetFile], FlashMessage::OK);
874  $this->writeLog(5, 1, 102, 'You are not allowed to rename files!', []);
875  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToRenameFiles');
876  } catch (IllegalFileExtensionException $e) {
877  $this->writeLog(5, 1, 101, 'Extension of file name "%s" or "%s" was not allowed!', [$sourceFileObject->getName(), $targetFile]);
878  $this->addMessageToFlashMessageQueue('FileUtility.ExtensionOfFileNameOrWasNotAllowed', [$sourceFileObject->getName(), $targetFile]);
879  } catch (ExistingTargetFileNameException $e) {
880  $this->writeLog(5, 1, 120, 'Destination "%s" existed already!', [$targetFile]);
881  $this->addMessageToFlashMessageQueue('FileUtility.DestinationExistedAlready', [$targetFile]);
882  } catch (NotInMountPointException $e) {
883  $this->writeLog(5, 1, 121, 'Destination path "%s" was not within your mountpoints!', [$targetFile]);
884  $this->addMessageToFlashMessageQueue('FileUtility.DestinationPathWasNotWithinYourMountpoints', [$targetFile]);
885  } catch (\RuntimeException $e) {
886  $this->writeLog(5, 1, 100, 'File "%s" was not renamed! Write-permission problem in "%s"?', [$sourceFileObject->getName(), $targetFile]);
887  $this->addMessageToFlashMessageQueue('FileUtility.FileWasNotRenamed', [$sourceFileObject->getName(), $targetFile]);
888  }
889  } else {
890  // Else means this is a Folder
891  try {
892  // Try to rename the Folder
893  $resultObject = $sourceFileObject->rename($targetFile);
894  $this->writeLog(5, 0, 2, 'Directory renamed from "%s" to "%s"', [$sourceFile, $targetFile]);
895  $this->addMessageToFlashMessageQueue('FileUtility.DirectoryRenamedFromTo', [$sourceFile, $targetFile], FlashMessage::OK);
897  $this->writeLog(5, 1, 111, 'You are not allowed to rename directories!', []);
898  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToRenameDirectories');
899  } catch (ExistingTargetFileNameException $e) {
900  $this->writeLog(5, 1, 120, 'Destination "%s" existed already!', [$targetFile]);
901  $this->addMessageToFlashMessageQueue('FileUtility.DestinationExistedAlready', [$targetFile]);
902  } catch (NotInMountPointException $e) {
903  $this->writeLog(5, 1, 121, 'Destination path "%s" was not within your mountpoints!', [$targetFile]);
904  $this->addMessageToFlashMessageQueue('FileUtility.DestinationPathWasNotWithinYourMountpoints', [$targetFile]);
905  } catch (\RuntimeException $e) {
906  $this->writeLog(5, 1, 110, 'Directory "%s" was not renamed! Write-permission problem in "%s"?', [$sourceFileObject->getName(), $targetFile]);
907  $this->addMessageToFlashMessageQueue('FileUtility.DirectoryWasNotRenamed', [$sourceFileObject->getName(), $targetFile]);
908  }
909  }
910  return $resultObject;
911  }
912 
923  public function func_newfolder($cmds)
924  {
925  if (!$this->isInit) {
926  return false;
927  }
928  $targetFolderObject = $this->getFileObject($cmds['target']);
929  if (!$targetFolderObject instanceof Folder) {
930  $this->writeLog(6, 2, 104, 'Destination "%s" was not a directory', [$cmds['target']]);
931  $this->addMessageToFlashMessageQueue('FileUtility.DestinationWasNotADirectory', [$cmds['target']]);
932  return false;
933  }
934  $resultObject = null;
935  try {
936  $folderName = $cmds['data'];
937  $resultObject = $targetFolderObject->createFolder($folderName);
938  $this->writeLog(6, 0, 1, 'Directory "%s" created in "%s"', [$folderName, $targetFolderObject->getIdentifier()]);
939  $this->addMessageToFlashMessageQueue('FileUtility.DirectoryCreatedIn', [$folderName, $targetFolderObject->getIdentifier()], FlashMessage::OK);
940  } catch (\TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException $e) {
941  $this->writeLog(6, 1, 104, 'Invalid folder name "%s"!', [$folderName]);
942  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToCreateDirectories', [$folderName]);
943  } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFolderWritePermissionsException $e) {
944  $this->writeLog(6, 1, 103, 'You are not allowed to create directories!', []);
945  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToCreateDirectories');
946  } catch (\TYPO3\CMS\Core\Resource\Exception\NotInMountPointException $e) {
947  $this->writeLog(6, 1, 102, 'Destination path "%s" was not within your mountpoints!', [$targetFolderObject->getIdentifier()]);
948  $this->addMessageToFlashMessageQueue('FileUtility.DestinationPathWasNotWithinYourMountpoints', [$targetFolderObject->getIdentifier()]);
949  } catch (\TYPO3\CMS\Core\Resource\Exception\ExistingTargetFolderException $e) {
950  $this->writeLog(6, 1, 101, 'File or directory "%s" existed already!', [$folderName]);
951  $this->addMessageToFlashMessageQueue('FileUtility.FileOrDirectoryExistedAlready', [$folderName]);
952  } catch (\RuntimeException $e) {
953  $this->writeLog(6, 1, 100, 'Directory "%s" not created. Write-permission problem in "%s"?', [$folderName, $targetFolderObject->getIdentifier()]);
954  $this->addMessageToFlashMessageQueue('FileUtility.DirectoryNotCreated', [$folderName, $targetFolderObject->getIdentifier()]);
955  }
956  return $resultObject;
957  }
958 
968  public function func_newfile($cmds)
969  {
970  if (!$this->isInit) {
971  return false;
972  }
973  $targetFolderObject = $this->getFileObject($cmds['target']);
974  if (!$targetFolderObject instanceof Folder) {
975  $this->writeLog(8, 2, 104, 'Destination "%s" was not a directory', [$cmds['target']]);
976  $this->addMessageToFlashMessageQueue('FileUtility.DestinationWasNotADirectory', [$cmds['target']]);
977  return false;
978  }
979  $resultObject = null;
980  $fileName = $cmds['data'];
981  try {
982  $resultObject = $targetFolderObject->createFile($fileName);
983  $this->writeLog(8, 0, 1, 'File created: "%s"', [$fileName]);
984  $this->addMessageToFlashMessageQueue('FileUtility.FileCreated', [$fileName], FlashMessage::OK);
985  } catch (IllegalFileExtensionException $e) {
986  $this->writeLog(8, 1, 106, 'Extension of file "%s" was not allowed!', [$fileName]);
987  $this->addMessageToFlashMessageQueue('FileUtility.ExtensionOfFileWasNotAllowed', [$fileName]);
989  $this->writeLog(8, 1, 103, 'You are not allowed to create files!', []);
990  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToCreateFiles');
991  } catch (NotInMountPointException $e) {
992  $this->writeLog(8, 1, 102, 'Destination path "%s" was not within your mountpoints!', [$targetFolderObject->getIdentifier()]);
993  $this->addMessageToFlashMessageQueue('FileUtility.DestinationPathWasNotWithinYourMountpoints', [$targetFolderObject->getIdentifier()]);
994  } catch (ExistingTargetFileNameException $e) {
995  $this->writeLog(8, 1, 101, 'File existed already in "%s"!', [$targetFolderObject->getIdentifier()]);
996  $this->addMessageToFlashMessageQueue('FileUtility.FileExistedAlreadyIn', [$targetFolderObject->getIdentifier()]);
997  } catch (InvalidFileNameException $e) {
998  $this->writeLog(8, 1, 106, 'File name "%s" was not allowed!', [$fileName]);
999  $this->addMessageToFlashMessageQueue('FileUtility.FileNameWasNotAllowed', [$fileName]);
1000  } catch (\RuntimeException $e) {
1001  $this->writeLog(8, 1, 100, 'File "%s" was not created! Write-permission problem in "%s"?', [$fileName, $targetFolderObject->getIdentifier()]);
1002  $this->addMessageToFlashMessageQueue('FileUtility.FileWasNotCreated', [$fileName, $targetFolderObject->getIdentifier()]);
1003  }
1004  return $resultObject;
1005  }
1006 
1013  public function func_edit($cmds)
1014  {
1015  if (!$this->isInit) {
1016  return false;
1017  }
1018  // Example indentifier for $cmds['target'] => "4:mypath/tomyfolder/myfile.jpg"
1019  // for backwards compatibility: the combined file identifier was the path+filename
1020  $fileIdentifier = $cmds['target'];
1021  $fileObject = $this->getFileObject($fileIdentifier);
1022  // Example indentifier for $cmds['target'] => "2:targetpath/targetfolder/"
1023  $content = $cmds['data'];
1024  if (!$fileObject instanceof File) {
1025  $this->writeLog(9, 2, 123, 'Target "%s" was not a file!', [$fileIdentifier]);
1026  $this->addMessageToFlashMessageQueue('FileUtility.TargetWasNotAFile', [$fileIdentifier]);
1027  return false;
1028  }
1029  $extList = $GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext'];
1030  if (!GeneralUtility::inList($extList, $fileObject->getExtension())) {
1031  $this->writeLog(9, 1, 102, 'File extension "%s" is not a textfile format! (%s)', [$fileObject->getExtension(), $extList]);
1032  $this->addMessageToFlashMessageQueue('FileUtility.FileExtensionIsNotATextfileFormat', [$fileObject->getExtension(), $extList]);
1033  return false;
1034  }
1035  try {
1036  $fileObject->setContents($content);
1037  clearstatcache();
1038  $this->writeLog(9, 0, 1, 'File saved to "%s", bytes: %s, MD5: %s ', [$fileObject->getIdentifier(), $fileObject->getSize(), md5($content)]);
1039  $this->addMessageToFlashMessageQueue('FileUtility.FileSavedToBytesMd5', [$fileObject->getIdentifier(), $fileObject->getSize(), md5($content)], FlashMessage::OK);
1040  return true;
1042  $this->writeLog(9, 1, 104, 'You are not allowed to edit files!', []);
1043  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToEditFiles');
1044  return false;
1046  $this->writeLog(9, 1, 100, 'File "%s" was not saved! Write-permission problem?', [$fileObject->getIdentifier()]);
1047  $this->addMessageToFlashMessageQueue('FileUtility.FileWasNotSaved', [$fileObject->getIdentifier()]);
1048  return false;
1049  } catch (IllegalFileExtensionException $e) {
1050  $this->writeLog(9, 1, 100, 'File "%s" was not saved! File extension rejected!', [$fileObject->getIdentifier()]);
1051  $this->addMessageToFlashMessageQueue('FileUtility.FileWasNotSaved', [$fileObject->getIdentifier()]);
1052  return false;
1053  }
1054  }
1055 
1086  public function func_upload($cmds)
1087  {
1088  if (!$this->isInit) {
1089  return false;
1090  }
1091  $uploadPosition = $cmds['data'];
1092  $uploadedFileData = $_FILES['upload_' . $uploadPosition];
1093  if (empty($uploadedFileData['name']) || is_array($uploadedFileData['name']) && empty($uploadedFileData['name'][0])) {
1094  $this->writeLog(1, 2, 108, 'No file was uploaded!', []);
1095  $this->addMessageToFlashMessageQueue('FileUtility.NoFileWasUploaded');
1096  return false;
1097  }
1098  // Example indentifier for $cmds['target'] => "2:targetpath/targetfolder/"
1099  $targetFolderObject = $this->getFileObject($cmds['target']);
1100  // Uploading with non HTML-5-style, thus, make an array out of it, so we can loop over it
1101  if (!is_array($uploadedFileData['name'])) {
1102  $uploadedFileData = [
1103  'name' => [$uploadedFileData['name']],
1104  'type' => [$uploadedFileData['type']],
1105  'tmp_name' => [$uploadedFileData['tmp_name']],
1106  'size' => [$uploadedFileData['size']]
1107  ];
1108  }
1109  $resultObjects = [];
1110  $numberOfUploadedFilesForPosition = count($uploadedFileData['name']);
1111  // Loop through all uploaded files
1112  for ($i = 0; $i < $numberOfUploadedFilesForPosition; $i++) {
1113  $fileInfo = [
1114  'name' => $uploadedFileData['name'][$i],
1115  'type' => $uploadedFileData['type'][$i],
1116  'tmp_name' => $uploadedFileData['tmp_name'][$i],
1117  'size' => $uploadedFileData['size'][$i]
1118  ];
1119  try {
1120  if ((int)$this->dontCheckForUnique === 1) {
1121  GeneralUtility::deprecationLog('dontCheckForUnique = 1 is deprecated. Use setExistingFilesConflictMode(DuplicationBehavior::REPLACE);. Support for dontCheckForUnique will be removed in TYPO3 CMS 8.');
1122  $this->existingFilesConflictMode = DuplicationBehavior::cast(DuplicationBehavior::REPLACE);
1123  }
1124 
1126  $fileObject = $targetFolderObject->addUploadedFile($fileInfo, (string)$this->existingFilesConflictMode);
1127  $fileObject = ResourceFactory::getInstance()->getFileObjectByStorageAndIdentifier($targetFolderObject->getStorage()->getUid(), $fileObject->getIdentifier());
1128  if ($this->existingFilesConflictMode->equals(DuplicationBehavior::REPLACE)) {
1129  $this->getIndexer($fileObject->getStorage())->updateIndexEntry($fileObject);
1130  }
1131  $resultObjects[] = $fileObject;
1132  $this->internalUploadMap[$uploadPosition] = $fileObject->getCombinedIdentifier();
1133  $this->writeLog(1, 0, 1, 'Uploading file "%s" to "%s"', [$fileInfo['name'], $targetFolderObject->getIdentifier()]);
1134  $this->addMessageToFlashMessageQueue('FileUtility.UploadingFileTo', [$fileInfo['name'], $targetFolderObject->getIdentifier()], FlashMessage::OK);
1136  $this->writeLog(1, 1, 107, 'You are not allowed to override "%s"!', [$fileInfo['name']]);
1137  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToOverride', [$fileInfo['name']]);
1138  } catch (UploadException $e) {
1139  $this->writeLog(1, 2, 106, 'The upload has failed, no uploaded file found!', []);
1140  $this->addMessageToFlashMessageQueue('FileUtility.TheUploadHasFailedNoUploadedFileFound');
1142  $this->writeLog(1, 1, 105, 'You are not allowed to upload files!', []);
1143  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToUploadFiles');
1144  } catch (UploadSizeException $e) {
1145  $this->writeLog(1, 1, 104, 'The uploaded file "%s" exceeds the size-limit', [$fileInfo['name']]);
1146  $this->addMessageToFlashMessageQueue('FileUtility.TheUploadedFileExceedsTheSize-limit', [$fileInfo['name']]);
1148  $this->writeLog(1, 1, 103, 'Destination path "%s" was not within your mountpoints!', [$targetFolderObject->getIdentifier()]);
1149  $this->addMessageToFlashMessageQueue('FileUtility.DestinationPathWasNotWithinYourMountpoints', [$targetFolderObject->getIdentifier()]);
1150  } catch (IllegalFileExtensionException $e) {
1151  $this->writeLog(1, 1, 102, 'Extension of file name "%s" is not allowed in "%s"!', [$fileInfo['name'], $targetFolderObject->getIdentifier()]);
1152  $this->addMessageToFlashMessageQueue('FileUtility.ExtensionOfFileNameIsNotAllowedIn', [$fileInfo['name'], $targetFolderObject->getIdentifier()]);
1153  } catch (ExistingTargetFileNameException $e) {
1154  $this->writeLog(1, 1, 101, 'No unique filename available in "%s"!', [$targetFolderObject->getIdentifier()]);
1155  $this->addMessageToFlashMessageQueue('FileUtility.NoUniqueFilenameAvailableIn', [$targetFolderObject->getIdentifier()]);
1156  } catch (\RuntimeException $e) {
1157  $this->writeLog(1, 1, 100, 'Uploaded file could not be moved! Write-permission problem in "%s"?', [$targetFolderObject->getIdentifier()]);
1158  $this->addMessageToFlashMessageQueue('FileUtility.UploadedFileCouldNotBeMoved', [$targetFolderObject->getIdentifier()]);
1159  }
1160  }
1161 
1162  return $resultObjects;
1163  }
1164 
1172  public function func_unzip($cmds)
1173  {
1174  if (!$this->isInit || $this->dont_use_exec_commands) {
1175  return false;
1176  }
1177  $theFile = $cmds['data'];
1178  if (!@is_file($theFile)) {
1179  $this->writeLog(7, 2, 105, 'The file "%s" did not exist!', [$theFile]);
1180  $this->addMessageToFlashMessageQueue('FileUtility.TheFileDidNotExist', [$theFile]);
1181  return false;
1182  }
1183  $fI = GeneralUtility::split_fileref($theFile);
1184  if (!isset($cmds['target'])) {
1185  $cmds['target'] = $fI['path'];
1186  }
1187  // Clean up destination directory
1188  // !!! Method has been put in the local driver, can be saftely removed
1189  $theDest = $this->is_directory($cmds['target']);
1190  if (!$theDest) {
1191  $this->writeLog(7, 2, 104, 'Destination "%s" was not a directory', [$cmds['target']]);
1192  $this->addMessageToFlashMessageQueue('FileUtility.DestinationWasNotADirectory', [$cmds['target']]);
1193  return false;
1194  }
1195  if (!$this->actionPerms['unzipFile']) {
1196  $this->writeLog(7, 1, 103, 'You are not allowed to unzip files', '');
1197  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToUnzipFiles');
1198  return false;
1199  }
1200  if ($fI['fileext'] != 'zip') {
1201  $this->writeLog(7, 1, 102, 'File extension is not "zip"', '');
1202  $this->addMessageToFlashMessageQueue('FileUtility.FileExtensionIsNotzip');
1203  return false;
1204  }
1205  if (!$this->checkIfFullAccess($theDest)) {
1206  $this->writeLog(7, 1, 101, 'You don\'t have full access to the destination directory "%s"!', [$theDest]);
1207  $this->addMessageToFlashMessageQueue('FileUtility.YouDontHaveFullAccessToTheDestinationDirectory', [$theDest]);
1208  return false;
1209  }
1210  // !!! Method has been put in the storage driver, can be safely removed
1211  if ($this->checkPathAgainstMounts($theFile) && $this->checkPathAgainstMounts($theDest . '/')) {
1212  // No way to do this under windows.
1213  $cmd = $this->unzipPath . 'unzip -qq ' . escapeshellarg($theFile) . ' -d ' . escapeshellarg($theDest);
1214  CommandUtility::exec($cmd);
1215  $this->writeLog(7, 0, 1, 'Unzipping file "%s" in "%s"', [$theFile, $theDest]);
1216  $this->addMessageToFlashMessageQueue('FileUtility.UnzippingFileIn', [$theFile, $theDest], FlashMessage::OK);
1217  return true;
1218  } else {
1219  $this->writeLog(7, 1, 100, 'File "%s" or destination "%s" was not within your mountpoints!', [$theFile, $theDest]);
1220  $this->addMessageToFlashMessageQueue('FileUtility.FileOrDestinationWasNotWithinYourMountpoints', [$theFile, $theDest]);
1221  return false;
1222  }
1223  }
1224 
1235  protected function replaceFile(array $cmdArr)
1236  {
1237  if (!$this->isInit) {
1238  return false;
1239  }
1240 
1241  $uploadPosition = $cmdArr['data'];
1242  $fileInfo = $_FILES['replace_' . $uploadPosition];
1243  if (empty($fileInfo['name'])) {
1244  $this->writeLog(1, 2, 108, 'No file was uploaded for replacing!', []);
1245  $this->addMessageToFlashMessageQueue('FileUtility.NoFileWasUploadedForReplacing');
1246  return false;
1247  }
1248 
1249  $keepFileName = ($cmdArr['keepFilename'] == 1) ? true : false;
1250  $resultObjects = [];
1251 
1252  try {
1253  $fileObjectToReplace = $this->getFileObject($cmdArr['uid']);
1254  $folder = $fileObjectToReplace->getParentFolder();
1255  $resourceStorage = $fileObjectToReplace->getStorage();
1256 
1257  $fileObject = $resourceStorage->addUploadedFile($fileInfo, $folder, $fileObjectToReplace->getName(), DuplicationBehavior::REPLACE);
1258 
1259  // Check if there is a file that is going to be uploaded that has a different name as the replacing one
1260  // but exists in that folder as well.
1261  // rename to another name, but check if the name is already given
1262  if ($keepFileName === false) {
1263  // if a file with the same name already exists, we need to change it to _01 etc.
1264  // if the file does not exist, we can do a simple rename
1265  $resourceStorage->moveFile($fileObject, $folder, $fileInfo['name'], DuplicationBehavior::RENAME);
1266  }
1267 
1268  $resultObjects[] = $fileObject;
1269  $this->internalUploadMap[$uploadPosition] = $fileObject->getCombinedIdentifier();
1270 
1271  $this->writeLog(1, 0, 1, 'Replacing file "%s" to "%s"', [$fileInfo['name'], $fileObjectToReplace->getIdentifier()]);
1272  $this->addMessageToFlashMessageQueue('FileUtility.ReplacingFileTo', [$fileInfo['name'], $fileObjectToReplace->getIdentifier()], FlashMessage::OK);
1274  $this->writeLog(1, 1, 107, 'You are not allowed to override "%s"!', [$fileInfo['name']]);
1275  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToOverride', [$fileInfo['name']]);
1276  } catch (UploadException $e) {
1277  $this->writeLog(1, 2, 106, 'The upload has failed, no uploaded file found!', []);
1278  $this->addMessageToFlashMessageQueue('FileUtility.TheUploadHasFailedNoUploadedFileFound');
1280  $this->writeLog(1, 1, 105, 'You are not allowed to upload files!', []);
1281  $this->addMessageToFlashMessageQueue('FileUtility.YouAreNotAllowedToUploadFiles');
1282  } catch (UploadSizeException $e) {
1283  $this->writeLog(1, 1, 104, 'The uploaded file "%s" exceeds the size-limit', [$fileInfo['name']]);
1284  $this->addMessageToFlashMessageQueue('FileUtility.TheUploadedFileExceedsTheSize-limit', [$fileInfo['name']]);
1286  $this->writeLog(1, 1, 103, 'Destination path "%s" was not within your mountpoints!', [$fileObjectToReplace->getIdentifier()]);
1287  $this->addMessageToFlashMessageQueue('FileUtility.DestinationPathWasNotWithinYourMountpoints', [$fileObjectToReplace->getIdentifier()]);
1288  } catch (IllegalFileExtensionException $e) {
1289  $this->writeLog(1, 1, 102, 'Extension of file name "%s" is not allowed in "%s"!', [$fileInfo['name'], $fileObjectToReplace->getIdentifier()]);
1290  $this->addMessageToFlashMessageQueue('FileUtility.ExtensionOfFileNameIsNotAllowedIn', [$fileInfo['name'], $fileObjectToReplace->getIdentifier()]);
1291  } catch (ExistingTargetFileNameException $e) {
1292  $this->writeLog(1, 1, 101, 'No unique filename available in "%s"!', [$fileObjectToReplace->getIdentifier()]);
1293  $this->addMessageToFlashMessageQueue('FileUtility.NoUniqueFilenameAvailableIn', [$fileObjectToReplace->getIdentifier()]);
1294  } catch (\RuntimeException $e) {
1295  throw $e;
1296  }
1297  return $resultObjects;
1298  }
1299 
1306  protected function addFlashMessage(FlashMessage $flashMessage)
1307  {
1309  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
1310 
1312  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
1313  $defaultFlashMessageQueue->enqueue($flashMessage);
1314  }
1315 
1322  protected function getIndexer(ResourceStorage $storage)
1323  {
1324  return GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\Index\Indexer::class, $storage);
1325  }
1326 
1332  protected function getDatabaseConnection()
1333  {
1334  return $GLOBALS['TYPO3_DB'];
1335  }
1336 
1340  protected function getBackendUser()
1341  {
1342  return $GLOBALS['BE_USER'];
1343  }
1344 
1350  protected function getLanguageService()
1351  {
1352  return $GLOBALS['LANG'];
1353  }
1354 }
writeLog($action, $error, $details_nr, $details, $data)
addMessageToFlashMessageQueue($localizationKey, array $replaceMarkers=[], $severity=FlashMessage::ERROR)
static exec($command, &$output=null, &$returnValue=0)
static getConstants($include_default=false)
static split_fileref($fileNameWithPath)
getFiles($start=0, $numberOfItems=0, $filterMode=self::FILTER_MODE_USE_OWN_AND_STORAGE_FILTERS, $recursive=false, $sort='', $sortRev=false)
Definition: Folder.php:218
const FILTER_MODE_USE_OWN_AND_STORAGE_FILTERS
Definition: Folder.php:68
static getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']