Tactical DDD, simplified for PHP. Tag your classes via PHP attributes and analyze forbidden relations.
composer require --dev makomweb/tactixRequirements:
- PHP ^8.2
- your source code being tagged with PHP Molecules
- install the tags package from PHP Molecules as a regular dependency via:
composer require xmolecules/phpmolecules- tag your classes with the available attributes:
use PHPMolecules\DDD\Attribute\AggregateRoot;
use PHPMolecules\DDD\Attribute\Entity;
use PHPMolecules\DDD\Attribute\ValueObject;
use PHPMolecules\DDD\Attribute\Service;
use PHPMolecules\DDD\Attribute\Factory;
use PHPMolecules\DDD\Attribute\Repository;
#[Entity]
final class User {}use Tactix\Check;
Check::className(User::class);
Check::folder(__DIR__.'/src');Check throws on violations:
Tactix\ClassViolationExceptionTactix\FolderViolationException
Both exceptions contain a $violations property of type array<Tactix\Violation> to get further details about whether there are missing tags, ambiguity or forbidden relations.
Tactix provides a Symfony Console command tactix:report that creates a static HTML report for a source folder.
# Run the report command for a folder.
bin/console tactix:report <folder>
# or, when installed as a dependency with optional output directory
vendor/bin/console tactix:report <folder> --out-dir=<out-dir>
# Exclude specific namespaces from the report (can be used multiple times)
vendor/bin/console tactix:report <folder> --exclude-namespace="App\\CLI\\" --exclude-namespace="App\\Infrastructure\\"Options:
--out-dir: Base output directory for reports (defaults to project root)--exclude-namespace: Namespace prefix to exclude from the report (can be used multiple times). By default,Doctrine\\,Symfony\\, andPsr\\namespaces are excluded. When you provide your own exclusions, you replace these defaults.
Notes:
- the output files index.html, report.js, chart.js, styles.css are created
- the command prints discovered classes and forbidden relations and finishes with
Report written to: ./report/index.html.
Tactix includes a small built-in blacklist (see Tactix\Forbidden) and reports violations as:
(MyValueObject)-[consumes]->(MyEntity) is a forbidden relation! ❌
See CONTRIBUTING.md for details.
