type sonata_type_model_list collection php file-upload symfony symfony-sonata

php - sonata_type_model_list - sonata collection type



¿Cómo mostrar la imagen actual sobre el campo de carga en SonataAdminBundle? (7)

Solución para Symfony3

La respuesta de @kkochanski es la forma más limpia que he encontrado hasta ahora. Aquí una versión portada a Symfony3 . También he arreglado algunos errores.

Cree una nueva plantilla image.html.twig para su nuevo tipo de formulario (ruta completa: 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 %}

Registre la nueva plantilla de tipo de formulario en su config.yml :

twig: form_themes: - AppBundle::Form/image.html.twig

Cree un nuevo tipo de formulario y guárdelo como ImageType.php (ruta completa: 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 has hecho esto. Solo puede importar el nuevo ImageType en su clase de administrador de entidad:

use AppBundle/Form/Type/ImageType

Y luego, finalmente use el nuevo tipo de formulario sin ningún código inline-html o repetitivo en configureFormFields :

$formMapper ->add(''imageFile'', ImageType::class, [''image_web_path'' => $image->getImagePath()]) ;

En lugar de $image->getImagePath() tienes que llamar a tu propio método que devuelve la URL a tu imagen.

Capturas de pantalla

Creando una nueva entidad de imagen usando sonata admin:

Editando una entidad de imagen usando sonata admin:

Estoy usando SonataAdminBundle (con Doctrine2 ORM) y he agregado con éxito una función de carga de archivos a mi modelo de imagen.

Me gustaría, en las páginas Mostrar y Editar , mostrar una <img src="{{ picture.url }} alt="{{ picture.title }} /> simple justo arriba del campo de formulario relevante (siempre que La imagen que se está editando no es nueva, por supuesto), por lo que el usuario puede ver la foto actual y decidir si la cambia o no.

Después de horas de investigación, no he podido averiguar cómo hacerlo. Supongo que necesito anular alguna plantilla, pero estoy un poco perdido ... ¿Alguien me puede dar una pista?

¡Gracias!

Aquí está la sección relevante de mi clase 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 }


Hay una forma fácil, pero verá la imagen debajo del botón de carga. SonataAdmin permite poner HTML en bruto en la opción de "ayuda" para cualquier campo de formulario dado. Puede utilizar esta funcionalidad para incrustar una etiqueta de imagen:

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


He logrado colocar la imagen sobre el campo en el formulario de edición. Pero mi solución es un poco específica, porque uso Vich Uploader Bundle para manejar las subidas, por lo que la generación de la URL de la imagen fue un poco más fácil gracias a los ayudantes de paquetes.

Veamos mi ejemplo, un campo de póster de una película en una entidad cinematográfica. Esto es parte de mi clase de administrador:

//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 se maneja mediante un tipo de campo personalizado, que es solo un hijo del tipo de archivo al configurar su método getParent : (no olvide registrar su clase de tipo como un servicio)

//MyCompany/MyBundle/Form/Type/MyBundleAdminImageType.php public function getParent() { return ''file''; }

Luego tengo una plantilla que amplía el estilo predeterminado de Sonata y la tengo incluida en la clase de administración:

//MyCompany/MyBundle/Admin/FilmAdmin.php public function getFormTheme() { return array(''MyCompanyMyBundle:Form:mycompany_admin_fields.html.twig''); }

Y, finalmente, tengo un bloque para mi tipo de imagen personalizada que amplía el tipo de archivo básico:

//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 %}

Esto hace que se muestre una vista previa amplia de la imagen de 200 píxeles (si existe) sobre el campo de carga, vinculada a su versión de tamaño completo que se abre en una nueva pestaña. Puede personalizarlo como desee, por ejemplo, agregando un complemento de lightbox.


Puede hacer esto fácilmente en la página de presentación por el atributo de plantilla que pasa en $showmapper

->add(''picture'', NULL, array( ''template'' => ''MyProjectBundle:Project:mytemplate.html.twig'' );

y dentro de tu plantilla obtienes el objeto actual para que puedas llamar al método de obtención y extracción de la ruta

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

Para mostrar la imagen en el modo de edición, debe anular fileType o crear su propio customType encima de fileType

También hay algún paquete que está teniendo este tipo de funcionalidad en este GenemuFormBundle


Puedes hacerlo de esta manera.

$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 ));


Teo.sk escribió el método de mostrar imágenes usando VichUploader. Encontré una opción que te permite mostrar imágenes sin este paquete.

Primero necesitamos crear nuestro form_type. Hay tutorial: symfony_tutorial

En la clase principal de administración:

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 siguiente parte es un código de la clase 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'']) ; } }

Y en el tiempo final para la plantilla de imagen de tipo de ramita.

{% 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 %}

¡Para mí está funcionando! También estoy usando un paquete de avalanchas para cambiar el tamaño de las imágenes.


Usted puede hacer esto fácilmente en la página de edición por parte de los ayudantes (FormMapper-> setHelps) o la opción "ayuda" pasar a 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) ; }