Download the PHP package baril/smoothie without Composer

On this page you can find all versions of the php package baril/smoothie. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package smoothie

Smoothie

Some fruity additions to Laravel's Eloquent:

:warning: Note: only MySQL is tested and actively supported.

Miscellaneous

Save model and restore modified attributes

This package adds a new option restore to the save method:

This forces the model to refresh its original array of attributes from the database before saving. It's useful when your database row has changed outside the current $model instance, and you need to make sure that the $model's current state will be saved exactly, even restoring attributes that haven't changed in the current instance:

To use this option, you need your model to extend the Baril\Smoothie\Model class instead of Illuminate\Database\Eloquent\Model.

Update only

Laravel's native update method will not only update the provided fields, but also whatever properties of the model were previously modified:

This package provides another method called updateOnly, that will update the provided fields but leave the rest of the row alone:

To use this method, you need your model to extend the Baril\Smoothie\Model class instead of Illuminate\Database\Eloquent\Model.

Explicitly order the query results

The package adds the following method to Eloquent collections:

It allows for explicit ordering of collections by primary key. In the above example, the returned collection will contain (in this order):

Similarly, using the findInOrder method on models or query builders, instead of findMany, will preserve the order of the provided ids:

In order to use these methods, you need Smoothie's service provider to be registered in your config\app.php (or use package auto-discovery):

Timestamp scopes

The Baril\Smoothie\Concerns\ScopesTimestamps trait provides some scopes for models with created_at and updated_at columns:

Cross-database relations

With Laravel, it's possible to declare relations between models that don't belong to the same connection, but it will fail in some cases:

This package provides a crossDatabase method that will solve this problem by prepending the table name with the database name. Of course, it works only if all databases are on the same server.

The usage is:

For a many-to-many relation, you can specify whether the pivot table is in the same database as the parent table or the related table. In the example below, the pivot table is in the same database as the posts table:

Debugging

This package adds a debugSql method to the Builder class. It is similar as toSql except that it returns an actual SQL query where bindings have been replaced with their values.

In order to use this method, you need Smoothie's service provider to be registered in your config\app.php (or use package auto-discovery).

(Credit for this method goes to Broutard, thanks!)

Field aliases

Basic usage

The Baril\Smoothie\Concerns\AliasesAttributes trait provides an easy way to normalize the attributes names of a model if you're working with an existing database with column namings you don't like.

There are 2 different ways to define aliases:

Let's say you're working with the following table (this example comes from the blog application Dotclear):

Then you could define your model as follows:

Now the blog_id column can be simply accessed this way: $model->id. Same goes for all other columns prefixed with blog_.

Also, the blog_desc column can be accessed with the more explicit alias description.

The original namings are still available. This means that there are actually 3 different ways to access the blog_desc column:

Note: you can't have an alias (explicit or implicit) for another alias. Aliases are for actual column names only.

Collisions and priorities

If an alias collides with a real column name, it will have priority over it. This means that in the example above, if the table had a column actually named desc or description, you wouldn't be able to access it any more. You still have the possibility to define another alias for the column though.

In the example above, the title attribute of the model returns the value of the meta_title column in the database. The value of the title column can be accessed with the original_title attribute.

Also, explicit aliases have priority over aliases implicitely defined by a column prefix. This means that when an "implicit alias" collides with a real column name, you can define an explicit alias that restores the original column name:

Here, the title attribute of the model will return the value of the title column of the database. The a_title column can be accessed with the a_title attribute (or you can define another alias for it).

Accessors, casts and mutators

You can define accessors either on the original attribute name, or the alias, or both.

The same logic applies to casts and mutators.

:warning: Note: if you define a cast on the alias and an accessor on the original attribute name, the accessor won't apply to the alias, only the cast will.

Trait conflict resolution

The AliasesAttributes trait overrides the getAttribute and setAttribute methods of Eloquent's Model class. If you're using this trait with another trait that override the same methods, you can just alias the other trait's methods to getUnaliasedAttribute and setUnaliasedAttribute. AliasesAttributes::getAttribute and AliasesAttributes::setAttribute will call getUnaliasedAttribute or setUnaliasedAttribute once the alias is resolved.

Accessor cache

Basic usage

Sometimes you define an accessor in your model that requires some computation time or executes some queries, and you don't want to go through the whole process everytime you call this accessor. That's why this package provides a trait that "caches" (in a protected property of the object) the results of the accessors.

You can define which accessors are cached using either the $cacheable property or the $uncacheable property. If none of them are set, then everything is cached.

Clearing cache

The cache for an attribute is cleared everytime this attribute is set. If you have an accessor for an attribute A that depends on another attribute B, you probably want to clear A's cache when B is set. You can use the $clearAccessorCache property to define such dependencies:

Cache and aliases

If you want to use both the AliasesAttributes trait and the CachesAccessors trait in the same model, the best way to do it is to use the AliasesAttributesWithCache trait, which merges the features of both traits properly. Setting an attribute or an alias will automatically clear the accessor cache for all aliases of the same attribute.

Fuzzy dates

The package provides a modified version of the Carbon class that can handle SQL "fuzzy" dates (where the day, or month and day, are zero).

With the original version of Carbon, such dates wouldn't be interpreted properly, for example 2010-10-00 would be interpreted as 2010-09-30.

With this version, zeros are allowed. An additional method is provided to determine if the date is fuzzy:

The format and formatLocalized methods now have two additional (optional) arguments $formatMonth and $formatYear. If the date is fuzzy, the method will automatically fallback to the appropriate format:

:warning: Note: because a fuzzy date can't convert to a timestamp, a date like 2010-10-00 is transformed to 2010-10-01 internally before conversion to timestamp. Thus, any method or getter that relies on the timestamp value might return an "unexpected" result:

If you need fuzzy dates in your models, use the Baril\Smoothie\Concerns\HasFuzzyDates trait. Then, fields cast as date or datetime will use this modified version of Carbon:

Alternatively, you can extend the Baril\Smoothie\Model class to achieve the same result. This class already uses the HasFuzzyDates trait (as well as some other traits described in the subsequent sections):

:warning: Note: you will need to disable MySQL strict mode in your database.php config file in order to use fuzzy dates:

If you don't want to disable strict mode, another option is to use 3 separate columns and merge them into one. To achieve this easily, you can use the mergeDate method in the accessor, and the splitDate method is the mutator:

The last 2 arguments of both methods can be omitted, if your column names use the suffixes _year, _month and _day. The following example is similar as the one above:

:warning: Note: your _month and _day columns must be nullable, since a "zero" month or day will be stored as null.

Mutually-belongs-to-many-selves relationship

Usage

This new type of relationship defines a many-to-many, mutual relationship to the same table/model. Laravel's native BelongsToMany relationship can already handle self-referencing relationships, but with a direction (for example sellers/buyers). The difference is that the MutuallyBelongsToManySelves relationship is meant to handle "mutual" relationships (such as friends):

With this type of relationship, attaching $user1 to $users2's friends will implicitely attach $user2 to $user1's friends as well:

Similarly, detaching one side of the relation will detach the other as well:

The full prototype for the mutuallyBelongsToManySelves method is similar to belongsToMany, without the first argument (which we don't need since we already know that the related class is the class itself):

In order to use the mutuallyBelongsToManySelves method, your model needs to either use the Baril\Smoothie\Concerns\HasMutualSelfRelationships, or extend the Baril\Smoothie\Model class.

Cleanup command

In order to avoid duplicates, the MutuallyBelongsToManySelves class will ensure that attaching $model1 to $model2 will insert the same pivot row as attaching $model2 to $model1: the key defined as the first pivot key of the relationship will always receive the smaller id. In case you're working with pre-existing data, and you're not sure that the content of your pivot table follows this rule, you can use the following Artisan command that will check the data and fix it if needed:

N-ary many-to-many relationships

Let's say that you're building a project management app. Each user of your app has many roles in your ACL system: projet manager, developer... But each role applies to a specific project rather than the whole app.

Your basic database structure probably looks something like this:

Of course, you could define classic belongsToMany relations between your models, and even add a withPivot clause to include the 3rd pivot column:

It won't be very satisfactory though, because:

That's where the belongsToMultiMany relation comes in handy.

Setup

Step 1: add a primary key to your pivot table.

Step 2: have your model use the Baril\Smoothie\Concerns\HasMultiManyRelationships trait (or extend the Baril\Smoothie\Model class).

Step 3: define your relations with belongsToMultiMany instead of belongsToMany. The prototype for both methods is the same except that:

You can do the same in all 3 classes, which means you will declare 6 different relations. Note that:

Also, notice that the definition of the relations are independant: there's nothing here that says that projects and roles are related to one another. The magic will happen only because they're defined as "multi-many" relationships and because they're using the same pivot table.

Querying the relations

Overall, multi-many relations behave exactly like many-to-many relations. There are 2 differences though.

The first difference is that multi-many relations will return "folded" (ie. deduplicated) results. For example, if $user has the role admin in 2 different projects, $user->roles will return admin only once (contrary to a regular BelongsToMany relation). Should you need to fetch the "unfolded" results, you can just chain the unfolded() method:

The 2nd (and most important) difference is that when you "chain" 2 (or more) "sibling" multi-many relations, the result returned by each relation will be automatically constrained by the previously chained relation(s).

Check the following example:

Here, a regular BelongsToMany relation would have returned all roles related to the project, whether they're attached to this $user or another one. But with multi-many relations, $roles contains only the roles of $user in this project.

If you ever need to, you can always cancel this behavior by chaining the all() method:

Now $roles contains all the roles for $project, whether they come from this $user or any other one.

Another way to use the multi-many relation is as follows:

This will return only the roles that $user has on $project. It's a nicer way to write the following:

The arguments for the for method are:

Eager-loading

The behavior described above works with eager loading too:

Similarly as the all() method described above, you can use withAll if you don't want to constrain the 2nd relation:

Note: for non multi-many relations, or "unconstrained" multi-many relations, withAll is just an alias of with:

Querying relationship existence

Querying the existence of a relation will also have the same behavior:

The query above will return the users who have a role in any project.

Attaching / detaching related models

Attaching models to a multi-many relation will fill the pivot values for all the previously chained "sibling" multi-many relations

Detaching models from a relation will also take into account all the "relation chain":

Again, the behavior described above can be disabled by chaining the all() method:

Multi-many relations "wrapper"

The WrapMultiMany relation provides an alternative way to handle multi-many relations. It can be used together with the BelongsToMultiMany relations or independantly.

Instead of looking at the ternary relation as six many-to-many relations that can be chained after another, we could look at it this way:

Of course, similarly, a role has many user/project pairs and a project has many role/user pairs.

To implement this, we could create a model for the pivot table and then define all relations manually, but the WrapMultiMany relation provides a quicker alternative.

The authorizations method above defines the following relations:

You can query the relations like any regular relation, and even eager-load them:

You can use the following methods to insert or update data in the pivot table:

The $pivots argument can be of different types:

Dynamic relationships

The Baril\Smoothie\Concerns\HasDynamicRelations trait gives you the ability to define new relations on your model on-the-fly.

These relations can be defined either "globally" (for all instances of the class), or locally (for a specific instance).

First, use the HasDynamicRelations trait on your model:

You can now define your relations by calling the defineRelation method, either statically or on an instance:

In both cases, once the relation has been defined, you can use it like any Eloquent relation:

Orderable behavior

Adds orderable behavior to Eloquent models (forked from https://github.com/boxfrommars/rutorika-sortable).

Setup

First, add a position field to your model (see below how to change this name):

Then, use the \Baril\Smoothie\Concerns\Orderable trait in your model. The position field should be guarded as it won't be filled manually.

You need to set the $orderColumn property if you want another name than position:

Basic usage

You can use the following method to change the model's position (no need to save it afterwards, the method does it already):

Also, this trait:

This model will be positioned at MAX(position) + 1.

To get ordered models, use the ordered scope:

(You can cancel the effect of this scope by calling the unordered scope.)

Previous and next models can be queried using the previous and next methods:

Mass reordering

The move* methods described above are not appropriate for mass reordering because:

Example:

The sample code above will corrupt the data because you need each model to be "fresh" before you change its position. The following code, on the other hand, will work properly:

It's still not a good way to do it though, because it performs many unneeded queries. A better way to handle mass reordering is to use the saveOrder method on a collection:

That's it! Now the items' order in the collection has been applied to the position column of the database.

To define the order explicitely, you can do something like this:

Note: Only the models within the collection are reordered / swapped between one another. The other rows in the table remain untouched.

Orderable groups / one-to-many relationships

Sometimes, the table's data is "grouped" by some column, and you need to order each group individually instead of having a global order. To achieve this, you just need to set the $groupColumn property:

If the group is defined by multiple columns, you can use an array:

Orderable groups can be used to handle ordered one-to-many relationships:

Ordered many-to-many relationships

If you need to order a many-to-many relationship, you will need a position column (or some other name) in the pivot table.

Have your model use the \Baril\Smoothie\Concerns\HasOrderedRelationships trait (or extend the Baril\Smoothie\Model class):

The prototype of the belongsToManyOrdered method is similar as belongsToMany with an added 2nd parameter $orderColumn:

Now all the usual methods from the BelongsToMany class will set the proper position to attached models:

When queried, the relation is sorted by default. If you want to order the related models by some other field, you will need to use the unordered scope first:

Of course, you can also define the relation like this if you don't want it ordered by default:

The BelongsToManyOrdered class has all the same methods as the Orderable trait, except that you will need to pass them a related $model to work with:

Note that if $model doesn't belong to the relationship, any of these methods will throw a Baril\Smoothie\GroupException.

There's also a method for mass reordering:

In the example above, tags with ids $id1, $id2, $id3 will now be at the beginning of the article's tags collection. Any other tags attached to the article will come after, in the same order as before calling setOrder.

Ordered morph-to-many relationships

Similarly, the package defines a MorphToManyOrdered type of relationship. The 3rd parameter of the morphToManyOrdered method is the name of the order column (defaults to position):

Same thing with the morphedByManyOrdered method:

Tree-like structures and closure tables

This is an implementation of the "Closure Table" design pattern for Laravel and SQL. This pattern allows for faster querying of tree-like structures stored in a relational database.

Setup

You will need to create a closure table in your database. For example, if your main table is tags, you will need a closure table named tag_tree (you can change this name if you want -- see below), with the following columns:

Of course, you don't need to write the migration manually: the package provides an Artisan command for that (see below).

Also, your main table will need a parent_id column with a self-referencing foreign key (you can change this name too -- see below). This column is the one that holds the actual hierarchical data: the closures are merely a duplication of that information.

Once your database is ready, have your model implement the Baril\Smoothie\Concerns\BelongsToTree trait.

You can use the following properties to configure the table and column names:

Artisan commands

Note: you need to configure your model as described above before you use these commands.

The grow-tree command will generate the migration file for the closure table:

If you use the --migrate option, then the command will also run the migration. If your main table already contains data, it will also insert the closures for the existing data.

:warning: Note: if you use the --migrate option, any other pending migrations will run too.

There are some additional options: use --help to learn more.

If you ever need to re-calculate the closures, you can use the following command:

It will truncate the table and fill it again based on the data from the main table.

Finally, the show-tree command provides a quick-and-easy way to output the content of the tree. It takes a label parameter that defines which column (or accessor) to use as label. Optionally you can also specify a max depth.

Basic usage

Just fill the model's parent_id and save the model: the closure table will be updated accordingly.

The save method will throw a \Baril\Smoothie\TreeException in case of a redundancy error (ie. if the parent_id corresponds to the model itself or one of its descendants).

When you delete a model, its closures will be automatically deleted. If the model has descendants, the delete method will throw a TreeException. You need to use the deleteTree method if you want to delete the model and all its descendants.

Relationships

The trait defines the following relationships (which can't be renamed for now):

:warning: Note: The ancestors and descendants (and -WithSelf) relations are read-only! Trying to use the attach or detach method on them will throw an exception.

The ancestors and descendants relations can be ordered by depth (ie. with the direct parent/children first):

Loading or eager-loading the descendants relation will automatically load the children relation (with no additional query). Furthermore, it will load the children relation recursively for all the eager-loaded descendants:

Of course, same goes with the ancestors and parent relations.

You can retrieve the whole tree with this method:

It will return a collection of the root elements, with the children relation eager-loaded on every element up to the leafs.

Methods

The trait defines the following methods:

Query scopes

Ordered tree

In case you need each level of the tree to be explicitely ordered, you can use the Baril\Smoothie\Concerns\BelongsToOrderedTree trait (instead of BelongsToTree).

You will need a position column in your main table (the name of the column can be configured with the $orderColumn property).

The children relation will now be ordered. In case you need to order it by some other field (or don't need the children ordered at all), you can use the unordered scope:

Also, all methods defined by the Orderable trait described above will now be available:

Cacheable behavior

This package provides a Cacheable trait for models. This is not a per-item or per-query cache but rather a caching system that will store the whole table contents as a collection. Thus, it's to be used with small tables that store referential data that won't change very often (such as a list of countries or statuses).

Basic principles

The basic principles are:

Setup

Just use the Cacheable trait on your model class. Optionally, you can specify which cache driver to use with the $cache property:

Of course $cache must reference a cache store defined in the cache.php config file.

If you need a finer customization of the cache store (such as setting tags), you can do so by overriding the getCache method:

By default, what will be stored in the cache is the return of Model::all(), but it can be customized by overriding the loadFromDatabase method, for example if you need to load relations:

Now the countries will be stored in the cache with their languages relation loaded.

Caching queries

Caching specific queries is possible but only for very simple queries (see below). In order to enable cache on a query, you need to chain the usingCache method to the builder:

When the get method is called, the following occurs:

  1. The collection with the whole table contents is fetched from the cache (or from the database and stored in the cache if it was previously empty).
  2. All where and orderBy clauses of the query are applied to the collection (using the where and sortBy methods).
  3. The filtered and sorted collection is returned.

Step 2 will work only on the following conditions:

:warning: If you use untranslatable clauses and still enable cache, no exception will be thrown, but the clauses will be ignored and the query will return unexpected results.

Cached relations

Since Laravel relations behave like query builders, they can use cache too. Of course, the related model needs to use the Cacheable trait.

Now the country relation will always use cache when queried, unless you disable it explicitely:

BelongsToMany (and BelongsToMultiMany) relations can use cache too, but:


All versions of smoothie with dependencies

PHP Build Version
Package Version
Requires php Version >=7.0
illuminate/database Version ~5.6
illuminate/support Version ~5.6
illuminate/cache Version ~5.6
illuminate/console Version ~5.6
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package baril/smoothie contains the following files

Loading the files please wait ....