Publié le

Formulaire dans une page AMP

Après avoir réaliser un article sur la mise en page de pages amp, je, je vais vous montrer dans cet exemple comment mettre en place un formulaire amp-form dans vos pages. Je donne ici un exemple complet afin de gérer l’affichage et le traitement des données.
Si vous avez un des messages d’erreur ci-dessous, vous trouverez toutes les informations nécessaires pour résoudre vos problèmes.

POST ERROR STATUS 500
The tag ‘amp-form extension .js script’ is missing or incorrect, but required by ‘FORM [method=POST]’
Response must contain the AMP-Access-Control-Allow-Source-Origin header
Form submission failed: Error: Response must contain the AMP-Access-Control-Allow-Source-Origin header??? _reported_

action-xhr requiert un site un https. Vous ne pourrez donc pas mettre en place se formulaire si votre site est en HTTP

Votre route dans le fichier web.php

Route::any('frontend/sendCommentsAmp', ['as'=>'frontend/sendCommentsAmp','uses'=>'Frontend\Posts\CommentsController@sendCommentsAmp']);

Partie html / page amp

Voilà un exemple de code html pour afficher un formulaire. Si vous utiliser Laravel n’oubliez pas le token avec {{ csrf_field() }} sinon vous aurez des erreurs

/*  A include dans le section head*/
<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.1.js"></script>
/*  fin de l'inclusion dans head */

<form id='form_review' class='clearboth form_review' method="POST" 
	action-xhr='<?php echo route('frontend/sendCommentsAmp');?>'
	target="_top">
	{{ csrf_field() }} /*  Sinon vous aurez une erreur*/ 
	<input type="hidden" name="idpost" value="22">
	<input type="text" name="name" id="name" value="" required>  
	<label for="txt_comment">Commentaire</label>
	<textarea name='txt_comment' id='txt_comment' rows="6" required> </textarea>                           
	<div submit-success>
		<template type="amp-mustache">
			@{{reponse}} /*  le @ permet d'échapper les { afin de ne pas avoir d'erreur avec blade*/ 
		</template>
	</div>
	<input class="btn btn-primary" type="submit" id='send_comment' value="Send"/>
</form>

Controller

Dans le controller, vous devez retourner les bon header sous peine d’avoir des erreurs.

class CommentsController extends Controller
{
    public function sendCommentsAmp(Request $request)
    {    
        $error_data=false;
        if(is_null($request->idpost) || !is_numeric($request->idpost) || is_null($request->txt_comment)
        || is_null($request->name)  ) {
            $error_data = true;
        }  
        if(!$error_data){
            $check_post = DB::table('mes_posts')->where('id',$request->idpost)->limit(1)->get();  
            if($check_post->count()==0){
                $error_data = true;
            }
        }
        if($error_data){
            $output = ['reponse' => 'Error'];
        }  else {
            /* On fait le traitement voulu*/
            $output = [ 'reponse' => 'Merci votre commentaire est en cours de validation.'];
        }
        header("Access-Control-Allow-Origin: https://cdn.ampproject.org");
        header("AMP-Access-Control-Allow-Source-Origin: https://".$_SERVER["SERVER_NAME"]);
        header("Access-Control-Expose-Headers:AMP-Access-Control-Allow-Source-Origin");
        echo json_encode($output);
        die();
    }
}
Publié le

Exemple de requêtes SQL avancées

Le but ici n’est pas de refaire la documentation de référence mais plutôt de donner d’une part quelques exemples et d’autre part de mettre en avant quelques fonctions bien utiles. 
C’est une librairie de fonctions que j’utilise fréquemment et qu’il me faut souvent copier pour ne pas faire d’erreurs.

Join: lier 2 tables sur un champ

Exemple tout simple d’un requête join qui lie 2 tables en fonction d’un champ.

$favorites = DB::table('favoris')
	->join('annonces', 'annonces.id', '=', 'favoris.idannonce')   
	->select('annonces.genre', 'favoris.*') 
	->where('favoris.iduser','=',$current_user_id)
	->whereNull('bla_bla');
	->whereNotNull('bla_bla_bla')
	->get();

Exemple d’une requête imbriquée

Exemple suivant montre comment créer une requête imbriquée en utilisant une variable pour la condition. La variable doit être passée avec le mot-clé use.

$allads = DB::table('anonnces')
	->join('anonnces_lang', function ($join)  use ($lang)  {
		$join->on('anonnces.id', '=', 'anonnces_lang.idfiche')
		->where('anonnces_lang.lang', $lang);
	})
	->select('anonnces.*', 'anonnces_lang.ville','anonnces_lang.ville_url')
	->orderBy('ville', 'asc')
	->whereNull('date_pause')
	->where('date_fin','>',date("Y-m-d H:i:s") )->get(); 

Champ calculé, raw sql

Exemple d’une requête générée par Laravel qui contient entre autres des champs calculés par le moteur de base de données.

$annonces = DB::table('annonces')
    ->select(DB::raw("annonces.id, annonces.name,
        if(`date_fin`<'".date("Y-m-d H:i:s")."',1,0) as annonce_active,
        if(`date_pause` is null,0,1) as annonce_pause
    "))
    ->where('name','like','a%')
    ->orderBy('created_at', 'asc') 
->get();

Champ calculé pour retourner un count avec un group by

Exemple d’une requête générée par Laravel qui contient entre autres des valeurs count avec un group by

$reviews = DB::table('reviews')
        ->select(DB::raw('count(*) as nb_reviews, idads'))
        ->where('status', 1)
        ->groupBy('idads')
        ->get();

$cronlog = DB::table('cron_log')
        ->select("*",DB::raw(" TIMESTAMPDIFF(SECOND,date_start,date_end) as duration"))
        ->orderBy('status','desc');

Comparer 2 champs dans une table

Dans certains cas, il est utile de comparer 2 champs dans une table. Dans mon cas, j’utilise cela pour ajouter une latence à une action. Ma cron a besoin de comparer le plus vite possible 2 champs. Pour effectuer une telle action, j’utilise la fonction whereRaw de la façon suivante:

$all = DB::table('annonces')->whereRaw('npa!=last_npa')->get();

Incrémenter, décrémenter un champ

Le système de génération de requête fournit également des méthodes pratiques pour incrémenter ou décrémenter un champ du nombre que vous désirez, et même modifier des valeurs en même temps.

//ajoute 1 au champ views
DB::table('annonces')->where('id', $idannonce)->increment('views');
//enlève 3 au champs views
DB::table('annonces')->where('id', $idannonce)->decrement('views',3);
//incrément de 1 le champs vue et ajoute la date du jour dans le champs last_view
DB::table('annonces')->where('id', $idannonce)->increment('views',1,['last_view'=>date('Y-m-d')]);
//il n'est pas possible d’incrémenter 2 champs en même temps. Pour réaliser cela, il faut faire:
DB::table('banner_pub')->where('id', 1)
   ->update([
      'view' => DB::raw('view + 1'),
      'view_day' => DB::raw('view_day + 1')
   ]);

Modifier des données avec la fonction update

//Modifier 1 champ 
DB::table('annonces')->where('id', $idannonce)->update(['ma_var' =>9]);
//Modifier plusieurs champs
DB::table('annonces')->update(['ma_var' => 0,'ma_var2'=>0]);
DB::table('annonces')->where('id', $idannonce)->update(['ma_var' => 0,'ma_var2'=>0]);
//Mettre champ a null
DB::table('annonces')->where('id',$idannonce)->update(['review_date' =>null]);

Utilisation de where, orWhere et whereIn

Les exemples suivants montrent comment utilise where ou orwhere en hiérarchisant les where. C’est compliqué a expliquer mais je pense que l’exemple suivant va vous le faire comprendre. Je montre aussi une utilisation de whereIn.

$yestrerday=date('Y-m-d H:i:s', strtotime("-1 days"));
$annonces = DB::table('annonces')
	->where('date_fin','<',$yestrerday)
	->orWhere('member_premium',1)
        ->limit(10)
	->get(); 

// Faire plusieurs OU sur des champs 
$fiches = DB::table('annonces')
->where('id',$idannonce)  
->where(function ($query) use ($iduser) {
	$query->where('iduser',$iduser)
	->orWhere('idvendeur',$iduser);
})
->get(); 
// Where avec un tableau de valeurs
$log = DB::table('log_fiche')
->whereIn('type_action', ['update', 'delete','reset'])
->get();
Publié le

Allez plus loins avec Laravel

Je regroupe ici les informations utiles qui ne nécessitent pas de créer un article dédié. Vous avez donc une liste non ordonnée de fonctions utiles et de snippets qui vous servirons dans vos développements.

1. Cacher que votre site est réalisé avec Laravel

Il est souvent utile de masquer la technologie qui a été utilisée pour la création d’un site web. Si vous voulez rendre moins facile cette détection sur votre site et cacher la technologie utilisée, un moyen basic et très simple est déjà de changer le nom de la session. 
Les projets Laravel ont comme nom de session laravel_session. Il est donc une bonne pratique de la renommer en modifiant son nom dans le fichier: config\session.php

#'cookie' => 'laravel_session',
'cookie' => 'webp_session',

Et si vous ne l’avez pas encore fait, changer le nom de l’application dans le fichier: config\app.php

#'name' => 'Laravel',
'name' => 'Web-Presence.ch',

2. Paramètre optionnel dans le fichier de routage

Il est possible d’ajouter un paramètre optionnel dans le routage en ajouter ? dans votre paramètre comme vous le montre l’exemple suivant:

Route::any('backend/event/{date?}', ['as'=> 'backend/event','uses'=>'Backend\EventController@index'])->middleware('auth');

Du côté du controller il suffit de déclarer la fonction de la manière suivante:

class EventController extends Controller
{
	public function index(Request $request,$date=null){   

		if(is_null($date)){
			$($ = date("Y-m-d");
		}

3. Cron sous Laravel

Il est très facile de mettre en place des crons sous Laravel, il faut bien évidemment le mettre dans le cron tab de votre serveur en appelant la commande suivante: artisan schedule:run

Ajout de la cron Laravel dans le crontab Ubuntu

Et ensuite ajouter les appels à fonctions dans le fichier app/Console/Kernel.php.

Vous avez de nombreuses façons de choisir à quel moment vos crons doivent être lancées. Je vous donne ci-dessous quelque exemple mais pour plus d’infos, je vous invite à vous référer à la doc officielle

class Kernel extends ConsoleKernel
{
	$schedule->call(function () {
		/* Cron éxécuté chaque heure à la 20ème et la 50ème minute  */
	})->cron('20,50 * * * *');

	$schedule->call(function () {
		/* Cron éxécuté à 9 heure et 13 heure à la 10ème, la 35ème et la 52ème minute  */
	})->cron('10,35,52 9,13 * * *');
	
	$schedule->call(function () {
		/* Cron éxécuté chaque jour à minuit  */
	})->daily();

4. Redirection des URL avec index.php

Les urls avec index.php sont valides et ne génèrent pas d’erreur. Si vous avez des balises canonical et que les chemins de vos ressources sont absolus ce n’est pas trop grave mais comme je n’aime pas cela, je vais générer des redirections depuis le fichier htacces. Le but du script ci-dessous est de rediriger les urls de la façon suivante:

http://www.crabcake.ch/blog/index.php => http://www.crabcake.ch/blog
http://www.crabcake.ch/blog/index.php/laravel-snippet-utile => http://www.crabcake.ch/blog/laravel-snippet-utile

RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index.php/?([^\ \?]*) [NC]
RewriteRule ^ %1/%2 [R=301,L]
Publié le

Gestion des emoji et émoticônes

Il est de plus en plus en vogue et apprécié des visiteurs de pouvoir insérer des émoticônes et emoji. Cela est particulièrement vrai pour les commentaires et évaluations. Comme la plupart des navigateurs gèrent bien l’affichage, il n’y a pas de raison de se priver. Les mettre en place sous Laravel est assez simple et il n’y a pas beaucoup de modifications à faire.

J’ai remarqué l’intérêt des visiteurs en constatant l’erreur suivante dans les logs.

SQLSTATE[HY000]: General error: 1366 Incorrect string value: ‘\xF0\x9F\x98\x8B’ for column ‘review’ at row 1

Après quelques recherches, j’ai constaté que ces caractères spéciaux sont des emoji inséré directement depuis un téléphone portable.

Autoriser l’ajout d’emoji

Pour permettre l’ajout, il faut modifier les champs de la base de données qui contiendront les textes ainsi que le fichier de configurations. Les champs de la base doivent avoir comme collation: utf8mb4_unicode_ci et vous devez modifier le fichier de config de la façon suivante:

//Modifier le fichier : config/database.php
'mysql' => [
'charset' => 'utf8mb4',[
'collation' => 'utf8mb4_unicode_ci',[
],

Refuser et supprimer les émoticones

Si vous désirez les supprimer, la fonction suivante permet d’enlever tous les caractères correspondant et permet d’enregistrer sans erreur.

/**
* find on https://gist.github.com/quantizer/5744907
*/
    public function removeEmoji($text) {

        $clean_text = "";

        // Match Emoticons
        $regexEmoticons = '/[\x{1F600}-\x{1F64F}]/u';
        $clean_text = preg_replace($regexEmoticons, '', $text);

        // Match Miscellaneous Symbols and Pictographs
        $regexSymbols = '/[\x{1F300}-\x{1F5FF}]/u';
        $clean_text = preg_replace($regexSymbols, '', $clean_text);

        // Match Transport And Map Symbols
        $regexTransport = '/[\x{1F680}-\x{1F6FF}]/u';
        $clean_text = preg_replace($regexTransport, '', $clean_text);

        // Match Miscellaneous Symbols
        $regexMisc = '/[\x{2600}-\x{26FF}]/u';
        $clean_text = preg_replace($regexMisc, '', $clean_text);

        // Match Dingbats
        $regexDingbats = '/[\x{2700}-\x{27BF}]/u';
        $clean_text = preg_replace($regexDingbats, '', $clean_text);

        return $clean_text;
    }
Publié le

Exemples de middlewares pour le routage

Les middlewares sont des fonctions qui permettent de relier des applications. Comme ils sont appelés à des moment bien définis, il permettent d’effectuer des traitements avant la sortie à l’écran comme vous pourrez le voir ici et aussi d’effectuer des tests de sécurité pour limiter des accès comme nous allons le voir ci-dessous.

Laravel permet de limiter l’accès à certaines pages en fonction de fonctions que vous définissez. Il suffit ensuite de le signaler dans le fichier routes/web.php en ajoutant simplement ->middleware(‘auth’); à la fin de votre route. Il est facile et particulièrement utile d’étendre ce principe à des contrôles personnalisé comme vérifier si l’utilisateur est un administrateur. Pour réaliser ce contrôle procédé comme suit:

Création du fichier

Pour créer le squelette du fichier, vous pouvez au choix copier un fichier existant ou utiliser artisan à l’aide de la commande suivante pour créer le fichier CheckAdmin.php:

php artisan make:middleware CheckAdmin

Une fois ce fichier crée (app/Http/Middleware/CheckAdmin.php), effectuez les tests que vous voulez comme limiter l’accès en fonction du type d’utilisateur.

use Closure;
use Auth;//Ajouté
use App\User;//Ajouté
use Session;//Ajouté

class CheckAdmin
{
    public function handle($request, Closure $next)
    {
        if (!Auth::check()) {
            return redirect('home');
        }
        $iduser = Auth::user()->id;//$user = User::find(1);
        $cur_user = User::find($iduser);
        if($cur_user->level<5){
            return redirect('home');
        }
        return $next($request);
    }
}

Pour qu’il soit possible de l’appeler, il faut maintenant modifier le fichier le fichier App\Http\Kernel.php en ajoutant le nouveau middleware dans le bon tableau de la façon suivante:

protected $routeMiddleware = [
	/* ... */
	'checkadmin' => \App\Http\Middleware\CheckAdmin::class,
];

Il suffit ensuite de l’appeler dans le fichier de routage web.php en ajoutant son nom.

Route::any('backend/parameters/edit/{id}', ['uses'=>'Backend\ParametersController@edit'])->where('id', '[0-9]+')->middleware('checkadmin');

Voilà, vous avez maintenant mis en place un système simple et imparable qui bloque l’accès aux pages de votre choix en fonction du niveau de l’utilisateur.

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