575 lines
22 KiB
PHP
575 lines
22 KiB
PHP
<?php
|
|
/**
|
|
* OrangeHRM is a comprehensive Human Resource Management (HRM) System that captures
|
|
* all the essential functionalities required for any enterprise.
|
|
* Copyright (C) 2006 OrangeHRM Inc., http://www.orangehrm.com
|
|
*
|
|
* OrangeHRM is free software; you can redistribute it and/or modify it under the terms of
|
|
* the GNU General Public License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* OrangeHRM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
* See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with this program;
|
|
* if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
namespace OrangeHRM\Installer\Util;
|
|
|
|
use DateTime;
|
|
use Doctrine\DBAL\Types\Types;
|
|
use Exception;
|
|
use InvalidArgumentException;
|
|
use OrangeHRM\Config\Config;
|
|
use OrangeHRM\Core\Exception\KeyHandlerException;
|
|
use OrangeHRM\Core\Utility\KeyHandler;
|
|
use OrangeHRM\Core\Utility\PasswordHash;
|
|
use OrangeHRM\Framework\Filesystem\Filesystem;
|
|
use OrangeHRM\Installer\Migration\V3_3_3\Migration;
|
|
use OrangeHRM\Installer\Util\Dto\DatabaseConnectionWrapper;
|
|
use OrangeHRM\Installer\Util\SystemConfig\SystemConfiguration;
|
|
use OrangeHRM\Installer\Util\V1\AbstractMigration;
|
|
|
|
class AppSetupUtility
|
|
{
|
|
public const MIGRATIONS_MAP = [
|
|
'3.3.3' => Migration::class, // From beginning to `3.3.3`
|
|
'4.0' => \OrangeHRM\Installer\Migration\V4_0\Migration::class,
|
|
'4.1' => \OrangeHRM\Installer\Migration\V4_1\Migration::class,
|
|
'4.1.1' => \OrangeHRM\Installer\Migration\V4_1_1\Migration::class,
|
|
'4.1.2' => \OrangeHRM\Installer\Migration\V4_1_2\Migration::class,
|
|
'4.1.2.1' => \OrangeHRM\Installer\Migration\V4_1_2_1\Migration::class,
|
|
'4.2' => \OrangeHRM\Installer\Migration\V4_2\Migration::class,
|
|
'4.2.0.1' => \OrangeHRM\Installer\Migration\V4_2_0_1\Migration::class,
|
|
'4.3' => \OrangeHRM\Installer\Migration\V4_3\Migration::class,
|
|
'4.3.1' => \OrangeHRM\Installer\Migration\V4_3_1\Migration::class,
|
|
'4.3.2' => \OrangeHRM\Installer\Migration\V4_3_2\Migration::class,
|
|
'4.3.3' => \OrangeHRM\Installer\Migration\V4_3_3\Migration::class,
|
|
'4.3.4' => \OrangeHRM\Installer\Migration\V4_3_4\Migration::class,
|
|
'4.3.5' => \OrangeHRM\Installer\Migration\V4_3_5\Migration::class,
|
|
'4.4' => \OrangeHRM\Installer\Migration\V4_4_0\Migration::class,
|
|
'4.5' => \OrangeHRM\Installer\Migration\V4_5_0\Migration::class,
|
|
'4.6' => \OrangeHRM\Installer\Migration\V4_6_0\Migration::class,
|
|
'4.6.0.1' => \OrangeHRM\Installer\Migration\V4_6_0_1\Migration::class,
|
|
'4.7' => \OrangeHRM\Installer\Migration\V4_7_0\Migration::class,
|
|
'4.8' => \OrangeHRM\Installer\Migration\V4_8_0\Migration::class,
|
|
'4.9' => \OrangeHRM\Installer\Migration\V4_9_0\Migration::class,
|
|
'4.10' => \OrangeHRM\Installer\Migration\V4_10_0\Migration::class,
|
|
'4.10.1' => \OrangeHRM\Installer\Migration\V4_10_1\Migration::class,
|
|
'5.0' => [
|
|
\OrangeHRM\Installer\Migration\V5_0_0_beta\Migration::class,
|
|
\OrangeHRM\Installer\Migration\V5_0_0\Migration::class,
|
|
],
|
|
'5.1' => \OrangeHRM\Installer\Migration\V5_1_0\Migration::class,
|
|
'5.2' => \OrangeHRM\Installer\Migration\V5_2_0\Migration::class,
|
|
'5.3' => \OrangeHRM\Installer\Migration\V5_3_0\Migration::class,
|
|
'5.4' => \OrangeHRM\Installer\Migration\V5_4_0\Migration::class,
|
|
];
|
|
|
|
public const INSTALLATION_DB_TYPE_NEW = 'new';
|
|
public const INSTALLATION_DB_TYPE_EXISTING = 'existing';
|
|
|
|
private ConfigHelper $configHelper;
|
|
private SystemConfiguration $systemConfiguration;
|
|
private MigrationHelper $migrationHelper;
|
|
|
|
/**
|
|
* @return ConfigHelper
|
|
*/
|
|
protected function getConfigHelper(): ConfigHelper
|
|
{
|
|
return $this->configHelper ??= new ConfigHelper();
|
|
}
|
|
|
|
/**
|
|
* @return SystemConfiguration
|
|
*/
|
|
protected function getSystemConfiguration(): SystemConfiguration
|
|
{
|
|
return $this->systemConfiguration ??= new SystemConfiguration();
|
|
}
|
|
|
|
/**
|
|
* @return MigrationHelper
|
|
*/
|
|
protected function getMigrationHelper(): MigrationHelper
|
|
{
|
|
return $this->migrationHelper ??= new MigrationHelper();
|
|
}
|
|
|
|
/**
|
|
* @param string $dbName
|
|
*/
|
|
public function createNewDatabase(string $dbName)
|
|
{
|
|
try {
|
|
DatabaseServerConnection::getConnection()->createSchemaManager()->createDatabase($dbName);
|
|
} catch (Exception $e) {
|
|
Logger::getLogger()->error($e->getMessage());
|
|
Logger::getLogger()->error($e->getTraceAsString());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Trying to connect database server without selecting a database
|
|
* @return DatabaseConnectionWrapper
|
|
*/
|
|
public function connectToDatabaseServer(): DatabaseConnectionWrapper
|
|
{
|
|
return DatabaseConnectionWrapper::establishConnection(fn () => DatabaseServerConnection::getConnection());
|
|
}
|
|
|
|
/**
|
|
* @param string $dbName
|
|
* @return bool
|
|
*/
|
|
public function isDatabaseExist(string $dbName): bool
|
|
{
|
|
try {
|
|
return in_array(
|
|
$dbName,
|
|
DatabaseServerConnection::getConnection()->createSchemaManager()->listDatabases()
|
|
);
|
|
} catch (Exception $e) {
|
|
Logger::getLogger()->error($e->getMessage());
|
|
Logger::getLogger()->error($e->getTraceAsString());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $dbUser
|
|
* @return bool
|
|
*/
|
|
public function isDatabaseUserExist(string $dbUser): bool
|
|
{
|
|
try {
|
|
$dbUser = DatabaseServerConnection::getConnection()->quote($dbUser);
|
|
$result = DatabaseServerConnection::getConnection()->executeQuery(
|
|
"SELECT USER FROM mysql.user WHERE USER = $dbUser"
|
|
);
|
|
return $result->rowCount() > 0;
|
|
} catch (Exception $e) {
|
|
Logger::getLogger()->error($e->getMessage());
|
|
Logger::getLogger()->error($e->getTraceAsString());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Trying to connect existing database
|
|
* @return DatabaseConnectionWrapper
|
|
*/
|
|
public function connectToDatabase(): DatabaseConnectionWrapper
|
|
{
|
|
return DatabaseConnectionWrapper::establishConnection(fn () => Connection::getConnection());
|
|
}
|
|
|
|
/**
|
|
* Connect existing database & check is empty
|
|
* @return bool
|
|
*/
|
|
public function isExistingDatabaseEmpty(): bool
|
|
{
|
|
return !(count(Connection::getConnection()->createSchemaManager()->listTables()) > 0);
|
|
}
|
|
|
|
/**
|
|
* Create database at the installation
|
|
*/
|
|
public function createDatabase(): void
|
|
{
|
|
if (StateContainer::getInstance()->getDbType() === AppSetupUtility::INSTALLATION_DB_TYPE_NEW) {
|
|
$dbName = StateContainer::getInstance()->getDbInfo()[StateContainer::DB_NAME];
|
|
if ($this->isDatabaseExist($dbName)) {
|
|
throw new InvalidArgumentException("Cannot create database `$dbName`, already exist");
|
|
}
|
|
$this->createNewDatabase($dbName);
|
|
return;
|
|
} elseif (StateContainer::getInstance()->getDbType() === AppSetupUtility::INSTALLATION_DB_TYPE_EXISTING) {
|
|
if (!$this->isExistingDatabaseEmpty()) {
|
|
$dbName = StateContainer::getInstance()->getDbInfo()[StateContainer::DB_NAME];
|
|
throw new InvalidArgumentException("Database `$dbName`, not empty");
|
|
}
|
|
return;
|
|
}
|
|
throw new InvalidArgumentException(
|
|
'Invalid installation database type ' . StateContainer::getInstance()->getDbType()
|
|
);
|
|
}
|
|
|
|
public function insertSystemConfiguration(): void
|
|
{
|
|
$this->insertCsrfKey();
|
|
$this->insertOrganizationInfo();
|
|
$this->insertSubunitOrganizationName();
|
|
$this->setDefaultLanguage();
|
|
$this->insertAdminEmployee();
|
|
$this->insertAdminUser();
|
|
!StateContainer::getInstance()->getRegConsent() ?: $this->insertInstanceIdentifier();
|
|
$this->getConfigHelper()->setConfigValue(
|
|
'instance.reg_consent',
|
|
(int)StateContainer::getInstance()->getRegConsent()
|
|
);
|
|
}
|
|
|
|
protected function insertCsrfKey(): void
|
|
{
|
|
$bytes = random_bytes(64); // 512/8
|
|
$csrfSecret = rtrim(strtr(base64_encode($bytes), '+/', '-_'), '=');
|
|
$this->getConfigHelper()->setConfigValue('csrf_secret', $csrfSecret);
|
|
}
|
|
|
|
protected function insertOrganizationInfo(): void
|
|
{
|
|
$instanceData = StateContainer::getInstance()->getInstanceData();
|
|
Connection::getConnection()->createQueryBuilder()
|
|
->insert('ohrm_organization_gen_info')
|
|
->values([
|
|
'name' => ':name',
|
|
'country' => ':countryCode',
|
|
])
|
|
->setParameter('name', $instanceData[StateContainer::INSTANCE_ORG_NAME])
|
|
->setParameter('countryCode', $instanceData[StateContainer::INSTANCE_COUNTRY_CODE])
|
|
->executeQuery();
|
|
}
|
|
|
|
protected function insertSubunitOrganizationName(): void
|
|
{
|
|
$instanceData = StateContainer::getInstance()->getInstanceData();
|
|
Connection::getConnection()->createQueryBuilder()
|
|
->update('ohrm_subunit', 'subunit')
|
|
->set('subunit.name', ':organizationName')
|
|
->setParameter('organizationName', $instanceData[StateContainer::INSTANCE_ORG_NAME])
|
|
->andWhere('subunit.level = :topLevel')
|
|
->setParameter('topLevel', 0)
|
|
->executeQuery();
|
|
}
|
|
|
|
protected function setDefaultLanguage(): void
|
|
{
|
|
$instanceData = StateContainer::getInstance()->getInstanceData();
|
|
$this->getConfigHelper()->setConfigValue(
|
|
'admin.localization.default_language',
|
|
$instanceData[StateContainer::INSTANCE_LANG_CODE] ?? 'en_US'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param string $employeeId
|
|
*/
|
|
protected function insertAdminEmployee(string $employeeId = '0001'): void
|
|
{
|
|
$adminUserData = StateContainer::getInstance()->getAdminUserData();
|
|
Connection::getConnection()->createQueryBuilder()
|
|
->insert('hs_hr_employee')
|
|
->values([
|
|
'employee_id' => ':employeeId',
|
|
// 'emp_lastname' => ':lastName',
|
|
'emp_firstname' => ':firstName',
|
|
'emp_work_email' => ':workEmail',
|
|
'emp_work_telephone' => ':contact',
|
|
])
|
|
->setParameter('employeeId', $employeeId)
|
|
->setParameter('firstName', $adminUserData[StateContainer::ADMIN_FIRST_NAME])
|
|
// ->setParameter('lastName', $adminUserData[StateContainer::ADMIN_LAST_NAME])
|
|
->setParameter('workEmail', $adminUserData[StateContainer::ADMIN_EMAIL])
|
|
->setParameter('contact', $adminUserData[StateContainer::ADMIN_CONTACT])
|
|
->executeQuery();
|
|
}
|
|
|
|
/**
|
|
* @param string $employeeId
|
|
*/
|
|
protected function insertAdminUser(string $employeeId = '0001'): void
|
|
{
|
|
$empNumber = Connection::getConnection()->createQueryBuilder()
|
|
->select('employee.emp_number')
|
|
->from('hs_hr_employee', 'employee')
|
|
->where('employee.employee_id = :employeeId')
|
|
->setParameter('employeeId', $employeeId)
|
|
->setMaxResults(1)
|
|
->fetchOne();
|
|
|
|
$adminUserRoleId = Connection::getConnection()->createQueryBuilder()
|
|
->select('userRole.id')
|
|
->from('ohrm_user_role', 'userRole')
|
|
->where('userRole.name = :userRoleName')
|
|
->setParameter('userRoleName', 'Admin')
|
|
->setMaxResults(1)
|
|
->fetchOne();
|
|
|
|
$adminUserData = StateContainer::getInstance()->getAdminUserData();
|
|
$passwordHasher = new PasswordHash();
|
|
$hashedPassword = $passwordHasher->hash($adminUserData[StateContainer::ADMIN_PASSWORD]);
|
|
Connection::getConnection()->createQueryBuilder()
|
|
->insert('ohrm_user')
|
|
->values([
|
|
'user_role_id' => ':userRoleId',
|
|
'emp_number' => ':empNumber',
|
|
'user_name' => ':username',
|
|
'user_password' => ':hashedPassword',
|
|
'date_entered' => ':created',
|
|
])
|
|
->setParameter('userRoleId', $adminUserRoleId)
|
|
->setParameter('empNumber', $empNumber)
|
|
->setParameter('username', $adminUserData[StateContainer::ADMIN_USERNAME])
|
|
->setParameter('hashedPassword', $hashedPassword)
|
|
->setParameter('created', new DateTime(), Types::DATETIME_MUTABLE)
|
|
->executeQuery();
|
|
|
|
$this->updateUniqueIdForAdminEmployeeInsertion();
|
|
}
|
|
|
|
private function updateUniqueIdForAdminEmployeeInsertion(): void
|
|
{
|
|
Connection::getConnection()->createQueryBuilder()
|
|
->update('hs_hr_unique_id', 'uniqueId')
|
|
->set('uniqueId.last_id', ':id')
|
|
->where('uniqueId.table_name = :table')
|
|
->setParameter('id', 1)
|
|
->setParameter('table', 'hs_hr_employee')
|
|
->executeQuery();
|
|
}
|
|
|
|
/**
|
|
* When installing via the application installer, it will get the
|
|
* unique identifiers from the session.
|
|
* When installing via the CLI installer, it will create new
|
|
* unique identifiers since no unique identifiers stored in the session.
|
|
*/
|
|
protected function insertInstanceIdentifier(): void
|
|
{
|
|
$instanceIdentifierData = StateContainer::getInstance()->getInstanceIdentifierData();
|
|
|
|
if (isset($instanceIdentifierData[StateContainer::INSTANCE_IDENTIFIER])) {
|
|
$this->getConfigHelper()->setConfigValue(
|
|
SystemConfiguration::INSTANCE_IDENTIFIER,
|
|
$instanceIdentifierData[StateContainer::INSTANCE_IDENTIFIER]
|
|
);
|
|
} else {
|
|
$instanceIdentifier = $this->getInstanceIdentifier();
|
|
$this->getConfigHelper()->setConfigValue(
|
|
SystemConfiguration::INSTANCE_IDENTIFIER,
|
|
$instanceIdentifier
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getInstanceIdentifier(): string
|
|
{
|
|
$instanceIdentifierData = $this->getInstanceIdentifierData();
|
|
return $this->getSystemConfiguration()
|
|
->createInstanceIdentifier(...$instanceIdentifierData);
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
private function getInstanceIdentifierData(): array
|
|
{
|
|
$adminUserData = StateContainer::getInstance()->getAdminUserData();
|
|
$instanceData = StateContainer::getInstance()->getInstanceData();
|
|
$dateTime = new DateTime();
|
|
return [
|
|
$instanceData[StateContainer::INSTANCE_ORG_NAME],
|
|
$adminUserData[StateContainer::ADMIN_EMAIL],
|
|
$adminUserData[StateContainer::ADMIN_FIRST_NAME],
|
|
$adminUserData[StateContainer::ADMIN_LAST_NAME],
|
|
$_SERVER['HTTP_HOST'] ?? null,
|
|
$instanceData[StateContainer::INSTANCE_COUNTRY_CODE] ?? null,
|
|
Config::PRODUCT_VERSION,
|
|
$dateTime->getTimestamp()
|
|
];
|
|
}
|
|
|
|
public function createDBUser(): void
|
|
{
|
|
if (StateContainer::getInstance()->getDbType() === AppSetupUtility::INSTALLATION_DB_TYPE_NEW) {
|
|
$dbInfo = StateContainer::getInstance()->getDbInfo();
|
|
$dbName = $dbInfo[StateContainer::DB_NAME];
|
|
$dbUser = $dbInfo[StateContainer::DB_USER];
|
|
$ohrmDbUser = $dbInfo[StateContainer::ORANGEHRM_DB_USER];
|
|
if ($ohrmDbUser === null || $dbUser === $ohrmDbUser) {
|
|
return;
|
|
}
|
|
$ohrmDbPassword = $dbInfo[StateContainer::ORANGEHRM_DB_PASSWORD];
|
|
$queries = [
|
|
...$this->getUserCreationQueries($dbName, $ohrmDbUser, $ohrmDbPassword, 'localhost'),
|
|
...$this->getUserCreationQueries($dbName, $ohrmDbUser, $ohrmDbPassword, '%'),
|
|
'FLUSH PRIVILEGES;'
|
|
];
|
|
foreach ($queries as $query) {
|
|
Connection::getConnection()->executeStatement($query);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function getUserCreationQueries(
|
|
string $dbName,
|
|
string $ohrmDbUser,
|
|
?string $ohrmDbPassword,
|
|
string $grantHost
|
|
): array {
|
|
$conn = Connection::getConnection();
|
|
$dbName = $conn->quoteIdentifier($dbName);
|
|
$ohrmDbUser = $conn->quote($ohrmDbUser);
|
|
|
|
$queryIdentifiedBy = is_null($ohrmDbPassword) ? '' : 'IDENTIFIED BY ' . $conn->quote($ohrmDbPassword);
|
|
$createQuery = "CREATE USER $ohrmDbUser@'$grantHost' $queryIdentifiedBy;";
|
|
$grantQuery = 'GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX, REFERENCES, CREATE ROUTINE, ALTER ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, EXECUTE ' .
|
|
"ON $dbName.* TO $ohrmDbUser@'$grantHost';";
|
|
return [$createQuery, $grantQuery];
|
|
}
|
|
|
|
public function writeConfFile(): void
|
|
{
|
|
$template = file_get_contents(realpath(__DIR__ . '/../config/Conf.tpl.php'));
|
|
$search = ['{{dbHost}}', '{{dbPort}}', '{{dbName}}', '{{dbUser}}', '{{dbPass}}'];
|
|
$dbInfo = StateContainer::getInstance()->getDbInfo();
|
|
$replace = [
|
|
$dbInfo[StateContainer::DB_HOST],
|
|
$dbInfo[StateContainer::DB_PORT],
|
|
$dbInfo[StateContainer::DB_NAME],
|
|
$dbInfo[StateContainer::DB_USER],
|
|
$dbInfo[StateContainer::DB_PASSWORD]
|
|
];
|
|
|
|
$fs = new Filesystem();
|
|
$fs->dumpFile(Config::get(Config::CONF_FILE_PATH), str_replace($search, $replace, $template));
|
|
clearstatcache(true);
|
|
}
|
|
|
|
/**
|
|
* @throws KeyHandlerException
|
|
*/
|
|
public function writeKeyFile(): void
|
|
{
|
|
$keyHandler = new KeyHandler();
|
|
$keyHandler::createKey();
|
|
}
|
|
|
|
/**
|
|
* @param string $fromVersion
|
|
* @param string|null $toVersion null for latest version
|
|
* @param bool $includeFromVersion
|
|
* @return string[]
|
|
*/
|
|
public function getVersionsInRange(
|
|
string $fromVersion,
|
|
?string $toVersion = null,
|
|
bool $includeFromVersion = true
|
|
): array {
|
|
$isIn = false;
|
|
$versions = [];
|
|
foreach (self::MIGRATIONS_MAP as $version => $migration) {
|
|
if ($version == $toVersion) {
|
|
$isIn = false;
|
|
$versions[] = $version;
|
|
} elseif ($isIn) {
|
|
$versions[] = $version;
|
|
} elseif ($version == $fromVersion) {
|
|
$isIn = true;
|
|
!$includeFromVersion ?: $versions[] = $version;
|
|
}
|
|
}
|
|
return $versions;
|
|
}
|
|
|
|
/**
|
|
* @param string $fromVersion
|
|
* @param string|null $toVersion null for latest version
|
|
*/
|
|
public function runMigrations(string $fromVersion, ?string $toVersion = null): void
|
|
{
|
|
foreach ($this->getVersionsInRange($fromVersion, $toVersion) as $version) {
|
|
$this->runMigrationFor($version);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $version
|
|
* @return void
|
|
*/
|
|
public function runMigrationFor(string $version): void
|
|
{
|
|
if (!isset(self::MIGRATIONS_MAP[$version])) {
|
|
throw new InvalidArgumentException("Invalid migration version `$version`");
|
|
}
|
|
|
|
if (is_array(self::MIGRATIONS_MAP[$version])) {
|
|
foreach (self::MIGRATIONS_MAP[$version] as $migration) {
|
|
$this->_runMigration($migration);
|
|
}
|
|
return;
|
|
}
|
|
|
|
$this->_runMigration(self::MIGRATIONS_MAP[$version]);
|
|
}
|
|
|
|
/**
|
|
* @param string $migrationClass
|
|
*/
|
|
private function _runMigration(string $migrationClass): void
|
|
{
|
|
$migration = new $migrationClass();
|
|
if ($migration instanceof AbstractMigration) {
|
|
$version = $migration->getVersion();
|
|
$this->getMigrationHelper()->logMigrationStarted($version);
|
|
$migration->up();
|
|
$this->getConfigHelper()->setConfigValue('instance.version', $version);
|
|
$this->getMigrationHelper()->logMigrationFinished($version);
|
|
return;
|
|
}
|
|
throw new InvalidArgumentException("Invalid migration class `$migrationClass`");
|
|
}
|
|
|
|
/**
|
|
* @return string|null
|
|
*/
|
|
public function getCurrentProductVersionFromDatabase(): ?string
|
|
{
|
|
$instanceVersion = $this->getConfigHelper()->getConfigValue('instance.version');
|
|
if ($instanceVersion == null) {
|
|
return null;
|
|
}
|
|
|
|
$migrationMap = self::MIGRATIONS_MAP;
|
|
for (end($migrationMap); ($version = key($migrationMap)) !== null; prev($migrationMap)) {
|
|
$migrationClasses = current($migrationMap);
|
|
if (!is_array($migrationClasses)) {
|
|
$migrationClasses = [$migrationClasses];
|
|
}
|
|
foreach ($migrationClasses as $migrationClass) {
|
|
$migration = new $migrationClass();
|
|
if ($migration instanceof AbstractMigration && $migration->getVersion() == $instanceVersion) {
|
|
return $version;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function cleanUpInstallOnFailure(): void
|
|
{
|
|
Connection::getConnection()->executeStatement('SET FOREIGN_KEY_CHECKS=0;');
|
|
foreach (Connection::getConnection()->createSchemaManager()->listTableNames() as $table) {
|
|
Connection::getConnection()->createSchemaManager()->dropTable($table);
|
|
}
|
|
Connection::getConnection()->executeStatement('SET FOREIGN_KEY_CHECKS=1;');
|
|
}
|
|
|
|
public function dropDatabase(): void
|
|
{
|
|
$dbName = StateContainer::getInstance()->getDbInfo()[StateContainer::DB_NAME];
|
|
Connection::getConnection()->createSchemaManager()->dropDatabase($dbName);
|
|
}
|
|
}
|