---
title: "Feature: Import writer for persons of another source"
manual: "Academic Profiles"
version: "main"
source: "Changelog/3.0/Feature-ProfileImportWriter.rst"
rendered: "2026-10-02T20:47:49+00:00"
---

# Feature: Import writer for persons of another source {#feature-1790970752}

## Description {#description}

Only the frontend user synchronisation filled person records so far. A project
that imports persons from another source, an HR or campus management system,
had to write its own DataHandler pipeline, and such pipelines tended to ignore
the import identifier and `skip_sync` and never announced the update, so
translations and slugs went stale.

`\FGTCLB\AcademicPersons\Import\ProfileImportWriter` does that part now.
Import code reads its source, maps each person to an
`ImportedProfile` with its contracts and their contact records, and hands
it over:

-   Every record is matched by its import identifier. Writing the same person
    twice yields one profile.
-   A new record gets every supplied field. An existing record gets only the
    supplied fields that are managed on it, so what an editor changed beside
    them survives. Without a managed field declaration no field of an
    existing record changes.
-   The visibility of an existing record is never changed by a write.
-   A profile excluded from the synchronisation is left untouched and reported
    as skipped.
-   Organisational units and function types are looked up by their import
    identifiers, never created.
-   `\FGTCLB\AcademicPersons\Event\BeforeImportedRecordWriteEvent` lets a
    listener change the values of each record or veto it.
-   `retire()` hides or deletes the records of a source that it no longer
    supplies. Records without an identifier, records of other sources and
    excluded profiles are never retired themselves. Deleting a profile or a
    contract deletes the records that belong to it, the ones an editor added
    included.
-   Each person is one DataHandler run in the live workspace, so history, the
    reference index and the hooks apply as for a backend save, and the profile
    is announced once with the origin `ProfileUpdateOrigin::Import`. With
    [`fgtclb/academic-persons-edit`](https://packagist.org/packages/fgtclb/academic-persons-edit) installed, that synchronises its
    translations and its slug, also from a command.

The writer, its data objects, its result and the event are public API.

See [Writing what an import supplies](../../Developers/Index.html#developers-import-writer).

## Impact {#impact}

Nothing changes for an installation that does not call the writer. Existing
import code keeps working.

## Affected Installations {#affected-installations}

Installations that import persons from a source other than the frontend users.
