首先:我完全意識到這一問題的創建日期,但最近我在同樣的問題,在這裏我想上傳一個MP3文件,並只保留文件擴展名的MP3,而不是切換其絆倒到mpga。據我所知,在過去三年中,沒有簡單的解決方案添加到源代碼中...
我很確定我的解決方案不是最好的,但它的工作與代碼少量添加:)
在我的項目,我有一個Media
對象的BinaryContent
設置爲Symfony的Request
類,從而導致問題恰好這條線上傳文件:
// FileProvider.php#L483
$guesser = ExtensionGuesser::getInstance();
$extension = $guesser->guess($media->getContentType());
FileProvider
類獲取ExtensionGuesser
的實例從Symfony和讓他做猜測擴展爲給定的ContentType應該是什麼樣的工作:
// MimeTypeExtensionGuesser.php#L623
'audio/mpeg' => 'mpga',
在我看來,這將是巨大的,如果我們既可以添加自己的MimeType->Extension
映射或簡單地替換之類的ExtensionGuesser在配置文件中有一個小改動。但沒有人知道像我們這樣的三個人不想上傳mp3文件,並將擴展名切換爲mpga ......所以沒有像這樣的解決方案。
但是實際上我們可以改變的className的FileProvider
的,只是覆蓋,我們希望做一些不同的方法:
// app/config/services.yml
parameters:
sonata.media.provider.file.class: Application\Sonata\MediaBundle\Provider\FileProvider
// Application\Sonata\MediaBundle\Provider\FileProvider:
<?php
namespace Application\Sonata\MediaBundle\Provider;
use Sonata\MediaBundle\Extra\ApiMediaFile;
use Sonata\MediaBundle\Model\MediaInterface;
use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser;
use Symfony\Component\HttpFoundation\Request;
/**
* Class FileProvider
*
* @package Application\Sonata\MediaBundle\Provider
*/
class FileProvider extends \Sonata\MediaBundle\Provider\FileProvider
{
/**
* @var array
*/
protected $contentTypeMapping = [
'audio/mpeg' => 'mp3'
];
/**
* Set media binary content according to request content.
*
* @param MediaInterface $media
*/
protected function generateBinaryFromRequest(MediaInterface $media)
{
if (php_sapi_name() === 'cli') {
throw new \RuntimeException('The current process cannot be executed in cli environment');
}
if (!$media->getContentType()) {
throw new \RuntimeException(
'You must provide the content type value for your media before setting the binary content'
);
}
$request = $media->getBinaryContent();
if (!$request instanceof Request) {
throw new \RuntimeException('Expected Request in binary content');
}
$content = $request->getContent();
$extension = $this->getExtension($media->getContentType());
$handle = tmpfile();
fwrite($handle, $content);
$file = new ApiMediaFile($handle);
$file->setExtension($extension);
$file->setMimetype($media->getContentType());
$media->setBinaryContent($file);
}
/**
* Returns the fileExtension for a given contentType
*
* First of all, we have to look at our own mapping and if we have no mapping defined, just use the ExtensionGuesser
*
* @param string $contentType
*
* @return string
*/
private function getExtension($contentType)
{
if (array_key_exists($contentType, $this->contentTypeMapping)) {
return $this->contentTypeMapping[$contentType];
}
// create unique id for media reference
$guesser = ExtensionGuesser::getInstance();
$extension = $guesser->guess($contentType);
if (!$extension) {
throw new \RuntimeException(
sprintf('Unable to guess extension for content type %s', $contentType)
);
}
return $extension;
}
}
直到現在它工作得很好,我沒有問題吧:)
你有沒有找到這個問題的解決方案? –
還沒有。我決定根據這位索納塔經理,供應商和發電機組撰寫自行車... – nvvetal