|
1 | 1 | <?php |
2 | | - |
3 | 2 | // This file is part of Moodle - http://moodle.org/ |
4 | 3 | // |
5 | 4 | // Moodle is free software: you can redistribute it and/or modify |
|
46 | 45 |
|
47 | 46 | $contents = file_get_contents($file); |
48 | 47 |
|
49 | | - $function_regexp = '\s*function\s+xmldb_[a-zA-Z0-9_]+?_upgrade\s*\(.*?version.*?\)(?::\sbool)?\s*(?=\{)'; |
50 | | - $return_regexp = '\s*return true;'; |
51 | | - $anyfunction_regexp = '\s*function\s*[a-z0-9_]+?\s*\(.*?\)\s*{'; // MDL-34103 |
| 48 | + $functionregexp = '\s*function\s+xmldb_[a-zA-Z0-9_]+?_upgrade\s*\(.*?version.*?\)(?::\sbool)?\s*(?=\{)'; |
| 49 | + $returnregexp = '\s*return true;'; |
| 50 | + $anyfunctionregexp = '\s*function\s*[a-z0-9_]+?\s*\(.*?\)\s*{'; // MDL-34103 |
52 | 51 |
|
53 | | -/// Find we have some xmldb_xxxx_function in code |
54 | | - if (! $countxmldb = preg_match_all('@' . $function_regexp . '@is', $contents, $matches)) { |
| 52 | + // Find we have some xmldb_xxxx_function in code |
| 53 | + if (! $countxmldb = preg_match_all('@' . $functionregexp . '@is', $contents, $matches)) { |
55 | 54 | echo " + ERROR: upgrade function not found" . LINEFEED; |
56 | 55 | continue; |
57 | 56 | } |
58 | | -/// Verify there is only one upgrade function |
| 57 | + // Verify there is only one upgrade function |
59 | 58 | if ($countxmldb !== 1) { |
60 | 59 | echo " + ERROR: multiple upgrade functions detected" . LINEFEED; |
61 | 60 | continue; |
62 | 61 | } |
63 | 62 |
|
64 | 63 | // Find we have some return true; in code |
65 | | - if (! $countreturn = preg_match_all('@' . $return_regexp . '@is', $contents, $matches)) { |
| 64 | + if (! $countreturn = preg_match_all('@' . $returnregexp . '@is', $contents, $matches)) { |
66 | 65 | echo " + ERROR: 'return true;' not found" . LINEFEED; |
67 | 66 | continue; |
68 | 67 | } |
|
88 | 87 | // In any case, all the replacements performed are stored in $discardedliterals just in case |
89 | 88 | // something needs to be recovered back. |
90 | 89 | $regexp = '(["\'])(?:\\\\\1|.)*?\1'; // Match all quoted literals in a text, ignoring escaped ones. |
91 | | - $discardedliterals = array(); |
| 90 | + $discardedliterals = []; |
92 | 91 | // Look for all quoted strings. |
93 | 92 | preg_match_all('@' . $regexp . '@', $contents, $matches); |
94 | 93 | // Iterate them, keeping safe ones and replacing by placeholder conflictive ones. |
|
97 | 96 | $unsaferegexp = '[\[\(\{\<\>\}\)\]]'; // Consider everything but [({<>})] safe. |
98 | 97 | if (preg_match('@' . $unsaferegexp . '@', $string)) { |
99 | 98 | // The string is not safe, replace it by placeholder and annotate the replacement. |
100 | | - $replacement = "'<%&%" . (string)(count($discardedliterals) +1) . "%&%>'"; |
| 99 | + $replacement = "'<%&%" . (string)(count($discardedliterals) + 1) . "%&%>'"; |
101 | 100 | $discardedliterals[$replacement] = $string; |
102 | 101 | } else { |
103 | 102 | // The string is safe, keep it as is, no need to replace it by placeholder. |
|
108 | 107 | $contents = str_replace($discardedliterals, array_keys($discardedliterals), $contents); |
109 | 108 | } |
110 | 109 |
|
111 | | -/// Arrived here, extract function contents |
112 | | - if (! preg_match_all('@' . $function_regexp . '.*?(\{(?>(?>[^{}]+)|(?1))*\})@is', $contents, $matches)) { |
| 110 | + // Arrived here, extract function contents |
| 111 | + if (! preg_match_all('@' . $functionregexp . '.*?(\{(?>(?>[^{}]+)|(?1))*\})@is', $contents, $matches)) { |
113 | 112 | echo " + NOTE: cannot find upgrade function contents" . LINEFEED; |
114 | 113 | continue; |
115 | 114 | } |
116 | 115 |
|
117 | | -/// Calculate function contents (must be a group of "if" blocks) |
| 116 | + // Calculate function contents (must be a group of "if" blocks) |
118 | 117 | $contents = trim(trim($matches[1][0], '}{')); |
119 | 118 |
|
120 | | - $if_regexp = 'if\s+?\(\s*?\$oldversion\s*?<\s*?([0-9.]{8,13}).*?\)\s*?'; |
121 | | - $sp_regexp = 'upgrade_(main|mod|block|plugin)_savepoint\s*?\(\s*?true\s*?,\s*?([0-9.]{8,13})\s*?.*?\);'; |
| 119 | + $ifregexp = 'if\s+?\(\s*?\$oldversion\s*?<\s*?([0-9.]{8,13}).*?\)\s*?'; |
| 120 | + $spregexp = 'upgrade_(main|mod|block|plugin)_savepoint\s*?\(\s*?true\s*?,\s*?([0-9.]{8,13})\s*?.*?\);'; |
122 | 121 |
|
123 | | -/// Count ifs and savepoints. Must match |
124 | | - $count_if = preg_match_all('@' . $if_regexp . '@is', $contents, $matches1); |
125 | | - $count_sp = preg_match_all('@' . $sp_regexp . '@is', $contents, $matches2); |
126 | | - if ($count_if > 0 || $count_sp > 0) { |
127 | | - if ($count_if !== $count_sp) { |
128 | | - if ($count_if < $count_sp) { |
129 | | - echo " + WARN: Detected fewer 'if' blocks ($count_if) than 'savepoint' calls ($count_sp). Repeated savepoints?" . LINEFEED; |
| 122 | + // Count ifs and savepoints. Must match |
| 123 | + $countif = preg_match_all('@' . $ifregexp . '@is', $contents, $matches1); |
| 124 | + $countsp = preg_match_all('@' . $spregexp . '@is', $contents, $matches2); |
| 125 | + if ($countif > 0 || $countsp > 0) { |
| 126 | + if ($countif !== $countsp) { |
| 127 | + if ($countif < $countsp) { |
| 128 | + echo " + WARN: Detected fewer 'if' blocks ($countif) than 'savepoint' calls ($countsp). Repeated savepoints?" . LINEFEED; |
130 | 129 | } else { |
131 | | - echo " + ERROR: Detected more 'if' blocks ($count_if) than 'savepoint' calls ($count_sp)" . LINEFEED; |
| 130 | + echo " + ERROR: Detected more 'if' blocks ($countif) than 'savepoint' calls ($countsp)" . LINEFEED; |
132 | 131 | } |
133 | 132 | } else { |
134 | | - echo " + found $count_if matching 'if' blocks and 'savepoint' calls" . LINEFEED; |
| 133 | + echo " + found $countif matching 'if' blocks and 'savepoint' calls" . LINEFEED; |
135 | 134 | } |
136 | 135 | } |
137 | 136 |
|
138 | | -/// Let's ensure there are no duplicate calls to a save point with the same version. |
139 | | - if ($count_sp > 0) { |
| 137 | + // Let's ensure there are no duplicate calls to a save point with the same version. |
| 138 | + if ($countsp > 0) { |
140 | 139 | foreach (array_count_values($matches2[2]) as $version => $count) { |
141 | 140 | if ($count > 1) { |
142 | | - echo " + ERROR: Detected multiple 'savepoint' calls for version $version".LINEFEED; |
| 141 | + echo " + ERROR: Detected multiple 'savepoint' calls for version $version" . LINEFEED; |
143 | 142 | } |
144 | 143 | } |
145 | 144 | } |
146 | 145 |
|
147 | | -/// Let's split them |
148 | | - if (!preg_match_all('@(' . $if_regexp . '(\{(?>(?>[^{}]+)|(?3))*\}))@is', $contents, $matches)) { |
| 146 | + // Let's split them |
| 147 | + if (!preg_match_all('@(' . $ifregexp . '(\{(?>(?>[^{}]+)|(?3))*\}))@is', $contents, $matches)) { |
149 | 148 | echo " + NOTE: cannot find 'if' blocks within the upgrade function" . LINEFEED; |
150 | 149 | continue; |
151 | 150 | } |
152 | 151 |
|
153 | 152 | $versions = $matches[2]; |
154 | 153 | $blocks = $matches[3]; |
155 | 154 |
|
156 | | -/// Foreach version, check order |
157 | | - $version_p = 0; |
158 | | - $has_version_error = false; |
159 | | - foreach($versions as $version) { |
160 | | - if (!$version_p) { |
161 | | - $version_p = $version; |
| 155 | + // Foreach version, check order |
| 156 | + $versionp = 0; |
| 157 | + $hasversionerror = false; |
| 158 | + foreach ($versions as $version) { |
| 159 | + if (!$versionp) { |
| 160 | + $versionp = $version; |
162 | 161 | continue; |
163 | 162 | } |
164 | | - if (((float)$version * 100) < ((float)$version_p * 100)) { |
165 | | - echo " + ERROR: Wrong order in versions: $version_p and $version" . LINEFEED; |
166 | | - $has_version_error = true; |
| 163 | + if (((float)$version * 100) < ((float)$versionp * 100)) { |
| 164 | + echo " + ERROR: Wrong order in versions: $versionp and $version" . LINEFEED; |
| 165 | + $hasversionerror = true; |
167 | 166 | } |
168 | | - $version_p = $version; |
| 167 | + $versionp = $version; |
169 | 168 | } |
170 | | - if (!$has_version_error) { |
| 169 | + if (!$hasversionerror) { |
171 | 170 | echo " + versions in upgrade blocks properly ordered" . LINEFEED; |
172 | 171 | } |
173 | 172 |
|
174 | | -/// Foreach version, look for corresponding savepoint |
175 | | - $has_version_mismatch = false; |
| 173 | + // Foreach version, look for corresponding savepoint |
| 174 | + $hasversionmismatch = false; |
176 | 175 | foreach ($versions as $key => $version) { |
177 | | - $count_spv = preg_match_all('@' .$sp_regexp . '@is', $blocks[$key], $matches); |
178 | | - if ($count_spv == 0) { |
| 176 | + $countspv = preg_match_all('@' . $spregexp . '@is', $blocks[$key], $matches); |
| 177 | + if ($countspv == 0) { |
179 | 178 | echo " + ERROR: version $version is missing corresponding savepoint call" . LINEFEED; |
180 | | - $has_version_mismatch = true; |
181 | | - } else if ($count_spv > 1) { |
| 179 | + $hasversionmismatch = true; |
| 180 | + } else if ($countspv > 1) { |
182 | 181 | echo " + ERROR: version $version has more than one savepoint call" . LINEFEED; |
183 | | - $has_version_mismatch = true; |
| 182 | + $hasversionmismatch = true; |
184 | 183 | } else { |
185 | 184 | if ($version !== $matches[2][0]) { |
186 | 185 | echo " + ERROR: version $version has wrong savepoint call with version {$matches[2][0]}" . LINEFEED; |
187 | | - $has_version_mismatch = true; |
| 186 | + $hasversionmismatch = true; |
188 | 187 | } |
189 | 188 | } |
190 | 189 | } |
191 | | - if (!$has_version_mismatch) { |
| 190 | + if (!$hasversionmismatch) { |
192 | 191 | echo " + versions in savepoint calls properly matching upgrade blocks" . LINEFEED; |
193 | 192 | } |
194 | 193 |
|
195 | | -/// Ensure a plugin does not upgrade past its defined version. |
196 | | - $versionfile = dirname(dirname($file)).'/version.php'; |
| 194 | + // Ensure a plugin does not upgrade past its defined version. |
| 195 | + $versionfile = dirname(dirname($file)) . '/version.php'; |
197 | 196 | if (file_exists($versionfile)) { |
198 | 197 | if (preg_match('/^\s*\$(module|plugin)->version\s*=\s*([\d.]+)/m', file_get_contents($versionfile), $versionmatches) === 1) { |
199 | 198 | foreach ($versions as $version) { |
200 | 199 | if (((float) $versionmatches[2] * 100) < ((float) $version * 100)) { |
201 | | - echo " + ERROR: version $version is higher than that defined in $versionfile file".LINEFEED; |
| 200 | + echo " + ERROR: version $version is higher than that defined in $versionfile file" . LINEFEED; |
202 | 201 | } |
203 | 202 | } |
204 | 203 | } |
|
208 | 207 | /** |
209 | 208 | * Given one full path, return one array with all the files to check |
210 | 209 | */ |
211 | | - function files_to_check($path) { |
212 | | - |
213 | | - $results = array(); |
214 | | - $pending = array(); |
| 210 | +function files_to_check($path) { |
215 | 211 |
|
216 | | - $dir = opendir($path); |
217 | | - while (false !== ($file=readdir($dir))) { |
| 212 | + $results = []; |
| 213 | + $pending = []; |
218 | 214 |
|
219 | | - $fullpath = $path . '/' . $file; |
| 215 | + $dir = opendir($path); |
| 216 | + while (false !== ($file = readdir($dir))) { |
| 217 | + $fullpath = $path . '/' . $file; |
220 | 218 |
|
221 | | - if (substr($file, 0, 1)=='.' || $file=='CVS' || $file=='.git') { /// Exclude some dirs |
222 | | - continue; |
223 | | - } |
224 | | - |
225 | | - if (is_dir($fullpath)) { /// Process dirs later |
226 | | - $pending[] = $fullpath; |
227 | | - continue; |
228 | | - } |
| 219 | + if (substr($file, 0, 1) == '.' || $file == 'CVS' || $file == '.git') { // Exclude some dirs |
| 220 | + continue; |
| 221 | + } |
229 | 222 |
|
230 | | - if (is_file($fullpath) && strpos($file, basename(__FILE__))!==false) { /// Exclude me |
231 | | - continue; |
232 | | - } |
| 223 | + if (is_dir($fullpath)) { // Process dirs later |
| 224 | + $pending[] = $fullpath; |
| 225 | + continue; |
| 226 | + } |
233 | 227 |
|
234 | | - if (is_file($fullpath) && strpos($fullpath, 'db/upgrade.php')===false) { /// Exclude non upgrade.php files |
235 | | - continue; |
236 | | - } |
| 228 | + if (is_file($fullpath) && strpos($file, basename(__FILE__)) !== false) { // Exclude me |
| 229 | + continue; |
| 230 | + } |
237 | 231 |
|
238 | | - if (!in_array($fullpath, $results)) { /// Add file if doesn't exists |
239 | | - $results[$fullpath] = $fullpath; |
240 | | - } |
| 232 | + if (is_file($fullpath) && strpos($fullpath, 'db/upgrade.php') === false) { // Exclude non upgrade.php files |
| 233 | + continue; |
241 | 234 | } |
242 | | - closedir($dir); |
243 | 235 |
|
244 | | - foreach ($pending as $pend) { |
245 | | - $results = array_merge($results, files_to_check($pend)); |
| 236 | + if (!in_array($fullpath, $results)) { // Add file if doesn't exists |
| 237 | + $results[$fullpath] = $fullpath; |
246 | 238 | } |
| 239 | + } |
| 240 | + closedir($dir); |
247 | 241 |
|
248 | | - return $results; |
| 242 | + foreach ($pending as $pend) { |
| 243 | + $results = array_merge($results, files_to_check($pend)); |
249 | 244 | } |
250 | | -?> |
| 245 | + |
| 246 | + return $results; |
| 247 | +} |
0 commit comments