Skip to main content

Drupal Standards Validation Checklist

Drupal Standards Validation Checklist

Comprehensive validation checklist for ensuring code quality and compliance with Drupal coding standards. Use this checklist before commits, during code review, and as part of CI/CD validation.

Quick Reference Checklist

Copy and use in commit messages or PR descriptions:

Drupal Standards Validation:
- [ ] declare(strict_types=1) at file top
- [ ] Type hints on ALL parameters
- [ ] Return types on ALL methods
- [ ] No \Drupal:: calls (dependency injection only)
- [ ] All lines <= 80 characters
- [ ] DocBlocks for classes and methods
- [ ] @param and @return tags complete
- [ ] No TODOs, HACKs, or temporary comments
- [ ] Proper namespace and use statements
- [ ] PHPCS and PHPStan passing

PHP File Standards

File Header & Declarations

  • <?php tag at the very first line (no blank lines before)
  • declare(strict_types=1); as second line
  • Blank line after declare statement
  • Proper namespace declaration: namespace Drupal\module_name\Subdir;
  • Use statements alphabetically sorted
  • No trailing whitespace anywhere
  • Single blank line at end of file

Correct Example:

<?php declare(strict_types=1); namespace Drupal\agent_buildkit_eca\Plugin\ECA\Action; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\PluginBase; use Drupal\eca\Plugin\ECA\Action\ActionBase; use Symfony\Component\DependencyInjection\ContainerInterface;

Violations:

  • Missing declare(strict_types=1);
  • Blank lines before namespace
  • Unsorted use statements (case-sensitive alphabetical)
  • Use statements not properly organized

Code Formatting

Line Length (STRICT REQUIREMENT)

  • All lines ** 80 characters** (Drupal standard)
  • Lines >80 chars broken into multiple lines
  • Indentation: 2 spaces (never tabs)
  • No trailing whitespace on any line

Violation - Line Too Long:

// WRONG - 86 characters public function executeAgent(string $agent_id, array $inputs, string $runtime = 'native'): array {

Fix - Proper Breaking:

// CORRECT - Split across multiple lines public function executeAgent( string $agent_id, array $inputs, string $runtime = 'native' ): array {

Line Length Validation Commands:

# Check for lines > 80 characters grep -r ".{81,}" src/ --include="*.php" --include="*.module" # Count violations grep -r ".{81,}" src/ --include="*.php" | wc -l # Show line and number grep -n ".{81,}" src/Controller/*.php

Indentation & Spacing

  • 2-space indentation (Drupal standard, not 4)
  • Single space around operators: $a = $b + $c
  • No space inside parentheses: function($param) not function( $param )
  • Blank line between method definitions
  • Blank line after opening curly braces in classes

Correct:

class MyClass { protected $property; public function method(): void { $result = $this->calculate($value); } private function calculate(int $value): int { return $value * 2; } }

Control Structures

  • Opening braces on same line: if (...) { not if (...)\n{
  • Closing braces on own line
  • Single statement blocks still require braces
  • Space before opening parenthesis in control structures

Violations:

// WRONG - Single line with no braces if ($condition) return $value; // WRONG - Brace on wrong line if ($condition) { return $value; } // WRONG - No space before parenthesis if($condition) { return $value; }

Correct:

// CORRECT if ($condition) { return $value; } if ($condition) { return $value; } else { return null; }

Array Formatting

  • Use [] syntax (not array())
  • Multi-line arrays: one element per line
  • Trailing comma on last element (modern PHP)
  • Proper indentation within arrays

Violations:

// WRONG - Old syntax $data = array('key' => 'value'); // WRONG - Multiple on one line $data = ['key1' => 'value1', 'key2' => 'value2']; // WRONG - Missing trailing comma $data = [ 'key1' => 'value1', 'key2' => 'value2' ];

Correct:

// CORRECT $data = [ 'key1' => 'value1', 'key2' => 'value2', ]; // Simple arrays can be inline $colors = ['red', 'green', 'blue'];

String Formatting

  • Use double quotes for strings with variables
  • Use single quotes for literal strings
  • Use string interpolation: "{$var}" not concatenation
  • Use t() function for translatable strings
  • Multi-line strings: use heredoc/nowdoc

Violations:

// WRONG - Concatenation $message = 'Hello ' . $name . ' welcome to ' . $site; // WRONG - Single quotes with variable $url = 'http://example.com/' . $path; // WRONG - No translation wrapper echo 'Error: ' . $message;

Correct:

// CORRECT - Interpolation $message = "Hello {$name} welcome to {$site}"; // CORRECT - Translatable $message = $this->t('Error: @error', ['@error' => $error]); // CORRECT - Translation with replacement $message = $this->t( 'Hello @name, welcome to @site!', [ '@name' => $name, '@site' => $site, ] );

Type Safety & Type Hints

Parameter Type Hints

  • ALL parameters have type hints
  • No mixed type (use specific types)
  • Nullable types use ?Type syntax: ?string $value = null
  • Union types for multiple options: string|int|array
  • Array types specific: array or ArrayInterface

Violations:

// WRONG - No type hints public function getData($id, $options) { // ... } // WRONG - Using mixed public function process(mixed $data): mixed { // ... } // WRONG - No null type public function getValue($default) { // ... }

Correct:

// CORRECT - All parameters typed public function getData( int $id, array $options = [] ): array { // ... } // CORRECT - Nullable when needed public function getValue(string $key, ?string $default = null): ?string { // ... } // CORRECT - Union type public function process(string|int|array $data): bool { // ... }

Return Type Hints

  • ALL methods have return type declarations
  • No void for methods that return nothing (use explicit return type)
  • Return type before method body: ): Type {
  • Nullable return: ?Type or Type|null

Violations:

// WRONG - No return type public function getData($id) { return $this->storage->load($id); } // WRONG - Using void for method with side effects public function execute(): void { $this->doSomething(); return null; // Redundant }

Correct:

// CORRECT - Explicit return types public function getData(int $id): ?EntityInterface { return $this->storage->load($id); } public function execute(): void { $this->doSomething(); } public function getStatus(): string { return 'healthy'; }

Strict Type Checking

  • declare(strict_types=1); required in all files
  • No type coercion tricks
  • Explicit casting when needed: (int)$value, (string)$data
  • Use is_* functions for type checking: is_string($value)

Example with strict types:

<?php declare(strict_types=1); namespace Drupal\agent_buildkit_eca; class TypeSafeExample { public function calculateTotal(int $base, int $percentage): float { // With strict_types=1, only int values accepted return $base + ($base * $percentage / 100); } public function processData(array $items): int { $count = 0; foreach ($items as $item) { if (is_string($item)) { $count++; } } return $count; } }

Documentation Standards

Class Documentation

  • Class has DocBlock comment
  • Starts with one-line description
  • Followed by detailed description (if needed)
  • Includes @see, @link, etc. when referencing
  • Document all public properties

Correct Class Documentation:

/** * Client for communicating with agent-buildkit and Langflow APIs. * * Handles both native agent-buildkit execution and Langflow-based * runtime execution. Supports health checks and agent status monitoring. * * @see https://gitlab.com/blueflyio/agent-platform/agent-buildkit */ class AgentBuildKitClient { /** * The HTTP client. * * @var \GuzzleHttp\ClientInterface */ protected $httpClient; }

Method/Function Documentation

  • ALL public and protected methods have DocBlocks
  • First line: concise description (ends with period)
  • Longer description: provide context and details
  • @param Type $name - for every parameter
  • @param array $options with nested documentation
  • @return Type - for every method
  • @throws \ExceptionClass - for every exception
  • @see URL - link to related documentation
  • Align parameter documentation for readability

Violation - Missing Documentation:

// WRONG - No DocBlock public function executeAgent($agent_id, $inputs, $runtime) { // ... } // WRONG - Incomplete documentation /** * Execute an agent. */ public function executeAgent(string $agent_id, array $inputs): array { // Missing @param and @return }

Correct - Complete Documentation:

/** * Execute an agent with provided inputs. * * Supports both native agent-buildkit and Langflow runtimes. * When $wait is true, blocks until execution completes. * * @param string $agent_id * The agent ID (or flow ID for Langflow). * @param array $inputs * Input data for the agent execution. * @param string $runtime * Runtime to use ('native' or 'langflow'). Defaults to 'native'. * @param bool $wait * Whether to wait for execution completion. Defaults to TRUE. * * @return array * Execution result with keys: * - executionId: Unique execution identifier * - status: Execution status (completed, failed, running) * - outputs: Agent output data * - metrics: Array of duration, cost, tokensUsed * * @throws \Exception * When API communication fails or JSON is invalid. * * @see \Drupal\agent_buildkit_eca\AgentBuildKitClient::executeLangflow() */ public function executeAgent( string $agent_id, array $inputs, string $runtime = 'native', bool $wait = TRUE ): array { // Implementation }

Documentation for Complex Parameters

  • Array parameters document all keys
  • Optional parameters marked clearly
  • Default values documented
  • Constraints documented (max length, allowed values)

Example - Complex Parameters:

/** * Process configuration options. * * @param array $options * Array of options with the following keys: * - timeout: (int, optional) Timeout in seconds. Defaults to 30. * - retries: (int, optional) Number of retries. Defaults to 3. * - headers: (array, optional) Custom HTTP headers. * - auth: (string, required) Bearer token for authentication. * * @return bool * TRUE if processed successfully, FALSE otherwise. * * @throws \InvalidArgumentException * If required 'auth' key is missing. */ public function processOptions(array $options): bool { // Implementation }

Dependency Injection & Services

Prohibition of Direct Drupal Calls

  • NO \Drupal:: calls in services/classes
  • NO \Drupal::service() anywhere
  • NO \Drupal::entityTypeManager()
  • NO \Drupal::configFactory()
  • NO \Drupal::logger()
  • Exception: only in procedural hooks (Drupal limitation)

Violation - Direct Drupal Calls:

// WRONG - Direct service access public function myFunction() { $entity = \Drupal::entityTypeManager()->getStorage('node')->load(1); $config = \Drupal::configFactory()->get('my_module.settings'); \Drupal::logger('my_module')->info('Message'); }

Correct - Dependency Injection:

use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Config\ConfigFactoryInterface; use Psr\Log\LoggerInterface; class MyService { protected EntityTypeManagerInterface $entityTypeManager; protected ConfigFactoryInterface $configFactory; protected LoggerInterface $logger; public function __construct( EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, LoggerInterface $logger ) { $this->entityTypeManager = $entity_type_manager; $this->configFactory = $config_factory; $this->logger = $logger; } public function myFunction(): void { $entity = $this->entityTypeManager->getStorage('node')->load(1); $config = $this->configFactory->get('my_module.settings'); $this->logger->info('Message'); } }

Constructor Injection Pattern

  • All dependencies injected via constructor
  • Use type-hinted parameters
  • Store in protected properties
  • Use in methods via $this->property

Correct Pattern:

/** * Service for handling agent execution. */ class ExecuteAgent { /** * The agent buildkit client. * * @var \Drupal\agent_buildkit_eca\AgentBuildKitClient */ protected $agentClient; /** * Constructs ExecuteAgent service. * * @param \Drupal\agent_buildkit_eca\AgentBuildKitClient $agent_client * The agent client service. */ public function __construct(AgentBuildKitClient $agent_client) { $this->agentClient = $agent_client; } /** * Execute agent workflow. */ public function execute(): void { $result = $this->agentClient->executeAgent('agent_id', []); } }

Service Definition

  • Service defined in *.services.yml
  • Proper class reference
  • All dependencies declared
  • Tags documented if applicable

Correct services.yml:

services: agent_buildkit_eca.client: class: Drupal\agent_buildkit_eca\AgentBuildKitClient arguments: - '@http_client' - '@config.factory' agent_buildkit_eca.execute_action: class: Drupal\agent_buildkit_eca\Plugin\ECA\Action\ExecuteAgent arguments: - '@agent_buildkit_eca.client' tags: - { name: 'eca_action_plugin' }

Common Violations & Fixes

1. String Concatenation Issues

Violation:

$message = 'Hello ' . $name . ' welcome to ' . $site; $url = 'http://example.com/' . $path . '?id=' . $id;

Fix:

$message = "Hello {$name} welcome to {$site}"; $url = "http://example.com/{$path}?id={$id}";

2. Missing Parameter Type Hints

Violation:

public function getData($id, $options = []) { return $this->storage->load($id); }

Fix:

public function getData(int $id, array $options = []): ?EntityInterface { return $this->storage->load($id); }

3. No Return Type Declaration

Violation:

public function getStatus() { return $this->status; } public function execute() { $this->doSomething(); }

Fix:

public function getStatus(): string { return $this->status; } public function execute(): void { $this->doSomething(); }

4. Incomplete Documentation

Violation:

/** * Process data. */ public function processData(array $data, string $format, int $depth) { // Missing parameter and return documentation }

Fix:

/** * Process data with specified format and depth. * * Transforms data according to the given format specification, * respecting the maximum nesting depth. * * @param array $data * Data array to process. * @param string $format * Output format (json, xml, csv). * @param int $depth * Maximum nesting depth (1-10). * * @return string * Formatted output. * * @throws \InvalidArgumentException * If format is unsupported or depth is out of range. */ public function processData( array $data, string $format, int $depth ): string { // Implementation }

5. TODOs and HACKs

Violation:

public function importData() { // TODO: Add error handling $data = $this->fetchData(); // HACK: Temporary workaround for API inconsistency if (isset($data['result'])) { return $data['result']; } // @fixme: This needs refactoring return $data; }

Fix:

/** * Import data from remote source. * * Note: Temporary mapping for API inconsistency documented in * https://gitlab.com/blueflyio/project/-/issues/123 * * @return array * Imported data. * * @throws \RuntimeException * When data fetch fails. * * @see https://gitlab.com/blueflyio/project/-/issues/123 */ public function importData(): array { try { $data = $this->fetchData(); } catch (\Exception $e) { throw new \RuntimeException('Failed to fetch data: ' . $e->getMessage()); } // API returns 'result' key, normalize to 'data' for consistency return $data['result'] ?? $data; }

6. Unsorted Use Statements

Violation:

use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\node\Entity\Node; use Drupal\Core\Form\FormBase; use GuzzleHttp\ClientInterface;

Fix - Alphabetically Sorted:

use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Form\FormBase; use Drupal\node\Entity\Node; use GuzzleHttp\ClientInterface;

7. Line Length Violations

Violation - 96 characters:

public function executeAgent(string $agent_id, array $inputs, string $runtime = 'native', bool $wait = TRUE): array {

Fix - Under 80 characters:

public function executeAgent( string $agent_id, array $inputs, string $runtime = 'native', bool $wait = TRUE ): array {

PHPCS Validation

Running PHPCS

# Check entire module vendor/bin/phpcs --standard=Drupal,DrupalPractice modules/custom/my_module # Check specific file vendor/bin/phpcs --standard=Drupal src/Service/MyService.php # Check with all details vendor/bin/phpcs -vvv --standard=Drupal modules/custom/my_module # Dry-run auto-fix (preview changes) vendor/bin/phpcbf --standard=Drupal --dry-run src/ # Auto-fix violations vendor/bin/phpcbf --standard=Drupal src/

PHPCS Configuration

Create phpcs.xml.dist in project root:

<?xml version="1.0" encoding="UTF-8"?> <ruleset name="drupal_module"> <description>Drupal module coding standards</description> <arg name="extensions" value="php,module,inc,install,test,profile"/> <arg name="colors"/> <arg value="p"/> <exclude-pattern>*/vendor/*</exclude-pattern> <exclude-pattern>*/node_modules/*</exclude-pattern> <exclude-pattern>*/tests/fixtures/*</exclude-pattern> <rule ref="Drupal"/> <rule ref="DrupalPractice"/> <!-- Strict line length enforcement --> <rule ref="Drupal.Files.LineLength"> <properties> <property name="lineLimit" value="80"/> </properties> </rule> <file>.</file> </ruleset>

PHPStan Static Analysis

Running PHPStan

# Analyze module (level 6) vendor/bin/phpstan analyze modules/custom/my_module --level=6 # Analyze at highest level (8) vendor/bin/phpstan analyze --level=8 src/ # Generate baseline for existing errors vendor/bin/phpstan analyze --generate-baseline # View baseline vendor/bin/phpstan analyze --no-baseline

PHPStan Configuration

Create phpstan.neon in project root:

includes: - vendor/mglaman/phpstan-drupal/extension.neon parameters: level: 6 paths: - src - tests scanDirectories: - web/core - web/modules/contrib excludePaths: - */tests/fixtures/* - */vendor/* drupal: drupal_root: web

PHPStan Error Examples

Violation - Untyped property:

// Line 15: Property $client has no type hint protected $client;

Fix:

/** * HTTP client. * * @var \GuzzleHttp\ClientInterface */ protected $client;

Pre-Commit Validation

Pre-Commit Checklist

Before every commit, verify:

  • All lines <= 80 characters: grep -r ".{81,}" src/
  • declare(strict_types=1); in all PHP files
  • Type hints on all parameters
  • Return types on all methods
  • No \Drupal:: calls (except in hooks)
  • DocBlocks on all public/protected methods
  • No TODOs, HACKs, or @fixme comments
  • Alphabetically sorted use statements
  • PHPCS passing: vendor/bin/phpcs --standard=Drupal src/
  • PHPStan passing: vendor/bin/phpstan analyze --level=6 src/

Git Pre-Commit Hook

Create .husky/pre-commit (TypeScript):

#!/usr/bin/env node const { execSync } = require('child_process'); const fs = require('fs'); // Get PHP files being committed const output = execSync( 'git diff --cached --name-only --diff-filter=ACM | grep -E "\\.php$|\\.module$"' ).toString().trim(); if (!output) { process.exit(0); } const files = output.split('\n'); console.log('Running PHPCS validation...'); try { execSync(`vendor/bin/phpcs --standard=Drupal,DrupalPractice ${files.join(' ')}`); } catch (error) { console.error('PHPCS violations found. Please fix before committing.'); console.error('Run: vendor/bin/phpcbf --standard=Drupal ' + files.join(' ')); process.exit(1); } console.log('Running PHPStan analysis...'); try { execSync(`vendor/bin/phpstan analyze ${files.join(' ')} --level=6`); } catch (error) { console.error('PHPStan errors found. Please fix before committing.'); process.exit(1); } console.log('All validations passed!');

CI/CD Integration

GitLab CI Configuration

# .gitlab-ci.yml stages: - test - build phpcs: stage: test image: php:8.2-cli before_script: - composer install script: - vendor/bin/phpcs --standard=Drupal,DrupalPractice src/ modules/custom/ allow_failure: false only: - merge_requests - development - /^release\/.*$/ phpstan: stage: test image: php:8.2-cli before_script: - composer install script: - vendor/bin/phpstan analyze src/ modules/custom/ --level=6 allow_failure: false only: - merge_requests - development - /^release\/.*$/ design_taste: stage: test script: - buildkit drupal taste src/ modules/custom/ allow_failure: true only: - merge_requests

GitLab Merge Request Rules

Set in Settings > Merge Requests > Merge request approvals:

  • Require approval from code owner
  • Require all discussions resolved
  • Block if CI pipeline fails
  • Block if PHPCS/PHPStan fail
  • Require test coverage >= 80%

Validation Automation

Quick Validation Script

#!/bin/bash # validate-drupal.sh MODULE_PATH="${1:-.}" ERRORS=0 echo "=== Drupal Standards Validation ===" echo "Module path: $MODULE_PATH" echo "" # Check line length echo "Checking line length (max 80 chars)..." LINE_VIOLATIONS=$(grep -r ".{81,}" "$MODULE_PATH" --include="*.php" --include="*.module" 2>/dev/null | wc -l) if [ "$LINE_VIOLATIONS" -gt 0 ]; then echo " ERROR: $LINE_VIOLATIONS lines exceed 80 characters" grep -r ".{81,}" "$MODULE_PATH" --include="*.php" --include="*.module" 2>/dev/null | head -5 ERRORS=$((ERRORS + 1)) fi # Check for missing declare strict_types echo "Checking for declare(strict_types=1)..." MISSING_STRICT=$(find "$MODULE_PATH" -name "*.php" -type f ! -exec grep -l "declare(strict_types=1)" {} \; | wc -l) if [ "$MISSING_STRICT" -gt 0 ]; then echo " WARNING: $MISSING_STRICT PHP files missing declare(strict_types=1)" fi # Check for Drupal:: calls echo "Checking for \\Drupal:: direct calls..." DRUPAL_CALLS=$(grep -r '\\Drupal::' "$MODULE_PATH" --include="*.php" 2>/dev/null | grep -v '//' | wc -l) if [ "$DRUPAL_CALLS" -gt 0 ]; then echo " WARNING: $DRUPAL_CALLS direct \\Drupal:: calls found" grep -r '\\Drupal::' "$MODULE_PATH" --include="*.php" 2>/dev/null | grep -v '//' | head -3 fi # Check for TODOs and HACKs echo "Checking for TODOs and HACKs..." ISSUES=$(grep -r -i '// TODO\|// HACK\|@fixme' "$MODULE_PATH" --include="*.php" 2>/dev/null | wc -l) if [ "$ISSUES" -gt 0 ]; then echo " WARNING: $ISSUES TODOs/HACKs found" grep -r -i '// TODO\|// HACK\|@fixme' "$MODULE_PATH" --include="*.php" 2>/dev/null | head -3 fi # Run PHPCS if command -v vendor/bin/phpcs &> /dev/null; then echo "" echo "Running PHPCS..." vendor/bin/phpcs --standard=Drupal,DrupalPractice "$MODULE_PATH" 2>/dev/null || ERRORS=$((ERRORS + 1)) fi # Run PHPStan if command -v vendor/bin/phpstan &> /dev/null; then echo "" echo "Running PHPStan..." vendor/bin/phpstan analyze "$MODULE_PATH" --level=6 2>/dev/null || ERRORS=$((ERRORS + 1)) fi echo "" echo "=== Validation Complete ===" if [ $ERRORS -eq 0 ]; then echo "All checks passed!" exit 0 else echo "Errors found: $ERRORS" exit 1 fi

Usage:

chmod +x validate-drupal.sh ./validate-drupal.sh src/ ./validate-drupal.sh modules/custom/my_module

Code Review Checklist

When reviewing Drupal code, verify:

File Structure

  • <?php is first line
  • declare(strict_types=1); is second line
  • Proper namespace and use statements
  • No trailing whitespace

Type Safety

  • All parameters have type hints
  • All methods have return types
  • No mixed types used
  • Strict types enforced

Documentation

  • Class has DocBlock
  • All public methods documented
  • @param tags for all parameters
  • @return tags on all methods
  • @throws tags for exceptions

Code Quality

  • No lines > 80 characters
  • 2-space indentation consistent
  • Proper brace placement
  • No TODOs or HACKs
  • No \Drupal:: calls (except in hooks)

Testing

  • Unit tests for all public methods
  • Test coverage >= 80%
  • Tests follow Drupal standards
  • Tests pass locally and in CI

Performance

  • No unnecessary loops
  • No repeated database queries
  • Proper caching where needed
  • Efficient algorithms

IDE Integration

PHPStorm Configuration

  1. Settings > PHP > Quality Tools > PHP_CodeSniffer

    • Path to PHP CodeSniffer: /path/to/vendor/bin/phpcs
    • Coding standard: Drupal, DrupalPractice
  2. Settings > PHP > Quality Tools > PHPStan

    • Path to PHPStan: /path/to/vendor/bin/phpstan
    • Configuration file: /path/to/phpstan.neon
  3. Settings > Editor > Inspections

    • Enable: PHP_CodeSniffer validation
    • Enable: PHPStan validation

VS Code Configuration

Install extensions:

  • ikappas.phpcs - PHP CodeSniffer
  • SanderRonde.phpstan-vscode - PHPStan

Configure .vscode/settings.json:

{ "phpcs.enable": true, "phpcs.standard": "Drupal,DrupalPractice", "phpcs.executablePath": "${workspaceFolder}/vendor/bin/phpcs", "phpstan.enabled": true, "phpstan.path": "${workspaceFolder}/vendor/bin/phpstan", "phpstan.configFile": "${workspaceFolder}/phpstan.neon" }

Troubleshooting

PHPCS Not Working

# Verify installation vendor/bin/phpcs --version # Reinstall composer require --dev drupal/coder dealerdirect/phpcodesniffer-composer-installer # Clear cache rm -rf ~/.phpcs-cache

PHPStan Errors

# Update baseline vendor/bin/phpstan analyze --generate-baseline # Clear cache vendor/bin/phpstan clear-result-cache # Verbose output vendor/bin/phpstan analyze -vvv

Line Length Issues

# Find problem files grep -r ".{81,}" src/ --include="*.php" -l # Fix with PHPCBF vendor/bin/phpcbf --standard=Drupal src/ # Manual inspection grep -rn ".{81,}" src/Controller/MyController.php

Resources


Last Updated: 2026-01-08 Maintained by: Agent Platform Development Team