1<?php
2
3/*
4 * This file is part of the TYPO3 CMS project.
5 *
6 * It is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License, either version 2
8 * of the License, or any later version.
9 *
10 * For the full copyright and license information, please read the
11 * LICENSE.txt file that was distributed with this source code.
12 *
13 * The TYPO3 project - inspiring people to share!
14 */
15
16namespace TYPO3\CMS\Install\Updates;
17
18use TYPO3\CMS\Core\Database\ConnectionPool;
19use TYPO3\CMS\Core\Database\Schema\SchemaMigrator;
20use TYPO3\CMS\Core\Database\Schema\SqlReader;
21use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
22use TYPO3\CMS\Core\Utility\GeneralUtility;
23
24/**
25 * Contains the update class for filling the basic repository record of the extension manager
26 *
27 * @internal This class is only meant to be used within EXT:install and is not part of the TYPO3 Core API.
28 */
29class ExtensionManagerTables implements UpgradeWizardInterface, RepeatableInterface
30{
31    /**
32     * @return string Unique identifier of this updater
33     */
34    public function getIdentifier(): string
35    {
36        return 'extensionManagerTables';
37    }
38
39    /**
40     * @return string Title of this updater
41     */
42    public function getTitle(): string
43    {
44        return 'Add the default Extension Manager database tables';
45    }
46
47    /**
48     * @return string Longer description of this updater
49     */
50    public function getDescription(): string
51    {
52        return 'Creates necessary database tables and adds static data for the Extension Manager.';
53    }
54
55    /**
56     * Checks if an update is needed
57     *
58     * @return bool Whether an update is needed (TRUE) or not (FALSE)
59     */
60    public function updateNecessary(): bool
61    {
62        $result = false;
63        // First check necessary database update
64        $updateStatements = array_filter($this->getUpdateStatements());
65        if (count($updateStatements) === 0) {
66            // Get count of rows in repository database table
67            $count = GeneralUtility::makeInstance(ConnectionPool::class)
68                ->getConnectionForTable('tx_extensionmanager_domain_model_repository')
69                ->count('*', 'tx_extensionmanager_domain_model_repository', []);
70
71            if ($count === 0) {
72                $result = true;
73            }
74        } else {
75            $result = true;
76        }
77        return $result;
78    }
79
80    /**
81     * @return string[] All new fields and tables must exist
82     */
83    public function getPrerequisites(): array
84    {
85        return [
86            DatabaseUpdatedPrerequisite::class
87        ];
88    }
89
90    /**
91     * Performs the database update.
92     *
93     * @return bool Whether it worked (TRUE) or not (FALSE)
94     */
95    public function executeUpdate(): bool
96    {
97        $result = true;
98
99        $sqlReader = GeneralUtility::makeInstance(SqlReader::class);
100        $createTableStatements = $this->getTableStatements();
101
102        // First perform all create, add and change queries
103        $schemaMigrationService = GeneralUtility::makeInstance(SchemaMigrator::class);
104        $schemaMigrationService->install($createTableStatements);
105
106        // Perform import of static data
107        $rawDefinitions = file_get_contents(
108            ExtensionManagementUtility::extPath('extensionmanager', 'ext_tables_static+adt.sql')
109        );
110
111        $insertStatements = $sqlReader->getInsertStatementArray($rawDefinitions);
112        $schemaMigrationService->importStaticData($insertStatements);
113
114        return $result;
115    }
116
117    /**
118     * Gets all create, add and change queries from ext_tables.sql
119     *
120     * @return array
121     */
122    protected function getUpdateStatements()
123    {
124        $updateStatements = [];
125        $emTableStatements = $this->getTableStatements();
126        if (count($emTableStatements)) {
127            $schemaMigrationService = GeneralUtility::makeInstance(SchemaMigrator::class);
128            $updateSuggestions = $schemaMigrationService->getUpdateSuggestions($emTableStatements);
129            $updateStatements = array_merge_recursive(...array_values($updateSuggestions));
130        }
131        return $updateStatements;
132    }
133
134    /**
135     * Get all CREATE TABLE statements from the ext_tables.sql file
136     *
137     * @return string[]
138     */
139    protected function getTableStatements(): array
140    {
141        $rawDefinitions = file_get_contents(ExtensionManagementUtility::extPath('extensionmanager', 'ext_tables.sql'));
142        $sqlReader = GeneralUtility::makeInstance(SqlReader::class);
143        return $sqlReader->getCreateTableStatementArray($rawDefinitions);
144    }
145}
146