# 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.1+, Symfony 5.4/6.x/7.x/8.x, Doctrine ORM 2.12+ ## 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**: DashboardControllerRegistry, CrudControllerRegistry, TemplateRegistry - **Provider**: AdminContextProvider, FieldProvider - **Typed Collections**: FieldCollection, ActionCollection, FilterCollection - **Argument Resolver**: AdminContextResolver, BatchActionDtoResolver ### Main Namespace `EasyCorp\Bundle\EasyAdminBundle\` ## Directory Structure ``` src/ ├── ArgumentResolver/ # Controller argument resolvers ├── Config/ # Configuration classes (Crud, Dashboard, Action, etc.) ├── Context/ # AdminContext and related context classes ├── Contracts/ # Public interfaces (stable API) ├── Controller/ # AbstractCrudController, AbstractDashboardController ├── Dto/ # Data transfer objects ├── Event/ # Event classes ├── EventListener/ # Event subscribers and listeners ├── Factory/ # ActionFactory, EntityFactory, FieldFactory, etc. ├── Field/ # Field type classes (TextField, AssociationField, etc.) ├── Filter/ # Filter type classes ├── Form/ # Form types and extensions ├── Provider/ # AdminContextProvider, FieldProvider ├── Registry/ # DashboardControllerRegistry, CrudControllerRegistry ├── Router/ # Admin URL generation ├── Security/ # Permission system ├── Twig/ # Twig extensions and components templates/ # Twig templates tests/ ├── Functional/ # Functional tests ├── TestUtils/ # Tests for the utility classes used in tests ├── Unit/ # Unit tests ``` ## Commands ### Development ```bash composer install # Install PHP dependencies yarn install # Install JS dependencies ``` ### Pre-Commit Checklist Before submitting changes, run these commands to verify them: If PHP code changed: - `./vendor/bin/phpstan analyse` passes with no errors - `php-cs-fixer fix --dry-run` shows no issues - Run tests with: ```bash ./vendor/bin/simple-phpunit # All tests ./vendor/bin/simple-phpunit tests/Field/ # Specific directory ./vendor/bin/simple-phpunit --filter=testName # Specific test USE_PRETTY_URLS=1 ./vendor/bin/simple-phpunit tests/Controller/PrettyUrls/ # only when working on pretty URLs feature ``` If JS/CSS changed: - `yarn ci` passes with no errors - `yarn biome check --write` shows no issues - `make build-assets` completed successfully If Twig templates changed: - `./vendor/bin/twig-cs-fixer lint templates/` passes If documentation changed: - `make linter-docs` to validate RST syntax If translations changed: - all locales updated consistently; use English as placeholder if unsure ## 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: `` (e.g., `add_new_field_type`) - Bug fix: `fix_` (e.g., `fix_123`) - Use lowercase with underscores ### Before Creating a PR Run the full check suite: ```bash make checks-before-pr ``` ## PHP Code Standards ### Syntax and Style - PHP 8.1+ syntax with constructor property promotion - PSR-1, PSR-2, PSR-4, PSR-12 standards - Yoda conditions: `if (null === $value)` (project convention) - Strict comparisons only (`===`, `!==`) - Braces required for all control structures - Trailing commas in multi-line arrays - Blank line before `return` (unless only statement in block) - Don't add comments in classes as separators (e.g. `// === Methods for dashboards ===`) ### 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 its 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 `setUp()`/`tearDown()` in tests 3. Method order: public, protected, private ### Code Practices - Don't add `declare(strict_types=1);` to PHP files - Use enums (use `UpperCamelCase` for case names) instead of constants for fixed sets of values - Avoid `else`/`elseif` after return/throw - Use `sprintf()` for exception messages with `get_debug_type()` for class names - Exception messages: capital letter start, period end, no backticks - `return null;` for nullable, `return;` for void - Always use parentheses when instantiating: `new Foo()` - Add `void` return types on test methods - No service autowiring - configure explicitly in `config/services.php` - Comments: only for complex/unintuitive code, lowercase start, no period end - Error messages: concise but precise and actionable (e.g. include class names, file paths) - Handle exceptions explicitly (no silent catches) - Config files in PHP format (`config/services.php`, `translations/*.php`) - Prefer project constants (Action::EDIT, EA::QUERY) over hardcoded strings ### PHPDoc - No `@return` for void methods - No single-line docblocks - Group annotations by type - `null` last in union types ## Templates (Twig) - Modern HTML5 and Twig syntax - Icons: FontAwesome 6.x names - All user-facing text via `|trans` filter (no hardcoded strings) - Translation logic in templates, not PHP (use `TranslatableInterface`) - Use components from `templates/components/` when available - Accessibility: `aria-*` attributes, semantic tags, labels ## JavaScript - ES6+ syntax - 4-space indentation - `camelCase` for variables and functions ## CSS - Standard CSS only (no SCSS/LESS) - 4-space indentation - Bootstrap 5.3 classes and utilities - Don't use nested rules - Logical properties: `margin-block-end` instead of `margin-bottom` - `kebab-case` for class names - Responsive design required; use only these Bootstrap breakpoints: - Medium (md): ≥768px - Large (lg): ≥992px - Extra large (xl): ≥1200px ## Testing ### Test Structure - **Unit tests**: `tests/Unit/` - isolated component tests - **Functional tests**: `tests/Controller/`, `tests/Field/` - integration tests - **Test applications**: Real Symfony apps in `tests/TestApplication/` ### Writing Tests - Extend `WebTestCase` for functional tests - Use simple names: 'Action 1', 'Field 1', not realistic data - Add `void` return type to all test methods - Name tests descriptively without `test` prefix duplication - Use `@testWith` and data providers when possible to avoid duplicated tests ### Test Fixtures - Data fixtures in each functional app in `tests/Functional/Apps/` - Doctrine fixtures loaded via `DoctrineFixturesBundle` - Deprecation baseline: `tests/baseline-ignore.txt` ## Anti-Patterns Avoid these common mistakes: - **Don't use service autowiring** - Configure explicitly in `config/services.php` - **Don't add typographic quotes** - Use straight quotes only (`'` and `"`) - **Don't hardcode user-facing text** - Always use translations with `|trans` - **Don't modify public interfaces lightly** - `Contracts/` contains stable API - **Don't use `else` after `return`/`throw`** - Return/throw early instead - **Don't use inline hyperlinks in docs** - Separate link text from URLs - **Don't use SCSS/LESS** - Standard CSS only - **Don't use nested CSS rules** - Keep selectors flat - **Don't skip pre-PR checks** - Run `make checks-before-pr` before every PR ## 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