Skip to content

Latest commit

 

History

History
193 lines (152 loc) · 8.69 KB

File metadata and controls

193 lines (152 loc) · 8.69 KB

AI Contribution Guidelines

Welcome, AI assistant. Please follow these guidelines when contributing to this repository.

Project Overview

EasyAdminBundle is a third-party Symfony bundle for creating admin backends. It provides CRUD controllers, dashboard management, and extensive field/filter configuration.

Requirements: PHP 8.2+, Symfony 6.4/7.x/8.x, Doctrine ORM 2.20+ or 3.6+

General Rules

  • Language: American English for code, comments, commits, branches
  • Code quotes: wrap strings with single quotes in PHP, CSS, JavaScript
  • Text quotes: straight quotes only (' and ", no typographic)
  • Security: prevent XSS, CSRF, injections, auth bypass, open redirects

Do Not Edit

  • vendor/ - managed by Composer
  • node_modules/ - managed by Yarn
  • var/ - Symfony cache/logs
  • public/bundles/ - generated assets
  • composer.lock, yarn.lock - update only via package manager commands

Architecture

Key Patterns

  • Factory: ActionFactory, EntityFactory, FieldFactory, FilterFactory, FormFactory
  • Configurator Chain: FieldConfiguratorInterface, FilterConfiguratorInterface
  • Context Facade: AdminContext wraps Request/Crud/Dashboard/I18n contexts
  • DTO Layer: Type-safe data transfer (ActionDto, EntityDto, FieldDto, etc.)
  • Event Subscriber: AdminRouterSubscriber, CrudAutocompleteSubscriber
  • Registry: AdminControllerRegistry, TemplateRegistry
  • Provider: AdminContextProvider, FieldProvider
  • Typed Collections: FieldCollection, ActionCollection, FilterCollection
  • Argument Resolver: AdminContextResolver, BatchActionDtoResolver

Don't modify the public API in Contracts/ lightly — it's a stable, versioned interface that third-party code depends on.

Design Principles

  • Never surface internal complexity to end users. Keep the public API small, simple, and consistent; push complexity down into internal classes (factories, configurators, DTOs), not onto the people configuring a backend.
  • Public APIs are stable contracts: prefer additive, backward-compatible changes and don't leak internal types or implementation details through them.

Backward Compatibility

Follow Symfony's BC policy: never break public API — deprecate first, keep the old path working, remove only in the next major. Emit deprecations with @trigger_deprecation('easycorp/easyadmin-bundle', '<version>', '<message>'), naming the replacement and removal version.

Configuration Model

User-facing config uses fluent builders (Config/, Field/): static new() + chainable setters returning self. Each builder converts via getAsDto() into an immutable DTO (Dto/) for internal use. New configurable concepts follow this split — fluent builder for users, DTO internally; never expose a DTO as the config surface.

Main Namespace

EasyCorp\Bundle\EasyAdminBundle\

Commands

The Makefile is the source of truth for build/lint/test commands; its targets match what CI runs. Prefer them over hand-typed invocations. Run make help to list every target.

Setup

make build          # composer update + yarn install (first-time setup)
composer install    # PHP dependencies only
yarn install        # JS dependencies only

Before Creating a PR

Run the full check suite (linters + tests, identical to CI):

make checks-before-pr

Pre-Commit Checklist

Run the relevant target(s) for what you changed:

Changed Run
PHP code make linter-phpstan, make linter-cs-fixer, make tests
JS / CSS yarn ci, then make build-assets
Twig templates make linter-twig
Documentation make linter-docs
Translations keep all locales consistent; use English as placeholder if unsure

Run targeted tests with make tests ARGS=... (keeps the deprecation baseline and cache reset; full guide in tests/AGENTS.md):

make tests                            # whole suite
make tests ARGS="tests/Unit/Field/"   # one directory
make tests ARGS="--filter=testFoo"    # one test

A bare ./vendor/bin/simple-phpunit run skips the deprecation baseline (tests/baseline-ignore.txt) and the cache reset.

Git and Pull Requests

Commit Messages

  • Use imperative mood: "Add feature" not "Added feature"
  • First line: concise summary (50 chars max)
  • Reference issues when applicable: "Fix #123"
  • No period at end of subject line

Branch Naming

  • Feature: <short description> (e.g., add_new_field_type)
  • Bug fix: fix_<issue number> (e.g., fix_123)
  • Use lowercase with underscores

PHP Code Standards

php-cs-fixer (@Symfony + @Symfony:risky) auto-formats most style — trailing commas, braces, strict comparisons, Yoda conditions, blank lines, quotes, etc. Run make linter-cs-fixer and let it handle formatting. The rules below are the conventions it does not enforce.

Conventions

  • PHP 8.2+ syntax with constructor property promotion
  • Don't add declare(strict_types=1); to PHP files
  • No service autowiring — configure explicitly in config/services.php
  • Use enums (UpperCamelCase case names) instead of constants for fixed sets of values
  • Prefer project constants (Action::EDIT, EA::QUERY) over hardcoded strings
  • Avoid else/elseif after return/throw — return/throw early instead
  • return null; for nullable, return; for void
  • Use sprintf() for exception messages with get_debug_type() for class names
  • Exception/error messages: start capital, end with a period, no backticks; concise but actionable (include class names, file paths)
  • Handle exceptions explicitly (no silent catches)
  • Comments: only for complex/unintuitive code, lowercase start, no period end; never as section separators (e.g. // === Methods for dashboards ===)
  • Config files in PHP format (config/services.php, translations/*.php)

Naming

  • Variables/methods: camelCase
  • Config/routes/Twig: snake_case
  • Constants: SCREAMING_SNAKE_CASE
  • Classes: UpperCamelCase
  • Abstract classes: Abstract* (except test cases)
  • Interfaces: *Interface, Traits: *Trait, Exceptions: *Exception
  • Most classes add a suffix showing their type: *Controller, *Configurator, *Context, *Dto, *Event, *Field, *Filter, *Subscriber, *Type, *Test
  • Templates/assets: snake_case (e.g., detail_page.html.twig)

Class Organization

  1. Properties before methods
  2. Constructor first, then public, protected, private methods in that order

PHPDoc

  • No single-line docblocks
  • No @return for void methods
  • Group annotations by type

Templates (Twig)

twig-cs-fixer handles formatting (make linter-twig). Conventions it doesn't enforce:

  • Modern HTML5 and Twig syntax
  • Icons: FontAwesome 6.x names
  • All user-facing text via |trans filter (no hardcoded strings)
  • Keep translation logic in templates, not PHP (use TranslatableInterface)
  • Reuse components from templates/components/ when available — see src/Twig/Component/AGENTS.md before adding or changing a component
  • Accessibility: aria-* attributes, semantic tags, labels

JavaScript

biome handles formatting (yarn ci). Conventions it doesn't enforce:

  • ES6+ syntax
  • camelCase for variables and functions

CSS

  • Standard CSS only (no SCSS/LESS)
  • Don't use nested rules — keep selectors flat
  • kebab-case for class names
  • Bootstrap 5.3 classes and utilities
  • Logical properties: margin-block-end instead of margin-bottom
  • Responsive design required; use only these Bootstrap breakpoints:
    • Medium (md): ≥768px
    • Large (lg): ≥992px
    • Extra large (xl): ≥1200px

Documentation (doc/)

  • Format: reStructuredText (.rst)
  • Heading symbols: =, -, ~, ., " for levels 1-5
  • Line length: 72-78 characters
  • Code blocks: prefer :: over .. code-block:: php
  • Separate link text from URLs (no inline hyperlinks)
  • Show config in order: YAML, XML, PHP (or Attributes)
  • Code line limit: 85 chars (use ... for folded code)
  • Include use statements for referenced classes
  • Bash lines prefixed with $
  • Root directory: your-project/
  • Vendor name: Acme
  • URLs: example.com, example.org, example.net
  • Trailing slashes for directories, leading dots for extensions

Writing Style

  • American English, second person (you)
  • Gender-neutral (they/them)
  • Use contractions (it's, don't, you're)
  • Avoid: "just", "obviously", "easy", "simply"
  • Realistic examples (no foo/bar placeholders)
  • Write for non-native English speakers: use simple vocabulary, avoid idioms, and complex sentence structures