PageRenderTime 48ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://bitbucket.org/kudutest1/moodlegit
PHP | 357 lines | 239 code | 23 blank | 95 comment | 46 complexity | 3c9e662f0cecb5da5963bb0fcb80a0fb 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 provides the interface for all the edit table actions
  23. *
  24. * Main page of edit table actions, from here fields/indexes/keys edition
  25. * can be invoked, plus links to PHP code generator, view SQL, rearrange
  26. * elements and so on.
  27. *
  28. * @package tool_xmldb
  29. * @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
  30. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  31. */
  32. class edit_table extends XMLDBAction {
  33. /**
  34. * Init method, every subclass will have its own
  35. */
  36. function init() {
  37. parent::init();
  38. // Set own custom attributes
  39. $this->sesskey_protected = false; // This action doesn't need sesskey protection
  40. // Get needed strings
  41. $this->loadStrings(array(
  42. 'change' => 'tool_xmldb',
  43. 'vieworiginal' => 'tool_xmldb',
  44. 'viewedited' => 'tool_xmldb',
  45. 'viewsqlcode' => 'tool_xmldb',
  46. 'viewphpcode' => 'tool_xmldb',
  47. 'newfield' => 'tool_xmldb',
  48. 'newkey' => 'tool_xmldb',
  49. 'newindex' => 'tool_xmldb',
  50. 'fields' => 'tool_xmldb',
  51. 'keys' => 'tool_xmldb',
  52. 'indexes' => 'tool_xmldb',
  53. 'edit' => 'tool_xmldb',
  54. 'up' => 'tool_xmldb',
  55. 'down' => 'tool_xmldb',
  56. 'delete' => 'tool_xmldb',
  57. 'reserved' => 'tool_xmldb',
  58. 'back' => 'tool_xmldb',
  59. 'viewxml' => 'tool_xmldb',
  60. 'pendingchanges' => 'tool_xmldb',
  61. 'pendingchangescannotbesaved' => 'tool_xmldb',
  62. 'save' => 'tool_xmldb'
  63. ));
  64. }
  65. /**
  66. * Invoke method, every class will have its own
  67. * returns true/false on completion, setting both
  68. * errormsg and output as necessary
  69. */
  70. function invoke() {
  71. parent::invoke();
  72. $result = true;
  73. // Set own core attributes
  74. $this->does_generate = ACTION_GENERATE_HTML;
  75. // These are always here
  76. global $CFG, $XMLDB;
  77. // Do the job, setting result as needed
  78. // Get the dir containing the file
  79. $dirpath = required_param('dir', PARAM_PATH);
  80. $dirpath = $CFG->dirroot . $dirpath;
  81. // Get the correct dirs
  82. if (!empty($XMLDB->dbdirs)) {
  83. $dbdir = $XMLDB->dbdirs[$dirpath];
  84. } else {
  85. return false;
  86. }
  87. // Check if the dir exists and copy it from dbdirs
  88. // (because we need straight load in case of saving from here)
  89. if (!isset($XMLDB->editeddirs[$dirpath])) {
  90. $XMLDB->editeddirs[$dirpath] = unserialize(serialize($dbdir));
  91. }
  92. if (!empty($XMLDB->editeddirs)) {
  93. $editeddir = $XMLDB->editeddirs[$dirpath];
  94. $structure = $editeddir->xml_file->getStructure();
  95. }
  96. $tableparam = required_param('table', PARAM_CLEAN);
  97. if (!$table = $structure->getTable($tableparam)) {
  98. // Arriving here from a name change, looking for the new table name
  99. $tableparam = required_param('name', PARAM_CLEAN);
  100. $table = $structure->getTable($tableparam);
  101. }
  102. $dbdir = $XMLDB->dbdirs[$dirpath];
  103. $origstructure = $dbdir->xml_file->getStructure();
  104. // Add the main form
  105. $o = '<form id="form" action="index.php" method="post">';
  106. $o.= '<div>';
  107. $o.= ' <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
  108. $o.= ' <input type="hidden" name ="table" value="' . $tableparam .'" />';
  109. $o.= ' <input type="hidden" name ="action" value="edit_table_save" />';
  110. $o.= ' <input type="hidden" name ="sesskey" value="' . sesskey() .'" />';
  111. $o.= ' <input type="hidden" name ="postaction" value="edit_table" />';
  112. $o.= ' <table id="formelements" class="boxaligncenter">';
  113. // If the table is being used, we cannot rename it
  114. if ($structure->getTableUses($table->getName())) {
  115. $o.= ' <tr valign="top"><td>Name:</td><td><input type="hidden" name ="name" value="' . s($table->getName()) . '" />' . s($table->getName()) .'</td></tr>';
  116. } else {
  117. $o.= ' <tr valign="top"><td><label for="name" accesskey="p">Name:</label></td><td><input name="name" type="text" size="28" maxlength="28" id="name" value="' . s($table->getName()) . '" /></td></tr>';
  118. }
  119. $o.= ' <tr valign="top"><td><label for="comment" accesskey="c">Comment:</label></td><td><textarea name="comment" rows="3" cols="80" id="comment">' . s($table->getComment()) . '</textarea></td></tr>';
  120. $o.= ' <tr valign="top"><td>&nbsp;</td><td><input type="submit" value="' .$this->str['change'] . '" /></td></tr>';
  121. $o.= ' </table>';
  122. $o.= '</div></form>';
  123. // Calculate the pending changes / save message
  124. $e = '';
  125. $cansavenow = false;
  126. if ($structure->hasChanged()) {
  127. if (!is_writeable($dirpath . '/install.xml') || !is_writeable($dirpath)) {
  128. $e .= '<p class="centerpara error">' . $this->str['pendingchangescannotbesaved'] . '</p>';
  129. } else {
  130. $e .= '<p class="centerpara warning">' . $this->str['pendingchanges'] . '</p>';
  131. $cansavenow = true;
  132. }
  133. }
  134. // Calculate the buttons
  135. $b = ' <p class="centerpara buttons">';
  136. // The view original XML button
  137. if ($origstructure->getTable($tableparam)) {
  138. $b .= '&nbsp;<a href="index.php?action=view_table_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=original&amp;table=' . $tableparam . '">[' . $this->str['vieworiginal'] . ']</a>';
  139. } else {
  140. $b .= '&nbsp;[' . $this->str['vieworiginal'] . ']';
  141. }
  142. // The view edited XML button
  143. if ($table->hasChanged()) {
  144. $b .= '&nbsp;<a href="index.php?action=view_table_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=edited&amp;table=' . $tableparam . '">[' . $this->str['viewedited'] . ']</a>';
  145. } else {
  146. $b .= '&nbsp;[' . $this->str['viewedited'] . ']';
  147. }
  148. // The new field button
  149. $b .= '&nbsp;<a href="index.php?action=new_field&amp;sesskey=' . sesskey() . '&amp;postaction=edit_field&amp;table=' . $tableparam . '&amp;field=changeme&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newfield'] . ']</a>';
  150. // The new key button
  151. $b .= '&nbsp;<a href="index.php?action=new_key&amp;sesskey=' . sesskey() . '&amp;postaction=edit_key&amp;table=' . $tableparam . '&amp;key=changeme&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newkey'] . ']</a>';
  152. // The new index button
  153. $b .= '&nbsp;<a href="index.php?action=new_index&amp;sesskey=' . sesskey() . '&amp;postaction=edit_index&amp;table=' . $tableparam . '&amp;index=changeme&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newindex'] . ']</a>';
  154. $b .= '</p>';
  155. $b .= ' <p class="centerpara buttons">';
  156. // The view sql code button
  157. $b .= '<a href="index.php?action=view_table_sql&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' .$this->str['viewsqlcode'] . ']</a>';
  158. // The view php code button
  159. $b .= '&nbsp;<a href="index.php?action=view_table_php&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['viewphpcode'] . ']</a>';
  160. // The save button (if possible)
  161. if ($cansavenow) {
  162. $b .= '&nbsp;<a href="index.php?action=save_xml_file&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;time=' . time() . '&amp;unload=false&amp;postaction=edit_table&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['save'] . ']</a>';
  163. }
  164. // The back to edit xml file button
  165. $b .= '&nbsp;<a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
  166. $b .= '</p>';
  167. $o .= $e . $b;
  168. require_once("$CFG->libdir/ddl/sql_generator.php");
  169. $reserved_words = sql_generator::getAllReservedWords();
  170. // Delete any 'changeme' field/key/index
  171. $table->deleteField('changeme');
  172. $table->deleteKey('changeme');
  173. $table->deleteIndex('changeme');
  174. // Add the fields list
  175. $fields = $table->getFields();
  176. if (!empty($fields)) {
  177. $o .= '<h3 class="main">' . $this->str['fields'] . '</h3>';
  178. $o .= '<table id="listfields" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">';
  179. $row = 0;
  180. foreach ($fields as $field) {
  181. // The field name (link to edit - if the field has no uses)
  182. if (!$structure->getFieldUses($table->getName(), $field->getName())) {
  183. $f = '<a href="index.php?action=edit_field&amp;field=' .$field->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">' . $field->getName() . '</a>';
  184. } else {
  185. $f = $field->getName();
  186. }
  187. // Calculate buttons
  188. $b = '</td><td class="button cell">';
  189. // The edit button (if the field has no uses)
  190. if (!$structure->getFieldUses($table->getName(), $field->getName())) {
  191. $b .= '<a href="index.php?action=edit_field&amp;field=' .$field->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>';
  192. } else {
  193. $b .= '[' . $this->str['edit'] . ']';
  194. }
  195. $b .= '</td><td class="button cell">';
  196. // The up button
  197. if ($field->getPrevious()) {
  198. $b .= '<a href="index.php?action=move_updown_field&amp;direction=up&amp;sesskey=' . sesskey() . '&amp;field=' . $field->getName() . '&amp;table=' . $table->getName() . '&amp;postaction=edit_table' . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['up'] . ']</a>';
  199. } else {
  200. $b .= '[' . $this->str['up'] . ']';
  201. }
  202. $b .= '</td><td class="button cell">';
  203. // The down button
  204. if ($field->getNext()) {
  205. $b .= '<a href="index.php?action=move_updown_field&amp;direction=down&amp;sesskey=' . sesskey() . '&amp;field=' . $field->getName() . '&amp;table=' . $table->getName() . '&amp;postaction=edit_table' . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['down'] . ']</a>';
  206. } else {
  207. $b .= '[' . $this->str['down'] . ']';
  208. }
  209. $b .= '</td><td class="button cell">';
  210. // The delete button (if we have more than one and it isn't used
  211. if (count($fields) > 1 &&
  212. !$structure->getFieldUses($table->getName(), $field->getName())) {
  213. $b .= '<a href="index.php?action=delete_field&amp;sesskey=' . sesskey() . '&amp;field=' . $field->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>';
  214. } else {
  215. $b .= '[' . $this->str['delete'] . ']';
  216. }
  217. $b .= '</td><td class="button cell">';
  218. // The view xml button
  219. $b .= '<a href="index.php?action=view_field_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;field=' . $field->getName() . '&amp;table=' . $table->getName() . '&amp;select=edited">[' . $this->str['viewxml'] . ']</a>';
  220. // Detect if the table name is a reserved word
  221. if (array_key_exists($field->getName(), $reserved_words)) {
  222. $b .= '&nbsp;<a href="index.php?action=view_reserved_words"><span class="error">' . $this->str['reserved'] . '</span></a>';
  223. }
  224. // The readable info
  225. $r = '</td><td class="readableinfo cell">' . $field->readableInfo() . '</td>';
  226. // Print table row
  227. $o .= '<tr class="r' . $row . '"><td class="table cell">' . $f . $b . $r . '</tr>';
  228. $row = ($row + 1) % 2;
  229. }
  230. $o .= '</table>';
  231. }
  232. // Add the keys list
  233. $keys = $table->getKeys();
  234. if (!empty($keys)) {
  235. $o .= '<h3 class="main">' . $this->str['keys'] . '</h3>';
  236. $o .= '<table id="listkeys" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">';
  237. $row = 0;
  238. foreach ($keys as $key) {
  239. // The key name (link to edit - if the key has no uses)
  240. if (!$structure->getKeyUses($table->getName(), $key->getName())) {
  241. $k = '<a href="index.php?action=edit_key&amp;key=' .$key->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">' . $key->getName() . '</a>';
  242. } else {
  243. $k = $key->getName();
  244. }
  245. // Calculate buttons
  246. $b = '</td><td class="button cell">';
  247. // The edit button (if the key hasn't uses)
  248. if (!$structure->getKeyUses($table->getName(), $key->getName())) {
  249. $b .= '<a href="index.php?action=edit_key&amp;key=' .$key->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>';
  250. } else {
  251. $b .= '[' . $this->str['edit'] . ']';
  252. }
  253. $b .= '</td><td class="button cell">';
  254. // The up button
  255. if ($key->getPrevious()) {
  256. $b .= '<a href="index.php?action=move_updown_key&amp;direction=up&amp;sesskey=' . sesskey() . '&amp;key=' . $key->getName() . '&amp;table=' . $table->getName() . '&amp;postaction=edit_table' . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['up'] . ']</a>';
  257. } else {
  258. $b .= '[' . $this->str['up'] . ']';
  259. }
  260. $b .= '</td><td class="button cell">';
  261. // The down button
  262. if ($key->getNext()) {
  263. $b .= '<a href="index.php?action=move_updown_key&amp;direction=down&amp;sesskey=' . sesskey() . '&amp;key=' . $key->getName() . '&amp;table=' . $table->getName() . '&amp;postaction=edit_table' . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['down'] . ']</a>';
  264. } else {
  265. $b .= '[' . $this->str['down'] . ']';
  266. }
  267. $b .= '</td><td class="button cell">';
  268. // The delete button (if the key hasn't uses)
  269. if (!$structure->getKeyUses($table->getName(), $key->getName())) {
  270. $b .= '<a href="index.php?action=delete_key&amp;sesskey=' . sesskey() . '&amp;key=' . $key->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>';
  271. } else {
  272. $b .= '[' . $this->str['delete'] . ']';
  273. }
  274. $b .= '</td><td class="button cell">';
  275. // The view xml button
  276. $b .= '<a href="index.php?action=view_key_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;key=' . $key->getName() . '&amp;table=' . $table->getName() . '&amp;select=edited">[' . $this->str['viewxml'] . ']</a>';
  277. // The readable info
  278. $r = '</td><td class="readableinfo cell">' . $key->readableInfo() . '</td>';
  279. // Print table row
  280. $o .= '<tr class="r' . $row . '"><td class="table cell">' . $k . $b . $r .'</tr>';
  281. $row = ($row + 1) % 2;
  282. }
  283. $o .= '</table>';
  284. }
  285. // Add the indexes list
  286. $indexes = $table->getIndexes();
  287. if (!empty($indexes)) {
  288. $o .= '<h3 class="main">' . $this->str['indexes'] . '</h3>';
  289. $o .= '<table id="listindexes" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">';
  290. $row = 0;
  291. foreach ($indexes as $index) {
  292. // The index name (link to edit)
  293. $i = '<a href="index.php?action=edit_index&amp;index=' .$index->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">' . $index->getName() . '</a>';
  294. // Calculate buttons
  295. $b = '</td><td class="button cell">';
  296. // The edit button
  297. $b .= '<a href="index.php?action=edit_index&amp;index=' .$index->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>';
  298. $b .= '</td><td class="button cell">';
  299. // The up button
  300. if ($index->getPrevious()) {
  301. $b .= '<a href="index.php?action=move_updown_index&amp;direction=up&amp;sesskey=' . sesskey() . '&amp;index=' . $index->getName() . '&amp;table=' . $table->getName() . '&amp;postaction=edit_table' . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['up'] . ']</a>';
  302. } else {
  303. $b .= '[' . $this->str['up'] . ']';
  304. }
  305. $b .= '</td><td class="button cell">';
  306. // The down button
  307. if ($index->getNext()) {
  308. $b .= '<a href="index.php?action=move_updown_index&amp;direction=down&amp;sesskey=' . sesskey() . '&amp;index=' . $index->getName() . '&amp;table=' . $table->getName() . '&amp;postaction=edit_table' . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['down'] . ']</a>';
  309. } else {
  310. $b .= '[' . $this->str['down'] . ']';
  311. }
  312. $b .= '</td><td class="button cell">';
  313. // The delete button
  314. $b .= '<a href="index.php?action=delete_index&amp;sesskey=' . sesskey() . '&amp;index=' . $index->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>';
  315. $b .= '</td><td class="button cell">';
  316. // The view xml button
  317. $b .= '<a href="index.php?action=view_index_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;index=' . $index->getName() . '&amp;table=' . $table->getName() . '&amp;select=edited">[' . $this->str['viewxml'] . ']</a>';
  318. // The readable info
  319. $r = '</td><td class="readableinfo cell">' . $index->readableInfo() . '</td>';
  320. // Print table row
  321. $o .= '<tr class="r' . $row . '"><td class="table cell">' . $i . $b . $r .'</tr>';
  322. $row = ($row + 1) % 2;
  323. }
  324. $o .= '</table>';
  325. }
  326. $this->output = $o;
  327. // Launch postaction if exists (leave this here!)
  328. if ($this->getPostAction() && $result) {
  329. return $this->launch($this->getPostAction());
  330. }
  331. // Return ok if arrived here
  332. return $result;
  333. }
  334. }