Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
DbValidator.php
Go to the documentation of this file.
1 <?php
8 
12 
16 class DbValidator
17 {
18 
22  const DB_PREFIX_LENGTH = 5;
23 
29  private $connectionFactory;
30 
36  public function __construct(ConnectionFactory $connectionFactory)
37  {
38  $this->connectionFactory = $connectionFactory;
39  }
40 
48  public function checkDatabaseTablePrefix($prefix)
49  {
50  //The table prefix should contain only letters (a-z), numbers (0-9) or underscores (_);
51  // the first character should be a letter.
52  if ($prefix !== '' && !preg_match('/^([a-zA-Z])([[:alnum:]_]+)$/', $prefix)) {
53  throw new \InvalidArgumentException(
54  'Please correct the table prefix format, should contain only numbers, letters or underscores.'
55  .' The first character should be a letter.'
56  );
57  }
58 
59  if (strlen($prefix) > self::DB_PREFIX_LENGTH) {
60  throw new \InvalidArgumentException(
61  'Table prefix length can\'t be more than ' . self::DB_PREFIX_LENGTH . ' characters.'
62  );
63  }
64 
65  return true;
66  }
67 
78  public function checkDatabaseConnection($dbName, $dbHost, $dbUser, $dbPass = '')
79  {
80  // establish connection to information_schema view to retrieve information about user and table privileges
81  $connection = $this->connectionFactory->create([
82  ConfigOptionsListConstants::KEY_NAME => 'information_schema',
87  ]);
88 
89  if (!$connection) {
90  throw new \Magento\Setup\Exception('Database connection failure.');
91  }
92 
93  $mysqlVersion = $connection->fetchOne('SELECT version()');
94  if ($mysqlVersion) {
95  if (preg_match('/^([0-9\.]+)/', $mysqlVersion, $matches)) {
96  if (isset($matches[1]) && !empty($matches[1])) {
97  if (version_compare($matches[1], Installer::MYSQL_VERSION_REQUIRED) < 0) {
98  throw new \Magento\Setup\Exception(
99  'Sorry, but we support MySQL version ' . Installer::MYSQL_VERSION_REQUIRED . ' or later.'
100  );
101  }
102  }
103  }
104  }
105 
106  return $this->checkDatabaseName($connection, $dbName) && $this->checkDatabasePrivileges($connection, $dbName);
107  }
108 
117  private function checkDatabaseName(\Magento\Framework\DB\Adapter\AdapterInterface $connection, $dbName)
118  {
119  $query = "SHOW DATABASES";
120  $accessibleDbs = $connection->query($query)->fetchAll(\PDO::FETCH_COLUMN, 0);
121  foreach ($accessibleDbs as $accessibleDbName) {
122  if ($dbName == $accessibleDbName) {
123  return true;
124  }
125  }
126  throw new \Magento\Setup\Exception(
127  "Database '{$dbName}' does not exist "
128  ."or specified database server user does not have privileges to access this database."
129  );
130  }
131 
140  private function checkDatabasePrivileges(\Magento\Framework\DB\Adapter\AdapterInterface $connection, $dbName)
141  {
142  $requiredPrivileges = [
143  'SELECT',
144  'INSERT',
145  'UPDATE',
146  'DELETE',
147  'CREATE',
148  'DROP',
149  'INDEX',
150  'ALTER',
151  'CREATE TEMPORARY TABLES',
152  'LOCK TABLES',
153  'EXECUTE',
154  'CREATE VIEW',
155  'SHOW VIEW',
156  'CREATE ROUTINE',
157  'ALTER ROUTINE',
158  'TRIGGER'
159  ];
160 
161  // check global privileges
162  $userPrivilegesQuery = "SELECT PRIVILEGE_TYPE FROM USER_PRIVILEGES "
163  . "WHERE REPLACE(GRANTEE, '\'', '') = current_user()";
164  $grantInfo = $connection->query($userPrivilegesQuery)->fetchAll(\PDO::FETCH_NUM);
165  if (empty(array_diff($requiredPrivileges, $this->parseGrantInfo($grantInfo)))) {
166  return true;
167  }
168 
169  // check table privileges
170  $schemaPrivilegesQuery = "SELECT PRIVILEGE_TYPE FROM SCHEMA_PRIVILEGES " .
171  "WHERE '$dbName' LIKE TABLE_SCHEMA AND REPLACE(GRANTEE, '\'', '') = current_user()";
172  $grantInfo = $connection->query($schemaPrivilegesQuery)->fetchAll(\PDO::FETCH_NUM);
173  if (empty(array_diff($requiredPrivileges, $this->parseGrantInfo($grantInfo)))) {
174  return true;
175  }
176 
177  $errorMessage = 'Database user does not have enough privileges. Please make sure '
178  . implode(', ', $requiredPrivileges) . " privileges are granted to table '{$dbName}'.";
179  throw new \Magento\Setup\Exception($errorMessage);
180  }
181 
188  private function parseGrantInfo(array $grantInfo)
189  {
190  $result = [];
191  foreach ($grantInfo as $grantRow) {
192  $result[] = $grantRow[0];
193  }
194  return $result;
195  }
196 }
$prefix
Definition: name.phtml:25
$connection
Definition: bulk.php:13