J'utilise SonataAdminBundle (avec Doctrine2 ORM) et j'ai ajouté avec succès une fonctionnalité de téléchargement de fichier à mon modèle Picture.
Je voudrais, sur les pages Afficher et Éditer , afficher une simple balise <img src="{{ picture.url }} alt="{{ picture.title }} />
juste au-dessus du champ de formulaire approprié (à condition que l'image en cours d'édition ne soit pas nouvelle, bien sûr), afin que l'utilisateur peut voir la photo actuelle et décider de la modifier ou non.
Après des heures de recherche, je suis incapable de comprendre comment le faire. Je suppose que je dois remplacer certains modèles, mais je suis un peu perdu ... Quelqu'un peut-il me donner un indice?
Merci!
Voici la section pertinente de ma classe PictureAdmin.
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('category', NULL, ['label' => 'Catégorie'])
->add('title', NULL, ['label' => 'Titre'])
->add('file', 'file', ['required' => false, 'label' => 'Fichier']) // Add picture near this field
->add('creation_date', NULL, ['label' => 'Date d\'ajout'])
->add('visible', NULL, ['required' => false, 'label' => 'Visible'])
->add('position', NULL, ['label' => 'Position']);
}
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->add('id', NULL, ['label' => 'ID'])
->add('category', NULL, ['label' => 'Catégorie'])
->add('title', NULL, ['label' => 'Titre'])
->add('slug', NULL, ['label' => 'Titre (URL)'])
->add('creation_date', NULL, ['label' => 'Date d\'ajout'])
->add('visible', NULL, ['label' => 'Visible'])
->add('position', NULL, ['label' => 'Position']);
// Add picture somewhere
}
Vous pouvez facilement faire cela sur show page par l'attribut template, transmettez $showmapper
.
->add('picture', NULL, array(
'template' => 'MyProjectBundle:Project:mytemplate.html.twig'
);
et à l'intérieur de votre modèle, vous obtenez un objet actuel pour pouvoir appeler la méthode get et extraire le chemin de l'image
<th>{% block name %}{{ admin.trans(field_description.label) }}{% endblock %}</th>
<td>
<img src="{{ object.getFile }}" title="{{ object.getTitle }}" />
</br>
{% block field %}{{ value|nl2br }}{% endblock %}
</td>
Pour afficher une image en mode édition, vous devez remplacer fileType
ou créer votre propre type personnalisé au-dessus de fileType
.
Il y a aussi un paquet qui a ce genre de fonctionnalité vérifier ceci GenemuFormBundle
J'ai réussi à mettre l'image au-dessus du champ dans le formulaire de modification. Mais ma solution est un peu spécifique, car j’utilise Vich Uploader Bundle pour gérer les chargements, de sorte que la création de l’URL de l’image était un peu plus facile grâce aux bundles.
Regardons mon exemple, un champ d’affiche de film dans une entité cinématographique. Cela fait partie de ma classe d'administrateur:
//MyCompany/MyBundle/Admin/FilmAdmin.php
class FilmAdmin extends Admin {
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('title')
....
->add('poster', 'mybundle_admin_image', array(
'required' => false,
))
}
mybundle_admin_image
est géré par un type de champ personnalisé, qui est simplement un enfant de type de fichier en définissant sa méthode getParent
: (n'oubliez pas d'enregistrer votre classe de type en tant que service)
//MyCompany/MyBundle/Form/Type/MyBundleAdminImageType.php
public function getParent()
{
return 'file';
}
Ensuite, j'ai un modèle qui étend le style par défaut de Sonata, et je l'ai inclus dans la classe admin:
//MyCompany/MyBundle/Admin/FilmAdmin.php
public function getFormTheme() {
return array('MyCompanyMyBundle:Form:mycompany_admin_fields.html.twig');
}
Et enfin, j'ai un bloc pour mon type d'image personnalisé qui étend le type de fichier de base:
//MyCompany/MyBundle/Resources/views/Form/mycompany_admin_fields.html.twig
{% block mybundle_admin_image_widget %}
{% spaceless %}
{% set subject = form.parent.vars.value %}
{% if subject.id and attribute(subject, name) %}
<a href="{{ asset(vich_uploader_asset(subject, name)) }}" target="_blank">
<img src="{{ asset(vich_uploader_asset(subject, name)) }}" width="200" />
</a><br/>
{% endif %}
{% set type = type|default('file') %}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
{% endspaceless %}
{% endblock %}
Cela entraîne l'affichage d'un aperçu de l'image de 200 pixels de large (s'il existe) au-dessus du champ de téléchargement, lié à sa version agrandie dans un nouvel onglet. Vous pouvez le personnaliser comme vous le souhaitez, par exemple ajout d'un plugin lightbox.
vous pouvez facilement le faire sur la page d'édition à l'aide de helpers (FormMapper-> setHelps) ou de l'option "help" pour transmettre FormMapper
protected function configureFormFields(FormMapper $formMapper) {
$options = array('required' => false);
if (($subject = $this->getSubject()) && $subject->getPhoto()) {
$path = $subject->getPhotoWebPath();
$options['help'] = '<img src="' . $path . '" />';
}
$formMapper
->add('title')
->add('description')
->add('createdAt', null, array('data' => new \DateTime()))
->add('photoFile', 'file', $options)
;
}
La réponse de @kkochanski est la manière la plus propre que j'ai trouvée jusqu'à présent. Voici une version portée sur Symfony3 . J'ai aussi corrigé des bugs.
Créez un nouveau modèle image.html.twig
pour votre nouveau type de formulaire (chemin d'accès complet: src/AppBundle/Resources/views/Form/image.html.twig
):
{% block image_widget %}
{% spaceless %}
{% set type = type|default('file') %}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
{% if image_web_path is not empty %}
<img src="{{ image_web_path }}" alt="image_photo"/>
{% endif %}
{% endspaceless %}
{% endblock %}
Enregistrez le nouveau modèle de type de formulaire dans votre config.yml
:
twig:
form_themes:
- AppBundle::Form/image.html.twig
Créez un nouveau type de formulaire et enregistrez-le sous le nom ImageType.php
(chemin complet: src/AppBundle/Form/Type/ImageType.php
):
<?php
namespace AppBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormBuilderInterface;
/**
* Class ImageType
*
* @package AppBundle\Form\Type
*/
class ImageType extends AbstractType
{
/**
* @return string
*/
public function getParent()
{
return 'file';
}
/**
* @return string
*/
public function getName()
{
return 'image';
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'image_web_path' => ''
));
}
/**
* @param FormView $view
* @param FormInterface $form
* @param array $options
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['image_web_path'] = $options['image_web_path'];
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->setAttribute('image_web_path', $options['image_web_path'])
;
}
}
Si vous avez fait cela. Vous pouvez simplement importer la nouvelle ImageType
dans votre classe admin d'entité:
use AppBundle\Form\Type\ImageType
Enfin, utilisez enfin le nouveau type de formulaire sans code inline-html ou boilerplate dans configureFormFields
:
$formMapper
->add('imageFile', ImageType::class, ['image_web_path' => $image->getImagePath()])
;
Au lieu de $image->getImagePath()
, vous devez appeler votre propre méthode qui renvoie l'URL à votre image.
Création d'une nouvelle entité image à l'aide de sonata admin:
Modification d’une entité image à l’aide de sonata admin:
Vous pouvez faire simple de cette façon
$image = $this->getSubject();
$imageSmall = '';
if($image){
$container = $this->getConfigurationPool()->getContainer();
$media = $container->get('sonata.media.twig.extension');
$format = 'small';
if($webPath = $image->getImageSmall()){
$imageSmall = '<img src="'.$media->path($image->getImageSmall(), $format).'" class="admin-preview" />';
}
}
$formMapper->add('imageSmall', 'sonata_media_type', array(
'provider' => 'sonata.media.provider.image',
'context' => 'default',
'help' => $imageSmall
));
Il existe un moyen simple - mais vous verrez l'image ci-dessous le bouton de téléchargement. SonataAdmin permet d'insérer du code HTML brut dans l'option ‘help’ pour tout champ de formulaire donné. Vous pouvez utiliser cette fonctionnalité pour incorporer une balise d'image:
protected function configureFormFields(FormMapper $formMapper) {
$object = $this->getSubject();
$container = $this->getConfigurationPool()->getContainer();
$fullPath = $container->get('request')->getBasePath().'/'.$object->getWebPath();
$formMapper->add('file', 'file', array('help' => is_file($object->getAbsolutePath() . $object->getPlanPath()) ? '<img src="' . $fullPath . $object->getPlanPath() . '" class="admin-preview" />' : 'Picture is not avialable')
}
Teo.sk a écrit la méthode d'affichage d'images à l'aide de VichUploader. J'ai trouvé une option qui vous permet d'afficher des images sans cet ensemble.
Nous devons d’abord créer notre type_formulaire. Il y a un tutoriel: symfony_tutorial
Dans la classe d'administration principale:
namespace Your\Bundle;
//.....//
class ApplicationsAdmin extends Admin {
//...//
public function getFormTheme() {
return array_merge(
parent::getFormTheme(),
array('YourBundle:Form:image_type.html.twig') //your path to form_type template
);
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper->add('file_photo', 'image', array(
'data_class' => 'Symfony\Component\HttpFoundation\File\File',
'label' => 'Photo',
'image_web_path' => $this->getRequest()->getBasePath().'/'.$subject->getWebPathPhoto()// it's a my name of common getWebPath method
))
//....//
;
}
}
La partie suivante est un code de la classe ImageType.
namespace Your\Bundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class ImageType extends AbstractType
{
public function getParent()
{
return 'file';
}
public function getName()
{
return 'image';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'image_web_path' => ''
));
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['image_web_path'] = $options['image_web_path'];
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->setAttribute('image_web_path', $options['image_web_path'])
;
}
}
Et à l'heure de la fin pour le modèle de brin image_type.
{% block image_widget %}
{% spaceless %}
{% set type = type|default('file') %}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
<img src="{{ image_web_path }}" alt="image_photo"/>
{% endspaceless %}
{% endblock %}
Pour moi ça marche! J'utilise également un paquet d'avalanche pour redimensionner les images.