web-dev-qa-db-fra.com

Comment afficher la photo actuelle au-dessus du champ de téléchargement dans SonataAdminBundle?

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
}
19
RockTheShow

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

9
Anil Gupta

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.

14
Teo.sk

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)
    ;
}
11

Solution pour Symfony3

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.

Captures d'écran

Création d'une nouvelle entité image à l'aide de sonata admin:

 enter image description here

Modification d’une entité image à l’aide de sonata admin:

 enter image description here

5
Thomas Kekeisen

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
   ));
2
Azam Alvi

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')

}
0
stefan pamm

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.

0
kkochanski