‪TYPO3CMS  ‪main
SchemaIndexDefinitionListener.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Doctrine\DBAL\Event\SchemaIndexDefinitionEventArgs;
21 use Doctrine\DBAL\Platforms\MySQLPlatform;
22 use Doctrine\DBAL\Schema\Index;
24 
30 {
39  public function ‪onSchemaIndexDefinition(SchemaIndexDefinitionEventArgs $event)
40  {
41  // Early return for non-MySQL-compatible platforms
42  if (!($event->getConnection()->getDatabasePlatform() instanceof MySQLPlatform)) {
43  return;
44  }
45 
46  $connection = $event->getConnection();
47  $indexName = $event->getTableIndex()['name'];
48  $sql = $event->getConnection()->getDatabasePlatform()->getListTableIndexesSQL(
49  $event->getTable(),
50  $event->getConnection()->getDatabase()
51  );
52 
53  // check whether ORDER BY is available in SQL
54  // and place the part 'AND INDEX_NAME = "SOME_INDEX_NAME"' before that
55  if (str_contains($sql, 'ORDER BY')) {
56  $posOfOrderBy = (int)strpos($sql, 'ORDER BY');
57  $tmpSql = substr($sql, 0, $posOfOrderBy);
58  $tmpSql .= ' AND ' . $connection->quoteIdentifier('INDEX_NAME') . ' = ' . $connection->quote($indexName);
59  $tmpSql .= ' ' . substr($sql, $posOfOrderBy);
60  $sql = $tmpSql;
61  unset($tmpSql);
62  } else {
63  $sql .= ' AND ' . $connection->quoteIdentifier('INDEX_NAME') . ' = ' . $connection->quote($indexName);
64  }
65 
66  $tableIndexes = $event->getConnection()->fetchAllAssociative($sql);
67 
68  $subPartColumns = array_filter(
69  $tableIndexes,
70  static function (array $column): ?int {
71  return $column['Sub_Part'];
72  }
73  );
74 
75  if (!empty($subPartColumns)) {
76  $event->setIndex($this->‪buildIndex($tableIndexes));
77  $event->preventDefault();
78  }
79  }
80 
87  protected function ‪buildIndex(array $tableIndexRows): Index
88  {
89  $data = null;
90  foreach ($tableIndexRows as $tableIndex) {
91  $tableIndex = array_change_key_case($tableIndex, CASE_LOWER);
92 
93  $tableIndex['primary'] = $tableIndex['key_name'] === 'PRIMARY';
94 
95  if (str_contains($tableIndex['index_type'], 'FULLTEXT')) {
96  $tableIndex['flags'] = ['FULLTEXT'];
97  } elseif (str_contains($tableIndex['index_type'], 'SPATIAL')) {
98  $tableIndex['flags'] = ['SPATIAL'];
99  }
100 
101  $indexName = $tableIndex['key_name'];
102  $columnName = $tableIndex['column_name'];
103 
104  if ($tableIndex['sub_part'] !== null) {
105  $columnName .= '(' . $tableIndex['sub_part'] . ')';
106  }
107 
108  if ($data === null) {
109  $data = [
110  'name' => $indexName,
111  'columns' => [$columnName],
112  'unique' => !$tableIndex['non_unique'],
113  'primary' => $tableIndex['primary'],
114  'flags' => $tableIndex['flags'] ?? [],
115  'options' => isset($tableIndex['where']) ? ['where' => $tableIndex['where']] : [],
116  ];
117  } else {
118  $data['columns'][] = $columnName;
119  }
120  }
121 
122  $index = GeneralUtility::makeInstance(
123  Index::class,
124  $data['name'],
125  $data['columns'],
126  $data['unique'],
127  $data['primary'],
128  $data['flags'],
129  $data['options']
130  );
131 
132  return $index;
133  }
134 }
‪TYPO3\CMS\Core\Database\Schema\EventListener\SchemaIndexDefinitionListener
Definition: SchemaIndexDefinitionListener.php:30
‪TYPO3\CMS\Core\Database\Schema\EventListener\SchemaIndexDefinitionListener\buildIndex
‪buildIndex(array $tableIndexRows)
Definition: SchemaIndexDefinitionListener.php:87
‪TYPO3\CMS\Core\Database\Schema\EventListener\SchemaIndexDefinitionListener\onSchemaIndexDefinition
‪onSchemaIndexDefinition(SchemaIndexDefinitionEventArgs $event)
Definition: SchemaIndexDefinitionListener.php:39
‪TYPO3\CMS\Core\Database\Schema\EventListener
Definition: SchemaAlterTableListener.php:18
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51