Application::loadDefaultThemePlugin()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
nc 3
nop 0
dl 0
loc 11
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
7
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
8
 *
9
 * Licensed under The MIT License
10
 * For full copyright and license information, please see the LICENSE.txt
11
 * Redistributions of files must retain the above copyright notice.
12
 *
13
 * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
14
 * @link      https://cakephp.org CakePHP(tm) Project
15
 * @since     3.3.0
16
 * @license   https://opensource.org/licenses/mit-license.php MIT License
17
 */
18
namespace App;
19
20
use App\Auth\AuthenticationServiceFactory;
21
use App\Middleware\SaitoBootstrapMiddleware;
22
use Authentication\AuthenticationService;
23
use Authentication\AuthenticationServiceProviderInterface;
24
use Authentication\Middleware\AuthenticationMiddleware;
25
use Authentication\UrlChecker\DefaultUrlChecker;
26
use Cake\Core\Configure;
27
use Cake\Core\Exception\MissingPluginException;
28
use Cake\Core\Plugin;
29
use Cake\Error\Middleware\ErrorHandlerMiddleware;
30
use Cake\Event\EventManagerInterface;
31
use Cake\Http\BaseApplication;
32
use Cake\Http\Middleware\EncryptedCookieMiddleware;
33
use Cake\Http\Middleware\SecurityHeadersMiddleware;
34
use Cake\Routing\Middleware\AssetMiddleware;
35
use Cake\Routing\Middleware\RoutingMiddleware;
36
use Psr\Http\Message\ResponseInterface;
37
use Psr\Http\Message\ServerRequestInterface;
38
use Saito\App\Registry;
39
use Stopwatch\Lib\Stopwatch;
40
41
/**
42
 * Application setup class.
43
 *
44
 * This defines the bootstrapping logic and middleware layers you
45
 * want to use in your application.
46
 */
47
class Application extends BaseApplication implements AuthenticationServiceProviderInterface
48
{
49
    /**
50
     * {@inheritDoc}
51
     */
52
    public function __construct($configDir, EventManagerInterface $eventManager = null)
53
    {
54
        Stopwatch::init();
55
        Stopwatch::enable();
56
        Stopwatch::start('Application::__construct');
57
        parent::__construct($configDir, $eventManager);
58
        Stopwatch::stop('Application::__construct');
59
    }
60
61
    /**
62
     * {@inheritDoc}
63
     */
64
    public function bootstrap()
65
    {
66
        Stopwatch::start('Application::bootstrap');
67
68
        parent::bootstrap();
69
70
        if (PHP_SAPI === 'cli') {
71
            $this->bootstrapCli();
72
        }
73
        /*
74
         * Only try to load DebugKit in development mode
75
         * Debug Kit should not be installed on a production system
76
         */
77
        if (Configure::read('debug')) {
78
            // $this->addPlugin(\DebugKit\Plugin::class);
79
        }
80
        // Load more plugins here
81
82
        Registry::initialize();
83
84
        $this->addPlugin('Authentication');
85
        $this->addPlugin(\Admin\Plugin::class, ['routes' => true]);
86
        $this->addPlugin(\Api\Plugin::class, ['bootstrap' => true, 'routes' => true]);
87
        $this->addPlugin(\Bookmarks\Plugin::class, ['routes' => true]);
88
        $this->addPlugin(\BbcodeParser\Plugin::class);
89
        $this->addPlugin(\Feeds\Plugin::class, ['routes' => true]);
90
        $this->addPlugin(\Installer\Plugin::class);
91
        $this->addPlugin(\SaitoHelp\Plugin::class, ['routes' => true]);
92
        $this->addPlugin(\SaitoSearch\Plugin::class, ['routes' => true]);
93
        $this->addPlugin(\Sitemap\Plugin::class, ['bootstrap' => true, 'routes' => true]);
94
        $this->addPlugin(\ImageUploader\Plugin::class, ['routes' => true]);
95
96
        $this->addPlugin(\Cron\Plugin::class);
97
        $this->addPlugin(\Commonmark\Plugin::class);
98
        $this->addPlugin(\Detectors\Plugin::class);
99
        $this->addPlugin(\MailObfuscator\Plugin::class);
100
        $this->addPlugin(\SpectrumColorpicker\Plugin::class);
101
        $this->addPlugin(\Stopwatch\Plugin::class);
102
103
        $this->addPlugin('Proffer');
104
105
        $this->addPlugin('Local');
106
        $this->loadDefaultThemePlugin();
107
108
        Stopwatch::stop('Application::bootstrap');
109
    }
110
111
    /**
112
     * Setup the middleware queue your application will use.
113
     *
114
     * @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to setup.
115
     * @return \Cake\Http\MiddlewareQueue The updated middleware queue.
116
     */
117
    public function middleware($middlewareQueue)
118
    {
119
        $middlewareQueue
120
            // Catch any exceptions in the lower layers,
121
            // and make an error page/response
122
            ->add(ErrorHandlerMiddleware::class)
123
124
            // Handle plugin/theme assets like CakePHP normally does.
125
            ->add(AssetMiddleware::class)
126
127
            // Add routing middleware.
128
            // Routes collection cache enabled by default, to disable route caching
129
            // pass null as cacheConfig, example: `new RoutingMiddleware($this)`
130
            // you might want to disable this cache in case your routing is extremely simple
131
            ->add(new RoutingMiddleware($this, '_cake_routes_'))
132
133
            ->insertAfter(RoutingMiddleware::class, new SaitoBootstrapMiddleware())
134
135
            ->add(new EncryptedCookieMiddleware(
136
                // Names of cookies to protect
137
                [Configure::read('Security.cookieAuthName')],
138
                Configure::read('Security.cookieSalt')
139
            ))
140
141
            // CakePHP authentication provider
142
            ->insertAfter(
143
                EncryptedCookieMiddleware::class,
144
                new AuthenticationMiddleware($this)
145
            );
146
147
        $security = (new SecurityHeadersMiddleware())
148
            ->setXFrameOptions(strtolower(Configure::read('Saito.X-Frame-Options')));
149
        $middlewareQueue->add($security);
150
151
        return $middlewareQueue;
152
    }
153
154
    /**
155
     * Get authentication service.
156
     *
157
     * Part of AuthenticationServiceProviderInterface.
158
     *
159
     * {@inheritDoc}
160
     */
161
    public function getAuthenticationService(ServerRequestInterface $request, ResponseInterface $response): AuthenticationService
162
    {
163
        $isApi = (new DefaultUrlChecker())
164
            ->check($request, ['#api/v2#'], ['useRegex' => true]);
165
        if ($isApi) {
166
            return AuthenticationServiceFactory::buildJwt();
167
        }
168
169
        return AuthenticationServiceFactory::buildApp();
170
    }
171
172
    /**
173
     * Load the plugin for Saito's default theme
174
     *
175
     * @return void
176
     */
177
    private function loadDefaultThemePlugin()
178
    {
179
        $defaultTheme = Configure::read('Saito.themes.default');
180
        if (empty($defaultTheme)) {
181
            throw new \RuntimeException(
182
                'Could not resolve default theme for plugin loading.',
183
                1556562215
184
            );
185
        }
186
        if (Plugin::isLoaded($defaultTheme) !== true) {
187
            $this->addPlugin($defaultTheme);
188
        }
189
    }
190
191
    /**
192
     * @return void
193
     */
194
    protected function bootstrapCli()
195
    {
196
        try {
197
            $this->addPlugin('Bake');
198
        } catch (MissingPluginException $e) {
199
            // Do not halt if the plugin is missing
200
        }
201
        $this->addPlugin('Migrations');
202
        // Load more plugins here
203
    }
204
}
205