### Install PHPArkitect using Composer Source: https://github.com/phparkitect/arkitect/blob/main/README.md This command installs PHPArkitect as a development dependency in your PHP project using Composer. It ensures that the tool is available for local development and CI/CD pipelines. ```bash composer require --dev phparkitect/phparkitect ``` -------------------------------- ### Install Composer Dependencies in arkitect Container Source: https://github.com/phparkitect/arkitect/blob/main/CONTRIBUTING.md This command installs the necessary PHP dependencies for the arkitect project using Composer. It should be run after entering the Docker container for the first time or after changes to composer.json. ```shell composer install ``` -------------------------------- ### GitHub Actions: CI Workflow for PHPArkitect Source: https://context7.com/phparkitect/arkitect/llms.txt This GitHub Actions workflow automates PHPArkitect architecture checks on every push and pull request. It sets up PHP, installs dependencies, runs the architecture check, and optionally generates a baseline on failure. ```yaml name: Architecture Tests on: [push, pull_request] jobs: phparkitect: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: '8.2' - name: Install dependencies run: composer install --prefer-dist --no-progress - name: Run PHPArkitect run: vendor/bin/phparkitect check --format=json - name: Generate baseline on failure if: failure() run: vendor/bin/phparkitect check --generate-baseline ``` -------------------------------- ### Build and Run Docker Image for arkitect Source: https://github.com/phparkitect/arkitect/blob/main/CONTRIBUTING.md These commands are used to build the Docker image for the arkitect project and then enter the container's shell for development. It requires Docker to be installed. The volume mount ensures the container has access to the project files. ```shell docker image build -t phparkitect . docker run --rm -it --entrypoint= -v $(PWD):/arkitect phparkitect bash ``` -------------------------------- ### Jenkins: Pipeline for PHPArkitect Architecture Checks Source: https://context7.com/phparkitect/arkitect/llms.txt This Jenkins pipeline defines stages for installing dependencies and running PHPArkitect architecture checks. It archives the report, generates a baseline on failure, and ensures the pipeline proceeds accordingly. ```groovy pipeline { agent any stages { stage('Install Dependencies') { steps { sh 'composer install --no-dev --prefer-dist' } } stage('Architecture Check') { steps { sh 'vendor/bin/phparkitect check --format=json > arkitect-report.json' } post { always { archiveArtifacts artifacts: 'arkitect-report.json', allowEmptyArchive: true } failure { sh 'vendor/bin/phparkitect check --generate-baseline' } } } } } ``` -------------------------------- ### GitLab CI: Pipeline for PHPArkitect Integration Source: https://context7.com/phparkitect/arkitect/llms.txt This GitLab CI configuration integrates PHPArkitect into the testing stage of a pipeline. It installs dependencies, runs the architecture check, outputs a code quality report, and allows failures to enable further pipeline stages. ```yaml phparkitect: stage: test image: php:8.2 before_script: - composer install --no-progress --no-interaction script: - vendor/bin/phparkitect check --format=gitlab > code-quality-report.json artifacts: reports: codequality: code-quality-report.json when: always expire_in: 1 week allow_failure: true ``` -------------------------------- ### Debug an Expression in PHPArkitect Source: https://github.com/phparkitect/arkitect/blob/main/README.md This command allows debugging specific Arkitect rules by providing the rule name and its arguments. It helps in identifying which classes satisfy a given rule within the current project directory. This is a CLI command example. ```bash phparkitect debug:expression ResideInOneOfTheseNamespaces App ``` -------------------------------- ### Enforce Naming Conventions with PHP Arkitect Rules Source: https://github.com/phparkitect/arkitect/blob/main/examples/naming-conventions.md Defines rules using PHP Arkitect to enforce naming conventions for classes within specific namespaces. The first rule ensures all classes in `AppInfrastructureController` end with 'Controller', and the second rule ensures classes in `AppDomainAuctionBids` start with 'Bid'. ```php $rule_1 = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Infrastructure\Controller')) ->should(new HaveNameMatching('*Controller')) ->because('we want to uniform controller name.'); $rule_2 = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Domain\Auction\Bids')) ->should(new HaveNameMatching('Bid*')) ->because('we want to uniform bids object inside our domain.'); ``` -------------------------------- ### Download and Execute PHPArkitect Phar Source: https://github.com/phparkitect/arkitect/blob/main/README.md This sequence of commands downloads the PHPArkitect Phar (a self-contained executable) from GitHub releases, makes it executable, and then runs the 'check' command. This is useful for projects with dependency conflicts. ```bash wget https://github.com/phparkitect/arkitect/releases/latest/download/phparkitect.phar chmod +x phparkitect.phar ./phparkitect.phar check ``` -------------------------------- ### Simplified Make Commands for arkitect Development Source: https://github.com/phparkitect/arkitect/blob/main/CONTRIBUTING.md Provides shortcuts for common development tasks within the arkitect project using Make. These commands abstract the underlying Docker or build processes. Use 'make' without arguments for a full list of available commands. ```shell make dbi make shell ``` -------------------------------- ### Run PHPArkitect Check with Default Configuration Source: https://github.com/phparkitect/arkitect/blob/main/README.md This command executes the PHPArkitect analysis using the default configuration file (`phparkitect.php`) located in the project's root directory. It will analyze the codebase against the defined architectural rules. ```bash phparkitect check ``` -------------------------------- ### Configure PHPArkitect with ClassSets and Rules Source: https://github.com/phparkitect/arkitect/blob/main/README.md This snippet demonstrates how to configure PHPArkitect by defining a `ClassSet` for specified directories and applying various `Rule` objects. It shows how to group rules and associate them with class sets for architectural analysis. Dependencies include the Arkitect library components. ```php that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new HaveNameMatching('*Controller')) ->because('we want uniform naming'); $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Domain')) ->should(new NotHaveDependencyOutsideNamespace('App\Domain')) ->because('we want protect our domain'); $config ->add($mvcClassSet, ...$rules); }; ``` -------------------------------- ### Run PHPArkitect Architectural Checks Source: https://context7.com/phparkitect/arkitect/llms.txt These bash commands illustrate various ways to execute PHPArkitect checks from the command line. Options include using default or custom configuration files, enabling verbose output, stopping on the first failure, specifying the target PHP version, and using a custom autoloader. ```bash # Run with default config file (phparkitect.php) phparkitect check # Run with custom config file phparkitect check --config=config/architecture.php # Run with verbose output phparkitect check -v # Stop immediately on first violation phparkitect check --stop-on-failure # Specify target PHP version for parser phparkitect check --target-php-version=8.1 # Use custom autoload file phparkitect check --autoload=vendor/autoload.php ``` -------------------------------- ### Basic PHPArkitect Configuration Source: https://context7.com/phparkitect/arkitect/llms.txt This PHP code sets up a basic configuration for PHPArkitect. It defines a ClassSet to analyze files in the 'src' directory and establishes two rules: one for controller naming conventions and another for domain layer isolation. ```php that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new HaveNameMatching('*Controller')) ->because('we want uniform naming'); // Rule: Domain layer should be isolated $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Domain')) ->should(new NotHaveDependencyOutsideNamespace('App\Domain')) ->because('we want to protect our domain'); // Add rules to configuration $config->add($mvcClassSet, ...$rules); }; ``` -------------------------------- ### PHPArkitect: Debugging Architectural Rules (CLI) Source: https://context7.com/phparkitect/arkitect/llms.txt This section demonstrates how to use the `phparkitect debug:expression` command to test specific architectural rules directly from the command line. It allows for quick validation of expressions like namespace residency, naming conventions, and interface implementations. ```bash # Test how ResideInOneOfTheseNamespaces works phparkitect debug:expression ResideInOneOfTheseNamespaces App\Controller # Test multiple expressions phparkitect debug:expression HaveNameMatching "*Service" phparkitect debug:expression Extend AbstractController phparkitect debug:expression Implement RepositoryInterface # Test with specific directory cd src && phparkitect debug:expression ResideInOneOfTheseNamespaces Domain ``` -------------------------------- ### Run PHPArkitect Check with Custom Configuration Source: https://github.com/phparkitect/arkitect/blob/main/README.md This command runs the PHPArkitect analysis, specifying a custom configuration file path using the `--config` option. This allows flexibility in defining where your architectural rules are located. ```bash phparkitect check --config=/project/yourConfigFile.php ``` -------------------------------- ### PHPArkitect Output in GitLab Code Quality Format Source: https://github.com/phparkitect/arkitect/blob/main/README.md This command executes PHPArkitect analysis and sets the output format to GitLab's code quality format using the `format=gitlab` parameter. This allows for direct integration with GitLab CI/CD for code quality reporting. ```bash phparkitect check --format=gitlab ``` -------------------------------- ### Define Layered Architecture Rules (PHP) Source: https://github.com/phparkitect/arkitect/blob/main/README.md This snippet demonstrates how to define components and their dependency rules using Arkitect's Architecture builder. It specifies components like Controller, Service, Repository, Entity, and Domain, and enforces rules for allowed dependencies between them. The `rules()` method generates the actual rules. ```php component('Controller')->definedBy('App\Controller\*') ->component('Service')->definedBy('App\Service\*') ->component('Repository')->definedBy('App\Repository\*') ->component('Entity')->definedBy('App\Entity\*') ->component('Domain')->definedBy('App\Domain\*') ->where('Controller')->mayDependOnComponents('Service', 'Entity') ->where('Service')->mayDependOnComponents('Repository', 'Entity') ->where('Repository')->mayDependOnComponents('Entity') ->where('Entity')->shouldNotDependOnAnyComponent() ->where('Domain')->shouldOnlyDependOnComponents('Domain') ->rules(); // Other rule definitions... $config->add($classSet, $serviceNamingRule, $repositoryNamingRule, ...$layeredArchitectureRules); }; ``` -------------------------------- ### Advanced PHPArkitect Configuration with Exclusions Source: https://context7.com/phparkitect/arkitect/llms.txt This advanced PHP configuration defines ClassSets for multiple directories and specifies paths to exclude from analysis. It also includes a rule for repositories implementing an interface and demonstrates skipping custom annotation parsing for performance. ```php excludePath('src/Legacy/*'); $classSet->excludePath('src/Generated/*'); $rules = []; $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Repository')) ->should(new Implement('App\Repository\RepositoryInterface')) ->because('all repositories must implement the interface'); // Skip parsing custom annotations for performance $config->skipParsingCustomAnnotations(); $config->add($classSet, ...$rules); }; ``` -------------------------------- ### PHP Layered Architecture with Components Source: https://context7.com/phparkitect/arkitect/llms.txt This rule builder defines a layered architecture for PHP projects using components. It specifies components, their namespaces, and the allowed dependencies between them, enforcing a structured and maintainable codebase. ```php component('Controller')->definedBy('App\Controller\*') ->component('Service')->definedBy('App\Service\*') ->component('Repository')->definedBy('App\Repository\*') ->component('Entity')->definedBy('App\Entity\*') ->component('Domain')->definedBy('App\Domain\*') // Define allowed dependencies ->where('Controller')->mayDependOnComponents('Service', 'Entity') ->where('Service')->mayDependOnComponents('Repository', 'Entity') ->where('Repository')->mayDependOnComponents('Entity') ->where('Entity')->shouldNotDependOnAnyComponent() ->where('Domain')->shouldOnlyDependOnComponents('Domain') ->rules(); $config->add($classSet, ...$layeredArchitectureRules); }; ``` -------------------------------- ### Define PHP Interface Implementation Rules with Arkitect Source: https://context7.com/phparkitect/arkitect/llms.txt This snippet illustrates how to enforce interface implementation rules using Arkitect. It demonstrates rules for ensuring all repositories implement a specific interface, controllers are container-aware, and public API classes are not container-aware. It utilizes `Implement` and `NotImplement` expressions. ```php that(new ResideInOneOfTheseNamespaces('App\Repository')) ->should(new Implement('App\Repository\RepositoryInterface')) ->because('all repositories should implement our interface'); // Rule: Controllers should be container aware $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new Implement('ContainerAwareInterface')) ->because('all controllers should be container aware'); // Rule: Public API should not be container aware $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Infrastructure\RestApi\Public')) ->should(new NotImplement('ContainerAwareInterface')) ->because('public controllers should not be container aware'); $config->add($classSet, ...$rules); }; ``` -------------------------------- ### PHPArkitect Output Format Options Source: https://context7.com/phparkitect/arkitect/llms.txt These bash commands demonstrate how to control the output format of PHPArkitect checks. Supported formats include default text, JSON for CI/CD integration, and GitLab's code quality format. ```bash # Default text output phparkitect check --format=text # JSON output for CI/CD integration phparkitect check --format=json # GitLab code quality format phparkitect check --format=gitlab ``` -------------------------------- ### PHPArkitect Output in JSON Format Source: https://github.com/phparkitect/arkitect/blob/main/README.md This command executes PHPArkitect analysis and sets the output format to JSON using the `format=json` parameter. This is useful for programmatic consumption of violation reports, such as in CI/CD pipelines or integration with other tools. ```bash phparkitect check --format=json ``` -------------------------------- ### PHPUnit: Test Repository Interface Implementation Source: https://context7.com/phparkitect/arkitect/llms.txt This PHPUnit test verifies that all classes within the 'App\Repository' namespace implement the 'App\Repository\RepositoryInterface'. It utilizes PHPArkitect's rule-checking capabilities to enforce this architectural constraint. ```php that(new ResideInOneOfTheseNamespaces('App\Repository')) ->should(new Implement('App\Repository\RepositoryInterface')) ->because('all repositories must implement our interface'); self::assertThat( $rule, new ArchRuleCheckerConstraintAdapter($classSet) ); } public function testControllersMustFollowNamingConvention(): void { $classSet = ClassSet::fromDir(__DIR__.'/../../src'); $rule = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new HaveNameMatching('*Controller')) ->because('we want uniform naming'); self::assertThat( $rule, new ArchRuleCheckerConstraintAdapter($classSet) ); } public function testDomainLayerIsolation(): void { $classSet = ClassSet::fromDir(__DIR__.'/../../src'); $rule = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Domain')) ->should(new NotHaveDependencyOutsideNamespace('App\Domain')) ->because('domain should be isolated'); self::assertThat( $rule, new ArchRuleCheckerConstraintAdapter($classSet) ); } } ``` -------------------------------- ### Generate PHPArkitect Baseline File Source: https://github.com/phparkitect/arkitect/blob/main/README.md This command generates a baseline JSON file (`phparkitect-baseline.json` by default) containing the current list of architectural violations. This is useful for gradually introducing or enforcing rules by ignoring existing violations. ```bash phparkitect check --generate-baseline ``` -------------------------------- ### PHPArkitect Baseline Management Source: https://context7.com/phparkitect/arkitect/llms.txt This set of bash commands manages baseline files for handling architectural violations in legacy codebases. It covers generating baseline files (with custom names), using specific baseline files, skipping the default baseline, and ignoring line numbers in baselines. ```bash # Generate a baseline file to ignore current violations phparkitect check --generate-baseline # Generate baseline with custom filename phparkitect check --generate-baseline=my-baseline.json # Use a specific baseline file phparkitect check --use-baseline=my-baseline.json # Skip the default baseline file phparkitect check --skip-baseline # Ignore line numbers in baseline (useful when code moves) phparkitect check --ignore-baseline-linenumbers ``` -------------------------------- ### Define PHP Class Extension Rules with Arkitect Source: https://context7.com/phparkitect/arkitect/llms.txt This snippet demonstrates how to define rules for class extensions using Arkitect. It covers scenarios like ensuring all controllers extend a base controller, allowing multiple parent classes for exceptions, and preventing specific extensions for admin controllers or domain classes. It utilizes `Extend` and `NotExtend` expressions. ```php that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new Extend('App\Controller\AbstractController')) ->because('we want all controllers to extend AbstractController'); // Rule: Multiple allowed parent classes (violation if none match) $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Exception')) ->should(new Extend( 'RuntimeException', 'LogicException', 'DomainException' )) ->because('exceptions should extend standard exception types'); // Rule: Admin controllers must not extend regular controller $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Controller\Admin')) ->should(new NotExtend('App\Controller\AbstractController')) ->because('admin controllers should not extend AbstractController for security'); // Rule: Multiple forbidden parent classes (violation if any match) $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Domain')) ->should(new NotExtend( 'Symfony\Component\HttpFoundation\Response', 'Illuminate\Support\Facades\Facade' )) ->because('domain should not extend framework classes'); $config->add($classSet, ...$rules); }; ``` -------------------------------- ### Use Custom PHPArkitect Baseline File Source: https://github.com/phparkitect/arkitect/blob/main/README.md This command runs the PHPArkitect analysis and instructs it to use a specific baseline file for checking violations, using the `--use-baseline=` option. This allows you to manage different sets of ignored violations. ```bash phparkitect check --use-baseline=my-baseline.json ``` -------------------------------- ### Run Only a Specific Rule (PHP) Source: https://github.com/phparkitect/arkitect/blob/main/README.md This snippet shows how to configure Arkitect to execute only a single, specific rule. The `runOnlyThis()` method is appended to a rule definition, ensuring that only this particular rule is enforced during the analysis. This is helpful for focused testing or debugging. ```php $rules[] = Rule::allClasses() ->except('App\Controller\FolderController\*') ->that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new HaveNameMatching('*Controller')) ->because('we want uniform naming') ->runOnlyThis(); ``` -------------------------------- ### Generate PHPArkitect Baseline with Custom Filename Source: https://github.com/phparkitect/arkitect/blob/main/README.md This command generates a baseline JSON file with a custom name and path using the `--generate-baseline=` option. This provides flexibility in naming and organizing baseline files. ```bash phparkitect check --generate-baseline=my-baseline.json ``` -------------------------------- ### Run Specific Arkitect Rules in PHP Source: https://context7.com/phparkitect/arkitect/llms.txt This PHP snippet shows how to control which Arkitect rules are executed. By using the `runOnlyThis()` method on a specific rule, you can instruct Arkitect to ignore all other defined rules, allowing for targeted analysis. ```php that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new HaveNameMatching('*Controller')) ->because('we want uniform naming'); // Only this rule will run $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Domain\Aggregates')) ->should(new IsFinal()) ->because('aggregates must be final') ->runOnlyThis(); // This rule will also be skipped $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Repository')) ->should(new HaveNameMatching('*Repository')) ->because('we want uniform naming'); $config->add($classSet, ...$rules); }; ``` -------------------------------- ### Define Hexagonal Architecture Rules in PHP Source: https://context7.com/phparkitect/arkitect/llms.txt This snippet defines architectural components and their dependencies for a hexagonal architecture using Arkitect. It specifies rules for domain, ports, application, and adapter layers, ensuring proper isolation and dependency flow. ```php component('Domain')->definedBy('App\Domain\*') // Ports ->component('DomainPorts')->definedBy('App\Domain\Port\*') // Application layer ->component('Application')->definedBy('App\Application\*') // Adapters ->component('WebAdapter')->definedBy('App\Infrastructure\Adapter\Web\*') ->component('PersistenceAdapter')->definedBy('App\Infrastructure\Adapter\Persistence\*') ->component('MessagingAdapter')->definedBy('App\Infrastructure\Adapter\Messaging\*') // Domain dependencies ->where('Domain')->shouldOnlyDependOnComponents('Domain') ->where('DomainPorts')->mayDependOnComponents('Domain') // Application layer dependencies ->where('Application')->mayDependOnComponents('Domain', 'DomainPorts') // Adapters can only depend on domain and ports ->where('WebAdapter')->mayDependOnComponents('Domain', 'DomainPorts', 'Application') ->where('PersistenceAdapter')->mayDependOnComponents('Domain', 'DomainPorts') ->where('MessagingAdapter')->mayDependOnComponents('Domain', 'DomainPorts', 'Application') ->rules('of hexagonal architecture'); $config->add($classSet, ...$hexagonalRules); }; ``` -------------------------------- ### Skip PHPArkitect Baseline Check Source: https://github.com/phparkitect/arkitect/blob/main/README.md This command runs the PHPArkitect analysis while explicitly skipping the use of any baseline file, using the `--skip-baseline` option. This ensures that all current violations are reported, regardless of any existing baseline. ```bash phparkitect check --skip-baseline ``` -------------------------------- ### Define Architectural Rule with PHPArkitect Source: https://github.com/phparkitect/arkitect/blob/main/README.md This snippet demonstrates how to define an architectural rule using PHPArkitect. It specifies that all classes residing in the 'App\Controller' namespace should have names matching '*Controller', enforcing a naming convention. This rule is then explained with a 'because' clause. ```php Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new HaveNameMatching('*Controller')) ->because('it\'s a symfony naming convention'); ``` -------------------------------- ### Rule: Ensure Classes Implement a Specific Interface Source: https://github.com/phparkitect/arkitect/blob/main/README.md This rule mandates that all classes within a namespace (`App\Controller`) must implement a given interface (e.g., `ContainerAwareInterface`). It's used to guarantee that classes provide a certain set of methods or adhere to a specific contract. Ensures interface implementation. ```php $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new Implement('ContainerAwareInterface')) ->because('all controllers should be container aware'); ``` -------------------------------- ### Enforce Abstract, Final, and Readonly Constraints in PHP Source: https://context7.com/phparkitect/arkitect/llms.txt This PHP code snippet demonstrates how to use Arkitect to enforce rules on abstract, final, and readonly properties of classes within specified namespaces. It includes rules for service layers, domain objects, aggregates, Doctrine entities, and value objects. Dependencies include the Arkitect library. ```php that(new ResideInOneOfTheseNamespaces('App\Customer\Service')) ->should(new IsAbstract()) ->because('we want service classes to be abstract'); // Rule: Domain should not have abstract classes $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Domain')) ->should(new IsNotAbstract()) ->because('we want to avoid abstract classes in domain'); // Rule: Aggregates must be final $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Domain\Aggregates')) ->should(new IsFinal()) ->because('aggregates should be final to prevent inheritance'); // Rule: Doctrine entities cannot be final $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Infrastructure\Doctrine')) ->should(new IsNotFinal()) ->because('Doctrine requires non-final classes for proxies'); // Rule: Value objects must be readonly (PHP 8.2+) $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Domain\ValueObjects')) ->should(new IsReadonly()) ->because('value objects should be readonly'); // Rule: Entities should not be readonly $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Domain\Entity')) ->should(new IsNotReadonly()) ->because('entities need to be mutable'); $config->add($classSet, ...$rules); }; ``` -------------------------------- ### Enforce Type-Specific Class Constraints in PHP with Arkitect Source: https://context7.com/phparkitect/arkitect/llms.txt This PHP code snippet utilizes Arkitect to enforce type-specific constraints on classes, ensuring correct usage of traits, interfaces, and enums within designated namespaces. It includes rules for trait placement, avoiding traits in domain, ensuring interface-only directories, and restricting interfaces in test directories, as well as rules for enums. Dependencies include the Arkitect library. ```php that(new ResideInOneOfTheseNamespaces('App\Customer\Service\Traits')) ->should(new IsTrait()) ->because('only traits should be in this namespace'); // Rule: Domain should not use traits $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Domain')) ->should(new IsNotTrait()) ->because('we want to avoid traits in our codebase'); // Rule: Interfaces directory should only contain interfaces $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Interfaces')) ->should(new IsInterface()) ->because('all files in Interfaces directory should be interfaces'); // Rule: No interfaces in test directories $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('Tests\Integration')) ->should(new IsNotInterface()) ->because('tests should not contain interface definitions'); // Rule: Enum namespace should only contain enums (PHP 8.1+) $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Enum')) ->should(new IsEnum()) ->because('all classes in Enum namespace should be enums'); // Rule: Controllers should not be enums $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new IsNotEnum()) ->because('controllers cannot be enums'); $config->add($classSet, ...$rules); }; ``` -------------------------------- ### Enforce Naming Conventions with PHP Arkitect Source: https://context7.com/phparkitect/arkitect/llms.txt This rule enforces consistent naming conventions for classes based on their namespace and name patterns. It uses `HaveNameMatching` and `NotHaveNameMatching` expressions to ensure classes adhere to predefined naming standards, improving code readability. ```php that(new ResideInOneOfTheseNamespaces('App\Service')) ->should(new HaveNameMatching('*Service')) ->because('we want uniform naming for services'); // Rule: Repositories must end with 'Repository' $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Repository')) ->should(new HaveNameMatching('*Repository')) ->because('we follow repository pattern naming'); // Rule: Avoid vague names $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App')) ->should(new NotHaveNameMatching('*Manager')) ->because('*Manager is too vague in naming classes'); $config->add($classSet, ...$rules); }; ``` -------------------------------- ### PHParkitect Rules for Dependency Inversion Source: https://github.com/phparkitect/arkitect/blob/main/examples/dependency-inversion-principle.md These rules enforce the Dependency Inversion Principle by defining namespace dependencies for the Domain and Application layers. They ensure that the domain layer is independent and the application layer depends only on the domain and itself. No external dependencies are expected. ```php $rule_1 = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Domain')) ->should(new DependsOnlyOnTheseNamespaces('App\Domain')) ->because('we want to avoid that domain depends on other namespaces.'); $rule_2 = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Application')) ->should(new DependsOnlyOnTheseNamespaces('App\Application', 'App\Domain')) ->because('we want that application depends only on itself and domain namespace.'); ``` -------------------------------- ### PHP DocBlock Annotation Rules Source: https://context7.com/phparkitect/arkitect/llms.txt This section defines rules based on DocBlock annotations within PHP classes. It ensures domain events are marked as immutable, entities have ORM annotations, and controllers are not marked as immutable, promoting code correctness and maintainability. ```php that(new ResideInOneOfTheseNamespaces('App\Domain\Events')) ->should(new ContainDocBlockLike('@psalm-immutable')) ->because('we want to enforce immutability on events'); // Rule: Entities should have ORM annotations $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Entity')) ->should(new ContainDocBlockLike('@ORM\Entity')) ->because('all entities must be properly annotated'); // Rule: Controllers should not be immutable $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new NotContainDocBlockLike('@psalm-immutable')) ->because('controllers should not be immutable'); $config->add($classSet, ...$rules); }; ``` -------------------------------- ### Rule: Enforce Class Name Pattern Matching Source: https://github.com/phparkitect/arkitect/blob/main/README.md This rule checks if classes within a specified namespace (`App\Service`) adhere to a naming pattern (e.g., `*Service`). It helps maintain consistent naming conventions across the codebase, improving readability and maintainability. The pattern uses wildcards. ```php $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Service')) ->should(new HaveNameMatching('*Service')) ->because('we want uniform naming for services'); ``` -------------------------------- ### Ensure classes matching '*Handler' reside in App\Application Source: https://github.com/phparkitect/arkitect/blob/main/README.md This rule mandates that all classes whose names end with '*Handler' must reside within the 'App\Application' namespace. It helps organize command handlers in a dedicated location. ```php $rules[] = Rule::allClasses() ->that(new HaveNameMatching('*Handler')) ->should(new ResideInOneOfTheseNamespaces('App\Application')) ->because('we want to be sure that all CommandHandlers are in a specific namespace'); ``` -------------------------------- ### Exclude Classes from Parser (PHP) Source: https://github.com/phparkitect/arkitect/blob/main/README.md This code illustrates how to exclude specific classes or patterns from Arkitect's parsing process using the `except` function. This is useful for preventing certain classes, like those in a specific folder, from being subject to rules. It's typically used within rule definitions. ```php $rules[] = Rule::allClasses() ->except('App\Controller\FolderController\*') ->that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new HaveNameMatching('*Controller')) ->because('we want uniform naming'); ``` -------------------------------- ### Control Namespace Dependencies with PHP Arkitect Source: https://context7.com/phparkitect/arkitect/llms.txt This rule manages dependencies between namespaces, ensuring that layers only depend on allowed namespaces and do not introduce unwanted external or internal dependencies. It utilizes expressions like `DependsOnlyOnTheseNamespaces` and `NotDependsOnTheseNamespaces`. ```php that(new ResideInOneOfTheseNamespaces('App\Domain')) ->should(new DependsOnlyOnTheseNamespaces( ['App\Domain', 'Ramsey\Uuid'], ['App\Domain\Excluded'] // Excluded namespaces )) ->because('we want to protect our domain from external dependencies'); // Rule: Application layer must not depend on Infrastructure $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Application')) ->should(new NotDependsOnTheseNamespaces( ['App\Infrastructure'], ['App\Infrastructure\Repository'] // Exceptions allowed )) ->because('we want to avoid coupling between layers'); // Rule: Domain must not have external dependencies $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Domain')) ->should(new NotHaveDependencyOutsideNamespace( 'App\Domain', ['Ramsey\Uuid'], // Allow specific external dependencies true // Enable strict checking )) ->because('we want to protect our domain'); $config->add($classSet, ...$rules); }; ``` -------------------------------- ### Enforce Namespace Residency Rules with PHP Arkitect Source: https://context7.com/phparkitect/arkitect/llms.txt This rule ensures that classes reside in their designated namespaces. It uses Arkitect's `ResideInOneOfTheseNamespaces` and `NotResideInTheseNamespaces` expressions to validate class locations, ensuring adherence to project structure. ```php that(new HaveNameMatching('*Handler')) ->should(new ResideInOneOfTheseNamespaces('App\Application')) ->because('we want all CommandHandlers in a specific namespace'); // Rule: Events must not reside in wrong layers $rules[] = Rule::allClasses() ->that(new Extend('App\Domain\Event')) ->should(new NotResideInTheseNamespaces('App\Application', 'App\Infrastructure')) ->because('events should not be in application or infrastructure layers'); $config->add($classSet, ...$rules); }; ``` -------------------------------- ### Rule: Check for Absence of Specific String in DocBlock Source: https://github.com/phparkitect/arkitect/blob/main/README.md This rule ensures that the DocBlock of classes within a given namespace (`App\Controller`) does not contain a specified string pattern (e.g., `@psalm-immutable`). It complements `ContainDocBlockLike` for enforcing or disallowing certain documentation markers. Assumes DocBlocks are present. ```php $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Controller')) ->should(new NotContainDocBlockLike('@psalm-immutable')) ->because('we don\'t want to enforce immutability'); ``` -------------------------------- ### Restrict dependencies outside namespaces for App\Application Source: https://github.com/phparkitect/arkitect/blob/main/README.md This rule prevents classes in the 'App\Application' namespace from depending on namespaces within 'App\Infrastructure', except for specified sub-namespaces. It enforces a clean separation between application and infrastructure layers. ```php $rules[] = Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces('App\Application')) ->should(new NotDependsOnTheseNamespaces(['App\Infrastructure'], ['App\Infrastructure\Repository'])) ->because('we want to avoid coupling between application layer and infrastructure layer'); ```