Commit 6715ff92 authored by Benjamin Franzke's avatar Benjamin Franzke Committed by Benni Mack
Browse files

[BUGFIX] Fix serialization of FileReference objects

FileReferences objects contain references to File
objects which itself contain service dependencies
(e.g. event dispatcher) which are not seralizable.

This leads to problems for instance when having
a multi-step form containing file uploads where
file reference objects are being serialized.

For TYPO3 v9.5 there is no direct exception, but serialized
data still contained lots of superfluous information. That's
why this change is back-ported to v9.5 as well.

Resolves: #91196
Releases: master, 10.4, 9.5
Change-Id: I7650186adc5c61528e1a1adcf06b8d6cf67a55cd
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/68341

Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent 61481707
......@@ -36,15 +36,6 @@ class FileReference implements FileInterface
*/
protected $propertiesOfFileReference;
/**
* The identifier of this file to identify it on the storage.
* On some drivers, this is the path to the file, but drivers could also just
* provide any other unique identifier for this file on the specific storage.
*
* @var string
*/
protected $uidOfFileReference;
/**
* The file name of this file. It's either the fileName of the original underlying file,
* or the overlay file name supplied by the user for this particular usage (FileReference) of the file.
......@@ -76,8 +67,8 @@ class FileReference implements FileInterface
* @param array $fileReferenceData
* @param ResourceFactory $factory
*
* @throws \RuntimeException
* @throws \InvalidArgumentException
* @throws Exception\FileDoesNotExistException
*/
public function __construct(array $fileReferenceData, $factory = null)
{
......@@ -85,18 +76,24 @@ class FileReference implements FileInterface
if (!$fileReferenceData['uid_local']) {
throw new \InvalidArgumentException('Incorrect reference to original file given for FileReference.', 1300098528);
}
if (!$factory) {
$this->originalFile = $this->getFileObject((int)$fileReferenceData['uid_local'], $factory);
$this->name = $fileReferenceData['name'] !== '' ? $fileReferenceData['name'] : $this->originalFile->getName();
}
/**
* @param int $uidLocal
* @param ResourceFactory|null $factory
* @return FileInterface
*
* @throws Exception\FileDoesNotExistException
*/
private function getFileObject(int $uidLocal, ResourceFactory $factory = null): FileInterface
{
if ($factory === null) {
/** @var ResourceFactory $factory */
$factory = ResourceFactory::getInstance();
}
$this->originalFile = $factory->getFileObject($fileReferenceData['uid_local']);
if (!is_object($this->originalFile)) {
throw new \RuntimeException(
'Original file not found for FileReference. UID given: "' . $fileReferenceData['uid_local'] . '"',
1300098529
);
}
$this->name = $fileReferenceData['name'] !== '' ? $fileReferenceData['name'] : $this->originalFile->getName();
return $factory->getFileObject($uidLocal);
}
/*******************************
......@@ -516,4 +513,24 @@ class FileReference implements FileInterface
{
return $this->originalFile->getParentFolder();
}
/**
* Avoids exporting original file object which contains
* singleton dependencies that must not be serialized.
*
* @return string[]
*/
public function __sleep(): array
{
$keys = get_object_vars($this);
unset($keys['originalFile']);
return array_keys($keys);
}
public function __wakeup(): void
{
$this->originalFile = $this->getFileObject(
(int)$this->propertiesOfFileReference['uid_local']
);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment