How to store blob image in database #13687
-
I am using filament file upload component and want to store the image in the database as a blob instead of storing it to a disk. How can I achieve this ? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
There doesn't seem to be an easy way to do this with the built-in image field as it is built around the laravel disk drivers. I was able to trick filament into storing the uploade file as a data URI in the field by doing the following: In the form I modified the field like so: Forms\FileUpload::make($yourFileFieldNameHere)
->disk('fake')
->getUploadedFileNameForStorageUsing(
fn(TemporaryUploadedFile $file): string => 'data:' . $file->getMimeType() . ';base64,' . base64_encode($file->getContent())
) Then I added the following to the 'fake' => [
'driver' => 'fake',
], I also registered the \Illuminate\Support\Facades\Storage::extend('fake', function (\Illuminate\Contracts\Foundation\Application $app, array $config) {
$adapter = new FakeAdapter();
return new \Illuminate\Filesystem\FilesystemAdapter(
new \League\Flysystem\Filesystem($adapter, $config),
$adapter,
$config
);
}); The use Composer\Downloader\FilesystemException;
use Illuminate\Http\Testing\MimeType;
use League\Flysystem\Config;
use League\Flysystem\FileAttributes;
use League\Flysystem\FilesystemAdapter;
use League\Flysystem\StorageAttributes;
use League\Flysystem\UnableToCheckExistence;
use League\Flysystem\UnableToCopyFile;
use League\Flysystem\UnableToCreateDirectory;
use League\Flysystem\UnableToDeleteDirectory;
use League\Flysystem\UnableToMoveFile;
use League\Flysystem\UnableToSetVisibility;
class FakeAdapter implements FilesystemAdapter
{
/**
* @throws FilesystemException
* @throws UnableToCheckExistence
*/
public function fileExists(string $path): bool
{
return true;
}
/**
* @throws FilesystemException
* @throws UnableToCheckExistence
*/
public function directoryExists(string $path): bool
{
throw new FilesystemException('Adapter does not support directory operations.');
}
/**
* @throws UnableToWriteFile
* @throws FilesystemException
*/
public function write(string $path, string $contents, Config $config): void
{
//
}
/**
* @param resource $contents
*
* @throws UnableToWriteFile
* @throws FilesystemException
*/
public function writeStream(string $path, $contents, Config $config): void
{
$this->write($path, stream_get_contents($contents), $config);
}
/**
* @throws UnableToReadFile
* @throws FilesystemException
*/
public function read(string $path): string
{
return $path;
}
/**
* @return resource
*
* @throws UnableToReadFile
* @throws FilesystemException
*/
public function readStream(string $path)
{
$stream = fopen('php://temp', 'r+');
fwrite($stream, $this->read($path));
rewind($stream);
return $stream;
}
/**
* @throws UnableToDeleteFile
* @throws FilesystemException
*/
public function delete(string $path): void
{
//
}
/**
* @throws UnableToDeleteDirectory
* @throws FilesystemException
*/
public function deleteDirectory(string $path): void
{
//
}
/**
* @throws UnableToCreateDirectory
* @throws FilesystemException
*/
public function createDirectory(string $path, Config $config): void
{
throw new FilesystemException('Adapter does not support directory operations.');
}
/**
* @throws InvalidVisibilityProvided
* @throws FilesystemException
*/
public function setVisibility(string $path, string $visibility): void
{
throw UnableToSetVisibility::atLocation($path, 'Adapter does not support visibility controls.');
}
/**
* @throws UnableToRetrieveMetadata
* @throws FilesystemException
*/
public function visibility(string $path): FileAttributes
{
return new FileAttributes($path);
}
/**
* @throws UnableToRetrieveMetadata
* @throws FilesystemException
*/
public function mimeType(string $path): FileAttributes
{
$matches = preg_match('/^data:([^;]+);base64/', $path);
if ($matches) return $matches[0];
return new FileAttributes($path, mimeType: MimeType::from($path));
}
/**
* @throws UnableToRetrieveMetadata
* @throws FilesystemException
*/
public function lastModified(string $path): FileAttributes
{
return new FileAttributes($path, lastModified: time());
}
/**
* @throws UnableToRetrieveMetadata
* @throws FilesystemException
*/
public function fileSize(string $path): FileAttributes
{
$matches = preg_match('/^data:[^;]+;base64,(.+)$/', $path);
if ($matches) return strlen(base64_decode($matches[0]));
return new FileAttributes($path, fileSize: strlen($path));
}
/**
* @return iterable<StorageAttributes>
*
* @throws FilesystemException
*/
public function listContents(string $path, bool $deep): iterable
{
throw new FilesystemException('Adapter does not support directory operations.');
}
/**
* @throws UnableToMoveFile
* @throws FilesystemException
*/
public function move(string $source, string $destination, Config $config): void
{
throw UnableToMoveFile::because(
'Adapter does not support directory operations.',
sourcePath: $source,
destinationPath: $destination,
);
}
/**
* @throws UnableToCopyFile
* @throws FilesystemException
*/
public function copy(string $source, string $destination, Config $config): void
{
throw UnableToCopyFile::because(
'Adapter does not support directory operations.',
sourcePath: $source,
destinationPath: $destination,
);
}
public function getUrl(string $path): string
{
return $path;
}
} A better approach might be to use a custom driver that writes to a model field and prevent the FileUpload field from writing its value (the filename) which would overwrite the file. But this would also require telling FileUpload how to turn the stored value into a file, which seems tricky. |
Beta Was this translation helpful? Give feedback.
There doesn't seem to be an easy way to do this with the built-in image field as it is built around the laravel disk drivers.
I was able to trick filament into storing the uploade file as a data URI in the field by doing the following:
In the form I modified the field like so:
Then I added the following to the
disks
entry inconfig/filesystems.php
:I also registered the
fake
storage in…