Controllers
Chamilo 2.0 uses a large number of controllers (in the order of dozens) organized across the bundles. The exact count drifts version to version — treat the names below as illustrative, not exhaustive.
Controller Types
Admin Controllers
Located in src/CoreBundle/Controller/Admin/. Handle platform administration:
AdminController— Dashboard, file info, email testingUserListController— User CRUDCourseListController— Course managementSessionAdminController— Session managementSettingsController— Platform settingsSecurityController— Login attempts, IDS eventsPluginsController— Plugin managementRoomController— Room management
API Action Controllers
Custom API Platform actions in src/CoreBundle/Controller/Api/:
These extend API Platform's built-in CRUD with custom business logic. Examples:
CreateDocumentFileAction— File upload for documentsCreateStudentPublicationFileAction— Assignment submission uploadUpdateVisibilityDocument— Toggle document visibilityExportCGlossaryAction— Export glossaryMoveDocumentAction— Move a document to a different folder
For read/write operations that don't need a dedicated HTTP controller — i.e. when you only want to change how an item or collection is fetched or persisted — prefer a State Provider or State Processor (see below). API Action Controllers are best reserved for endpoints that genuinely need request-level logic (file uploads, custom response formats, multi-step flows).
AI Controller
src/CoreBundle/Controller/AiController.php is the entry point for AI-related endpoints (Aiken question generation, learning-path generation, image/video generation, open-answer grading, document analysis…). The exact set of routes evolves quickly — read the controller's #[Route] attributes for the current list rather than relying on a copy here.
Chat Controller
src/CoreBundle/Controller/ChatController.php handles real-time chat and AI tutor:
User-to-user messaging
AI tutor chat (docked chat panel)
Message history and polling
API Platform State Providers & Processors
Not every API endpoint is backed by a controller. API Platform 3 splits the work between two interfaces:
State Providers (
ApiPlatform\State\ProviderInterface) — return data forGEToperations (a single item or a collection).State Processors (
ApiPlatform\State\ProcessorInterface) — handle writes forPOST,PUT,PATCH, andDELETEoperations.
Chamilo's implementations live in src/CoreBundle/State/ (around 35+ classes). They are wired to entities via the provider: and processor: arguments of #[ApiResource] operations rather than via routes.
When to use them
Reach for a provider/processor — instead of an API Action Controller — when:
The endpoint follows the standard REST shape (list / read / create / update / delete) but needs custom data assembly or persistence logic.
You need to filter, denormalize, or enrich the result of a collection or item read (e.g. respecting the current Access URL, course context, or visibility rules).
You need to run side effects on write (audit logs, file generation, related-entity updates) while keeping API Platform's normalization, validation, and pagination pipeline.
You want to keep the operation discoverable in the OpenAPI / Hydra schema without registering a custom route.
If the endpoint instead needs raw Request access, returns a non-resource payload (file download, CSV, redirect), or orchestrates a multi-step flow, an API Action Controller in src/CoreBundle/Controller/Api/ is a better fit.
Wiring on the entity
Reference the class on the operation:
Provider example
src/CoreBundle/State/DocumentProvider.php resolves a CDocument by URI variable and throws NotFoundHttpException when missing:
Processor example
src/CoreBundle/State/ColorThemeStateProcessor.php delegates to the default Doctrine persistProcessor, then runs side effects (generates a CSS file on the themes Flysystem filesystem, links the theme to the current Access URL):
Patterns to know
Compose with the default processor. Decorate
ProcessorInterface $persistProcessor(Doctrine's built-in) so Chamilo-specific logic runs around the standard persist, not instead of it.Collection providers do their own pagination. When a collection provider builds a custom query, it must respect
?page,?itemsPerPage, and search filters — API Platform's automatic paginator only kicks in for the default Doctrine collection provider.One class per resource + operation kind is common, but a provider can serve several operations (see
UsergroupStateProvider, reused across four operations onUsergroup).Naming convention:
<Entity>StateProvider/<Entity>StateProcessorfor resource-wide handlers;<Entity><Action>Processor(e.g.CBlogAssignAuthorProcessor,CStudentPublicationDeleteProcessor) for narrower operations.
Routing
Controllers use PHP 8 attributes for route definitions:
API Platform resources use #[ApiResource] attributes on entities, with custom operations pointing to controller actions.
Traits
Controllers use shared traits for common functionality:
ControllerTrait— Access to settings, serializer, and common servicesCourseControllerTrait— Course context helpersResourceControllerTrait— Resource node operations
Last updated
Was this helpful?