PrestaConcept
Nos réalisations
Nos métiers
  • Découvrez nos métiers
  • Développement web sur mesure

    Nous développons en méthode agile des back sous le framework PHP Symfony, des front en Angular.

  • Maintenance d'applications

    Maintien en condition opérationnelle de votre plateforme Symfony.

  • Expertise Symfony

    Coaching, formation, audit et conseil.

  • Hébergement et Infogérance

    Une expertise de l'hébergement depuis plus de 15 ans et l’infogérance de centaines de machines en production actuellement.

  • Qui sommes nous
  • Découvrez Prestaconcept
  • PrestaConcept

    Notre histoire, nos convictions, notre vision... Découvrez ce qui nous anime !

  • L'équipe

    Plus de 15 ans minimum d'expérience sur Symfony.

  • Nos engagements RSE

    Une société engagée pour un numérique responsable.

  • Nos convictions

    Co-construction, transparence.. Les principes qui guident nos collaborations !

  • Nous rejoindre

    Envie de nous rejoindre ? Consultez nos offres !

  • Blog
    J'ai un projet Nous contacter
    J'ai un projet Nous contacter Menu
    • Accueil
    • Blog
    • Tech
    • Librarie Open Source : PrestaImageBundle

    Blog

    Librarie Open Source : PrestaImageBundle

    bundle form formulaire image open source php symfony upload
    Benoit Jouhaud
    Benoit Jouhaud Développeur expert Symfony
    Publié le mercredi 3 mars 2021

    Le bundle open source made by Prestaconcept qui permet à vos utilisateurs de redimensionner une image à l'upload.

    Besoin

    Charger une image sur son site est un besoin fréquent, par exemple pour enrichir son compte d'une photo de profil, illustrer un article de blog ou un produit de sa boutique en ligne.

    Problématique

    Pour respecter la mise en page du site, il est généralement nécessaire de contraindre les images dans un format et/ou des dimensions bien précises, ce qui conduit souvent à des images aplaties ou étirées. Or un utilisateur lambda a rarement cette notion à l'esprit lorsqu'il choisit son image, et encore plus rarement les outils adaptés pour la redimensionner.

    Solution

    C'est là qu'intervient ce bundle.

    En couplant la librairie JavaScript Cropper.js avec Symfony, il permet à vos utilisateurs de redimensionner une image en ligne en amont de son chargement sur le serveur, selon un format adapté pour son usage que vous aurez potentiellement contraint au préalable.

    Cela permet à vos utilisateurs de garder le contrôle sur l'image qu'ils souhaitent charger tout en vous évitant d'avoir à la redimensionner côté serveur avec le risque de la déformer ou de perdre le sujet de l'image.

    Installation

    Ajoutez le bundle en dépendance de votre projet.

    composer require presta/image-bundle
    

    Si vous n'êtes pas encore passés sous symfony/flex (vous devriez y songer), ajoutez les bundles suivants à votre kernel.

    new Vich\UploaderBundle\VichUploaderBundle(),
    new Presta\ImageBundle\PrestaImageBundle(),
    

    Importez les routes du bundle.

    presta_image:
        resource: "@PrestaImageBundle/Resources/config/routing.yml"
    

    Configurez Twig pour utiliser le thème du formulaire (ou développez le vôtre).

    twig:
        form_themes:
            - "@PrestaImage/form/bootstrap_4.html.twig"
    

    Configurez VichUploader.

    vich_uploader:
        db_driver: 'orm'
    
        mappings:
            profile_image:
                uri_prefix: '/images/profiles'
                upload_destination: '%kernel.project_dir%/public/images/profiles'
                namer: 'Vich\UploaderBundle\Naming\SmartUniqueNamer'
    

    Installez les dépendances JavaScript.

    npm install jquery-cropper jquery cropperjs bootstrap
    

    Incluez les scripts et les styles suivants sur votre page.

    /path/to/jquery.min.js
    /path/to/cropper.min.js
    /path/to/cropper.min.css
    /path/to/jquery-cropper.min.js
    /path/to/bootstrap.min.js
    /path/to/bootstrap.min/css
    @PrestaImageBundle/Resources/public/css/cropper.css
    @PrestaImageBundle/Resources/public/js/cropper.js
    

    Initialisez la librairie Cropper du bundle.

    (function(w, $) {
    
        'use strict';
    
        $(function() {
            $('.cropper').each(function() {
                new Cropper($(this));
            });
        });
    
    })(window, jQuery);
    

    Alternative avec Webpack Encore.

    Installation

    npm install --save-dev @symfony/webpack-encore node-sass sass-loader webpack-notifier
    

    Fichier de configuration (webpack.config.js)

    const Encore = require('@symfony/webpack-encore');
    const path = require('path');
    
    Encore
        .setOutputPath('public/build/')
        .setPublicPath('/build')
    
        .addEntry('js/app', './assets/js/app.js')
        .addStyleEntry('css/app', './assets/css/app.scss')
    
        .cleanupOutputBeforeBuild()
        .enableBuildNotifications()
        .enableSourceMaps(!Encore.isProduction())
        .enableVersioning(Encore.isProduction())
    
        .addAliases({
            prestaimage: path.resolve(__dirname, 'public/bundles/prestaimage')
        })
    
        .enableSassLoader()
        .autoProvidejQuery()
    ;
    
    module.exports = Encore.getWebpackConfig();
    

    Fichier de styles (assets/css/app.scss)

    @import "~bootstrap/scss/bootstrap";
    @import "~cropper/dist/cropper.min.css";
    @import "../../public/bundles/prestaimage/css/cropper.css";
    

    Fichier de scripts (assets/js/app.js)

    import 'bootstrap';
    import 'cropper/dist/cropper.min'
    import * as Cropper from 'prestaimage/js/cropper';
    
    $(function() {
        $('.cropper').each(function() {
            new Cropper($(this));
        });
    });
    

    Voilà, c'est installé. Ne reste plus qu'à développer vos formulaires d'upload d'images et à les intégrer.

    Cas d'usage

    Imaginons que vous souhaitiez permettre à vos utilisateurs de charger une image de profil au format 4:3.

    Création de l'entité.

    <?php
    
    namespace App\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use Symfony\Component\HttpFoundation\File\File;
    use Vich\UploaderBundle\Entity\File as EmbeddedFile;
    use Vich\UploaderBundle\Mapping\Annotation as Vich;
    
    /**
     * @ORM\Entity
     * @Vich\Uploadable
     */
    class User
    {
        /**
         * @var int|null
         * 
         * @ORM\Id()
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * NOTE: This is not a mapped field of entity metadata, just a simple property.
         * 
         * @var File|null
         * 
         * @Vich\UploadableField(mapping="profile_image", fileNameProperty="picture.name", size="picture.size", mimeType="picture.mimeType", originalName="picture.originalName", dimensions="picture.dimensions")
         */
        private $pictureFile;
    
        /**
         * @var EmbeddedFile
         *
         * @ORM\Embedded(class="Vich\UploaderBundle\Entity\File")
         */
        private $picture;
    
        /**
         * @var \DateTimeImmutable|null
         *
         * @ORM\Column(type="datetime_immutable")
         */
        private $updatedAt;
    
        public function __construct()
        {
            $this->picture = new EmbeddedFile();
        }
    
        public function setPictureFile(?File $pictureFile = null): void
        {
            $this->pictureFile = $pictureFile;
    
            if (null !== $pictureFile) {
                // It is required that at least one field changes if you are using doctrine
                // otherwise the event listeners won't be called and the file is lost
                $this->updatedAt = new \DateTimeImmutable();
            }
        }
    
        public function getPictureFile(): ?File
        {
            return $this->pictureFile;
        }
    
        public function setPicture(EmbeddedFile $picture): void
        {
            $this->picture = $picture;
        }
    
        public function getPicture(): ?EmbeddedFile
        {
            return $this->picture;
        }
    }
    

    Création du contrôleur.

    <?php
    
    namespace App\Controller;
    
    use App\Entity\User;
    use App\Form\Type\ProfileType;
    use Doctrine\ORM\EntityManagerInterface;
    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    
    class ProfileController extends AbstractController
    {
        public function __invoke(Request $request, EntityManagerInterface $entityManager, User $user): Response
        {
            $form = $this->createForm(ProfileType::class, $user);
            $form->handleRequest($request);
    
            if (!$form->isSubmitted() || !$form->isValid()) {
                return $this->render('profile.html.twig', [
                    'form' => $form->createView(),
                ];
            }
    
            $entityManager->flush();
    
            return $this->redirectToRoute('...');
        }
    }
    

    Création du template Twig.

    {% extends 'base.html.twig' %}
    
    {% block body %}
        {{ form(form) }}
    {% endblock %}
    

    Création du formulaire d'upload d'image.

    <?php
    
    namespace App\Form\Type;
    
    use App\Entity\User;
    use Presta\ImageBundle\Form\Type\ImageType;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    
    class ProfileType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options): void
        {
            $builder
                ->add('picture', ImageType::class)
            ;
        }
    
        public function configureOptions(OptionsResolver $resolver): void
        {
            $resolver
                ->setDefault('data_class', User::class)
            ;
        }
    }
    

    Par défaut, la liste des formats disponibles est la suivante : 16:9, 4:3, 1, 2:3, Libre, mais vous pouvez la configurer à votre guise.

    use Presta\ImageBundle\Model\AspectRatio;
    
    $builder
        ->add('picture', ImageType::class, [
            'aspect_ratios' => [
                '3_4' => new AspectRatio(3/4, 'translation_path.3_4', true),
                '3_2' => new AspectRatio(1.5, 'translation_path.3_2', false),
            ],
        ])
    ;
    

    Pour voir la liste des options disponibles et plus de détails sur l'intégration du bundle, vous pouvez vous reporter au Dépôt GitHub du projet.

    Conclusion

    Grâce à ce bundle, finis les problèmes d'images aplaties ou étirées. Vous pouvez contraindre le format d'image en préalable à son chargement, tout en fournissant un moyen simple et intégré à vos utilisateurs pour qu'ils gardent le contrôle sur les images qu'ils vont charger.

    Next steps

    La sortie récente de Symfony UX pourrait permettre une meilleure intégration de ce bundle à l'écosystème Symfony grâce notamment au composant Symfony UX Cropper.js. Utiliser ce composant pourrait notamment permettre d'automatiser l'installation des dépendances JavaScript, afin de simplifier le processus d'installation.

    Cette refonte pourrait également être l'occasion de se séparer de jQuery en réécrivant le code en JavaScript natif. On pourrait aussi en profiter pour proposer un template standard indépendant de Bootstrap.

    Voici plusieurs axes d'évolution à considérer dans les semaines ou les mois à venir...

    Blog

    Pour continuer votre lecture ...

    Tech

    Des filtres enregistrés dans vos admins Sonata

    Par Benoit Jouhaud 07/12/2023

    Le PrestaSonataSavedFiltersBundle est un bundle Symfony qui permet de gérer des filtres enregistrés pouvant être appliqués aux listes des admins Sonata afin de les restaurer dans un état précis.
    Il s'intègre aux écrans de liste via un menu situé en haut à droite de l'écran, et dispose d'une admin p...

    Lire la suite
    Tech

    Librarie Open Source : YokaiEnumBundle

    Par Yann Eugoné 04/06/2021

    Un bundle OpenSource qui apporte un système d'énumération totalement intégré à votre projet Symfony.

    Lire la suite
    Tech

    Librarie Open Source : PrestaSitemapBundle

    Par Yann Eugoné 23/10/2020

    Le bundle OpenSource made by Prestaconcept qui génère le sitemap de votre projet Symfony

    Lire la suite

    Vous avez un projet Laravel ?

    Nous sommes spécialisés en Symfony, et grâce à Web^ID, l’agence sœur du groupe Agile Invest, nous couvrons aussi toute l’expertise Laravel.

    Découvrir Web^ID

    Une question, un projet ?
    Planifiez un échange avec nous !

    Choisissez votre date
    PrestaConcept - Groupe Agile Invest
    5, imp. Morel, 69003 Lyon +33 (0)4 78 54 45 45
    Suivez-nous
    Ecoindex B

    Ce site internet est un site basse consommation. En savoir plus sur l'Ecoindex

    Nos réalisations

  • Logiciel de mise en conformité réglementaire
  • Application de suivi de production des centrales éoliennes
  • Outil d'aide à la décision
  • Portail client
  • Nos métiers

  • Développement sur-mesure
  • Reprise d'application Symfony
  • Expertise Symfony
  • Hébergement & Infogérance
  • Qui sommes-nous

  • PrestaConcept
  • Groupe Agile Invest
  • L'équipe
  • Engagement RSE
  • Blog

  • Tech
  • Méthodologie
  • PrestaConcept
  • RSE
  • © 2025 PrestaConcept
    Mentions légales Politique de confidentialité 🍪
    Retour en haut de page