Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/HuasoFoundries/phpPgAdmin6.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/classes/ContainerUtils.php')
-rw-r--r--src/classes/ContainerUtils.php504
1 files changed, 185 insertions, 319 deletions
diff --git a/src/classes/ContainerUtils.php b/src/classes/ContainerUtils.php
index 36e4b2a6..dffc30e0 100644
--- a/src/classes/ContainerUtils.php
+++ b/src/classes/ContainerUtils.php
@@ -7,238 +7,143 @@
namespace PHPPgAdmin;
use Psr\Container\ContainerInterface;
-use Slim\App;
-
-\defined('BASE_PATH') || \define('BASE_PATH', \dirname(__DIR__, 2));
-\defined('THEME_PATH') || \define('THEME_PATH', BASE_PATH . '/assets/themes');
-
-\defined('DEBUGMODE') || \define('DEBUGMODE', false);
-\defined('IN_TEST') || \define('IN_TEST', false);
+use Slim\Collection;
+use Slim\DefaultServicesProvider;
/**
- * A class that adds convenience methods to the container.
+ * @property array $deploy_info
+ * @property \Slim\Flash\Messages $flash
+ * @property \GuzzleHttp\Client $fcIntranetClient
+ * @property \PHPPgAdmin\Misc $misc
+ * @property \PHPPgAdmin\ViewManager $view
+ * @property \Slim\Http\Request $request
+ * @property \Slim\Http\Response $response
+ * @property string $BASE_PATH
+ * @property string $THEME_PATH
+ * @property string $subFolder
+ * @property bool $DEBUGMODE
+ * @property bool $IN_TEST
+ * @property string $server
+ * @property string $database
+ * @property string $schema
+ * @property
*/
-class ContainerUtils
+class ContainerUtils extends \Slim\Container implements ContainerInterface
{
use \PHPPgAdmin\Traits\HelperTrait;
- /**
- * @var string
- */
- const BASE_PATH = BASE_PATH;
- /**
- * @var string
- */
- const SUBFOLDER = PHPPGA_SUBFOLDER;
- /**
- * @var string
- */
- const DEBUGMODE = DEBUGMODE;
-
- /**
- * @var string
- */
- const THEME_PATH = THEME_PATH;
/**
- * @var ContainerInterface
+ * @var null|self
*/
- protected $container;
+ private static $instance;
/**
- * @var App
+ * $appInstance.
+ *
+ * @var null|\Slim\App
*/
- protected $_app;
+ private static $appInstance;
/**
+ * Default settings.
+ *
* @var array
*/
- protected $conf;
+ private $defaultSettings = [
+ 'httpVersion' => '1.1',
+ 'responseChunkSize' => 4096,
+ 'outputBuffering' => 'append',
+ 'determineRouteBeforeAppMiddleware' => false,
+ 'displayErrorDetails' => false,
+ 'addContentLengthHeader' => true,
+ 'routerCacheFile' => false,
+ ];
/**
- * @var self
+ * Undocumented variable.
+ *
+ * @var array
*/
- protected static $_instance;
+ private static $envConfig = [
+ 'BASE_PATH' => '',
+ 'subFolder' => '',
+ 'DEBUGMODE' => false,
+ 'THEME_PATH' => '',
+ ];
/**
- * Constructor of the ContainerUtils class.
+ * @param array $values the parameters or objects
*/
- public function __construct()
+ final public function __construct(array $values = [])
{
- $composerinfo = \json_decode(\file_get_contents(BASE_PATH . '/composer.json'));
- $appVersion = $composerinfo->extra->version;
-
- $phpMinVer = (\str_replace(['<', '>', '='], '', $composerinfo->require->php));
- //$this->prtrace($appVersion);
- //$this->dump($composerinfo);
- $settings = [
- 'determineRouteBeforeAppMiddleware' => true,
- 'base_path' => self::BASE_PATH,
- 'subfolder' => self::SUBFOLDER,
- 'debug' => self::DEBUGMODE,
-
- // Configuration file version. If this is greater than that in config.inc.php, then
- // the app will refuse to run. This and $conf['version'] should be incremented whenever
- // backwards incompatible changes are made to config.inc.php-dist.
- 'base_version' => 61,
- // Application version
- 'appVersion' => 'v' . $appVersion,
- // Application name
- 'appName' => 'phpPgAdmin6',
-
- // PostgreSQL and PHP minimum version
- 'postgresqlMinVer' => '9.3',
- 'phpMinVer' => $phpMinVer,
- 'displayErrorDetails' => self::DEBUGMODE,
- 'addContentLengthHeader' => false,
- ];
-
- if (!self::DEBUGMODE && !IN_TEST) {
- $settings['routerCacheFile'] = self::BASE_PATH . '/temp/route.cache.php';
- }
- $config = [
- 'msg' => '',
- 'appThemes' => [
- 'default' => 'Default',
- 'cappuccino' => 'Cappuccino',
- 'gotar' => 'Blue/Green',
- 'bootstrap' => 'Bootstrap3',
- ],
- 'settings' => $settings,
- ];
-
- $this->_app = new App($config);
+ parent::__construct($values);
- // Fetch DI Container
- $container = $this->_app->getContainer();
- $container['utils'] = $this;
- $container['version'] = 'v' . $appVersion;
- $container['errors'] = [];
- $container['requestobj'] = $container['request'];
- $container['responseobj'] = $container['response'];
+ $userSettings = $values['settings'] ?? [];
+ $this->registerDefaultServices($userSettings);
- $this->container = $container;
+ self::$instance = $this;
}
/**
- * Gets the container instance.
+ * Gets the subfolder.
*
- * @throws \Exception (description)
+ * @param string $path The path
*
- * @return ContainerInterface the container instance
+ * @return string the subfolder
*/
- public static function getContainerInstance()
+ public function getSubfolder(string $path = ''): string
{
- $_instance = self::getInstance();
-
- if (!$container = $_instance->container) {
- throw new \Exception('Could not get a container');
- }
-
- return $container;
+ return \implode(\DIRECTORY_SEPARATOR, [$this->subFolder, $path]);
}
- /**
- * Gets the instance.
- *
- * @return self the instance
- */
- public static function getInstance()
+ public static function getAppInstance(array $config = []): \Slim\App
{
- if (!self::$_instance) {
- self::$_instance = new self();
- }
+ $config = \array_merge(self::getDefaultConfig($config['debugmode'] ?? false), $config);
- return self::$_instance;
- }
+ $container = self::getContainerInstance($config);
- /**
- * Creates a container.
- *
- * @param array $conf The conf
- *
- * @return [ContainerInterface,App] ( description_of_the_return_value )
- */
- public static function createContainer($conf)
- {
- $_instance = self::getInstance();
-
- $_instance
- ->setConf($conf)
- ->setExtra()
- ->setMisc()
- ->setViews();
+ if (!self::$appInstance) {
+ self::$appInstance = new \Slim\App($container);
+ }
- //ddd($container->subfolder);
- return [$_instance->container, self::$_instance->_app];
+ return self::$appInstance;
}
- public function maybeRenderIframes($response, $subject, $query_string)
+ public static function getContainerInstance(array $config = []): self
{
- $c = self::getContainerInstance();
-
- $in_test = $c->view->offsetGet('in_test');
-
- if ('1' === $in_test) {
- $className = '\PHPPgAdmin\Controller\\' . \ucfirst($subject) . 'Controller';
- $controller = new $className($c);
+ self::$envConfig = [
+ 'msg' => '',
+ 'appThemes' => [
+ 'default' => 'Default',
+ 'cappuccino' => 'Cappuccino',
+ 'gotar' => 'Blue/Green',
+ 'bootstrap' => 'Bootstrap3',
+ ],
+ 'BASE_PATH' => $config['BASE_PATH'] ?? \dirname(__DIR__, 2),
+ 'subFolder' => $config['subfolder'] ?? '',
+ 'debug' => $config['debugmode'] ?? false,
+ 'THEME_PATH' => $config['theme_path'] ?? \dirname(__DIR__, 2) . '/assets/themes',
+ 'IN_TEST' => $config['IN_TEST'] ?? false,
+ 'webdbLastTab' => [],
+ ];
- return $controller->render();
- }
+ self::$envConfig = \array_merge(self::$envConfig, $config);
- $viewVars = [
- 'url' => '/src/views/' . $subject . ($query_string ? '?' . $query_string : ''),
- 'headertemplate' => 'header.twig',
- ];
+ if (!self::$instance) {
+ self::$instance = new static(self::$envConfig);
- return $c->view->render($response, 'iframe_view.twig', $viewVars);
- }
+ self::$instance
+ ->withConf(self::$envConfig);
- /**
- * Gets the theme from
- * 1. The $_REQUEST global (when it's chosen from start screen)
- * 2. Server specific config theme 3.- $_SESSION global (subsequent requests after 1.) 4.- $_COOKIE global (mostly
- * fallback for $_SESSION after 1.- and 3.-) 5.- theme as set in config 6.- 'default' theme.
- *
- * @param array $conf The conf
- * @param null|mixed $_server_info
- *
- * @return string the theme
- */
- public function getTheme(array $conf, $_server_info = null)
- {
- $_theme = null;
- // List of themes
- $themefolders = $this->getThemeFolders();
- // Check if theme is in $_REQUEST, $_SESSION or $_COOKIE
- // 1.- First priority: $_REQUEST, this happens when you use the selector
- if (\array_key_exists('theme', $_REQUEST) &&
- \array_key_exists($_REQUEST['theme'], $themefolders)) {
- $_theme = $_REQUEST['theme'];
- } elseif ( // otherwise, see if there's a theme associated with this particular server
- null !== $_server_info &&
- \array_key_exists('theme', $_server_info) &&
- \is_string($_server_info['theme']) &&
- \array_key_exists($_COOKIE['ppaTheme'], $themefolders)) {
- $_theme = $_server_info['theme'];
- } elseif (\array_key_exists('ppaTheme', $_SESSION) &&
- \array_key_exists($_SESSION['ppaTheme'], $themefolders)) {
- // otherwise check $_SESSION
- $_theme = $_SESSION['ppaTheme'];
- } elseif (\array_key_exists('ppaTheme', $_SESSION) &&
- \array_key_exists($_COOKIE['ppaTheme'], $themefolders)) {
- // oterwise check $_COOKIE
- $_theme = $_COOKIE['ppaTheme'];
- } elseif ( // see if there's a valid theme set in config file
- \array_key_exists('theme', $conf) &&
- \is_string($conf['theme']) &&
- \array_key_exists($conf['theme'], $themefolders)) {
- $_theme = $conf['theme'];
- } else {
- // okay then, use default theme
- $_theme = 'default';
+ $handlers = new ContainerHandlers(self::$instance);
+ $handlers->setExtra()
+ ->setMisc()
+ ->setViews()
+ ->storeMainRequestParams()
+ ->setHaltHandler();
}
-
- return $_theme;
+ //ddd($container->subfolder);
+ return self::$instance;
}
/**
@@ -248,14 +153,15 @@ class ContainerUtils
*/
public function getRedirectUrl()
{
- $query_string = $this->container->requestobj->getUri()->getQuery();
+ $container = self::getContainerInstance();
+ $query_string = $container->request->getUri()->getQuery();
// if server_id isn't set, then you will be redirected to intro
- if (null === $this->container->requestobj->getQueryParam('server')) {
- $destinationurl = self::SUBFOLDER . '/src/views/intro';
+ if (null === $container->request->getQueryParam('server')) {
+ $destinationurl = self::$envConfig['subFolder'] . '/src/views/intro';
} else {
// otherwise, you'll be redirected to the login page for that server;
- $destinationurl = self::SUBFOLDER . '/src/views/login' . ($query_string ? '?' . $query_string : '');
+ $destinationurl = self::$envConfig['subFolder'] . '/src/views/login' . ($query_string ? '?' . $query_string : '');
}
return $destinationurl;
@@ -273,9 +179,10 @@ class ContainerUtils
if ('' === $key) {
$key = self::getBackTrace();
}
+ $container = self::getContainerInstance();
// $this->dump(__METHOD__ . ': addMessage ' . $key . ' ' . json_encode($content));
- if ($this->container->flash) {
- $this->container->flash->addMessage($key, $content);
+ if ($container->flash) {
+ $container->flash->addMessage($key, $content);
}
}
@@ -289,33 +196,37 @@ class ContainerUtils
*/
public function getDestinationWithLastTab($subject)
{
- $_server_info = $this->container->misc->getServerInfo();
+ $container = self::getContainerInstance();
+ $_server_info = $container->misc->getServerInfo();
$this->addFlash($subject, 'getDestinationWithLastTab');
//$this->prtrace('$_server_info', $_server_info);
// If username isn't set in server_info, you should login
+ $url = $container->misc->getLastTabURL($subject) ?? ['url' => 'alldb', 'urlvars' => ['subject' => 'server']];
+ $destinationurl = $this->getRedirectUrl();
+
if (!isset($_server_info['username'])) {
- $destinationurl = $this->getRedirectUrl();
- } else {
- $url = $this->container->misc->getLastTabURL($subject);
- $this->addFlash($url, 'getLastTabURL for ' . $subject);
- // Load query vars into superglobal arrays
- if (isset($url['urlvars'])) {
- $urlvars = [];
-
- foreach ($url['urlvars'] as $key => $urlvar) {
- //$this->prtrace($key, $urlvar);
- $urlvars[$key] = \PHPPgAdmin\Decorators\Decorator::get_sanitized_value($urlvar, $_REQUEST);
- }
- $_REQUEST = \array_merge($_REQUEST, $urlvars);
- $_GET = \array_merge($_GET, $urlvars);
- }
+ return $destinationurl;
+ }
- $actionurl = \PHPPgAdmin\Decorators\Decorator::actionurl($url['url'], $_GET);
- $destinationurl = $actionurl->value($_GET);
+ if (!\is_array($url)) {
+ return $this->getRedirectUrl($subject);
}
- $destinationurl = \str_replace('views/?', "views/{$subject}?", $destinationurl);
- // $this->prtrace('destinationurl for ' . $subject, $destinationurl);
- return $destinationurl;
+ $this->addFlash($url, 'getLastTabURL for ' . $subject);
+ // Load query vars into superglobal arrays
+ if (isset($url['urlvars'])) {
+ $urlvars = [];
+
+ foreach ($url['urlvars'] as $key => $urlvar) {
+ //$this->prtrace($key, $urlvar);
+ $urlvars[$key] = \PHPPgAdmin\Decorators\Decorator::get_sanitized_value($urlvar, $_REQUEST);
+ }
+ $_REQUEST = \array_merge($_REQUEST, $urlvars);
+ $_GET = \array_merge($_GET, $urlvars);
+ }
+ $actionurl = \PHPPgAdmin\Decorators\Decorator::actionurl($url['url'], $_GET);
+ $destinationurl = $actionurl->value($_GET);
+
+ return \str_replace('views/?', "views/{$subject}?", $destinationurl);
}
/**
@@ -323,24 +234,60 @@ class ContainerUtils
*
* @param string $errormsg The error msg
*
- * @return ContainerInterface The app container
+ * @return\Slim\Container The app container
*/
- public function addError(string $errormsg): ContainerInterface
+ public function addError(string $errormsg): \Slim\Container
{
- //dump($errormsg);
- $errors = $this->container->get('errors');
+ $container = self::getContainerInstance();
+ $errors = $container->get('errors');
$errors[] = $errormsg;
- $this->container->offsetSet('errors', $errors);
+ $container->offsetSet('errors', $errors);
+
+ return $container;
+ }
- return $this->container;
+ /**
+ * Returns a string with html <br> variant replaced with a new line.
+ *
+ * @param string $msg message to parse (<br> separated)
+ *
+ * @return string parsed message (linebreak separated)
+ */
+ public static function br2ln($msg)
+ {
+ return \str_replace(['<br>', '<br/>', '<br />'], \PHP_EOL, $msg);
}
- private function setConf($conf)
+ public static function getDefaultConfig(bool $debug = false): array
+ {
+ return [
+ 'settings' => [
+ 'displayErrorDetails' => $debug,
+ 'determineRouteBeforeAppMiddleware' => true,
+ 'base_path' => \dirname(__DIR__, 2),
+ 'debug' => $debug,
+ 'phpMinVer' => '7.2', // PHP minimum version
+ 'addContentLengthHeader' => false,
+ 'appName' => 'PHPPgAdmin6',
+ ],
+ ];
+ }
+
+ /**
+ * @param array $conf
+ */
+ private function withConf($conf): self
{
$container = self::getContainerInstance();
$conf['plugins'] = [];
- $container['conf'] = static function ($c) use ($conf) {
+ $container->BASE_PATH = $conf['BASE_PATH'];
+ $container->subFolder = $conf['subfolder'];
+ $container->debug = $conf['debugmode'];
+ $container->THEME_PATH = $conf['theme_path'];
+ $container->IN_TEST = $conf['IN_TEST'];
+ $container['errors'] = [];
+ $container['conf'] = static function (\Slim\Container $c) use ($conf): array {
$display_sizes = $conf['display_sizes'];
if (\is_array($display_sizes)) {
@@ -371,115 +318,34 @@ class ContainerUtils
return $conf;
};
- $container->subfolder = self::SUBFOLDER;
+
+ $container->subFolder = $conf['subfolder'];
return $this;
}
/**
- * Sets the views.
+ * This function registers the default services that Slim needs to work.
*
- * @return self ( description_of_the_return_value )
+ * All services are shared, they are registered such that the
+ * same instance is returned on subsequent calls.
+ *
+ * @param array $userSettings Associative array of application settings
*/
- private function setViews()
+ private function registerDefaultServices($userSettings): void
{
- $container = self::getContainerInstance();
+ $defaultSettings = $this->defaultSettings;
/**
- * return ViewManager.
+ * This service MUST return an array or an instance of ArrayAccess.
+ *
+ * @return array|ArrayAccess
*/
- $container['view'] = static function ($c) {
- $misc = $c->misc;
- $view = new ViewManager(BASE_PATH . '/assets/templates', [
- 'cache' => BASE_PATH . '/temp/twigcache',
- 'auto_reload' => $c->get('settings')['debug'],
- 'debug' => $c->get('settings')['debug'],
- ], $c);
-
- $misc->setView($view);
-
- return $view;
- };
-
- return $this;
- }
-
- /**
- * Sets the instance of Misc class.
- *
- * @return self ( description_of_the_return_value )
- */
- private function setMisc()
- {
- $container = self::getContainerInstance();
- $container['misc'] = static function ($c) {
- $misc = new \PHPPgAdmin\Misc($c);
-
- $conf = $c->get('conf');
-
- // 4. Check for theme by server/db/user
- $_server_info = $misc->getServerInfo();
-
- /* starting with PostgreSQL 9.0, we can set the application name */
- if (isset($_server_info['pgVersion']) && 9 <= $_server_info['pgVersion']) {
- \putenv('PGAPPNAME=' . $c->get('settings')['appName'] . '_' . $c->get('settings')['appVersion']);
- }
-
- return $misc;
+ $this['settings'] = static function () use ($userSettings, $defaultSettings): \Slim\Collection {
+ return new Collection(\array_merge($defaultSettings, $userSettings));
};
- return $this;
- }
-
- private function setExtra()
- {
- $container = self::getContainerInstance();
- $container['flash'] = static function () {
- return new \Slim\Flash\Messages();
- };
-
- $container['lang'] = static function ($c) {
- $translations = new \PHPPgAdmin\Translations($c);
-
- return $translations->lang;
- };
-
- return $this;
- }
-
- /**
- * Traverse THEME_PATH, consider as theme folders those which
- * contain a `global.css` stylesheet.
- *
- * @return array the theme folders
- */
- private function getThemeFolders()
- {
- // no THEME_PATH (how?) then return empty array
- if (!$gestor = \opendir(self::THEME_PATH)) {
- \closedir($gestor);
-
- return [];
- }
- $themefolders = [];
-
- /* This is the right way to iterate on a folder */
- while (false !== ($foldername = \readdir($gestor))) {
- if ('.' === $foldername || '..' === $foldername) {
- continue;
- }
-
- $folderpath = \sprintf('%s%s%s', self::THEME_PATH, \DIRECTORY_SEPARATOR, $foldername);
- $stylesheet = \sprintf('%s%s%s', $folderpath, \DIRECTORY_SEPARATOR, 'global.css');
- // if $folderpath if indeed a folder and contains a global.css file, then it's a theme
- if (\is_dir($folderpath) &&
- \is_file($stylesheet)) {
- $themefolders[$foldername] = $folderpath;
- }
- }
-
- \closedir($gestor);
-
- return $themefolders;
+ $defaultProvider = new DefaultServicesProvider();
+ $defaultProvider->register($this);
}
}