Download the PHP package fuzz/magic-box without Composer
On this page you can find all versions of the php package fuzz/magic-box. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download fuzz/magic-box
More information about fuzz/magic-box
Files in fuzz/magic-box
Package magic-box
Short Description A magical implementation of Laravel's Eloquent models as injectable, masked resource repositories.
License MIT
Homepage https://fuzzproductions.com/
Informations about the package magic-box
Laravel Magic Box
⛔️ DEPRECATED ⛔️
This project is no longer supported or maintained. If you need a modern version of Magic Box that is compatible with newer versions of Laravel please consider using the spiritual successor to this project — Koala Pouch.
Magic Box modularizes Fuzz's magical implementation of Laravel's Eloquent models as injectable, masked resource repositories.
Magic Box has two goals:
- To create a two-way interchange format, so that the JSON representations of models broadcast by APIs can be re-applied back to their originating models for updating existing resources and creating new resources.
- Provide an interface for API clients to request exactly the data they want in the way they want.
Installation/Setup
composer require fuzz/magic-box
- Use or extend
Fuzz\MagicBox\Middleware\RepositoryMiddleware
into your project and register your class under the$routeMiddleware
array inapp/Http/Kernel.php
.RepositoryMiddleware
contains a variety of configuration options that can be overridden -
If you're using
fuzz/api-server
, you can use magical routing by updatingapp/Providers/RouteServiceProvider.php
,RouteServiceProvider@map
, to include: - Set up your MagicBox resource routes under the middleware key you assign to your chosen
RepositoryMiddleware
class - Set up a
YourAppNamespace\Http\Controllers\ResourceController
, here is what a ResourceController might look like . - Set up models according to
Model Setup
section
Testing
Just run phpunit
after you composer install
.
Eloquent Repository
Fuzz\MagicBox\EloquentRepository
implements a CRUD repository that cascades through relationships,
whether or not related models have been created yet.
Consider a simple model where a User has many Posts. EloquentRepository's basic usage is as follows:
Create a User with the username Steve who has a single Post with the title Stuff.
When $repository->save()
is invoked, a User will be created with the username "Steve", and a Post will
be created with the user_id
belonging to that User. The nonsensical "nonsense" property is simply
ignored, because it does not actually exist on the table storing Users.
By itself, EloquentRepository is a blunt weapon with no access controls that should be avoided in any public APIs. It will clobber every relationship it touches without prejudice. For example, the following is a BAD way to add a new Post for the user we just created.
This will delete poor Steve's first post—not the intended effect. The safe(r) way to append a Post would be either of the following:
Generally speaking, the latter is preferred and is less likely to explode in your face.
The public API methods that return models from a repository are:
create
read
update
delete
save
, which will either callcreate
orupdate
depending on the state of its inputfind
, which will find a model by IDfindOrFail
, which will find a model by ID or throw\Illuminate\Database\Eloquent\ModelNotFoundException
The public API methods that return an \Illuminate\Database\Eloquent\Collection
are:
all
Filtering
Fuzz\MagicBox\Filter
handles Eloquent Query Builder modifications based on filter values passed through the filters
parameter.
Tokens and usage:
Token | Description | Example |
---|---|---|
^ |
Field starts with | https://api.yourdomain.com/1.0/users?filters[name]=^John |
$ |
Field ends with | https://api.yourdomain.com/1.0/users?filters[name]=$Smith |
~ |
Field contains | https://api.yourdomain.com/1.0/users?filters[favorite_cheese]=~cheddar |
< |
Field is less than | https://api.yourdomain.com/1.0/users?filters[lifetime_value]=<50 |
> |
Field is greater than | https://api.yourdomain.com/1.0/users?filters[lifetime_value]=>50 |
>= |
Field is greater than or equals | https://api.yourdomain.com/1.0/users?filters[lifetime_value]=>=50 |
<= |
Field is less than or equals | https://api.yourdomain.com/1.0/users?filters[lifetime_value]=<=50 |
= |
Field is equal to | https://api.yourdomain.com/1.0/users?filters[username]==Specific%20Username |
!= |
Field is not equal to | https://api.yourdomain.com/1.0/users?filters[username]=!=common%20username |
[...] |
Field is one or more of | https://api.yourdomain.com/1.0/users?filters[id]=[1,5,10] |
![...] |
Field is not one of | https://api.yourdomain.com/1.0/users?filters[id]=![1,5,10] |
NULL |
Field is null | https://api.yourdomain.com/1.0/users?filters[address]=NULL |
NOT_NULL |
Field is not null | https://api.yourdomain.com/1.0/users?filters[email]=NOT_NULL |
Filtering relations
Assuming we have users and their related tables resembling the following structure:
We can filter by users' hobbies with users?filters[profile.hobbies.name]=^Cook
. Relationships can be of arbitrary
depth.
Filter conjuctions
We can use AND
and OR
statements to build filters such as users?filters[username]==Bobby&filters[or][username]==Johnny&filters[and][profile.favorite_cheese]==Gouda
. The PHP array that's built from this filter is:
and this filter can be read as select (users with username Bobby) OR (users with username Johnny who's profile.favorite_cheese attribute is Gouda)
.
Model Setup
Models need to implement Fuzz\MagicBox\Contracts\MagicBoxResource
before MagicBox will allow them to be exposed as a MagicBox resource. This is done so exposure is an explicit process and no more is exposed than is needed.
Models also need to define their own $fillable
array including attributes and relations that can be filled through this model. For example, if a User has many posts and has many comments but an API consumer should only be able to update comments through a user, the $fillable
array would look like:
MagicBox will only modify attributes/relations that are explicitly defined.
Resolving models
Magic Box is great and all, but we don't want to resolve model classes ourselves before we can instantiate a repository...
If you've configured a RESTful URI structure with pluralized resources (i.e. https://api.mydowmain.com/1.0/users
maps to the User model), you can use Fuzz\MagicBox\Utility\Modeler
to resolve a model class name from a route name.
Testing
phpunit
:)
TODO
- Route service provider should be pre-setup
- Support more relationships (esp. polymorphic relations) through cascading saves.
- Support paginating nested relations