Test Failed
Pull Request — develop (#340)
by Felipe
05:31
created

ContainerUtils::createApp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 13
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 19
rs 9.8333
1
<?php
2
3
/**
4
 * PHPPgAdmin 6.0.0
5
 */
6
7
namespace PHPPgAdmin;
8
9
use Slim\App;
10
use Slim\Container;
11
12
13
/**
14
 * A class that adds convenience methods to the container.
15
 */
16
class ContainerUtils
17
{
18
    use \PHPPgAdmin\Traits\HelperTrait;
19
   
20
    /**
21
     * Undocumented variable
22
     *
23
     * @var array
24
     */
25
    private static $envConfig=[
0 ignored issues
show
Coding Style introduced by
Private member variable "envConfig" must be prefixed with an underscore
Loading history...
26
        'BASE_PATH'=>'',
27
        'SUBFOLDER'=>'',
28
        'DEBUGMODE'=>false,
29
        'THEME_PATH'=>''
30
31
    ];
32
    /**
33
     * @var string
34
     */
35
    private  $THEME_PATH;
0 ignored issues
show
Coding Style introduced by
Private member variable "THEME_PATH" must be prefixed with an underscore
Loading history...
36
37
    /**
38
     * @var \Slim\Container
39
     */
40
    protected $container;
41
42
    /**
43
     * @var App
44
     */
45
    protected $_app;
46
47
    /**
48
     * @var array
49
     */
50
    protected $conf;
51
52
    /**
53
     * @var self
54
     */
55
    protected static $_instance;
56
57
    public function __get($varname) {
0 ignored issues
show
Coding Style introduced by
Opening brace should be on a new line
Loading history...
58
return $this->container->settings[$varname];
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected at least 8 spaces, found 0
Loading history...
59
    }
60
    /**
61
     * Constructor of the ContainerUtils class.
62
     */
63
    public function __construct ()
0 ignored issues
show
Coding Style introduced by
Expected 0 spaces before opening parenthesis; 1 found
Loading history...
64
    {
65
        $composerinfo = \json_decode(\file_get_contents(self::$envConfig['BASE_PATH'] . '/composer.json'));
66
        $appVersion = $composerinfo->extra->version;
67
68
        $phpMinVer = (\str_replace(['<', '>', '='], '', $composerinfo->require->php));
69
        
70
        $settings = [
71
            'determineRouteBeforeAppMiddleware' => true,
72
            'base_path' => self::$envConfig['BASE_PATH'],
73
            'subfolder' => self::$envConfig['SUBFOLDER'],
74
            'debug' => self::$envConfig['DEBUGMODE'],
75
76
            // Configuration file version.  If this is greater than that in config.inc.php, then
77
            // the app will refuse to run.  This and $conf['version'] should be incremented whenever
78
            // backwards incompatible changes are made to config.inc.php-dist.
79
            'base_version' => 61,
80
            // Application version
81
            'appVersion' => 'v' . $appVersion,
82
            // Application name
83
            'appName' => 'phpPgAdmin6',
84
85
            // PostgreSQL and PHP minimum version
86
            'postgresqlMinVer' => '9.3',
87
            'phpMinVer' => $phpMinVer,
88
            'displayErrorDetails' => self::$envConfig['BASE_PATH'],
89
            'addContentLengthHeader' => false,
90
        ];
91
 
92
        if (!self::$envConfig['DEBUGMODE'] && !self::$envConfig['IN_TEST']) {
93
            $settings['routerCacheFile'] = self::$envConfig['BASE_PATH'] . '/temp/route.cache.php';
94
        }
95
        self::$envConfig=array_merge(self::$envConfig,$settings);
96
        $config = [
97
            'msg' => '',
98
            'appThemes' => [
99
                'default' => 'Default',
100
                'cappuccino' => 'Cappuccino',
101
                'gotar' => 'Blue/Green',
102
                'bootstrap' => 'Bootstrap3',
103
            ],
104
            'settings' => $settings,
105
        ];
106
107
        $this->_app = new App($config);
108
109
        // Fetch DI Container
110
        $container = $this->_app->getContainer();
111
        $container['utils'] = $this;
112
        $container['version'] = 'v' . $appVersion;
113
        $container['errors'] = [];
114
        $container['requestobj'] = $container['request'];
115
        $container['responseobj'] = $container['response'];
116
117
        $this->container = $container;
118
    }
119
120
    /**
121
     * Gets the container instance.
122
     *
123
     * @throws \Exception (description)
124
     *
125
     * @return \Slim\Container the container instance
126
     */
127
    public static function getContainerInstance()
128
    {
129
        $_instance = self::getInstance();
130
131
        if (!$container = $_instance->container) {
132
            throw new \Exception('Could not get a container');
133
        }
134
135
        return $container;
136
    }
137
138
    /**
139
     * Gets the instance.
140
     */
141
    public static function getInstance(): self
142
    {
143
        if (!$_instance = self::$_instance) {
144
            self::$_instance = new self();
145
            $_instance = self::$_instance;
146
        }
147
148
        return $_instance;
149
    }
150
151
    /**
152
     * Creates a container.
153
     *
154
     * @param array $conf The conf
155
     *
156
     * @return \Slim\App ( description_of_the_return_value )
157
     */
158
    public static function createApp($conf)
159
    {
160
        self::$envConfig=[
161
            'BASE_PATH'=>$conf['BASE_PATH'],
162
            'SUBFOLDER'=>$conf['subfolder'],
163
            'DEBUGMODE'=>$conf['debugmode'],
164
            'THEME_PATH'=>$conf['theme_path'],
165
            'IN_TEST'=>$conf['IN_TEST']
166
        ];
167
        
168
        $_instance = self::getInstance();
169
        $_instance
170
            ->withConf($conf)
171
            ->setExtra()
172
            ->setMisc()
173
            ->setViews();
174
175
        //ddd($container->subfolder);
176
        return $_instance->_app;
177
    }
178
179
    /**
180
     * Determines the redirection url according to query string.
181
     *
182
     * @return string the redirect url
183
     */
184
    public function getRedirectUrl()
185
    {
186
        $query_string = $this->container->requestobj->getUri()->getQuery();
187
188
        // if server_id isn't set, then you will be redirected to intro
189
        if (null === $this->container->requestobj->getQueryParam('server')) {
190
            $destinationurl = self::$envConfig['SUBFOLDER'] . '/src/views/intro';
191
        } else {
192
            // otherwise, you'll be redirected to the login page for that server;
193
            $destinationurl = self::$envConfig['SUBFOLDER'] . '/src/views/login' . ($query_string ? '?' . $query_string : '');
194
        }
195
196
        return $destinationurl;
197
    }
198
199
    /**
200
     * Adds a flash message to the session that will be displayed on the next request.
201
     *
202
     * @param mixed  $content msg content (can be object, array, etc)
203
     * @param string $key     The key to associate with the message. Defaults to the stack
204
     *                        trace of the closure or method that called addFlassh
205
     */
206
    public function addFlash($content, $key = ''): void
207
    {
208
        if ('' === $key) {
209
            $key = self::getBackTrace();
210
        }
211
        // $this->dump(__METHOD__ . ': addMessage ' . $key . '  ' . json_encode($content));
212
        if ($this->container->flash) {
213
            $this->container->flash->addMessage($key, $content);
214
        }
215
    }
216
217
    /**
218
     * Gets the destination with the last active tab selected for that controller
219
     * Usually used after going through a redirect route.
220
     *
221
     * @param string $subject The subject, usually a view name like 'server' or 'table'
222
     *
223
     * @return string The destination url with last tab set in the query string
224
     */
225
    public function getDestinationWithLastTab($subject)
226
    {
227
        $_server_info = $this->container->misc->getServerInfo();
228
        $this->addFlash($subject, 'getDestinationWithLastTab');
229
        //$this->prtrace('$_server_info', $_server_info);
230
        // If username isn't set in server_info, you should login
231
        $url = $this->container->misc->getLastTabURL($subject) ?? ['url' => 'alldb', 'urlvars' => ['subject' => 'server']];
232
        $destinationurl = $this->getRedirectUrl();
233
234
        if (!isset($_server_info['username'])) {
235
            return $destinationurl;
236
        }
237
238
        if (!\is_array($url)) {
239
            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

239
            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...
240
        }
241
        $this->addFlash($url, 'getLastTabURL for ' . $subject);
242
        // Load query vars into superglobal arrays
243
        if (isset($url['urlvars'])) {
244
            $urlvars = [];
245
246
            foreach ($url['urlvars'] as $key => $urlvar) {
247
                //$this->prtrace($key, $urlvar);
248
                $urlvars[$key] = \PHPPgAdmin\Decorators\Decorator::get_sanitized_value($urlvar, $_REQUEST);
249
            }
250
            $_REQUEST = \array_merge($_REQUEST, $urlvars);
251
            $_GET = \array_merge($_GET, $urlvars);
252
        }
253
        $actionurl = \PHPPgAdmin\Decorators\Decorator::actionurl($url['url'], $_GET);
254
        $destinationurl = $actionurl->value($_GET);
255
256
        return \str_replace('views/?', "views/{$subject}?", $destinationurl);
257
    }
258
259
    /**
260
     * Adds an error to the errors array property of the container.
261
     *
262
     * @param string $errormsg The error msg
263
     *
264
     * @return\Slim\Container The app container
265
     */
266
    public function addError(string $errormsg): \Slim\Container
267
    {
268
        //dump($errormsg);
269
        $errors = $this->container->get('errors');
270
        $errors[] = $errormsg;
271
        $this->container->offsetSet('errors', $errors);
272
273
        return $this->container;
274
    }
275
276
    /**
277
     * @param array $conf
278
     */
279
    private function withConf($conf): self
280
    {
281
        $container = self::getContainerInstance();
282
        $conf['plugins'] = [];
283
        
284
            $container->BASE_PATH=$conf['BASE_PATH'];
0 ignored issues
show
Bug introduced by
The property BASE_PATH does not seem to exist on Slim\Container.
Loading history...
285
            $container->SUBFOLDER=$conf['subfolder'];
0 ignored issues
show
Bug introduced by
The property SUBFOLDER does not seem to exist on Slim\Container.
Loading history...
286
            $container->DEBUGMODE=$conf['debugmode'];
0 ignored issues
show
Bug introduced by
The property DEBUGMODE does not seem to exist on Slim\Container.
Loading history...
287
            $container->THEME_PATH=$conf['theme_path'];
0 ignored issues
show
Bug introduced by
The property THEME_PATH does not seem to exist on Slim\Container.
Loading history...
288
            $container->IN_TEST=$conf['IN_TEST'];
0 ignored issues
show
Bug introduced by
The property IN_TEST does not seem to exist on Slim\Container.
Loading history...
289
         
290
        $container['conf'] = static function (\Slim\Container $c) use ($conf): array {
291
            $display_sizes = $conf['display_sizes'];
292
293
            if (\is_array($display_sizes)) {
294
                $conf['display_sizes'] = [
295
                    'schemas' => (bool) isset($display_sizes['schemas']) && true === $display_sizes['schemas'],
296
                    'tables' => (bool) isset($display_sizes['tables']) && true === $display_sizes['tables'],
297
                ];
298
            } else {
299
                $conf['display_sizes'] = [
300
                    'schemas' => (bool) $display_sizes,
301
                    'tables' => (bool) $display_sizes,
302
                ];
303
            }
304
305
            if (!isset($conf['theme'])) {
306
                $conf['theme'] = 'default';
307
            }
308
309
            foreach ($conf['servers'] as &$server) {
310
                if (!isset($server['port'])) {
311
                    $server['port'] = 5432;
312
                }
313
314
                if (!isset($server['sslmode'])) {
315
                    $server['sslmode'] = 'unspecified';
316
                }
317
            }
318
            //self::$envConfig=[
319
                //'BASE_PATH'=>$conf['BASE_PATH'],
320
                //'SUBFOLDER'=>$conf['subfolder'],
321
                //'DEBUGMODE'=>$conf['debugmode'],
322
                //'THEME_PATH'=>$conf['theme_path'],
323
                //'IN_TEST'=>$conf['IN_TEST']
324
            //];
325
326
            return $conf;
327
        };
328
      
329
        $container->subfolder = $conf['subfolder'];
0 ignored issues
show
Bug introduced by
The property subfolder does not seem to exist on Slim\Container.
Loading history...
330
        
331
332
        return $this;
333
    }
334
335
    /**
336
     * Sets the views.
337
     *
338
     * @return self ( description_of_the_return_value )
339
     */
340
    private function setViews()
341
    {
342
        $container = self::getContainerInstance();
343
344
        /**
345
         * @return \PHPPgAdmin\ViewManager
346
         */
347
        $container['view'] = static function (\Slim\Container $c): \PHPPgAdmin\ViewManager {
348
            $misc = $c->misc;
349
            $view = new ViewManager(BASE_PATH . '/assets/templates', [
350
                'cache' => BASE_PATH . '/temp/twigcache',
351
                'auto_reload' => $c->get('settings')['debug'],
352
                'debug' => $c->get('settings')['debug'],
353
            ], $c);
354
355
            $misc->setView($view);
356
357
            return $view;
358
        };
359
360
        return $this;
361
    }
362
363
    /**
364
     * Sets the instance of Misc class.
365
     *
366
     * @return self ( description_of_the_return_value )
367
     */
368
    private function setMisc()
369
    {
370
        $container = self::getContainerInstance();
371
        /**
372
         * @return \PHPPgAdmin\Misc
373
         */
374
        $container['misc'] = static function (\Slim\Container $c): \PHPPgAdmin\Misc {
375
            $misc = new \PHPPgAdmin\Misc($c);
376
377
            $conf = $c->get('conf');
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
378
379
            // 4. Check for theme by server/db/user
380
            $_server_info = $misc->getServerInfo();
381
382
            /* starting with PostgreSQL 9.0, we can set the application name */
383
            if (isset($_server_info['pgVersion']) && 9 <= $_server_info['pgVersion']) {
384
                \putenv('PGAPPNAME=' . $c->get('settings')['appName'] . '_' . $c->get('settings')['appVersion']);
385
            }
386
387
            return $misc;
388
        };
389
390
        return $this;
391
    }
392
393
    private function setExtra()
394
    {
395
        $container = self::getContainerInstance();
396
        $container['flash'] = static function (): \Slim\Flash\Messages {
397
            return new \Slim\Flash\Messages();
398
        };
399
400
        $container['lang'] = static function (\Slim\Container $c): array {
401
            $translations = new \PHPPgAdmin\Translations($c);
402
403
            return $translations->lang;
404
        };
405
406
        return $this;
407
    }
408
}
409