Test Failed
Pull Request — develop (#340)
by Felipe
03:49
created

ContainerUtils::getTheme()   C

Complexity

Conditions 14
Paths 6

Size

Total Lines 35
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 25
c 0
b 0
f 0
nc 6
nop 2
dl 0
loc 35
rs 6.2666

1 Method

Rating   Name   Duplication   Size   Complexity  
A ContainerUtils::addError() 0 8 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * PHPPgAdmin 6.0.0
5
 */
6
7
namespace PHPPgAdmin;
8
9
use Psr\Container\ContainerInterface;
10
use Slim\Collection;
11
use Slim\DefaultServicesProvider;
12
13
/**
14
 * @property array $deploy_info
15
 * @property \Slim\Flash\Messages $flash
16
 * @property \GuzzleHttp\Client $fcIntranetClient
17
 * @property \PHPPgAdmin\Misc $misc
18
 * @property \PHPPgAdmin\ViewManager $view
19
 * @property \Slim\Http\Request $request
20
 * @property \Slim\Http\Response $response
21
 * @property string $BASE_PATH
22
 * @property string $THEME_PATH
23
 * @property string $subfolder
24
 * @property bool $DEBUGMODE
25
 * @property bool $IN_TEST
26
 * @property string  $server
27
 * @property string $database
28
 * @property string  $schema
29
 * @property
30
 */
31
class ContainerUtils extends \Slim\Container implements ContainerInterface
32
{
33
    use \PHPPgAdmin\Traits\HelperTrait;
34
35
    /**
36
     * @var null|self
37
     */
38
    private static $instance;
39
40
    /**
41
     * $appInstance.
42
     *
43
     * @var null|\Slim\App
44
     */
45
    private static $appInstance;
46
47
    /**
48
     * Default settings.
49
     *
50
     * @var array
51
     */
52
    private $defaultSettings = [
53
        'httpVersion' => '1.1',
54
        'responseChunkSize' => 4096,
55
        'outputBuffering' => 'append',
56
        'determineRouteBeforeAppMiddleware' => false,
57
        'displayErrorDetails' => false,
58
        'addContentLengthHeader' => true,
59
        'routerCacheFile' => false,
60
    ];
61
62
    /**
63
     * Undocumented variable.
64
     *
65
     * @var array
66
     */
67
    private static $envConfig = [
68
        'BASE_PATH' => '',
69
        'subFolder' => '',
70
        'DEBUGMODE' => false,
71
        'THEME_PATH' => '',
72
    ];
73
74
    /**
75
     * @param array $values the parameters or objects
76
     */
77
    final public function __construct(array $values = [])
78
    {
79
        parent::__construct($values);
80
81
        $userSettings = $values['settings'] ?? [];
82
        $this->registerDefaultServices($userSettings);
83
84
        self::$instance = $this;
85
    }
86
87
    /**
88
     * Gets the subfolder.
89
     *
90
     * @param string $path The path
91
     *
92
     * @return string the subfolder
93
     */
94
    public function getSubfolder(string $path = ''): string
95
    {
96
        return \implode(\DIRECTORY_SEPARATOR, [$this->subFolder, $path]);
97
    }
98
99
    public static function getAppInstance(array $config = []): \Slim\App
100
    {
101
        $config = \array_merge(self::getDefaultConfig(), $config);
102
        $container = self::getContainerInstance($config);
103
104
        if (!self::$appInstance) {
105
            self::$appInstance = new \Slim\App($container);
106
        }
107
108
        return self::$appInstance;
109
    }
110
111
    public static function getContainerInstance(array $config = []): self
112
    {
113
        self::$envConfig = [
114
            'msg' => '',
115
            'appThemes' => [
116
                'default' => 'Default',
117
                'cappuccino' => 'Cappuccino',
118
                'gotar' => 'Blue/Green',
119
                'bootstrap' => 'Bootstrap3',
120
            ],
121
            'BASE_PATH' => $config['BASE_PATH'] ?? \dirname(__DIR__, 2),
122
            'subFolder' => $config['subfolder'] ?? '',
123
            'DEBUGMODE' => $config['debugmode'] ?? false,
124
            'THEME_PATH' => $config['theme_path'] ?? \dirname(__DIR__, 2) . '/assets/themes',
125
            'IN_TEST' => $config['IN_TEST'] ?? false,
126
            'webdbLastTab' => [],
127
        ];
128
129
        self::$envConfig = \array_merge(self::$envConfig, $config);
130
131
        if (!self::$instance) {
132
            self::$instance = new static(self::$envConfig);
133
134
            self::$instance
135
                ->withConf(self::$envConfig)
136
                ->setExtra()
137
                ->setMisc()
138
                ->setViews();
139
        }
140
        //ddd($container->subfolder);
141
        return self::$instance;
142
    }
143
144
    /**
145
     * Determines the redirection url according to query string.
146
     *
147
     * @return string the redirect url
148
     */
149
    public function getRedirectUrl()
150
    {
151
        $container = self::getContainerInstance();
152
        $query_string = $container->request->getUri()->getQuery();
153
154
        // if server_id isn't set, then you will be redirected to intro
155
        if (null === $container->request->getQueryParam('server')) {
156
            $destinationurl = self::$envConfig['subFolder'] . '/src/views/intro';
157
        } else {
158
            // otherwise, you'll be redirected to the login page for that server;
159
            $destinationurl = self::$envConfig['subFolder'] . '/src/views/login' . ($query_string ? '?' . $query_string : '');
160
        }
161
162
        return $destinationurl;
163
    }
164
165
    /**
166
     * Adds a flash message to the session that will be displayed on the next request.
167
     *
168
     * @param mixed  $content msg content (can be object, array, etc)
169
     * @param string $key     The key to associate with the message. Defaults to the stack
170
     *                        trace of the closure or method that called addFlassh
171
     */
172
    public function addFlash($content, $key = ''): void
173
    {
174
        if ('' === $key) {
175
            $key = self::getBackTrace();
176
        }
177
        $container = self::getContainerInstance();
178
        // $this->dump(__METHOD__ . ': addMessage ' . $key . '  ' . json_encode($content));
179
        if ($container->flash) {
180
            $container->flash->addMessage($key, $content);
0 ignored issues
show
Bug introduced by
It seems like $key can also be of type array<string,mixed|string>; however, parameter $key of Slim\Flash\Messages::addMessage() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

180
            $container->flash->addMessage(/** @scrutinizer ignore-type */ $key, $content);
Loading history...
181
        }
182
    }
183
184
    /**
185
     * Gets the destination with the last active tab selected for that controller
186
     * Usually used after going through a redirect route.
187
     *
188
     * @param string $subject The subject, usually a view name like 'server' or 'table'
189
     *
190
     * @return string The destination url with last tab set in the query string
191
     */
192
    public function getDestinationWithLastTab($subject)
193
    {
194
        $container = self::getContainerInstance();
195
        $_server_info = $container->misc->getServerInfo();
196
        $this->addFlash($subject, 'getDestinationWithLastTab');
197
        //$this->prtrace('$_server_info', $_server_info);
198
        // If username isn't set in server_info, you should login
199
        $url = $container->misc->getLastTabURL($subject) ?? ['url' => 'alldb', 'urlvars' => ['subject' => 'server']];
200
        $destinationurl = $this->getRedirectUrl();
201
202
        if (!isset($_server_info['username'])) {
203
            return $destinationurl;
204
        }
205
206
        if (!\is_array($url)) {
207
            return $this->getRedirectUrl($subject);
0 ignored issues
show
Unused Code introduced by
The call to PHPPgAdmin\ContainerUtils::getRedirectUrl() has too many arguments starting with $subject. ( Ignorable by Annotation )

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

207
            return $this->/** @scrutinizer ignore-call */ getRedirectUrl($subject);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
208
        }
209
        $this->addFlash($url, 'getLastTabURL for ' . $subject);
210
        // Load query vars into superglobal arrays
211
        if (isset($url['urlvars'])) {
212
            $urlvars = [];
213
214
            foreach ($url['urlvars'] as $key => $urlvar) {
215
                //$this->prtrace($key, $urlvar);
216
                $urlvars[$key] = \PHPPgAdmin\Decorators\Decorator::get_sanitized_value($urlvar, $_REQUEST);
217
            }
218
            $_REQUEST = \array_merge($_REQUEST, $urlvars);
219
            $_GET = \array_merge($_GET, $urlvars);
220
        }
221
        $actionurl = \PHPPgAdmin\Decorators\Decorator::actionurl($url['url'], $_GET);
222
        $destinationurl = $actionurl->value($_GET);
223
224
        return \str_replace('views/?', "views/{$subject}?", $destinationurl);
225
    }
226
227
    /**
228
     * Adds an error to the errors array property of the container.
229
     *
230
     * @param string $errormsg The error msg
231
     *
232
     * @return\Slim\Container The app container
233
     */
234
    public function addError(string $errormsg): \Slim\Container
235
    {
236
        $container = self::getContainerInstance();
237
        $errors = $container->get('errors');
238
        $errors[] = $errormsg;
239
        $container->offsetSet('errors', $errors);
240
241
        return $container;
242
    }
243
244
    /**
245
     * Returns a string with html <br> variant replaced with a new line.
246
     *
247
     * @param string $msg message to parse (<br> separated)
248
     *
249
     * @return string parsed message (linebreak separated)
250
     */
251
    public static function br2ln($msg)
252
    {
253
        return \str_replace(['<br>', '<br/>', '<br />'], \PHP_EOL, $msg);
254
    }
255
256
    public static function getDefaultConfig(): array
257
    {
258
        return  [
259
            'settings' => [
260
                'displayErrorDetails' => self::$envConfig['DEBUGMODE'],
261
                'determineRouteBeforeAppMiddleware' => true,
262
                'base_path' => \dirname(__DIR__, 2),
263
                'debug' => self::$envConfig['DEBUGMODE'],
264
                'phpMinVer' => '7.1', // PHP minimum version
265
                'addContentLengthHeader' => false,
266
                'appName' => 'PHPPgAdmin6',
267
            ],
268
        ];
269
    }
270
271
    /**
272
     * @param array $conf
273
     */
274
    private function withConf($conf): self
275
    {
276
        $container = self::getContainerInstance();
277
        $conf['plugins'] = [];
278
279
        $container->BASE_PATH = $conf['BASE_PATH'];
280
        $container->subFolder = $conf['subfolder'];
281
        $container->DEBUGMODE = $conf['debugmode'];
282
        $container->THEME_PATH = $conf['theme_path'];
283
        $container->IN_TEST = $conf['IN_TEST'];
284
        $container['errors'] = [];
285
        $container['conf'] = static function (\Slim\Container $c) use ($conf): array {
286
            $display_sizes = $conf['display_sizes'];
287
288
            if (\is_array($display_sizes)) {
289
                $conf['display_sizes'] = [
290
                    'schemas' => (bool) isset($display_sizes['schemas']) && true === $display_sizes['schemas'],
291
                    'tables' => (bool) isset($display_sizes['tables']) && true === $display_sizes['tables'],
292
                ];
293
            } else {
294
                $conf['display_sizes'] = [
295
                    'schemas' => (bool) $display_sizes,
296
                    'tables' => (bool) $display_sizes,
297
                ];
298
            }
299
300
            if (!isset($conf['theme'])) {
301
                $conf['theme'] = 'default';
302
            }
303
304
            foreach ($conf['servers'] as &$server) {
305
                if (!isset($server['port'])) {
306
                    $server['port'] = 5432;
307
                }
308
309
                if (!isset($server['sslmode'])) {
310
                    $server['sslmode'] = 'unspecified';
311
                }
312
            }
313
            //self::$envConfig=[
314
            //'BASE_PATH'=>$conf['BASE_PATH'],
315
            //'subFolder'=>$conf['subfolder'],
316
            //'DEBUGMODE'=>$conf['debugmode'],
317
            //'THEME_PATH'=>$conf['theme_path'],
318
            //'IN_TEST'=>$conf['IN_TEST']
319
            //];
320
321
            return $conf;
322
        };
323
324
        $container->subfolder = $conf['subfolder'];
325
326
        return $this;
327
    }
328
329
    /**
330
     * Sets the views.
331
     *
332
     * @return self ( description_of_the_return_value )
333
     */
334
    private function setViews()
335
    {
336
        $container = self::getContainerInstance();
337
338
        /**
339
         * @return \PHPPgAdmin\ViewManager
340
         */
341
        $container['view'] = static function (\Slim\Container $c): \PHPPgAdmin\ViewManager {
342
            $misc = $c->misc;
343
            $view = new ViewManager(BASE_PATH . '/assets/templates', [
344
                'cache' => BASE_PATH . '/temp/twigcache',
345
                'auto_reload' => $c->get('settings')['debug'],
346
                'debug' => $c->get('settings')['debug'],
347
            ], $c);
348
349
            $misc->setView($view);
350
351
            return $view;
352
        };
353
354
        return $this;
355
    }
356
357
    /**
358
     * Sets the instance of Misc class.
359
     *
360
     * @return self ( description_of_the_return_value )
361
     */
362
    private function setMisc()
363
    {
364
        $container = self::getContainerInstance();
365
        /**
366
         * @return \PHPPgAdmin\Misc
367
         */
368
        $container['misc'] = static function (\Slim\Container $c): \PHPPgAdmin\Misc {
369
            $misc = new \PHPPgAdmin\Misc($c);
370
371
            $conf = $c->get('conf');
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
372
373
            // 4. Check for theme by server/db/user
374
            $_server_info = $misc->getServerInfo();
375
376
            /* starting with PostgreSQL 9.0, we can set the application name */
377
            if (isset($_server_info['pgVersion']) && 9 <= $_server_info['pgVersion']) {
378
                \putenv('PGAPPNAME=' . $c->get('settings')['appName'] . '_' . $c->get('settings')['appVersion']);
379
            }
380
381
            return $misc;
382
        };
383
384
        return $this;
385
    }
386
387
    private function setExtra()
388
    {
389
        $container = self::getContainerInstance();
390
        $container['flash'] = static function (): \Slim\Flash\Messages {
391
            return new \Slim\Flash\Messages();
392
        };
393
394
        $container['lang'] = static function (\Slim\Container $c): array {
395
            $translations = new \PHPPgAdmin\Translations($c);
396
397
            return $translations->lang;
398
        };
399
400
        return $this;
401
    }
402
403
    /**
404
     * This function registers the default services that Slim needs to work.
405
     *
406
     * All services are shared, they are registered such that the
407
     * same instance is returned on subsequent calls.
408
     *
409
     * @param array $userSettings Associative array of application settings
410
     */
411
    private function registerDefaultServices($userSettings): void
412
    {
413
        $defaultSettings = $this->defaultSettings;
414
415
        /**
416
         * This service MUST return an array or an instance of ArrayAccess.
417
         *
418
         * @return array|ArrayAccess
419
         */
420
        $this['settings'] = static function () use ($userSettings, $defaultSettings): \Slim\Collection {
421
            return new Collection(\array_merge($defaultSettings, $userSettings));
422
        };
423
424
        $defaultProvider = new DefaultServicesProvider();
425
        $defaultProvider->register($this);
426
    }
427
}
428