Beta J-550 !
exemple carousel

Ajouter une fonction "carousel" à votre cms/blog - partie 1

Par Julie, le 01/03/2017

Nous allons voir dans cette suite comment mettre à place un "carousel" Bootstrap ou plutôt, comment donner à l'administrateur la possibilité d'en créer un, de l'éditer, etc.

 

Etape 1 : les entités :  

Afin de proposer ce genre d'option dans le Blog sur lequel vous êtes, il m'a fallu créer 2 entities.

 - Dans un premier temps nous allons créer la première entité :  Carousel.php, elle aura biensur un ID, un nom, des images que j'appelerais(galleries), et un champ published.

<?php

namespace CMS\BlogBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * Carousel
 *
 * @ORM\Table(name="carousel")
 * @ORM\Entity(repositoryClass="CMS\BlogBundle\Repository\CarouselRepository")
 */
class Carousel
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="nom", type="string", length=255)
     */
    private $nom;

    /**
     * @ORM\OneToMany(targetEntity="CMS\BlogBundle\Entity\Gallery", mappedBy="carousel")
     */
    private $galleries;

    /**
     * @ORM\Column(name="published", type="boolean")
     */
    private $published;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->galleries = new ArrayCollection();
    }

Je ne fais pas apparaître ici les Getters et Setters, il suffit de les générer en console.

Dans cette entité, la seule "subtilité", c'est la relation OneToMany qui concerne la variable $galleries, en effet un Carousel peut avoir 1 ou plusieurs gallerie. Avec mappedBy="carousel", on indique une relation bidirectionnelle. Il faudra indiquer à notre autre entité "Gallery" l'inverse, nous le verrons plus bas. Cela aura pour résultat de créer une clé étrangère "carousel_id" dans la table Gallery.

Il est également nécessaire de déclarer dans le "_construct", nos galleries en tableaux, pour ce faire : "new ArrayCollection()". Cela initialisera nos galleries en Objet.

 

- Dans un second temps :  l'entité Gallery, qui est plutôt intéressante car on va y voir comment uploader des images sur le serveur en utilisant la mémoire tampon. Je vais publier celle-ci en entier car elle est un peu plus complexe : 

<?php

namespace CMS\BlogBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;

/**
 * Gallery
 *
 * @ORM\Table(name="gallery")
 * @ORM\Entity(repositoryClass="CMS\BlogBundle\Repository\GalleryRepository")
 * @ORM\HasLifecycleCallbacks
 */
class Gallery
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="url", type="string", length=255)
     */
    private $url;

    /**
     * @var string
     *
     * @ORM\Column(name="alt", type="string", length=255)
     */
    private $alt;

    /**
     * @ORM\ManyToOne(targetEntity="CMS\BlogBundle\Entity\Carousel", inversedBy="galleries")
     * @ORM\JoinColumn(nullable=false)
     */
    private $carousel;

    /**
     * @var string
     * @ORM\Column(name="description", type="string", length=255, nullable=true)
     */
    private $description;

    /**
     * @var UploadedFile
     */
    private $file;

    // on ajoute une mémoire tampon
    private $tempFilename;

    /**
     * @param UploadedFile $file
     */
    public function setFile(UploadedFile $file)
    {
        $this->file = $file;

        // Vérification si on a déjà un fichier pour cette entité
        if ($this->url !== null) {
            $this->tempFilename = $this->url;

            // Réinitialisation des ttribut url et alt
            $this->url = null;
            $this->alt = null;
        }
    }

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function preUpload()
    {

        // si il n'y a pas de fichier on fait rien
        if ($this->file === null) {
            return;
        }

        // le nom du fichier est son id, on doit juste stocker son extensino
        $this->url = $this->file->guessExtension();

        // on attriut a alt, la valeur du nom de fichier sur le pc de l'util
        $this->alt = $this->file->getClientOriginalName();
    }

    /**
     * Début fonction upload
     * @ORM\PostPersist()
     * @ORM\PostUpdate()
     */
    public function upload()
    {

        // si pas de fichier on ne fait rien
        if (null === $this->file) {
            return;
        }

        // Si on a un ancien fichier on le supprime
        if ($this->tempFilename !== null) {
            $oldFile = $this->getUploadRootDir() . '/' . $this->id . '.' . $this->tempFilename;
            if (file_exists($oldFile)) {
                unlink($oldFile);
            }
        }

        // On déplace le fichier envoyé dans le répertoire de notre choxi
        $this->file->move(
            $this->getUploadRootDir(),
            $this->id . '.' . $this->url
        );
    }

    /**
     * @ORM\PreRemove()
     */
    public function preRemoveUpload()
    {
        // On sauvegarde temporairement le nom du fichier, car il dépend de l'id
        $this->tempFilename = $this->getUploadRootDir() . '/' . $this->id . '.' . $this->url;
    }

    /**
     * @ORM\PostRemove()
     */
    public function removeUpload()
    {
        // En PostRemove, on n'a pas accès à l'id, on utilise notre nom sauvegardé
        if (file_exists($this->tempFilename)) {
            // On supprime le fichier
            unlink($this->tempFilename);
        }
    }

    /**
     * Retourne le chemin relatif
     */
    public function getUploadDir()
    {
        return 'uploads/gallery';
    }

    /**
     * Retourne le chemin relatif vers l'image pour notre code php
     */
    public function getUploadRootDir()
    {
        return __DIR__ . '/../../../../web/' . $this->getUploadDir();
    }


    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return UploadedFile
     */
    public function getFile()
    {
        return $this->file;
    }

    /**
     * Set url
     *
     * @param string $url
     *
     * @return Gallery
     */
    public function setUrl($url)
    {
        $this->url = $url;

        return $this;
    }

    /**
     * Get url
     *
     * @return string
     */
    public function getUrl()
    {
        return $this->url;
    }

    /**
     * Set alt
     *
     * @param string $alt
     *
     * @return Gallery
     */
    public function setAlt($alt)
    {
        $this->alt = $alt;

        return $this;
    }

    /**
     * Get alt
     *
     * @return string
     */
    public function getAlt()
    {
        return $this->alt;
    }

    /**
     * Set carousel
     *
     * @param \CMS\BlogBundle\Entity\Carousel $carousel
     *
     * @return Gallery
     */
    public function setCarousel(\CMS\BlogBundle\Entity\Carousel $carousel)
    {
        $this->carousel = $carousel;

        return $this;
    }

    /**
     * Get carousel
     *
     * @return \CMS\BlogBundle\Entity\Carousel
     */
    public function getCarousel()
    {
        return $this->carousel;
    }

    /**
     * Set description
     *
     * @param string $description
     *
     * @return Gallery
     */
    public function setDescription($description)
    {
        $this->description = $description;

        return $this;
    }

    /**
     * Get description
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }
}

Détaillons un peu cette entité.

 - @ORM\HasLifecycleCallbacks : on va pouvoir grâce à cette annotations préciser à Doctrine à quel moment effectuer telle ou telle opération. Par exemple avant ou après le "Persist" d'une entité.

 - On retrouve ici notre variable "carousel" , que l'on va donc déclarer en ManyToOne avec un "inversedBy" pour correspondre avec la relation créée dans l'entité "Carousel".

 - Tout le reste de l'entité concerne l'upload de Fichier, le code est assez clair et simple à comprendre, prenez le temps de lire et vous comprendrez comment il fonctionne. Dans cet exemple,  les images iront donc se stocker dans le répértoire web/uploads/gallery.

Si vous avez des questions, n'hésitez pas! Dans les prochaines parties nous verrons les controller, les vues et formulaires.

 

Cet article est paru dans les catégories suivantes: Tutos Divers