Failed Conditions
Push — multiproject/domainsettings ( c67fcc )
by Simon
04:29
created

WebStart   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 201
Duplicated Lines 0 %

Test Coverage

Coverage 10.81%

Importance

Changes 4
Bugs 1 Features 1
Metric Value
wmc 23
eloc 64
dl 0
loc 201
ccs 8
cts 74
cp 0.1081
rs 10
c 4
b 1
f 1

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A main() 0 12 1
A cleanupEnvironment() 0 6 3
A checkForceLogout() 0 24 4
A setupHelpers() 0 22 4
A setPublic() 0 3 1
A setupEnvironment() 0 37 4
A run() 0 18 4
A isPublic() 0 3 1
1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca;
10
11
use Waca\DataObjects\User;
12
use Waca\Exceptions\EnvironmentException;
13
use Waca\Exceptions\ReadableException;
14
use Waca\Helpers\BlacklistHelper;
15
use Waca\Helpers\FakeBlacklistHelper;
16
use Waca\Helpers\TypeAheadHelper;
17
use Waca\Providers\GlobalState\GlobalStateProvider;
18
use Waca\Router\IRequestRouter;
19
use Waca\Security\ContentSecurityPolicyManager;
20
use Waca\Security\RoleConfiguration;
21
use Waca\Security\SecurityManager;
22
use Waca\Security\TokenManager;
23
use Waca\Tasks\ITask;
24
use Waca\Tasks\InternalPageBase;
25
use Waca\Tasks\PageBase;
26
27
/**
28
 * Application entry point.
29
 *
30
 * @package Waca
31
 */
32
class WebStart extends ApplicationBase
33
{
34
    /**
35
     * @var IRequestRouter $requestRouter The request router to use. Note that different entry points have different
36
     *                                    routers and hence different URL mappings
37
     */
38
    private $requestRouter;
39
    /**
40
     * @var bool $isPublic Determines whether to use public interface objects or internal interface objects
41
     */
42
    private $isPublic = false;
43
44
    /**
45
     * WebStart constructor.
46
     *
47
     * @param SiteConfiguration $configuration The site configuration
48
     * @param IRequestRouter    $router        The request router to use
49
     */
50 2
    public function __construct(SiteConfiguration $configuration, IRequestRouter $router)
51
    {
52 2
        parent::__construct($configuration);
53
54 2
        $this->requestRouter = $router;
55 2
    }
56
57
    /**
58
     * @param ITask             $page
59
     * @param SiteConfiguration $siteConfiguration
60
     * @param PdoDatabase       $database
61
     *
62
     * @return void
63
     */
64
    protected function setupHelpers(
65
        ITask $page,
66
        SiteConfiguration $siteConfiguration,
67
        PdoDatabase $database
68
    ) {
69
        parent::setupHelpers($page, $siteConfiguration, $database);
70
71
        if ($page instanceof PageBase) {
72
            $page->setTokenManager(new TokenManager());
73
            $page->setCspManager(new ContentSecurityPolicyManager($siteConfiguration));
74
75
            if ($page instanceof InternalPageBase) {
76
                $page->setTypeAheadHelper(new TypeAheadHelper());
77
78
                $identificationVerifier = new IdentificationVerifier($page->getHttpHelper(), $siteConfiguration, $database);
79
                $page->setSecurityManager(new SecurityManager($identificationVerifier, new RoleConfiguration()));
80
81
                if ($siteConfiguration->getTitleBlacklistEnabled()) {
82
                    $page->setBlacklistHelper(new FakeBlacklistHelper());
83
                }
84
                else {
85
                    $page->setBlacklistHelper(new BlacklistHelper($page->getHttpHelper(), $database));
86
                }
87
            }
88
        }
89
    }
90
91
    /**
92
     * Application entry point.
93
     *
94
     * Sets up the environment and runs the application, performing any global cleanup operations when done.
95
     */
96
    public function run()
97
    {
98
        try {
99
            if ($this->setupEnvironment()) {
100
                $this->main();
101
            }
102
        }
103
        catch (EnvironmentException $ex) {
104
            ob_end_clean();
105
            print Offline::getOfflineMessage($this->isPublic(), $ex->getMessage());
106
        }
107
            /** @noinspection PhpRedundantCatchClauseInspection */
108
        catch (ReadableException $ex) {
109
            ob_end_clean();
110
            print $ex->getReadableError();
111
        }
112
        finally {
113
            $this->cleanupEnvironment();
114
        }
115
    }
116
117
    /**
118
     * Environment setup
119
     *
120
     * This method initialises the tool environment. If the tool cannot be initialised correctly, it will return false
121
     * and shut down prematurely.
122
     *
123
     * @return bool
124
     * @throws EnvironmentException
125
     */
126
    protected function setupEnvironment()
127
    {
128
        // initialise global exception handler
129
        set_exception_handler(array(ExceptionHandler::class, 'exceptionHandler'));
130
        set_error_handler(array(ExceptionHandler::class, 'errorHandler'), E_RECOVERABLE_ERROR);
131
132
        // start output buffering if necessary
133
        if (ob_get_level() === 0) {
134
            ob_start();
135
        }
136
137
        // initialise super-global providers
138
        WebRequest::setGlobalStateProvider(new GlobalStateProvider());
139
140
        if (Offline::isOffline()) {
141
            print Offline::getOfflineMessage($this->isPublic());
142
            ob_end_flush();
143
144
            return false;
145
        }
146
147
        // Call parent setup
148
        if (!parent::setupEnvironment()) {
149
            return false;
150
        }
151
152
        // Start up sessions
153
        Session::start();
154
155
        // Check the user is allowed to be logged in still. This must be before we call any user-loading functions and
156
        // get the current user cached.
157
        // I'm not sure if this function call being here is particularly a good thing, but it's part of starting up a
158
        // session I suppose.
159
        $this->checkForceLogout();
160
161
        // environment initialised!
162
        return true;
163
    }
164
165
    /**
166
     * Main application logic
167
     */
168
    protected function main()
169
    {
170
        // Get the right route for the request
171
        $page = $this->requestRouter->route();
172
173
        $siteConfiguration = $this->getConfiguration();
174
        $database = PdoDatabase::getDatabaseConnection('acc');
175
176
        $this->setupHelpers($page, $siteConfiguration, $database);
177
178
        // run the route code for the request.
179
        $page->execute();
180
    }
181
182
    /**
183
     * Any cleanup tasks should go here
184
     *
185
     * Note that we need to be very careful here, as exceptions may have been thrown and handled.
186
     * This should *only* be for cleaning up, no logic should go here.
187
     */
188
    protected function cleanupEnvironment()
189
    {
190
        // Clean up anything we splurged after sending the page.
191
        if (ob_get_level() > 0) {
192
            for ($i = ob_get_level(); $i > 0; $i--) {
193
                ob_end_clean();
194
            }
195
        }
196
    }
197
198
    private function checkForceLogout()
199
    {
200
        $database = PdoDatabase::getDatabaseConnection('acc');
201
202
        $sessionUserId = WebRequest::getSessionUserId();
203
        iF ($sessionUserId === null) {
204
            return;
205
        }
206
207
        // Note, User::getCurrent() caches it's result, which we *really* don't want to trigger.
208
        $currentUser = User::getById($sessionUserId, $database);
209
210
        if ($currentUser === false) {
0 ignored issues
show
introduced by
The condition $currentUser === false is always false.
Loading history...
211
            // Umm... this user has a session cookie with a userId set, but no user exists...
212
            Session::restart();
213
214
            $currentUser = User::getCurrent($database);
215
        }
216
217
        if ($currentUser->getForceLogout()) {
218
            Session::restart();
219
220
            $currentUser->setForceLogout(false);
221
            $currentUser->save();
222
        }
223
    }
224
225 1
    public function isPublic()
226
    {
227 1
        return $this->isPublic;
228
    }
229
230 1
    public function setPublic($isPublic)
231
    {
232 1
        $this->isPublic = $isPublic;
233 1
    }
234
}
235