Completed
Branch BUG/11268/session-ticket-relea... (71e39e)
by
unknown
27:50 queued 13:47
created

BootstrapCore::bootstrapDomain()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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