diff --git a/application/Espo/Binding.php b/application/Espo/Binding.php index 03662b47be..7f68110e61 100644 --- a/application/Espo/Binding.php +++ b/application/Espo/Binding.php @@ -240,6 +240,11 @@ class Binding implements BindingProcessor 'Espo\\ORM\\PDO\\PDOProvider', 'Espo\\ORM\\PDO\\DefaultPDOProvider' ); + + $binder->bindImplementation( + 'Espo\\Core\\Utils\\Database\\ConfigDataProvider', + 'Espo\\Core\\Utils\\Database\\DefaultConfigDataProvider' + ); } private function bindMisc(Binder $binder): void diff --git a/application/Espo/Core/Utils/Database/ConfigDataProvider.php b/application/Espo/Core/Utils/Database/ConfigDataProvider.php index afe413b947..fcc9522a60 100644 --- a/application/Espo/Core/Utils/Database/ConfigDataProvider.php +++ b/application/Espo/Core/Utils/Database/ConfigDataProvider.php @@ -29,16 +29,7 @@ namespace Espo\Core\Utils\Database; -use Espo\Core\Utils\Config; - -class ConfigDataProvider +interface ConfigDataProvider { - private const DEFAULT_PLATFORM = 'Mysql'; - - public function __construct(private Config $config) {} - - public function getPlatform(): string - { - return $this->config->get('database.platform') ?? self::DEFAULT_PLATFORM; - } + public function getPlatform(): string; } diff --git a/application/Espo/Core/Utils/Database/DefaultConfigDataProvider.php b/application/Espo/Core/Utils/Database/DefaultConfigDataProvider.php new file mode 100644 index 0000000000..8144de363a --- /dev/null +++ b/application/Espo/Core/Utils/Database/DefaultConfigDataProvider.php @@ -0,0 +1,44 @@ +config->get('database.platform') ?? self::DEFAULT_PLATFORM; + } +} diff --git a/application/Espo/Resources/defaults/systemConfig.php b/application/Espo/Resources/defaults/systemConfig.php index aa05af152c..6ff9a6f398 100644 --- a/application/Espo/Resources/defaults/systemConfig.php +++ b/application/Espo/Resources/defaults/systemConfig.php @@ -75,6 +75,7 @@ return [ 'internalOutboundEmailFromAddress', 'requiredPhpVersion', 'requiredMysqlVersion', + 'requiredPostgresqlVersion', 'recommendedMysqlParams', 'requiredPhpLibs', 'recommendedPhpLibs', @@ -270,6 +271,7 @@ return [ 'requiredMysqlVersion' => '5.7.0', 'recommendedMysqlParams' => [], 'requiredMariadbVersion' => '10.2.2', + 'requiredPostgresqlVersion' => '15.0', 'recommendedMariadbParams' => [], /** Max execution time (in seconds) allocated for a single job. If exceeded then set to Failed.*/ 'jobPeriod' => 7800, diff --git a/application/Espo/Tools/Installer/DatabaseConfigDataProvider.php b/application/Espo/Tools/Installer/DatabaseConfigDataProvider.php new file mode 100644 index 0000000000..366c2ac9d2 --- /dev/null +++ b/application/Espo/Tools/Installer/DatabaseConfigDataProvider.php @@ -0,0 +1,44 @@ +platform; + } +} diff --git a/install/core/Installer.php b/install/core/Installer.php index b1b31941e4..ef6279456a 100644 --- a/install/core/Installer.php +++ b/install/core/Installer.php @@ -32,6 +32,7 @@ use Espo\Core\Container; use Espo\Core\DataManager; use Espo\Core\InjectableFactory; use Espo\Core\ORM\DatabaseParamsFactory; +use Espo\Core\Utils\Database\ConfigDataProvider; use Espo\Core\Utils\Database\Dbal\ConnectionFactoryFactory; use Espo\Core\Utils\Id\RecordIdGenerator; use Espo\Core\Utils\ScheduledJob as ScheduledJobUtil; @@ -52,6 +53,7 @@ use Espo\Entities\Job; use Espo\Entities\ScheduledJob; use Espo\Entities\User; use Espo\ORM\Query\SelectBuilder; +use Espo\Tools\Installer\DatabaseConfigDataProvider; class Installer { @@ -299,13 +301,22 @@ class Installer public function getSystemRequirementList($type, $requiredOnly = false, array $additionalData = null) { + $platform = $additionalData['databaseParams']['platform'] ?? 'Mysql'; + + $dbConfigDataProvider = new DatabaseConfigDataProvider($platform); + /** @var SystemRequirements $systemRequirementManager */ - $systemRequirementManager = $this->app + $systemRequirementManager = $this->app ->getContainer() ->getByClass(InjectableFactory::class) - ->create(SystemRequirements::class); + ->createWithBinding( + SystemRequirements::class, + BindingContainerBuilder::create() + ->bindInstance(ConfigDataProvider::class, $dbConfigDataProvider) + ->build() + ); - return $systemRequirementManager->getRequiredListByType($type, $requiredOnly, $additionalData); + return $systemRequirementManager->getRequiredListByType($type, $requiredOnly, $additionalData); } public function checkDatabaseConnection(array $rawParams, bool $createDatabase = false): void diff --git a/install/core/actions/saveSettings.php b/install/core/actions/saveSettings.php index 10aaecf134..d76b6250c5 100644 --- a/install/core/actions/saveSettings.php +++ b/install/core/actions/saveSettings.php @@ -40,15 +40,16 @@ $database = [ 'dbname' => $_SESSION['install']['db-name'], 'user' => $_SESSION['install']['db-user-name'], 'password' => $_SESSION['install']['db-user-password'], + 'platform' => $_SESSION['install']['db-platform'], ]; $host = $_SESSION['install']['host-name']; -if (strpos($host,':') === false) { +if (!str_contains($host, ':')) { $host .= ":"; } -list($database['host'], $database['port']) = explode(':', $host); +[$database['host'], $database['port']] = explode(':', $host); $saveData = [ 'database' => $database, diff --git a/install/core/actions/settingsTest.php b/install/core/actions/settingsTest.php index be5342224a..998a5ff171 100644 --- a/install/core/actions/settingsTest.php +++ b/install/core/actions/settingsTest.php @@ -29,7 +29,10 @@ ob_start(); -$result = array('success' => true, 'errors' => array()); +$result = [ + 'success' => true, + 'errors' => [], +]; $phpRequiredList = $installer->getSystemRequirementList('php', true); @@ -40,11 +43,13 @@ foreach ($phpRequiredList as $name => $details) { case 'version': $result['success'] = false; $result['errors']['phpVersion'] = $details['required']; + break; default: $result['success'] = false; $result['errors']['phpRequires'][] = $name; + break; } } @@ -52,14 +57,22 @@ foreach ($phpRequiredList as $name => $details) { $allPostData = $postData->getAll(); -if ($result['success'] && !empty($allPostData['dbName']) && !empty($allPostData['hostName']) && !empty($allPostData['dbUserName'])) { +if ( + $result['success'] && + !empty($allPostData['dbName']) && + !empty($allPostData['hostName']) && + !empty($allPostData['dbUserName']) +) { $connect = false; $dbName = trim($allPostData['dbName']); - if (strpos($allPostData['hostName'],':') === false) { + + if (!str_contains($allPostData['hostName'], ':')) { $allPostData['hostName'] .= ":"; } - list($hostName, $port) = explode(':', trim($allPostData['hostName'])); + + [$hostName, $port] = explode(':', trim($allPostData['hostName'])); + $dbUserName = trim($allPostData['dbUserName']); $dbUserPass = trim($allPostData['dbUserPass']); @@ -67,7 +80,10 @@ if ($result['success'] && !empty($allPostData['dbName']) && !empty($allPostData[ $port = null; } + $platform = $allPostData['dbPlatform'] ?? 'Mysql'; + $databaseParams = [ + 'platform' => $platform, 'host' => $hostName, 'port' => $port, 'user' => $dbUserName, @@ -79,7 +95,8 @@ if ($result['success'] && !empty($allPostData['dbName']) && !empty($allPostData[ try { $installer->checkDatabaseConnection($databaseParams, true); - } catch (\Exception $e) { + } + catch (\Exception $e) { $isConnected = false; $result['success'] = false; $result['errors']['dbConnect']['errorCode'] = $e->getCode(); @@ -92,16 +109,17 @@ if ($result['success'] && !empty($allPostData['dbName']) && !empty($allPostData[ foreach ($databaseRequiredList as $name => $details) { if (!$details['acceptable']) { - switch ($details['type']) { case 'version': $result['success'] = false; $result['errors'][$name] = $details['required']; + break; default: $result['success'] = false; $result['errors'][$name][] = $name; + break; } } diff --git a/install/core/actions/setupConfirmation.php b/install/core/actions/setupConfirmation.php index f6f3cdfd46..b0eeabece2 100644 --- a/install/core/actions/setupConfirmation.php +++ b/install/core/actions/setupConfirmation.php @@ -39,6 +39,7 @@ $dbConfig = [ 'dbname' => $installData['db-name'], 'user' => $installData['db-user-name'], 'password' => $installData['db-user-password'], + 'platform' => $installData['db-platform'] ]; $mysqlRequirementList = $installer->getSystemRequirementList('database', false, ['databaseParams' => $dbConfig]); diff --git a/install/core/actions/step2.php b/install/core/actions/step2.php index 0adb00bbfc..7ece04ccce 100644 --- a/install/core/actions/step2.php +++ b/install/core/actions/step2.php @@ -43,30 +43,39 @@ foreach ($clearedCookieList as $cookieName) { $config = $installer->getConfig(); -$fields = array( - 'db-driver' => array( +$fields = [ + 'db-platform' => [ + 'default' => $config->get('database.platform', 'Mysql'), + ], + 'db-driver' => [ 'default' => $config->get('database.driver', ''), - ), - 'db-name' => array( + ], + 'db-name' => [ 'default' => $config->get('database.dbname', ''), - ), - 'host-name' => array( - 'default' => $config->get('database.host', '') . ($config->get('database.port') ? ':' . $config->get('database.port') : ''), - ), - 'db-user-name' => array( + ], + 'host-name' => [ + 'default' => $config->get('database.host', '') . + ($config->get('database.port') ? ':' . $config->get('database.port') : ''), + ], + 'db-user-name' => [ 'default' => $config->get('database.user', ''), - ), - 'db-user-password' => array( - //'default' => $config->get('database.password', ''), - ), -); + ], + 'db-user-password' => [], +]; foreach ($fields as $fieldName => $field) { if (isset($_SESSION['install'][$fieldName])) { $fields[$fieldName]['value'] = $_SESSION['install'][$fieldName]; } else { - $fields[$fieldName]['value'] = isset($field['default']) ? $field['default'] : ''; + $fields[$fieldName]['value'] = $field['default'] ?? ''; } } +$platforms = [ + 'Mysql' => 'MySQL', + 'Postgresql' => 'PostgreSQL', +]; + +$smarty->assign('platforms', $platforms); + $smarty->assign('fields', $fields); diff --git a/install/core/i18n/en_US/install.json b/install/core/i18n/en_US/install.json index ab940db6a9..526cdedcff 100644 --- a/install/core/i18n/en_US/install.json +++ b/install/core/i18n/en_US/install.json @@ -56,6 +56,7 @@ "fields": { "Choose your language": "Choose your language", "Database Name": "Database Name", + "Platform": "Platform", "Host Name": "Host Name", "Port": "Port", "Database User Name": "Database User Name", diff --git a/install/core/tpl/step2.tpl b/install/core/tpl/step2.tpl index 49e9fb864b..b89fb8f275 100644 --- a/install/core/tpl/step2.tpl +++ b/install/core/tpl/step2.tpl @@ -6,6 +6,23 @@
+
+ +
+ +
+
diff --git a/public/install/js/install.js b/public/install/js/install.js index 2260be6dff..aed84d1b77 100644 --- a/public/install/js/install.js +++ b/public/install/js/install.js @@ -363,6 +363,7 @@ InstallScript.prototype.finish = function() { } InstallScript.prototype.setConnSett = function() { + this.connSett.dbPlatform = $('[name="db-platform"]').val(); this.connSett.dbName = $('[name="db-name"]').val(); this.connSett.hostName = $('[name="host-name"]').val(); this.connSett.dbUserName = $('[name="db-user-name"]').val();