MDL-69973 xmldb: Ensure all reports use fresh metadata (not cached)
[moodle.git] / admin / tool / xmldb / actions / XMLDBCheckAction.class.php
CommitLineData
bd79ec56 1<?php
bd79ec56 2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
85d6dd38 18 * @package tool_xmldb
b007a5d0
PS
19 * @copyright 2008 onwards Tim Hunt
20 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
bd79ec56 21 */
22
23/**
24 * This is a base class for the various actions that interate over all the
25 * tables and check some aspect of their definition.
26 *
85d6dd38 27 * @package tool_xmldb
b007a5d0
PS
28 * @copyright 2008 onwards Tim Hunt
29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
bd79ec56 30 */
9f5e5dee 31abstract class XMLDBCheckAction extends XMLDBAction {
32 /**
d8bf2a14 33 * @var string This string is displayed with a yes/no choice before the report is run.
9f5e5dee 34 * You must set this to the name of a lang string in xmldb.php before calling init.
35 */
36 protected $introstr = '';
37
38 /**
39 * Init method, every subclass will have its own
40 */
41 function init() {
42 parent::init();
43
35c4f1e2 44 // Set own core attributes
9f5e5dee 45
35c4f1e2 46 // Set own custom attributes
9f5e5dee 47
35c4f1e2 48 // Get needed strings
9f5e5dee 49 $this->loadStrings(array(
b007a5d0 50 $this->introstr => 'tool_xmldb',
9f5e5dee 51 'ok' => '',
b007a5d0
PS
52 'wrong' => 'tool_xmldb',
53 'table' => 'tool_xmldb',
54 'field' => 'tool_xmldb',
55 'searchresults' => 'tool_xmldb',
56 'completelogbelow' => 'tool_xmldb',
9f5e5dee 57 'yes' => '',
58 'no' => '',
59 'error' => '',
b007a5d0 60 'back' => 'tool_xmldb'
9f5e5dee 61 ));
62 }
63
64 /**
65 * Invoke method, every class will have its own
66 * returns true/false on completion, setting both
67 * errormsg and output as necessary
68 */
69 function invoke() {
70 parent::invoke();
71
72 $result = true;
73
35c4f1e2 74 // Set own core attributes
9f5e5dee 75 $this->does_generate = ACTION_GENERATE_HTML;
76
35c4f1e2 77 // These are always here
8fbce1c8 78 global $CFG, $XMLDB, $DB, $OUTPUT;
9f5e5dee 79
35c4f1e2 80 // And we nedd some ddl suff
9f5e5dee 81 $dbman = $DB->get_manager();
82
35c4f1e2 83 // Here we'll acummulate all the wrong fields found
9f5e5dee 84 $problemsfound = array();
85
35c4f1e2 86 // Do the job, setting $result as needed
9f5e5dee 87
35c4f1e2 88 // Get the confirmed to decide what to do
9f5e5dee 89 $confirmed = optional_param('confirmed', false, PARAM_BOOL);
90
35c4f1e2 91 // If not confirmed, show confirmation box
9f5e5dee 92 if (!$confirmed) {
ac6efbaf 93 $o = '<table class="generaltable" border="0" cellpadding="5" cellspacing="0" id="notice">';
9f5e5dee 94 $o.= ' <tr><td class="generalboxcontent">';
95 $o.= ' <p class="centerpara">' . $this->str[$this->introstr] . '</p>';
96 $o.= ' <table class="boxaligncenter" cellpadding="20"><tr><td>';
97 $o.= ' <div class="singlebutton">';
f25d53a9 98 $o.= ' <form action="index.php?action=' . $this->title . '&amp;confirmed=yes&amp;sesskey=' . sesskey() . '" method="post"><fieldset class="invisiblefieldset">';
9f5e5dee 99 $o.= ' <input type="submit" value="'. $this->str['yes'] .'" /></fieldset></form></div>';
100 $o.= ' </td><td>';
101 $o.= ' <div class="singlebutton">';
102 $o.= ' <form action="index.php?action=main_view" method="post"><fieldset class="invisiblefieldset">';
103 $o.= ' <input type="submit" value="'. $this->str['no'] .'" /></fieldset></form></div>';
104 $o.= ' </td></tr>';
105 $o.= ' </table>';
106 $o.= ' </td></tr>';
107 $o.= '</table>';
108
109 $this->output = $o;
110 } else {
35c4f1e2 111 // The back to edit table button
9f5e5dee 112 $b = ' <p class="centerpara buttons">';
113 $b .= '<a href="index.php">[' . $this->str['back'] . ']</a>';
114 $b .= '</p>';
115
35c4f1e2 116 // Iterate over $XMLDB->dbdirs, loading their XML data to memory
9f5e5dee 117 if ($XMLDB->dbdirs) {
85d6dd38 118 $dbdirs = $XMLDB->dbdirs;
9f5e5dee 119 $o='<ul>';
120 foreach ($dbdirs as $dbdir) {
35c4f1e2 121 // Only if the directory exists
9f5e5dee 122 if (!$dbdir->path_exists) {
123 continue;
124 }
35c4f1e2 125 // Load the XML file
9f5e5dee 126 $xmldb_file = new xmldb_file($dbdir->path . '/install.xml');
127
35c4f1e2 128 // Only if the file exists
9f5e5dee 129 if (!$xmldb_file->fileExists()) {
130 continue;
131 }
35c4f1e2 132 // Load the XML contents to structure
9f5e5dee 133 $loaded = $xmldb_file->loadXMLStructure();
134 if (!$loaded || !$xmldb_file->isLoaded()) {
8fbce1c8 135 echo $OUTPUT->notification('Errors found in XMLDB file: '. $dbdir->path . '/install.xml');
9f5e5dee 136 continue;
137 }
35c4f1e2 138 // Arriving here, everything is ok, get the XMLDB structure
9f5e5dee 139 $structure = $xmldb_file->getStructure();
140
141 $o.=' <li>' . str_replace($CFG->dirroot . '/', '', $dbdir->path . '/install.xml');
35c4f1e2 142 // Getting tables
9f5e5dee 143 if ($xmldb_tables = $structure->getTables()) {
144 $o.=' <ul>';
35c4f1e2 145 // Foreach table, process its fields
9f5e5dee 146 foreach ($xmldb_tables as $xmldb_table) {
35c4f1e2 147 // Skip table if not exists
9f5e5dee 148 if (!$dbman->table_exists($xmldb_table)) {
149 continue;
150 }
35c4f1e2 151 // Fetch metadata from physical DB. All the columns info.
12e273dd 152 if (!$metacolumns = $DB->get_columns($xmldb_table->getName(), false)) {
35c4f1e2 153 // / Skip table if no metacolumns is available for it
9f5e5dee 154 continue;
155 }
35c4f1e2 156 // Table processing starts here
9f5e5dee 157 $o.=' <li>' . $xmldb_table->getName();
35c4f1e2 158 // Do the specific check.
9f5e5dee 159 list($output, $newproblems) = $this->check_table($xmldb_table, $metacolumns);
160 $o.=$output;
161 $problemsfound = array_merge($problemsfound, $newproblems);
162 $o.=' </li>';
35c4f1e2 163 // Give the script some more time (resetting to current if exists)
bd79ec56 164 if ($currenttl = @ini_get('max_execution_time')) {
165 @ini_set('max_execution_time',$currenttl);
166 }
9f5e5dee 167 }
168 $o.=' </ul>';
169 }
170 $o.=' </li>';
171 }
172 $o.='</ul>';
173 }
174
35c4f1e2 175 // Create a report of the problems found.
9f5e5dee 176 $r = $this->display_results($problemsfound);
177
35c4f1e2 178 // Combine the various bits of output.
9f5e5dee 179 $this->output = $b . $r . $o;
180 }
181
35c4f1e2 182 // Launch postaction if exists (leave this here!)
9f5e5dee 183 if ($this->getPostAction() && $result) {
184 return $this->launch($this->getPostAction());
185 }
186
35c4f1e2 187 // Return ok if arrived here
9f5e5dee 188 return $result;
189 }
190
191 /**
192 * Do the checks necessary on one particular table.
193 *
194 * @param xmldb_table $xmldb_table the table definition from the install.xml file.
195 * @param array $metacolumns the column information read from the database.
196 * @return array an array with two elements: First, some additional progress output,
197 * for example a list (<ul>) of the things check each with an one work ok/not ok summary.
198 * Second, an array giving the details of any problems found. These arrays
8926f844 199 * for all tables will be aggregated, and then passed to
9f5e5dee 200 */
201 abstract protected function check_table(xmldb_table $xmldb_table, array $metacolumns);
202
203 /**
204 * Display a list of the problems found.
205 *
206 * @param array $problems_found an aggregation of all the problems found by
207 * all the check_table calls.
208 * @return string a display of all the problems found as HTML.
209 */
210 abstract protected function display_results(array $problems_found);
211}