Completed
Pull Request — newinternal (#285)
by Simon
06:16 queued 03:05
created

WebStart::isPublic()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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\SecurityManager;
20
use Waca\Security\TokenManager;
21
use Waca\Tasks\ITask;
22
use Waca\Tasks\InternalPageBase;
23
use Waca\Tasks\PageBase;
24
25
/**
26
 * Application entry point.
27
 *
28
 * @package Waca
29
 */
30
class WebStart extends ApplicationBase
31
{
32
    /**
33
     * @var IRequestRouter $requestRouter The request router to use. Note that different entry points have different
34
     *                                    routers and hence different URL mappings
35
     */
36
    private $requestRouter;
37
    /**
38
     * @var bool $isPublic Determines whether to use public interface objects or internal interface objects
39
     */
40
    private $isPublic = false;
41
42
    /**
43
     * WebStart constructor.
44
     *
45
     * @param SiteConfiguration $configuration The site configuration
46
     * @param IRequestRouter    $router        The request router to use
47
     */
48 3
    public function __construct(SiteConfiguration $configuration, IRequestRouter $router)
49
    {
50 3
        parent::__construct($configuration);
51
52 3
        $this->requestRouter = $router;
53 3
    }
54
55
    /**
56
     * @param ITask             $page
57
     * @param SiteConfiguration $siteConfiguration
58
     * @param PdoDatabase       $database
59
     * @param PdoDatabase       $notificationsDatabase
0 ignored issues
show
Documentation introduced by
Should the type for parameter $notificationsDatabase not be null|PdoDatabase?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
60
     *
61
     * @return void
62
     */
63
    protected function setupHelpers(
64
        ITask $page,
65
        SiteConfiguration $siteConfiguration,
66
        PdoDatabase $database,
67
        PdoDatabase $notificationsDatabase = null
68
    ) {
69
        parent::setupHelpers($page, $siteConfiguration, $database, $notificationsDatabase);
70
71
        if ($page instanceof PageBase) {
72
            $page->setTokenManager(new TokenManager());
73
74
            if ($page instanceof InternalPageBase) {
75
                $page->setTypeAheadHelper(new TypeAheadHelper());
76
77
                $identificationVerifier = new IdentificationVerifier($page->getHttpHelper(), $siteConfiguration,
78
                    $database);
79
                $page->setIdentificationVerifier($identificationVerifier);
80
81
                $page->setSecurityManager(new SecurityManager($identificationVerifier,
82
                    $siteConfiguration->getForceIdentification()));
83
84
                if ($siteConfiguration->getTitleBlacklistEnabled()) {
85
                    $page->setBlacklistHelper(new FakeBlacklistHelper());
86
                }
87
                else {
88
                    $page->setBlacklistHelper(new BlacklistHelper($page->getHttpHelper(),
89
                        $siteConfiguration->getMediawikiWebServiceEndpoint()));
90
                }
91
            }
92
        }
93
    }
94
95
    /**
96
     * Application entry point.
97
     *
98
     * Sets up the environment and runs the application, performing any global cleanup operations when done.
99
     */
100
    public function run()
101
    {
102
        try {
103
            if ($this->setupEnvironment()) {
104
                $this->main();
105
            }
106
        }
107
        catch (EnvironmentException $ex) {
108
            ob_end_clean();
109
            print Offline::getOfflineMessage($this->isPublic(), $ex->getMessage());
110
        }
111
        catch (ReadableException $ex) {
112
            ob_end_clean();
113
            print $ex->getReadableError();
114
        }
115
        finally {
116
            $this->cleanupEnvironment();
117
        }
118
    }
119
120
    /**
121
     * Environment setup
122
     *
123
     * This method initialises the tool environment. If the tool cannot be initialised correctly, it will return false
124
     * and shut down prematurely.
125
     *
126
     * @return bool
127
     * @throws EnvironmentException
128
     */
129
    protected function setupEnvironment()
130
    {
131
        // initialise global exception handler
132
        set_exception_handler(array(ExceptionHandler::class, 'exceptionHandler'));
133
        set_error_handler(array(ExceptionHandler::class, 'errorHandler'), E_RECOVERABLE_ERROR);
134
135
        // start output buffering if necessary
136
        if (ob_get_level() === 0) {
137
            ob_start();
138
        }
139
140
        // initialise super-global providers
141
        WebRequest::setGlobalStateProvider(new GlobalStateProvider());
142
143
        if (Offline::isOffline()) {
144
            print Offline::getOfflineMessage($this->isPublic());
145
            ob_end_flush();
146
147
            return false;
148
        }
149
150
        // Call parent setup
151
        if (!parent::setupEnvironment()) {
152
            return false;
153
        }
154
155
        // Start up sessions
156
        Session::start();
157
158
        // Check the user is allowed to be logged in still. This must be before we call any user-loading functions and
159
        // get the current user cached.
160
        // I'm not sure if this function call being here is particularly a good thing, but it's part of starting up a
161
        // session I suppose.
162
        $this->checkForceLogout();
163
164
        // environment initialised!
165
        return true;
166
    }
167
168
    /**
169
     * Main application logic
170
     */
171
    protected function main()
172
    {
173
        // Get the right route for the request
174
        $page = $this->requestRouter->route();
175
176
        $siteConfiguration = $this->getConfiguration();
177
        $database = PdoDatabase::getDatabaseConnection('acc');
178
179
        if ($siteConfiguration->getIrcNotificationsEnabled()) {
180
            $notificationsDatabase = PdoDatabase::getDatabaseConnection('notifications');
181
        }
182
        else {
183
            // @todo federated table here?
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
184
            $notificationsDatabase = $database;
185
        }
186
187
        $this->setupHelpers($page, $siteConfiguration, $database, $notificationsDatabase);
188
189
        /* @todo Remove this global statement! It's here for User.php, which does far more than it should. */
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
190
        global $oauthHelper;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
191
        $oauthHelper = $page->getOAuthHelper();
192
193
        /* @todo Remove this global statement! It's here for Request.php, which does far more than it should. */
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
194
        global $globalXffTrustProvider;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
195
        $globalXffTrustProvider = $page->getXffTrustProvider();
196
197
        // run the route code for the request.
198
        $page->execute();
199
    }
200
201
    /**
202
     * Any cleanup tasks should go here
203
     *
204
     * Note that we need to be very careful here, as exceptions may have been thrown and handled.
205
     * This should *only* be for cleaning up, no logic should go here.
206
     */
207
    protected function cleanupEnvironment()
208
    {
209
        // Clean up anything we splurged after sending the page.
210
        if (ob_get_level() > 0) {
211
            for ($i = ob_get_level(); $i > 0; $i--) {
212
                ob_end_clean();
213
            }
214
        }
215
    }
216
217
    private function checkForceLogout()
218
    {
219
        $database = PdoDatabase::getDatabaseConnection('acc');
220
221
        $sessionUserId = WebRequest::getSessionUserId();
222
        iF ($sessionUserId === null) {
223
            return;
224
        }
225
226
        // Note, User::getCurrent() caches it's result, which we *really* don't want to trigger.
227
        $currentUser = User::getById($sessionUserId, $database);
228
229
        if ($currentUser === false) {
230
            // Umm... this user has a session cookie with a userId set, but no user exists...
231
            Session::restart();
232
        }
233
234
        if ($currentUser->getForceLogout()) {
235
            Session::restart();
236
237
            $currentUser->setForceLogout(false);
238
            $currentUser->save();
239
        }
240
    }
241
242 1
    public function isPublic()
243
    {
244 1
        return $this->isPublic;
245
    }
246
247 1
    public function setPublic($isPublic)
248
    {
249 1
        $this->isPublic = $isPublic;
250 1
    }
251
}
252