Lifecycle
This document provides an overview of the request lifecycle in Forme, including initialisation processes and bootstrapping. Understanding this lifecycle will help you grasp how the framework manages operations.
The Lifecycle
In WordPress, all requests pass through the index.php
file, which serves as the front controller. The index.php
file bootstraps WordPress, including loading plugins, running the theme's functions.php
, determining the template to be used, and rendering HTML.
If you are familiar with Laravel, you can think of bootstrap/app.php
as the equivalent entry point in the lifecycle. This comes immediately after the index.php
entry point (which includes the composer autoload), and takes care of instantiating the Laravel app.
Forme leverages default WordPress files to achieve a similar flow within the WordPress lifecycle.
During set up, we include our autoload in wp-config.php
and define the FORME_PRIVATE_ROOT
constant.
Regarding bootstrapping:
- For themes, we use
functions.php
for bootstrapping. - For plugins, we use the plugin bootstrap file.
This ensures that Forme bootstraps and runs before any pages in the template hierarchy.
Bootstrapping
The bootstrap file performs the following steps:
- Checks the
WP_ENV
constant and loads Whoops if we are in development mode and it is not already loaded. - Loads the dotenv file if it exists and is not already loaded.
- Includes the custom routes file. Any routes defined here will be registered with the relevant WordPress hooks.
- Instantiates the Forme theme or plugin object. This object's main task is to initialise the Forme Framework loader.
- The loader calls
Forme\getContainer()
, which uses the singleton pattern to create the application container if it doesn't already exist or retrieve it if it does. - The container includes a logger (via Monolog) and a database connection (via Capsule, booted with Eloquent).
- The loader registers all hooks defined in the
app/config/hooks.yaml
file, ensuring that the relevant classes/methods are called through the container. - It also sets up the Template handler, allowing the use of Template controllers in Forme themes.
- For plugins, the bootstrap file sets up activation and deactivation files, along with related admin notices. This includes database schema migrations for plugins. Themes handle this differently, as they can be tied to a hook, specified in the
hooks.yaml
file. - For themes, the bootstrap starts a session if one isn't already in progress.
You generally won't need to modify the bootstrap/functions.php file, although you can refer to it if you require early access to certain components in the lifecycle.
What no functions.php?
Nope! Global functions are placed in helpers.php and should primarily be used within your views. Anything else probably wants to be in a class.
Routing
Each of our HTTP route handling strategies intercepts WordPress using a relevant hook and takes control from there if the route matches.
The Custom Route strategy inserts itself before any core WordPress routing occurs.
The other strategies do not interfere with core WordPress routing; they only handle the request and response parts.
Each strategy runs after WordPress has loaded but before it has sent any page output. Therefore, you can generally rely on WordPress functionality being available as expected.
The specific hooks used for each strategy are as follows, which may be useful for debugging:
- Custom Routes -
wp_loaded
- Ajax Private Routes -
wp_ajax_$route_name
- Ajax Public Routes -
wp_ajax_nopriv_$route_name
- Rest Routes -
rest_api_init
- WordPress Routes aka Template Controllers -
template_include
After gaining control, each route handling strategy performs the following steps:
- Retrieves the PSR-15 middleware queue configured for the corresponding route.
- Adds its own handler to the end of the queue to provide the final HTTP response.
- Retrieves the PSR-7 Request.
- Dispatches the full queue using Relay.
- Forces shutdown, meaning control is not handed back to WordPress.