Gestion des images sous Laravel (dossiers virtuels)

Pour un bon référencement utiliser du texte dans l’url de l’image est bon :

/images/le best des produits/produits/tux.png

En fait il faut charger une images /images/produits/tux.png; notre 2eme dossier est la pour  google :)

avec un .htaccess par exemple on ne garde que les 2 id :

RewriteEngine on
RewriteRule ([0-9]+)/([0-9]+)-([^/]+)\.jpg /images/produits/$1/$2.jpg [L]
RewriteRule ([0-9]+)/([^/]+)-([0-9]+)\.jpg /images/produits/$1/$3.jpg [L]

Ici nous allons faire un package Images, donc /images/ sera aussi virtuel, notre package aura une route (dans config.php) sur public/images/ …. /tux.png

et si l’image n’existe pas nous retournons celle ci 404, elle est belle :), et écrirons dans le log l’erreur.

1) Créer le package

La, je ne revient pas trop dessus (voir autre article), un php artisan workbench monlogin/images , php artisan dump-autoload et ajouter  dans /app/config/app.php la ligne ’Monlogin\Images\ImagesServiceProvider’,   dans providers; c’est très très simple et rapide au bout de 10 fois :)

Dans ImagesServiceProvider.php :

public function boot()
{
	$this->package('monlogin/images');
	include __DIR__.'/../../routes.php';
	//include __DIR__.'/../../filters.php';
}

2) Ecrire notre route et contrôleur

Dans config/config.php mettre « images » pour la clé « url »  (voir autre article pour créer config.php).

<?php
  return array(
      'url' => 'images',
      'folder' =>storage_path().'/images/'
  );

Dans / j’ai créé un dossier /public/ et y ai collé mon image 404.png.

La route :
<?php // src/routes.php

// images/ texte sans importance / sous-dossier / image.jpg [/action]
Route::controller( \Config::get('images::config.url'), 'Papajoker\Images\Images' );

J’ai ajouté « /action » qui correspond a une taille ou tout autre…

Le contrôleur
<?php namespace Monlogin\Images;

class Images extends \Illuminate\Routing\Controllers\Controller
{

     /**
     * porte d'entrée du controleur
     */
    public function missingMethod($parameters)
    {
        $action='index';
        try
        {
            array_shift( $parameters ); // supp la phrase
            $last= last( $parameters );
            if (strpos($last, '.')===false){
                $action=$last;
                array_pop( $parameters );
            }
            $path=implode( '/', $parameters );
            $path=\Config::get( 'images::config.folder' ).$path;
        } catch (Exception $e) {
            $path='404';
        }
        return $this-&gt;$action( $path );
    }

    public function index($path)
    {
        if (!file_exists($path)){
            \Log::error('image non trouvée :'.$path);
            $path=__dir__.'/../../../public/404.png';
        }
        return $this-&gt;inline( $path,null,64000);
    }
    // url type images/.../tux.png/zoom
    private function zoom($path) {
        echo 'afficher img '.$path.' en grande taille';
    }

    // url type images/.../tux.jpg/exif
    private function exif($path)
    {
        if (file_exists($path)){
            try
            {
               $data=exif_read_data($path);
               $data['FileDateTime'] = date('Y/m/d',$data['FileDateTime']);
               echo 'infos sur:'.$path.'<code>'.print_r($data,true).'</code>';
            } catch (ErrorException $e) {
            echo 'fichier non supporté';
        }
    }
}

Ici, l’action est la phrase, donc l’entrée a ce contrôleur est la méthode ->missingMethod(). Elle transforme les paramètres en path+nom d’image et cherche une éventuelle action. Et pour finir lance l’action(index par défaut).

$f =\Conf::get(‘images::config.folder’) : va chercher les images dans le dossier mit dans config.php.

La méthode Images->inline va intégrer dans \Responce l’image passée en paramètre (celle demandée ou notre 404.png)

    private function inline($path, $name = null, $lifetime = 0)
    {
        if (is_null($name)) $name = basename($path);

        $filetime = filemtime($path);
        $etag = md5($filetime . $path);
        $time = gmdate('r', $filetime);
        $expires = gmdate('r', $filetime + $lifetime);
        $length = filesize($path);

        $headers = array(
            'Content-Disposition' => 'inline; filename="' . $name . '"',
            'Last-Modified' => $time,
            'Cache-Control' => 'must-revalidate',
            'Expires' => $expires,
            'Pragma' => 'public',
            'Etag' => $etag,
        );

        $headerTest1 = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $_SERVER['HTTP_IF_MODIFIED_SINCE'] == $time;
        $headerTest2 = isset($_SERVER['HTTP_IF_NONE_MATCH']) && str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == $etag;
        if ($headerTest1 || $headerTest2) { //image en cache
            return \Response::make('', 304, $headers);
        }

        $headers = array_merge($headers, array(
            'Content-Type' => mime_content_type($path),
            'Content-Length' => $length,
        ));

        return \Response::make(\File::get($path), 200, $headers);

    }
Tests – utilisation

Copiez une image (tux.png) dans /storage/images/  (ou-et /storage/images/produits)

/images/le best des produits/produits/tux.png
/images/le best des produits/tux.png/zoom
/images/le best de tout/produits/toto.jpg/exit
/images/super-produit/200/tux.png

 

Share Button

Vous devriez aimer...