Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
64.00% covered (warning)
64.00%
32 / 50
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Migration400Alpha3
64.00% covered (warning)
64.00%
32 / 50
75.00% covered (warning)
75.00%
3 / 4
10.99
0.00% covered (danger)
0.00%
0 / 1
 getVersion
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDependencies
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDescription
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 up
61.70% covered (warning)
61.70%
29 / 47
0.00% covered (danger)
0.00%
0 / 1
6.40
1<?php
2
3/**
4 * Migration for phpMyFAQ 4.0.0-alpha.3.
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public License,
7 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
8 * obtain one at https://mozilla.org/MPL/2.0/.
9 *
10 * @package   phpMyFAQ
11 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
12 * @copyright 2023-2026 phpMyFAQ Team
13 * @license   https://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
14 * @link      https://www.phpmyfaq.de
15 * @since     2026-01-25
16 */
17
18declare(strict_types=1);
19
20namespace phpMyFAQ\Setup\Migration\Versions;
21
22use phpMyFAQ\Setup\Migration\AbstractMigration;
23use phpMyFAQ\Setup\Migration\Operations\OperationRecorder;
24
25readonly class Migration400Alpha3 extends AbstractMigration
26{
27    public function getVersion(): string
28    {
29        return '4.0.0-alpha.3';
30    }
31
32    public function getDependencies(): array
33    {
34        return ['4.0.0-alpha.2'];
35    }
36
37    public function getDescription(): string
38    {
39        return 'SEO table, media hosts config, layout settings, rich snippets';
40    }
41
42    public function up(OperationRecorder $recorder): void
43    {
44        // Create SEO table
45        if ($this->isMySql()) {
46            $recorder->addSql(sprintf(
47                'CREATE TABLE %sfaqseo (
48                    id INT(11) NOT NULL,
49                    type VARCHAR(32) NOT NULL,
50                    reference_id INT(11) NOT NULL,
51                    reference_language VARCHAR(5) NOT NULL,
52                    title TEXT DEFAULT NULL,
53                    description TEXT DEFAULT NULL,
54                    slug TEXT DEFAULT NULL,
55                    created DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
56                    PRIMARY KEY (id)) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB',
57                $this->tablePrefix,
58            ), 'Create SEO table (MySQL)');
59            return;
60        }
61
62        if ($this->isSqlServer()) {
63            $recorder->addSql(sprintf(
64                'CREATE TABLE %sfaqseo (
65                    id INT NOT NULL,
66                    type VARCHAR(32) NOT NULL,
67                    reference_id INT NOT NULL,
68                    reference_language VARCHAR(5) NOT NULL,
69                    title TEXT NULL,
70                    description TEXT NULL,
71                    slug TEXT NULL,
72                    created DATETIME NOT NULL DEFAULT GETDATE(),
73                    PRIMARY KEY (id))',
74                $this->tablePrefix,
75            ), 'Create SEO table (SQL Server)');
76            return;
77        }
78
79        if ($this->isSqlite()) {
80            $recorder->addSql(sprintf(
81                'CREATE TABLE %sfaqseo (
82                    id INT NOT NULL,
83                    type VARCHAR(32) NOT NULL,
84                    reference_id INT NOT NULL,
85                    reference_language VARCHAR(5) NOT NULL,
86                    title TEXT NULL,
87                    description TEXT NULL,
88                    slug TEXT NULL,
89                    created DATETIME NOT NULL DEFAULT (datetime(\'now\')),
90                    PRIMARY KEY (id))',
91                $this->tablePrefix,
92            ), 'Create SEO table (SQLite)');
93            return;
94        }
95
96        if ($this->isPostgreSql()) {
97            $recorder->addSql(sprintf(
98                'CREATE TABLE %sfaqseo (
99                    id INTEGER NOT NULL,
100                    type VARCHAR(32) NOT NULL,
101                    reference_id INTEGER NOT NULL,
102                    reference_language VARCHAR(5) NOT NULL,
103                    title TEXT,
104                    description TEXT,
105                    slug TEXT NULL,
106                    created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
107                    PRIMARY KEY (id))',
108                $this->tablePrefix,
109            ), 'Create SEO table (PostgreSQL)');
110        }
111
112        // Update bot ignore list
113        $recorder->updateConfig(
114            'main.botIgnoreList',
115            'nustcrape,webpost,GoogleBot,msnbot,crawler,scooter,bravobrian,archiver,'
116            . 'w3c,controler,wget,bot,spider,Yahoo! Slurp,htdig,gsa-crawler,AirControler,Uptime-Kuma,facebookcatalog/1.0,'
117            . 'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php),facebookexternalhit/1.1',
118        );
119
120        // New configuration items
121        $recorder->addConfig('mail.noReplySenderAddress', '');
122        $recorder->addConfig('records.allowedMediaHosts', 'www.youtube.com');
123        $recorder->addConfig('seo.title', '');
124        $recorder->addConfig('seo.description', '');
125        $recorder->addConfig('layout.enablePrivacyLink', 'true');
126        $recorder->addConfig('layout.customCss', '');
127        $recorder->addConfig('seo.enableRichSnippets', 'false');
128
129        // Delete old config items
130        $recorder->deleteConfig('main.urlValidateInterval');
131        $recorder->deleteConfig('main.enableGzipCompression');
132        $recorder->deleteConfig('main.metaKeywords');
133        $recorder->deleteConfig('main.send2friendText');
134
135        // Rename config items
136        $recorder->renameConfig('main.templateSet', 'layout.templateSet');
137        $recorder->renameConfig('main.enableCookieConsent', 'layout.enableCookieConsent');
138        $recorder->renameConfig('main.contactInformationHTML', 'layout.contactInformationHTML');
139    }
140}