4.2.1 Use cases for custom Providers

FluidTYPO3 File contexts, Providers

A Provider is a class which:

  1. Is always associated with one database table, fx tt_content or pages or your custom tables.
  2. Is resolved through Flux whenever a record from that table is edited, moved, saved, deleted, rendered etc.
  3. Triggers (as in: processes records from the table it connects with) only under certain circumstances, for example when a tt_content record has a list_type that matches a particular plugin.
  4. Contains a number of methods to get information based on one row from the table the Provider is connected with.
  5. Contains a number of methods to manipulate records from the DB table it connects with.
  6. 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.

Jump to...