Completed
Branch FET/11399/verify-paypal-creden... (c7ad03)
by
unknown
66:22 queued 52:43
created

BootstrapCore::buildRequestStack()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 40
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 20
nc 2
nop 0
dl 0
loc 40
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\core\services\bootstrap;
4
5
use EE_Error;
6
use EEH_Autoloader;
7
use EventEspresso\core\exceptions\InvalidDataTypeException;
8
use EventEspresso\core\exceptions\InvalidInterfaceException;
9
use EventEspresso\core\services\loaders\LoaderInterface;
10
use EventEspresso\core\services\request\RequestInterface;
11
use EventEspresso\core\services\request\RequestStack;
12
use EventEspresso\core\services\request\RequestStackBuilder;
13
use EventEspresso\core\services\request\RequestStackCoreApp;
14
use EventEspresso\core\services\request\ResponseInterface;
15
use InvalidArgumentException;
16
use ReflectionException;
17
18
defined('EVENT_ESPRESSO_VERSION') || exit;
19
20
21
22
/**
23
 * Class BootstrapCore
24
 * Bootstraps the main DI container as well as the Request and Response objects.
25
 * Then loads a few required autoloaders, then proceeds to build a request stack
26
 * which consists of an array of EE_Middleware request decorator classes.
27
 * Each middleware class wraps the previous middleware class with itself,
28
 * with the core application loader residing at the center.
29
 * The stack is then processed by passing an EE_Request object to the first class in the stack.
30
 * Each middleware class:
31
 *      accepts the request object
32
 *        passes the request to the next middleware class in the stack
33
 *        receives an EE_Response object from that next middleware class
34
 *        applies it's logic before and/or after doing the above
35
 *        returns an EE_Response object to the previous middleware class
36
 *        and can terminate the request at any point during the above
37
 * If none of the middleware classes terminate the request,
38
 * then the Request Stack will terminate itself after everything else is finished.
39
 *
40
 * @package EventEspresso\core\services\bootstrap
41
 * @author  Brent Christensen
42
 * @since   $VID:$
43
 */
44
class BootstrapCore
45
{
46
47
    /**
48
     * @type LoaderInterface $loader
49
     */
50
    private $loader;
51
52
    /**
53
     * @var RequestInterface $request
54
     */
55
    protected $request;
56
57
    /**
58
     * @var ResponseInterface $response
59
     */
60
    protected $response;
61
62
    /**
63
     * @var RequestStackBuilder $request_stack_builder
64
     */
65
    protected $request_stack_builder;
66
67
    /**
68
     * @var RequestStack $request_stack
69
     */
70
    protected $request_stack;
71
72
73
74
    public function __construct()
75
    {
76
        // construct request stack and run middleware apps as soon as all WP plugins are loaded
77
        add_action('plugins_loaded', array($this, 'initialize'), 0);
78
    }
79
80
81
    /**
82
     * @throws EE_Error
83
     * @throws InvalidArgumentException
84
     * @throws InvalidDataTypeException
85
     * @throws InvalidInterfaceException
86
     * @throws ReflectionException
87
     */
88
    public function initialize()
89
    {
90
        $this->bootstrapDependencyInjectionContainer();
91
        $bootstrap_request = $this->bootstrapRequestResponseObjects();
92
        add_action(
93
            'EE_Load_Espresso_Core__handle_request__initialize_core_loading',
94
            array($bootstrap_request, 'setupLegacyRequest')
95
        );
96
        $this->runRequestStack();
97
    }
98
99
100
    /**
101
     * @throws ReflectionException
102
     * @throws EE_Error
103
     * @throws InvalidArgumentException
104
     * @throws InvalidDataTypeException
105
     * @throws InvalidInterfaceException
106
     */
107
    private function bootstrapDependencyInjectionContainer()
108
    {
109
        $bootstrap_di = new BootstrapDependencyInjectionContainer();
110
        $bootstrap_di->buildLegacyDependencyInjectionContainer();
111
        $bootstrap_di->buildLoader();
112
        $registry = $bootstrap_di->getRegistry();
113
        $dependency_map = $bootstrap_di->getDependencyMap();
114
        $dependency_map->initialize();
115
        $registry->initialize();
116
        $this->loader = $bootstrap_di->getLoader();
117
    }
118
119
120
    /**
121
     * sets up the request and response objects
122
     *
123
     * @return BootstrapRequestResponseObjects
124
     * @throws InvalidArgumentException
125
     */
126
    private function bootstrapRequestResponseObjects()
127
    {
128
        /** @var BootstrapRequestResponseObjects $bootstrap_request */
129
        $bootstrap_request = $this->loader->getShared(
130
            'EventEspresso\core\services\bootstrap\BootstrapRequestResponseObjects',
131
            array($this->loader)
132
        );
133
        $bootstrap_request->buildRequestResponse();
134
        $bootstrap_request->shareRequestResponse();
135
        $this->request  = $this->loader->getShared('EventEspresso\core\services\request\Request');
136
        $this->response = $this->loader->getShared('EventEspresso\core\services\request\Response');
137
        return $bootstrap_request;
138
    }
139
140
141
142
    /**
143
     * run_request_stack
144
     * construct request stack and run middleware apps
145
     *
146
     * @throws InvalidInterfaceException
147
     * @throws InvalidDataTypeException
148
     * @throws EE_Error
149
     * @throws InvalidArgumentException
150
     * @throws ReflectionException
151
     */
152
    public function runRequestStack()
153
    {
154
        $this->loadAutoloader();
155
        $this->setAutoloadersForRequiredFiles();
156
        $this->request_stack_builder = $this->buildRequestStack();
157
        $this->request_stack         = $this->request_stack_builder->resolve(
158
            new RequestStackCoreApp()
159
        );
160
        $this->request_stack->handleRequest($this->request, $this->response);
161
        $this->request_stack->handleResponse();
162
    }
163
164
165
    /**
166
     * load_autoloader
167
     *
168
     * @throws EE_Error
169
     */
170
    protected function loadAutoloader()
171
    {
172
        // load interfaces
173
        espresso_load_required(
174
            'EEH_Autoloader',
175
            EE_CORE . 'helpers' . DS . 'EEH_Autoloader.helper.php'
176
        );
177
        EEH_Autoloader::instance();
178
    }
179
180
181
182
    /**
183
     * load_required_files
184
     *
185
     * @throws EE_Error
186
     */
187
    protected function setAutoloadersForRequiredFiles()
188
    {
189
        // load interfaces
190
        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'interfaces', true);
191
        // load helpers
192
        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_HELPERS);
193
        // load request stack
194
        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'request_stack' . DS);
195
        // load middleware
196
        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(EE_CORE . 'middleware' . DS);
197
    }
198
199
200
201
    /**
202
     * build_request_stack
203
     *
204
     * @return RequestStackBuilder
205
     */
206
    public function buildRequestStack()
207
    {
208
        $request_stack_builder = new RequestStackBuilder($this->loader);
209
        /**
210
         * ! IMPORTANT ! The middleware stack operates FILO : FIRST IN LAST OUT
211
         * so items at the beginning of the final middleware stack will run last.
212
         * First parameter is the middleware classname, second is an array of arguments
213
         */
214
        $stack_apps            = apply_filters(
215
            'FHEE__EventEspresso_core_services_bootstrap_BootstrapCore__buildRequestStack__stack_apps',
216
            array(
217
                // first in last out
218
                'EventEspresso\core\services\request\middleware\BotDetector' => array(),
219
                'EventEspresso\core\services\request\middleware\DetectFileEditorRequest' => array(),
220
                'EventEspresso\core\services\request\middleware\PreProductionVersionWarning' => array(),
221
                'EventEspresso\core\services\request\middleware\RecommendedVersions' => array(),
222
                // last in first out
223
                'EventEspresso\core\services\request\middleware\DetectLogin' => array(),
224
            )
225
        );
226
        // legacy filter for backwards compatibility
227
        $stack_apps            = apply_filters(
228
            'FHEE__EE_Bootstrap__build_request_stack__stack_apps',
229
            $stack_apps
230
        );
231
        // load middleware onto stack : FILO (First In Last Out)
232
        // items at the beginning of the $stack_apps array will run last
233
        foreach ((array) $stack_apps as $stack_app => $stack_app_args) {
234
            $request_stack_builder->push(array($stack_app, $stack_app_args));
235
        }
236
        // finally, we'll add this on its own because we need it to always be part of the stack
237
        // and we also need it to always run first because the rest of the system relies on it
238
        $request_stack_builder->push(
239
            array('EventEspresso\core\services\request\middleware\SetRequestTypeContextChecker', array())
240
        );
241
        return apply_filters(
242
            'FHEE__EE_Bootstrap__build_request_stack__request_stack_builder',
243
            $request_stack_builder
244
        );
245
    }
246
247
248
}
249
// Location: BootstrapCore.php
250