Download the PHP package dashworthy/foundry without Composer

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

Packagist PHP from Packagist Laravel versions GitHub Workflow Status (0.x) Total Downloads

Single-argument actions and queries with reusable preconditions and owned transactions for Laravel, plus domain-aware generators.

The four pieces

Foundry models a write as an Action and a read as a Query. Each takes exactly one Data object and is gated by the same reusable Precondition pipes. The base classes own the plumbing: an Action runs handle() inside a database transaction and calls rollback() on failure; a Query runs the builder handle() returns and hands back a Collection.

Piece Namespace Shape
Data Dashworthy\Foundry\Data abstract readonly class Data — the one argument every unit takes
Precondition Dashworthy\Foundry\Preconditions interface with handle(Data $data, Closure $next): mixed
Action Dashworthy\Foundry\Actions abstract class Action — write side, owns the transaction
Query Dashworthy\Foundry\Queries abstract class Query — read side, no transaction

Installation

You can install the package via Composer:

Usage

Defining data

Every unit takes a single argument: a final readonly class extending Data. Data is a readonly base, so a subclass is readonly too.

Defining an action

Extend Action, list preconditions cheapest/most-restrictive first, and implement handle(). handle() runs inside a database transaction by default.

handle() takes your own {Name}Data, not the Data base. Action gets that by declaring handle() as a @method annotation rather than a real abstract method: PHP forbids narrowing a parameter type in an override, so a real abstract protected function handle(Data $data) would fatal any subclass that named its actual data class. The trade is that an action which never declares handle() fails on its first execute() rather than at class-declaration time — worth asserting in an architecture test over your own units:

PHPStan reads the action's return type from the second @extends Action<{Name}Data, …> argument, not from the handle() signature — keep the two in step.

Preconditions

A precondition is one rule checked before an Action or a Query runs, and the same rule can gate both sides. It implements Precondition and runs as a pipe in a Laravel Illuminate\Pipeline\Pipeline — the same chain-of-responsibility convention Laravel's own HTTP middleware uses. handle() receives the Data and the next pipe: call $next($data) to let the chain continue, or throw to refuse. The exception is whatever the application wants — this package doesn't ship one and doesn't wrap it.

Because a precondition is shared across the write and read sides, it types on the base Data and narrows inside — with an instanceof, or against a contract your application layers onto its own Data classes.

preconditions() returns a list of pipe instances, or class-strings the Pipeline resolves from the container:

Running an action

Resolve the unit from the container with make() (or run() for make() + execute() in one call). Prefer these to new so a bound decorator or fake is honoured.

execute() always does the same two things, in order, with no way for a subclass to reorder them: assert preconditions, then run handle() inside a transaction. Preconditions run in declaration order and the chain stops at the first that throws — whatever exception it throws propagates unchanged, before handle() ever runs.

The package does not dispatch events for you. If a side effect must not fire until the work commits, use Laravel's own tools: ShouldQueueAfterCommit on the notification or job, or a DB::afterCommit() call from inside handle().

To ask whether an action would be allowed — for deciding whether a control renders — without running it:

permits() runs the precondition chain and returns false if anything throws, true otherwise. It never runs handle().

Defining and running a query

A Query is the read-side twin of an Action: same make()/run()/permits()/fake() helpers and the same precondition pipeline, minus the transaction. handle() builds the read and returns the Eloquent builder; the base asserts the preconditions, runs ->get(), and returns the rows. A concrete query never runs the builder itself.

Keep the query about which rows: shaping them into whatever a page, export, or API needs is the caller's job.

Handling refusals

There is nothing to configure. A precondition throws whatever exception the application defines — a domain exception, a Laravel AuthorizationException, anything — and assert()/execute()/get()/permits() never touch it beyond letting it propagate (or, for permits(), catching it to answer false). Catch it wherever that decision belongs — typically the app's own exception handler:

Rolling back on failure

The transaction already undoes any database writes when handle() throws. It cannot undo anything else handle() did — an external charge, a third-party API call. Override rollback() for that:

rollback() takes no arguments — unlike handle() it has a body to override, so narrowing a data type on it is the thing PHP forbids. Capture whatever the rollback needs, the data included, as an instance property during handle().

rollback() runs only when handle() throws — never for a refused precondition, since nothing has happened yet to undo. If rollback() itself throws, that's reported and swallowed; the exception that caused the rollback is always what propagates.

Deliberate opt-outs

Both live on the call, not the class, and both should be rare.

Calling a unit from inside a transaction

Nesting execute() inside a caller-managed transaction is supported — a plain DB::transaction(), another action's handle(), whatever:

The action's own DB::transaction() call becomes a savepoint inside the caller's, exactly as you'd expect. execute() doesn't need to own the outermost transaction, so there's no guard here and nothing to restructure the caller around.

Generators

make:action and make:query scaffold the matching {Name}Data and wire it into the @extends annotation. Use make:data alone only when a Data class must exist without a matching unit. All the generators are domain-aware: pass --domain / --subdomain to place files under app/Domains/…, and they layer the same placement onto Laravel's own make:* generators.

Folder placement is driven by config/foundry.php. Publish it to customise the domain base directory and per-type subdirectories:

Changelog

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

Contributing

Thank you for considering contributing to Foundry! Please review our contributing guide to get started.

Credits

License

Foundry is open-sourced software licensed under the MIT license.


All versions of foundry with dependencies

PHP Build Version
Package Version
Requires php Version ^8.4
illuminate/console Version ^12.0||^13.0
illuminate/contracts Version ^12.0||^13.0
illuminate/database Version ^12.0||^13.0
illuminate/pipeline Version ^12.0||^13.0
illuminate/support Version ^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 dashworthy/foundry contains the following files

Loading the files please wait ...