Download the PHP package lava83/laravel-ddd without Composer

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

Laravel DDD

Latest Version on Packagist

Work in progress. The public API may still change between releases.

Foundational building blocks for Domain-Driven Design in Laravel. The package ships battle-tested base classes and contracts — Entities, Aggregates, Value Objects, Repositories, Entity ↔ Model Mappers and Domain Events — so your applications can focus on the domain instead of the plumbing.

It enforces a strict layer separation (Domain, Application, Infrastructure) and gives you optimistic locking, automatic domain-event dispatching on save, and a set of ready-made value objects out of the box.

Requirements

Installation

The service provider and the LaravelDdd facade are registered automatically through Laravel package discovery. There are no migrations to publish, and no configuration is required — you build your own domains on top of the provided base classes, as shown below. An optional config file tunes the make:aggregate scaffolder (see Scaffolding).

Quick start

The example models a single Article aggregate with a Title value object and persists it through a mapper and a repository. It is the smallest slice that still exercises every core building block: a value object, an aggregate, an Eloquent model, a mapper and a repository.

Suggested structure inside a consuming application:

1. Value objects

An identity and a small, self-validating value object. Both are immutable.

2. Aggregate

State changes go through updateAggregateRoot(), which tracks the change and bumps the version (and can record a domain event — see What else is in the box). Business rules live here, never in the application or infrastructure layer.

3. Eloquent model & migration

Extend the package Model — it provides a UUID primary key (via the HasUuids concern), version tracking, timestamp casts and a filtering layer. Point the model at its entity so toEntity() can resolve the mapper.

The id, version, created_at and updated_at columns are handled by the base model, so the migration only adds them plus your own fields:

4. Mapper

The mapper is the single translation point between the domain and the database. findOrCreateModelFillData() (from the base mapper) loads or creates the row and fills the shared columns (id, version, timestamps) for you.

5. Repository

Keep the contract in the domain layer and the Eloquent implementation in the infrastructure layer. The base Repository provides saveEntity() / deleteEntity(), the optimistic-locking check and automatic domain-event dispatching; you add the read methods your application needs.

6. Wire it up

Register the mapper with the resolver and bind the repository contract to its implementation. A dedicated service provider keeps this in one place.

Register the provider in bootstrap/providers.php:

7. Use it

Scaffolding

Rather than writing every class by hand (as the Quick start does), make:aggregate generates the building blocks for an aggregate in a bounded context: the identity value object, the aggregate root and the Eloquent model, and — optionally — a repository (contract plus Eloquent implementation) and an entity mapper.

Run it interactively and answer the prompts (aggregate name, bounded context, identity type, and whether to also create a repository and a mapper):

Or pass everything up front:

Options

In non-interactive contexts (e.g. CI) the prompts are skipped: arguments and options drive everything, the identity type defaults to uuid, and the repository and mapper are generated only when their flags are present.

What it generates

Always:

On request:

The generated files are skeletons: the model and mapper carry a name placeholder column, and the aggregate's validate() and the mapper's toModel() are left for you to complete. Existing files are reported as SKIPPED (exists) and left untouched unless you pass --force. After writing, the command prints the service-provider bindings to register — the mapper via entity_mapper_resolver()->registerMapper(...) and the repository via $this->app->bind(...) — and warns if the target root namespace isn't autoloaded yet.

Namespaces

Two keys in config/laravel-ddd.php decide where the classes land:

With the defaults, make:aggregate Order OrderProcessing --with-repository --with-entity-mapper writes:

Set bounded_contexts_without_own_layers to false and each context owns its layers instead — the context and layer segments swap, e.g. App\BoundedContexts\OrderProcessing\Domain\Aggregates\Order.

Target paths are resolved from your composer.json PSR-4 map; if the root namespace isn't mapped yet, the command prints the autoload entry to add and reminds you to run composer dump-autoload.

Publish the config to change these defaults:

What else is in the box

Beyond the slice above, the package provides an AggregateRoot contract with domain-event recording: events collected through updateAggregateRoot($changes, $eventClass) are dispatched automatically via Laravel's event system after a successful save(), then cleared from the aggregate. Every aggregate carries a version for optimistic locking and raises a ConcurrencyException on conflicting writes. You also get a growing catalogue of ready-made value objects — Uuid, Email, Phonenumber, Money, Link, Json, GeoAddress and more — plus a fluent Eloquent filtering layer on the base Model (see Filtering).

Filtering

The base Model ships with a filtering layer built on indexzer0/eloquent-filtering. Infrastructure\Models\Filter\Builder composes a set of filters fluently and serialises them — via toArray() — to the operator-array shape the model's filter() query scope consumes.

Building and applying filters

toArray() produces one MongoDB-style operator entry per filter ($eq, $gte, $in, $null, …):

Reconstructing filters from a request

Builder::fromArray() is the inverse of toArray() — it rebuilds a Builder from that array shape, for example from filters that arrive over HTTP. It validates strictly and throws Filter\Filters\Exceptions\FilterArrayNotValid on a missing key, an unknown operator, or a value whose type does not match the operator.

Because the check is strict, carry the filters as JSON rather than as bracket-notation query parameters. PHP parses every query-string value as a string, so ?filters[0][type]=$gte&filters[0][value]=18 yields the string "18" — which the numeric operators ($gt, $gte, $lt, $lte) and $null reject, while string-friendly operators like $eq and $in would still pass, making bracket notation deceptively half-working. A JSON payload preserves int and bool:

URL-encode the filters value in practice ([%5B, "%22, $%24, …); it is shown decoded here for readability.

On the server, decode the JSON and hand the array to fromArray():

The request above reconstructs exactly:

Development

License

The MIT License (MIT). See LICENSE.md for details.


All versions of laravel-ddd with dependencies

PHP Build Version
Package Version
Requires php Version ^8.4
giggsey/libphonenumber-for-php Version ^9.0
illuminate/contracts Version ^13.0
indexzer0/eloquent-filtering Version ^2.2
lava83/laravel-sqid Version ^0.2.0
spatie/laravel-data Version ^4.18
spatie/laravel-package-tools Version ^1.16
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 lava83/laravel-ddd contains the following files

Loading the files please wait ...