---
title: "Taking part in the frontend user synchronisation"
manual: "Academic Profiles"
version: "main"
permalink: "https://docs.typo3.org/permalink/fgtclb/academic-persons:developers-frontend-user-sync-events@main"
source: "Developers/FrontendUserSync.rst"
rendered: "2026-10-15T10:24:29+00:00"
---

# Taking part in the frontend user synchronisation {#developers-frontend-user-sync-events}

The commands `academic:createprofiles` and
`academic:updateprofiles` build profiles from the data of frontend
users, following the map described in [Frontend user synchronisation](https://docs.typo3.org/permalink/fgtclb/academic-persons:configuration-frontend-user-sync@main).
Two events let a project add data of its own and adjust the result, without a
profile factory of its own. `AbstractProfileFactory` dispatches them, so
every factory extending it does, a project's factory included, unless it
overrides `createProfileForUser()` or `updateProfileForUser()`
without calling the parent method.

| Event | Dispatched | A listener can |
| --- | --- | --- |
| [BeforeProfileMappedFromFrontendUserEvent](https://docs.typo3.org/permalink/fgtclb/academic-persons:developers-event-before-profile-mapped-from-frontend-user-event@main) | before the data of a frontend user is mapped: once per frontend user when a profile is created, and once per synchronised profile of the frontend user when profiles are updated, not for a profile whose `skip_sync` flag is set | add or change values, or skip the frontend user on creation and the profile on update |
| [AfterProfileMappedFromFrontendUserEvent](https://docs.typo3.org/permalink/fgtclb/academic-persons:developers-event-after-profile-mapped-from-frontend-user-event@main) | after the mapping, before the profile is saved | change the profile |

For one frontend user, a run goes through these steps:

1.  [ChooseProfileFactoryEvent](https://docs.typo3.org/permalink/fgtclb/academic-persons:developers-event-choose-profile-factory-event@main)
    chooses the factory.
1.  `BeforeProfileMappedFromFrontendUserEvent` carries the data of the
    frontend user, the action (`ProfileActionType::Create` or
    `ProfileActionType::Update`) and, on update, the profile.
    `getProfile()` is `null` when a profile is created.
1.  The factory maps the data onto the profile and its imported contract.
1.  `AfterProfileMappedFromFrontendUserEvent` carries the profile, the
    data the mapping used, with the values added in step 2, and the action.
1.  The profile is saved, and
    [AfterProfileUpdateEvent](https://docs.typo3.org/permalink/fgtclb/academic-persons:developers-event-after-profile-update-event@main)
    announces it, see [AfterProfileUpdateEvent](https://docs.typo3.org/permalink/fgtclb/academic-persons:developers-trigger@main).

On update, steps 2 to 4 repeat for every synchronised profile of the frontend
user, and step 5 then saves and announces them together. Each event of step 2
starts from the data of the frontend user, not from what a listener set for
the profile before.

Listeners of one event are ordered with the `before` and `after`
arguments of `#[AsEventListener]`. Use TYPO3's attribute,
`\TYPO3\CMS\Core\Attribute\AsEventListener`: Symfony's registers nothing,
and the listener never runs.

A factory of its own may decline to create a profile, see
[Custom profile factories](https://docs.typo3.org/permalink/fgtclb/academic-persons:configuration-frontend-user-sync-factories@main).

The commands also dispatch
`\FGTCLB\AcademicPersons\Service\Event\ModifyProfileCommandEnvironmentStateBuildContextForFrontendUserEvent`
before they set up the environment of a frontend user's site. It is marked
`@internal` as experimental, like the environment handling it belongs
to, and is not documented here.
