[TASK] Doctrine : Migrate DatabaseCharsetUpdate
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Updates / DatabaseCharsetUpdate.php
1 <?php
2 namespace TYPO3\CMS\Install\Updates;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Doctrine\DBAL\DBALException;
18 use TYPO3\CMS\Core\Database\ConnectionPool;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20 use TYPO3\CMS\Core\Utility\StringUtility;
21
22 /**
23 * Move "wizard done" flags to system registry
24 */
25 class DatabaseCharsetUpdate extends AbstractUpdate
26 {
27 /**
28 * @var string
29 */
30 protected $title = 'Set default database charset to utf-8';
31
32 /**
33 * Checks if an update is needed
34 *
35 * @param string &$description The description for the update
36 * @return bool Whether an update is needed (TRUE) or not (FALSE)
37 * @throws \InvalidArgumentException
38 * @throws \Doctrine\DBAL\DBALException
39 */
40 public function checkForUpdate(&$description)
41 {
42 if ($this->isWizardDone() || !$this->isDefaultConnectionMySQL()) {
43 return false;
44 }
45
46 $result = false;
47 $description = 'Sets the default database charset to utf-8 to'
48 . ' ensure new tables are created with correct charset.
49 WARNING: This will NOT convert any existing data.';
50
51 // check if database charset is utf-8, also allows utf8mb4
52 if (!StringUtility::beginsWith($this->getDefaultDatabaseCharset(), 'utf8')) {
53 $result = true;
54 } else {
55 $this->markWizardAsDone();
56 }
57
58 return $result;
59 }
60
61 /**
62 * Performs the accordant updates.
63 *
64 * @param array &$dbQueries Queries done in this update
65 * @param mixed &$customMessages Custom messages
66 * @return bool Whether everything went smoothly or not
67 * @throws \InvalidArgumentException
68 * @throws \Doctrine\DBAL\DBALException
69 */
70 public function performUpdate(array &$dbQueries, &$customMessages)
71 {
72 $connection = GeneralUtility::makeInstance(ConnectionPool::class)
73 ->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
74 $sql = 'ALTER DATABASE ' . $connection->quoteIdentifier($connection->getDatabase()) . ' CHARACTER SET utf8';
75
76 try {
77 $connection->exec($sql);
78 } catch (DBALException $e) {
79 $customMessages = 'SQL-ERROR: ' . htmlspecialchars($e->getPrevious()->getMessage());
80 return false;
81 }
82 $dbQueries[] = $sql;
83 $this->markWizardAsDone();
84
85 return true;
86 }
87
88 /**
89 * Return TRUE if this TYPO3 instance runs on a MySQL compatible databasa instance
90 *
91 * @return bool
92 * @throws \InvalidArgumentException
93 * @throws \Doctrine\DBAL\DBALException
94 */
95 protected function isDefaultConnectionMySQL(): bool
96 {
97 $connection = GeneralUtility::makeInstance(ConnectionPool::class)
98 ->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
99
100 return StringUtility::beginsWith($connection->getServerVersion(), 'MySQL');
101 }
102
103 /**
104 * Retrieves the default character set of the database.
105 *
106 * @return string
107 * @throws \InvalidArgumentException
108 * @throws \Doctrine\DBAL\DBALException
109 */
110 protected function getDefaultDatabaseCharset(): string
111 {
112 $connection = GeneralUtility::makeInstance(ConnectionPool::class)
113 ->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
114 $queryBuilder = $connection->createQueryBuilder();
115 return (string)$queryBuilder->select('DEFAULT_CHARACTER_SET_NAME')
116 ->from('information_schema.SCHEMATA')
117 ->where(
118 $queryBuilder
119 ->expr()
120 ->eq('SCHEMA_NAME', $queryBuilder->quote($connection->getDatabase()))
121 )
122 ->setMaxResults(1)
123 ->execute()
124 ->fetchColumn();
125 }
126 }