Test Failed
Pull Request — develop (#380)
by Felipe
03:42
created

ContainerUtils::getDestinationWithLastTab()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

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

196
            $container->flash->addMessage(/** @scrutinizer ignore-type */ $key, $content);
Loading history...
197
        }
198
    }
199
200
    /**
201
     * Gets the destination with the last active tab selected for that controller
202
     * Usually used after going through a redirect route.
203
     *
204
     * @param string $subject The subject, usually a view name like 'server' or 'table'
205
     *
206
     * @return string The destination url with last tab set in the query string
207
     */
208
    public function getDestinationWithLastTab($subject)
209
    {
210
        $container = self::getContainerInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $container is dead and can be removed.
Loading history...
211
        $container = self::getContainerInstance();
212
        $_server_info = $container->misc->getServerInfo();
213
        $this->addFlash($subject, 'getDestinationWithLastTab');
214
        //$this->prtrace('$_server_info', $_server_info);
215
        // If username isn't set in server_info, you should login
216
        $url = $container->misc->getLastTabURL($subject) ?? ['url' => 'alldb', 'urlvars' => ['subject' => 'server']];
217
        $destinationurl = $this->getRedirectUrl();
218
219
        if (!isset($_server_info['username'])||!\is_array($url)) {
220
            return $destinationurl;
221
        }
222
223
        $this->addFlash($url, 'getLastTabURL for ' . $subject);
224
        // Load query vars into superglobal arrays
225
        if (isset($url['urlvars'])) {
226
            $urlvars = [];
227
228
            foreach ($url['urlvars'] as $key => $urlvar) {
229
                //$this->prtrace($key, $urlvar);
230
                $urlvars[$key] = Decorator::get_sanitized_value($urlvar, $_REQUEST);
231
            }
232
            $_REQUEST = \array_merge($_REQUEST, $urlvars);
233
            $_GET = \array_merge($_GET, $urlvars);
234
        }
235
        $actionurl = Decorator::actionurl($url['url'], $_GET);
236
        $destinationurl =str_replace($this->subFolder,'', $actionurl->value($_GET));
237
if(strpos($destinationurl,$subject)===0) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
238
    $destinationurl=$this->subFolder.'/'.$destinationurl;
239
}
240
        return $destinationurl;
241
    }
242
243
    /**
244
     * Adds an error to the errors array property of the container.
245
     *
246
     * @param string $errormsg The error msg
247
     *
248
     * @return Container The app container
249
     */
250
    public function addError(string $errormsg): Container
251
    {
252
        $container = self::getContainerInstance();
253
        $errors = $container->get('errors');
254
        $errors[] = $errormsg;
255
        $container->offsetSet('errors', $errors);
256
257
        return $container;
258
    }
259
260
    /**
261
     * Returns a string with html <br> variant replaced with a new line.
262
     *
263
     * @param string $msg message to parse (<br> separated)
264
     *
265
     * @return string parsed message (linebreak separated)
266
     */
267
    public static function br2ln($msg)
268
    {
269
        return \str_replace(['<br>', '<br/>', '<br />'], \PHP_EOL, $msg);
270
    }
271
272
    public static function getDefaultConfig(bool $debug = false): array
273
    {
274
        return  [
275
            'settings' => [
276
                'displayErrorDetails' => $debug,
277
                'determineRouteBeforeAppMiddleware' => true,
278
                'base_path' => \dirname(__DIR__, 2),
279
                'debug' => $debug,
280
                'phpMinVer' => '7.2', // PHP minimum version
281
                'addContentLengthHeader' => false,
282
                'appName' => 'PHPPgAdmin6',
283
            ],
284
        ];
285
    }
286
287
    /**
288
     * @param array $conf
289
     */
290
    private function withConf($conf): self
291
    {
292
        $container = self::getContainerInstance();
293
        $conf['plugins'] = [];
294
295
        $container->BASE_PATH = $conf['BASE_PATH'];
296
        $container->subFolder = $conf['subfolder']??$conf['subFolder'];
297
        $container->debug = $conf['debugmode'];
298
        $container->THEME_PATH = $conf['theme_path'];
299
        $container->IN_TEST = $conf['IN_TEST'];
300
        $container['errors'] = [];
301
        $container['conf'] = static function (Container $c) use ($conf): array {
302
            $display_sizes = $conf['display_sizes'];
303
304
            if (\is_array($display_sizes)) {
305
                $conf['display_sizes'] = [
306
                    'schemas' => (bool) isset($display_sizes['schemas']) && true === $display_sizes['schemas'],
307
                    'tables' => (bool) isset($display_sizes['tables']) && true === $display_sizes['tables'],
308
                ];
309
            } else {
310
                $conf['display_sizes'] = [
311
                    'schemas' => (bool) $display_sizes,
312
                    'tables' => (bool) $display_sizes,
313
                ];
314
            }
315
316
            if (!isset($conf['theme'])) {
317
                $conf['theme'] = 'default';
318
            }
319
320
            foreach ($conf['servers'] as &$server) {
321
                if (!isset($server['port'])) {
322
                    $server['port'] = 5432;
323
                }
324
325
                if (!isset($server['sslmode'])) {
326
                    $server['sslmode'] = 'unspecified';
327
                }
328
            }
329
            //self::$envConfig=[
330
            //'BASE_PATH'=>$conf['BASE_PATH'],
331
            //'subFolder'=>$conf['subfolder'],
332
            //'DEBUGMODE'=>$conf['debugmode'],
333
            //'THEME_PATH'=>$conf['theme_path'],
334
            //'IN_TEST'=>$conf['IN_TEST']
335
            //];
336
337
            return $conf;
338
        };
339
340
        $container->subFolder = $conf['subfolder'];
341
342
        return $this;
343
    }
344
345
    /**
346
     * This function registers the default services that Slim needs to work.
347
     *
348
     * All services are shared, they are registered such that the
349
     * same instance is returned on subsequent calls.
350
     *
351
     * @param array $userSettings Associative array of application settings
352
     */
353
    private function registerDefaultServices($userSettings): void
354
    {
355
        $defaultSettings = $this->defaultSettings;
356
357
        /**
358
         * This service MUST return an array or an instance of ArrayAccess.
359
         *
360
         * @return array|ArrayAccess
361
         */
362
        $this['settings'] = static function () use ($userSettings, $defaultSettings): Collection {
363
            return new Collection(\array_merge($defaultSettings, $userSettings));
364
        };
365
366
        $defaultProvider = new DefaultServicesProvider();
367
        $defaultProvider->register($this);
368
    }
369
}
370