[FEATURE] Add Contexts for storing data access modes
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Documentation / Changelog / master / Feature-85389-ContextAPIForConsistentDataHandling.rst
1 .. include:: ../../Includes.txt
2
3 ==========================================================
4 Feature: #85389 - Context API for consistent data handling
5 ==========================================================
6
7 See :issue:`85389`
8
9 Description
10 ===========
11
12 A new Context API is introduced, which encapsulates various information for data retrieval (e.g. inside
13 the database) and analysis of current permissions and caching information.
14
15 Previously, various information was distributed inside globally accessible objects (:php:`$TSFE` or :php:`$BE_USER`)
16 like the current workspace ID or if a frontend or backend user is authenticated. Having a global object
17 available was also dependent on the current request type (frontend or backend), instead of having
18 one consistent place where all this data is located.
19
20 The context is currently instantiated at the very beginning of each TYPO3 entry point, keeping track
21 of the current time (formally known as :php:`$GLOBALS['EXEC_TIME']`, and if a user is logged in,
22 and which workspace is currently accessed.
23
24 This information is separated in so-called "Aspects", being responsible for a certain area:
25
26 - VisibilityAspect, holding information if hidden/deleted records should be fetched from the database
27 - DateTimeAspect, keeping the current date as immutable datetime object
28 - UserAspect, holding frontend/backend user IDs, usernames and usergroups
29 - WorkspaceAspect, holding the currently visible workspace (default to "0"/ live)
30
31 Further aspects related to the current request (e.g. selected language information and fallback strategy)
32 will follow, but extensions can add their own Aspects as well, as they only need to implement the AspectInterface.
33
34 The Context object is used as a Singleton, available via :php:`GeneralUtility::makeInstance(Context::class)`.
35
36 Adding or replacing an aspect has implications on the whole further request. The recommended way on doing
37 so is done in a PSR-15 middleware. In the future (TYPO3 v10), the global context will have a "frozen" state
38 after all PSR-15 middlewares are run through, to ensure a consistent object throughout all renderings
39 within a backend.
40
41 However, if, for a certain retrieval part a custom context is needed, the necessary PHP classes, like
42 :php:`PageRepository` can receive a custom Context object. For this to work, a new Context object can be
43 created via :php:`new Context()`  and or cloned from the master context via
44 :php:`$myContext = clone GeneralUtility::makeInstance(Context::class);` to keep all existing aspects but only to
45 override a certain aspect locally.
46
47 A huge benefit when using the Context API is a strong decoupling of various architectural failures within
48 TYPO3 Core, which are now "Context aware" and not depending if a certain global object is available.
49
50 This will not unify the code quality, but also introduce a better standard, where hard intermingling within
51 Extbase, PageRepository and TypoScriptFrontendController can be found.
52
53 Impact
54 ======
55
56 The new Context API replaces lots of places known for a very long time:
57
58 * DateTimeAspect replaces :php:`$GLOBALS['SIM_EXEC_TIME']` and :php:`$GLOBALS['EXEC_TIME']`
59 * VisibilityAspect replaces :php:`$GLOBALS['TSFE']->showHiddenPages` and :php:`$GLOBALS['TSFE']->showHiddenRecords`
60 * WorkspaceAspect replaces :php:`$GLOBALS['BE_USER']->workspace`
61 * UserAspect replaces various calls and checks on :php:`$GLOBALS['BE_USER']` and :php:`$GLOBALS['TSFE']->fe_user`
62 options when only some information is needed.
63
64
65 TYPO3 Core comes with the following Aspects within the global context:
66
67 * date
68 * frontend.user
69 * backend.user
70 * workspace
71 * visibility
72
73 Usage
74 =====
75
76 As for TYPO3 v9, the old properties can be used the same way as before, but will throw a deprecation warning.
77
78 It is recommended to read data from the current global Context for custom extensions:
79
80 .. code-block:: php
81
82     $context = GeneralUtility::makeInstance(Context::class);
83
84     // Reading the current data instead of $GLOBALS['EXEC_TIME']
85     $currentTimestamp = $context->getPropertyFromAspect('date', 'timestamp');
86
87     // Checking if a user is logged in
88     $userIsLoggedIn = $context->getPropertyFromAspect('frontend.user', 'isLoggedIn');
89
90
91 Additionally, if custom DB queries need to be made, this can be solved via cloning the Context API
92
93 .. code-block:: php
94
95     // Current global context
96     $context = GeneralUtility::makeInstance(Context::class);
97     $localContextWithoutFrontendUser = clone $context;
98     $localContextWithoutFrontendUser->setAspect('frontend.user', GeneralUtility::makeInstance(UserAspect::class, null);
99
100     // Fetch a page which is publically available, but not accessible when logged in
101     $sysPage = GeneralUtility::makeInstance(PageRepository::class, $localContextWithoutFrontendUser);
102     $pageRow = $sysPage->getPage($pageId);
103
104
105 Further development
106 ===================
107
108 There will be additional aspects that will be introduced in TYPO3 Core. Also see PSR-15 middlewares shipped with TYPO3
109 Frontend or Backend to see how aspects can be modified.
110
111 Aspects eventually will become the successor of Database Restrictions, as they contain all information
112 necessary to restrict a database query.
113
114 .. index:: PHP-API, ext:core