PageRenderTime 23ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/admin/tool/xmldb/actions/edit_index_save/edit_index_save.class.php

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