Skip to content

Commit

Permalink
fixed serializing file uploads into a PostgreSQL database
Browse files Browse the repository at this point in the history
  • Loading branch information
craue committed Aug 30, 2023
1 parent 5a79c93 commit 94c7720
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
26 changes: 26 additions & 0 deletions Storage/SerializableFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,30 @@ public static function isSupported($file) {
return $file instanceof UploadedFile;
}

public function __serialize() : array {
return [
'content' => $this->content,
'type' => $this->type,
'clientOriginalName' => $this->clientOriginalName,
'clientMimeType' => $this->clientMimeType,
];
}

public function __unserialize(array $data) : void {
// TODO remove for 4.0
// handle representation of object which got serialized before `__serialize` method was added
if (count(array_diff(array_keys($data), ["\x00*\x00content", "\x00*\x00type", "\x00*\x00clientOriginalName", "\x00*\x00clientMimeType"])) === 0) {
$this->content = $data["\x00*\x00content"];
$this->type = $data["\x00*\x00type"];
$this->clientOriginalName = $data["\x00*\x00clientOriginalName"];
$this->clientMimeType = $data["\x00*\x00clientMimeType"];
return;
}

$this->content = $data['content'];
$this->type = $data['type'];
$this->clientOriginalName = $data['clientOriginalName'];
$this->clientMimeType = $data['clientMimeType'];
}

}
75 changes: 75 additions & 0 deletions Tests/Storage/DataManagerIntegrationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace Craue\FormFlowBundle\Tests\Storage;

use Craue\FormFlowBundle\Form\FormFlow;
use Craue\FormFlowBundle\Storage\DataManager;
use Craue\FormFlowBundle\Storage\SerializableFile;
use Craue\FormFlowBundle\Tests\IntegrationTestCase;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;

/**
* @group integration
* @group run-with-multiple-databases-only
*
* @author Christian Raue <[email protected]>
* @copyright 2011-2023 Christian Raue
* @license http://opensource.org/licenses/mit-license.php MIT License
*/
class DataManagerIntegrationTest extends IntegrationTestCase {

/**
* Ensure that a file uploaded within a flow is saved and restored correctly.
*/
public function testSaveLoad_file() : void {
$session = new Session(new MockArraySessionStorage());
$session->setId('12345');

$request = Request::create('/');
$request->setSession($session);

$this->getService('request_stack')->push($request);

/** @var $dataManager DataManager */
$dataManager = $this->getService('craue.form.flow.data_manager');
$dataManager->dropAll();

$flow = $this->getFlow('testFlow', 'instance');

$imagePath = __DIR__ . '/../Fixtures/blue-pixel.png';
$imageFile = new UploadedFile($imagePath, basename($imagePath), 'image/png', null, true);

$dataIn = ['photo' => new SerializableFile($imageFile)];
$dataOut = ['photo' => $imageFile];

$dataManager->save($flow, $dataIn);

$this->assertEquals($dataOut, $dataManager->load($flow));
}

/**
* @return MockObject|FormFlow
*/
private function getFlow(string $name, string $instanceId) {
$flow = $this->getMockBuilder(FormFlow::class)->onlyMethods(['getName', 'isHandleFileUploads'])->getMock();

$flow
->method('getName')
->will($this->returnValue($name))
;

$flow
->method('isHandleFileUploads')
->will($this->returnValue(true))
;

$flow->setInstanceId($instanceId);

return $flow;
}

}
11 changes: 11 additions & 0 deletions Tests/Storage/SerializableFileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,17 @@ public function testSerialization_unsupportedType() {
new SerializableFile(new File(__FILE__));
}

// TODO remove for 4.0
public function testSerialization_unserializeLegacyRepresentation() : void {
$legacySerializedObject = <<<HERE
O:45:"Craue\FormFlowBundle\Storage\SerializableFile":4:{s:10:"\x00*\x00content";s:16:"c29tZSB0ZXh0DQo=";s:7:"\x00*\x00type";s:50:"Symfony\Component\HttpFoundation\File\UploadedFile";s:21:"\x00*\x00clientOriginalName";s:6:"my.txt";s:17:"\x00*\x00clientMimeType";s:10:"text/plain";}
HERE;

$object = new SerializableFile($this->getNewUploadedFile(__DIR__ . self::DOCUMENT, 'my.txt', 'text/plain'));

$this->assertEquals($object, unserialize($legacySerializedObject));
}

public function testIsSupported() {
$this->assertTrue(SerializableFile::isSupported($this->getNewUploadedFile(__FILE__, basename(__FILE__))));
$this->assertFalse(SerializableFile::isSupported(new File(__FILE__)));
Expand Down

0 comments on commit 94c7720

Please sign in to comment.