问题
I'm trying to create two custom providers, one for PDF and another one for ZIP files.
This is my code.
services.yml
parameters:
application_sonata_media.zip_class: Application\Sonata\MediaBundle\Provider\ZipProvider
services:
sonata.media.provider.zip:
class: %application_sonata_media.zip_class%
tags:
- { name: sonata.media.provider }
arguments:
- sonata.media.provider.zip
- @sonata.media.filesystem.local
- @sonata.media.cdn.server
- @sonata.media.generator.default
- @sonata.media.thumbnail.format
- ['zip']
- ['application/zip']
sonata_media.yml
sonata_media:
contexts:
eag_zip:
download:
strategy: sonata.media.security.public_strategy
mode: http
providers:
- sonata.media.provider.zip
formats:
reference: { quality: 100 }
ZipProvider.php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
namespace Application\Sonata\MediaBundle\Provider;
use Sonata\MediaBundle\Provider\BaseProvider;
use Gaufrette\Filesystem;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\CoreBundle\Model\Metadata;
use Sonata\MediaBundle\CDN\CDNInterface;
use Sonata\MediaBundle\Generator\GeneratorInterface;
use Sonata\MediaBundle\Metadata\MetadataBuilderInterface;
use Sonata\MediaBundle\Model\MediaInterface;
use Sonata\MediaBundle\Thumbnail\ThumbnailInterface;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotNull;
/**
* Description of ZipProvider
*
* @author Juanjo García <juanjogarcia@editartgroup.com>
*/
class ZipProvider extends BaseProvider {
protected $allowedExtensions;
protected $allowedMimeTypes;
protected $metadata;
/**
* @param string $name
* @param \Gaufrette\Filesystem $filesystem
* @param \Sonata\MediaBundle\CDN\CDNInterface $cdn
* @param \Sonata\MediaBundle\Generator\GeneratorInterface $pathGenerator
* @param \Sonata\MediaBundle\Thumbnail\ThumbnailInterface $thumbnail
* @param array $allowedExtensions
* @param array $allowedMimeTypes
* @param \Sonata\MediaBundle\Metadata\MetadataBuilderInterface $metadata
*/
public function __construct($name, Filesystem $filesystem, CDNInterface $cdn, GeneratorInterface $pathGenerator, ThumbnailInterface $thumbnail, array $allowedExtensions = array(), array $allowedMimeTypes = array(), MetadataBuilderInterface $metadata = null)
{
parent::__construct($name, $filesystem, $cdn, $pathGenerator, $thumbnail);
$this->allowedExtensions = $allowedExtensions;
$this->allowedMimeTypes = $allowedMimeTypes;
$this->metadata = $metadata;
}
/**
* {@inheritdoc}
*/
public function getProviderMetadata()
{
return new Metadata($this->getName(), $this->getName().'.description', false, 'SonataMediaBundle', array('class' => 'fa fa-file-text-o'));
}
/**
* {@inheritdoc}
*/
public function getReferenceImage(MediaInterface $media)
{
return sprintf('%s/%s',
$this->generatePath($media),
$media->getProviderReference()
);
}
/**
* {@inheritdoc}
*/
public function getReferenceFile(MediaInterface $media)
{
return $this->getFilesystem()->get($this->getReferenceImage($media), true);
}
/**
* {@inheritdoc}
*/
public function buildEditForm(FormMapper $formMapper)
{
$formMapper->add('name');
$formMapper->add('enabled', null, array('required' => false));
$formMapper->add('authorName');
$formMapper->add('cdnIsFlushable');
$formMapper->add('description');
$formMapper->add('copyright');
$formMapper->add('binaryContent', 'file', array('required' => false));
}
/**
* {@inheritdoc}
*/
public function buildCreateForm(FormMapper $formMapper)
{
$formMapper->add('binaryContent', 'file', array(
'constraints' => array(
new NotBlank(),
new NotNull(),
),
));
}
/**
* {@inheritdoc}
*/
public function buildMediaType(FormBuilder $formBuilder)
{
$formBuilder->add('binaryContent', 'file');
}
/**
* {@inheritdoc}
*/
public function postPersist(MediaInterface $media)
{
if ($media->getBinaryContent() === null) {
return;
}
$this->setFileContents($media);
$this->generateThumbnails($media);
}
/**
* {@inheritdoc}
*/
public function postUpdate(MediaInterface $media)
{
if (!$media->getBinaryContent() instanceof \SplFileInfo) {
return;
}
// Delete the current file from the FS
$oldMedia = clone $media;
$oldMedia->setProviderReference($media->getPreviousProviderReference());
$path = $this->getReferenceImage($oldMedia);
if ($this->getFilesystem()->has($path)) {
$this->getFilesystem()->delete($path);
}
$this->fixBinaryContent($media);
$this->setFileContents($media);
$this->generateThumbnails($media);
}
/**
* @throws \RuntimeException
*
* @param \Sonata\MediaBundle\Model\MediaInterface $media
*
* @return
*/
protected function fixBinaryContent(MediaInterface $media)
{
if ($media->getBinaryContent() === null) {
return;
}
// if the binary content is a filename => convert to a valid File
if (!$media->getBinaryContent() instanceof File) {
if (!is_file($media->getBinaryContent())) {
throw new \RuntimeException('The file does not exist : '.$media->getBinaryContent());
}
$binaryContent = new File($media->getBinaryContent());
$media->setBinaryContent($binaryContent);
}
}
/**
* @throws \RuntimeException
*
* @param \Sonata\MediaBundle\Model\MediaInterface $media
*/
protected function fixFilename(MediaInterface $media)
{
if ($media->getBinaryContent() instanceof UploadedFile) {
$media->setName($media->getName() ?: $media->getBinaryContent()->getClientOriginalName());
$media->setMetadataValue('filename', $media->getBinaryContent()->getClientOriginalName());
} elseif ($media->getBinaryContent() instanceof File) {
$media->setName($media->getName() ?: $media->getBinaryContent()->getBasename());
$media->setMetadataValue('filename', $media->getBinaryContent()->getBasename());
}
// this is the original name
if (!$media->getName()) {
throw new \RuntimeException('Please define a valid media\'s name');
}
}
/**
* {@inheritdoc}
*/
protected function doTransform(MediaInterface $media)
{
$this->fixBinaryContent($media);
$this->fixFilename($media);
// this is the name used to store the file
if (!$media->getProviderReference()) {
$media->setProviderReference($this->generateReferenceName($media));
}
if ($media->getBinaryContent()) {
$media->setContentType($media->getBinaryContent()->getMimeType());
$media->setSize($media->getBinaryContent()->getSize());
}
$media->setProviderStatus(MediaInterface::STATUS_OK);
}
/**
* {@inheritdoc}
*/
public function updateMetadata(MediaInterface $media, $force = true)
{
// this is now optimized at all!!!
$path = tempnam(sys_get_temp_dir(), 'sonata_update_metadata');
$fileObject = new \SplFileObject($path, 'w');
$fileObject->fwrite($this->getReferenceFile($media)->getContent());
$media->setSize($fileObject->getSize());
}
/**
* {@inheritdoc}
*/
public function generatePublicUrl(MediaInterface $media, $format)
{
if ($format == 'reference') {
$path = $this->getReferenceImage($media);
} else {
// @todo: fix the asset path
$path = sprintf('sonatamedia/files/%s/file.png', $format);
}
return $this->getCdn()->getPath($path, $media->getCdnIsFlushable());
}
/**
* {@inheritdoc}
*/
public function getHelperProperties(MediaInterface $media, $format, $options = array())
{
return array_merge(array(
'title' => $media->getName(),
'thumbnail' => $this->getReferenceImage($media),
'file' => $this->getReferenceImage($media),
), $options);
}
/**
* {@inheritdoc}
*/
public function generatePrivateUrl(MediaInterface $media, $format)
{
if ($format == 'reference') {
return $this->getReferenceImage($media);
}
return false;
}
/**
* Set the file contents for an image.
*
* @param \Sonata\MediaBundle\Model\MediaInterface $media
* @param string $contents path to contents, defaults to MediaInterface BinaryContent
*/
protected function setFileContents(MediaInterface $media, $contents = null)
{
$file = $this->getFilesystem()->get(sprintf('%s/%s', $this->generatePath($media), $media->getProviderReference()), true);
if (!$contents) {
$contents = $media->getBinaryContent()->getRealPath();
}
$metadata = $this->metadata ? $this->metadata->get($media, $file->getName()) : array();
$file->setContent(file_get_contents($contents), $metadata);
}
/**
* @param \Sonata\MediaBundle\Model\MediaInterface $media
*
* @return string
*/
protected function generateReferenceName(MediaInterface $media)
{
return sha1($media->getName().rand(11111, 99999)).'.'.$media->getBinaryContent()->guessExtension();
}
/**
* {@inheritdoc}
*/
public function getDownloadResponse(MediaInterface $media, $format, $mode, array $headers = array())
{
// build the default headers
$headers = array_merge(array(
'Content-Type' => $media->getContentType(),
'Content-Disposition' => sprintf('attachment; filename="%s"', $media->getMetadataValue('filename')),
), $headers);
if (!in_array($mode, array('http', 'X-Sendfile', 'X-Accel-Redirect'))) {
throw new \RuntimeException('Invalid mode provided');
}
if ($mode == 'http') {
if ($format == 'reference') {
$file = $this->getReferenceFile($media);
} else {
$file = $this->getFilesystem()->get($this->generatePrivateUrl($media, $format));
}
return new StreamedResponse(function () use ($file) {
echo $file->getContent();
}, 200, $headers);
}
if (!$this->getFilesystem()->getAdapter() instanceof \Sonata\MediaBundle\Filesystem\Local) {
throw new \RuntimeException('Cannot use X-Sendfile or X-Accel-Redirect with non \Sonata\MediaBundle\Filesystem\Local');
}
$filename = sprintf('%s/%s',
$this->getFilesystem()->getAdapter()->getDirectory(),
$this->generatePrivateUrl($media, $format)
);
return new BinaryFileResponse($filename, 200, $headers);
}
/**
* {@inheritdoc}
*/
public function validate(ErrorElement $errorElement, MediaInterface $media)
{
if (!$media->getBinaryContent() instanceof \SplFileInfo) {
return;
}
if ($media->getBinaryContent() instanceof UploadedFile) {
$fileName = $media->getBinaryContent()->getClientOriginalName();
} elseif ($media->getBinaryContent() instanceof File) {
$fileName = $media->getBinaryContent()->getFilename();
} else {
throw new \RuntimeException(sprintf('Invalid binary content type: %s', get_class($media->getBinaryContent())));
}
if (!in_array(strtolower(pathinfo($fileName, PATHINFO_EXTENSION)), $this->allowedExtensions)) {
$errorElement
->with('binaryContent')
->addViolation('Invalid extensions')
->end();
}
if (!in_array($media->getBinaryContent()->getMimeType(), $this->allowedMimeTypes)) {
$errorElement
->with('binaryContent')
->addViolation('Invalid mime type : '.$media->getBinaryContent()->getMimeType())
->end();
}
}
}
When I push create and edit button, the file pass the validation, save in DDBB and file in server, but in URL /admin/sonata/media/media/233/edit?provider=sonata.media.provider.zip&context=eag_zip I get this Error message:
Unable to find template "" in SonataMediaBundle:MediaAdmin:edit.html.twig at line 48.
Trying to go to /admin/sonata/media/media/list?provider=sonata.media.provider.zip&context=eag_zip or /admin/sonata/media/media/list?context=eag_zip
Unable to find template "" in SonataMediaBundle:MediaAdmin:inner_row_media.html.twig at line 19.
I don't know to solve it.
any help would be welcome
thanks a lot
回答1:
Solved here
services:
sonata.media.provider.zip:
class: %application_sonata_media.zip_class%
tags:
- { name: sonata.media.provider }
arguments:
- sonata.media.provider.zip
- @sonata.media.filesystem.local
- @sonata.media.cdn.server
- @sonata.media.generator.default
- @sonata.media.thumbnail.format
- ['zip']
- ['application/zip']
calls:
- [ setTemplates, [{helper_view:SonataMediaBundle:Provider:view_image.html.twig,helper_thumbnail:SonataMediaBundle:Provider:thumbnail.html.twig}]]
来源:https://stackoverflow.com/questions/35648019/sonatamediabundle-custom-provider