ModifyTcaSelectFieldItemsEvent
\FGTCLB\ is owned by
academic_base, which describes it for every academic extension in
its developer chapter.
This page says which items of academic_jobs it carries.
When it is dispatched
Two fields of the job record build their items with an item provider of this extension, and each provider dispatches the event once each time it runs. The option Job Type of the job list offers the job types of the record behind its own None, and dispatches the event with the table and the field of the record:
| Field |
table
and
field
|
Item provider | Shipped items |
|---|---|---|---|
| Job Type | tx_, type |
\FGTCLB\ | 1 Job, 2 Sidejob, 3 Thesis |
| Employment Type | tx_, employment_ |
\FGTCLB\ | 1 Full-time, 2 Part-time |
| Job Type of the job list | tx_, type |
\FGTCLB\,
which calls
Type | 1 Job, 2 Sidejob, 3 Thesis, after 0 None, which the
listeners do not get |
The providers run in three places:
- in the backend, when an editor opens the record of a job.
- in the backend, when an editor opens a Job List content element, for its option Job Type.
- in the frontend, each time the Job Form
renders, to build the choices of its two select fields. The form translates
the labels after the listeners ran, so a label may be an
LLL:reference.
What this extension passes in
| Method | Returns |
|---|---|
get,
set | The parameters of the item provider.
items
holds the items,
the ones of this extension as arrays with
label
and
value
.
table
,
field
,
effective,
site
and
TSconfig
say where they are built. In the
backend
row
holds the job being edited. In the frontend
row
is an empty array, and
effective is the page
of the form. |
For the job list,
table
and
field
name the field of the job
record, and every other parameter is the one TYPO3 passes for the FlexForm
field:
flex holds the content element,
row
the values of its FlexForm,
effective its page, and
config
and
TSconfig
belong to the FlexForm field. Only the job
list passes
flex, so a listener that means the record
or the list alone checks it:
$isJobList = isset($parameters['flexParentDatabaseRow']);
In the backend form, TYPO3 v13 and v14 hand the static items of a field to the
item provider as
\TYPO3\ objects,
and the items a provider adds are arrays. A
Select implements
\Array, so a closure typed
array that reads
$item works for both.
The two job fields declare no static items, but a project that adds one in the TCA gets an object in the backend form. The job form of the frontend hands every item over as an array. Such an item comes first, and a shipped item with a value it declares already is left out, see Important: Job type items keep the declared items.
Example: the job types of an institution
An institution does not publish side jobs, and advertises doctoral positions as a type of their own. The listener removes the one type and adds the other, in the backend and in the job form alike:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\EventListener;
use FGTCLB\AcademicBase\Event\ModifyTcaSelectFieldItemsEvent;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Schema\Struct\SelectItem;
final class AdaptJobTypes
{
private const JOB_TYPE_SIDEJOB = 2;
private const JOB_TYPE_DOCTORAL_POSITION = 10;
#[AsEventListener(identifier: 'my-extension/adapt-job-types')]
public function __invoke(ModifyTcaSelectFieldItemsEvent $event): void
{
$parameters = $event->getParameters();
if ($parameters['table'] !== 'tx_academicjobs_domain_model_job'
|| $parameters['field'] !== 'type'
) {
return;
}
$parameters['items'] = array_values(array_filter(
$parameters['items'],
static fn(array|SelectItem $item): bool => (int)($item['value'] ?? 0) !== self::JOB_TYPE_SIDEJOB,
));
$parameters['items'][] = [
'label' => 'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:jobType.doctoralPosition',
'value' => self::JOB_TYPE_DOCTORAL_POSITION,
];
$event->setParameters($parameters);
}
}
The job list and the job detail name the type of a job with the frontend label
jobs. of this extension, so the new type needs one, see
Labels:
plugin.tx_academicjobs._LOCAL_LANG.default.jobs.type.10 = Doctoral position
Rules and pitfalls
Check the table and the field first. The event is dispatched by the item providers of several academic extensions, for fields of other tables and of FlexForms, so a listener returns early for every field it does not mean.
Do not rely on the row. The job form calls the providers without a record
and passes an empty
row
. The event declares
row
optional, so a
listener reads it with a fallback,
$parameters, and every
field of it as well, for example the page as
$row. For the job list, that is
the page of the content element, because
row
holds the values of its
FlexForm and has no
pid
. The storage folder of the list is a field of
the content element, which
flex holds.
Removing an item hides it. A job that already has the value keeps it, and the job form does not check a submitted value against the items.
The job list offers the same types. A type a listener adds to the field
type
can be chosen for the job list as well, and one it removes is not
offered there, see Important: Job list offers the job types of listeners.
Give a type a positive integer as its value: the column of the job stores an
integer, and the list treats 0 and below as None.
Introduced in
- Feature: Dispatch ModifyTcaSelectFieldItemsEvent in TypeItems and EmploymentTypeItems: the item providers of the job type and the employment type dispatch the event. The example of that entry names methods the event does not have, the example above uses the ones it has.
- Important: Job list offers the job types of listeners: the option Job Type of the job list offers the types of the listeners.