philipphermes/symfony-layered-architecture

Provides a Twig compiler pass and routing loaders that enable support for a layered architecture.

Installs: 87

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/philipphermes/symfony-layered-architecture

1.0.0 2025-12-18 10:22 UTC

This package is auto-updated.

Last update: 2025-12-18 10:24:07 UTC


README

Provides a Twig compiler pass and routing loaders that enable support for a layered architecture.

CI PHP

Table of Contents

  1. Installation
    1. twig compiler pass
    2. services
    3. routes
    4. doctrine
    5. migrations
    6. install deptrac
    7. configure deptrac
  2. Code Quality
    1. deptrac
    2. phpstan
  3. Test
    1. phpunit

Installation

composer require philipphermes/symfony-layered-architecture

Register Twig Compiler Pass

<?php

namespace App;

use PhilippHermes\Symfony\LayeredArchitecture\Shared\Twig\TwigPathCompilerPass;
use PhilippHermes\Symfony\LayeredArchitecture\Shared\Twig\TwigPathRegistrator\Plugin\BackendTwigRegistratorPlugin;
use PhilippHermes\Symfony\LayeredArchitecture\Shared\Twig\TwigPathRegistrator\Plugin\FrontendTwigRegistratorPlugin;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;

class Kernel extends BaseKernel
{
    use MicroKernelTrait;

    /**
     * @inheritDoc
     */
    protected function build(ContainerBuilder $container): void
    {
        $twigPathCompilerPass = new TwigPathCompilerPass([
            //TwigRegistratorPlugins
            new BackendTwigRegistratorPlugin(),
            new FrontendTwigRegistratorPlugin(),
            //you can add your own ones e.g. when you have an additional layer like for merchants
        ]);
    
        $container->addCompilerPass($twigPathCompilerPass);
    }
}

Update services.yaml

parameters:

services:
  _defaults:
    autowire: true
    autoconfigure: true

  App\:
    resource: '../src/'
    exclude:
      - '../src/DependencyInjection/'
      - '../src/**/Entity/**'
      - '../src/Kernel.php'

  PhilippHermes\Symfony\LayeredArchitecture\Shared\Routing\ControllerLoader:
    arguments:
      $classLoader: '@routing.loader.attribute'
      $projectDir: '%kernel.project_dir%'
    tags:
      - { name: routing.loader }

Update routes.yaml

modular_controllers:
    resource: .
    type: modular

Update doctrine.yaml

doctrine:
    ...
    orm:
        validate_xml_mapping: true
        naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
        identity_generation_preferences:
            Doctrine\DBAL\Platforms\PostgreSQLPlatform: identity
        auto_mapping: true
        mappings:
            Backend:
                type: attribute
                is_bundle: false
                dir: '%kernel.project_dir%/src/Backend'
                prefix: 'App\Backend'
                alias: Backend
            Frontend:
                type: attribute
                is_bundle: false
                dir: '%kernel.project_dir%/src/Frontend'
                prefix: 'App\Frontend'
                alias: Frontend
    ...

Update doctrine_migrations.yaml

doctrine_migrations:
    migrations_paths:
        'DoctrineMigrations': '%kernel.project_dir%/src/Generated/Migrations'
    enable_profiler: false

install deptrac:

composer require --dev deptrac/deptrac

Add deptrac.yaml to your project root:

deptrac:
  paths:
    - ./src
  exclude_files:
    - '#.*test.*#i'
  layers:
    - name: Backend_Business
      collectors:
        - type: directory
          value: src/Backend/.+/Business/.*
    - name: Backend_Persistence
      collectors:
        - type: directory
          value: src/Backend/.+/Persistence/.*
    - name: Backend_Communication
      collectors:
        - type: directory
          value: src/Backend/.+/Communication/.*
    - name: Backend_Presentation
      collectors:
        - type: directory
          value: src/Backend/.+/Presentation/.*
    - name: Frontend_Controller
      collectors:
        - type: directory
          value: src/Frontend/.+/Controller/.*
    - name: Frontend_Theme
      collectors:
        - type: directory
          value: src/Frontend/.+/Theme/.*
    - name: Client
      collectors:
        - type: directory
          value: src/Client/.+/*
    - name: Service
      collectors:
        - type: directory
          value: src/Service/.+/*
    - name: Shared
      collectors:
        - type: directory
          value: src/Shared/.+/*
  ruleset:
    Backend_Business:
      - Backend_Business
      - Backend_Persistence
      - Service
      - Shared
    Backend_Persistence:
      - Backend_Persistence
      - Service
      - Shared
    Backend_Communication:
      - Backend_Communication
      - Backend_Business
      - Service
      - Shared
    Backend_Presentation:
      - Backend_Presentation
    Frontend_Controller:
      - Frontend_Controller
      - Client
      - Service
      - Shared
    Frontend_Theme:
      - Frontend_Theme
    Client:
      - Backend_Business
      - Client
      - Service
      - Shared
    Service:
      - Service
      - Shared
    Shared:
      - Shared

Code Quality

Deptrac

vendor/bin/deptrac

Phpstan

vendor/bin/phpstan analyse --memory-limit=1G

Test

Phpunit

vendor/bin/phpunit

# With coverage
XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html coverage-report