5

I'm building an API using Slim and the Illuminate Database package with Eloquent models etc. I have instantiated the database handler using Capsule as shown in the README. However, now I want to use the validation features on my models without installing the full Laravel suite, but I cannot quite wrap my head around the design of this library.

How would I go about this? It seems like the documentation provided for Laravel is pretty much expecting that you use Laravel out of the box.

Viktor
  • 487
  • 2
  • 8
  • 26
  • Using composer adding `illuminate/validation` to your requirements will download the required dependencies ready for using in your non `laravel` application – William George Feb 18 '15 at 00:46
  • Yeah, but what I don't get is how to use this package. In the package there is a `Factory` class and a `Validator` class, both requiring a `TranslatorInterface` as a parameter to their constructors. What do I pass in? – Viktor Feb 18 '15 at 22:25

5 Answers5

13

Here is a solution for the current version: Laravel 5.4. The composer.json file:

{ "name": "Validation standalone", "require": { "php": ">=5.6.4", "illuminate/validation": "5.4.*", "illuminate/translation": "5.4.*" } }

Note that we must also require "illuminate/translation": "5.4.*". And then in your php file:

use Illuminate\Validation;
use Illuminate\Filesystem;
use Illuminate\Translation;

include 'vendor/autoload.php';

$filesystem = new Filesystem\Filesystem();
$fileLoader = new Translation\FileLoader($filesystem, '');
$translator = new Translation\Translator($fileLoader, 'en_US');
$factory = new Validation\Factory($translator);

$messages = [
    'required' => 'The :attribute field is required.',
];

$dataToValidate = ['title' => 'Some title'];
$rules = [
    'title' => 'required',
    'body' => 'required'
];

$validator = $factory->make($dataToValidate, $rules, $messages);

if($validator->fails()){
    $errors = $validator->errors();
    foreach($errors->all() as $message){
        var_dump($message);
    }
}

Here I have intentionally missed the "body" field in the data provided for validation, so that a validation error is displayed.

vivanov
  • 1,422
  • 3
  • 21
  • 29
  • 1
    Is there a way to use the default messages of laravel as well though? – mrateb Jul 11 '18 at 11:42
  • 1
    @mrateb though late to the table but better late than never. [Below](https://stackoverflow.com/a/65968740/6597265) I explain how you add default messages. – Valentine Shi Jan 30 '21 at 14:16
5

As for early 2021 the solution from @vivanov here works perfectly with Laravel 8 packages.

Here I add the ability to use default Laravel validation messages as using your own is too annoying.

Here is what you have to change in the @vinvanov solution.

  1. Upddate composer.json
    "require": {
        "illuminate/validation": "^8.25",
        "illuminate/translation": "^8.25"
    },
  1. Copy Laravel validation messages file to your project/laravel/en/validation folder.

  2. Amend @ivanov's solution code as follows (only changes are reflected)

$translationDir = dirname(__DIR__, 4) . '/project/laravel/en/validation';

$fileLoader = new Translation\FileLoader($filesystem, $translationDir);
$fileLoader->addNamespace('lang', $translationDir);
$fileLoader->load('en', 'validation', 'lang');

$validator = $factory->make($dataToValidate, $rules);

See the full code with more comments in my gist;

This is it. You have the default Laravel messages in place working for you.

Here is the Laravel validation docs.

PS: Credits also go to this blog post from Jeff.

PPS: This is brilliant that despite version jump from 5.6 to 8.25 the packages interface is stable and works seamlessly. So mature and insightful open source attitude and great care about developers from Taylor Otwell. You can only apreciate the utmost convenience of this when you work outside of modern PHP frameworks within a shitty PHP codebase.

Valentine Shi
  • 6,604
  • 4
  • 46
  • 46
1

I hate to suggest this but the Laravel validator is probably not what you want. I suggest having a look at the validator classes in either Symfony or Zend Framework (2+). They work quite well as stand-alone validators and in fact I am using the ZF2 form classes and validator in a Laravel project at the moment because the Laravel form and validator classes are just not up to scratch.

It's probably not the answer you wanted to hear but it might save you some pain in the long term.

delatbabel
  • 3,601
  • 24
  • 29
  • Totally agree here. I've had extensive experience with ZF1 validators and form elements (and a bit with ZF2) and it's in a different league to Laravel. Laravel's front-end and forms/validators seem like an afterthought. – dKen Sep 21 '16 at 07:16
1

I was just wondering the same thing, and here I am a year later finding delatbabel's answer to be seriously wanting. I did find the following Gist where spekkionu has a fairly simple setup to get you started. (It's working on my machine?? ;P ) It shows how to make the translator for the factory, etc, etc. It's all included when you import illuminate/validation with composer.

Hope it helps: https://gist.github.com/spekkionu/e9103993138e666f9f63

Best,

Patrick
  • 807
  • 6
  • 12
0

Unfortunately none of the previous solutions will work, if you are planning to use Laravel's custom validation rules.

You can check out my solution in my gist.

Huge thanks to @vivanov and @Valentine-shi.

The custom Rule is calling the global trans() function. This is why it is in the helpers.php and registered via Composer.
This trans() function is also used to create the validator factory.

  1. Add custom helper php file for global functions.
//<project-path>/src/helpers.php

<?php

use Illuminate\Filesystem\Filesystem;
use Illuminate\Translation\FileLoader;
use Illuminate\Translation\Translator;

if (!function_exists('trans')) {
    function trans(string $key = null, array $replace = [], string $locale = null): Translator|array|string|null
    {
        $translationDir = dirname(__DIR__).'/lang';

        $fileLoader = new FileLoader(new Filesystem(), $translationDir);
        $fileLoader->addNamespace('lang', $translationDir);
        $fileLoader->load('en', 'validation', 'lang');
        $translator = new Translator($fileLoader, 'en');
        $translator->setLocale('en');
        $translator->setFallback('en');

        if (is_null($key)) {
            return $translator;
        }

        return $translator->get($key, $replace, $locale);
    }
}
  1. Register it in composer.json
//<project-path>/composer.json

{
    "require": {
        "php": "^8.1",
        "illuminate/translation": "^10.9",
        "illuminate/validation": "^10.9",
    },
    "autoload": {
        "files": [
            "src/helpers.php"
        ]
    }
}
  1. Add locale file
//<project-path>/lang/en/validation.php

<?php

return [
    'accepted' => 'The :attribute must be accepted.',
    // ... rest of the validations
    // Copy it from Laravel. 
];
  1. Create the validation factory, and use it
//<project-path>/scr/Validation/Validator.php

<?php

namespace <insert-your-namespace-here>;

use Illuminate\Validation\Factory;

class Validator
{
    protected Factory $validator;

    public function __construct()
    {
        $this->validator = new Factory(trans());
    }
}

I'm pretty sure you can play with the required versions.

Levente Otta
  • 713
  • 6
  • 17