Skip to content

Migrating to version 6.0

Runtime requirements

Use PHP 8.5, Doctrine ORM 3.7+, DBAL 4.5+, Symfony Cache/Console 8, and doctrineextensions 1.5+. CodeIgniter 4.7+ is required only by the adapter. Composer enforces these requirements. Security advisories remain enabled for the development environment; use a supported, patched PHP build for Composer updates.

Doctrine always uses native lazy objects. Remove proxyFactory, proxies, proxiesNamespace, and setAutoGenerateProxyClasses from app/Config/Doctrine.php. Do not generate proxy classes during deployment. The published config is now a minimal subclass of the package config, containing only application overrides.

Package and namespace split (6.x)

The core daycry/doctrine no longer installs or boots CodeIgniter. CI4 applications must require daycry/doctrine-codeigniter4:^6.0, which also installs the core. The installation guide describes Packagist releases and local path repositories for development.

Previous CI4 API Adapter API
Daycry\Doctrine\Doctrine with CI4 config arguments Daycry\Doctrine\CodeIgniter4\Doctrine
Daycry\Doctrine\Config\Doctrine Daycry\Doctrine\CodeIgniter4\Config\Doctrine
Daycry\Doctrine\Config\Services Daycry\Doctrine\CodeIgniter4\Config\Services
Daycry\Doctrine\Commands, Debug, Libraries, Boot Same suffixes under Daycry\Doctrine\CodeIgniter4
Daycry\Doctrine\Helpers\getFromCacheOrQuery Daycry\Doctrine\CodeIgniter4\Helpers\getFromCacheOrQuery

Update imports, toolbar/filter registrations and application config inheritance. Republish cli-config.php because its imports also changed. The service names, Spark command names and framework helper doctrine_instance() remain available through the adapter. No namespace aliases or legacy constructor shims are provided.

Standalone code uses Daycry\Doctrine\Configuration and passes DBAL connection parameters to Daycry\Doctrine\Doctrine. Supply PSR-6 pools and a PSR-3 logger explicitly. DataTables\Builder now throws SPL InvalidArgumentException.

DataTables API changes

Removed API/behavior Replacement
getData() $page = $builder->getPage(); $rows = $page->getItems();
getRecordsFiltered() $page->getTotalCount() on the same page
setUseOutputWalkers(bool) withOutputWalkers(bool)
withIndexColumn() Remove the call; identifiers come from ORM metadata
DBAL QueryBuilder input Pass an ORM QueryBuilder; invalid types raise TypeError
Unlimited page size / withMaxPageLength(0) A positive cap; default 200
Zero page length or negative start Send a positive length and non-negative start

getPage() returns Doctrine's immutable WindowPage with rows, filtered total and window metadata. Read its items and total from the same instance to avoid repeated queries. getRecordsTotal() remains available for a standalone unfiltered count or an injected withRecordsTotal() value. getResponse() returns the DataTables JSON shape and casts draw to a non-negative integer.

length=-1 is clamped to the page cap, and an omitted length defaults to 10. For large exports, use an application-level batch/streaming endpoint.

The default output-walker behavior remains safe for entity queries and HAVING. For scalar-select queries, use withOutputWalkers(false) when required. Queries with to-many fetch joins should retain withFetchJoinCollection(true).

Caches, groups, and reopened managers

Result-cache pools use a zero default lifetime. Set an explicit lifetime on results that must expire. getFromCacheOrQuery(..., ttl: 0, ...) persists until invalidation. The file backend uses FilesystemAdapter for dynamic results/SLC and PhpFilesAdapter for query/metadata caches.

Group names are case-sensitive. Implicit and explicit calls for the same effective group share one instance. Under testing the effective implicit group is tests. Service/cache keys encode exact group names; named groups may start with cold caches.

reOpen() uses the constructor configuration. It creates a fresh EntityManager and reapplies configured listeners, types and enabled filters. Reapply runtime filter parameters before issuing queries, and reload previously managed entities.

READ_WRITE SLC uses file locks. Processes sharing cached regions must share the configured secondLevelCacheLockPath or supply a suitable concurrent region.

Deployment sequence

  1. Update dependencies using PHP 8.5 and apply the API/config changes above. In the consuming application, commit its lockfile and deploy with composer install --no-dev --optimize-autoloader --no-interaction.
  2. Clear the package query/result/metadata pools for each configured group: php spark doctrine:cache:clear --group <group>.
  3. Invalidate the application's SLC entity, collection and query regions when their mappings/data layout change. The cache:clear command does not evict SLC regions.
  4. Run php spark doctrine:cache:warmup --group <group> to load metadata.
  5. Run php spark doctrine:doctor --group <group> --json and require exit code zero.
  6. Validate or migrate the schema with the application's migration process before routing traffic to the new release. Warmup and doctor do not modify the schema.

An ArrayAdapter warning means metadata is process-local. Use a persistent backend for deployment warmup. Doctor validates mappings/connectivity/cache access, not schema synchronization; use doctrine:validate for the latter.