PHPackages                             cpsit/typo3-personio-jobs - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. cpsit/typo3-personio-jobs

ActiveTypo3-cms-extension[API Development](/categories/api)

cpsit/typo3-personio-jobs
=========================

TYPO3 CMS Extension to integrate jobs from Personio Recruiting API

0.6.0(10mo ago)43.4k↓46.4%4[6 PRs](https://github.com/CPS-IT/personio-jobs/pulls)GPL-2.0-or-laterPHPPHP ~8.2.0 || ~8.3.0 || ~8.4.0CI passing

Since Mar 20Pushed 1mo ago5 watchersCompare

[ Source](https://github.com/CPS-IT/personio-jobs)[ Packagist](https://packagist.org/packages/cpsit/typo3-personio-jobs)[ RSS](/packages/cpsit-typo3-personio-jobs/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (25)Versions (31)Used By (0)

[![Extension icon](Resources/Public/Icons/Extension.svg)](Resources/Public/Icons/Extension.svg)

TYPO3 extension `personio_jobs`
===============================

[](#typo3-extension-personio_jobs)

[![Coverage](https://camo.githubusercontent.com/afc61d52a03b99a34c0934be1beadaeba0f90cff02d4828db8fd71f291673777/68747470733a2f2f696d672e736869656c64732e696f2f636f766572616c6c73436f7665726167652f6769746875622f4350532d49542f706572736f6e696f2d6a6f62733f6c6f676f3d636f766572616c6c73)](https://coveralls.io/github/CPS-IT/personio-jobs)[![CGL](https://github.com/CPS-IT/personio-jobs/actions/workflows/cgl.yaml/badge.svg)](https://github.com/CPS-IT/personio-jobs/actions/workflows/cgl.yaml)[![Release](https://github.com/CPS-IT/personio-jobs/actions/workflows/release.yaml/badge.svg)](https://github.com/CPS-IT/personio-jobs/actions/workflows/release.yaml)[![License](https://camo.githubusercontent.com/47bf9267d0b6f8f188bf54d1dfbf1a4e69e4c84816cd83ecb8396f243b02b3ee/687474703a2f2f706f7365722e707567782e6f72672f63707369742f7479706f332d706572736f6e696f2d6a6f62732f6c6963656e7365)](LICENSE.md)
[![Version](https://camo.githubusercontent.com/89ae49e7ef817d0d9201257d8c1e0aee2a2d1845be59d30bd4412ad4adc4b422/68747470733a2f2f736869656c64732e696f2f656e64706f696e743f75726c3d68747470733a2f2f7479706f332d6261646765732e6465762f62616467652f706572736f6e696f5f6a6f62732f76657273696f6e2f736869656c6473)](https://extensions.typo3.org/extension/personio_jobs)[![Downloads](https://camo.githubusercontent.com/03077b2af903b27e4a04aec379739fd0584bda7f1a769ee9104c22fb45aa952b/68747470733a2f2f736869656c64732e696f2f656e64706f696e743f75726c3d68747470733a2f2f7479706f332d6261646765732e6465762f62616467652f706572736f6e696f5f6a6f62732f646f776e6c6f6164732f736869656c6473)](https://extensions.typo3.org/extension/personio_jobs)[![Supported TYPO3 versions](https://camo.githubusercontent.com/7db4e13f2d71c201048eb67f0fabd61250b1961c21b21396639ab565826660bb/68747470733a2f2f736869656c64732e696f2f656e64706f696e743f75726c3d68747470733a2f2f7479706f332d6261646765732e6465762f62616467652f706572736f6e696f5f6a6f62732f7479706f332f736869656c6473)](https://extensions.typo3.org/extension/personio_jobs)[![Extension stability](https://camo.githubusercontent.com/603ffc0f45135959f768dbde7904e9cbb650028870240de1e3e256faa55db679/68747470733a2f2f736869656c64732e696f2f656e64706f696e743f75726c3d68747470733a2f2f7479706f332d6261646765732e6465762f62616467652f706572736f6e696f5f6a6f62732f73746162696c6974792f736869656c6473)](https://extensions.typo3.org/extension/personio_jobs)

📦 [Packagist](https://packagist.org/packages/cpsit/typo3-personio-jobs) | 🐥 [TYPO3 extension repository](https://extensions.typo3.org/extension/personio_jobs) | 💾 [Repository](https://github.com/CPS-IT/personio-jobs) | 🐛 [Issue tracker](https://github.com/CPS-IT/personio-jobs/issues)

---

An extension for TYPO3 CMS that integrates jobs from Personio Recruiting API into TYPO3. It provides a console command to import jobs into modern-typed value objects. In addition, plugins for list and detail views are provided with preconfigured support for Bootstrap v5 components.

🚀 Features
----------

[](#-features)

- Console command to import jobs from Personio Recruiting API
- Usage of modern-typed value objects during the import process
- Plugins for list and detail view
- Optional support for JSON Schema on job detail pages using [EXT:schema](https://extensions.typo3.org/extension/schema)
- Compatible with TYPO3 12.4 LTS and 13.0

🔥 Installation
--------------

[](#-installation)

### Composer

[](#composer)

```
composer require cpsit/typo3-personio-jobs
```

💡 If you want to use the [JSON schema](#json-schema) feature, you must additionally require the `schema` extension:

```
composer require brotkrueml/schema
```

### TER

[](#ter)

Alternatively, you can download the extension via the [TYPO3 extension repository (TER)](https://extensions.typo3.org/extension/personio_jobs).

### First-step configuration

[](#first-step-configuration)

Once installed, make sure to include the TypoScript setup at `EXT:personio_jobs/Configuration/TypoScript` in your root template.

⚡ Usage
-------

[](#-usage)

### Plugins

[](#plugins)

The extension provides two plugins:

IconDescription[![List plugin icon](Resources/Public/Icons/plugins.list.svg)](Resources/Public/Icons/plugins.list.svg)**Personio: Job list**
Lists all imported jobs as unordered list. Each list item shows the job title, office and schedule and links to the job's detail view.[![Detail plugin icon](Resources/Public/Icons/plugins.show.svg)](Resources/Public/Icons/plugins.show.svg)**Personio: Job detail**
Shows a single job, including several job properties and all imported job descriptions. In addition, it renders a button to apply for the job.### Command-line usage

[](#command-line-usage)

#### `personio-jobs:import`

[](#personio-jobsimport)

```
typo3 personio-jobs:import  [options]
```

The following command parameters are available:

Command parameterDescriptionRequiredDefault**`storage-pid`**Storage pid of imported jobs✅–**`-f`**, **`--force`**Enforce re-import of unchanged jobs–no**`--no-delete`**Do not delete orphaned jobs–no**`--no-update`**Do not update imported jobs that have been changed–no**`--dry-run`**Do not perform database operations, only display changes–no💡 Increase verbosity with `--verbose` or `-v` to show all changes, even unchanged jobs that were skipped.

### Code usage

[](#code-usage)

The Personio job import process can also be triggered directly within PHP. For this, two services exist:

- [`PersonioApiService`](Classes/Service/PersonioApiService.php) provides the main functionality to fetch jobs from Personio API and return them as hydrated [`Job`](Classes/Domain/Model/Job.php) models. Note that these jobs are not yet persisted. Instead, they only represent the current Personio job feed as strong-typed value objects.
- [`PersonioImportService`](Classes/Service/PersonioImportService.php) provides additional functionality to actually persist imported jobs. Under the hood, the previously mentioned `PersonioApiService` is called to fetch jobs, followed by their actual persistence. For the import process, a set of import settings is available:
    - `int $storagePid`: Page ID where to persist new or updated jobs.
    - `bool $updateExistingJobs = true`: Define whether to update jobs that were already imported, but have changed in the meantime.
    - `bool $deleteOrphans = true`: Define whether to delete jobs that are no longer available on Personio.
    - `bool $forceImport = false`: Select whether existing, unchanged jobs should be re-imported.
    - `bool $dryRun = false`: Do not perform any persistence operations, just fetch and validate jobs.

#### Fetch jobs from Personio API

[](#fetch-jobs-from-personio-api)

```
use CPSIT\Typo3PersonioJobs\Service\PersonioApiService;
use TYPO3\CMS\Core\Utility\GeneralUtility;

$apiService = GeneralUtility::makeInstance(PersonioApiService::class);
$jobs = $apiService->getJobs();

foreach ($jobs as $job) {
    echo 'Successfully fetched job: ' . $job->getName() . PHP_EOL;
}
```

#### Import jobs from Personio API

[](#import-jobs-from-personio-api)

```
use CPSIT\Typo3PersonioJobs\Service\PersonioImportService;
use TYPO3\CMS\Core\Utility\GeneralUtility;

$importService = GeneralUtility::makeInstance(PersonioImportService::class);
$result = $importService->import();

foreach ($result->getNewJobs() as $newJob) {
    echo 'Imported new job: ' . $newJob->getName() . PHP_EOL;
}

foreach ($result->getUpdatedJobs() as $updatedJob) {
    echo 'Updated job: ' . $updatedJob->getName() . PHP_EOL;
}

foreach ($result->getRemovedJobs() as $removedJob) {
    echo 'Removed job: ' . $removedJob->getName() . PHP_EOL;
}

foreach ($result->getSkippedJobs() as $skippedJob) {
    echo 'Skipped job: ' . $skippedJob->getName() . PHP_EOL;
}
```

### JSON schema

[](#json-schema)

In combination with [EXT:schema](https://extensions.typo3.org/extension/schema), a JSON schema for a single job is included on job detail pages. It is rendered as type [`JobPosting`](https://schema.org/JobPosting) and includes some generic job properties.

**⚠️ The `schema` extension must be installed to use this feature. Read more in the [installation](#-installation) section above.**

📂 Configuration
---------------

[](#-configuration)

### TypoScript

[](#typoscript)

The following TypoScript constants are available:

TypoScript constantDescriptionRequiredDefault**`plugin.tx_personiojobs.view.templateRootPath`**Path to template root––**`plugin.tx_personiojobs.view.partialRootPath`**Path to template partials––**`plugin.tx_personiojobs.view.layoutRootPath`**Path to template layouts––### Extension configuration

[](#extension-configuration)

The following extension configuration options are available:

Configuration keyDescriptionRequiredDefault**`apiUrl`**URL to Personio job page, e.g. `https://my-company.jobs.personio.de`✅–### Routing configuration

[](#routing-configuration)

On each import, a slug is generated. The slug can be used for an advanced routing configuration of job detail pages.

Example:

```
# config/sites//config.yaml

routeEnhancers:
  PersonioJobDetail:
    type: Extbase
    limitToPages:
      # Replace with the actual detail page id
      - 10
    extension: PersonioJobs
    plugin: Show
    routes:
      -
        routePath: '/job/{job_title}'
        _controller: 'Job::show'
        _arguments:
          job_title: job
    defaultController: 'Job::show'
    aspects:
      job_title:
        type: PersistedAliasMapper
        tableName: tx_personiojobs_domain_model_job
        routeFieldName: slug
```

⏰ Events
--------

[](#-events)

PSR-14 events can be used to modify jobs and job schemas. The following events are available:

- [`AfterJobsImportedEvent`](Classes/Event/AfterJobsImportedEvent.php)
- [`AfterJobsMappedEvent`](Classes/Event/AfterJobsMappedEvent.php)
- [`EnrichJobPostingSchemaEvent`](Classes/Event/EnrichJobPostingSchemaEvent.php)

🚧 Migration
-----------

[](#-migration)

### 0.4.x → 0.5.x

[](#04x--05x)

#### Decouple import process

[](#decouple-import-process)

Import process is moved to a separate service class.

- All import operations are now performed by the new [`PersonioImportService`](Classes/Service/PersonioImportService.php) class.
- `PersonioService` was renamed to [`PersonioApiService`](Classes/Service/PersonioApiService.php). Replace all usages of this class by the new class name.
- Import results are now properly displayed by objects of the new [`ImportResult`](Classes/Domain/Model/Dto/ImportResult.php) class.
- Public methods in [`AfterJobsImportedEvent`](Classes/Event/AfterJobsImportedEvent.php)have changed to match the new `ImportResult` class. Use the new public method `AfterJobsImportedEvent::getImportResult()` instead of previously available methods.

### 0.3.x → 0.4.x

[](#03x--04x)

#### Finalize `SchemaFactory`

[](#finalize-schemafactory)

[`SchemaFactory`](Classes/Domain/Factory/SchemaFactory.php) is now final and cannot be extended anymore.

- Remove classes extending from `SchemaFactory`.
- Replace customizations of the `SchemaFactory` by an event listener for the [`EnrichJobPostingSchemaEvent`](Classes/Event/EnrichJobPostingSchemaEvent.php)PSR-14 event.

🧑‍💻 Contributing
----------------

[](#‍-contributing)

Please have a look at [`CONTRIBUTING.md`](CONTRIBUTING.md).

💎 Credits
---------

[](#-credits)

The Personio logo as part of all distributed icons is a trademark of [Personio SE &amp; Co. KG](https://www.personio.de/).

⭐ License
---------

[](#-license)

This project is licensed under [GNU General Public License 2.0 (or later)](LICENSE.md).

###  Health Score

48

—

FairBetter than 95% of packages

Maintenance74

Regular maintenance activity

Popularity28

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity63

Established project with proven stability

 Bus Factor1

Top contributor holds 50.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~38 days

Recently: every ~139 days

Total

23

Last Release

307d ago

PHP version history (4 changes)0.1.0PHP ~8.1.0 || ~8.2.0

0.5.8PHP ~8.1.0 || ~8.2.0 || ~8.3.0

0.5.12PHP ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0

0.6.0PHP ~8.2.0 || ~8.3.0 || ~8.4.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/144cefe55242b883c87cb537463f3ba75a0f8198fc5b602b50c838aae31fe7ee?d=identicon)[eliashaeussler](/maintainers/eliashaeussler)

![](https://www.gravatar.com/avatar/a664c83f7a6760600d2a325f751b2a206f686b3dcb2f1dce5655ead343dc5a24?d=identicon)[cps](/maintainers/cps)

---

Top Contributors

[![eliashaeussler](https://avatars.githubusercontent.com/u/16313625?v=4)](https://github.com/eliashaeussler "eliashaeussler (278 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (138 commits)")[![renovate[bot]](https://avatars.githubusercontent.com/in/2740?v=4)](https://github.com/renovate[bot] "renovate[bot] (135 commits)")[![mbrodala](https://avatars.githubusercontent.com/u/5037116?v=4)](https://github.com/mbrodala "mbrodala (1 commits)")

---

Tags

apicmsextensionjobspersoniorecruitingtypo3

###  Code Quality

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/cpsit-typo3-personio-jobs/health.svg)

```
[![Health](https://phpackages.com/badges/cpsit-typo3-personio-jobs/health.svg)](https://phpackages.com/packages/cpsit-typo3-personio-jobs)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[eliashaeussler/typo3-warming

Warming - Warms up Frontend caches based on an XML sitemap. Cache warmup can be triggered via TYPO3 backend or using a console command. Supports multiple languages and custom crawler implementations.

20229.9k](/packages/eliashaeussler-typo3-warming)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[eliashaeussler/typo3-form-consent

Extension for TYPO3 CMS that adds double opt-in functionality to EXT:form

1481.0k](/packages/eliashaeussler-typo3-form-consent)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.2M386](/packages/shopware-core)[friendsoftypo3/content-blocks

TYPO3 CMS Content Blocks - Content Types API | Define reusable components via YAML

96374.6k23](/packages/friendsoftypo3-content-blocks)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
