The package provides an expressive "fluent" way to define model attributes.

Overview

Laravel Fluent

The package provides an expressive "fluent" way to define model attributes. It automatically builds casts at the runtime and adds a native autocompletion to the models' properties.

Introduction

With laravel-fluent, you can define Model attributes as you would do with any other class. The values will be transformed to the corresponding types depending on the native types of the properties.

Before:



/**
 * @property Collection $features
 * @property float $price
 * @property int $available
 */
class Product extends Model
{
    protected $casts = [
        'features' => 'collection',
        'price' => 'float',
        'available' => 'integer',
    ];
}

After:



class Product extends Model
{
    use Fluent;

    public Collection $features;
    public float $price;
    public int $available;
}

Installation

This version supports PHP 8.0. You can install the package via composer:

composer require based/laravel-fluent

Then, add the Based\Fluent\Fluent trait to your models:



class User extends Model
{
    use Fluent;
}

Model attributes

Define the public properties. laravel-fluent supports all native types and Laravel primitive casts:



class Order extends Model
{
    use Fluent;

    public int $amount;
    public Carbon $expires_at;

    #[AsDecimal(2)]
    public float $total;

    #[Cast('encrypted:array')]
    public array $payload;
}

Relations

The package also handles relationships.



class Product extends Model
{
    use Fluent;

    #[Relation]
    public Collection $features;
    public Category $category;

    public function features(): HasMany
    {
        return $this->hasMany(Feature::class);
    }

    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }
}

Relations method declaration is still required for proper autocompletion. However, the package can automatically resolve relations from attributes.



class Product extends Model
{
    use Fluent;

    #[HasMany(Feature::class)]
    public Collection $features;
    #[BelongsTo]
    public Category $category;
}

Testing

composer test

Todo

  • Migration generator

Credits

License

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

Comments
  • Error : Typed property App\Models\User::$name must not be accessed before initialization

    Error : Typed property App\Models\User::$name must not be accessed before initialization

    Hi, I have a very simple example like this:

    class User extends Model
    {
        use Fluent;
    
        public string $name;
    }
    

    Within tests:

    $user = UserFactory::new()->create();
    dd($user->name);
    

    Throws an error:

    Error : Typed property App\Models\User::$name must not be accessed before initialization
    
    opened by milewski 9
  • Add CarbonImmutable Cast Support

    Add CarbonImmutable Cast Support

    This PR add CarbonImmutablecast support, as it is natively supported by Laravel as immutable_datetime I think this PR is important for programmers like me as the packages is unusable to cast dates when using Date::use(CarbonImmutable::class); as all dates and datetimes will be instance of CarbonImmutable

    opened by Attia-Ahmed 2
  • Incrementing property of laravel throw an error

    Incrementing property of laravel throw an error

    Hi, i was testing some models with uuid, so i need to add de $incrementing property to false like the docs, that throws an error, i guess is for the public access of the property

    class User extends Model
    {
         use Fluent;
    
         /**
         * Indicates if the IDs are auto-incrementing.
         *
         * @var bool
         */
         public $incrementing = false;
    }
    

    when i try to retrieve the model from database this throw

        PHP Error:  Call to a member function getName() on null
    

    by the way, i love this package

    opened by ghost 2
  • Fillable attributes for mass-assignment protection

    Fillable attributes for mass-assignment protection

    I was thinking it might be possible to mark properties as fillable or guarded for Laravel's mass-assignment protection.

    class Person extends Model
    {
        use Fluent;
    
        #[Fillable]
        public string $first_name;
    
        #[Fillable]
        public string $last_name;
    
        // not fillable since it does not have the Fillable attribute
        public bool $is_admin;
    }
    

    If you are not interested in adding this feature, no big deal.

    opened by ejunker 2
  • Laravel 9.x Compatibility

    Laravel 9.x Compatibility

    This is an automated pull request from Shift to update your package code and dependencies to be compatible with Laravel 9.x.

    Before merging, you need to:

    • Checkout the l9-compatibility branch
    • Review all comments for additional changes
    • Thoroughly test your package

    If you do find an issue, please report it by commenting on this PR to help improve future automation.

    opened by laravel-shift 1
  • Support for accessors

    Support for accessors

    This is an idea of how to improve on Laravel's accessors so that you would get IDE autocompletion and other benefits of having it defined as a real property.

    class Person extends Model
    {
        use Fluent;
    
        public string $first_name;
        public string $last_name;
    
        #[Accessor('getFullNameAttribute')]
        public readonly string $full_name;
    
        #[Accessor(function() {
            return $this->first_name . ' ' . $this->last_name;
        })]
        public readonly string $full_name2;
    }
    

    The readonly keyword will not work until PHP 8.1 and also I do not think it is possible to pass a closure to an attribute until PHP 8.1. The first accessor lets you reference a method name and the second example defines the logic in the closure.

    Feel free to close this issue if you are not interested in adding this feature.

    opened by ejunker 1
  •  Call to a member function getName() on null

    Call to a member function getName() on null

    Hello , I'm facing the following exception

    Error : Call to a member function getName() on null
     /var/www/codebase/itrainer_dashboard/vendor/based/laravel-fluent/src/HasProperties.php:56
    

    When i override Eloquent model public properties that doesn't have types like [ $timestamps ]

    Simple Solution is to exclude public properties without types with the following

     ->reject(fn (ReflectionProperty $property) => $property->getType() === null)
    
    opened by hsmfawaz 0
  • Fully support default values, and avoid clobbering retrieved values

    Fully support default values, and avoid clobbering retrieved values

    Hello, I've recently stumbled across this library. I really like what it's aiming to do, so I wanted to submit some changes that I've been working on.

    This supports both types of default values that are available:

    1. Defining a default within the eloquent model's $attributes array, and
    2. Setting a default value on a PHP property being managed by Fluent

    Under the hood, the main gimmick to make this work is that any default values defined on PHP properties will be copied into the eloquent model's $attributes array. That allows Laravel's internals to truly see that value as a default value, in the event of e.g. creating a new, empty instance of a model.

    We also override the setRawAttributes method to unset our managed properties in a way similar to how this code already behaved in setAttribute. Within our overridden setRawAttributes, we also want to avoid triggering redundant calls to parent::setAttribute, so there's a simple flag for doing that.

    Resolves #10

    Test cases included.

    opened by adelaidegb 0
  • Confusion with Laravel Fluent class

    Confusion with Laravel Fluent class

    Now that Laravel implements a Illuminate\Support\Fluent class there is a risk of confusion when using the trait:

    class User extends Model {
      use Fluent; // Here comes the confusion, are we using this package or Laravel's class?
    }  
    

    A simple workaround is to alias the class, eg:

    use Based\Fluent\Fluent as HasFluentAttributes;
    
    class User extends Model {
      use HasFluentAttributes;
    }  
    

    One could say there's a great risk to forget doing this when generating a model with artisan make:model.
    Publishing then editing the stubs could be a workaround, but this would create a lot of friction for simpler projects.

    I'd suggest renaming the trait so users don't risk any error.

    Let me know if you're OK with that and I'll drop a PR.

    opened by superbiche 1
  • Support custom casts

    Support custom casts

    Fantastic project!

    Any chance we can get support for Custom Casts? https://laravel.com/docs/8.x/eloquent-mutators#custom-casts

    If no one with experience with the project has time, I can try implementing the feature, but in that case some help (i.e. direction) would be needed.

    opened by Putr 2
  • More PHP 8 attributes for adding validation constraints to fields

    More PHP 8 attributes for adding validation constraints to fields

    I really like the possibilities for this library. What do you think about the idea of letting people add laravel validation constraints to fields as well. So when you setAttribute() something, it'll validate and throw exceptions when invalid data is set into the model.

    Since it's optional and built when the class is constructed, it should be fairly transparent. Something like this might be nice

    #[Validate('int|between:3,100')]
    public int $someNumber;
    

    Then if I set a valid of 200, it'll throw a validation exception that if I want to catch myself and handle, I can do so. Or perhaps add a default or fallback values for situations where it might be appropriate.

    opened by christhomas 0
Releases(v0.0.2)
Owner
Boris Lepikhin
Making some tricky stuff with Laravel, Vue.js and Tailwind CSS.
Boris Lepikhin
This package provides a simple and intuitive way to work on the Youtube Data API. It provides fluent interface to Youtube features.

Laravel Youtube Client This package provides a simple and intuitive way to work on the Youtube Data API. It provides fluent interface to Youtube featu

Tilson Mateus 6 May 31, 2023
Attributes to define PHP language extensions (to be enforced by static analysis)

PHP Language Extensions (currently in BETA) This library provides attributes for extending the PHP language (e.g. adding package visibility). The inte

Dave Liddament 70 Dec 19, 2022
[READ-ONLY] Properties define model metadata.

Charcoal Property Properties define object's metadata. They provide the building blocks of the Model's definition. Properties are defined globally for

The Charcoal PHP Framework 0 Jun 21, 2022
Enforce that your classes get only instantiated by the factories you define!

Enforce that your classes get only instantiated by the factories you define!

null 3 Nov 15, 2021
Allow composer packages to define compilation steps

Composer Compile Plugin The "Compile" plugin enables developers of PHP libraries to define free-form "compilation" tasks, such as: Converting SCSS to

CiviCRM 11 Aug 3, 2022
Kiaan PHP is a web application framework with expressive, elegant syntax.

About Kiaan framework Kiaan is a web application framework for PHP. Kiaan is easy, flexible and professional. Documentation You can learn kiaan with t

Kiaan 30 Oct 17, 2022
Strings Package provide a fluent, object-oriented interface for working with multibyte string

Strings Package provide a fluent, object-oriented interface for working with multibyte string, allowing you to chain multiple string operations together using a more readable syntax compared to traditional PHP strings functions.

Glowy PHP 14 Mar 12, 2022
MOP is a php query handling and manipulation library providing easy and reliable way to manipulate query and get result in a fastest way

Mysql Optimizer mysql optimizer also known as MOP is a php query handling and manipulation library providing easy and reliable way to manipulate query

null 2 Nov 20, 2021
Allows reflection of object attributes, including inherited and non-public ones

sebastian/object-reflector Allows reflection of object attributes, including inherited and non-public ones. Installation You can add this library as a

Sebastian Bergmann 6k Jan 4, 2023
Magento 2 custom extension to add custom attributes(longitude, latitude) to customer address

Magento 2 custom extension to add custom attributes(longitude, latitude) to customer address. Then save them to quote model and copy them from quote address to order address on bakend, frontend, rest api

MageArab 2 Jul 14, 2022
A PocketMine-MP plugin that allows you to comfortably register events using a new piece of PHP 8 power — attributes.

AdvancedEvents This is a PocketMine-MP plugin that allows you to comfortably register events using a new piece of PHP 8 power — attributes. Inspired b

JuraSciix 7 Dec 5, 2022
Creating data transfer objects with the power of php objects. No php attributes, no reflection api, and no other under the hook work.

Super Simple DTO Creating data transfer objects with the power of php objects. No php attributes, no reflection api, and no other under the hook work.

Mohammed Manssour 8 Jun 8, 2023
Fluent regular expressions in PHP

FLUX (Fluent Regex) 0.5.2 by Selvin Ortiz Description Fluent Regular Expressions in PHP inspired by and largely based on VerbalExpressions:JS by Jesse

Selvin Ortiz 341 Nov 20, 2022
Enable method chaining or fluent expressions for any value and method.

PHP Pipe Operator A (hopefully) temporary solution to implement the pipe operator in PHP. Table of contents Requirements How to install How to use The

Sebastiaan Luca 268 Dec 26, 2022
Create executable strings using a fluent API.

command-builder A PHP class to build executable with using fluent API. Summary About Features Installation Examples Compatibility table Tests About I

Khalyomede 2 Jan 26, 2022
A simple, standalone, modern PHP class inspector and mapper library, wrapping PHPs native reflection in a fluent interface

A simple, standalone, modern PHP class inspector and mapper library, wrapping PHPs native reflection in a fluent interface.

smpl 9 Sep 1, 2022
A fluent interface for interacting with Netopia's services.

laravel-netopia A fluent interface for interacting with Netopia's services. Info Database It'll create a table named netopia_payments with the followi

Codestage 3 Oct 10, 2022
Laravel Blog Package. Easiest way to add a blog to your Laravel website. A package which adds wordpress functionality to your website and is compatible with laravel 8.

Laravel Blog Have you worked with Wordpress? Developers call this package wordpress-like laravel blog. Give our package a Star to support us ⭐ ?? Inst

Binshops 279 Dec 28, 2022
This package was created to provide simple way to manipulate arrays in PHP

PHP Collections This package was created to provide simple way to manipulate arrays in PHP. The package was inspired by the Laravel Collections.

Wojciech Mleczek 13 Jul 26, 2021