---
title: "AfterProfileUpdateEvent"
manual: "Academic Profiles Edit"
version: "main"
permalink: "https://docs.typo3.org/permalink/fgtclb/academic-persons-edit:developers-event-after-profile-update-event@main"
source: "Developers/Events/AfterProfileUpdateEvent.rst"
rendered: "2026-10-17T08:48:06+00:00"
---

# AfterProfileUpdateEvent {#developers-event-after-profile-update-event}

`\FGTCLB\AcademicPersons\Event\AfterProfileUpdateEvent` announces a
profile that was changed and stored. It is owned by
**academic_persons**, which dispatches it for a backend save, an
import and its commands as well. The [developer chapter of academic_persons](https://docs.typo3.org/p/fgtclb/academic-persons/main/en-us/Developers/Events/AfterProfileUpdateEvent.html)
describes the event in general. This page describes what the profile editing
of this extension passes in.

-   [When it is dispatched](https://docs.typo3.org/permalink/fgtclb/academic-persons-edit:when-it-is-dispatched@main)
-   [What a listener reads](https://docs.typo3.org/permalink/fgtclb/academic-persons-edit:what-a-listener-reads@main)
-   [Example](https://docs.typo3.org/permalink/fgtclb/academic-persons-edit:example@main)
-   [Rules and pitfalls](https://docs.typo3.org/permalink/fgtclb/academic-persons-edit:rules-and-pitfalls@main)
-   [Introduced in](https://docs.typo3.org/permalink/fgtclb/academic-persons-edit:introduced-in@main)

## When it is dispatched {#when-it-is-dispatched}

The profile editing dispatches the event once after each write it stored, of
the profile and of everything that belongs to it:

-   a field of the profile, one or all of them,
-   the synchronisation switch and the visibility switch,
-   the upload and the removal of the profile image,
-   the creation, update, hiding, deletion and sorting of a document, a
    contract or a profile information entry, and of a contact of a contract.

The event comes after the write is stored, and after the
[write event](https://docs.typo3.org/permalink/fgtclb/academic-persons-edit:developers-event-before-profile-editing-write-event@main) a
listener may have used to change or refuse it. A write a listener refused
neither stores nor announces anything, just like one the editor refused
itself.

Nothing is announced in three cases:

-   **An edit in a translated site language.** The editor then works on the
    translation of the profile, and the event announces default-language
    profiles only. Edits in the default language of the site are announced,
    and with `profile.allowedLanguages` configured, the translation
    synchronisation of this extension carries them into the translations.
-   **A write that changed nothing.** A sort that left every row in its place,
    and the removal of an image the profile does not have.
-   **A failed write.** A request the editor or a listener refused, or one
    that failed while it was stored.

## What a listener reads {#what-a-listener-reads}

| Method | What the profile editing passes in |
| --- | --- |
| `getProfile()` | The stored default-language profile, after the write. For a write of a document or a contact, the profile it belongs to. |
| `getSite()` | The site of the request the editor runs in, or `null` for a request without one. |
| `getOrigin()` | Always `ProfileUpdateOrigin::FrontendEditing`, a case of `\FGTCLB\AcademicPersons\Event\ProfileUpdateOrigin`. |

The event carries no information about what was written. A listener that needs
it listens to `BeforeProfileEditingWriteEvent` as well, keeps what it
needs of the write, and acts on it once the update is announced.

## Example {#example}

An office that reviews the profiles people maintain themselves wants a log
entry for every change made through the editor, and none for the changes made
in the backend or by an import:

**EXT:my_extension/Classes/EventListener/LogProfileEdit.php**

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\EventListener;

use FGTCLB\AcademicPersons\Event\AfterProfileUpdateEvent;
use FGTCLB\AcademicPersons\Event\ProfileUpdateOrigin;
use Psr\Log\LoggerInterface;
use TYPO3\CMS\Core\Attribute\AsEventListener;

final readonly class LogProfileEdit
{
    public function __construct(
        private LoggerInterface $logger,
    ) {}

    #[AsEventListener(identifier: 'my-extension/log-profile-edit')]
    public function __invoke(AfterProfileUpdateEvent $event): void
    {
        if ($event->getOrigin() !== ProfileUpdateOrigin::FrontendEditing) {
            return;
        }
        $profile = $event->getProfile();
        $this->logger->info('Profile {uid} was edited in the frontend.', [
            'uid' => $profile->getUid(),
            'site' => $event->getSite()?->getIdentifier(),
        ]);
    }
}
```

## Rules and pitfalls {#rules-and-pitfalls}

-   **This extension listens itself.** Two listeners of this extension react
    to the event: one carries the change into the translations of the profile
    when `profile.allowedLanguages` is configured, see
    [General configuration](https://docs.typo3.org/permalink/fgtclb/academic-persons-edit:configuration-general@main), and one regenerates the slug of the profile
    from its name. Their identifiers are not public API, and no order between
    them and a listener of a project is promised.
-   **Writing a profile again.** A listener that writes the profile through
    the DataHandler marks that run as internal, or the backend announcement of
    **academic_persons** announces it once more. The [extension points
    page](https://docs.typo3.org/p/fgtclb/academic-base/main/en-us/Developers/ExtensionPoints/Index.html#developers-extension-points-services)
    names the class for it.
-   **The answer waits for the listeners.** The event is dispatched inside
    the request of the editor, so the person waits for every listener before
    the editor shows the write as saved. Hand slow work, a mail or a request
    to another system, to a queue.

## Introduced in {#introduced-in}

-   [Feature: Frontend profile edits synchronize translations](https://docs.typo3.org/permalink/fgtclb/academic-persons-edit:feature-1788197189@main)
