Coder Social home page Coder Social logo

cybercog / laravel-ownership Goto Github PK

View Code? Open in Web Editor NEW
89.0 5.0 16.0 154 KB

Laravel Ownership simplify management of Eloquent model's owner.

Home Page: https://komarev.com/sources/laravel-ownership

License: MIT License

PHP 98.04% Dockerfile 1.96%
laravel trait ownership owner author owned ownable eloquent creator proprietor cog polymorphic package ownable-models polymorphism

laravel-ownership's Introduction

cog-laravel-ownership

Discord Build StyleCI Releases License

Introduction

Laravel Ownership simplify management of Eloquent model's owner. Group can be an owner of event, user can be an owner of chat room, organization can own licenses. It can be used for many cases not limited by authorship. Make any model as owner and create ownable models in a minutes!

Contents

Features

  • Designed to work with Laravel Eloquent models
  • Using contracts to keep high customization capabilities
  • Each model can has owners of one type or use polymorphism
  • Option to auto-assigning current authenticated user on model creation as owner
  • Configurable auto-owner resolve strategy on model creation
  • Option to manually assign owner on model creation
  • Option to manually skip auto-assigning current user
  • Transfer ownership (change owner)
  • Make model orphaned (abandon owner)
  • Various ownership checks and query scopes
  • Following PHP Standard Recommendations:
  • Covered with unit tests

Installation

First, pull in the package through Composer.

composer require cybercog/laravel-ownership

Register Package Manually (optional)

If you disabled package auto-discovery you can register it manually.

Include the service provider within app/config/app.php.

'providers' => [
    Cog\Laravel\Ownership\Providers\OwnershipServiceProvider::class,
];

Usage

Laravel Ownership allows model to have strict owner model type (HasOwner trait) or use polymorphic relation (HasMorphOwner trait).

Strict ownership is useful when model can belong to only one model type. Attempt to set owner of not defined model type will throw an exception InvalidOwnerType. Example: Only users allowed to create posts.

Polymorphic ownership is useful when model can belong to owners of different types. Example: Users and Organizations can upload applications to marketplace.

Prepare owner model

At the owner model use CanBeOwner contract and implement it:

use Cog\Contracts\Ownership\CanBeOwner as CanBeOwnerInterface;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements CanBeOwnerInterface
{
    // ...
}

Prepare ownable model with strict ownership

Use Ownable contract in model which will get ownership behavior and implement it or just use HasOwner trait.

use Cog\Contracts\Ownership\Ownable as OwnableInterface;
use Cog\Laravel\Ownership\Traits\HasOwner;
use Illuminate\Database\Eloquent\Model;

class Article extends Model implements OwnableInterface
{
    use HasOwner;
}

Ownable model with strict ownership must have in database additional nullable column to store owner relation:

Schema::table('articles', function (Blueprint $table) {
    $table->integer('owned_by_id')->unsigned()->nullable();

    $table->index('owned_by_id');
});

Overwrite strict ownership owner's foreign key

By default, owner model will be the same as config('auth.providers.users.model') provides.

To override default owner model in strict ownership, it's primary key or foreign key extend your ownable model with additional attributes:

use Cog\Contracts\Ownership\Ownable as OwnableInterface;
use Cog\Laravel\Ownership\Traits\HasOwner;
use Illuminate\Database\Eloquent\Model;

class Article extends Model implements OwnableInterface
{
    use HasOwner;

    protected $ownerModel = Group::class;
    protected $ownerPrimaryKey = 'gid';
    protected $ownerForeignKey = 'group_id';
}

Prepare ownable model with polymorphic ownership

Use Ownable contract in model which will get polymorphic ownership behavior and implement it or just use HasMorphOwner trait.

use Cog\Contracts\Ownership\Ownable as OwnableInterface;
use Cog\Laravel\Ownership\Traits\HasMorphOwner;
use Illuminate\Database\Eloquent\Model;

class Article extends Model implements OwnableInterface
{
    use HasMorphOwner;
}

Ownable model with polymorphic ownership must have in database additional nullable columns to store owner relation:

Schema::table('articles', function (Blueprint $table) {
    $table->nullableMorphs('owned_by');
});

Available methods

Get owner relation

$article->ownedBy();
$article->owner();

Get model owner

$article->getOwner();
$article->ownedBy;
$article->owner;

Change (set) owner

$article->changeOwnerTo($owner);

Abandon (unset) owner

$article->abandonOwner();

Check if has owner

$article->hasOwner();

Check if owned by owner

$article->isOwnedBy($owner);

Check not owned by owner

$article->isNotOwnedBy($owner);

Manually define default owner on model creation

$article = new Article;
$article->withDefaultOwner()->save();

Will use resolveDefaultOwner() method under the hood.

Or provide concrete owner:

$user = User::where('name', 'admin')->first();
$article = new Article;
$article->withDefaultOwner($user)->save();

Skip defining default owner on model creation

$article = new Article;
$article->withoutDefaultOwner()->save();

Scopes

Scope models by owner

Article::whereOwnedBy($owner)->get();

Scope models by not owned by owner

Article::whereNotOwnedBy($owner)->get();

Set authenticated user as owner automatically

To set currently authenticated user as owner for ownable model create - extend it with attribute withDefaultOwnerOnCreate. It works for both strict and polymorphic ownership behavior.

use Cog\Contracts\Ownership\Ownable as OwnableInterface;
use Cog\Laravel\Ownership\Traits\HasOwner;
use Illuminate\Database\Eloquent\Model;

class Article extends Model implements OwnableInterface
{
    use HasOwner;

    protected $withDefaultOwnerOnCreate = true;
}

To override strategy of getting default owner extend ownable model with resolveDefaultOwner method:

use Cog\Contracts\Ownership\Ownable as OwnableInterface;
use Cog\Laravel\Ownership\Traits\HasOwner;
use Illuminate\Database\Eloquent\Model;

class Article extends Model implements OwnableInterface
{
    use HasOwner;

    public $withDefaultOwnerOnCreate = true;

    /**
     * Resolve entity default owner.
     * 
     * @return \Cog\Contracts\Ownership\CanBeOwner|null
     */
    public function resolveDefaultOwner()
    {
        return \App\User::where('name', 'admin')->first();
    }
}

Changelog

Please see CHANGELOG for more information on what has changed recently.

Upgrading

Please see UPGRADING for detailed upgrade instructions.

Contributing

Please see CONTRIBUTING for details.

Testing

Run the tests with:

vendor/bin/phpunit

Security

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

Credits

@antonkomarev
Anton Komarev
@soap
Prasit Gebsaap

Laravel Ownership contributors list

Alternatives

Feel free to add more alternatives as Pull Request.

License

About CyberCog

CyberCog is a Social Unity of enthusiasts. Research the best solutions in product & software development is our passion.

CyberCog

laravel-ownership's People

Contributors

antonkomarev avatar dionysiosarvanitis avatar joshuadoshua avatar soap avatar wilburjzhao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

laravel-ownership's Issues

Total refactoring

This package requires total refactoring before adding new Laravel versions support and new features.

Behavior with softDeletes

So, if anyone have similar issues, plz tell me.

My models are:

User implements CanBeOwner contract
Profile use HasOwner trait

Both use SoftCascadeTrait

// in User model 
public function profile(): HasOne
{
    // using withTrashed() here
    return $this->hasOne(Profile::class, 'owned_by_id')->withTrashed();
}

But for Profile model, I don't set this association cause it's already handled by the trait.

The problem is, when fetching Profile content, I need to configure it everytime using ->with().

$profiles = Profile::withTrashed()->with(['owner' => function ($query) {
    $query->withTrashed(); // not filtering trashed owners
}])->get();

I just wanna to simplify, call it directly and stay not filtering trashed records. Any thoughts?

Ownership change events

Require to add events:

  • \Cog\Ownership\Events\OwnershipWasChanged
  • \Cog\Ownership\Events\OwnershipWasAbandoned

What to check:

  • Both of this events shouldn't been fired on model create.
  • Maybe additional methods like changeOwnerTo and abandonOwner would be required.

Middleware

Could you make route middleware for ownership checking ?

OwnedOrFail

Could you add method(s) throwing exception when not owner ?

OwnedByDefaultUser

Could you add method for checking if model if owned by currently authorized user ?

Overwrite owner on create

$owner = NotUserModel::first();
OwnableModel::withDefaultOwner($owner)->create([
    'title' => 'Test title',
]);
OwnableModel::create([
    'title' => 'Test title',
])->withDefaultOwner($owner);

Both of this variants wouldn't work.

To set owners on creation this variants could be used:

$owner = NotUserModel::first();
$model = OwnableModel::create([
    'title' => 'Test title',
]);
$model->withDefaultOwner($owner);
$model->save();
$owner = NotUserModel::first();
$model = (new OwnableModel([
    'title' => 'Test title',
]))->withDefaultOwner($owner)->save();

The Model Owner Wont Link Up With The Owned Model

I Get Error Saying

{ "message": "Type error: Argument 1 passed to App\\Brand::changeOwnerTo() must be an instance of Cog\\Contracts\\Ownership\\CanBeOwner, instance of App\\User given, called in C:\\xampp\\htdocs\\real\\haayaa\\app\\Http\\Controllers\\Auth\\RegisterController.php on line 142", "exception": "Symfony\\Component\\Debug\\Exception\\FatalThrowableError", "file": "C:\\xampp\\htdocs\\real\\haayaa\\vendor\\cybercog\\laravel-ownership\\src\\Traits\\HasMorphOwner.php", "line": 139, "trace": }

Laravel ban triggers errors on composer install.

A time ago. I created a pr for support Laravel ban on 5.5-dev.

REF: cybercog/laravel-ban#8

But now it triggers errors. So here is the stacktrace.

```laravel/framework 5.5.x-dev - don't install illuminate/database v5.4.19|don't install laravel/framework 5.5.x-dev - don't install illuminate/database v5.4.9|don't install laravel/framework 5.5.x-dev - Installation request for laravel/framework 5.5.* -> satisfiable by laravel/framework[5.5.x-de v].

PS C:\Users\Gebruiker\Desktop\petition> composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

Problem 1
- Installation request for cybercog/laravel-ban dev-laravel-5.5 -> satisfiable by cybercog/lara
vel-ban[dev-laravel-5.5].
- cybercog/laravel-ban dev-laravel-5.5 requires cybercog/laravel-ownership ^3.0 -> satisfiable
by cybercog/laravel-ownership[3.0.0].
- Conclusion: remove laravel/framework 5.5.x-dev
- cybercog/laravel-ownership 3.0.0 requires illuminate/database ~5.2.0|~5.3.0|~5.4.0 -> satisfi
able by illuminate/database[5.2.x-dev, 5.3.x-dev, 5.4.x-dev, v5.2.0, v5.2.19, v5.2.21, v5.2.24, v5.
2.25, v5.2.26, v5.2.27, v5.2.28, v5.2.31, v5.2.32, v5.2.37, v5.2.43, v5.2.45, v5.2.6, v5.2.7, v5.3.
0, v5.3.16, v5.3.23, v5.3.4, v5.4.0, v5.4.13, v5.4.17, v5.4.19, v5.4.9].
- don't install illuminate/database 5.2.x-dev|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database 5.3.x-dev|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database 5.4.x-dev|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.0|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.19|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.21|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.24|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.25|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.26|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.27|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.28|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.31|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.32|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.37|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.43|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.45|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.6|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.2.7|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.3.0|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.3.16|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.3.23|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.3.4|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.4.0|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.4.13|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.4.17|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.4.19|don't install laravel/framework 5.5.x-dev
- don't install illuminate/database v5.4.9|don't install laravel/framework 5.5.x-dev
- Installation request for laravel/framework 5.5.* -> satisfiable by laravel/framework[5.5.x-dev].```

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.