Publié le

Minifier HTML de sortie avec Laravel

Les moteurs de recherche donnent des consignes de qualité afin d’améliorer le positionnement dans les SERP. Je vais vous donnez le code permettant de mettre en place un moyen tous simple pour aller dans ce sens et minifier le code HTML afin de réduire la taille de la page de façon simple et automatisée et donner un signal positif aux algorithmes des moteurs de recherche. Modification dans les fichier app\Http\Kernel.php

protected $middlewareGroups = [
        'web' => [
            //...
           'minifier' => \App\Http\Middleware\minifier::class,
        ],

Créer le fichier app\Http\Middleware\minifier.php avec le contenu suivant:

<?php

namespace App\Http\Middleware;

use Closure;

class minifier {
 
    public function handle($request, Closure $next)
    {
    
        $response = $next($request);
        $buffer = $response->getContent();
       
	$replace = array(
		'//s' => '',
		"/<\?php/"                  => '<?php ',
		"/\n([\S])/"                => '$1',
		"/\r/"                      => '',
		"/\n/"                      => '',
		"/\t/"                      => '',
		"/ +/"                      => ' ',
	);
	$buffer = preg_replace(array_keys($replace), array_values($replace), $buffer);
	$response->setContent($buffer);
 
        ini_set('zlib.output_compression', 'On'); // If you like to enable GZip, too!
        return $response;
    }
}

Attention: Une fois ce script en place, vous ne pouvez plus utiliser la forme // dans les commentaires. Il vous faut donc utiliser la forme /* mon commentaire … */

Publié le

Utiliser Ajax avec JQuery

Dans cet exemple, je vais vous donnez un exemple complet permettant de faire des appels Ajax depuis une fichier php. Vous devez dans ce cas modifier les fichiers routes/web.php, bien évidemment le fichier html et créer un contrôleur.

Ajouter la route dans routes/web.ph

Comme toujours, il faut ajouter la nouvelle route dans le fichier web afin que Laravel ne retourne pas une erreur 404.

Route::any('backend/users/loadInfo', ['as'=>'backend/users/loadInfo', 'uses'=>'Backend\UsersController@loadInfo'])->middleware('auth');

Route::post suffit mais j’ai mis Route::any afin de pouvoir faire des tests en allant sur la page http://www.crabcake.ch/blog/backend/users/loadInfo?iduser=1

Exemple de contenu du fichier html ou php

<span class='btn_info_user glyphicon glyphicon-info-sign' id='iduser_1' aria-hidden='true'>Username</span>
<div id='infouser_data_1'></div>   
                    
	  
<script type="text/javascript">

    jQuery( document ).ready(function( $ ) {

        jQuery( ".btn_info_user" ).click(function() { 

            var arr_val = $(this).attr('id').split("_");
            var iduser = arr_val[1];
			
            var posting = jQuery.post( "<?php  echo route('backend/users/loadInfo');?>", { '_token': '{ { csrf_token() } }',iduser: iduser } );
            posting.done(function( data ) {
                if(data.success) {
                    jQuery( "#infouser_data_"+iduser).html(data.div_content);
                } else {
                    alert(data.msg) 
                } 
            });   

            console.log(iduser);
        });

    });
</script>

Contenu du fichier php

class UsersController extends Controller
{

    public function loadInfo(Request $request){

        if(!isset($request->iduser) || !is_numeric($request->iduser)){
            $arr_response = array(
                'success' => false,
                'msg' => 'Error iduser missing',
            );
            return response()->json($arr_response);
        }
	$arr_response = array(
            'success' => true,
            'div_content' => "Contenu à retourner...",
        );
	return response()->json($arr_response);
		
}
Publié le

Mettre en place l’upload d’image simple / upload multiple de fichiers

La gestion de l’upload est simplifiée par Laravel. Nous allons voir dans l’exemple qui suit comment faire un formulaire de téléchargement d’image simple, multiple, comment utiliser la validation dans ces deux cas, et même ajouter une validation personalisé en fonction des dimensions des images. Pour créer un formulaire d’upload basic insérez le code qui suit:

Formulaire d’upload d’image simpl

Pour un téléchargement d’image simple mettez en place le code suivant dans votre fichier html.

{!! Form::open(array('url' => 'backend/account/edit_social','method'=>'POST', 'files'=>true)) !!} 
{!! Form::file('image_banner',null) !!} 
{!! Form::file('avatar_upload',array('accept'=>'image/*','class'=>'bgtans')) !!}
{!! Form::close() !!}

Pour mettre en place un filtre en fonction de l’extension, remplacez dans l’exemple null par array(‘accept’=>’image/jpeg’) il ajoutera la ligne suivante dans votre entrée l’input html  <input … accept= »image/jpeg » …/>

Pour mettre en place la route insérer par exemple la ligne suivante dans votre web.php

//Dans notre cas, il faut être connecté à cause de ->middleware('auth');
Route::post('backend/account/edit_social', ['uses'=>'Backend\AccountController@editsocial'])->middleware('auth');

Et pour finir, dans votre contrôleur (Backend\PicturesController.php dans l’exemple) mettez le code suivante:

namespace App\Http\Controllers\Backend;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use App\Http\Requests\FichePictures; 

use Validator; 
use Illuminate\Support\Facades\Redirect; 

class AccountController extends Controller
{ 
  public function editsocial(Request $request)
    { 

        if(null!==($request->file('avatar_upload'))){
            $this->validate($request, [
                'avatar_upload' => 'image|mimes:jpeg,jpg,png|max:4000',//Permet de limiter la taille et le type de fichier
            ]);

            $arr_original_img = pathinfo($request->file('avatar_upload')->getClientOriginalName());

            $path_img_folder = base_path()."/public_html/img/avatar";
            $new_img_folder_path =  base_path()."/public_html/img/avatar/";
            /*  On uniformise les extensions*/
            switch (strtolower($arr_original_img['extension'])){
                case 'jpg':
                case 'jpeg':
                    $new_filename =  Auth::user()->id.".jpg";
                    break;
                case 'png':
                    $new_filename =  Auth::user()->id.".png";
                    break;
            }

            $new_img_path =  $new_img_folder_path.$new_filename;

            $file_path_jpg =$path_img_folder."/".Auth::user()->id.".jpg";
            $file_path_png =$path_img_folder."/".Auth::user()->id.".png";
            /*  On supprime l'ancienne image si elle existe*/
            if(file_exists($file_path_jpg)){
                unlink($file_path_jpg); 
            } elseif(file_exists($file_path_png)){
                unlink($file_path_png);
            }
	    /* on déplace l'image et on change le nom*/
            $request->file('avatar_upload')->move($new_img_folder_path,$new_filename); //

            $path_parts = pathinfo($new_img_path);
	    /* Optimisation des images avec jpegoptim */ 
            if($path_parts['extension']=='jpg'){
                exec("exec jpegoptim -m80  -P --strip-all ".$new_img_path.";");
            }
        }
        return redirect('backend/account');
    }

Upload d’images – multiple

L’exemple suivant met en place un upload d’images et en plus de la validation pour un array d’images, met en place une autre validation en fonction de la taille des images. Pour mettre en place la route insérer par exemple la ligne suivante dans votre web.php

//Dans notre cas, il faut être connecté à cause de ->middleware('auth');
Route::post('multiple_upload', ['as'=>'multiple_upload','uses'=>'Backend\PicturesController@multiple_upload'])->middleware('auth');

Notre controller (Backend\PicturesController.php) contient le code suivant:

namespace App\Http\Controllers\Backend;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use App\Helpers\BackendHelper;
use App\Http\Requests\FichePictures;   //Permet de mettre en place la validateur personnalisé
use Validator;     
use Illuminate\Support\Facades\Redirect;                         

class PicturesController extends Controller
{              
   public function multiple_upload(FichePictures $request)//<------ Ma nouvelle classe!!!
   {
      foreach($request->file('images_file') as $image) {
         //...
      } 
      return back()->withInput();
   }
}

Et dans cet exemple nous devons créer le fichier suivant : app\ Http\ Requests\ FichePictures.php Soit vous créer directement le fichier, soit vous exécutez la ligne suivant:

php artisan make:request FichePictures

Au final, votre fichier devra contenir les lignes suivantes

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;    
use Illuminate\Http\Request; 
use Validator;


define("IMG_SIZE_MIN", 600);//taille minimu de l'image
 
class FichePictures extends FormRequest
{
    public function authorize()//Permet de restreindre l'accès
    {
      return true;
    }
    protected function getValidatorInstance()
    {
      return parent::getValidatorInstance()->after(function ($validator) {
         $this->after($validator);
      });
    }
    public function rules()
    {
      $arr_images =  Request::file('images_file');
      
      $nbr = count($arr_images) - 1;
      
      foreach(range(0, $nbr) as $index) {
         $rules['images_file.' . $index] = 'image|mimes:jpeg,jpg|max:4000';
      }  
          
      return $rules;        
    } 
    public function after($validator)
    {

      $arr_images =  Request::file('images_file');
      foreach($arr_images as $image) {
            echo $image->getClientOriginalName()."
";
            list($width, $height) = getimagesize($image);
            echo "--->".$width." x ".$height."
";
           if ($widthsetLocale('fr');
               $validator->errors()->add('images.0', $image->getClientOriginalName()" ".trans('customlang.img to small'));
           }
      }
    }
}

Voilà, le temps m’a manqué pour détailler toutes les informations nécessaires, mais vous avez au moins un exemple de code complet et fonctionnel.

Publié le

Utilisations des Accessors & Mutators / Setters & guetter

Laravel propose une système d’accesseurs et de mutateurs très efficace et simplissime à utiliser. Ce petit exemple vous montre leurs utilisation dans un modèle. Les accesseurs et mutateurs que l’on appèle aussi setters et guetters permettent, si vous ne le savez pas de modifier le comportement normal de la lecture ou de l’écriture d’un attribute. Dans le cas ci-dessous, il contrôle si la valeur à stocker est corente et retounre la valeur texte d’un enregistrement numérique de ma table. Leur très grand avantage est qu’il ne peuvent pas être contournés.

public function getNomAttributAttribute(){ 
// appelé par exemple : $categories->genre = 12;
}
public function setNomAttributAttribute($to_set){
// echo $categories->genre = 1;

Ci dessous vous avez un exemple complet:

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model;

class Categories extends Model
{
    use Notifiable; 
 
    protected $table = 'categories';
    public $timestamps = false; //champ created_at updated_at 
    public $attributs_range;
 
    protected $fillable = [ //champs que l'on peut modifier
       'idfiche','url'
    ];
 
    public function __construct()
    {
       $this->attributs_range['genre'] =array(1,2,3,4);
    }
    public function setGenreAttribute($to_set){
       if(!in_array($to_set,$this->attributs_range['genre'])){
          $to_set = null;
       }
       $this->attributes['genre'] = $to_set;
    } 
    public function getGenreAttribute(){
       switch($this->attributes['genre']){
          case '1':
             return "Videos";
          break;
          //...
       }
    } 
}

Pour l’utilisation dans un contrôleur par exemple:

$categories->genre = 12; //null sera enregistré dans la bse de donnée
echo $categories->genre = 1; //va afficher Videos
Publié le

Routage sous Laraval 5

Je vais ici donner des explications pour le routage sous Laravel, montrer comment générer des URL avec ou sans paramètre en fonction du fichier web.php. Je vais également vous donner une solution pour mettre en place un routage dynamique en fonction d’une table présente dans ma base de données. Cette solution sort d’un cas concret. Le site en question est un site de petites annonces et le routage multi langue doit afficher soit une catégorie soit une annonce en fonction de l’url. Pour cela, j’ai besoin d’une table que j’ai appelé core_url_rewrite en clin d’œil à Magento, d’un controller et de vues que je vous laisse le soin de faire vous-même.

Routage de base

Exemple de génération d’url sans paramètre.

// #### Dans routes\web.php
Route::get('mon_ex_1', ['as'=>'ex1','uses'=>'Frontend\ExempleController@index']);
// #### Appel dans fichier php
echo route('ex1'); 
// => http://www.crabcake.ch/blog/mon_ex_1
// #### Dans appel dans template blade
{{ url('mon_ex_1') }} 
//ou
{{ URL::route('ex1') }}
// => http://www.crabcake.ch/blog/mon_ex_1

Exemple de génération d’url avec paramètre

// #### Dans routes\web.php
Route::get('{lang}/mon_ex_2', ['as'=>'ex2','uses'=>'Frontend\ExempleController@index']);
// #### Appel dans fichier php
$url2 = route('ex2',['lang'=>'fr']);
// => http://www.crabcake.ch/blog/fr/mon_ex_2

Exemple de génération d’url avec paramètre et avec paramètre optionnel

// #### Dans routes\web.php
Route::get('{lang}/mon_ex_2', ['as'=>'ex2','uses'=>'Frontend\ExempleController@index']);
// ou
Route::get('{lang}/mon_ex_2/{id?}', ['as'=>'ex2','uses'=>'Frontend\ExempleController@index']); 
// #### Appel dans fichier php
echo route('ex2',['lang'=>'fr']);
// => http://www.crabcake.ch/blog/fr/mon_ex_3
echo route('ex3',['lang'=>'fr','id'=>22]);
// => http://www.crabcake.ch/blog/fr/mon_ex_3/22

Routage depuis une base de données

La table est toute simple. Je vous donne ici le fichier de migration. Je vous laisse le soin de la peupler correctement selon vos besoins, mais j’en profite pour montrer comment insérer des données ou peupler une table dans le fichier de migration laravel.

<?php 
use Illuminate\Support\Facades\Schema; 
use Illuminate\Database\Schema\Blueprint; 
use Illuminate\Database\Migrations\Migration; 

class CoreUrlRewrite extends Migration { public function up() { Schema::create('core_url_rewrite', function (Blueprint $table) { $table->increments('id');
            
            $table->string('lang');
            $table->string('request_path')->default('');
            $table->string('id_categorie')->default('');   
            $table->string('id_file')->default('');          
        });
        // Insert some stuff
        DB::table('core_url_rewrite')->insert(
            array(        
                'lang' => 'fr',
                'request_path' => 'suisse',
                'id_categorie' => '2',
                'id_file' => ''
            ) );
        DB::table('core_url_rewrite')->insert( array(        
                'lang' => 'fr',
                'request_path' => 'studio-lumineux',
                'id_categorie' => '',
                'id_file' => '3'
            )
        );
    }

    public function down()
    {
        Schema::drop('core_url_rewrite');
    }
}

Le contrôleur que j’ai appelé DynamicController qui se trouve bien sur sous app\ Controllers\ DynamicController.php

<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Notifications\Notifiable; use Illuminate\Support\Facades\DB; class DynamicController extends Controller { public function manage($lang,$url) { $categories = DB::table('core_url_rewrite')->where('lang', '=', $lang)->where('request_path', '=', $url)->get();

        if($categories->count()==0){
           echo "No route in url_rewrite";
            exit();
        }
        $categorie = $categories->first();
       
       if($categorie->id_categorie){
            $cat = \App\Categorie::find($categorie->id_categorie);
            dd($cat);
            $modelCat = new \App\MyClasses\Categorie($lang,$cat);
            return view('frontend.categories',array('categorie'=>$modelCat));
       } elseif($categorie->id_file){
           
            $annnonce = \App\File::find($categorie->id_categorie);
            dd($annnonce);
            return view('frontend.categories',array('categorie'=>$cat));
       }
    }
}

Il faut bien évidemment également modifier le fichier web.php Pour ne pas perdre les autres routeurs, il faut ajouter notre nouvelle route tout à la fin du fichier.

Route::get('{slug1}/{slug2}', 'DynamicController@manage')
->where('slug1', implode('|', array_flip(config('app.languages'))))
->where('slug2', '([A-Za-z0-9-_]+)');

Nous prenons soins dans ce routage de contrôler si la langue correspond à une des langues présentes dans notre fichier de config (->where(‘slug1’, implode(‘|’, array_flip(config(‘app.languages’))) ) et si la page a une URL plausible ( ->where(‘slug2’, ‘([A-Za-z0-9-_]+)’) ). Voilà, vous avez maintenant mis en place un système de routage en fonction de la base de données. Pour tester votre page naviguez par exemple à l’url http://www.votre-site.com/fr/suisse

Publié le

Internationalisation sous Laravel 5

Il est relativement facile de créer un site multilingue sous Laravel 5.4. La solution que je vous propose en terme d’internationalisation n’est pas la seule, mais elle conviendra à la plupart. Pour mettre en place la localization, il est comme vous allez le voir pas nécessaire de modifier beaucoup de fichiers. Notre but est de gérer les choix, faire un choix de langue par défaut et afficher la possibilité de choisir la langue.

Nous commençons par définir la langue par défaut et les langues disponibles dans le fichier config.app. Nous définissons ici que la langue par défaut est le français.

'locale' => 'fr',
    'languages' => [
    'fr' => 'Français',
    'de' => 'Deutsch',
    'en' => 'English'
    ],  

    'fallback_locale' => 'fr',

Lorsque l’on modifie le fichier config/app.php, il faut exécuter la commande suivante pour que les système prenne en compte les changement:
php artisan cache:clear

Nous créons ensuite un Middleware qui permettra de toujours avoir une langue définie. Nous créons donc le fichier app\Http\Middleware\Language.php

<?php


namespace App\Http\Middleware;

use Closure;
use Illuminate\Foundation\Application;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Session;

class Language
{
    public function handle($request, Closure $next)
    {     
        $segment_1 = $request->segment(1);

        $arr_languages = config('app.languages');
        //la page d'accueil sans choix de langue
        if(is_null($segment_1) && is_null(Session::get('applocale')) ){
            //Comme aucune langue n'est definie on prend celle par défault
            $fallback_locale = config('app.fallback_locale');
            Session::put('applocale', $fallback_locale);   
            Session::put('lang_name', $arr_languages[$fallback_locale]);
        }
        //Le segment correspond a une des langues que l'on a                    
        if(isset($arr_languages[$segment_1])){
            //Si la langue de l'url n'est pas celle de la session, on la change
            if($segment_1 !=Session::get('applocale')){
                Session::put('applocale', $segment_1);   
                Session::put('lang_name', $arr_languages[$segment_1]); 
            } 
        }   
        //si c'est la home, on redirige avec la langue a la fin
        if(is_null($segment_1)){
              return redirect(url('/')."/".Session::get('applocale')."/"); 
        }
        //On set la langue pour les fichier de trad
        App::setLocale(Session::get('applocale'));
        
        return $next($request);
    }
}

Nous modifions ensuite le fichier app\Http\Kernel.php pour ajouter notre middleware à la fin:

protected $middlewareGroups = [
	'web' => [
		...
		\App\Http\Middleware\Language::class,
	],
];

Nous créons la route qui gère les langues de la page d’accueil dans le fichier routes/web.php

Route::get('/{lang?}', function () {
    return view('welcome');
})->where('lang', implode('|', array_flip(config('app.languages'))));

Nous créons ensuite la zone qui permet à l’utilisateur de changer la langue en modifiant le fichier welcome.

@if (Route::has('login'))
<div class="top-right links">
<a href="{ { url('/login') } }">Login</a>
<a href="{ { url('/register') } }">Register</a> 
 
 @foreach ( config('app.languages') as $local_code => $local_string)
 @if($local_string !== config('app.lang_name'))
<?php
 $style = 'padding:0';
 if ($local_code == session('applocale')){
 $style = 'padding:0;border-bottom:2px solid red;';
 }
 ?>
<a style='<?php echo $style;?>' href="{!! url('/') !!}/{ { $local_code } }/"><img width="32" height="22" alt="{ { $local_string } }" title="{ { $local_string } }" src="{!! asset('img/' . $local_code . '-flag.png') !!}"></a>
 @endif
 @endforeach

Et finalement nous créons nos fichiers de langue dans le répertoire resources/ lang. Dans mon cas je vais créer de/customlang.php,fr/customlang.php, en/customlang.php, … qui contiendront le tableau de mes traductions sous la forme suivant:

 return [
 'test' => 'Es klappt',
];

Pour afficher mes traduction il me suffira d’écrire les ligne suivantes (nom_du_fichier.indice_du_tableau):

{{ trans('customlang.test') }} //avec blade
@lang('customlang.test')  //avec blade

Il faudra maintenant tenir compte de la langue dans le fichier de routage. Vous pouvez le faire de la façon suivante:

Route::get('{lang}/contact', 'Frontend\ContactController@index');

Comme nous utilisons les sessions Laravel, il est utile de savoir que vous pouvez supprimer toutes les sessions en supprimant tous les fichiers présent dans storage/framework/sessions/

Publié le

Fonction globales et helpers

Il y a de nombreuses solutions pour créer des helpers sous Laravel. Je vous propose donc une solution qui me convient. La première étape consiste à créer un fichier dans un nouveau dossier sous app/ Helpers/ BackendHelper.php. Dans mon exemple que vais écrire une fonction qui me génère une string en minuscule propre en enlevant les caractères accentués les plus probables pour moi. Je pourrai ensuite l’utiliser pour générer des urls.

namespace App\Helpers;

class BackendHelper
{
 public static function convertToUrl(string $string)
 {
    $unwanted_array = array( 'Š'=>'S', 'š'=>'s', 'Ž'=>'Z', 'ž'=>'z', 'À'=>'A', 
      'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 
      'É'=>'E','Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 
      'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U','Ú'=>'U', 
      'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss', 'à'=>'a', 'á'=>'a', 'â'=>'a', 
      'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c','è'=>'e', 'é'=>'e', 'ê'=>'e', 
      'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 
      'ó'=>'o', 'ô'=>'o', 'õ'=>'o','ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 
      'ý'=>'y', 'þ'=>'b', 'ÿ'=>'y','G'=>'G', 'I'=>'I', 'S'=>'S', 'g'=>'g', 'i'=>'i', 
      's'=>'s', 'ü'=>'u','a'=>'a', 'A'=>'A', '?'=>'s', '?'=>'S', '?'=>'t', '?'=>'T' );
    
   $string = strtr( $string, $unwanted_array );
    return htmlentities(strtolower($string));
 }
}

J’ajoute ensuite un alias dans le fichier config/app.php

...
'aliases' => [
    ...
    'BackendHelper' => App\Helpers\BackendHelper::class,
 ],

Maintenant que tout est en place, pour l’utiliser dans une vue avec blade ou en php j’utilise les lignes de commande suivante:

{!! BackendHelper::convertToUrl('Catégorie Électro-ménager') !!}

Une fois cela fais, il faut recharger les fichiers dans le cache a l’aide de la fonction suivante:

composer dump-autoload

Pour l’utiliser dans un contrôleur

use App\Helpers\BackendHelper;
...
public function newCat(Request $request){
   ...
   $new_cat->url_fr  = BackendHelper::convertToUrl($request->input('url_fr'));
   ...
}

Charger automatiquement des classes – AutoLoad

Si vous désirez que votre classe soit accessible depuis partour, voua avez aussi comme solution de l’ajouter à l’Autoload de Laravel. Pour ce faire il faut modifier le fichier composer.json présent à la racine de votre dossier et le modifier de la façon suivante:

"autoload": {
   "classmap": [
      "database"
   ],
   "files": [
      "app/Helpers/lessc.inc.php", //#### Classe à inclure
      "app/Helpers/geshi/geshi.php" //#### Classe à inclure
   ],

Maintenant si vous ne voulez pas avoir l’erreur Class not found vous devez exécuter la commande suivante: composer dump-autoload

Publié le

Pagination dans une collection

Nous allons ajouter très facilement une pagination à nos collection. Laravel met à disposition des outils extrêmement simple d’utilisations. Dans notre cas, la liste des categories dispose d’une pagination tous les 5 enregistrements. Elle est mise en place dans notre contrôleur CategoriesController.php avec la ligne suivante

public function listAll(){
  $categorie = \App\Categorie::paginate(5);
  return view('backend.categories.list',array('categories'=>$categorie));
}

il serait bien sur également possible d’accéder aux enregistrements de la façon suivante:

public function listAll(){
  $categorie = DB::table('ategorie')->paginate(5) ; /*  Requiert use Illuminate\Support\Facades\DB;*/
  return view('backend.categories.list',array('categories'=>$categorie));
}

et dans la vue list.blade.php avec la ligne suivante:

{!! $categories->links(); !!}

Passer paramètres supplémentaire au système de pagination

Il est souvent très utile de passer des paramètres supplémentaire au système de pagination. Ils permettent par exemple de paginer des résultats triés. L’exemple ci-dessous vous montre comment faire.

public function listAll(){
/*{!! $categories->links(); !!}*/ 
/* On ajoute des paramètre a la pagination en utilisant ->appends(*/
  echo $terms->appends(array('sort' => $sort))->links();
Publié le

Création simplifié de formulaires, affichage de listes, validation de formulaire

Laravel permet de créer assez simplement des formulaire sécurisé avec des options. Si vous désirez utiliser cette option, il faut depuis Laravel 5.4 installer un package de la façon suivante. (Vous trouvez une information complète sur le site de doc Laravel.

composer require "laravelcollective/html":"^5.3.0"

et aller modifier ensuite le fichier config/app.php en ajoutant les 3 lignes suivante:

'providers' => [
    //....
    Collective\Html\HtmlServiceProvider::class,
 ],
 'aliases' => [
    //....
    'Form' => Collective\Html\FormFacade::class,
    'Html' => Collective\Html\HtmlFacade::class,
 ],

Création des pages du backend, des contrôleurs et modification du routage

Affichage de liste dans le backend

Nous allons maintenant créer les pages permettant de modifier, créer et supprimer nos catégories depuis la partie backend de notre site. Je vais vous donner tout le code et expliquer ensuite ce qui se passe.

Routage avec contrôle de paramètres et de connexion

J’ai ajouté les nouvelles routes suivantes à mon fichier routes/ web.php afin de pouvoir éditer, lister, créer et supprimer des catégories.

A noter 3 choses:
Les Route::get et Routes::any : any me permet de récupérer les valeurs de mes formulaires en POST.
Le ->where(‘id’, ‘[0-9]+’) : Qui permet de mettre une expression régulière qui contrôle que l’id est bien transmis et est numérique.
Le ->middleware(‘auth’); : Qui permet de restreindre l’accès aux utilisateurs connectés

Contrôleurs du backend et options de validations

Vous voyez ici le code source complet de mon controller Http/ Controllers/ Backend/ CategoriesController.php. J’ai décidé de faire un seul contrôleur pour toute la gestion des catégories. Ce n’est pas forcément idéal mais ca permet des fois d’aller plus vite ou d’être plus lisbible.

namespace App\Http\Controllers\Backend;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
//use Illuminate\Support\Facades\DB; nécessaire pour l'utilisation de DB::table

class CategoriesController extends Controller
{
   public function listAll(){
     $categorie = \App\Categorie::paginate(5);
     return view('backend.categories.list',array('categories'=>$categorie));
   }
   public function newCat(Request $request){
 
   if(!is_null($request->input('name'))){
     $this->validate($request, [
       'name' => "required|max:255|min:4|unique:categories",//validateur contrôle le nom
     ]);
     $new_cat = new \App\Categorie; 
     $new_cat->name = trim($request->input('name'));
     $new_cat->save();
     return $this->listAll()->withSuccessMsg('Catégorie '.$new_cat->name.' créee avec succès');
   }
   return view('backend.categories.new');
 }
 
 public function delete($id){
   $categorie = \App\Categorie::find($id);
   if(!is_null($categorie)){ //la catégorie n'a pu être trouvé, on retourne sur l'accueil
     $categorie->delete();
     return $this->listAll()->withSuccessMsg(sprintf('suppression %s effectuées',$categorie->name));
   }
   return $this->listAll();
 }
 public function edit($id,Request $request){

   $categorie = \App\Categorie::find($id);
   if(is_null($categorie)){ //la catégorie n'a pu être trouvé, on retourne sur l'accueil
     return redirect('home');
   }
   if(!is_null($request->input('name'))){
 
       $this->validate($request, [
       'name' => "required|max:255|min:4|unique:categories,name,".$id,//validateor controle le nom sauf pour cet id
     ]);
 
     $name = trim($request->input('name'));
     /* 
     $check = \App\Categorie::where('name', $name)->where('id','!=',$id)->get()->count();
     $check = DB::('categories')->where('name', '=', $name)->where('id', '!=', $id)->get()->count();
     if($check!=0){
       $categorie->name = $name;
       return view('backend.categories.edit',array('categorie'=>$categorie))->withErrorMsg(sprintf('Le nom %s est déjà utilisé',$name)); 
     } 
     */ 
     $categorie->name = $name;
     $categorie->save();
     return view('backend.categories.edit',array('categorie'=>$categorie))->withSuccessMsg('Modifications effectuées');
   }
   return view('backend.categories.edit',array('categorie'=>$categorie));
 }
}

Charger un modèle

Vous avez un exemple de chargement de modèle de 3 manières différentes. Nous utilisons find() afin de charger selon l’id ou avec la clause where() qui permet d’effectuer une recherche sur n’importes quels champs.

//retourne un objet de mon modèle Categorie ou null s'il n'en trouve pas 
$categorie = \App\Categorie::find($id);
//retourne le nombre d'élément du même nom et avec un id différent
$check = \App\Categorie::where('name', $name)->where('id','!=',$id)->get()->count();
//Même chose de la ligne précédente mais d'une autre manière
//pour cette solution il faut ajouter [use Illuminate\Support\Facades\DB;] en haut de votre controller
$check = DB::('categories')->where('name', '=', $name)->where('id', '!=', $id)->get()->count();

Validation des champs de formulaire

Laravel fourni de nombreux outils permettant de contrôler la validation des champs de formulaire. Vous avez-ici un exemple d’utilisation.

//validateur qui contrôle que le champs est setté, qu'il est de la bonne 
//taille et qu'il est unique
$this->validate($request, [
 'name' => "required|max:255|min:4|unique:categories",
]);
//validateur qui contrôle en plus que le nom est unique sauf pour lui-même
$this->validate($request, [
 'name' => "required|max:255|min:4|unique:categories,name,".$id,
]);
//////les erreurs de validation sont affichés par notre fichier app.blade.php
//@if (count($errors) > 0)
// @foreach ($errors->all() as $error)
// {{ $error }}
// @endforeach
//@endif

Formulaires dans les vues

L’exemple ci-dessous affiche le formulaire de modification. Comme @extends(‘home’) le signale, il va utiliser le template et ajouter dans sa section content le code contenu entre section(‘content’) et endsection. Ce code contient la création simplifié de formulaire et d’ajout de champs et bouton

Ajouter une valeur par défaut à un champ de formulaire:
Form::text(‘input name’,’valeur par defaut’,$fiche->npa,array(‘class’ => ‘small_input’) );

{ { Form::open(array('url' => 'backend/categories/edit/'.$categorie->id)) } }
 <table style='width:100%'>
 <tr>
 <td>ID</td>
 <td>{ { $categorie->id } }</td>
 </tr>
 <tr>
 <td>Categorie</td>
 <td><?php echo Form::text('name',$categorie->name );?></td>
 </tr>
 <tr>
 <td></td>
 <td> <?php echo Form::submit('Save');?></td>
 </tr>
 </table> 
 { { Form::close() } } 
@endsection</pre>
 <td></td>
 <td> <?php echo Form::submit('Save');?></td>
 </tr>
 </table> 

@endsection

Publié le

Authentification Laravel et personnalisation du template blade

Nous allons maintenant mettre en place le système d’authentification de Laravel et utiliser le template blade pour afficher les pages plus élégamment. Pour activer l’authentification, il suffit d’exécuter la ligne suivant en mode console.

php artisan make:auth

Elle aura pour effet d’ajouter ces 2 lignes dans votre fichier routes/web.php et les champs login et register sur la home.

Auth::routes();
Route::get('/home', 'HomeController@index');/

Vous pouvez donc maintenant créer un compte et vous connecter.

Bloquer l’accès aux personnes non connectées

Comme vous le verrez plus tard, vous avez plusieurs solutions pour bloquer l’accès à certaines pages aux personnes qui ne se sont pas connectées et les rediriger vers la page de connexion. Je vous donne ici 3 possibilités avant de mettre à disposition du code qui utilise ces fonctions. La première solution se met en place dans les routes et la seconde dans le controllers. 2 solutions de mise en place dans le routes\web.php

//Ajouter ->middleware('auth'); à la fin de la ligne
Route::get('/backend/categories', 'Backend\CategoriesController@index')->middleware('auth');

//... autre manière ... en si signalant avec middleware
Route::any('backend/categories/new/', 
[
 'middleware' => 'auth',
 'uses'=>'Backend\CategoriesController@newCat',
]);

Mise en place dans le controller

 public function __construct()
 {
    $this->middleware('auth');//limite l'accès aux personne connectées
 }

Personnaliser le template Blade – L’espace membre

Espace membre de base

Je vais maintenant ajouter un menu à gauche de mon espace membre et afficher des liens qui pointerons sur mes futures pages d’administration.

Routage et principe d’affichage pour le tamplate Blade

Parmi les modification que j’ai effectuée sur le fichier resources/ views/ layouts/ app.blade.php, j’ai personnalisé une zone si l’utilisateur est connecté ou non qui affichera mon menu personnalisé. J’ai également créer une zone qui affichera les différents messages d’erreur ou d’information.

@if (Auth::guest())
   @yield('content')
@else
@endif
//...
//...
//...
 
 @if (!empty($success_msg))// Un utilisant une session bootsrap
{{ $success_msg }}
 @endif 
 @if (!empty($info_msg))// Un utilisant une session bootsrap
{{ $info_msg }
 @endif 
 @if (!empty($error_msg))// Un utilisant une session bootstrap
{{ $error_msg }}
 @endif 
 @if (count($errors) > 0)//Afficher les message d'erreur levé par laravel
         @foreach ($errors->all() as $error)  
{{ $error }}
         @endforeach
 @endif