Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Illuminate Contao Laravel Package

mpociot/illuminate-contao

Bridges Laravel's Illuminate components with Contao CMS, making database, container, events, and related APIs available inside Contao. Use familiar Laravel-style patterns and Eloquent workflows without leaving your Contao project.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Verify the host before anything else. The bridge targets Composer-managed Contao 4.x with PSR-4 autoloading. Contao 3's system/modules layout and bespoke autoloader are effectively unsupported. Confirm your Contao major and PHP version first — this is the gate that ends most adoption attempts.

2. Pin exactly. composer require mpociot/illuminate-contao:0.1.0. There is one tag, no changelog, and no semver promise. A caret range is an uncontrolled upgrade path on a package with zero dependents.

3. Read vendor/mpociot/illuminate-contao/composer.json, then src/. There is no documentation, so the source is the documentation. Two things to extract:

  • The illuminate/* constraints — these dictate which Laravel components get resolved next to your app, and whether they collide with anything already installed.
  • The bootstrap entry point. Look for where the Illuminate container is populated and where the database connection is configured (most likely a Capsule\Manager setup reading Contao's $GLOBALS['TL_CONFIG']['db*'] values). Note whether it self-registers or expects a manual call from your contao/ bootstrap or a bundle class.

4. Smoke-test inside one custom module you own. Three checks, in order: resolve a trivial class from the container; dispatch a no-op event; run one query-builder select() against an existing tl_ table. If the connection isn't configured from Contao's settings, fix that before writing any real code.

First use case: take one hand-written \Database::getInstance()->prepare(...)->execute(...) read and re-express it as a fluent query wrapped in an Illuminate\Support\Collection. Small, reversible, and it exercises exactly the two things you need to trust — connection config and query building.

Implementation Patterns

Container-first services. The daily win is writing business logic as plain classes with constructor dependencies and resolving them from the Illuminate container, instead of new-ing objects or reaching into $GLOBALS. A Contao content element or frontend module becomes a thin adapter that pulls a service out of the container and calls one method. That service is then directly instantiable in a unit test with fakes — which is the entire point.

$reporter = $container->make(SalesReporter::class);
$rows = $reporter->forMonth($month); // returns a Collection

Query builder as an escape hatch, not a lifestyle. Keep Contao's Database class for anything the CMS itself owns — DCA-driven CRUD, framework internals, migrations. Use the builder for reporting queries, multi-table joins, and pagination, where its ergonomics actually pay off. Configure the connection from Contao's own settings rather than duplicating credentials in a second config file.

Eloquent on tl_ tables, with conventions explicitly disabled. Contao tables don't have created_at/updated_at, and key shapes vary. Every model needs:

protected $table = 'tl_news';
protected $primaryKey = 'id';
public $timestamps = false;
protected $guarded = [];

Do not assume Laravel defaults carry over. Where a tl_ table has a composite or non-id key, stay on the query builder rather than fighting Eloquent's assumptions.

Hook → event bridge. Convert Contao hooks (initializeSystem, loadDataContainer, DCA callbacks, custom $GLOBALS['TL_HOOKS'] entries) into Illuminate events, so listeners are dependency-injected classes instead of global functions. Keep the shim itself to two or three lines — the listener does the work.

Hydrate into DTOs, not arrays. A pattern that holds up well: a repository class runs a builder query, maps rows to readonly value objects inside ->map(), and returns a Collection. Callers get typed properties instead of $row['foo'] string keys, and the query builder never leaks past the repository.

Pagination and reporting. ->paginate() from the builder is a genuine day-to-day win over hand-rolled LIMIT/OFFSET with a separate count query — use it for backend listing views and exports.

Adapter boundary. Put the bridge behind a thin interface your modules call (Db, Events, Container). With zero dependents and no release history, that boundary doubles as your removal plan: swapping the implementation for hand-rolled Capsule wiring later touches one file.

Testing. Boot a minimal Capsule container in your test bootstrap against in-memory SQLite with the tl_ tables you need, so query-builder and repository tests run without a Contao install. Use a spy listener or the dispatcher's assertion helpers for event tests — check they exist in the resolved Illuminate version first.

Gotchas and Tips

  • Two containers, no shared lifetimes. Contao 4 runs a Symfony container (System::getContainer()); the bridge adds an Illuminate one. Resolve each type from exactly one container. Never let a Symfony service leak into an Illuminate singleton — that's how stale state appears in long-running workers and cron.

  • Two PDO connections, one database. Mixing Database::getInstance() and the query builder inside one unit of work means the two connections cannot see each other's uncommitted transactions. Pick one per transaction. Also verify charset and PDO::ATTR_EMULATE_PREPARES match Contao's own settings, or you'll get subtly different escaping behaviour between paths.

  • Container/config cache. After changing registrations, clear Contao's cache (cache:clear, wipe var/cache). A cached container silently ignores new bindings and sends you debugging the wrong layer.

  • Double dispatch. Registering the same hook through both Contao and the bridge fires listeners twice. Keep one registration point and comment it.

  • Serialized columns. Some tl_ columns hold PHP-serialized arrays. The builder returns them as raw strings; Eloquent casts won't rescue you. Unserialize explicitly at the hydration boundary.

  • Illuminate version drift. The bridge's constraints may resolve an Illuminate version well behind current Laravel. Helpers you reach for reflexively in Collection, Str, or the builder may not exist. Check vendor/illuminate/* before assuming.

  • Schema changes stay in Contao. Do not use Eloquent's schema builder or migrations against tl_ tables — Contao's install tool and DCA definitions own that schema, and a parallel migration path will drift.

  • Debugging. Capsule::connection()->enableQueryLog() / getQueryLog() for the DB side; dump the container's bindings for the DI side. Both beat guessing at the wiring.

  • Pin, then review every bump by hand. A 0.2.x may rename methods or move namespaces with no deprecation cycle. Upgrade = read the diff + rerun the smoke test.

  • Ownership reality. Zero dependents, no release notes: you are the de facto maintainer. Timebox the spike, keep the adapter boundary, and be prepared to vendor the source into your repo. If the spike shows the bridge is a few hundred lines of glue, reimplementing it in-house may be cheaper than tracking it — that's a legitimate outcome, not a failure.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo