TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-104002-1718273913:
|
||||
|
||||
=============================
|
||||
Feature: #104002 - Schema API
|
||||
=============================
|
||||
|
||||
See :issue:`104002`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new Schema API is introduced to access information about TCA structures
|
||||
in a unified way.
|
||||
|
||||
The main goal of this architecture is to reduce direct access to
|
||||
:php:`$GLOBALS['TCA']` after the Bootstrap process is completed.
|
||||
|
||||
The Schema API implements the following design goals:
|
||||
|
||||
#. An object-oriented approach to access common TCA information such as if a
|
||||
database table is localizable or workspace-aware, if it has a "deleted" field
|
||||
("soft-delete"), or other common functionality such as "enableFields" / "enablecolumns",
|
||||
which can be accessed via "Capabilities" within a Schema.
|
||||
|
||||
#. A unified way to access information which "types" a TCA table has available,
|
||||
such as "tt_content", where the "CType" field is the divisor for types, thus,
|
||||
allowing a Schema to have sub-schemata for a TCA Table.
|
||||
|
||||
The API in turn then handles which fields are available for a specific "CType".
|
||||
An example is "tt_content" with type "textpic": The sub-schema "tt_content.textpic"
|
||||
only contains the fields that are registered of that "CType", such as "bodytext",
|
||||
which then knows it is a Rich Text Field (the default column does not have this information),
|
||||
or "image" (a file relation field), but the sub-schema does not contain fields
|
||||
that are irrelevant for this type, such as "assets" (also a file relation field).
|
||||
|
||||
#. An abstracted approach to available TCA field types such as "input" or "select",
|
||||
which also takes information into account, if a select field is a selection of a
|
||||
static list (such as "pages.layout") or if it contains a relation to another
|
||||
schema or field (based on "foreign_table"). Previously, this was evaluated in
|
||||
many places in TYPO3 Core, and can now be reduced.
|
||||
|
||||
Thus, Schema API can now be utilized to determine the :php:`RelationshipType`
|
||||
of a relational field type in a unified way without having to deal with deeply
|
||||
nested arrays.
|
||||
|
||||
#. Information about relations to other database tables or fields. This is
|
||||
especially useful when dealing with Inline elements or category selection fields.
|
||||
|
||||
Schema API can find out, which fields of other schemata are pointing to one-self.
|
||||
Schema API differentiates between an "Active Relation" and a "Passive Relation".
|
||||
An Active Relation is the information that a field such as "pages.media"
|
||||
(a field of type "file") contains a reference to the "sys_file_reference.uid_foreign"
|
||||
field. Active Relations in consequence are connected to a specific field
|
||||
(of type :php:`RelationalFieldTypeInterface`).
|
||||
|
||||
In turn, a "Passive Relation" is the information what other schemata/fields are
|
||||
pointing to a specific table or field.
|
||||
|
||||
A common example of a "Passive Relation" is "sys_workspace_stage":
|
||||
The information stored in :php:`$GLOBALS[TCA][sys_workspace_stage]` does not contain
|
||||
the information that this table is actually used as a reference from the database
|
||||
field `sys_workspace.custom_stages`, the `sys_workspace_stage` Schema now
|
||||
contains this information directly via :php:`TcaSchema->getPassiveRelations()`.
|
||||
This is possible as TcaSchemaFactory is evaluating all TCA information and
|
||||
holistically as a graph. Passive Relations
|
||||
are currently only connected to a Schema, and Active Relations to a Field or
|
||||
a Schema.
|
||||
|
||||
As the Schema API fetches information solely based on the TCA, an Active Relation
|
||||
only points to **possible** references, however, the actual reference
|
||||
(does a record really have a connection to another database table) would
|
||||
require an actual Record instance (a database row) to evaluate this information.
|
||||
|
||||
Relations do not know about the "Type" or "Quantity" (many-to-many etc) as
|
||||
this information is already stored in the Field information. For this reason,
|
||||
the "Relations" currently only contain a flat information structure of the table
|
||||
(and possibly a field) pointing TO another schema name (Active Relation) or
|
||||
FROM another schema name / field (Passive Relation).
|
||||
|
||||
Schema API also parses all available FlexForm data structures in order to
|
||||
resolve relations. As a result, a field of type FlexFormField contains
|
||||
a list of possible "FlexFormSchema" instances, which resolve all fields, sheets
|
||||
and section containers within each data structure.
|
||||
|
||||
#. Once built, the Schema can never be changed. Whereas the TCA could be
|
||||
overridden at runtime, all TCA is now evaluated once and
|
||||
then cached. This is a consequence of working with an object-oriented approach.
|
||||
|
||||
If the TCA is changed after the Bootstrap process is completed,
|
||||
the Schema needs to be rebuilt manually, which TYPO3 Core currently does, for
|
||||
example, in some Functional Testing Scenarios.
|
||||
|
||||
All key objects (Schema, FieldType, Capabilities) are treated as immutable DTOs
|
||||
and never contain cross-references to their parent objects (Sub schemata do not
|
||||
know information about their parent schema, a field does not know which schema
|
||||
it belongs to), so the only entry point is always the :php:`TcaSchemaFactory`
|
||||
object.
|
||||
|
||||
This design allows the API to be fully cacheable at PHP level as a nested tree.
|
||||
|
||||
#. Low-level, not full-fledged but serves as a basis.
|
||||
|
||||
Several API decisions were made in order to let Schema API keep only its
|
||||
original purpose, but can be encapsulated further in other APIs:
|
||||
|
||||
- Schema API is not available during Bootstrap as it needs TCA to be available
|
||||
and fully finished.
|
||||
|
||||
- Schema API does not contain all available TCA properties for each field type.
|
||||
An example is "renderType" for select fields. This information is not relevant
|
||||
when querying records in the frontend, and mainly relevant for FormEngine -
|
||||
it is not generic enough to justify a getter method.
|
||||
|
||||
- Extensibility: custom field types are currently not available
|
||||
until TYPO3 Core as fully migrated to Schema API.
|
||||
|
||||
- User Permissions: Evaluating if a user has access to "tt_content.bodytext"
|
||||
requires information about the currently logged in user, thus it is not part of the
|
||||
Schema API. A "Permission API" should evaluate this information in the
|
||||
future.
|
||||
|
||||
- Available options for a field. As an example, a common scenario is to find out
|
||||
which possible options are available for "pages.backend_layout". In TYPO3 Core
|
||||
an :php:`itemsProcFunc` is connected to that field in TCA. Whether there is an
|
||||
:php:`itemsProcFunc` is stored, but Schema API is not designed to actually
|
||||
execute the itemsProcFunc as it is dependent on various factors evaluated during
|
||||
runtime, such as the page it resides on, user permissions or PageTsConfig
|
||||
overrides.
|
||||
|
||||
Schema API is currently marked as internal, as it might be changed during
|
||||
TYPO3 v13 development, because more parts of TYPO3 will be migrated towards
|
||||
Schema API.
|
||||
|
||||
DataHandler and the Record Factory already utilize Schema API in order to reduce
|
||||
direct access to :php:`$GLOBALS[TCA]`.
|
||||
|
||||
In the future Schema API might be used to evaluate information
|
||||
for Site Configurations, like TCA and FlexForms.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Reading and writing :php:`$GLOBALS[TCA]` within :file:`Configuration/TCA/*`
|
||||
and via TCA Overrides is untouched, as the API is meant for reading the
|
||||
information there in a unified way.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
The API can now be used to find out information about TCA fields.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function __construct(
|
||||
protected readonly PageRepository $pageRepository,
|
||||
protected readonly TcaSchemaFactory $tcaSchemaFactory
|
||||
) {}
|
||||
|
||||
public function myMethod(string $tableName): void
|
||||
{
|
||||
if (!$this->tcaSchemaFactory->has($tableName)) {
|
||||
// this table is not managed via TYPO3's TCA API
|
||||
return;
|
||||
}
|
||||
$schema = $this->tcaSchemaFactory->get($tableName);
|
||||
|
||||
// Find out if a table is localizable
|
||||
if ($schema->isLocalizable()) {
|
||||
// do something
|
||||
}
|
||||
|
||||
// Find all registered types
|
||||
$types = $schema->getSubSchemata();
|
||||
|
||||
}
|
||||
|
||||
Using the API improves handling for parts such as evaluating :php:`columnsOverrides`,
|
||||
foreign field structures, FlexForm Schema parsing, and evaluating type fields
|
||||
for database fields.
|
||||
|
||||
.. index:: PHP-API, TCA, ext:core
|
||||
Reference in New Issue
Block a user