3 ///////////////////////////////////////////////////////////////////////////
5 // NOTICE OF COPYRIGHT //
7 // Moodle - Modular Object-Oriented Dynamic Learning Environment //
8 // http://moodle.com //
10 // Copyright (C) 2001-3001 Martin Dougiamas http://dougiamas.com //
11 // (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
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. //
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: //
23 // http://www.gnu.org/copyleft/gpl.html //
25 ///////////////////////////////////////////////////////////////////////////
27 /// This class will save the changes performed to one index
29 class edit_index_save
extends XMLDBAction
{
32 * Init method, every subclass will have its own
37 /// Set own custom attributes
39 /// Get needed strings
40 $this->loadStrings(array(
41 'indexnameempty' => 'xmldb',
42 'incorrectindexname' => 'xmldb',
43 'duplicateindexname' => 'xmldb',
44 'nofieldsspecified' => 'xmldb',
45 'duplicatefieldsused' => 'xmldb',
46 'fieldsnotintable' => 'xmldb',
47 'fieldsusedinkey' => 'xmldb',
48 'fieldsusedinindex' => 'xmldb',
49 'administration' => ''
54 * Invoke method, every class will have its own
55 * returns true/false on completion, setting both
56 * errormsg and output as necessary
63 /// Set own core attributes
64 $this->does_generate
= ACTION_NONE
;
65 //$this->does_generate = ACTION_GENERATE_HTML;
67 /// These are always here
70 /// Do the job, setting result as needed
72 if (!data_submitted('nomatch')) { ///Basic prevention
73 error('Wrong action call');
77 $dirpath = required_param('dir', PARAM_PATH
);
78 $dirpath = $CFG->dirroot
. stripslashes_safe($dirpath);
80 $tableparam = strtolower(required_param('table', PARAM_PATH
));
81 $indexparam = strtolower(required_param('index', PARAM_PATH
));
82 $name = trim(strtolower(optional_param('name', $indexparam, PARAM_PATH
)));
84 $comment = required_param('comment', PARAM_CLEAN
);
85 $comment = trim(stripslashes_safe($comment));
87 $unique = required_param('unique', PARAM_INT
);
88 $fields = required_param('fields', PARAM_CLEAN
);
89 $fields = str_replace(' ', '', trim(strtolower(stripslashes_safe($fields))));
91 $editeddir =& $XMLDB->editeddirs
[$dirpath];
92 $structure =& $editeddir->xml_file
->getStructure();
93 $table =& $structure->getTable($tableparam);
94 $index =& $table->getIndex($indexparam);
95 $oldhash = $index->getHash();
97 $errors = array(); /// To store all the errors found
99 /// Perform some checks
102 $errors[] = $this->str
['indexnameempty'];
104 /// Check incorrect name
105 if ($name == 'changeme') {
106 $errors[] = $this->str
['incorrectindexname'];
108 /// Check duplicate name
109 if ($indexparam != $name && $table->getIndex($name)) {
110 $errors[] = $this->str
['duplicateindexname'];
112 $fieldsarr = explode(',', $fields);
113 /// Check the fields isn't empty
114 if (empty($fieldsarr[0])) {
115 $errors[] = $this->str
['nofieldsspecified'];
117 /// Check that there aren't duplicate column names
118 $uniquearr = array_unique($fieldsarr);
119 if (count($fieldsarr) != count($uniquearr)) {
120 $errors[] = $this->str
['duplicatefieldsused'];
122 /// Check that all the fields in belong to the table
123 foreach ($fieldsarr as $field) {
124 if (!$table->getField($field)) {
125 $errors[] = $this->str
['fieldsnotintable'];
129 /// Check that there isn't any key using exactly the same fields
130 $tablekeys = $table->getKeys();
132 foreach ($tablekeys as $tablekey) {
133 $keyfieldsarr = $tablekey->getFields();
134 /// Compare both arrays, looking for diferences
135 $diferences = array_merge(array_diff($fieldsarr, $keyfieldsarr), array_diff($keyfieldsarr, $fieldsarr));
136 if (empty($diferences)) {
137 $errors[] = $this->str
['fieldsusedinkey'];
142 /// Check that there isn't any index using exactlt the same fields
143 $tableindexes = $table->getIndexes();
145 foreach ($tableindexes as $tableindex) {
146 /// Skip checking against itself
147 if ($indexparam == $tableindex->getName()) {
150 $indexfieldsarr = $tableindex->getFields();
151 /// Compare both arrays, looking for diferences
152 $diferences = array_merge(array_diff($fieldsarr, $indexfieldsarr), array_diff($indexfieldsarr, $fieldsarr));
153 if (empty($diferences)) {
154 $errors[] = $this->str
['fieldsusedinindex'];
161 if (!empty($errors)) {
162 $tempindex = new XMLDBIndex($name);
163 $tempindex->setUnique($unique);
164 $tempindex->setFields($fieldsarr);
165 /// Prepare the output
167 print_header("$site->shortname: XMLDB",
169 "<a href=\"../index.php\">" . $this->str
['administration'] . "</a> -> <a href=\"index.php\">XMLDB</a>");
170 notice ('<p>' .implode(', ', $errors) . '</p>
171 <p>' . $tempindex->readableInfo(),
172 'index.php?action=edit_index&index=' .$index->getName() . '&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot
, '', $dirpath)));
176 /// Continue if we aren't under errors
177 if (empty($errors)) {
178 /// If there is one name change, do it, changing the prev and next
179 /// atributes of the adjacent fields
180 if ($indexparam != $name) {
181 $index->setName($name);
182 if ($index->getPrevious()) {
183 $prev =& $table->getIndex($index->getPrevious());
184 $prev->setNext($name);
185 $prev->setChanged(true);
187 if ($index->getNext()) {
188 $next =& $table->getIndex($index->getNext());
189 $next->setPrevious($name);
190 $next->setChanged(true);
195 $index->setComment($comment);
197 /// Set the rest of fields
198 $index->setUnique($unique);
199 $index->setFields($fieldsarr);
201 /// If the hash has changed from the old one, change the version
202 /// and mark the structure as changed
203 $index->calculateHash(true);
204 if ($oldhash != $index->getHash()) {
205 $index->setChanged(true);
206 $table->setChanged(true);
207 /// Recalculate the structure hash
208 $structure->calculateHash(true);
209 $structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
211 $structure->setChanged(true);
214 /// Launch postaction if exists (leave this here!)
215 if ($this->getPostAction() && $result) {
216 return $this->launch($this->getPostAction());
220 /// Return ok if arrived here