diff --git a/admin/tool/xmldb/actions/main_view/main_view.class.php b/admin/tool/xmldb/actions/main_view/main_view.class.php index 7a37f8eb1ad..8071a71530b 100644 --- a/admin/tool/xmldb/actions/main_view/main_view.class.php +++ b/admin/tool/xmldb/actions/main_view/main_view.class.php @@ -57,6 +57,7 @@ class main_view extends XMLDBAction { 'checkforeignkeys' => 'tool_xmldb', 'checkbigints' => 'tool_xmldb', 'checkoraclesemantics' => 'tool_xmldb', + 'reconcilefiles' => 'tool_xmldb', 'doc' => 'tool_xmldb', 'filemodifiedoutfromeditor' => 'tool_xmldb', 'viewxml' => 'tool_xmldb', @@ -97,6 +98,8 @@ class main_view extends XMLDBAction { $b .= ' [' . $this->str['reservedwords'] . ']'; // The docs button $b .= ' [' . $this->str['doc'] . ']'; + // The reconcile XMLDB files button. + $b .= ' [' . $this->str['reconcilefiles'] . ']'; // The check indexes button $b .= ' [' . $this->str['checkindexes'] . ']'; // The check defaults button diff --git a/admin/tool/xmldb/actions/reconcile_files/reconcile_files.class.php b/admin/tool/xmldb/actions/reconcile_files/reconcile_files.class.php new file mode 100644 index 00000000000..7536ad2b6ce --- /dev/null +++ b/admin/tool/xmldb/actions/reconcile_files/reconcile_files.class.php @@ -0,0 +1,124 @@ +. + +/** + * List all the files needing reconcile because the definitions don't match the XML contents. + * + * @package tool_xmldb + * @copyright 2022 onwards Eloy Lafuente (stronk7) {@link https://stronk7.com} + * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class reconcile_files extends XMLDBAction { + + /** + * Init method, every subclass will have its own + */ + public function init() { + parent::init(); + + // Set own custom attributes. + $this->sesskey_protected = false; // This action doesn't need sesskey protection. + + // Get needed strings. + $this->loadStrings([ + 'backtomainview' => 'tool_xmldb', + 'reconcile_files_intro' => 'tool_xmldb', + 'reconcile_files_no' => 'tool_xmldb', + 'reconcile_files_yes' => 'tool_xmldb', + 'searchresults' => 'tool_xmldb', + ]); + } + + /** + * Invoke method, every class will have its own + * returns true/false on completion, setting both + * errormsg and output as necessary + */ + public function invoke() { + parent::invoke(); + + $result = true; + + // Set own core attributes. + $this->does_generate = ACTION_GENERATE_HTML; + + // These are always here. + global $CFG, $XMLDB; + + // Do the job, setting $result as needed. + + // Add link back to home. + $b = '

'; + $b .= ' [' . $this->str['backtomainview'] . ']'; + $b .= '

'; + $this->output .= $b; + + $c = '

'; + $c .= $this->str['reconcile_files_intro']; + $c .= '

'; + $this->output .= $c; + + // Get the list of DB directories. + $result = $this->launch('get_db_directories'); + if ($result && !empty($XMLDB->dbdirs)) { + $needfix = []; + foreach ($XMLDB->dbdirs as $key => $dbdir) { + // Verify it exists. + if (!file_exists($key . '/install.xml') && !is_readable($key . '/install.xml')) { + continue; + } + + // Read the raw contents of the file. + $rawcontents = file_get_contents($key . '/install.xml'); + + // Load the XMLDB file and its structure. + $xmldb = new xmldb_file($key . '/install.xml'); + $xmldb->loadXMLStructure(); + + // Generate the XML contents from the loaded structure. + $xmlcontents = $xmldb->getStructure()->xmlOutput(); + + if ($rawcontents != $xmlcontents) { + $relpath = str_replace($CFG->dirroot . '/', '', $key) . '/install.xml'; + $needfix[] = $relpath; + // Left here on purpose, as a quick way to fix problems. To be + // enabled and run by developers only, uncomment the next line: + // file_put_contents($key . '/install.xml', $xmlcontents); + // (this script won't ever do that officially). + } + } + } + + $r = '

' . $this->str['searchresults'] . '

'; + if ($needfix) { + $r .= '

' . $this->str['reconcile_files_yes'] . count($needfix) . '

'; + $r .= ''; + + } else { + $r .= '

' . $this->str['reconcile_files_no'] . '

'; + } + + // Set the output. + $this->output .= $r; + + // Launch postaction if exists (leave this unmodified). + if ($this->getPostAction() && $result) { + return $this->launch($this->getPostAction()); + } + + return $result; + } +} diff --git a/admin/tool/xmldb/lang/en/tool_xmldb.php b/admin/tool/xmldb/lang/en/tool_xmldb.php index e87983503f1..786de3fc70c 100644 --- a/admin/tool/xmldb/lang/en/tool_xmldb.php +++ b/admin/tool/xmldb/lang/en/tool_xmldb.php @@ -176,6 +176,13 @@ $string['persistentfieldscomplete'] = 'The following fields have been added: '; $string['persistentfieldsexist'] = 'The following fields already exist: '; $string['pluginname'] = 'XMLDB editor'; $string['primarykeyonlyallownotnullfields'] = 'Primary keys cannot be null'; +$string['reconcilefiles'] = 'Reconcile XMLDB files'; +$string['reconcile_files'] = 'Look for XMLDB files needing reconcile'; +$string['reconcile_files_intro'] = 'This functionality looks for the current contents of all the XMLDB files, verifying that they match the results of generating them from the XMLDB Editor. + +A list of files needing to be reconciled (regenerated) will be displayed and the XMLDB Editor should be used to fix them.'; +$string['reconcile_files_no'] = 'All files are ok, no reconcile action needed'; +$string['reconcile_files_yes'] = 'Found files to reconcile: '; $string['reserved'] = 'Reserved'; $string['reservedwords'] = 'Reserved words'; $string['revert'] = 'Revert';