prevent NULL contents before field change (old servers can have this wrongly defined...
[moodle.git] / admin / xmldb / actions / check_defaults / check_defaults.class.php
CommitLineData
dfac8649 1<?php // $Id$
2
3///////////////////////////////////////////////////////////////////////////
4// //
5// NOTICE OF COPYRIGHT //
6// //
7// Moodle - Modular Object-Oriented Dynamic Learning Environment //
8// http://moodle.com //
9// //
10// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
11// (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
12// //
13// This program is free software; you can redistribute it and/or modify //
14// it under the terms of the GNU General Public License as published by //
15// the Free Software Foundation; either version 2 of the License, or //
16// (at your option) any later version. //
17// //
18// This program is distributed in the hope that it will be useful, //
19// but WITHOUT ANY WARRANTY; without even the implied warranty of //
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
21// GNU General Public License for more details: //
22// //
23// http://www.gnu.org/copyleft/gpl.html //
24// //
25///////////////////////////////////////////////////////////////////////////
26
27/// This class will check all the default values existing in the DB
28/// match those specified in the xml specs
29/// and providing one SQL script to fix all them.
30
31class check_defaults extends XMLDBAction {
32
33 /**
34 * Init method, every subclass will have its own
35 */
36 function init() {
37 parent::init();
38
39 /// Set own core attributes
40
41 /// Set own custom attributes
42
43 /// Get needed strings
44 $this->loadStrings(array(
45 'confirmcheckdefaults' => 'xmldb',
46 'ok' => '',
47 'wrong' => 'xmldb',
48 'table' => 'xmldb',
49 'field' => 'xmldb',
50 'searchresults' => 'xmldb',
51 'wrongdefaults' => 'xmldb',
52 'completelogbelow' => 'xmldb',
53 'nowrongdefaultsfound' => 'xmldb',
54 'yeswrongdefaultsfound' => 'xmldb',
55 'yes' => '',
56 'no' => '',
57 'error' => '',
58 'shouldbe' => 'xmldb',
59 'butis' => 'xmldb',
60 'back' => 'xmldb'
61
62 ));
63 }
64
65 /**
66 * Invoke method, every class will have its own
67 * returns true/false on completion, setting both
68 * errormsg and output as necessary
69 */
70 function invoke() {
71 parent::invoke();
72
73 $result = true;
74
75 /// Set own core attributes
76 $this->does_generate = ACTION_GENERATE_HTML;
77
78 /// These are always here
79 global $CFG, $XMLDB, $db;
80
81 /// And we nedd some ddl suff
82 require_once ($CFG->libdir . '/ddllib.php');
83
84 /// Here we'll acummulate all the wrong fields found
85 $wrong_fields = array();
86
87 /// Do the job, setting $result as needed
88
89 /// Get the confirmed to decide what to do
90 $confirmed = optional_param('confirmed', false, PARAM_BOOL);
91
92 /// If not confirmed, show confirmation box
93 if (!$confirmed) {
94 $o = '<table class="generalbox" border="0" cellpadding="5" cellspacing="0" id="notice">';
95 $o.= ' <tr><td class="generalboxcontent">';
96 $o.= ' <p class="centerpara">' . $this->str['confirmcheckdefaults'] . '</p>';
97 $o.= ' <table class="boxaligncenter" cellpadding="20"><tr><td>';
98 $o.= ' <div class="singlebutton">';
99 $o.= ' <form action="index.php?action=check_defaults&amp;confirmed=yes" method="post"><fieldset class="invisiblefieldset">';
100 $o.= ' <input type="submit" value="'. $this->str['yes'] .'" /></fieldset></form></div>';
101 $o.= ' </td><td>';
102 $o.= ' <div class="singlebutton">';
103 $o.= ' <form action="index.php?action=main_view" method="post"><fieldset class="invisiblefieldset">';
104 $o.= ' <input type="submit" value="'. $this->str['no'] .'" /></fieldset></form></div>';
105 $o.= ' </td></tr>';
106 $o.= ' </table>';
107 $o.= ' </td></tr>';
108 $o.= '</table>';
109
110 $this->output = $o;
111 } else {
112 /// The back to edit table button
113 $b = ' <p class="centerpara buttons">';
114 $b .= '<a href="index.php">[' . $this->str['back'] . ']</a>';
115 $b .= '</p>';
116
117 /// Iterate over $XMLDB->dbdirs, loading their XML data to memory
118 if ($XMLDB->dbdirs) {
119 $dbdirs =& $XMLDB->dbdirs;
120 $o='<ul>';
121 foreach ($dbdirs as $dbdir) {
122 /// Only if the directory exists
123 if (!$dbdir->path_exists) {
124 continue;
125 }
126 /// Load the XML file
127 $xmldb_file = new XMLDBFile($dbdir->path . '/install.xml');
128 /// Load the needed XMLDB generator
129 $classname = 'XMLDB' . $CFG->dbtype;
130 $generator = new $classname();
131 $generator->setPrefix($CFG->prefix);
132
133 /// Only if the file exists
134 if (!$xmldb_file->fileExists()) {
135 continue;
136 }
137 /// Load the XML contents to structure
138 $loaded = $xmldb_file->loadXMLStructure();
139 if (!$loaded || !$xmldb_file->isLoaded()) {
140 notify('Errors found in XMLDB file: '. $dbdir->path . '/install.xml');
141 continue;
142 }
143 /// Arriving here, everything is ok, get the XMLDB structure
144 $structure = $xmldb_file->getStructure();
145//echo "<pre>"; print_r( $structure ); die;
146 $o.=' <li>' . str_replace($CFG->dirroot . '/', '', $dbdir->path . '/install.xml');
147 /// Getting tables
148 if ($xmldb_tables = $structure->getTables()) {
149 $o.=' <ul>';
150 /// Foreach table, process its fields
151 foreach ($xmldb_tables as $xmldb_table) {
152 /// Skip table if not exists
153 if (!table_exists($xmldb_table)) {
154 continue;
155 }
156 /// Fetch metadata from phisical DB. All the columns info.
157 if ($metacolumns = $db->MetaColumns($CFG->prefix . $xmldb_table->getName())) {
158 $metacolumns = array_change_key_case($metacolumns, CASE_LOWER);
159// echo "<pre>".$xmldb_table->getName(); print_r( $metacolumns ); die;
160 } else {
161 //// Skip table if no metacolumns is available for it
162 continue;
163 }
164 /// Table processing starts here
165 $o.=' <li>' . $xmldb_table->getName();
166 /// Get and process XMLDB fields
167 if ($xmldb_fields = $xmldb_table->getFields()) {
168 $o.=' <ul>';
169 foreach ($xmldb_fields as $xmldb_field) {
170//echo "<pre>"; print_r( $xmldb_field ); die;
171
172 // Get the default value for the field
173 $xmldbdefault = $xmldb_field->getDefault();
174
175 /// If the metadata for that column doesn't exist, skip
176 if (!isset($metacolumns[$xmldb_field->getName()])) {
177 continue;
178 }
179
180 /// To variable for better handling
181 $metacolumn = $metacolumns[$xmldb_field->getName()];
182
183 /// Going to check this field in DB
184 $o.=' <li>' . $this->str['field'] . ': ' . $xmldb_field->getName() . ' ';
185
186 // get the value of the physical default (or blank if there isn't one)
187 if ($metacolumn->has_default==1) {
188 $physicaldefault = $metacolumn->default_value;
189 }
190 else {
191 $physicaldefault = '';
192 }
193
194 // there *is* a default and it's wrong
195 if ($physicaldefault != $xmldbdefault) {
196 $info = '['.$this->str['shouldbe']." '$xmldbdefault' ".$this->str['butis'].
197 " '$physicaldefault']";
198 $o.='<font color="red">' . $this->str['wrong'] . " $info</font>";
199 /// Add the wrong field to the list
200 $obj = new object;
201 $obj->table = $xmldb_table;
202 $obj->field = $xmldb_field;
203 $obj->physicaldefault = $physicaldefault;
204 $obj->xmldbdefault = $xmldbdefault;
205 $wrong_fields[] = $obj;
206 } else {
207 $o.='<font color="green">' . $this->str['ok'] . '</font>';
208 }
209 $o.='</li>';
210 }
211 $o.=' </ul>';
212 }
213 $o.=' </li>';
214 }
215 $o.=' </ul>';
216 }
217 $o.=' </li>';
218 }
219 $o.='</ul>';
220 }
221
222 /// We have finished, let's show the results of the search
223 $s = '';
224 $r = '<table class="generalbox boxaligncenter boxwidthwide" border="0" cellpadding="5" cellspacing="0" id="results">';
225 $r.= ' <tr><td class="generalboxcontent">';
226 $r.= ' <h2 class="main">' . $this->str['searchresults'] . '</h2>';
227 $r.= ' <p class="centerpara">' . $this->str['wrongdefaults'] . ': ' . count($wrong_fields) . '</p>';
228 $r.= ' </td></tr>';
229 $r.= ' <tr><td class="generalboxcontent">';
230
231 /// If we have found wrong defaults inform about them
232 if (count($wrong_fields)) {
233 $r.= ' <p class="centerpara">' . $this->str['yeswrongdefaultsfound'] . '</p>';
234 $r.= ' <ul>';
235 foreach ($wrong_fields as $obj) {
236 $xmldb_table = $obj->table;
237 $xmldb_field = $obj->field;
238 $physicaldefault = $obj->physicaldefault;
239 $xmldbdefault = $obj->xmldbdefault;
240
241 // get the alter table command
242 $sqlarr = $xmldb_table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $xmldb_field, true);
243
244 $r.= ' <li>' . $this->str['table'] . ': ' . $xmldb_table->getName() . '. ' .
245 $this->str['field'] . ': ' . $xmldb_field->getName() . ', ' .
246 $this->str['shouldbe'] . ' ' . "'$xmldbdefault'" . ' ' .
247 $this->str['butis'] . ' ' . "'$physicaldefault'" . '</li>';
248 /// Add to output if we have sentences
249 if ($sqlarr) {
250 $s.= '<code>' . str_replace("\n", '<br />', implode('<br />', $sqlarr)) . '</code><br />';
251 }
252 }
253 $r.= ' </ul>';
254 /// Add the SQL statements (all together)
255 $r.= '<hr />' . $s;
256 } else {
25b05ce5 257 $r.= ' <p class="centerpara">' . $this->str['nowrongdefaultsfound'] . '</p>';
dfac8649 258 }
259 $r.= ' </td></tr>';
260 $r.= ' <tr><td class="generalboxcontent">';
261 /// Add the complete log message
262 $r.= ' <p class="centerpara">' . $this->str['completelogbelow'] . '</p>';
263 $r.= ' </td></tr>';
264 $r.= '</table>';
265
266 $this->output = $b . $r . $o;
267 }
268
269 /// Launch postaction if exists (leave this here!)
270 if ($this->getPostAction() && $result) {
271 return $this->launch($this->getPostAction());
272 }
273
274 /// Return ok if arrived here
275 return $result;
276 }
277}
278?>