![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/setup/src/Magento/Setup/Validator/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Setup\Validator; use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Setup\Model\Installer; use Magento\Setup\Module\ConnectionFactory; /** * Class DbValidator - validates DB related settings */ class DbValidator { /** * Db prefix max length */ public const DB_PREFIX_LENGTH = 5; /** * DB connection factory * * @var ConnectionFactory */ private $connectionFactory; /** * Constructor * * @param ConnectionFactory $connectionFactory */ public function __construct(ConnectionFactory $connectionFactory) { $this->connectionFactory = $connectionFactory; } /** * Check if database table prefix is valid * * @param string $prefix * @return bool * @throws \InvalidArgumentException */ public function checkDatabaseTablePrefix($prefix) { //The table prefix should contain only letters (a-z), numbers (0-9) or underscores (_); // the first character should be a letter. if ($prefix !== '' && !preg_match('/^([a-zA-Z])([[:alnum:]_]+)$/', $prefix)) { throw new \InvalidArgumentException( 'Please correct the table prefix format, should contain only numbers, letters or underscores.' .' The first character should be a letter.' ); } if (strlen($prefix) > self::DB_PREFIX_LENGTH) { throw new \InvalidArgumentException( 'Table prefix length can\'t be more than ' . self::DB_PREFIX_LENGTH . ' characters.' ); } return true; } /** * Checks Database Connection * * @param string $dbName * @param string $dbHost * @param string $dbUser * @param string $dbPass * @return bool * @throws \Magento\Setup\Exception * @deprecated */ public function checkDatabaseConnection($dbName, $dbHost, $dbUser, $dbPass = '') { return $this->checkDatabaseConnectionWithDriverOptions($dbName, $dbHost, $dbUser, $dbPass, []); } /** * Checks Database Connection with Driver Options * * @param string $dbName * @param string $dbHost * @param string $dbUser * @param string $dbPass * @param array $driverOptions * @return bool * @throws \Magento\Setup\Exception */ public function checkDatabaseConnectionWithDriverOptions( $dbName, $dbHost, $dbUser, $dbPass = '', $driverOptions = [] ) { // establish connection to information_schema view to retrieve information about user and table privileges $connection = $this->connectionFactory->create( [ ConfigOptionsListConstants::KEY_NAME => 'information_schema', ConfigOptionsListConstants::KEY_HOST => $dbHost, ConfigOptionsListConstants::KEY_USER => $dbUser, ConfigOptionsListConstants::KEY_PASSWORD => $dbPass, ConfigOptionsListConstants::KEY_ACTIVE => true, ConfigOptionsListConstants::KEY_DRIVER_OPTIONS => $driverOptions, ] ); if (!$connection) { throw new \Magento\Setup\Exception('Database connection failure.'); } $mysqlVersion = $connection->fetchOne('SELECT version()'); if ($mysqlVersion) { if (preg_match('/^([0-9\.]+)/', $mysqlVersion, $matches)) { if (isset($matches[1]) && !empty($matches[1])) { if (version_compare($matches[1], Installer::MYSQL_VERSION_REQUIRED) < 0) { throw new \Magento\Setup\Exception( 'Sorry, but we support MySQL version ' . Installer::MYSQL_VERSION_REQUIRED . ' or later.' ); } } } } return $this->checkDatabaseName($connection, $dbName) && $this->checkDatabasePrivileges($connection, $dbName); } /** * Checks if specified database exists and visible to current user * * @param \Magento\Framework\DB\Adapter\AdapterInterface $connection * @param string $dbName * @return bool * @throws \Magento\Setup\Exception */ private function checkDatabaseName(\Magento\Framework\DB\Adapter\AdapterInterface $connection, $dbName) { try { $query = sprintf("SHOW TABLES FROM `%s`", $dbName); $connection->query($query)->fetchAll(\PDO::FETCH_COLUMN, 0); return true; } catch (\Exception $e) { throw new \Magento\Setup\Exception( "Database '{$dbName}' does not exist " . "or specified database server user does not have privileges to access this database." ); } } /** * Checks database privileges * * @param \Magento\Framework\DB\Adapter\AdapterInterface $connection * @param string $dbName * @return bool * @throws \Magento\Setup\Exception */ private function checkDatabasePrivileges(\Magento\Framework\DB\Adapter\AdapterInterface $connection, $dbName) { $requiredPrivileges = [ 'SELECT', 'INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP', 'INDEX', 'ALTER', 'CREATE TEMPORARY TABLES', 'LOCK TABLES', 'EXECUTE', 'CREATE VIEW', 'SHOW VIEW', 'CREATE ROUTINE', 'ALTER ROUTINE', 'TRIGGER' ]; // check global privileges // phpcs:ignore Magento2.SQL.RawQuery $userPrivilegesQuery = "SELECT PRIVILEGE_TYPE FROM USER_PRIVILEGES " . "WHERE REPLACE(GRANTEE, '\'', '') = current_user()"; $grantInfo = $connection->query($userPrivilegesQuery)->fetchAll(\PDO::FETCH_NUM); if (empty(array_diff($requiredPrivileges, $this->parseGrantInfo($grantInfo)))) { return true; } // check database privileges // phpcs:ignore Magento2.SQL.RawQuery $schemaPrivilegesQuery = "SELECT PRIVILEGE_TYPE FROM SCHEMA_PRIVILEGES " . "WHERE '$dbName' LIKE TABLE_SCHEMA AND REPLACE(GRANTEE, '\'', '') = current_user()"; $grantInfo = $connection->query($schemaPrivilegesQuery)->fetchAll(\PDO::FETCH_NUM); if (empty(array_diff($requiredPrivileges, $this->parseGrantInfo($grantInfo)))) { return true; } $errorMessage = 'Database user does not have enough privileges. Please make sure ' . implode(', ', $requiredPrivileges) . " privileges are granted to database '{$dbName}'."; throw new \Magento\Setup\Exception($errorMessage); } /** * Parses query result * * @param array $grantInfo * @return array */ private function parseGrantInfo(array $grantInfo) { $result = []; foreach ($grantInfo as $grantRow) { $result[] = $grantRow[0]; } return $result; } }