1 <?php 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 /** 18 * @package tool_xmldb 19 * @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} 20 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 21 */ 22 23 /** 24 * This class will edit one loaded XML file 25 * 26 * Main page to start editing one XML file. From here it's possible to access 27 * to tables edition plus PHP code generation and other utilities 28 * 29 * @package tool_xmldb 30 * @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} 31 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 32 */ 33 class edit_xml_file extends XMLDBAction { 34 35 /** 36 * Init method, every subclass will have its own 37 */ 38 function init() { 39 parent::init(); 40 41 // Set own custom attributes 42 $this->sesskey_protected = false; // This action doesn't need sesskey protection 43 44 // Get needed strings 45 $this->loadStrings(array( 46 'change' => 'tool_xmldb', 47 'edit' => 'tool_xmldb', 48 'up' => 'tool_xmldb', 49 'down' => 'tool_xmldb', 50 'delete' => 'tool_xmldb', 51 'vieworiginal' => 'tool_xmldb', 52 'viewedited' => 'tool_xmldb', 53 'tables' => 'tool_xmldb', 54 'newtable' => 'tool_xmldb', 55 'newtablefrommysql' => 'tool_xmldb', 56 'viewsqlcode' => 'tool_xmldb', 57 'viewphpcode' => 'tool_xmldb', 58 'reserved' => 'tool_xmldb', 59 'backtomainview' => 'tool_xmldb', 60 'viewxml' => 'tool_xmldb', 61 'pendingchanges' => 'tool_xmldb', 62 'pendingchangescannotbesaved' => 'tool_xmldb', 63 'save' => 'tool_xmldb' 64 )); 65 } 66 67 /** 68 * Invoke method, every class will have its own 69 * returns true/false on completion, setting both 70 * errormsg and output as necessary 71 */ 72 function invoke() { 73 global $OUTPUT, $PAGE; 74 parent::invoke(); 75 76 $result = true; 77 78 // Set own core attributes 79 $this->does_generate = ACTION_GENERATE_HTML; 80 81 // These are always here 82 global $CFG, $XMLDB, $DB; 83 84 // Do the job, setting $result as needed 85 86 // Get the dir containing the file 87 $dirpath = required_param('dir', PARAM_PATH); 88 $dirpath = $CFG->dirroot . $dirpath; 89 90 // Get the correct dir 91 if (!empty($XMLDB->dbdirs)) { 92 $dbdir = $XMLDB->dbdirs[$dirpath]; 93 if ($dbdir) { 94 // Only if the directory exists and it has been loaded 95 if (!$dbdir->path_exists || !$dbdir->xml_loaded) { 96 return false; 97 } 98 // Check if the in-memory object exists and create it 99 if (empty($XMLDB->editeddirs)) { 100 $XMLDB->editeddirs = array(); 101 } 102 // Check if the dir exists and copy it from dbdirs 103 if (!isset($XMLDB->editeddirs[$dirpath])) { 104 $XMLDB->editeddirs[$dirpath] = unserialize(serialize($dbdir)); 105 } 106 // Get it 107 $editeddir = $XMLDB->editeddirs[$dirpath]; 108 $structure = $editeddir->xml_file->getStructure(); 109 110 // Add the main form 111 $o = '<form id="form" action="index.php" method="post">'; 112 $o.= '<div>'; 113 $o.= ' <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />'; 114 $o.= ' <input type="hidden" name ="action" value="edit_xml_file_save" />'; 115 $o.= ' <input type="hidden" name ="postaction" value="edit_xml_file" />'; 116 $o.= ' <input type="hidden" name ="path" value="' . s($structure->getPath()) .'" />'; 117 $o.= ' <input type="hidden" name ="version" value="' . s($structure->getVersion()) .'" />'; 118 $o.= ' <input type="hidden" name ="sesskey" value="' . sesskey() .'" />'; 119 $o .= ' <table id="formelements">'; 120 $o.= ' <tr valign="top"><td>Path:</td><td>' . s($structure->getPath()) . '</td></tr>'; 121 $o.= ' <tr valign="top"><td>Version:</td><td>' . s($structure->getVersion()) . '</td></tr>'; 122 $o .= ' <tr valign="top"><td><label for="comment" accesskey="c">Comment:</label></td><td> 123 <textarea name="comment" rows="3" cols="80" id="comment" class="form-control">' . 124 $structure->getComment() . '</textarea></td></tr>'; 125 $o .= ' <tr><td> </td><td><input type="submit" value="' . $this->str['change'] . 126 '"class="btn btn-secondary" /></td></tr>'; 127 $o.= ' </table>'; 128 $o.= '</div></form>'; 129 // Calculate the pending changes / save message 130 $e = ''; 131 $cansavenow = false; 132 if ($structure->hasChanged()) { 133 if (!is_writeable($dirpath . '/install.xml') || !is_writeable($dirpath)) { 134 $e .= '<p class="centerpara error">' . $this->str['pendingchangescannotbesaved'] . '</p>'; 135 } else { 136 $e .= '<p class="centerpara warning">' . $this->str['pendingchanges'] . '</p>'; 137 $cansavenow = true; 138 } 139 } 140 // Calculate the buttons 141 $b = ' <p class="centerpara buttons">'; 142 // The view original XML button 143 $b .= ' <a href="index.php?action=view_structure_xml&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&select=original">[' . $this->str['vieworiginal'] . ']</a>'; 144 // The view edited XML button 145 if ($structure->hasChanged()) { 146 $b .= ' <a href="index.php?action=view_structure_xml&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&select=edited">[' . $this->str['viewedited'] . ']</a>'; 147 } else { 148 $b .= ' [' . $this->str['viewedited'] . ']'; 149 } 150 // The new table button 151 $b .= ' <a href="index.php?action=new_table&sesskey=' . sesskey() . '&postaction=edit_table&table=changeme&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newtable'] . ']</a>'; 152 // The new from MySQL button 153 if ($DB->get_dbfamily() == 'mysql') { 154 $b .= ' <a href="index.php?action=new_table_from_mysql&sesskey=' . sesskey() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newtablefrommysql'] . ']</a>'; 155 } else { 156 $b .= ' [' . $this->str['newtablefrommysql'] . ']'; 157 } 158 159 // The view sql code button 160 $b .= '<a href="index.php?action=view_structure_sql&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' .$this->str['viewsqlcode'] . ']</a>'; 161 // The view php code button 162 $b .= ' <a href="index.php?action=view_structure_php&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['viewphpcode'] . ']</a>'; 163 // The save button (if possible) 164 if ($cansavenow) { 165 $b .= ' <a href="index.php?action=save_xml_file&sesskey=' . sesskey() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&time=' . time() . '&unload=false&postaction=edit_xml_file&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['save'] . ']</a>'; 166 } 167 168 // The back to main menu button 169 $b .= ' <a href="index.php?action=main_view#lastused">[' . $this->str['backtomainview'] . ']</a>'; 170 $b .= '</p>'; 171 $o .= $e . $b; 172 173 // Join all the reserved words into one big array 174 // Calculate list of available SQL generators 175 require_once("$CFG->libdir/ddl/sql_generator.php"); 176 $reserved_words = sql_generator::getAllReservedWords(); 177 178 // Add the tables list 179 $tables = $structure->getTables(); 180 if ($tables) { 181 $o .= '<h3 class="main">' . $this->str['tables'] . '</h3>'; 182 $o .= '<table id="listtables" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">'; 183 $row = 0; 184 foreach ($tables as $table) { 185 // Drag element for sortorder. 186 $move = html_writer::span($OUTPUT->render_from_template('core/drag_handle', 187 ['movetitle' => get_string('movecontent', 'moodle', $table->getName())]), '', 188 ['data-action' => 'move_updown_table', 'data-dir' => str_replace($CFG->dirroot, '', $dirpath), 189 'data-table' => $table->getName()]); 190 // The table name (link to edit table) 191 $t = '<a href="index.php?action=edit_table&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">' . $table->getName() . '</a>'; 192 // Calculate buttons 193 $b = '</td><td class="button cell">'; 194 // The edit button 195 $b .= '<a href="index.php?action=edit_table&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>'; 196 $b .= '</td><td class="button cell">'; 197 // The delete button (if we have more than one and it isn't used) 198 if (count($tables) > 1 && 199 !$structure->getTableUses($table->getName())) { 200 // !$structure->getTableUses($table->getName())) { 201 $b .= '<a href="index.php?action=delete_table&sesskey=' . sesskey() . '&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>'; 202 } else { 203 $b .= '[' . $this->str['delete'] . ']'; 204 } 205 $b .= '</td><td class="button cell">'; 206 // The view xml button 207 $b .= '<a href="index.php?action=view_table_xml&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&table=' . $table->getName() . '&select=edited">[' . $this->str['viewxml'] . ']</a>'; 208 // Detect if the table name is a reserved word 209 if (array_key_exists($table->getName(), $reserved_words)) { 210 $b .= ' <a href="index.php?action=view_reserved_words"><span class="error">' . $this->str['reserved'] . '</span></a>'; 211 } 212 $b .= '</td>'; 213 // Print table row 214 $o .= '<tr class="r' . $row . '" data-name="' . s($table->getName()) . '"><td class="cell firstcol">' . 215 (count($tables) > 1 ? $move : '') . 216 $t . $b . '</tr>'; 217 $row = ($row + 1) % 2; 218 } 219 $o .= '</table>'; 220 } 221 // Add the back to main. 222 $this->output = $o; 223 $PAGE->requires->js_call_amd('tool_xmldb/move', 'init', ['listtables', 'move_updown_table']); 224 } 225 } 226 227 // Launch postaction if exists (leave this unmodified) 228 if ($this->getPostAction() && $result) { 229 return $this->launch($this->getPostAction()); 230 } 231 232 return $result; 233 } 234 } 235
title
Description
Body
title
Description
Body
title
Description
Body
title
Body