[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