Passed
Push — develop ( 1026fb...945d40 )
by Felipe
04:55
created

ContainerUtils::createContainer()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 7
rs 10
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-RC1
5
 */
6
7
namespace PHPPgAdmin;
8
9
/**
10
 * @file
11
 * A class that adds convenience methods to the container
12
 */
13
14
/**
15
 * A class that adds convenience methods to the container.
16
 *
17
 * @package PHPPgAdmin
18
 */
19
class ContainerUtils
20
{
21
    use \PHPPgAdmin\Traits\HelperTrait;
22
23
    protected $container;
24
    /** @var Connector */
0 ignored issues
show
Bug introduced by
The type PHPPgAdmin\Connector was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
25
    protected static $instance;
26
27
    /**
28
     * Constructor of the ContainerUtils class.
29
     *
30
     * @param \Slim\Container $container The app container
31
     */
32
    public function __construct()
33
    {
34
        $composerinfo = json_decode(file_get_contents(BASE_PATH.'/composer.json'));
35
        $appVersion   = $composerinfo->version;
36
37
        $phpMinVer = (str_replace(['<', '>', '='], '', $composerinfo->require->php));
38
        $config    = [
39
            'msg'       => '',
40
            'appThemes' => [
41
                'default'    => 'Default',
42
                'cappuccino' => 'Cappuccino',
43
                'gotar'      => 'Blue/Green',
44
                'bootstrap'  => 'Bootstrap3',
45
            ],
46
            'settings'  => [
47
                'displayErrorDetails'               => DEBUGMODE,
48
                'determineRouteBeforeAppMiddleware' => true,
49
                'base_path'                         => BASE_PATH,
50
                'debug'                             => DEBUGMODE,
51
52
                'routerCacheFile'                   => BASE_PATH.'/temp/route.cache.php',
53
54
                // Configuration file version.  If this is greater than that in config.inc.php, then
55
                // the app will refuse to run.  This and $conf['version'] should be incremented whenever
56
                // backwards incompatible changes are made to config.inc.php-dist.
57
                'base_version'                      => 60,
58
                // Application version
59
                'appVersion'                        => 'v'.$appVersion,
60
                // Application name
61
                'appName'                           => 'phpPgAdmin6',
62
63
                // PostgreSQL and PHP minimum version
64
                'postgresqlMinVer'                  => '9.3',
65
                'phpMinVer'                         => $phpMinVer,
66
                'displayErrorDetails'               => DEBUGMODE,
67
                'addContentLengthHeader'            => false,
68
            ],
69
        ];
70
71
        $this->app = new \Slim\App($config);
72
73
        // Fetch DI Container
74
        $container            = $this->app->getContainer();
75
        $container['utils']   = $this;
76
        $container['version'] = 'v'.$appVersion;
77
        $container['errors']  = [];
78
79
        $this->container = $container;
80
    }
81
82
    public static function createContainer()
83
    {
84
        if (!self::$instance) {
85
            self::$instance = new self();
0 ignored issues
show
Documentation Bug introduced by
It seems like new self() of type PHPPgAdmin\ContainerUtils is incompatible with the declared type PHPPgAdmin\Connector of property $instance.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
86
        }
87
88
        return [self::$instance->container, self::$instance->app];
89
    }
90
91
    public function maybeRenderIframes($response, $subject, $query_string)
92
    {
93
        $c       = $this->container;
94
        $in_test = $c->view->offsetGet('in_test');
0 ignored issues
show
Bug introduced by
Accessing view on the interface Psr\Container\ContainerInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
95
96
        if ($in_test === '1') {
97
            $className  = '\PHPPgAdmin\Controller\\'.ucfirst($subject).'Controller';
98
            $controller = new $className($c);
99
100
            return $controller->render();
101
        }
102
103
        $viewVars = [
104
            'url'            => '/src/views/'.$subject.($query_string ? '?'.$query_string : ''),
105
            'headertemplate' => 'header.twig',
106
        ];
107
108
        return $c->view->render($response, 'iframe_view.twig', $viewVars);
109
    }
110
111
    /**
112
     * Gets the theme from
113
     * 1. The $_REQUEST global (when it's chosen from start screen)
114
     * 2. Server specific config theme
115
     * 3.- $_SESSION global (subsequent requests after 1.)
116
     * 4.- $_COOKIE global (mostly fallback for $_SESSION after 1.- and 3.-)
117
     * 5.- theme as set in config
118
     * 6.- 'default' theme.
119
     *
120
     * @param <type>     $conf         The conf
0 ignored issues
show
Documentation Bug introduced by
The doc comment <type> at position 0 could not be parsed: Unknown type name '<' at position 0 in <type>.
Loading history...
121
     * @param null|mixed $_server_info
122
     *
123
     * @return string the theme
124
     */
125
    public function getTheme(array $conf, $_server_info = null)
126
    {
127
        $_theme = null;
128
        // List of themes
129
        $themefolders = $this->getThemeFolders();
130
        // Check if theme is in $_REQUEST, $_SESSION or $_COOKIE
131
        // 1.- First priority: $_REQUEST, this happens when you use the selector
132
        if (array_key_exists('theme', $_REQUEST) &&
133
            array_key_exists($_REQUEST['theme'], $themefolders)) {
134
            $_theme = $_REQUEST['theme'];
135
        } elseif ( // otherwise, see if there's a theme associated with this particular server
0 ignored issues
show
Coding Style introduced by
First condition of a multi-line IF statement must directly follow the opening parenthesis
Loading history...
136
            !is_null($_server_info) &&
137
            array_key_exists('theme', $_server_info) &&
138
            is_string($_server_info['theme']) &&
139
            array_key_exists($_COOKIE['ppaTheme'], $themefolders)) {
140
            $_theme = $_server_info['theme'];
141
        } elseif (array_key_exists('ppaTheme', $_SESSION) &&
142
            array_key_exists($_SESSION['ppaTheme'], $themefolders)) {
143
            // otherwise check $_SESSION
144
            $_theme = $_SESSION['ppaTheme'];
145
        } elseif (array_key_exists('ppaTheme', $_SESSION) &&
146
            array_key_exists($_COOKIE['ppaTheme'], $themefolders)) {
147
            // oterwise check $_COOKIE
148
            $_theme = $_COOKIE['ppaTheme'];
149
        } elseif ( // see if there's a valid theme set in config file
0 ignored issues
show
Coding Style introduced by
First condition of a multi-line IF statement must directly follow the opening parenthesis
Loading history...
150
            array_key_exists('theme', $conf) &&
151
            is_string($conf['theme']) &&
152
            array_key_exists($conf['theme'], $themefolders)) {
153
            $_theme = $conf['theme'];
154
        } else {
155
            // okay then, use default theme
156
            $_theme = 'default';
157
        }
158
159
        return $_theme;
160
    }
161
162
    /**
163
     * Traverse THEME_PATH, consider as theme folders those which
164
     * contain a `global.css` stylesheet.
165
     *
166
     * @return array the theme folders
167
     */
168
    private function getThemeFolders()
169
    {
170
        // no THEME_PATH (how?) then return empty array
171
        if (!$gestor = opendir(THEME_PATH)) {
172
            closedir($gestor);
0 ignored issues
show
Bug introduced by
It seems like $gestor can also be of type false; however, parameter $dir_handle of closedir() does only seem to accept resource, 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

172
            closedir(/** @scrutinizer ignore-type */ $gestor);
Loading history...
173
174
            return [];
175
        }
176
        $themefolders = [];
177
178
        /* This is the right way to iterate on a folder */
179
        while (false !== ($foldername = readdir($gestor))) {
180
            if ($foldername == '.' || $foldername == '..') {
181
                continue;
182
            }
183
184
            $folderpath = sprintf('%s%s%s', THEME_PATH, DIRECTORY_SEPARATOR, $foldername);
185
            $stylesheet = sprintf('%s%s%s', $folderpath, DIRECTORY_SEPARATOR, 'global.css');
186
            // if $folderpath if indeed a folder and contains a global.css file, then it's a theme
187
            if (is_dir($folderpath) &&
188
                is_file($stylesheet)) {
189
                $themefolders[$foldername] = $folderpath;
190
            }
191
        }
192
193
        closedir($gestor);
194
195
        return $themefolders;
196
    }
197
198
    /**
199
     * Determines the redirection url according to query string.
200
     *
201
     * @return string the redirect url
202
     */
203
    public function getRedirectUrl()
204
    {
205
        $query_string = $this->container->requestobj->getUri()->getQuery();
0 ignored issues
show
Bug introduced by
Accessing requestobj on the interface Psr\Container\ContainerInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
206
207
        // if server_id isn't set, then you will be redirected to intro
208
        if ($this->container->requestobj->getQueryParam('server') === null) {
209
            $destinationurl = \SUBFOLDER.'/src/views/intro';
210
        } else {
211
            // otherwise, you'll be redirected to the login page for that server;
212
            $destinationurl = \SUBFOLDER.'/src/views/login'.($query_string ? '?'.$query_string : '');
213
        }
214
215
        return $destinationurl;
216
    }
217
218
    /**
219
     * Gets the destination with the last active tab selected for that controller
220
     * Usually used after going through a redirect route.
221
     *
222
     * @param string $subject The subject, usually a view name like 'server' or 'table'
223
     *
224
     * @return string The destination url with last tab set in the query string
225
     */
226
    public function getDestinationWithLastTab($subject)
227
    {
228
        $_server_info = $this->container->misc->getServerInfo();
0 ignored issues
show
Bug introduced by
Accessing misc on the interface Psr\Container\ContainerInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
229
        $this->addFlash($subject, 'getDestinationWithLastTab');
230
        //$this->prtrace('$_server_info', $_server_info);
231
        // If username isn't set in server_info, you should login
232
        if (!isset($_server_info['username'])) {
233
            $destinationurl = $this->getRedirectUrl();
234
        } else {
235
            $url = $this->container->misc->getLastTabURL($subject);
236
            $this->addFlash($url, 'getLastTabURL for '.$subject);
237
            // Load query vars into superglobal arrays
238
            if (isset($url['urlvars'])) {
239
                $urlvars = [];
240
                foreach ($url['urlvars'] as $key => $urlvar) {
241
                    //$this->prtrace($key, $urlvar);
242
                    $urlvars[$key] = \PHPPgAdmin\Decorators\Decorator::get_sanitized_value($urlvar, $_REQUEST);
243
                }
244
                $_REQUEST = array_merge($_REQUEST, $urlvars);
245
                $_GET     = array_merge($_GET, $urlvars);
246
            }
247
248
            $actionurl      = \PHPPgAdmin\Decorators\Decorator::actionurl($url['url'], $_GET);
249
            $destinationurl = $actionurl->value($_GET);
250
        }
251
        $destinationurl = str_replace('views/?', "views/{$subject}?", $destinationurl);
252
        //$this->prtrace('destinationurl for ' . $subject, $destinationurl);
253
        return $destinationurl;
254
    }
255
256
    /**
257
     * Adds an error to the errors array property of the container.
258
     *
259
     * @param string $errormsg The error msg
260
     *
261
     * @return \Slim\Container The app container
262
     */
263
    public function addError($errormsg)
264
    {
265
        $errors   = $this->container->get('errors');
266
        $errors[] = $errormsg;
267
        $this->container->offsetSet('errors', $errors);
268
269
        return $this->container;
270
    }
271
}
272