ModifyProjectDemandEvent
\FGTCLB\ hands a
listener the demand a project list is about to be queried with. The demand a
listener hands back is the one that is queried and assigned to the view as
{demand}
.
When it is dispatched
Project dispatches the event once per rendering
of the Projects and the Selected Projects content
elements, after the demand is built from the settings of the content element
and the selection of the visitor, and before the projects are queried.
ModifyProjectListEvent follows once the projects
are queried.
The event does not fire for a submission of the filter and sorting form: the plugin answers the POST with a redirect to a URL carrying the selection before the event, and the event fires on the request that follows, with the selection in the query string (or the route), not in the parsed body. See Feature: Project filter selections have a URL.
What a listener reads and changes
| Method | What it does |
|---|---|
get | The demand,
\FGTCLB\.
It is an object, so a change to it takes effect without
set. |
set | Replaces the demand that is queried. |
get | The context of the rendering,
\FGTCLB\:
the request, the site and its language, the content object of the
element, the settings of the content element and the plugin name. |
What the query reads from the demand:
| Getter and setter | Meaning |
|---|---|
get,
set | The uids of the field below the options: the pages the projects sit directly in, or the picked project pages. Empty means every project page of the installation. |
get,
set | How the pages are read:
true
for Selected
Projects, where they are the project pages themselves, matched
across languages,
false
for Projects, where they
are the parent pages. |
get,
set | all, active or completed. The setter throws an
\Invalid for any other value. |
get,
set | The selected categories, those of the visitor or the
Categories of the element, as a
\FGTCLB\, or
null
for none. A project has to carry every one of them. |
get,
set, and the field and the
direction on their own | The ordering, one of the values of
\FGTCLB\, for
example tx_. |
get,
set | Whether hidden project pages are listed, the field Show hidden records of the element. |
The plugin names are the names the plugins were registered with,
Project and
Project, not the content element
types.
Example
A site keeps its main project list to the running projects, whatever state the editor or the visitor chose, and leaves the selections made by hand alone:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\EventListener;
use FGTCLB\AcademicProjects\Event\ModifyProjectDemandEvent;
use TYPO3\CMS\Core\Attribute\AsEventListener;
final class ShowRunningProjectsOnly
{
#[AsEventListener(identifier: 'my-extension/show-running-projects-only')]
public function __invoke(ModifyProjectDemandEvent $event): void
{
if ($event->getPluginControllerActionContext()->getPluginName() !== 'ProjectList') {
return;
}
$event->getDemand()->setActiveState('active');
}
}
The state select of the form then still offers All and
Completed, which change nothing. Switch off
Show active state options in the content elements the listener
acts on, or check the content element in the listener, through the record on
get of the context.
Rules and pitfalls
Warning
A demand listener widens as easily as it narrows. The demand is the
query here, not a constraint added to one, and almost nothing guards it:
set shows hidden project pages to every
visitor,
set drops the storage restriction the editor chose
in the content element, and
set overrides the editor's
ordering for every element that renders, though only for a value that is
one of the
Sorting constants, since anything else is ignored
without a word. Two listeners that disagree are resolved by the order they
run in, and the last one wins.
What a listener cannot undo: the page type is pinned unconditionally,
show reaches the
disabled
flag alone (start- and
endtime,
fe_ and
deleted
stay in effect), and a
uid
tiebreaker is always appended to the ordering.
A replaced demand starts from the defaults.
set is there for
a listener that builds its own demand, and such a demand carries none of what
the plugin put in the one it was handed: the
show choice of
the editor, and the three the visitor can set themselves through the filter
form, the
sorting
, the
active and the
filter, so a replacement resets the ordering, the state
filter and the category filter under them.
show has to travel
with
pages
or it changes what they mean: the repository reads
pages
as the selected project uids when
show is true and
as storage page uids when it is false, so a single-selection element whose
demand is replaced without it turns into a storage-folder restriction. Mutate
the demand where that is enough, and carry
get,
get,
get,
get,
get and
get
over where it is not.
A category a listener adds is shown as an active filter. The active filter
tags of Active filters, reset link and result count read the demand the list was
queried with. A category a listener adds to every request is a tag the visitor
cannot remove, since the listener adds it again on the page the tag leads to.
The same holds for a state other than all.
A field the project adds to the filter form does not reach the event. The redirect after a submission carries the selection the plugin accepted and nothing else, so a listener cannot read a field of its own from the request that follows.
Introduced in
- Feature: Change the project lists by event added the event in 3.0.
- Breaking: The project controller is final made the controller final and names the event as the replacement of a subclass that changed the filter, the state or the sorting.
- Feature: Project filter selections have a URL answers a filter submission with a redirect, so the event fires on the request that follows it.