Search code examples
phpvalidationlaravellaravel-5laravel-validation

I am using Laravel 5's Command Bus and I am unclear how to implement a validator class


I am using Laravel 5's Command Bus and I am unclear how to implement a validator class.

I would like to create a ResizeImageCommandValidator class that checks that the image is actually an image before attempting to resize the image.

The code I'd like to pull out is here from the ResizeImageCommandHandler resize method.

if (!($image instanceof Image))
{
    throw new ImageInvalidException('ResizeImageCommandHandler');
}

The idea came from Laracasts Commands and Domain Events, but Jeffrey doesn't use the Laravel 5 architecture.

Here's the code.

ResizeImageCommandHandler.php

<?php namespace App\Handlers\Commands;

use App\Commands\ResizeImageCommand;

use App\Exceptions\ImageInvalidException;
use Illuminate\Queue\InteractsWithQueue;
use Intervention\Image\Image;

class ResizeImageCommandHandler {

    /**
     * Create the command handler.
     */
    public function __construct()
    {
    }
    /**
     * Handle the command.
     *
     * @param  ResizeImageCommand  $command
     * @return void
     */
    public function handle($command)
    {
        $this->resizeImage($command->image, $command->dimension);
    }
    /**
     * Resize the image by width, designed for square image only
     * @param Image $image Image to resize
     * @param $dimension
     * @throws ImageInvalidException
     */
    private function resizeImage(&$image, $dimension)
    {
        if (!($image instanceof Image))
        {
            throw new ImageInvalidException('ResizeImageCommandHandler');
        }
        $image->resize($dimension, null, $this->constrainAspectRatio());
    }
    /**
     * @return callable
     */
    private function constrainAspectRatio()
    {
        return function ($constraint) {
            $constraint->aspectRatio();
        };
    }


}      

ResizeImageCommand.php

<?php namespace App\Commands;

use App\Commands\Command;

use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldBeQueued;
use Image;

class ResizeImageCommand extends Command {
    use InteractsWithQueue, SerializesModels;

    public $image;
    public $savePath;
    public $dimension;

    /**
     * Create a new command instance.
     * @param Image $image
     * @param string $savePath
     * @param int $dimension
     * @param int $pose_id
     * @param int $state_id
     */
    public function __construct(&$image, $savePath, $dimension)
    {
        $this->image = $image;
        $this->savePath = $savePath;
        $this->dimension = $dimension;
    }

}

Solution

  • In an attempt to answer your question, I suggest don't get too hung up on the Command part of it. In Laravel 5.1 that folder is being renamed to "Jobs" - refer to;

    https://laravel-news.com/2015/04/laravel-5-1/

    This is precisely because Taylor felt folks were getting too stuck on the word "Command."

    See also http://www.laravelpodcast.com/episodes/6823-episode-21-commands-pipelines-and-packages and https://laracasts.com/lessons/laravel-5-commands

    The validator classes in the Illuminate packages are pretty great, http://laravel.com/api/5.0/Illuminate/Validation/Validator.html - I'm not sure what the issue is with that, I guess.

    I'd say that unless you have a compelling reason to use a Command class for this, don't. also see: http://www.laravelpodcast.com/episodes/9313-episode-23-new-beginnings-envoyer-laravel-5-1

    I humbly suggest you may have asked the wrong question, and maybe you don't need to use a Command to handle this.

    This is probably the answer you're looking for: https://mattstauffer.co/blog/laravel-5.0-validateswhenresolved

    use Illuminate\Contracts\Validation\ValidatesWhenResolved;

    and if that doesn't work, sign up for Larachat, http://larachat.co/ - a Slack channel for just this sort of thing. Best place ever for Laravel help. (except Stack Overflow, of course)

    Here's a little class I use for checking the format of an image, also, thought you might find it useful.

    <?php
    Class FileUploadFormat
    {
    public function is_image($image_path)
      {
          if (!$f = fopen($image_path, 'rb'))
          {
              return false;
          }
    
          $data = fread($f, 8);
          fclose($f);
    
          // signature checking
          $unpacked = unpack("H12", $data);
          if (array_pop($unpacked) == '474946383961' || array_pop($unpacked) == '474946383761') return "gif";
          $unpacked = unpack("H4", $data);
          if (array_pop($unpacked) == 'ffd8') return "jpg";
          $unpacked = unpack("H16", $data);
          if (array_pop($unpacked) == '89504e470d0a1a0a') return "png";
          return false;
      }
    }