unite-cms/core-bundle
Unite CMS CoreBundle is the foundational Symfony bundle for the Unite CMS headless content management system. It provides core services, configuration, and integration points for managing structured content, building custom APIs, and supporting extensible admin workflows.
Reality check before you type composer require: this is a Symfony bundle, not a Laravel package. It assumes Symfony's DI container, event dispatcher, security voters, Doctrine ORM/DBAL, and its own GraphQL schema builder. It will not "just install" into a Laravel app. The day-to-day leverage you get is one of two shapes:
Minimal path to a first query (sidecar route):
composer.json constraints and build the sidecar on a matching skeleton (e.g. Symfony 4.4). Do not attempt a modern Symfony 6/7 install.composer require unite-cms/core-bundle, register UniteCMS\CoreBundle\UniteCMSCoreBundle, configure Doctrine + the unite_cms_core config block, and create schema tables.Where to look first in the source:
ContentType/ and FieldType/ — the type system and manager services.Domain/ — multi-tenant resolution and domain-scoped config.GraphQL/ — how field types contribute to the generated schema.Security/ — role-based, field-aware permissions.First real use case: model an Article (title/slug/body), create a domain, insert a record, read it back over GraphQL from a Laravel HTTP client. Once that loop closes, everything else (permissions, custom field types, event listeners) is incremental.
Model content types as data, not code. Content types live in the database as runtime configuration (name, fields, settings), managed by the content type manager. In practice you seed them from a fixture or console command — build a ContentType, attach FieldType instances, persist via the manager. Keep a repeatable seeder per environment because there is no migration story for content-type changes in this bundle.
Go through the manager services, not the Doctrine entities. The bundle exposes a content type manager, field type manager, and domain manager as DI services. Resolve them from the container in commands, fixtures, and tests. Treating the entities as your API invites breakage when schema changes or lifecycle events fire.
Custom field types are the main extension point. Implement the field type interface, register it as a service and add it to the field type manager (tagged service or explicit addFieldType call — check which your version supports). You inherit GraphQL type generation and validation for free.
Use lifecycle events for cross-cutting behavior. Subscribe with a standard Symfony listener to do slug generation, audit logging, cache invalidation, or webhook dispatch instead of overriding core services.
Never let Unite types leak into Laravel domain code. Wrap the GraphQL client behind an adapter interface (e.g. ContentRepository) on the Laravel side. DTOs in, arrays out. This keeps the sidecar swappable and makes the day-to-day cost of the framework mismatch manageable.
Domain resolution belongs at the edge. Resolve the domain early (host/subdomain via the domain manager) and scope every query to it. A small request-scoped "current domain" service beats threading domain IDs through every layer.
GraphQL is your integration surface. Register your own *.graphql queries/mutations; the schema builder merges core and app schemas. Keep resolvers thin and delegate to managers. On the Laravel side, cache query results with tagged cache keys per domain/content type.
Testing pattern. Boot a Symfony kernel with the bundle and SQLite in CI, seed one domain + one content type per test, and assert against the GraphQL endpoint. On the Laravel side, contract-test your adapter against a recorded GraphQL fixture.
ReturnTypeWillChange issues. Check composer.json constraints and composer why-not before committing; assume fork ownership.bin/console cache:clear.unite_cms_core throw at container compile time. Use bin/console debug:config unite_cms_core instead of guessing key names.doctrine:schema:update blind. Don't share table prefixes with app entities.bin/console debug:container | grep unite finds manager services and listeners; GraphiQL against the endpoint is the fastest way to confirm a type/field made it into the schema.How can I help you explore Laravel packages today?