[TYPO3-dev] ResourceStorage : Question about postFileCopySignal, "conflictMode" and "getUniqueName"

Christian Reiter cr at cNOSPAMxd.de
Mon Jun 1 10:55:46 CEST 2015


Hi,

In TYPO3\CMS\Core\Resource\ResourceStorage, among the signals emitted 
when handling files are pre + postFileCopySignal.

I see issues when "conflictmode = renameNewFile" is hit, which is the 
default (see TYPO3\CMS\Core\Resource\ResourceStorage::copyFile)

Scenario:
I copy "fileadmin/test.jpg" to "fileadmin/folder/" where there is 
already "test.jpg", "test_0.jpg", "test_1.jpg", "test_3.jpg".

Both pre and post transfer the *original* fileobject and target folder 
object.

Let's assume I have a script that wants to do smething with the newly 
created copy of the file(object). The postFileCopySignal is emitted 
after that is created.

   $this->emitPostFileCopySignal($file, $targetFolder);

The problem:
The listener of the signal can't figure out the new filename 
unambiguosly in all cases. And it doesn't get the new Fileobject to just 
ask FAL. It only gets the old fileobject.

If TYPO3\CMS\Core\Resource\ResourceStorage::copyFile detected that a 
file of the same name already exists at the target, this happens:

// File exists and we should find another name, let's find another one
if (
   $conflictMode === 'renameNewFile' &&
   $targetFolder->hasFile($sanitizedTargetFileName)
    ) {

   $sanitizedTargetFileName = $this->getUniqueName(
     $targetFolder,
     $sanitizedTargetFileName
     );
...
$newFileObjectIdentifier = $this->driver->copyFileWithinStorage(
     $file->getIdentifier(),
     $targetFolder->getIdentifier(),
     $sanitizedTargetFileName
   );
...
$newFileObject = ResourceFactory::getInstance()->
    getFileObjectByStorageAndIdentifier(
      $this->getUid(),
      $newFileObjectIdentifier
      );

That means the name of the new copy is not in all cases just built from 
the basename of the path of $file and the path of $targetFolder.

In "conflictMode == renameNewFile" case  it can be "whatever got 
returned by $this->getUniqueName".

So the Slot method would need to

* perhaps check if the file mtime of the filename deduced from $file & 
$targetfolder is older than the original, cannot therefore be the newly 
created copy, and then "hunt" for the copy until a "plausible match" is 
found?
Note: just running getUniqueName again does not give the same result of 
course, it will be the name for the *next* possible copy, we need 
"previous getUnique result..."

* use the last generated FAL uid (race conditions...)

Wouldn't it be better to have the signals like this:

   $this->emitPreFileCopySignal($file, $targetFolder);
   $this->emitPostFileCopySignal($file, $newFileObject);

so that after the copy, the Slot gets the $newFileObject,
instead of the current (6.2 and master) situation where both just get 
the original input.

   $this->emitPreFileCopySignal($file, $targetFolder);
   $this->emitPostFileCopySignal($file, $targetFolder);

By emitting the "post" signal with the fileobject that results from the 
operation, we avoid forcing the listener to duplicate implementation of 
internal logic of the preceding operation.

In general I think it would be a good idea, that if an operation emits 
"pre" and "post" signals, and creates new non-trivial result objects 
from the input, the "post" signal should give a slot some handle to 
access the result object?

Thanks for any feedback,


Christian







More information about the TYPO3-dev mailing list