doctrine-bootstrap

Explains how OrangeHRM configures the Doctrine ORM EntityManager, entity discovery, caches, and proxies.

Updated Jul 23, 2026
One-click install
npx skills add https://github.com/snow-gift111/orangehrm-ai-sdlc-capstone --skill doctrine-bootstrap-snow-gift111
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: doctrine-bootstrap
Source: https://github.com/snow-gift111/orangehrm-ai-sdlc-capstone/tree/main/.agents/skills/doctrine-bootstrap
Command: npx skills add https://github.com/snow-gift111/orangehrm-ai-sdlc-capstone --skill doctrine-bootstrap-snow-gift111

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? OrangeHRM's Doctrine ORM setup has non-obvious wiring — a single shared EntityManager, multi-path entity discovery across plugin directories, a multi-path PSR-4 namespace in composer.json, and dev/prod cache and proxy splits — and misconfiguring any of these causes confusing errors like "class not found" or "entity has no metadata." This Skill documents the full bootstrap so you can register new plugin entities, debug mapping failures, and extend DQL without trial and error. ## Core Features & Use Cases - Entity registration guidance: Explains the two required registrations (ohrm_plugin_paths for Doctrine scanning and the OrangeHRM\Entity\ PSR-4 array in src/composer.json) plus the composer dump-autoload step that is commonly forgotten. - Cache and proxy management: Documents the dev ArrayAdapter vs prod FilesystemAdapter split, AUTOGENERATE_ALWAYS vs AUTOGENERATE_NEVER proxy strategies, and the bin/console cache:clear and orm:generate-proxies commands needed after entity changes. - Custom DQL functions and enum mapping: Shows how to add custom DQL functions like TIME_DIFF by extending FunctionNode, and how legacy MySQL ENUM columns are mapped to strings via a platform-level type mapping. - Use Case: You create a new plugin with an entity directory and get "Entity 'OrangeHRM\Entity\Foo' has no metadata" at query time — this Skill walks you through the PSR-4 registration, dump-autoload, and cache-clearing steps to fix it. ## Quick Start Ask the agent to explain how to register a new plugin's entity directory with Doctrine and fix the resulting metadata error.

Frequently Asked Questions about doctrine-bootstrap

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I register a new plugin's entity directory in Doctrine?

Add the plugin's entity path to the OrangeHRM\Entity\ PSR-4 array in src/composer.json, then run composer dump-autoload -d src. The ohrm_plugin_paths config picks up plugin entity dirs automatically; in prod also run bin/console orm:generate-proxies and cache:clear.

Why does Doctrine say my entity has no metadata?

The most common cause is a missing PSR-4 path in src/composer.json or a forgotten composer dump-autoload after editing it. Other causes are a stale prod metadata cache (fix with bin/console cache:clear) or a missing @ORM\Entity annotation on the class.

Does OrangeHRM use PHP 8 attributes for Doctrine mapping?

No. OrangeHRM uses Doctrine 2.20 with createAnnotationMetadataConfiguration, so all mapping is docblock @ORM annotations. Adding attributes to a single entity will be ignored, so partial migrations must be avoided.

How do I add a custom DQL function in Doctrine?

Create a class under src/lib/orm/Functions/ extending FunctionNode with parse() and getSql() methods, then register it in Doctrine.php using addCustomStringFunction, addCustomNumericFunction, or addCustomDatetimeFunction. Clear the query cache afterward since DQL parsing is cached.

How are MySQL ENUM columns handled in Doctrine entities?

The bootstrap registers a platform-level mapping of the enum type to string, since DBAL has no built-in enum type. Entities declare the column as type="string" and define allowed values as class constants, such as Employee::MARITAL_STATUS_*.

Why do lazy-loaded relations break after deploying entity changes?

In prod, proxies use AUTOGENERATE_NEVER, so stale proxy classes cause misbehaving lazy relations. Run bin/console orm:generate-proxies and cache:clear; composer's post-autoload-dump script does this automatically on composer install or dump-autoload.