---
title: "Upgrading from 2.3 to 3.0"
manual: "Academic Base"
version: "main"
permalink: "https://docs.typo3.org/permalink/fgtclb/academic-base:upgrade-from-2-3-to-3-0@main"
source: "Upgrade/From23To30.rst"
rendered: "2026-10-17T08:47:46+00:00"
---

# Upgrading from 2.3 to 3.0 {#upgrade-from-2-3-to-3-0}

This page takes an installation of **academic_base** 2.3 straight to
3.0, without the step to 2.4. Version 3.0 drops TYPO3 12, removes the
environment and state manager classes and the file upload converter, and ships
the form and image partials the other academic extensions render, with speaking
classes and without a stylesheet. The page leaves out two states of 2.4 that
3.0 replaces: version 1.x of **environment_state_manager**, see
[Important: New required dependency fgtclb/environment-state-manager](https://docs.typo3.org/permalink/fgtclb/academic-base:important-ace-254-academic-base@main), and the deprecated environment and
state manager classes 2.4 kept in this extension, see
[Deprecation: Internal environment / state-manager subsystem moved to own extension](https://docs.typo3.org/permalink/fgtclb/academic-base:deprecation-1783574951@main). Work through the sections in order. Skip a step
that does not apply to the installation.

## Before you start {#upgrade-from-2-3-to-3-0-before-you-start}

Version 3.0 runs on TYPO3 13.4 from 13.4.35 on and on TYPO3 14.3 from 14.3.7
on, with PHP 8.2 or later.

**academic_base** 3.0 needs one new package:

-   [`fgtclb/environment-state-manager`](https://packagist.org/packages/fgtclb/environment-state-manager) 2.x, the extension
    **environment_state_manager**. It is declared in
    `composer.json` as `^2.0.1` and in `ext_emconf.php` as
    `2.0.1-2.99.99`, see [Important: fgtclb/environment-state-manager 2 is required](https://docs.typo3.org/permalink/fgtclb/academic-base:important-environment-state-manager-2@main).
    Composer installs it on its own. A classic installation installs it before
    it activates **academic_base** 3.0.

Every other academic extension depends on this one. Upgrade it in the same
deployment as all academic extensions of the installation, and on a classic
installation before them.

These changes have to ship in the same deployment as the update, because the
site fails or loses configuration until they are made:

-   Code that uses a removed environment and state manager class or the file
    upload converter moves to their replacements, see
    [Adapt your code](https://docs.typo3.org/permalink/fgtclb/academic-base:upgrade-from-2-3-to-3-0-code@main).
-   A subclass or an XCLASS of a plugin controller of an academic extension
    goes, see [Subclasses and XCLASSes](https://docs.typo3.org/permalink/fgtclb/academic-base:upgrade-from-2-3-to-3-0-extension-points@main).
-   An `@import` of a moved page TSconfig file of this extension
    names the new path, see [Page TSconfig imports](https://docs.typo3.org/permalink/fgtclb/academic-base:upgrade-from-2-3-to-3-0-page-tsconfig@main).

The module paths on this page are those of TYPO3 13, where the upgrade runs.

## Update TYPO3 first {#upgrade-from-2-3-to-3-0-typo3}

Update TYPO3 to 13.4.35 or later while the site still runs 2.3, which supports
TYPO3 13.4. Version 3.0 no longer installs on TYPO3 12, and Composer and the
Extension Manager refuse it next to an older patch release of TYPO3 13.

Stay on TYPO3 13 until the upgrade is complete when the installation also has
**academic_jobs**, **academic_persons**,
**academic_persons_edit** or **academic_projects**. Their
content element wizards read the column `tt_content.list_type`, which
TYPO3 14 removes, so they only run on TYPO3 13. Move to TYPO3 14.3.7 or later
once they have run.

See [Breaking: Removed TYPO3 v12 support](https://docs.typo3.org/permalink/fgtclb/academic-base:breaking-removed-typo3-v12-support@main) and
[Important: TYPO3 13.4.35 or 14.3.7 is required](https://docs.typo3.org/permalink/fgtclb/academic-base:important-minimum-typo3-versions@main).

## Update the package {#upgrade-from-2-3-to-3-0-package}

```bash
composer require -W \
    'fgtclb/academic-base':'~3.0.0'
```

Composer installs [`fgtclb/environment-state-manager`](https://packagist.org/packages/fgtclb/environment-state-manager) 2.x with it.

On a classic installation, install **environment_state_manager** 2.x
from the TER in **Admin Tools > Extensions** first, because
**academic_base** 3.0 cannot be activated without it. Then update
**academic_base** there, and after it every other academic extension of
the installation. Run the commands of this page with
`typo3/sysext/core/bin/typo3` instead of `vendor/bin/typo3`.

```bash
vendor/bin/typo3 cache:flush
```

## Update the database {#upgrade-from-2-3-to-3-0-database}

```bash
vendor/bin/typo3 extension:setup
```

Or apply the changes in **Admin Tools > Maintenance > Analyze
Database Structure**.

This extension has no table of its own. The comparison applies the changes of
the index definitions TYPO3 13.4.35 and 14.3.7 bring, and the changes of the
other academic extensions, which their upgrade chapters describe.

## Adapt the configuration {#upgrade-from-2-3-to-3-0-configuration}

### The upgrade check {#upgrade-from-2-3-to-3-0-upgrade-check}

**academic_base** 3.0 ships the console command
`academic:upgrade:check`. Without an argument it reads the stored
configuration of the installation and reports what no longer reaches the
academic extensions: a static template that delivers nothing, a page TSconfig
import of a file that is gone, a site that depends on a set a release removed,
an XCLASS of a class that is `final` now. An installation coming from 2.3
meets every path change of 2.4 and 3.0 at once, so run it on the staging copy
right after the package update, and work through what it reports together with
the next steps:

```bash
vendor/bin/typo3 academic:upgrade:check
```

With the key of an academic extension and `--site` it also compares the
template overrides of a site with the templates that extension ships:

```bash
vendor/bin/typo3 academic:upgrade:check <extension key> --site=<site identifier>
```

Each finding, and what to do about it, is described in [Upgrade check](https://docs.typo3.org/permalink/fgtclb/academic-base:upgrade-check@main).

### Page TSconfig imports {#upgrade-from-2-3-to-3-0-page-tsconfig}

The page TSconfig that labels the content element group **Academic**
moved, and the directory `Configuration/TsConfig/` is spelled
`Configuration/TSconfig/` now. An `@import` of an old path
loads nothing and reports no error. The upgrade check reports it as
`tsconfig-import`. Search the site package for the old paths and replace them:

| Old path | New path |
| --- | --- |
| `EXT:academic_base/Configuration/TsConfig/Wizards/NewContentElement.tsconfig` | `EXT:academic_base/Configuration/TSconfig/CTypeGroup/page.tsconfig` |
| `EXT:academic_base/Configuration/TsConfig/Wizards/*.tsconfig` | `EXT:academic_base/Configuration/TSconfig/Full/page.tsconfig` |
| `EXT:academic_base/Configuration/Sets/AcademicBaseCTypeGroup/page.tsconfig` | `EXT:academic_base/Configuration/TSconfig/CTypeGroup/page.tsconfig` |

An import that only served to label the group can be removed instead. The
[`Configuration/page.tsconfig`](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/FileStructure/Configuration/PageTsconfig.html#file-extension-configuration-page-tsconfig) of this extension delivers the label to
every installation, whatever the site configuration says.

Site configurations need no change. The set
`fgtclb/academic-base-ctype-group` keeps its name, and the aggregate set
`fgtclb/academic-base` depends on it. Two entries for the page field
**Include static Page TSconfig (from extensions)** on the tab
**Resources** are new as well and need not be selected. See
[Breaking: Site sets and page TSconfig have been restructured](https://docs.typo3.org/permalink/fgtclb/academic-base:breaking-site-sets-and-page-tsconfig-restructured@main).

### Position of the content element group {#upgrade-from-2-3-to-3-0-wizard-position}

The group **Academic** of the new content element wizard comes after
the groups of TYPO3, and the wizard opens on **Typical page content**.
Version 2.3 placed the group after **Special elements** and opened the
wizard on that group. A site that wants that placement back sets it in its page
TSconfig:

```typoscript
mod.wizards.newContentElement.wizardItems.academic.after = special
```

See [Important: The academic group comes last in the content element wizard](https://docs.typo3.org/permalink/fgtclb/academic-base:important-1790839252@main), and [Where the group appears](https://docs.typo3.org/permalink/fgtclb/academic-base:integration-wizard-position@main) for the
other placements.

### Label overrides of select items {#upgrade-from-2-3-to-3-0-select-item-labels}

The items of a TCA select field that a frontend form of an academic extension
offers, the job type of the job form of **academic_jobs** for example,
read their label overrides from the path without underscores. Move an override
from the extension key to the extension name, or to the path of the one plugin
it is meant for:

```typoscript
# Before
plugin.tx_academic_jobs._LOCAL_LANG.default.tx_academicjobs_domain_model_job.jobtype.job = Position

# After
plugin.tx_academicjobs._LOCAL_LANG.default.tx_academicjobs_domain_model_job.jobtype.job = Position
```

See [Important: Select item labels are read from the documented path](https://docs.typo3.org/permalink/fgtclb/academic-base:important-select-item-labels-read-the-documented-path@main). On TYPO3 14
the override of the plugin reaches these items as well, see
[Important: Select item labels read the plugin override on TYPO3 v14](https://docs.typo3.org/permalink/fgtclb/academic-base:important-select-item-labels-read-the-plugin-override-on-typo3-v14@main).

## Adapt templates and assets {#upgrade-from-2-3-to-3-0-templates}

### Site stylesheets {#upgrade-from-2-3-to-3-0-site-stylesheets}

No academic extension ships a stylesheet for its markup in 3.0, and the
templates carry speaking classes with the prefix `ace-` instead of the classes
of the theme they were developed with, see [What the extensions ship](https://docs.typo3.org/permalink/fgtclb/academic-base:styling-shipped@main). The site
package styles the markup. How the class system is built, and which classes of
Bootstrap the templates keep, is described in [Styling](https://docs.typo3.org/permalink/fgtclb/academic-base:styling@main). The stylesheet
of the development instances of the academic extensions is a complete example
to start from, see [A complete stylesheet as a reference](https://docs.typo3.org/permalink/fgtclb/academic-base:styling-project-reference@main).

The form field partials and the image partial of this extension are rendered
by the new job form of **academic_jobs** and by every image of a list
item or a page of the other extensions. Move the selectors of the site
stylesheet that styled those fields, their messages and those images to the
new classes, `ace-field`, `ace-control`, `ace-field-errors`, `ace-errors`,
`ace-image`, `ace-figure` and the others the table of
[Breaking: Form and image partials carry speaking classes](https://docs.typo3.org/permalink/fgtclb/academic-base:breaking-base-speaking-frontend-classes@main) lists. A Bootstrap theme no
longer shows the message of a field by itself, because it shows
`invalid-feedback` only.

The upgrade chapter of each academic extension names the changes of its own
plugins.

### The partials of this extension {#upgrade-from-2-3-to-3-0-partials}

The partials below `Resources/Private/Partials/Academic/` are new in 3.0,
so no project overrides them yet. The academic extensions register their path
in the partial root paths of their plugins with the key `-1`. A project that
replaces the partial root paths of an academic plugin completely, instead of
adding a path of its own, lists that path itself:

```typoscript
plugin.tx_academicpersons.view.partialRootPaths {
    -1 = EXT:academic_base/Resources/Private/Partials/
}
```

Without it, the plugin fails on the partial it cannot resolve. See
[Overriding the partial](https://docs.typo3.org/permalink/fgtclb/academic-base:templates-image-override@main) and [Feature: A responsive image partial to share](https://docs.typo3.org/permalink/fgtclb/academic-base:feature-responsive-image-partial@main).

A project that overrides a form field partial passes `invalid` as
`errorClass`, and an override of `Form/Textarea.html` keeps the class
`ace-ckeditor` on a rich text area, which the rich text editor of the job form
starts on. See [The form partials](https://docs.typo3.org/permalink/fgtclb/academic-base:templates-form@main).

### Frontend icons {#upgrade-from-2-3-to-3-0-icons}

The icons a visitor sees come from a frontend icon registry of this extension
now, which every extension and site package fills through its own
`Configuration/FrontendIcons.php`. The templates of the academic
extensions render them with the icon view helper of this extension, no longer
with `<core:icon>`. A site package that replaced an icon of an academic
extension in its [`Configuration/Icons.php`](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/FileStructure/Configuration/Icons.html#file-extension-configuration-icons-php) registers the replacement in
`Configuration/FrontendIcons.php`, under the identifier the extension
uses in 3.0, and depends on the extension it replaces the icon of. See
[Feature: A frontend icon registry and an icon view helper](https://docs.typo3.org/permalink/fgtclb/academic-base:feature-1791061865@main), [Replacing an icon in a site package](https://docs.typo3.org/permalink/fgtclb/academic-base:icons-override@main) and the upgrade chapter of the
extension that renders the icon.

## Adapt your code {#upgrade-from-2-3-to-3-0-code}

### The environment and state manager {#upgrade-from-2-3-to-3-0-environment-state-manager}

The classes of the namespaces `\FGTCLB\AcademicBase\Environment`,
`\FGTCLB\AcademicBase\Core12\Environment` and
`\FGTCLB\AcademicBase\Core13\Environment` are removed. They were marked
`@internal`. Version 2.4 deprecated them in favour of the extension
**environment_state_manager**, and 3.0 removes them, see
[Breaking: Removed internal environment / state-manager subsystem](https://docs.typo3.org/permalink/fgtclb/academic-base:breaking-removed-internal-environment-state-manager-subsystem@main). Code of a
project that uses them raises a fatal error until it:

1.  Requires [`fgtclb/environment-state-manager`](https://packagist.org/packages/fgtclb/environment-state-manager) `^2.0.1` in its own
    `composer.json`, or **environment_state_manager** in its own
    `ext_emconf.php`.
1.  Replaces the namespace prefix with `\FGTCLB\EnvironmentStateManager`,
    and `\Core13\Environment` with `Core13`. The class names stay the
    same. Version 2.x of **environment_state_manager** ships
    `Core13` and `Core14`, and nothing for TYPO3 12, so code that
    used `\Core12\Environment` names the class of the running TYPO3
    version instead.
1.  Types against the `ExtendedStateInterface` of `Core13` where it
    calls the TypoScriptFrontendController accessors of a state, which
    `StateInterface` no longer declares.

### Own handlers of a TCA select field {#upgrade-from-2-3-to-3-0-items-proc-func}

An `itemsProcFunc` handler that is reached through
`GetSelectItemsForTcaManagedTableFieldMethodTrait` receives the same
`$parameters['TSconfig']` as in the backend form: the page TSconfig below
`itemsProcFunc.` of the field, or `null`. A handler that
descended through the complete page TSconfig tree to compensate reads the
setting directly instead:

```php
// Before, only through the trait
$mySetting = $parameters['TSconfig']['TCEFORM.'][$table . '.'][$field . '.']['itemsProcFunc.']['mySetting'] ?? null;

// After, the same as in the backend form
$mySetting = $parameters['TSconfig']['mySetting'] ?? null;
```

The parameters of
`\FGTCLB\AcademicBase\Event\ModifyTcaSelectFieldItemsEvent` declare that
entry as nullable for the same reason. See
[Important: The select item helper passes the field TSconfig](https://docs.typo3.org/permalink/fgtclb/academic-base:important-items-proc-func-helper-passes-the-field-ts-config@main).

The trait passes an empty `$parameters['row']` now, because there is no
record outside the backend form, and the event declares `row` optional.
A listener of the event reads the row, and every field of it, with a
fallback:

```php
$row = $parameters['row'] ?? [];
$pageId = (int)($row['pid'] ?? $parameters['effectivePid']);
```

See [Important: The select item helper passes an empty row](https://docs.typo3.org/permalink/fgtclb/academic-base:important-select-item-helper-passes-an-empty-row@main).

The event now declares the other parameters as TYPO3 passes them, as the
PHPStan type alias `ItemsProcFuncParameters`. `inlineParentUid` and
`inlineTopMostParentUid` are the empty string `''` for a record that is
not edited as an inline child and a `NEW...` string for a parent that is not
saved yet, `site` is a `NullSite` for a record outside any site, and
an item TYPO3 built is a `SelectItem`. A listener casts an inline uid,
checks the site, and types an item as `array|SelectItem`:

```php
$parentUid = (int)($parameters['inlineParentUid'] ?? 0);
```

See [Important: The select item event declares what TYPO3 passes](https://docs.typo3.org/permalink/fgtclb/academic-base:important-select-item-event-declares-what-typo3-passes@main).

### The file upload converter {#upgrade-from-2-3-to-3-0-file-upload-converter}

`\FGTCLB\AcademicBase\Extbase\Property\TypeConverter\FileUploadConverter`
is removed, together with the language file
[`EXT:academic_base/Resources/Private/Language/locallang.xlf`](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/FileStructure/Resources/Private/Language.html#file-extension-resources-private-language-locallang-xlf) and its
German translation, which held its error messages. Code that registered the
converter for an argument of its own uses the native file upload handling of
Extbase, a `FileUploadConfiguration` on the argument. An override of one
of the removed labels can go. See [Breaking: Removed FileUploadConverter](https://docs.typo3.org/permalink/fgtclb/academic-base:breaking-removed-file-upload-converter@main).

### Subclasses and XCLASSes {#upgrade-from-2-3-to-3-0-extension-points}

The chapter [Extension points](https://docs.typo3.org/permalink/fgtclb/academic-base:developers-extension-points@main) names what a project may build
on in every academic extension. Everything else may change in any release, and
every plugin controller is `final` in 3.0, so a subclass or an XCLASS of a
controller no longer loads. Move such code to the events the chapter lists.
`academic:upgrade:check` reports every XCLASS of an academic class, as an
error where the class is `final` or gone, and as a notice where it is a
domain model, which a project may extend. See
[Important: What a project may build on is now named](https://docs.typo3.org/permalink/fgtclb/academic-base:important-extension-point-policy@main).

### Listeners of the plugin events {#upgrade-from-2-3-to-3-0-plugin-context}

-   The events one plugin rendering dispatches share one plugin action
    context. A listener that checked for the class
    `\FGTCLB\AcademicBase\Domain\Model\Dto\PluginControllerActionContext`
    checks for
    `\FGTCLB\AcademicBase\Domain\Model\Dto\PluginControllerActionContextInterface`
    instead, because the persons plugins hand the view event their own
    context. See [Important: The events of one plugin rendering share their context](https://docs.typo3.org/permalink/fgtclb/academic-base:important-1790607225@main).
-   The getters of `PluginControllerActionContext` for the site, the
    language and the content object renderer return `null` for a request
    attribute of another type, instead of failing. A `try` around such a
    call can go. See [Important: The plugin action context never fails on the site or the language](https://docs.typo3.org/permalink/fgtclb/academic-base:important-ace-748-academic-base@main) and
    [Important: The plugin action context never fails on the content object](https://docs.typo3.org/permalink/fgtclb/academic-base:important-plugin-controller-action-context-content-object@main).

## Check the result {#upgrade-from-2-3-to-3-0-check}

-   `vendor/bin/typo3 academic:upgrade:check` exits with `0`. A
    notice alone does not fail it. Run it with an extension key and
    `--site` for every academic extension whose templates the project
    overrides, see [Letting a site name the folders](https://docs.typo3.org/permalink/fgtclb/academic-base:upgrade-check-site@main).
-   On a classic installation, **environment_state_manager** 2.x is
    listed as active in **Admin Tools > Extensions**.
-   The new content element wizard shows the group **Academic** with
    its label on every site, after the groups of TYPO3 or where the page
    TSconfig of the site places it.
-   Open an existing academic content element on a page where its component is
    not enabled. The field **Type** shows the stored type followed by
    **(not enabled on this page)**, and saving the record keeps it.
    This holds for the content elements of every academic extension. See
    [Important: A hidden academic content type stays selected](https://docs.typo3.org/permalink/fgtclb/academic-base:important-ace-666-academic-base@main).
-   A field of the job form of **academic_jobs** that fails
    validation shows its message right below it, see
    [Important: The form partials mark rejected fields](https://docs.typo3.org/permalink/fgtclb/academic-base:important-form-partials-mark-rejected-fields@main).
-   With **academic_persons** installed, the images of the profile
    cards and of the public profile are rendered as a `<picture>` and
    are styled by the site stylesheet.
-   A search of the site package and of own extensions for
    `TsConfig/Wizards`, `Sets/AcademicBaseCTypeGroup`,
    `AcademicBaseEnvironment`, `AcademicBaseCore12Environment`,
    `AcademicBaseCore13Environment` and `FileUploadConverter` finds nothing
    any more.
