This is another go at an architectural document. As you'll read below, it is much more scaled back than the previous draft. However, as chx said, this is the Butler working group. We are working on the context part here. Other discussions can happen elsewhere, but let's get one thing done at a time.
This document is mostly based on the last document but with the addition of my discussions with chx and sdboyer.
- Centralizing all "context" into a single object rather than scattered about various globals, collector functions, and statics.
- Allow for centralized, lazy-loaded, pluggable access to "rich context" that is not currently available in any standard fashion. (Current OG, etc.)
- Allow portions of core to be segmented into easily testable parts.
Implementation will proceed in multiple phases. Each phase can be viewed as a unit. We can go through as many or as few phases as we want, and Drupal will be stable and functional should development stop or be delayed between any two phases, and even so there it will be a huge improvement.
It is possible that not all phases will happen during the Drupal 8 development cycle. That is OK. As long as we are not in mid-phase when Drupal 8 goes into code freeze we will be left with a stable and greatly improved system.
Phase 1: Centralized context API
During bootstrap, we create a container for contextual information. This container will initially contain information derived from the HTTP request itself. It will be responsible for ensuring sane defaults are returned in unusual cases.
Examples of what will be contained:
- GET parameters.
- POST parameters if any.
- Cookie values.
- Session information.
- $_SERVER information.
- Additional information available directly from the HTTP request or equivalent.
It will also include the following derived information that other code may assume is always present. Again, it will be responsible for ensuring sane defaults are returned in unusual cases.
- Current language
- Requested path (both raw and de-aliased)
Core will also offer centralized access to the following derived contextual information that will be lazy-loaded on request.
- Current user (Because this is explicitly driven by session/cookie in the Request)
- Level-1 loaded entities (i.e., what is currently loaded by %node and similar menu callbacks)
- Pager state
- Others that may be found during implementation
Context will not be alterable. Once a given element of context has been determined, it will remain constant for the remainder of the page.
Additionally, there will be a method for any contributed module to register information which can also be lazy-loaded.
The scope of this first phase is quite small: all it does is introduce the new API that can be utilized by later phases.
Phase 2: Convert old API
In this phase, we'll convert old APIs which previously were context to the new system. Thus, they can be called from a central source, the context object.
Phase 3: Use new API
All existing uses of one-off context in core will be removed in favor of the global context. These include, but are not limited to, arg(), drupal_get_normal_path(), the global $user and $language variables, the $pager_* globals, all references to PHP super globals ($_GET, $_POST, etc.), and numerous other instances of scattered context.
Once all uses of such scattered context are expunged, the existing mechanisms will be removed. (That is, arg() will be removed from core in this phase. There will then be a party that includes ponies.)
Phase 4: Awesome
Possibly, every function call in Drupal will receive a context as an object. Alternately, we could evaluate functions on an individual basis and decide whether or not to pass context in. TBD. In either case, there will be no more global context - it will become the local context. This allows easy unit testing and contextual blocks.