-
Notifications
You must be signed in to change notification settings - Fork 177
/
Copy pathConvert_LorisMenuID_to_ModuleID.php
159 lines (143 loc) · 5.32 KB
/
Convert_LorisMenuID_to_ModuleID.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<?php declare(strict_types=1);
/**
* This script is used to correctly establish a link betwen the `issues` table
* used by the Issue Tracker module and the new table `modules`.
* It outputs SQL statements necessary to upgrade this table from LORIS version
* 22 to version 23.
* It relies on the existence of the `LorisMenu` table and the `modules` table
* so it must be used in the following way:
*
* 1. A user must apply the patch file:
* SQL/New_patches/2019-12-05-AddModuleTable.sql
* 2. The user runs this script
* 3. The user executes the commands it generates
* 4. Proceed with the release as normal.
*/
require_once __DIR__ . '/../generic_includes.php';
$sqlPatch = realpath(
__DIR__ . '/../../SQL/New_patches/2019-12-05-AddModuleTable.sql'
);
$cleanupPatch = realpath(
__DIR__ . '/../../SQL/New_patches/2020-02-28-foreign_key_issues_modules.sql'
);
$confirm = false;
if (isset($argv[1]) && $argv[1] === "confirm") {
$confirm = true;
}
// Create a mapping of IDs and Names from the LorisMenu table.
// This array is indexed by the NAME.
$result = $DB->pselect('SELECT ID,Name FROM modules', []);
if (empty($result)) {
throw new \DatabaseException(
'Could not load data from the `modules` table. Please make sure you '
. "have applied the patch file $sqlPatch"
);
}
$modulesTableMapping = [];
foreach ($result as $row) {
// Non-alphabetical characters are removed from the module name. The LorisMenu
// table adds forward-slashes at the end of its values making comparison more
// difficult without this step.
$modulesTableMapping[filterNonAlpha($row['Name'])] = $row['ID'];
}
unset($result);
// Create a mapping of IDs and Links from the LorisMenu table.
// This array is indexed by the ID.
$result = $DB->pselect(
'SELECT ID,Link,Parent FROM LorisMenu WHERE Parent IS NOT NULL',
[]
);
$menuTableMapping = [];
foreach ($result as $row) {
$menuTableMapping[$row['ID']] = filterNonAlpha($row['Link']);
}
unset($result);
// Use mapping arrays to replace old `LorisMenu` ID values in issue_tracker
// `module` column with new `modules` table ID values.
$result = $DB->pselect(
'SELECT issueID,module FROM issues WHERE module IS NOT NULL',
[]
);
$issueTrackerMapping = [];
foreach ($result as $row) {
$issueTrackerMapping[$row['issueID']] = $row['module'];
}
unset($result);
$correctMapping = [];
$incorrectMapping = [];
foreach ($issueTrackerMapping as $issueID => $menuTableID) {
// Using the menuTableID, look up the corresponding module name from the
// `LorisMenu` table.
// Using the module name, look up the new ID in the `modules` table.
if (!array_key_exists($menuTableID, $menuTableMapping)) {
echo "[!] Issue ID: $issueID. Could not find key `$menuTableID` in ".
"LorisMenu mapping array\n";
$incorrectMapping[] =$issueID;
continue;
}
if (!array_key_exists($menuTableMapping[$menuTableID], $modulesTableMapping)) {
echo "[!] Issue ID: $issueID. Could not find key ".
"`$menuTableMapping[$menuTableID]` in modules mapping array\n";
$incorrectMapping[] =$issueID;
continue;
}
$correctMapping[$issueID]
= $modulesTableMapping[$menuTableMapping[$menuTableID]];
}
// Now we have an array of issue IDs mapped to the IDs in the `module` table
// matched based on the name of modules. This should fix the problem.
$patch = [];
foreach ($correctMapping as $issueID => $modulesTableID) {
$result = $DB->pselect(
"SELECT i.issueID,lm.Link as module FROM LorisMenu lm
INNER JOIN issues i ON (i.module=lm.ID AND i.issueID=:id)",
['id' => $issueID]
);
$idBefore = $result[0]['issueID'];
$moduleBefore = $result[0]['module'];
$moduleAfter = $DB->pselectOne(
'SELECT name FROM modules WHERE ID=:id',
['id' => $modulesTableID]
);
echo sprintf(
"Issue ID: %s. Module before (`LorisMenu`): `%s`. Module after "
. "(`modules`): `%s`\n",
$idBefore,
$moduleBefore,
$moduleAfter
);
$patch[$issueID] = $modulesTableID;
}
if ($confirm) {
foreach ($patch as $issueID=>$modulesTableID) {
$DB->update('issues', ['module'=>$modulesTableID], ['issueID'=>$issueID]);
}
foreach ($incorrectMapping as $issueID) {
$DB->update('issues', ['module'=>null], ['issueID'=>$issueID]);
}
echo "Done. Make sure to run the clean-up patch $cleanupPatch to complete ".
"the process\n";
} else {
foreach ($patch as $issueID=>$modulesTableID) {
echo "UPDATE `issues` SET module=$modulesTableID WHERE issueID=$issueID;\n";
}
foreach ($incorrectMapping as $issueID) {
echo "UPDATE `issues` SET module=NULL WHERE issueID=$issueID;\n";
}
echo "ALTER TABLE `issues` ADD FOREIGN KEY (module) REFERENCES modules(ID);\n\n";
echo "Run this tool again with the argument 'confirm' to ".
"perform the changes.\n".
"Note: The module field for issues for which a mapping between LorisMenu and
modules can not be found will be nullified.\n\n";
}
/**
* Removes non-alphabetical characters from a string.
*
* @param string $value The string to modify
*
* @return string $value with non-alpha characters removed.
*/
function filterNonAlpha(string $value): string
{
return preg_replace('/[^a-z]/i', '', $value);
}