Giter VIP home page Giter VIP logo

laravel-savable's Introduction

Social Icon of Laravel Savable

Laravel Savable

Latest Stable Version Total Downloads License Tests

Savable is a Laravel package that will help you organize your business logic.

Installation

You can install the package via composer:

composer require chargefield/laravel-savable

Usage

Savable Trait

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Chargefield\Savable\Traits\IsSavable;

class Post extends Model
{
    use IsSavable;
}

Example

A simple example for storing a record from a controller:

namespace App\Http\Controllers;

use App\Models\Post;
use Chargefield\Savable\Fields\SlugField;
use Chargefield\Savable\Fields\StringField;
use Illuminate\Http\Request;

class PostController
{
    public function store(Request $request)
    {
        $post = Post::make()->savable($request->all())->columns([
            StringField::make('title'),
            SlugField::make('slug')->fromField('title'),
            StringField::make('body'),
        ])->save();
    }
}

Savable Columns

Setting columns:

$post = Post::make()->savable([...])->columns([
    StringField::make('title'),
    SlugField::make('slug')->fromField('title'),
    StringField::make('body'),
])->save();

Alternatively, you can set savable columns in a model:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Chargefield\Savable\Fields\Field;
use Chargefield\Savable\Traits\IsSavable;
use Chargefield\Savable\Fields\JsonField;
use Chargefield\Savable\Fields\SlugField;
use Chargefield\Savable\Fields\FileField;
use Chargefield\Savable\Fields\StringField;
use Chargefield\Savable\Fields\BooleanField;
use Chargefield\Savable\Fields\IntegerField;
use Chargefield\Savable\Fields\DatetimeField;

class Post extends Model
{
    use IsSavable;

    /**
     * @return Field[]
     */
    public function savableColumns(): array
    {
        return [
            StringField::make('title')->rules('required|string'),
            SlugField::make('slug')->fromField('title'),
            StringField::make('body')->rules('required|string'),
            FileField::make('image')->nullable()->rules('nullable|image'),
            BooleanField::make('is_featured')->rules('required|boolean'),
            IntegerField::make('order')->strict()->rules('required|integer|min:1'),
            JsonField::make('options')->nullable(),
            DatetimeField::make('published_at')->nullable(),
        ];
    }
}

NOTE: savableColumns() will get overridden by columns([...])

Savable Data

Setting data:

$post = Post::make()->savable(request()->all())->columns([...])->save();

or

$post = Post::make()->savable()->data(request()->all())->columns([...])->save();

Setting data from request:

$post = Post::make()->savable()->fromRequest()->columns([...])->save();

Setting data from a given request:

$post = Post::make()->savable()->fromRequest(request())->columns([...])->save();

Validation

Validating before saving (throws Illuminate\Validation\ValidationException):

$post = Post::make()->savable()->data([...])->columns([...])->validate()->save();

Validating without throwing an exception:

Post::make()->savable()->data([...])->columns([...])->hasErrors();
// return bool

or

Post::make()->savable()->data([...])->columns([...])->getErrors();
// return Illuminate\Support\MessageBag

NOTE: Fields must set rules([...]) in order to validate their data.

Fields

String Field:

StringField::make('title');

Slug Field:

SlugField::make('slug')->fromField('title')->separateBy('-');

File Field:

FileField::make('image')->disk('local')->path('images')->withOriginalName();

Boolean Field:

BooleanField::make('is_featured');

Integer Field:

IntegerField::make('age')->strict();

Json Field:

JsonField::make('options')->pretty()->depth(512);

Datetime Field:

DatetimeField::make('published_at');

Additional Methods:

Sets the column name and default value:

StringField::make('title', 'Default Title');

or

StringField::make('title')->value('Default Title');

Sets the field name if not the same as the column name:

StringField::make('title')->fieldName('name');

Sets the nullable flag, null will be returned if value is empty/null/exception:

StringField::make('title')->nullable();

Sets the validation rules for the field (Laravel validation rules):

StringField::make('user_id')->rules('required|exists:users,id');

or

StringField::make('user_id')->rules([
    'required',
    Rule::exists('users', 'id'),
]);

Sets a closure to transform the value:

StringField::make('title')->transform(function ($fieldName, $fieldValue, $fieldsData) {
    return Str::title($fieldValue);
});

Custom Fields

You can create custom fields with ease using the artisan command.

php artisan make:field CustomField

Outputs:

namespace App\Fields;

use Chargefield\Savable\Fields\Field; 

class CustomField extends Field
{
    /**
     * @param array $data
     * @return mixed
     */
    public function handle(array $data = [])
    {
        if (empty($this->value) && $this->nullable) {
            return null;
        }
        
        // Logic goes here

        return $this->value;
    }
}

Testing custom fields:

Field::assertHandle

$field = CustomField::fake('title');
$field->value('Example Title');
$field->assertHandle('Example Title'); // passed
$field->assertHandle('Not The Same'); // failed

Field::assertTransform

$field = CustomField::fake('title');
$field->value('Example Title');
$field->transform(function ($name, $value, $data) {
    return "{$data['prefix']} {$value}";
});
$field->assertTransform('Prefixed Example Title', ['prefix' => 'Prefixed']); // passed
$field->assertTransform('Example Title', ['prefix' => 'Prefixed']); // failed

Field::assertValidation

$field = CustomField::fake('title');
$field->rules('required|string');
$field->assertValidation('Example Text'); // passed
$field->assertValidation(''); // failed

Testing

You can run the tests with:

vendor/bin/phpunit

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

laravel-savable's People

Contributors

chargefield avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.