Passed
Push — master ( a8ec29...5f73fa )
by Chauncey
08:25
created

AdminModule::setupMetadataForAdmin()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 0
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Charcoal\Admin;
4
5
// From PSR-7
6
use Psr\Http\Message\RequestInterface;
7
use Psr\Http\Message\ResponseInterface;
8
9
// From 'charcoal-app'
10
use Charcoal\App\Handler\HandlerInterface;
11
use Charcoal\App\Module\AbstractModule;
12
13
// From 'charcoal-admin'
14
use Charcoal\Admin\ServiceProvider\AdminServiceProvider;
15
16
/**
17
 * Charcoal Administration Module
18
 */
19
class AdminModule extends AbstractModule
20
{
21
    /**
22
     * Charcoal Administration Setup.
23
     *
24
     * This module is bound to the `/admin` URL.
25
     *
26
     * ## Provides
27
     *
28
     * - `charcoal/admin/module` An instance of this module
29
     *   - Exact type: `\Charcoal\Admin\AdminModule`
30
     *   - which implements `\Charcoal\Module\ModuleInterface`
31
     *
32
     * ## Dependencies
33
     * - `charcoal/config` Provided by \Charcoal\CharcoalModule
34
     *
35
     * @return AdminModule Chainable
36
     */
37
    public function setup()
38
    {
39
        // Hack: skip if the request does not start with '/admin'
40
        $container = $this->app()->getContainer();
41
        if (substr(ltrim($container['request']->getUri()->getPath(), '/'), 0, 5) !== 'admin') {
42
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Charcoal\Admin\AdminModule which is incompatible with the return type mandated by Charcoal\App\Module\ModuleInterface::setup() of void.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
43
        }
44
45
        // A session is necessary for the admin module
46
        if (session_id() === '') {
47
            session_start();
48
        }
49
        $container->register(new AdminServiceProvider());
0 ignored issues
show
Bug introduced by
The method register() does not exist on Psr\Container\ContainerInterface. It seems like you code against a sub-type of Psr\Container\ContainerInterface such as Slim\Container. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

49
        $container->/** @scrutinizer ignore-call */ 
50
                    register(new AdminServiceProvider());
Loading history...
50
51
        $module = $this;
52
        $container['charcoal/admin/module'] = function ($c) use ($module) {
0 ignored issues
show
Unused Code introduced by
The parameter $c is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

52
        $container['charcoal/admin/module'] = function (/** @scrutinizer ignore-unused */ $c) use ($module) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
53
            return $module;
54
        };
55
56
        $adminConfig = $container['admin/config'];
57
58
        $this->setConfig($adminConfig);
59
60
        $groupIdent = '/'.trim($adminConfig['base_path'], '/');
61
62
        // Add the route group
63
        $this->app()->group($groupIdent, 'charcoal/admin/module:setupRoutes')
64
                    ->add('charcoal/admin/module:setupHandlers');
65
66
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Charcoal\Admin\AdminModule which is incompatible with the return type mandated by Charcoal\App\Module\ModuleInterface::setup() of void.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
67
    }
68
69
    /**
70
     * Set up the module's routes and handlers.
71
     *
72
     * @return AdminModule Chainable
73
     */
74
    public function setupRoutes()
75
    {
76
        if ($this->routeManager === null) {
77
            parent::setupRoutes();
78
79
            // Serve the Admin's "Not Found" handler for the Admin's route group.
80
            $this->app()->any('{catchall:.*}', 'notFoundHandler');
81
        }
82
83
        return $this;
84
    }
85
86
    /**
87
     * Set up the module's handlers, via group middleware.
88
     *
89
     * @param  RequestInterface  $request  A PSR7 request object.
90
     * @param  ResponseInterface $response A PSR7 response object.
91
     * @param  callable          $next     The next callable middleware.
92
     * @return ResponseInterface A PSR7 response object.
93
     */
94
    public function setupHandlers(
95
        RequestInterface $request,
96
        ResponseInterface $response,
97
        callable $next
98
    ) {
99
        $container = $this->app()->getContainer();
100
101
        /**
102
         * HTTP 404 (Not Found) handler.
103
         *
104
         * @param  object|HandlerInterface $handler An error handler instance.
105
         * @return HandlerInterface
106
         */
107
        $container->extend('notFoundHandler', function ($handler, $container) {
0 ignored issues
show
Bug introduced by
The method extend() does not exist on Psr\Container\ContainerInterface. It seems like you code against a sub-type of Psr\Container\ContainerInterface such as Slim\Container. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

107
        $container->/** @scrutinizer ignore-call */ 
108
                    extend('notFoundHandler', function ($handler, $container) {
Loading history...
108
            $appConfig = $container['config'];
109
            $adminConfig = $container['admin/config'];
110
            if ($handler instanceof HandlerInterface) {
111
                $config = $handler->createConfig($appConfig['handlers.defaults']);
112
                $config->merge($adminConfig['handlers.defaults']);
113
114
                if (!empty($adminConfig['handlers.notFound'])) {
115
                    $config->merge($adminConfig['handlers.notFound']);
116
                }
117
118
                $handler->setConfig($config)->init();
0 ignored issues
show
Bug introduced by
The method init() does not exist on Charcoal\Config\ConfigurableInterface. It seems like you code against a sub-type of Charcoal\Config\ConfigurableInterface such as Charcoal\App\App or Charcoal\App\Handler\AbstractHandler. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

118
                $handler->setConfig($config)->/** @scrutinizer ignore-call */ init();
Loading history...
119
            }
120
121
            return $handler;
122
        });
123
124
        /**
125
         * HTTP 405 (Not Allowed) handler.
126
         *
127
         * @param  object|HandlerInterface $handler An error handler instance.
128
         * @return HandlerInterface
129
         */
130
        $container->extend('notAllowedHandler', function ($handler, $container) {
131
            $appConfig = $container['config'];
132
            $adminConfig = $container['admin/config'];
133
            if ($handler instanceof HandlerInterface) {
134
                $config = $handler->createConfig($appConfig['handlers.defaults']);
135
                $config->merge($adminConfig['handlers.defaults']);
136
137
                if (!empty($adminConfig['handlers.notAllowed'])) {
138
                    $config->merge($adminConfig['handlers.notAllowed']);
139
                }
140
141
                $handler->setConfig($config)->init();
142
            }
143
144
            return $handler;
145
        });
146
147
        /**
148
         * HTTP 500 (Error) handler for PHP 7+ Throwables.
149
         *
150
         * @param  object|HandlerInterface $handler An error handler instance.
151
         * @return HandlerInterface
152
         */
153
        $container->extend('phpErrorHandler', function ($handler, $container) {
154
            $appConfig = $container['config'];
155
            $adminConfig = $container['admin/config'];
156
            if ($handler instanceof HandlerInterface) {
157
                $config = $handler->createConfig($appConfig['handlers.defaults']);
158
                $config->merge($adminConfig['handlers.defaults']);
159
160
                if (!empty($adminConfig['handlers.phpError'])) {
161
                    $config->merge($adminConfig['handlers.phpError']);
162
                }
163
164
                $handler->setConfig($config)->init();
165
            }
166
167
            return $handler;
168
        });
169
170
        /**
171
         * HTTP 500 (Error) handler.
172
         *
173
         * @param  object|HandlerInterface $handler An error handler instance.
174
         * @return HandlerInterface
175
         */
176
        $container->extend('errorHandler', function ($handler, $container) {
177
            $appConfig = $container['config'];
178
            $adminConfig = $container['admin/config'];
179
            if ($handler instanceof HandlerInterface) {
180
                $config = $handler->createConfig($appConfig['handlers.defaults']);
181
                $config->merge($adminConfig['handlers.defaults']);
182
183
                if (!empty($adminConfig['handlers.error'])) {
184
                    $config->merge($adminConfig['handlers.error']);
185
                }
186
187
                $handler->setConfig($config)->init();
188
            }
189
190
            return $handler;
191
        });
192
193
        /**
194
         * HTTP 503 (Service Unavailable) handler.
195
         *
196
         * This handler is not part of Slim.
197
         *
198
         * @param  object|HandlerInterface $handler An error handler instance.
199
         * @return HandlerInterface
200
         */
201
        $container->extend('maintenanceHandler', function ($handler, $container) {
202
            $appConfig = $container['config'];
203
            $adminConfig = $container['admin/config'];
204
            if ($handler instanceof HandlerInterface) {
205
                $config = $handler->createConfig($appConfig['handlers.defaults']);
206
                $config->merge($adminConfig['handlers.defaults']);
207
208
                if (!empty($adminConfig['handlers.maintenance'])) {
209
                    $config->merge($adminConfig['handlers.maintenance']);
210
                }
211
212
                $handler->setConfig($config)->init();
213
            }
214
215
            return $handler;
216
        });
217
218
        return $next($request, $response);
219
    }
220
}
221