See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
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 verifies all the data introduced when editing an index for correctness, 25 * performing changes / displaying errors depending of the results. 26 * 27 * @package tool_xmldb 28 * @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} 29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 30 */ 31 class edit_index_save extends XMLDBAction { 32 33 /** 34 * Init method, every subclass will have its own 35 */ 36 function init() { 37 parent::init(); 38 39 // Set own custom attributes 40 41 // Get needed strings 42 $this->loadStrings(array( 43 'indexnameempty' => 'tool_xmldb', 44 'incorrectindexname' => 'tool_xmldb', 45 'duplicateindexname' => 'tool_xmldb', 46 'nofieldsspecified' => 'tool_xmldb', 47 'duplicatefieldsused' => 'tool_xmldb', 48 'fieldsnotintable' => 'tool_xmldb', 49 'fieldsusedinkey' => 'tool_xmldb', 50 'fieldsusedinindex' => 'tool_xmldb', 51 'back' => 'tool_xmldb', 52 'administration' => '' 53 )); 54 } 55 56 /** 57 * Invoke method, every class will have its own 58 * returns true/false on completion, setting both 59 * errormsg and output as necessary 60 */ 61 function invoke() { 62 parent::invoke(); 63 64 $result = true; 65 66 // Set own core attributes 67 //$this->does_generate = ACTION_NONE; 68 $this->does_generate = ACTION_GENERATE_HTML; 69 70 // These are always here 71 global $CFG, $XMLDB; 72 73 // Do the job, setting result as needed 74 75 if (!data_submitted()) { // Basic prevention 76 throw new \moodle_exception('wrongcall', 'error'); 77 } 78 79 // Get parameters 80 $dirpath = required_param('dir', PARAM_PATH); 81 $dirpath = $CFG->dirroot . $dirpath; 82 83 $tableparam = strtolower(required_param('table', PARAM_PATH)); 84 $indexparam = strtolower(required_param('index', PARAM_PATH)); 85 $name = trim(strtolower(optional_param('name', $indexparam, PARAM_PATH))); 86 87 $comment = required_param('comment', PARAM_CLEAN); 88 $comment = trim($comment); 89 90 $unique = required_param('unique', PARAM_INT); 91 $fields = required_param('fields', PARAM_CLEAN); 92 $fields = str_replace(' ', '', trim(strtolower($fields))); 93 $hints = required_param('hints', PARAM_CLEAN); 94 $hints = str_replace(' ', '', trim(strtolower($hints))); 95 96 $editeddir = $XMLDB->editeddirs[$dirpath]; 97 $structure = $editeddir->xml_file->getStructure(); 98 $table = $structure->getTable($tableparam); 99 $index = $table->getIndex($indexparam); 100 $oldhash = $index->getHash(); 101 102 $errors = array(); // To store all the errors found 103 104 // Perform some checks 105 // Check empty name 106 if (empty($name)) { 107 $errors[] = $this->str['indexnameempty']; 108 } 109 // Check incorrect name 110 if ($name == 'changeme') { 111 $errors[] = $this->str['incorrectindexname']; 112 } 113 // Check duplicate name 114 if ($indexparam != $name && $table->getIndex($name)) { 115 $errors[] = $this->str['duplicateindexname']; 116 } 117 $fieldsarr = explode(',', $fields); 118 // Check the fields isn't empty 119 if (empty($fieldsarr[0])) { 120 $errors[] = $this->str['nofieldsspecified']; 121 } else { 122 // Check that there aren't duplicate column names 123 $uniquearr = array_unique($fieldsarr); 124 if (count($fieldsarr) != count($uniquearr)) { 125 $errors[] = $this->str['duplicatefieldsused']; 126 } 127 // Check that all the fields in belong to the table 128 foreach ($fieldsarr as $field) { 129 if (!$table->getField($field)) { 130 $errors[] = $this->str['fieldsnotintable']; 131 break; 132 } 133 } 134 // Check that there isn't any key using exactly the same fields 135 $tablekeys = $table->getKeys(); 136 if ($tablekeys) { 137 foreach ($tablekeys as $tablekey) { 138 $keyfieldsarr = $tablekey->getFields(); 139 // Compare both arrays, looking for differences 140 $diferences = array_merge(array_diff($fieldsarr, $keyfieldsarr), array_diff($keyfieldsarr, $fieldsarr)); 141 if (empty($diferences)) { 142 $errors[] = $this->str['fieldsusedinkey']; 143 break; 144 } 145 } 146 } 147 // Check that there isn't any index using exactly the same fields 148 $tableindexes = $table->getIndexes(); 149 if ($tableindexes) { 150 foreach ($tableindexes as $tableindex) { 151 // Skip checking against itself 152 if ($indexparam == $tableindex->getName()) { 153 continue; 154 } 155 $indexfieldsarr = $tableindex->getFields(); 156 // Compare both arrays, looking for differences 157 $diferences = array_merge(array_diff($fieldsarr, $indexfieldsarr), array_diff($indexfieldsarr, $fieldsarr)); 158 if (empty($diferences)) { 159 $errors[] = $this->str['fieldsusedinindex']; 160 break; 161 } 162 } 163 } 164 } 165 $hintsarr = array(); 166 foreach (explode(',', $hints) as $hint) { 167 $hint = preg_replace('/[^a-z]/', '', $hint); 168 if ($hint === '') { 169 continue; 170 } 171 $hintsarr[] = $hint; 172 } 173 174 if (!empty($errors)) { 175 $tempindex = new xmldb_index($name); 176 $tempindex->setUnique($unique); 177 $tempindex->setFields($fieldsarr); 178 $tempindex->setHints($hintsarr); 179 // Prepare the output 180 $o = '<p>' .implode(', ', $errors) . '</p> 181 <p>' . $tempindex->readableInfo() . '</p>'; 182 $o.= '<a href="index.php?action=edit_index&index=' .$index->getName() . '&table=' . $table->getName() . 183 '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>'; 184 $this->output = $o; 185 } 186 187 // Continue if we aren't under errors 188 if (empty($errors)) { 189 // If there is one name change, do it, changing the prev and next 190 // attributes of the adjacent fields 191 if ($indexparam != $name) { 192 $index->setName($name); 193 if ($index->getPrevious()) { 194 $prev = $table->getIndex($index->getPrevious()); 195 $prev->setNext($name); 196 $prev->setChanged(true); 197 } 198 if ($index->getNext()) { 199 $next = $table->getIndex($index->getNext()); 200 $next->setPrevious($name); 201 $next->setChanged(true); 202 } 203 } 204 205 // Set comment 206 $index->setComment($comment); 207 208 // Set the rest of fields 209 $index->setUnique($unique); 210 $index->setFields($fieldsarr); 211 $index->setHints($hintsarr); 212 213 // If the hash has changed from the old one, change the version 214 // and mark the structure as changed 215 $index->calculateHash(true); 216 if ($oldhash != $index->getHash()) { 217 $index->setChanged(true); 218 $table->setChanged(true); 219 // Recalculate the structure hash 220 $structure->calculateHash(true); 221 $structure->setVersion(userdate(time(), '%Y%m%d', 99, false)); 222 // Mark as changed 223 $structure->setChanged(true); 224 } 225 226 // Launch postaction if exists (leave this here!) 227 if ($this->getPostAction() && $result) { 228 return $this->launch($this->getPostAction()); 229 } 230 } 231 232 // Return ok if arrived here 233 return $result; 234 } 235 } 236
title
Description
Body
title
Description
Body
title
Description
Body
title
Body