TYPO3 CMS  TYPO3_8-7
InitialDatabaseSchemaUpdate.php
Go to the documentation of this file.
1 <?php
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 
21 
26 {
30  public function __construct()
31  {
32  parent::__construct();
33  $this->title = 'Update database schema: Create tables and fields';
34  }
35 
50  public function checkForUpdate(&$description)
51  {
52  $description = 'There are tables or fields in the database which need to be created.<br /><br />' .
53  'You have to run this update wizard before you can run any other update wizard to make sure all ' .
54  'needed tables and fields are present.';
55 
56  $databaseDifferences = $this->getDatabaseDifferences();
57  foreach ($databaseDifferences as $schemaDiff) {
58  // A new table is required, early return
59  if (!empty($schemaDiff->newTables)) {
60  return true;
61  }
62 
63  // A new field or index is required
64  foreach ($schemaDiff->changedTables as $changedTable) {
65  if (!empty($changedTable->addedColumns)) {
66  return true;
67  }
68 
69  // Ignore new indexes that work on columns that need changes
70  foreach ($changedTable->addedIndexes as $indexName => $addedIndex) {
71  // Strip MySQL prefix length information to get real column names
72  $indexColumns = array_map(
73  function ($columnName) {
74  return preg_replace('/\(\d+\)$/', '', $columnName);
75  },
76  $addedIndex->getColumns()
77  );
78  $columnChanges = array_intersect($indexColumns, array_keys($changedTable->changedColumns));
79  if (!empty($columnChanges)) {
80  unset($changedTable->addedIndexes[$indexName]);
81  }
82  }
83 
84  if (!empty($changedTable->addedIndexes)) {
85  return true;
86  }
87  }
88  }
89 
90  return false;
91  }
92 
107  public function getUserInput($inputPrefix): string
108  {
109  $result = '';
110  $addedTables = '';
111  $addedFields = '';
112  $addedIndexes = '';
113 
114  $databaseDifferences = $this->getDatabaseDifferences();
115  foreach ($databaseDifferences as $schemaDiff) {
116  $addedTables .= $this->getAddedTableInformation($schemaDiff);
117  $addedFields .= $this->getAddedFieldInformation($schemaDiff);
118  $addedIndexes .= $this->getAddedIndexInformation($schemaDiff);
119  }
120 
121  $result .= $this->renderList('Add the following tables:', $addedTables);
122  $result .= $this->renderList('Add the following fields to tables:', $addedFields);
123  $result .= $this->renderList('Add the following keys to tables:', $addedIndexes);
124 
125  return $result;
126  }
127 
135  public function performUpdate(array &$dbQueries, &$customMessage): bool
136  {
137  $statements = $this->getDatabaseDefinition();
138  $result = $this->schemaMigrationService->install($statements, true);
139 
140  // Extract all statements stored in the keys, independent of error status
141  $dbQueries = array_merge($dbQueries, array_keys($result));
142 
143  // Only keep error messages
144  $result = array_filter($result);
145 
146  $customMessage = implode(
147  LF,
148  array_map(
149  function (string $message) {
150  return 'SQL-ERROR: ' . htmlspecialchars($message);
151  },
152  $result
153  )
154  );
155 
156  return empty($result);
157  }
158 
165  protected function getAddedTableInformation(SchemaDiff $schemaDiff): string
166  {
167  $items = array_map(
168  function (Table $table) {
169  return $this->renderTableListItem($table->getName());
170  },
171  $schemaDiff->newTables
172  );
173 
174  return trim(implode(LF, $items));
175  }
176 
183  protected function getAddedFieldInformation(SchemaDiff $schemaDiff): string
184  {
185  $items = [];
186 
187  foreach ($schemaDiff->changedTables as $changedTable) {
188  $columns = array_map(
189  function (Column $column) use ($changedTable) {
190  return $this->renderFieldListItem($changedTable->name, $column->getName());
191  },
192  $changedTable->addedColumns
193  );
194 
195  $items[] = implode(LF, $columns);
196  }
197 
198  return trim(implode(LF, $items));
199  }
200 
207  protected function getAddedIndexInformation(SchemaDiff $schemaDiff): string
208  {
209  $items = [];
210 
211  foreach ($schemaDiff->changedTables as $changedTable) {
212  $indexes = array_map(
213  function (Index $index) use ($changedTable) {
214  return $this->renderFieldListItem($changedTable->name, $index->getName());
215  },
216  $changedTable->addedIndexes
217  );
218 
219  $items[] = implode(LF, $indexes);
220  }
221 
222  return trim(implode(LF, $items));
223  }
224 }