Download the PHP package firevel/includes without Composer

On this page you can find all versions of the php package firevel/includes. 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 includes

Laravel Includes

A standalone query-string include parser for Eloquent (JSON:API-style relationship loading). It turns an include request parameter into an array ready for Eloquent's with(), routing per-relationship parameters into a constraint closure you supply.

It's just a parser — it has no opinion about authorization, filtering, or your models. Drop it into any Laravel app.

Requires PHP 8.1+ and Laravel 10–13 (illuminate/support + illuminate/database).

What it does

The parser turns the string into relationship paths plus arbitrary key/value parameters, then hands each path's parameters to your closure, which returns the eager-load constraint for that relationship (or null to load it open). Filtering is the typical use of the parameters, but they can drive anything — sorting a relation, limiting it, selecting columns, etc. The package never inspects them.

Quick start

IncludesParser is bound in the container so app(IncludesParser::class) picks up your config. It holds per-request state, so each resolution is a fresh instance — never share one across requests. You can also just new it (see Using it without the container).

Model trait (recommended)

For the common case, add the HasIncludes trait to a model and it collapses into the query chain — no manual parser wiring, and the model is derived from the query itself:

The controller becomes a single chain:

If you don't want the trait, the underlying parser API is always available.

Composing with filter, sort and visibility

firevel/includes knows nothing about these scopes — your includeConstraints() (or generateWith() closure) wires them up. The closure receives the relation, so it can call whatever the related model supports. A convention-A router:

Things to know:

The contract

IncludesParser exposes four public methods:

Method Returns Purpose
parseIncludes(string\|array $include): self $this Parse and store the include parameter.
setAllowedIncludes(array $allowed): self $this Restrict accepted paths to an allowlist.
setModel(Model\|class-string $model): self $this Accept any path that is a real relationship on this model.
generateWith(Closure $factory): array with() array Build the eager-load array.

For each parsed include path the parser calls $factory($parameters), where $parameters are the parameters parsed for that path (an empty array if none). The factory returns either:

So one factory can constrain some relationships and leave others open.

Constraint closure patterns

The closure is yours — these are just patterns. The package requires none of them and references nothing in your models.

Apply parameters

A value may carry multiple comma-separated values, so a whereIn is the natural handling (a single value is just a one-element whereIn):

Load some relationships open

Return null to skip the constraint entirely for a given path:

Per-related-model policy (chain of constraint types)

The closure receives the Relation, so it can pick a different policy for each link of the chain based on the model being loaded there ($relationship->getRelated()). For ?include=property.rooms.facilities you might constrain rooms but leave the public facilities open:

If your models expose their own query scopes (e.g. a visibleBy() for authorization or a filter() scope), call them here too — that logic stays in your closure, never in this package:

A model can even decide for itself: have the closure delegate to a method on the related model ($related->constrainInclude($relationship, $parameters)), so each model owns its own include policy without a separate class.

MorphTo

The closure also receives polymorphic relations, so per-type constraints go through Eloquent's own MorphTo::constrain():

Grammar

The include parameter is a comma-separated list of relationship paths.

Comma-separated list

Dot notation for nesting

Nested paths are expanded into the multiple with() entries Eloquent needs, so each level can carry its own parameters. Ancestors are added automatically:

produces the keys comments, comments.replies, and comments.author.

Per-include parameters

Any segment may carry an optional, parenthesised group of pipe-separated key:value pairs:

A value may freely contain commas, which is the usual way to express multiple values (the caller splits them, e.g. into a whereIn):

comments{status: "active,pending", limit: "5"}.

Parameters attach to the relationship at their own level, so each level of a nested path carries its own:

comments{status: "published"}, comments.replies{limit: "5"}.

These parameters are passed through verbatim to your closure — the parser never interprets them. Treating them as filters is the common case, but they can mean anything you like.

Grammar rules and decisions

Where the grammar was ambiguous, the simplest defensible rule was chosen:

  1. Separators are positional. Commas separate paths at the top level, dots separate segments, pipes separate parameters — and all are ignored inside the value of a parameter. So a value may safely contain a . or a , (e.g. after:2020.01.01, status:active,pending).
  2. Parameter pairs split on the first colon only, so a value may contain colons (sort:created:desc{sort: "created:desc"}).
  3. Parameters are pipe-separated (|) inside the parentheses. A value may therefore contain commas — the usual multi-value convention — but cannot contain a pipe. Commas pass straight to firevel/sortable (sort:-created_at,name → two fields) and feed firevel/filterable's in operator (which explodes them into a whereIn); see Composing with filter, sort and visibility.
  4. A bare token with no colon is a boolean flag (comments(featured){featured: true}).
  5. Parameter values are returned as trimmed strings (no numeric/bool coercion, aside from the bare-flag case above). The caller casts as needed.
  6. Whitespace is trimmed around paths, segments, parameter keys and values.
  7. Empty segments are dropped: author,,commentsauthor,comments; comments..repliescomments.replies; comments()comments with no parameters; a trailing comma is ignored.
  8. Paths are deduped and their parameters merged, with the later occurrence winning on a key conflict.
  9. Relationship names pass through verbatim — they are not camelCased. The with() key matches what the client sent, so include=comment_replies yields the key comment_replies. If your relation methods are camelCase and you accept snake_case input, normalize it before parsing or in your closure.
  10. parseIncludes() also accepts an array of path strings; each element is parsed exactly as a comma-separated string would be.

Allowlist & limits

Requested paths are gated in this order of precedence:

  1. Max depth — always enforced.
  2. Allowlist — if one was set with setAllowedIncludes().
  3. Relationship existence — otherwise, if a model was set with setModel().
  4. With neither an allowlist nor a model, every (in-depth) path passes.

Allowlist

Gate input against a list of known paths:

The allowlist is matched against the full path the client requested (before expansion). Ancestors created by expanding an allowed nested path are implicitly permitted — allowing comments.replies also allows the comments key it expands into.

Validate against a model

When you have not set an allowlist, you can instead let the parser accept any path that resolves to a real Eloquent relationship on a model:

Each segment of a requested path must be a real relation on the model at that level of the chain — comments.replies requires Post::comments() to return a relation and the related Comment to define replies(). Unknown segments cause the whole path to be rejected (per on_disallowed).

Two caveats:

An allowlist takes precedence: if both are set, only the allowlist is consulted.

Max depth

The maximum nesting depth is enforced from config and counted in segments (comments.replies is depth 2). Paths deeper than max_depth are rejected.

Behaviour on rejection

The allowlist, the depth limit, and the relationship-existence check are all governed by on_disallowed:

Configuration

Publish the config file:

config/includes.php:

Both can also be set per-instance with setMaxDepth() and setOnDisallowed().

Using it without the container

The parser has no hard dependency on the container or config — construct it directly and parsing works the same:

The service provider only does two things: merge/publish the config and bind the parser with those config values applied.

Testing

License

MIT. See LICENSE.


All versions of includes with dependencies

PHP Build Version
Package Version
Requires php Version ^8.1
illuminate/support Version ^10.0 || ^11.0 || ^12.0 || ^13.0
illuminate/database Version ^10.0 || ^11.0 || ^12.0 || ^13.0
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 firevel/includes contains the following files

Loading the files please wait ...