Passed
Pull Request — master (#198)
by Daniel
05:44
created

Setup::schema()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 37
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 0 Features 0
Metric Value
cc 6
eloc 20
c 8
b 0
f 0
nc 10
nop 1
dl 0
loc 37
rs 8.9777
1
<?php
2
3
/**
4
 * @license GPLv3, http://www.gnu.org/copyleft/gpl.html
5
 * @copyright Aimeos (aimeos.org), 2014-2016
6
 * @package TYPO3
7
 */
8
9
10
namespace Aimeos\Aimeos;
11
12
13
use \Symfony\Component\Console\Output\OutputInterface;
0 ignored issues
show
Bug introduced by
The type \Symfony\Component\Console\Output\OutputInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use \TYPO3\CMS\Core\Package\Event\AfterPackageActivationEvent;
0 ignored issues
show
Bug introduced by
The type \TYPO3\CMS\Core\Package\...rPackageActivationEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use \TYPO3\CMS\Core\Database\Event\AlterTableDefinitionStatementsEvent;
0 ignored issues
show
Bug introduced by
The type \TYPO3\CMS\Core\Database...finitionStatementsEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use \TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
0 ignored issues
show
Bug introduced by
The type \TYPO3\CMS\Install\Updates\UpgradeWizardInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use \TYPO3\CMS\Install\Updates\RepeatableInterface;
0 ignored issues
show
Bug introduced by
The type \TYPO3\CMS\Install\Updates\RepeatableInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use \TYPO3\CMS\Install\Updates\ChattyInterface;
0 ignored issues
show
Bug introduced by
The type \TYPO3\CMS\Install\Updates\ChattyInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use \TYPO3\CMS\Core\Utility\GeneralUtility;
0 ignored issues
show
Bug introduced by
The type \TYPO3\CMS\Core\Utility\GeneralUtility was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
21
22
/**
23
 * Aimeos setup class.
24
 *
25
 * @package TYPO3
26
 */
27
class Setup implements UpgradeWizardInterface, RepeatableInterface, ChattyInterface
28
{
29
    private $output;
30
31
32
    /**
33
     * Return the identifier for this wizard
34
     * This should be the same string as used in the ext_localconf class registration
35
     *
36
     * @return string
37
     */
38
    public function getIdentifier() : string
39
    {
40
      return 'aimeos';
41
    }
42
43
44
    /**
45
     * Return the speaking name of this wizard
46
     *
47
     * @return string
48
     */
49
    public function getTitle() : string
50
    {
51
      return 'Aimeos database migration';
52
    }
53
54
55
    /**
56
     * Return the description for this wizard
57
     *
58
     * @return string
59
     */
60
    public function getDescription() : string
61
    {
62
      return 'Updates the Aimeos database tables and migrates data if necessary';
63
    }
64
65
66
    /**
67
     * Execute the update
68
     *
69
     * @return bool
70
     */
71
    public function executeUpdate() : bool
72
    {
73
        try {
74
            ob_start();
75
            $exectimeStart = microtime(true);
76
77
            self::execute();
78
79
            $this->output->writeln(ob_get_clean());
80
            $this->output->writeln(sprintf('Setup process lasted %1$f sec', (microtime(true) - $exectimeStart)));
81
        } catch(\Throwable $t) {
82
            $this->output->writeln(ob_get_clean());
83
            $this->output->writeln($t->getMessage());
84
            $this->output->writeln($t->getTraceAsString());
85
86
            return false;
87
        }
88
89
        return true;
90
    }
91
92
93
    /**
94
     * Returns the classes the upgrade wizard depends on
95
     *
96
     * @return string[]
97
     */
98
    public function getPrerequisites() : array
99
    {
100
        return [];
101
    }
102
103
104
    /**
105
     * Setter injection for output into upgrade wizards
106
     *
107
     * @param OutputInterface $output
108
     */
109
    public function setOutput(OutputInterface $output) : void
110
    {
111
        $this->output = $output;
112
    }
113
114
115
    /**
116
     * Checks if  update is necessary
117
     *
118
     * @return bool Whether an update is required (TRUE) or not (FALSE)
119
     */
120
    public function updateNecessary() : bool
121
    {
122
        return true;
123
    }
124
125
126
    /**
127
     * Executes the setup tasks for updating the database.
128
     */
129
    public static function execute()
130
    {
131
        ini_set('max_execution_time', 0);
132
133
        $objectManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Extbase\Object\ObjectManager was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
134
        $extconf = $objectManager->get('TYPO3\CMS\Core\Configuration\ExtensionConfiguration');
135
        $demo = $extconf->get('aimeos', 'useDemoData');
136
137
        \Aimeos\MShop::cache(false);
138
        \Aimeos\MAdmin::cache(false);
139
140
        $site = \Aimeos\Aimeos\Base::getExtConfig('siteCode', 'default');
141
        $template = \Aimeos\Aimeos\Base::getExtConfig('siteTpl', 'default');
142
143
        $boostrap = \Aimeos\Aimeos\Base::aimeos();
144
        $ctx = self::context(['setup' => ['default' => ['demo' => (string) $demo]]])->setEditor('setup');
145
146
        \Aimeos\Setup::use($boostrap)->verbose('vvv')
147
            ->context($ctx->setEditor('aimeos:setup'))
148
            ->up($site, $template);
149
150
        if (defined('TYPO3_version') && version_compare(constant('TYPO3_version'), '11.0.0', '<')) {
151
            $extconf->set('aimeos', 'useDemoData', '');
152
        } else {
153
            $extconf->set('aimeos', ['useDemoData' => '']);
154
        }
155
    }
156
157
158
    /**
159
     * Returns the current schema for the install tool
160
     *
161
     * @param array $sql List of SQL statements
162
     * @return array SQL statements required for the install tool
163
     */
164
    public static function schema(array $sql) : array
165
    {
166
        $ctx = self::getContext();
167
        $dbm = $ctx->getDatabaseManager();
168
        $connectionNames = array_keys($ctx->getConfig()->get( 'resource'));
169
        $connectionNames = array_filter($connectionNames, fn (string $key): bool => str_starts_with($key, 'db'));
170
171
        foreach ($connectionNames as $connectionName) {
172
            $conn = $dbm->acquire($connectionName);
173
174
            $tables = [];
175
176
            foreach(['fe_users_', 'madmin_', 'mshop_'] as $prefix) {
177
                $result = $conn->create('SHOW TABLES like \'' . $prefix . '%\'')->execute();
178
179
                while(($row = $result->fetch(\Aimeos\Base\DB\Result\Base::FETCH_NUM)) !== null) {
180
                    $tables[] = $row[0];
181
                }
182
            }
183
184
            foreach($tables as $table) {
185
                $result = $conn->create('SHOW CREATE TABLE `' . $table . '`')->execute();
186
187
                while(($row = $result->fetch(\Aimeos\Base\DB\Result\Base::FETCH_NUM)) !== null) {
188
                    $str = $row[1];
189
190
                    $str = str_replace('"', '`', $str);
191
                    $str = preg_replace('#CONSTRAINT `[a-zA-Z0-9_-]+` #', '', $str);
192
193
                    $sql[] = $str . ";\n";
194
                }
195
            }
196
197
            $dbm->release($conn);
198
        }
199
200
        return ['sqlString' => $sql];
201
    }
202
203
204
    /**
205
     * For existing installations
206
     *
207
     * @param string|null $extname Installed extension name
208
     */
209
    public static function executeOnSignal(string $extname = null)
210
    {
211
        self::signal($extname);
212
    }
213
214
215
    /**
216
     * Update schema if extension is installed
217
     *
218
     * @param string|null $extname Installed extension name
219
     */
220
    public static function signal(string $extname = null)
221
    {
222
        if ($extname === 'aimeos' && \Aimeos\Aimeos\Base::getExtConfig('autoSetup', true)) {
223
            self::execute();
224
        }
225
    }
226
227
228
    /**
229
     * Alter schema to avoid TYPO3 dropping Aimeos tables
230
     *
231
     * @param AlterTableDefinitionStatementsEvent $event Event object
232
     */
233
    public function schemaEvent(AlterTableDefinitionStatementsEvent $event)
234
    {
235
        $list = self::schema([]);
236
237
        foreach ($list['sqlString'] ?? [] as $sql) {
238
            $event->addSqlData($sql);
239
        }
240
    }
241
242
243
    /**
244
     * Update schema if extension is installed
245
     *
246
     * @param AfterPackageActivationEvent $event Event object
247
     */
248
    public function setupEvent(AfterPackageActivationEvent $event)
249
    {
250
        if ($event->getPackageKey() === 'aimeos' && \Aimeos\Aimeos\Base::getExtConfig('autoSetup', true)) {
251
            self::execute();
252
        }
253
    }
254
255
256
    /**
257
     * Returns a new context object.
258
     *
259
     * @param array $config Nested array of configuration settings
260
     * @return \Aimeos\MShop\ContextIface Context object
261
     */
262
    protected static function context(array $config = []) : \Aimeos\MShop\ContextIface
263
    {
264
        $aimeosExtPath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('aimeos');
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Core\Utility\ExtensionManagementUtility was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
265
266
        if (file_exists($aimeosExtPath . '/Resources/Libraries/autoload.php') === true) {
267
            require_once $aimeosExtPath . '/Resources/Libraries/autoload.php';
268
        }
269
270
        $ctx = new \Aimeos\MShop\Context();
271
        $conf = \Aimeos\Aimeos\Base::config($config);
272
273
        $ctx->setConfig($conf);
274
        $ctx->setDatabaseManager(new \Aimeos\Base\DB\Manager\Standard($conf->get('resource', []), 'DBAL'));
275
        $ctx->setFilesystemManager(new \Aimeos\Base\Filesystem\Manager\Standard($conf->get('resource', [])));
276
        $ctx->setLogger(new \Aimeos\Base\Logger\Errorlog(\Aimeos\Base\Logger\Iface::INFO));
277
        $ctx->setSession(new \Aimeos\Base\Session\None());
278
        $ctx->setCache(new \Aimeos\Base\Cache\None());
279
280
        // Reset before child processes are spawned to avoid lost DB connections afterwards (TYPO3 9.4 and above)
281
        if (php_sapi_name() === 'cli' && class_exists('\TYPO3\CMS\Core\Database\ConnectionPool')
282
            && method_exists('\TYPO3\CMS\Core\Database\ConnectionPool', 'resetConnections')
283
        ) {
284
            $ctx->setProcess(new \Aimeos\Base\Process\Pcntl(\Aimeos\Aimeos\Base::getExtConfig('pcntlMax', 4)));
285
        } else {
286
            $ctx->setProcess(new \Aimeos\Base\Process\None());
287
        }
288
289
        $factory = GeneralUtility::makeInstance('TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory');
290
        return $ctx->setPassword(new \Aimeos\Base\Password\Typo3($factory->getDefaultHashInstance('FE')));
291
    }
292
}
293