1 | <?php |
||||
2 | |||||
3 | /** |
||||
4 | * PHPPgAdmin 6.1.3 |
||||
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['debugmode'] ?? false), $config); |
||||
102 | |||||
103 | $container = self::getContainerInstance($config); |
||||
104 | |||||
105 | if (!self::$appInstance) { |
||||
106 | self::$appInstance = new \Slim\App($container); |
||||
107 | } |
||||
108 | |||||
109 | return self::$appInstance; |
||||
110 | } |
||||
111 | |||||
112 | public static function getContainerInstance(array $config = []): self |
||||
113 | { |
||||
114 | self::$envConfig = [ |
||||
115 | 'msg' => '', |
||||
116 | 'appThemes' => [ |
||||
117 | 'default' => 'Default', |
||||
118 | 'cappuccino' => 'Cappuccino', |
||||
119 | 'gotar' => 'Blue/Green', |
||||
120 | 'bootstrap' => 'Bootstrap3', |
||||
121 | ], |
||||
122 | 'BASE_PATH' => $config['BASE_PATH'] ?? \dirname(__DIR__, 2), |
||||
123 | 'subFolder' => $config['subfolder'] ?? '', |
||||
124 | 'debug' => $config['debugmode'] ?? false, |
||||
125 | 'THEME_PATH' => $config['theme_path'] ?? \dirname(__DIR__, 2) . '/assets/themes', |
||||
126 | 'IN_TEST' => $config['IN_TEST'] ?? false, |
||||
127 | 'webdbLastTab' => [], |
||||
128 | ]; |
||||
129 | |||||
130 | self::$envConfig = \array_merge(self::$envConfig, $config); |
||||
131 | |||||
132 | if (!self::$instance) { |
||||
133 | self::$instance = new static(self::$envConfig); |
||||
134 | |||||
135 | self::$instance |
||||
136 | ->withConf(self::$envConfig); |
||||
137 | |||||
138 | $handlers = new ContainerHandlers(self::$instance); |
||||
139 | $handlers->setExtra() |
||||
140 | ->setMisc() |
||||
141 | ->setViews() |
||||
142 | ->storeMainRequestParams() |
||||
143 | ->setHaltHandler(); |
||||
144 | } |
||||
145 | //ddd($container->subfolder); |
||||
146 | return self::$instance; |
||||
147 | } |
||||
148 | |||||
149 | /** |
||||
150 | * Determines the redirection url according to query string. |
||||
151 | * |
||||
152 | * @return string the redirect url |
||||
153 | */ |
||||
154 | public function getRedirectUrl() |
||||
155 | { |
||||
156 | $container = self::getContainerInstance(); |
||||
157 | $query_string = $container->request->getUri()->getQuery(); |
||||
158 | |||||
159 | // if server_id isn't set, then you will be redirected to intro |
||||
160 | if (null === $container->request->getQueryParam('server')) { |
||||
161 | $destinationurl = self::$envConfig['subFolder'] . '/src/views/intro'; |
||||
162 | } else { |
||||
163 | // otherwise, you'll be redirected to the login page for that server; |
||||
164 | $destinationurl = self::$envConfig['subFolder'] . '/src/views/login' . ($query_string ? '?' . $query_string : ''); |
||||
165 | } |
||||
166 | |||||
167 | return $destinationurl; |
||||
168 | } |
||||
169 | |||||
170 | /** |
||||
171 | * Adds a flash message to the session that will be displayed on the next request. |
||||
172 | * |
||||
173 | * @param mixed $content msg content (can be object, array, etc) |
||||
174 | * @param string $key The key to associate with the message. Defaults to the stack |
||||
175 | * trace of the closure or method that called addFlassh |
||||
176 | */ |
||||
177 | public function addFlash($content, $key = ''): void |
||||
178 | { |
||||
179 | if ('' === $key) { |
||||
180 | $key = self::getBackTrace(); |
||||
181 | } |
||||
182 | $container = self::getContainerInstance(); |
||||
183 | // $this->dump(__METHOD__ . ': addMessage ' . $key . ' ' . json_encode($content)); |
||||
184 | if ($container->flash) { |
||||
185 | $container->flash->addMessage($key, $content); |
||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
186 | } |
||||
187 | } |
||||
188 | |||||
189 | /** |
||||
190 | * Gets the destination with the last active tab selected for that controller |
||||
191 | * Usually used after going through a redirect route. |
||||
192 | * |
||||
193 | * @param string $subject The subject, usually a view name like 'server' or 'table' |
||||
194 | * |
||||
195 | * @return string The destination url with last tab set in the query string |
||||
196 | */ |
||||
197 | public function getDestinationWithLastTab($subject) |
||||
198 | { |
||||
199 | $container = self::getContainerInstance(); |
||||
200 | $_server_info = $container->misc->getServerInfo(); |
||||
201 | $this->addFlash($subject, 'getDestinationWithLastTab'); |
||||
202 | //$this->prtrace('$_server_info', $_server_info); |
||||
203 | // If username isn't set in server_info, you should login |
||||
204 | $url = $container->misc->getLastTabURL($subject) ?? ['url' => 'alldb', 'urlvars' => ['subject' => 'server']]; |
||||
205 | $destinationurl = $this->getRedirectUrl(); |
||||
206 | |||||
207 | if (!isset($_server_info['username'])) { |
||||
208 | return $destinationurl; |
||||
209 | } |
||||
210 | |||||
211 | if (!\is_array($url)) { |
||||
212 | return $this->getRedirectUrl($subject); |
||||
0 ignored issues
–
show
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
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. ![]() |
|||||
213 | } |
||||
214 | $this->addFlash($url, 'getLastTabURL for ' . $subject); |
||||
215 | // Load query vars into superglobal arrays |
||||
216 | if (isset($url['urlvars'])) { |
||||
217 | $urlvars = []; |
||||
218 | |||||
219 | foreach ($url['urlvars'] as $key => $urlvar) { |
||||
220 | //$this->prtrace($key, $urlvar); |
||||
221 | $urlvars[$key] = \PHPPgAdmin\Decorators\Decorator::get_sanitized_value($urlvar, $_REQUEST); |
||||
222 | } |
||||
223 | $_REQUEST = \array_merge($_REQUEST, $urlvars); |
||||
224 | $_GET = \array_merge($_GET, $urlvars); |
||||
225 | } |
||||
226 | $actionurl = \PHPPgAdmin\Decorators\Decorator::actionurl($url['url'], $_GET); |
||||
227 | $destinationurl = $actionurl->value($_GET); |
||||
228 | |||||
229 | return \str_replace('views/?', "views/{$subject}?", $destinationurl); |
||||
230 | } |
||||
231 | |||||
232 | /** |
||||
233 | * Adds an error to the errors array property of the container. |
||||
234 | * |
||||
235 | * @param string $errormsg The error msg |
||||
236 | * |
||||
237 | * @return\Slim\Container The app container |
||||
238 | */ |
||||
239 | public function addError(string $errormsg): \Slim\Container |
||||
240 | { |
||||
241 | $container = self::getContainerInstance(); |
||||
242 | $errors = $container->get('errors'); |
||||
243 | $errors[] = $errormsg; |
||||
244 | $container->offsetSet('errors', $errors); |
||||
245 | |||||
246 | return $container; |
||||
247 | } |
||||
248 | |||||
249 | /** |
||||
250 | * Returns a string with html <br> variant replaced with a new line. |
||||
251 | * |
||||
252 | * @param string $msg message to parse (<br> separated) |
||||
253 | * |
||||
254 | * @return string parsed message (linebreak separated) |
||||
255 | */ |
||||
256 | public static function br2ln($msg) |
||||
257 | { |
||||
258 | return \str_replace(['<br>', '<br/>', '<br />'], \PHP_EOL, $msg); |
||||
259 | } |
||||
260 | |||||
261 | public static function getDefaultConfig(bool $debug = false): array |
||||
262 | { |
||||
263 | return [ |
||||
264 | 'settings' => [ |
||||
265 | 'displayErrorDetails' => $debug, |
||||
266 | 'determineRouteBeforeAppMiddleware' => true, |
||||
267 | 'base_path' => \dirname(__DIR__, 2), |
||||
268 | 'debug' => $debug, |
||||
269 | 'phpMinVer' => '7.2', // PHP minimum version |
||||
270 | 'addContentLengthHeader' => false, |
||||
271 | 'appName' => 'PHPPgAdmin6', |
||||
272 | ], |
||||
273 | ]; |
||||
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']; |
||||
285 | $container->subFolder = $conf['subfolder']; |
||||
286 | $container->debug = $conf['debugmode']; |
||||
287 | $container->THEME_PATH = $conf['theme_path']; |
||||
288 | $container->IN_TEST = $conf['IN_TEST']; |
||||
289 | $container['errors'] = []; |
||||
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 | |||||
319 | return $conf; |
||||
320 | }; |
||||
321 | |||||
322 | $container->subFolder = $conf['subfolder']; |
||||
323 | |||||
324 | return $this; |
||||
325 | } |
||||
326 | |||||
327 | /** |
||||
328 | * This function registers the default services that Slim needs to work. |
||||
329 | * |
||||
330 | * All services are shared, they are registered such that the |
||||
331 | * same instance is returned on subsequent calls. |
||||
332 | * |
||||
333 | * @param array $userSettings Associative array of application settings |
||||
334 | */ |
||||
335 | private function registerDefaultServices($userSettings): void |
||||
336 | { |
||||
337 | $defaultSettings = $this->defaultSettings; |
||||
338 | |||||
339 | /** |
||||
340 | * This service MUST return an array or an instance of ArrayAccess. |
||||
341 | * |
||||
342 | * @return array|ArrayAccess |
||||
343 | */ |
||||
344 | $this['settings'] = static function () use ($userSettings, $defaultSettings): \Slim\Collection { |
||||
345 | return new Collection(\array_merge($defaultSettings, $userSettings)); |
||||
346 | }; |
||||
347 | |||||
348 | $defaultProvider = new DefaultServicesProvider(); |
||||
349 | $defaultProvider->register($this); |
||||
350 | } |
||||
351 | } |
||||
352 |