diff --git a/src/app/CliTools/Console/Command/Mysql/AbstractCommand.php b/src/app/CliTools/Console/Command/Mysql/AbstractCommand.php index b1452e9..41e1bbf 100644 --- a/src/app/CliTools/Console/Command/Mysql/AbstractCommand.php +++ b/src/app/CliTools/Console/Command/Mysql/AbstractCommand.php @@ -21,6 +21,7 @@ * along with this program. If not, see . */ +use CliTools\Console\Command\Traits\ClisyncConfigTrait; use CliTools\Database\DatabaseConnection; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -28,6 +29,7 @@ abstract class AbstractCommand extends \CliTools\Console\Command\AbstractCommand { + use ClisyncConfigTrait; /** * Configure command @@ -85,6 +87,9 @@ protected function initialize(InputInterface $input, OutputInterface $output) { parent::initialize($input, $output); + // Try to read credentials from clisync.yml if present + $this->initDatabaseConfigurationFromClisync(); + $dsn = null; $user = null; $password = null; diff --git a/src/app/CliTools/Console/Command/Sync/AbstractCommand.php b/src/app/CliTools/Console/Command/Sync/AbstractCommand.php index 89272c6..00b3740 100644 --- a/src/app/CliTools/Console/Command/Sync/AbstractCommand.php +++ b/src/app/CliTools/Console/Command/Sync/AbstractCommand.php @@ -21,6 +21,7 @@ * along with this program. If not, see . */ +use CliTools\Console\Command\Traits\ClisyncConfigTrait; use CliTools\Database\DatabaseConnection; use CliTools\Reader\ConfigReader; use CliTools\Shell\CommandBuilder\CommandBuilder; @@ -29,7 +30,6 @@ use CliTools\Shell\CommandBuilder\RemoteCommandBuilder; use CliTools\Shell\CommandBuilder\SelfCommandBuilder; use CliTools\Utility\ConsoleUtility; -use CliTools\Utility\DockerUtility; use CliTools\Utility\FilterUtility; use CliTools\Utility\PhpUtility; use CliTools\Utility\UnixUtility; @@ -43,6 +43,7 @@ abstract class AbstractCommand extends \CliTools\Console\Command\AbstractDockerCommand { + use ClisyncConfigTrait; const CONFIG_FILE = 'clisync.yml'; const GLOBAL_KEY = 'GLOBAL'; @@ -155,64 +156,8 @@ protected function initializeConfiguration() // Read configuration $this->readConfiguration(); - $this->initDatabaseConfiguration(); - $this->initDockerContainer(); - } - - /** - * Init database configuration (for local one) - */ - protected function initDatabaseConfiguration() - { - $hostname = DatabaseConnection::getDbHostname(); - $port = DatabaseConnection::getDbPort(); - $username = DatabaseConnection::getDbUsername(); - $password = DatabaseConnection::getDbPassword(); - - if ($this->config->exists('LOCAL.mysql.hostname')) { - $hostname = $this->config->get('LOCAL.mysql.hostname'); - } - - if ($this->config->exists('LOCAL.mysql.port')) { - $port = $this->config->get('LOCAL.mysql.port'); - } - - if ($this->config->exists('LOCAL.mysql.username')) { - $username = $this->config->get('LOCAL.mysql.username'); - } - - if ($this->config->exists('LOCAL.mysql.password')) { - $password = $this->config->get('LOCAL.mysql.password'); - } - - $dsn = 'mysql:host=' . urlencode($hostname) . ';port=' . (int)$port; - - DatabaseConnection::setDsn($dsn, $username, $password); - } - - /** - * Init docker container setting - */ - protected function initDockerContainer() - { - $useDockerMysql = false; - - if ($this->config->exists('LOCAL.mysql.docker')) { - $this->setLocalDockerContainer(\CliTools\Console\Command\AbstractDockerCommand::DOCKER_ALIAS_MYSQL , $this->config->get('LOCAL.mysql.docker')); - $useDockerMysql = true; - } elseif ($this->config->exists('LOCAL.mysql.docker-compose')) { - $this->setLocalDockerContainer(\CliTools\Console\Command\AbstractDockerCommand::DOCKER_ALIAS_MYSQL , $this->config->get('LOCAL.mysql.docker-compose'), true); - $useDockerMysql = true; - } - - if ($useDockerMysql) { - $container = $this->getLocalDockerContainer(\CliTools\Console\Command\AbstractDockerCommand::DOCKER_ALIAS_MYSQL); - $password = DockerUtility::getDockerContainerEnv($container, 'MYSQL_ROOT_PASSWORD'); - if (empty($password)) { - $password = DockerUtility::getDockerContainerEnv($container, 'MARIADB_ROOT_PASSWORD'); - } - DatabaseConnection::setDsn('mysql:host=localhost', 'root', $password); - } + // Init database and Docker configuration using trait (pass already loaded config) + $this->initDatabaseConfigurationFromClisync($this->config); } /** diff --git a/src/app/CliTools/Console/Command/TYPO3/BeUserCommand.php b/src/app/CliTools/Console/Command/TYPO3/BeUserCommand.php index 1bc0d83..ccb81d1 100644 --- a/src/app/CliTools/Console/Command/TYPO3/BeUserCommand.php +++ b/src/app/CliTools/Console/Command/TYPO3/BeUserCommand.php @@ -58,7 +58,7 @@ protected function configure() ->addArgument( 'hash', InputArgument::OPTIONAL, - 'Choose the hashing algorithm for saving the password: md5, md5_salted, bcrypt, argon2i, argon2id' + 'Choose the hashing algorithm for saving the password: bcrypt, argon2i, argon2id' ); } @@ -207,10 +207,11 @@ protected function setTypo3UserForDatabase($database, $username, $password) $beUserId = reset($beUserId); // Insert or update user in TYPO3 database + $uidValue = $beUserId ? $this->mysqlQuote($beUserId) : 'NULL'; $query = 'INSERT INTO ' . DatabaseConnection::sanitizeSqlDatabase($database) . '.be_users (uid, tstamp, crdate, realName, username, password, TSconfig, admin, disable, starttime, endtime) VALUES( - ' . $this->mysqlQuote($beUserId) . ', + ' . $uidValue . ', UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), ' . $this->mysqlQuote('DEVELOPMENT') . ', diff --git a/src/app/CliTools/Console/Command/TYPO3/ClearCacheCommand.php b/src/app/CliTools/Console/Command/TYPO3/ClearCacheCommand.php deleted file mode 100644 index 380a2ec..0000000 --- a/src/app/CliTools/Console/Command/TYPO3/ClearCacheCommand.php +++ /dev/null @@ -1,102 +0,0 @@ - - * - * This program 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 3 of the License, or - * (at your option) any later version. - * - * This program 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, see . - */ - -use CliTools\Shell\CommandBuilder\CommandBuilder; -use CliTools\Utility\Typo3Utility; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class ClearCacheCommand extends \CliTools\Console\Command\AbstractCommand -{ - - /** - * Configure command - */ - protected function configure() - { - $this->setName('typo3:clearcache') - ->setDescription( - 'Clear cache on all (or one specific) TYPO3 instances' - ) - ->addArgument( - 'path', - InputArgument::OPTIONAL, - 'Path to TYPO3 instance' - ); - } - - /** - * Execute command - * - * @param InputInterface $input Input instance - * @param OutputInterface $output Output instance - * - * @return int|null|void - */ - public function execute(InputInterface $input, OutputInterface $output): int - { - // #################### - // Init - // #################### - $basePath = $this->getApplication() - ->getConfigValue('config', 'www_base_path', '/var/www/'); - $maxDepth = 3; - - $output->writeln('

Clear TYPO3 cache

'); - - if ($input->getArgument('path')) { - $basePath = $input->getArgument('path'); - } - - // #################### - // Find and loop through TYPO3 instances - // #################### - foreach (Typo3Utility::getTypo3InstancePathList($basePath, $maxDepth) as $dirPath) { - - // Check if coreapi is installed - if (!is_dir($dirPath . '/typo3conf/ext/coreapi/')) { - $output->writeln('

EXT:coreapi is missing on ' . $dirPath . ', skipping

'); - continue; - } - - $params = array( - $dirPath . '/typo3/cli_dispatch.phpsh', - 'coreapi', - 'cache:clearallcaches' - ); - - $output->writeln('

Running clearcache command on ' . $dirPath . '

'); - try { - - $command = new CommandBuilder('php'); - $command->setArgumentList($params) - ->executeInteractive(); - } catch (\Exception $e) { - $output->writeln(' Failed with exception: ' . $e->getMessage() . ''); - } - } - - return 0; - } -} diff --git a/src/app/CliTools/Console/Command/TYPO3/DomainCommand.php b/src/app/CliTools/Console/Command/TYPO3/DomainCommand.php deleted file mode 100644 index 7ed1b9f..0000000 --- a/src/app/CliTools/Console/Command/TYPO3/DomainCommand.php +++ /dev/null @@ -1,296 +0,0 @@ - - * - * This program 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 3 of the License, or - * (at your option) any later version. - * - * This program 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, see . - */ - -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; - -class DomainCommand extends \CliTools\Console\Command\Mysql\AbstractCommand -{ - - /** - * Configure command - */ - protected function configure() - { - parent::configure(); - - $this->setName('typo3:domain') - ->setDescription('Add common development domains to database') - ->addArgument( - 'db', - InputArgument::OPTIONAL, - 'Database name' - ) - ->addOption( - 'baseurl', - null, - InputOption::VALUE_NONE, - 'Also set config.baseURL setting' - ) - ->addOption( - 'list', - null, - InputOption::VALUE_NONE, - 'List only databases' - ) - ->addOption( - 'remove', - null, - InputOption::VALUE_REQUIRED, - 'Remove domain (with wildcard support)' - ) - ->addOption( - 'duplicate', - null, - InputOption::VALUE_REQUIRED, - 'Add duplication domains (will duplicate all domains in system, eg. for vagrant share)' - ) - ->addOption( - 'suffix', - null, - InputOption::VALUE_REQUIRED, - 'Domain suffix' - ); - } - - /** - * Execute command - * - * @param InputInterface $input Input instance - * @param OutputInterface $output Output instance - * - * @return int|null|void - */ - public function execute(InputInterface $input, OutputInterface $output): int - { - // ################## - // Init - // ################## - $dbName = $input->getArgument('db'); - - $output->writeln('

Updating TYPO3 domain entries

'); - - // ############## - // Loop through databases - // ############## - - if (empty($dbName)) { - // ############## - // All databases - // ############## - $databaseList = $this->mysqlDatabaseList(); - - foreach ($databaseList as $dbName) { - // Check if database is TYPO3 instance - $query = 'SELECT COUNT(*) as count - FROM information_schema.tables - WHERE table_schema = ' . $this->mysqlQuote($dbName) . ' - AND table_name = \'sys_domain\''; - $isTypo3Database = $this->execSqlCommand($query); - $isTypo3Database = reset($isTypo3Database); - - if ($isTypo3Database) { - $this->runTaskForDomain($dbName); - } - } - } else { - // ############## - // One databases - // ############## - $this->runTaskForDomain($dbName); - } - - return 0; - } - - /** - * Run tasks for one domain - */ - protected function runTaskForDomain($dbName) - { - if ($this->input->getOption('list')) { - // Show domain list (and skip all other tasks) - $this->showDomainList($dbName); - } else { - // Remove domains (eg. for cleanup) - if ($this->input->getOption('remove')) { - $this->removeDomains($dbName, $this->input->getOption('remove')); - } - - // Set development domains - $this->manipulateDomains($dbName); - - // Add sharing domains - if ($this->input->getOption('baseurl')) { - $this->updateBaseUrlConfig($dbName); - } - - // Add sharing domains - if ($this->input->getOption('duplicate')) { - $this->addDuplicateDomains($dbName, $this->input->getOption('duplicate')); - } - - // Show domain list - $this->showDomainList($dbName); - } - } - - /** - * Remove domains - */ - protected function removeDomains($dbName, $pattern) - { - $pattern = str_replace('*', '%', $pattern); - - $query = 'DELETE FROM ' . $dbName . '.sys_domain WHERE domainName LIKE %s'; - $query = sprintf($query, $this->mysqlQuote($pattern)); - $this->execSqlCommand($query); - } - - /** - * Update baseURL config - */ - protected function updateBaseUrlConfig($dbName) - { - $query = 'SELECT st.uid as template_id, - st.config as template_config, - (SELECT sd.domainName - FROM sys_domain sd - WHERE sd.pid = st.pid - AND sd.hidden = 0 - ORDER BY sd.forced DESC, - sd.sorting ASC - LIMIT 1) as domain_name - FROM ' . $dbName . '.sys_template st - WHERE st.root = 1 - AND st.deleted = 0 - HAVING domain_name IS NOT NULL'; - $templateIdList = $this->execSqlQuery($query); - - foreach ($templateIdList as $row) { - $templateId = $row['template_id']; - $domainName = $row['domain_name']; - $templateConf = $row['template_config']; - - // Remove old baseURL entries (no duplciates) - $templateConf = preg_replace('/^config.baseURL = .*$/m', '', $templateConf); - $templateConf = trim($templateConf); - - // Add new baseURL - $templateConf .= "\n" . 'config.baseURL = http://' . $domainName . '/'; - - $query = 'UPDATE ' . $dbName . '.sys_template SET config = %s WHERE uid = %s'; - $query = sprintf($query, $this->mysqlQuote($templateConf), (int)$templateId); - $this->execSqlCommand($query); - } - } - - /** - * Add share domains (eg. for vagrantshare) - * - * @param string $suffix Domain suffix - */ - protected function addDuplicateDomains($dbName, $suffix) - { - $devDomain = '.' . $this->getApplication() - ->getConfigValue('config', 'domain_dev'); - - $query = 'SELECT * FROM ' . $dbName . '.sys_domain'; - $domainList = $this->execSqlQuery($query); - - foreach ($domainList as $domain) { - unset($domain['uid']); - - $domainName = $domain['domainName']; - - // remove development suffix - $domainName = preg_replace('/' . preg_quote($devDomain) . '$/', '', $domainName); - - // add share domain - $domainName .= '.' . ltrim($suffix, '.'); - - $domain['domainName'] = $domainName; - - // create insert - $table = 'sys_domain'; - $fieldList = array_keys($domain); - - $valueList = array(); - foreach ($domain as $value) { - $valueList[] = $this->mysqlQuote($value); - } - - $query = 'INSERT INTO %s (%s) VALUES (%s)'; - $query = sprintf($query, $table, implode(',', $fieldList), implode(',', $valueList)); - $this->execSqlCommand($query); - } - } - - /** - * Show list of domains - * - * @param string $dbName Domain name - */ - protected function showDomainList($dbName) - { - $query = 'SELECT domainName - FROM ' . $dbName . '.sys_domain - WHERE hidden = 0 - ORDER BY domainName ASC'; - $domainList = $this->execSqlQuery($query); - - $this->output->writeln('

Domain list of "' . $dbName . '":

'); - - foreach ($domainList as $domain) { - $this->output->writeln('

' . reset($domain) . '

'); - } - $this->output->writeln(''); - } - - /** - * Set development domains for TYPO3 database - * - * @return void - */ - protected function manipulateDomains($dbName) - { - $devDomain = '.' . $this->getApplication() - ->getConfigValue('config', 'domain_dev'); - - if ($this->input->getOption('suffix')) { - $devDomain = $this->input->getOption('suffix'); - } - - $domainLength = strlen($devDomain); - - // ################## - // Fix domains - // ################## - $query = 'UPDATE ' . $dbName . '.sys_domain - SET domainName = CONCAT(domainName, ' . $this->mysqlQuote($devDomain) . ') - WHERE RIGHT(domainName, ' . $domainLength . ') <> ' . $this->mysqlQuote($devDomain); - $this->execSqlCommand($query); - } -} diff --git a/src/app/CliTools/Console/Command/TYPO3/ListCommand.php b/src/app/CliTools/Console/Command/TYPO3/ListCommand.php index 50a0ec9..2ec2953 100644 --- a/src/app/CliTools/Console/Command/TYPO3/ListCommand.php +++ b/src/app/CliTools/Console/Command/TYPO3/ListCommand.php @@ -63,48 +63,22 @@ public function execute(InputInterface $input, OutputInterface $output): int $basePath = Typo3Utility::guessBestTypo3BasePath($basePath, $input, 'path'); - $versionFileList = array( - // 6.x version - '/typo3/sysext/core/Classes/Core/SystemEnvironmentBuilder.php' => '/define\(\'TYPO3_version\',[\s]*\'([^\']+)\'\)/i', - // 4.x version - '/t3lib/config_default.php' => '/\$TYPO_VERSION[\s]*=[\s]*\'([^\']+)\'/i', - ); - // #################### // Find and loop through TYPO3 instances // #################### $typo3List = array(); foreach (Typo3Utility::getTypo3InstancePathList($basePath, $maxDepth) as $dirPath) { - $typo3Version = null; - $typo3Path = $dirPath; - - // Detect version (dirty way...) - foreach ($versionFileList as $versionFile => $versionRegExp) { - $versionFile = $dirPath . $versionFile; - - if (file_exists($versionFile)) { - $tmp = file_get_contents($versionFile); - if (preg_match($versionRegExp, $tmp, $matches)) { - $typo3Version = $matches[1]; - break; - } - } - } + $typo3Version = $this->detectTypo3Version($dirPath); - if (strpos($typo3Version, '6') === 0) { - // TYPO3 6.x + if ($typo3Version !== null) { $typo3Version = '' . $typo3Version . ''; - } elseif (!empty($typo3Version)) { - // TYPO3 4.x - $typo3Version = '' . $typo3Version . ''; } else { - // Unknown $typo3Version = 'unknown'; } $typo3List[] = array( - $typo3Path, + $dirPath, $typo3Version, ); } @@ -119,4 +93,46 @@ public function execute(InputInterface $input, OutputInterface $output): int return 0; } + + /** + * Detect TYPO3 version from installation path + * + * @param string $dirPath Path to TYPO3 installation + * @return string|null + */ + protected function detectTypo3Version(string $dirPath): ?string + { + // Try composer.json in vendor (Composer mode) + $composerFile = $dirPath . '/vendor/typo3/cms-core/composer.json'; + if (file_exists($composerFile)) { + $composerData = json_decode(file_get_contents($composerFile), true); + if (isset($composerData['version'])) { + return $composerData['version']; + } + } + + // Try composer.lock in project root + $composerLock = $dirPath . '/composer.lock'; + if (file_exists($composerLock)) { + $lockData = json_decode(file_get_contents($composerLock), true); + if (isset($lockData['packages'])) { + foreach ($lockData['packages'] as $package) { + if ($package['name'] === 'typo3/cms-core') { + return $package['version']; + } + } + } + } + + // Try ext_emconf.php (classic mode) + $extEmconfFile = $dirPath . '/typo3/sysext/core/ext_emconf.php'; + if (file_exists($extEmconfFile)) { + $content = file_get_contents($extEmconfFile); + if (preg_match('/[\'"]version[\'"]\s*=>\s*[\'"]([^\'"]+)[\'"]/', $content, $matches)) { + return $matches[1]; + } + } + + return null; + } } diff --git a/src/app/CliTools/Console/Command/Traits/ClisyncConfigTrait.php b/src/app/CliTools/Console/Command/Traits/ClisyncConfigTrait.php new file mode 100644 index 0000000..00de846 --- /dev/null +++ b/src/app/CliTools/Console/Command/Traits/ClisyncConfigTrait.php @@ -0,0 +1,148 @@ + + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + */ + +use CliTools\Console\Command\AbstractDockerCommand; +use CliTools\Database\DatabaseConnection; +use CliTools\Reader\ConfigReader; +use CliTools\Utility\DockerUtility; +use CliTools\Utility\PhpUtility; +use CliTools\Utility\UnixUtility; +use Symfony\Component\Yaml\Yaml; + +trait ClisyncConfigTrait +{ + /** + * Init database configuration from clisync.yml if present + * + * @param ConfigReader|null $config Optional config reader (if already loaded) + */ + protected function initDatabaseConfigurationFromClisync(?ConfigReader $config = null) + { + if ($config === null) { + $config = $this->loadClisyncConfig(); + if ($config === null) { + return; + } + } + + // Handle Docker container configuration first (takes precedence) + if ($this->initDockerContainerFromConfig($config)) { + return; + } + + // Apply standard MySQL credentials + $this->applyMysqlCredentialsFromConfig($config); + } + + /** + * Load clisync.yml configuration + * + * @return ConfigReader|null + */ + protected function loadClisyncConfig(): ?ConfigReader + { + $confFileList = array( + 'clisync.yml', + '.clisync.yml', + ); + + $confFilePath = UnixUtility::findFileInDirectortyTree($confFileList); + if (empty($confFilePath) || !file_exists($confFilePath)) { + return null; + } + + $conf = Yaml::parse(PhpUtility::fileGetContents($confFilePath)); + if (empty($conf)) { + return null; + } + + $config = new ConfigReader(); + $config->setData($conf); + + return $config; + } + + /** + * Apply MySQL credentials from config to DatabaseConnection + * + * @param ConfigReader $config + */ + protected function applyMysqlCredentialsFromConfig(ConfigReader $config) + { + $hostname = DatabaseConnection::getDbHostname(); + $port = DatabaseConnection::getDbPort(); + $username = DatabaseConnection::getDbUsername(); + $password = DatabaseConnection::getDbPassword(); + + if ($config->exists('LOCAL.mysql.hostname')) { + $hostname = $config->get('LOCAL.mysql.hostname'); + } + + if ($config->exists('LOCAL.mysql.port')) { + $port = $config->get('LOCAL.mysql.port'); + } + + if ($config->exists('LOCAL.mysql.username')) { + $username = $config->get('LOCAL.mysql.username'); + } + + if ($config->exists('LOCAL.mysql.password')) { + $password = $config->get('LOCAL.mysql.password'); + } + + $dsn = 'mysql:host=' . urlencode($hostname) . ';port=' . (int)$port; + + DatabaseConnection::setDsn($dsn, $username, $password); + } + + /** + * Init Docker container from config + * + * @param ConfigReader $config + * @return bool True if Docker was configured + */ + protected function initDockerContainerFromConfig(ConfigReader $config): bool + { + $useDockerMysql = false; + + if ($config->exists('LOCAL.mysql.docker')) { + $this->setLocalDockerContainer(AbstractDockerCommand::DOCKER_ALIAS_MYSQL, $config->get('LOCAL.mysql.docker')); + $useDockerMysql = true; + } elseif ($config->exists('LOCAL.mysql.docker-compose')) { + $this->setLocalDockerContainer(AbstractDockerCommand::DOCKER_ALIAS_MYSQL, $config->get('LOCAL.mysql.docker-compose'), true); + $useDockerMysql = true; + } + + if ($useDockerMysql) { + $container = $this->getLocalDockerContainer(AbstractDockerCommand::DOCKER_ALIAS_MYSQL); + $password = DockerUtility::getDockerContainerEnv($container, 'MYSQL_ROOT_PASSWORD'); + if (empty($password)) { + $password = DockerUtility::getDockerContainerEnv($container, 'MARIADB_ROOT_PASSWORD'); + } + DatabaseConnection::setDsn('mysql:host=localhost', 'root', $password); + return true; + } + + return false; + } +} diff --git a/src/app/CliTools/Iterator/Filter/Typo3RecursiveDirectoryFilter.php b/src/app/CliTools/Iterator/Filter/Typo3RecursiveDirectoryFilter.php index 938444a..04c569f 100644 --- a/src/app/CliTools/Iterator/Filter/Typo3RecursiveDirectoryFilter.php +++ b/src/app/CliTools/Iterator/Filter/Typo3RecursiveDirectoryFilter.php @@ -52,7 +52,7 @@ class Typo3RecursiveDirectoryFilter extends \CliTools\Iterator\Filter\RecursiveD * * @return bool */ - public function accept() + public function accept(): bool { if (!parent::accept()) { return false; diff --git a/src/app/CliTools/Utility/Typo3Utility.php b/src/app/CliTools/Utility/Typo3Utility.php index e6ae507..8423a65 100644 --- a/src/app/CliTools/Utility/Typo3Utility.php +++ b/src/app/CliTools/Utility/Typo3Utility.php @@ -27,11 +27,9 @@ class Typo3Utility { - const PASSWORD_TYPE_MD5 = 'md5'; - const PASSWORD_TYPE_MD5_SALTED = 'md5_salted'; - const PASSWORD_TYPE_BCRYPT = 'bcrypt'; - const PASSWORD_TYPE_ARGON2I = 'argon2i'; - const PASSWORD_TYPE_ARGON2ID = 'argon2id'; + const PASSWORD_TYPE_BCRYPT = 'bcrypt'; + const PASSWORD_TYPE_ARGON2I = 'argon2i'; + const PASSWORD_TYPE_ARGON2ID = 'argon2id'; /** * Generate TYPO3 password @@ -39,25 +37,13 @@ class Typo3Utility * @param string $password Password * @param ?string $type Type of password (see constants) * - * @return null|string + * @return array [hash, algorithm_name] */ public static function generatePassword($password, ?string $type = null) { $ret = null; switch ($type) { - - case self::PASSWORD_TYPE_MD5: - $ret = md5($password); - break; - - case self::PASSWORD_TYPE_MD5_SALTED: - // Salted md5 - $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; - $salt = '$1$' . substr(str_shuffle($chars), 0, 6) . '$'; - $ret = crypt($password, $salt); - break; - case self::PASSWORD_TYPE_BCRYPT: $ret = password_hash($password, PASSWORD_BCRYPT); break; @@ -72,8 +58,7 @@ public static function generatePassword($password, ?string $type = null) default: $possibleAlgorithms = []; - # Commented out since TYPO3 9.5 doesn't support argon2id yet - #defined('PASSWORD_ARGON2ID') && $possibleAlgorithms[PASSWORD_ARGON2ID] = self::PASSWORD_TYPE_ARGON2ID; + defined('PASSWORD_ARGON2ID') && $possibleAlgorithms[PASSWORD_ARGON2ID] = self::PASSWORD_TYPE_ARGON2ID; defined('PASSWORD_ARGON2I') && $possibleAlgorithms[PASSWORD_ARGON2I] = self::PASSWORD_TYPE_ARGON2I; defined('PASSWORD_BCRYPT') && $possibleAlgorithms[PASSWORD_BCRYPT] = self::PASSWORD_TYPE_BCRYPT;