Completed
Push — master ( ac2b38...d1e3c1 )
by Alberto
19s queued 12s
created

Application::loadPluginsFromConfig()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 16
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
cc 6
eloc 13
c 1
b 1
f 1
nc 4
nop 0
dl 0
loc 16
rs 9.2222
1
<?php
2
/**
3
 * BEdita, API-first content management framework
4
 * Copyright 2019 ChannelWeb Srl, Chialab Srl
5
 *
6
 * This file is part of BEdita: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as published
8
 * by the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details.
12
 */
13
namespace App;
14
15
use App\Middleware\ProjectMiddleware;
16
use BEdita\I18n\Middleware\I18nMiddleware;
17
use BEdita\WebTools\BaseApplication;
18
use Cake\Core\Configure;
19
use Cake\Core\Configure\Engine\PhpConfig;
20
use Cake\Error\Middleware\ErrorHandlerMiddleware;
21
use Cake\Http\MiddlewareQueue;
22
use Cake\Http\Middleware\CsrfProtectionMiddleware;
23
use Cake\Routing\Middleware\AssetMiddleware;
24
use Cake\Routing\Middleware\RoutingMiddleware;
25
26
/**
27
 * Application class.
28
 */
29
class Application extends BaseApplication
30
{
31
    /**
32
     * {@inheritDoc}
33
     */
34
    public function bootstrap()
35
    {
36
        parent::bootstrap();
37
        $this->addPlugin('BEdita/WebTools', ['bootstrap' => true]);
38
    }
39
40
    /**
41
     * @return void
42
     */
43
    protected function bootstrapCli()
44
    {
45
        parent::bootstrapCli();
46
        $this->addPlugin('BEdita/I18n');
47
    }
48
49
    /**
50
     * Load plugins from 'Plugins' configuration.
51
     * This method will be invoked by `ProjectMiddleware`.
52
     * Should not be invoked in `bootstrap`, to avoid duplicate plugin bootstratp calls.
53
     *
54
     * @return void
55
     */
56
    public function loadPluginsFromConfig(): void
57
    {
58
        $plugins = Configure::read('Plugins', []);
59
        if ($plugins) {
60
            $defaults = [
61
                'debugOnly' => false,
62
                'autoload' => false,
63
                'bootstrap' => false,
64
                'routes' => false,
65
                'ignoreMissing' => false,
66
            ];
67
            foreach ($plugins as $plugin => $options) {
68
                $options = array_merge($defaults, $options);
69
                if (!$options['debugOnly'] || ($options['debugOnly'] && Configure::read('debug'))) {
70
                    $this->addPlugin($plugin, $options);
71
                    $this->plugins->get($plugin)->bootstrap($this);
72
                }
73
            }
74
        }
75
    }
76
77
    /**
78
     * {@inheritDoc}
79
     */
80
    public function middleware($middlewareQueue): MiddlewareQueue
81
    {
82
        $middlewareQueue
83
            // Catch any exceptions in the lower layers,
84
            // and make an error page/response
85
            ->add(new ErrorHandlerMiddleware(null, Configure::read('Error')))
86
87
            // Handle plugin/theme assets like CakePHP normally does.
88
            ->add(new AssetMiddleware([
89
                'cacheTime' => Configure::read('Asset.cacheTime'),
90
            ]))
91
92
            // Load current project configuration if `multiproject` instance
93
            // Manager plugins will also be loaded here via `loadPluginsFromConfig()`
94
            ->add(new ProjectMiddleware($this))
95
96
            // Add I18n middleware.
97
            ->add(new I18nMiddleware([
98
                'cookie' => Configure::read('I18n.cookie'),
99
                'switchLangUrl' => Configure::read('I18n.switchLangUrl'),
100
            ]))
101
102
            // Add routing middleware.
103
            ->add(new RoutingMiddleware($this))
104
105
            // Csrf Middleware
106
            ->add($this->csrfMiddleware());
107
108
        return $middlewareQueue;
109
    }
110
111
    /**
112
     * Get internal Csrf Middleware
113
     *
114
     * @return CsrfProtectionMiddleware
115
     */
116
    protected function csrfMiddleware(): CsrfProtectionMiddleware
117
    {
118
        // Csrf Middleware
119
        $csrf = new CsrfProtectionMiddleware();
120
        // Token check will be skipped when callback returns `true`.
121
        $csrf->whitelistCallback(function ($request) {
122
            $actions = (array)Configure::read(sprintf('CsrfExceptions.%s', $request->getParam('controller')));
123
            // Skip token check for API URLs.
124
            if (in_array($request->getParam('action'), $actions)) {
125
                return true;
126
            }
127
        });
128
129
        return $csrf;
130
    }
131
132
    /**
133
     * Load project configuration if corresponding config file is found
134
     *
135
     * @param string|null $project The project name.
136
     * @param string $projectsPath The project configuration files base path.
137
     * @return void
138
     */
139
    public static function loadProjectConfig(?string $project, string $projectsPath): void
140
    {
141
        if (empty($project)) {
142
            return;
143
        }
144
145
        if (file_exists($projectsPath . $project . '.php')) {
146
            Configure::config('projects', new PhpConfig($projectsPath));
147
            Configure::load($project, 'projects');
148
        }
149
    }
150
}
151