4.2.1 Use cases for custom Providers
A Provider is a class which:
- Is always associated with one database table, fx
tt_content
orpages
or your custom tables. - Is resolved through Flux whenever a record from that table is edited, moved, saved, deleted, rendered etc.
- Triggers (as in: processes records from the table it connects with) only under certain circumstances, for example when a
tt_content
record has alist_type
that matches a particular plugin. - Contains a number of methods to get information based on one row from the table the Provider is connected with.
- Contains a number of methods to manipulate records from the DB table it connects with.
- Is used by your Flux-enabled controller when it are rendered through frontend plugins to fetch important rendering-related information like which controller to use, which template file, the paths for the View object, etc.
Illustration of purpose
For example, the fluidcontent
Provider - named ContentProvider
- connects with the tt_content
table and is triggered only
when the CType
value of the record matches fluidcontent_content
(which is the plugin signature name for fluidcontent
).
This Provider gets used in the backend to resolve a FluidTYPO3\Flux\Form
instance based on which specific fluidcontent
element you select. It reads values which were stored in the record by filling and saving the Flux form. It reacts to cache
clearing (by refreshing the stored definitions of available fluidcontent
templates) and finally, it is integrated in the
ContentController
from fluidcontent
which renders each element - here, in the controller, it is used to return variables,
template paths, desired controller name and controller extension name, and so on.
Flux then uses these variables and settings to route the request to the proper controller based on extension name etc.
(fluidcontent
uses this to make it possible to add your own ContentControllers
in other extensions). Since your fluidcontent
element is identified by a combination of extension key and template name, this Provider can then (by getting extension key based
on this value, for example fluidcontent_bootstrap:Alert.html
) detect a class name of a controller to which Flux should
delegate rendering).
Other Providers may choose completely different ways of enabling for example a dynamic template filename which changes based on the record's type or some other way of discriminating types of records from the same table, but this example should illustrate the essense of what Providers are meant to do (without overloading you completely, because there is of course much more it can do).
Connecting frontend and backend
Provider classes are meant to be the connection between backend and frontend - but you can also use them exclusively in the backend or frontend as you like. The main benefit comes when you also use a Flux-enabled controller in an Extbase plugin - when you do this, the Provider acts as the link between your records and the template file, paths, variables and so on that your controller should use when rendering each record.
All in all this makes the Provider the place to return dynamic returns for template, paths, rendering variables. Since the Provider gets used in both frontend and backend, the return values will be consistent in both places.
Test friendly
Along with the better separation of concern a Provider is also easy to write unit tests for. And, since it works the same way in
both frontend and backend, ensuring that it connects properly in one context also means it connects properly in others. Since it
mainly delegates to Services and other classes, it becomes easy to mock those so-called "fan-outs" in tests. Finally, it removes
some of the usually necessary code from controller classes into more a separate, much more test friendly context. As a bonus, Flux
provides a base unit test class which when used, should immediately cover a lot of the custom methods you choose to add. This class
is called FluidTYPO3\Flux\Tests\Unit\Provider\AbstractProviderTestCase
and can be easily subclassed in your own unit test.