Environment State Manager 

Extension key

environment_state_manager

Package name

fgtclb/environment-state-manager

Version

main

Language

en

Author

FGTCLB GmbH

License

This document is published under the Open Content License.

Rendered

Sat, 20 Jun 2026 20:26:32 +0000


TYPO3 CMS extension providing an environment builder and a state manager. It builds and applies a fully featured TYPO3 environment (request, controller context, TypoScript, language and visibility aspects, …) for a given page and safely backs up and restores the global state around such an operation.

This functionality was extracted from fgtclb/academic-base into a dedicated, reusable extension.

Over the time there has been multiple extensions to allow the creation of the TypoScriptFrontendController (TSFE) but missed all the other handling and state in various places. They further lacked all a proper state management and build when used in FE or BE web-requests and did not returned to the previous state leaving the context in a populated (broken) state, something this extension tries to handle more properly over the different TYPO3 versions.

It ca be used in tasks, commands, schedulers, frontend requests, backend requests and also within functional tests to properly build the more global state.


Introduction 

Learn what the extension provides and when to use it.

Administration 

Install and update the extension in your TYPO3 installation.

Developer Corner 

Technical description and code examples for the environment builder and the state manager.

Contribution 

Set up a development environment, run the tests and follow the commit message rules.

Changelog 

Overview of the changes per released version.

Introduction 

What does it do? 

The Environment State Manager extension provides a programmatic way to build, apply and restore a TYPO3 environment.

It is useful whenever code that usually runs in a frontend request context has to be executed in a different context – for example in a backend module, a command line task or a middleware – where a fully initialized frontend environment (request, frontend controller, TypoScript, language and visibility aspects) is not available.

Features 

  • EnvironmentBuilderFactory returning a TYPO3 core version compatible environment builder for TYPO3 v12 and v13. A FrontendEnvironmentBuilder is shipped today; a backend environment builder is planned.
  • StateManager to build, apply and restore an environment state.
  • StateApplyEvent and StateBackupEvent PSR-14 events dispatched around applying and backing up the state.

Compatibility 

Branch Extension TYPO3 PHP
main 1.x v12 / v13 8.1 - 8.5

Installation 

The extension has to be installed like any other TYPO3 CMS extension. You can install the extension using one of the following methods:

  1. Use composer: Run

    composer require fgtclb/environment-state-manager
    Copied!

    in your TYPO3 installation.

  2. Get it from the Extension Manager: Switch to the module Admin Tools > Extensions. Switch to Get Extensions and search for the extension key environment_state_manager and import the extension from the repository.
  3. Get it from typo3.org: You can always get the current version from TER by downloading the zip version. Upload the file afterwards in the Extension Manager.

The extension does not require any further configuration. See the Developer Corner on how to use the provided services.

Updates 

This page documents update and migration steps between major versions.

Version 1.x 

This is the initial release of the standalone extension. There are no migration steps required for a fresh installation.

The environment builder and state manager were extracted from fgtclb/academic-base. Code that previously consumed the feature through the fgtclb/academic-base internal classes needs to switch to the new package and namespace:

  • Require fgtclb/environment-state-manager in addition to (or instead of) relying on the classes shipped within fgtclb/academic-base.
  • Replace the FGTCLB\AcademicBase\Environment\* namespace with FGTCLB\EnvironmentStateManager\* and drop the Environment sub-namespace segment, for example FGTCLB\AcademicBase\Environment\StateManagerInterface becomes FGTCLB\EnvironmentStateManager\StateManagerInterface.

Developer Corner 

This chapter describes the API provided by the extension and shows how to use the environment builder and the state manager. Always depend on the public interfaces and let dependency injection resolve the TYPO3 core-version specific implementation; see Public API and stability for what is covered by the backward-compatibility promise and what is internal.

Environment Builder 

An environment builder creates a StateInterface instance describing a fully bootstrapped TYPO3 environment for a given StateBuildContext.

The build context 

The StateBuildContext is a small, immutable DTO describing what environment should be built:

use FGTCLB\EnvironmentStateManager\StateBuildContext;
use TYPO3\CMS\Core\Http\ApplicationType;

$stateBuildContext = new StateBuildContext(
    applicationType: ApplicationType::FRONTEND,
    pageId: 1,
    languageId: 0,
);
Copied!

The factory 

The concrete builder differs between the supported TYPO3 core versions. Use the EnvironmentBuilderFactoryInterface to retrieve a TYPO3 core version compatible builder for the given context. The factory is registered as a public service and can be injected through dependency injection:

use FGTCLB\EnvironmentStateManager\EnvironmentBuilderFactoryInterface;
use FGTCLB\EnvironmentStateManager\StateBuildContext;
use FGTCLB\EnvironmentStateManager\StateInterface;
use TYPO3\CMS\Core\Http\ApplicationType;

final class MyService
{
    public function __construct(
        private readonly EnvironmentBuilderFactoryInterface $environmentBuilderFactory,
    ) {}

    public function buildState(int $pageId): StateInterface
    {
        $stateBuildContext = new StateBuildContext(
            applicationType: ApplicationType::FRONTEND,
            pageId: $pageId,
            languageId: 0,
        );

        $environmentBuilder = $this->environmentBuilderFactory->create($stateBuildContext);

        return $environmentBuilder->build($stateBuildContext);
    }
}
Copied!

The returned StateInterface holds the bootstrapped environment elements, for example the ServerRequestInterface, the TypoScriptFrontendController, the PageRenderer and the Context.

In most cases you do not interact with the builder directly but use the state manager, which uses the factory internally.

State Manager 

The StateManagerInterface is the central, public service of this extension. It bootstraps an environment for a given context, applies it to the global TYPO3 state and is able to back up and restore that state.

The state manager is registered as a public service and resolved to a TYPO3 core version compatible implementation. Inject it through dependency injection:

use FGTCLB\EnvironmentStateManager\StateManagerInterface;

final class MyService
{
    public function __construct(
        private readonly StateManagerInterface $stateManager,
    ) {}
}
Copied!

Execute code within an environment 

The recommended way to run code inside a built environment is the execute() method. It backs up the current environment, bootstraps the environment described by the StateBuildContext, runs the given closure and restores the previous environment afterwards – even if the closure throws:

use FGTCLB\EnvironmentStateManager\StateBuildContext;
use TYPO3\CMS\Core\Http\ApplicationType;

$stateBuildContext = new StateBuildContext(
    applicationType: ApplicationType::FRONTEND,
    pageId: 42,
    languageId: 0,
);

$this->stateManager->execute($stateBuildContext, function () {
    // Code in here runs within the frontend environment built for page 42.
    // The previous environment is restored automatically afterwards.
});
Copied!

Manual backup, bootstrap and restore 

If you need finer control, the individual steps are available as well. Always make sure to restore a previously created backup, for example by using a try/finally block:

use FGTCLB\EnvironmentStateManager\StateBuildContext;
use TYPO3\CMS\Core\Http\ApplicationType;

$stateBuildContext = new StateBuildContext(
    applicationType: ApplicationType::FRONTEND,
    pageId: 42,
    languageId: 0,
);

$this->stateManager->backup();
try {
    $state = $this->stateManager->bootstrap($stateBuildContext);
    // work with the bootstrapped $state ...
} finally {
    $this->stateManager->restore();
}
Copied!

Applying a pre-built state 

A StateInterface instance – for example one created through the environment builder – can be applied to the global environment directly:

$this->stateManager->apply($state);
Copied!

PSR-14 events 

The state manager dispatches the following events that can be used to react on state changes:

Event Dispatched
FGTCLBEnvironmentStateManagerEventStateApplyEvent When a state is applied to the global environment.
FGTCLBEnvironmentStateManagerEventStateBackupEvent When the current environment is backed up onto the snapshot stack.

Register an event listener as usual through the Services.yaml / Services.php or the #[AsEventListener] attribute:

use FGTCLB\EnvironmentStateManager\Event\StateApplyEvent;
use TYPO3\CMS\Core\Attribute\AsEventListener;

final class MyStateApplyListener
{
    #[AsEventListener]
    public function __invoke(StateApplyEvent $event): void
    {
        // react on the applied state
    }
}
Copied!

Public API and stability 

This extension was extracted from another extension to provide a stable, reusable API that other extensions can build on and rely on. To keep that promise meaningful, the API surface is split into a public part covered by backward-compatibility guarantees and an internal part that may change at any time.

Public API 

The following types form the public API. Depend on these interfaces and types:

Type Purpose
FGTCLBEnvironmentStateManagerStateManagerInterface Central service to backup, bootstrap, apply, restore and execute within an environment.
FGTCLBEnvironmentStateManagerEnvironmentBuilderFactoryInterface Resolves a TYPO3 core-version compatible environment builder.
FGTCLBEnvironmentStateManagerEnvironmentBuilderInterface Builds a StateInterface for a given build context.
FGTCLBEnvironmentStateManagerStateInterface Immutable snapshot of the bootstrapped environment elements.
FGTCLBEnvironmentStateManagerStateBuildContext DTO describing which environment to build.
FGTCLBEnvironmentStateManagerEventStateApplyEvent, FGTCLBEnvironmentStateManagerEventStateBackupEvent PSR-14 events to react on state changes.
FGTCLBEnvironmentStateManagerExceptionNoTypo3VersionCompatibleEnvironmentBuilderFound, FGTCLBEnvironmentStateManagerExceptionSiteConfigCouldNotBeDetermined Exceptions thrown by the API.

The TYPO3 core-version specific Core12ExtendedStateInterface and Core13ExtendedStateInterface extend StateInterface and are part of the public API as well. They exist for future version-specific additions to the state contract. Type-hint the version-agnostic StateInterface in code that should work across core versions, and only reference an ExtendedStateInterface when you explicitly target a specific TYPO3 core version.

Internal implementation details 

The concrete, TYPO3 core-version specific implementations under the FGTCLBEnvironmentStateManagerCore12 and FGTCLBEnvironmentStateManagerCore13 namespaces – for example Core13StateManager, Core13FrontendEnvironmentBuilder and Core13State – as well as the EnvironmentBuilderFactory and the internal traits are marked @internal. They are registered as dependency injection services and resolved to the implementation matching the running TYPO3 core version.

Contribution 

Contributions are welcome. This chapter describes how to set up a development environment, how to run the tests and quality checks, and the commit message rules used in this repository.

The source code and issue tracker are hosted on GitHub: fgtclb/environment-state-manager.

Development environment 

All tests and quality tools run in containers through the Build/Scripts/runTests.sh wrapper. The only requirement on the host is a container runtime – podman (preferred) or docker. The wrapper pulls the required TYPO3 testing images on first use; nothing else is installed on the host.

Dependencies are installed into the git-ignored .Build/ directory. The wrapper installs them for a specific TYPO3 core and PHP version:

# Install dependencies for TYPO3 v12 on PHP 8.2 (default matrix).
Build/Scripts/runTests.sh -t 12 -p 8.2 -s composerUpdate

# Switch the working copy to the TYPO3 v13 dependency set.
Build/Scripts/runTests.sh -t 13 -p 8.2 -s composerUpdate
Copied!

Run Build/Scripts/runTests.sh -h to see all options.

Running tests 

# Unit tests.
Build/Scripts/runTests.sh -s unit

# Functional tests on SQLite (no database container required).
Build/Scripts/runTests.sh -s functional -d sqlite

# Functional tests against other database management systems.
Build/Scripts/runTests.sh -s functional -d mariadb -i 10.6
Build/Scripts/runTests.sh -s functional -d mysql -i 8.0
Build/Scripts/runTests.sh -s functional -d postgres -i 10
Copied!

To run a single test class or method, append phpunit arguments after a -- separator (the wrapper parses its own options with getopts, so phpunit flags must follow --):

Build/Scripts/runTests.sh -s functional -d sqlite -- --filter EnvironmentBuilderFactoryTest
Copied!

The functional Tests/Functional/Core12/ and Tests/Functional/Core13/ directories are gated with phpunit groups (not-core-12 / not-core-13), so the wrapper automatically runs the set matching the installed core version.

Code quality 

# Coding guidelines: fix in place ...
Build/Scripts/runTests.sh -s cgl

# ... or check only (no changes), as run in CI.
Build/Scripts/runTests.sh -s cgl -n

# Static analysis (PHPStan).
Build/Scripts/runTests.sh -s phpstan

# Render this documentation into Documentation-GENERATED-temp.
Build/Scripts/runTests.sh -s renderDocumentation
Copied!

Please make sure cgl -n, phpstan and the unit and functional test suites pass before opening a pull request.

Commit message rules 

This repository follows the TYPO3 core commit message conventions.

Format 

[TAG] Short imperative summary

A wrapped body (around 72 characters per line) that explains what the
change does and, more importantly, why it is needed. Describe the
behaviour change and the motivation, not the line-by-line diff.
Copied!

Rules:

  • The subject line starts with a tag in square brackets, followed by a short summary in imperative mood ("Add", "Fix", "Rename"), capitalized and without a trailing period.
  • Keep the subject concise (aim for  52 characters,  72 at most).
  • Separate the subject from the body with a single blank line.
  • Wrap the body at around 72 characters and explain the what and why.
  • An issue reference is not required. When a change relates to a GitHub issue, you may reference it in the body (for example Resolves: #123).

Tags 

Tag Use for
[FEATURE] A new feature or capability.
[TASK] Maintenance, refactoring, tooling and other non-functional changes.
[BUGFIX] A bug fix.
[DOCS] Documentation-only changes.
[TEST] Changes to tests only.

Breaking changes are additionally prefixed with [!!!] in front of the tag, so reviewers and users can spot them immediately:

[!!!][TASK] Remove deprecated state accessor

Explain what breaks and how to migrate.
Copied!

Examples 

[FEATURE] Add backend environment builder

[TASK] Mark concrete implementations as internal

[DOCS] Document the public API and stability guarantees
Copied!

Changelog 

Every notable change to the Environment State Manager extension is documented here, grouped by version and change type.

Feature: Initial release 

Description 

Initial release of the fgtclb/environment-state-manager extension. The environment builder and state manager were extracted from fgtclb/academic-base into this dedicated, reusable extension.

The extension provides:

  • EnvironmentBuilderFactory returning a TYPO3 core version compatible environment builder for TYPO3 v12 and v13. A FrontendEnvironmentBuilder is shipped; backend environment handling is planned to be added later.
  • StateManager to bootstrap, apply, back up and restore an environment state.
  • StateApplyEvent and StateBackupEvent PSR-14 events.

The classes are provided under the FGTCLBEnvironmentStateManager namespace. See the Developer Corner for usage examples.