php artisan boost:add-skill easycorp/easyadmin-bundle
Save this content to: AGENTS.md
---
package: easycorp/easyadmin-bundle
source_path: AGENTS.md
repo: https://github.com/EasyCorp/EasyAdminBundle
---
# 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: `<short description>` (e.g., `add_new_field_type`)
- Bug fix: `fix_<issue number>` (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
Welcome, AI assistant. Please follow these guidelines when contributing to this repository.
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+
' and ", no typographic)vendor/ - managed by Composernode_modules/ - managed by Yarnvar/ - Symfony cache/logspublic/bundles/ - generated assetscomposer.lock, yarn.lock - update only via package manager commandsEasyCorp\Bundle\EasyAdminBundle\
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
composer install # Install PHP dependencies
yarn install # Install JS dependencies
Before submitting changes, run these commands to verify them:
If PHP code changed:
./vendor/bin/phpstan analyse passes with no errorsphp-cs-fixer fix --dry-run shows no issues./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 errorsyarn biome check --write shows no issuesmake build-assets completed successfullyIf Twig templates changed:
./vendor/bin/twig-cs-fixer lint templates/ passesIf documentation changed:
make linter-docs to validate RST syntaxIf translations changed:
<short description> (e.g., add_new_field_type)fix_<issue number> (e.g., fix_123)Run the full check suite:
make checks-before-pr
if (null === $value) (project convention)===, !==)return (unless only statement in block)// === Methods for dashboards ===)camelCasesnake_caseSCREAMING_SNAKE_CASEUpperCamelCaseAbstract* (except test cases)*Interface, Traits: *Trait, Exceptions: *Exception*Controller, *Configurator, *Context, *Dto, *Event,
*Field, *Filter, *Subscriber, *Type, *Testsnake_case (e.g., detail_page.html.twig)setUp()/tearDown() in testsdeclare(strict_types=1); to PHP filesUpperCamelCase for case names) instead of constants for fixed sets of valueselse/elseif after return/throwsprintf() for exception messages with get_debug_type() for class namesreturn null; for nullable, return; for voidnew Foo()void return types on test methodsconfig/services.phpconfig/services.php, translations/*.php)@return for void methodsnull last in union types|trans filter (no hardcoded strings)TranslatableInterface)templates/components/ when availablearia-* attributes, semantic tags, labelscamelCase for variables and functionsmargin-block-end instead of margin-bottomkebab-case for class namestests/Unit/ - isolated component teststests/Controller/, tests/Field/ - integration teststests/TestApplication/WebTestCase for functional testsvoid return type to all test methodstest prefix duplication@testWith and data providers when possible to avoid duplicated teststests/Functional/Apps/DoctrineFixturesBundletests/baseline-ignore.txtAvoid these common mistakes:
config/services.php' and ")|transContracts/ contains stable APIelse after return/throw - Return/throw early insteadmake checks-before-pr before every PR=, -, ~, ., " for levels 1-5:: over .. code-block:: php... for folded code)use statements for referenced classes$your-project/Acmeexample.com, example.org, example.netHow can I help you explore Laravel packages today?