예제 #1
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_GENERATE_XML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     /// Get the file parameter
     $file = required_param('file', PARAM_PATH);
     $file = $CFG->dirroot . $file;
     /// File must be under $CFG->wwwroot and
     ///  under one db directory (simple protection)
     if (substr($file, 0, strlen($CFG->dirroot)) == $CFG->dirroot && substr(dirname($file), -2, 2) == 'db') {
         /// Everything is ok. Load the file to memory
         $this->output = file_get_contents($file);
     } else {
         /// Switch to HTML and error
         $this->does_generate = ACTION_GENERATE_HTML;
         $this->errormsg = 'File not viewable (' . $file . ')';
         $result = false;
     }
     /// Return ok if arrived here
     return $result;
 }
예제 #2
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     /// Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . $dirpath;
     /// Get the correct dirs
     if (!empty($XMLDB->dbdirs)) {
         $dbdir =& $XMLDB->dbdirs[$dirpath];
     } else {
         return false;
     }
     if (!empty($XMLDB->editeddirs)) {
         $editeddir =& $XMLDB->editeddirs[$dirpath];
         $structure =& $editeddir->xml_file->getStructure();
     }
     /// ADD YOUR CODE HERE
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
예제 #3
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     // Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     // These are always here
     global $CFG, $XMLDB;
     // Do the job, setting result as needed
     // Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . $dirpath;
     // Get the correct dirs
     if (!empty($XMLDB->dbdirs)) {
         $dbdir =& $XMLDB->dbdirs[$dirpath];
     } else {
         return false;
     }
     if (!empty($XMLDB->editeddirs)) {
         $editeddir =& $XMLDB->editeddirs[$dirpath];
         $structure =& $editeddir->xml_file->getStructure();
     }
     // If the changeme table exists, just get it and continue
     $changeme_exists = false;
     if ($tables =& $structure->getTables()) {
         if ($table =& $structure->getTable('changeme')) {
             $changeme_exists = true;
         }
     }
     if (!$changeme_exists) {
         // Lets create the table
         $field = new xmldb_field('id');
         $field->setType(XMLDB_TYPE_INTEGER);
         $field->setLength(10);
         $field->setNotNull(true);
         $field->setUnsigned(true);
         $field->setSequence(true);
         $field->setLoaded(true);
         $field->setChanged(true);
         $key = new xmldb_key('primary');
         $key->setType(XMLDB_KEY_PRIMARY);
         $key->setFields(array('id'));
         $key->setLoaded(true);
         $key->setChanged(true);
         $table = new xmldb_table('changeme');
         $table->setComment('Default comment for the table, please edit me');
         $table->addField($field);
         $table->addKey($key);
         // Finally, add the whole retrofitted table to the structure
         // in the place specified
         $structure->addTable($table);
     }
     // Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     // Return ok if arrived here
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting $result as needed
     /// Lets go to add all the db directories available inside Moodle
     /// Create the array if it doesn't exists
     if (!isset($XMLDB->dbdirs)) {
         $XMLDB->dbdirs = array();
     }
     /// get list of all dirs and create objects with status
     $db_direcotries = get_db_directories();
     foreach ($db_direcotries as $path) {
         $dbdir = new stdClass();
         $dbdir->path = $path;
         if (!isset($XMLDB->dbdirs[$dbdir->path])) {
             $XMLDB->dbdirs[$dbdir->path] = $dbdir;
         }
         $XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path);
         //Update status
     }
     /// Sort by key
     ksort($XMLDB->dbdirs);
     /// Return ok if arrived here
     return true;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_GENERATE_XML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     /// Get the file parameter
     $select = required_param('select', PARAM_ALPHA);
     //original/edited
     /// Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . stripslashes_safe($dirpath);
     /// Get the correct dir
     if ($select == 'original') {
         if (!empty($XMLDB->dbdirs)) {
             $base =& $XMLDB->dbdirs[$dirpath];
         }
     } else {
         if ($select == 'edited') {
             if (!empty($XMLDB->editeddirs)) {
                 $base =& $XMLDB->editeddirs[$dirpath];
             }
         } else {
             $this->errormsg = 'Cannot access to ' . $select . ' info';
             $result = false;
         }
     }
     if ($base) {
         /// Only if the directory exists and it has been loaded
         if (!$base->path_exists || !$base->xml_loaded) {
             $this->errormsg = 'Directory ' . $dirpath . ' not loaded';
             return false;
         }
     } else {
         $this->errormsg = 'Problem handling ' . $select . ' files';
         return false;
     }
     /// Get the structure
     if ($result) {
         if (!($structure =& $base->xml_file->getStructure())) {
             $this->errormsg = 'Error retrieving ' . $select . ' structure';
             $result = false;
         }
     }
     if ($result) {
         /// Everything is ok. Generate the XML output
         $this->output = $structure->xmlOutput();
     } else {
         /// Switch to HTML and error
         $this->does_generate = ACTION_GENERATE_HTML;
     }
     /// Return ok if arrived here
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting $result as needed
     /// Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . stripslashes_safe($dirpath);
     /// Get the correct dir
     if (!empty($XMLDB->dbdirs)) {
         $dbdir =& $XMLDB->dbdirs[$dirpath];
         if ($dbdir) {
             /// Set some defaults
             $dbdir->xml_exists = false;
             $dbdir->xml_writeable = false;
             $dbdir->xml_loaded = false;
             ///Only if the directory exists
             if (!$dbdir->path_exists) {
                 return false;
             }
             $xmldb_file = new XMLDBFile($dbdir->path . '/install.xml');
             ///Set the XML DTD and schema
             $xmldb_file->setDTD($CFG->dirroot . '/lib/xmldb/xmldb.dtd');
             $xmldb_file->setSchema($CFG->dirroot . '/lib/xmldb/xmldb.xsd');
             /// Set dbdir as necessary
             if ($xmldb_file->fileExists()) {
                 $dbdir->xml_exists = true;
             }
             if ($xmldb_file->fileWriteable()) {
                 $dbdir->xml_writeable = true;
             }
             /// Load the XML contents to structure
             $loaded = $xmldb_file->loadXMLStructure();
             if ($loaded && $xmldb_file->isLoaded()) {
                 $dbdir->xml_loaded = true;
                 $dbdir->filemtime = filemtime($dbdir->path . '/install.xml');
             }
             $dbdir->xml_file = $xmldb_file;
         } else {
             $this->errormsg = 'Wrong directory (' . $dirpath . ')';
             $result = false;
         }
     } else {
         $this->errormsg = 'XMLDB structure not found';
         $result = false;
     }
     /// Launch postaction if exists
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     return $result;
 }
예제 #7
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     // Set own core attributes
     $this->does_generate = ACTION_NONE;
     // These are always here
     global $CFG, $XMLDB;
     // Do the job, setting result as needed
     // Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . $dirpath;
     $unload = optional_param('unload', true, PARAM_BOOL);
     // Get the edited dir
     if (!empty($XMLDB->editeddirs)) {
         if (isset($XMLDB->editeddirs[$dirpath])) {
             $editeddir = $XMLDB->editeddirs[$dirpath];
         }
     }
     // Copy the edited dir over the original one
     if (!empty($XMLDB->dbdirs)) {
         if (isset($XMLDB->dbdirs[$dirpath])) {
             $XMLDB->dbdirs[$dirpath] = unserialize(serialize($editeddir));
             $dbdir = $XMLDB->dbdirs[$dirpath];
         }
     }
     // Check for perms
     if (!is_writeable($dirpath . '/install.xml')) {
         $this->errormsg = $this->str['filenotwriteable'] . '(' . $dirpath . '/install.xml)';
         return false;
     }
     // Save the original dir
     $result = $dbdir->xml_file->saveXMLFile();
     if ($result) {
         // Delete the edited dir
         unset($XMLDB->editeddirs[$dirpath]);
         // Unload de originaldir
         unset($XMLDB->dbdirs[$dirpath]->xml_file);
         unset($XMLDB->dbdirs[$dirpath]->xml_loaded);
         unset($XMLDB->dbdirs[$dirpath]->xml_changed);
         unset($XMLDB->dbdirs[$dirpath]->xml_exists);
         unset($XMLDB->dbdirs[$dirpath]->xml_writeable);
     } else {
         $this->errormsg = 'Error saving XML file (' . $dirpath . ')';
         return false;
     }
     // If unload has been disabled, simulate it by reloading the file now
     if (!$unload) {
         return $this->launch('load_xml_file');
     }
     // Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     // Return ok if arrived here
     return $result;
 }
예제 #8
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB, $DB;
     $dbman = $DB->get_manager();
     /// Do the job, setting result as needed
     /// Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . $dirpath;
     /// Get the correct dirs
     if (!empty($XMLDB->dbdirs)) {
         $dbdir =& $XMLDB->dbdirs[$dirpath];
     } else {
         return false;
     }
     if (!empty($XMLDB->editeddirs)) {
         $editeddir =& $XMLDB->editeddirs[$dirpath];
         $structure =& $editeddir->xml_file->getStructure();
     }
     /// ADD YOUR CODE HERE
     /// Get parameters
     $tableparam = required_param('table', PARAM_PATH);
     if (!($table = $structure->getTable($tableparam))) {
         $this->errormsg = 'Wrong table specified: ' . $tableparam;
         return false;
     }
     /// The back to edit table button
     $b = ' <p class="centerpara buttons">';
     $b .= '<a href="index.php?action=edit_table&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
     $b .= '</p>';
     $o = $b;
     $o .= '    <table id="formelements" class="boxaligncenter" cellpadding="5">';
     $o .= '      <tr><td><textarea cols="80" rows="32">';
     /// Get an array of statements
     if ($starr = $DB->get_manager()->generator->getCreateTableSQL($table)) {
         $starr = $dbman->generator->getEndedStatements($starr);
         $sqltext = '';
         foreach ($starr as $st) {
             $sqltext .= s($st) . "\n\n";
         }
         $sqltext = trim($sqltext);
         $o .= $sqltext;
     }
     $o .= '</textarea></td></tr>';
     $o .= '    </table>';
     $this->output = $o;
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     /// Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . stripslashes_safe($dirpath);
     $confirmed = optional_param('confirmed', false, PARAM_BOOL);
     /// If  not confirmed, show confirmation box
     if (!$confirmed) {
         $o = '<table width="60" class="generalbox boxaligncenter" border="0" cellpadding="5" cellspacing="0" id="notice">';
         $o .= '  <tr><td class="generalboxcontent">';
         $o .= '    <p class="centerpara">' . $this->str['confirmrevertchanges'] . '<br /><br />' . $dirpath . '</p>';
         $o .= '    <table class="boxaligncenter" cellpadding="20"><tr><td>';
         $o .= '      <div class="singlebutton">';
         $o .= '        <form action="index.php?action=revert_changes&amp;sesskey=' . sesskey() . '&amp;confirmed=yes&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;postaction=main_view#lastused" method="post"><fieldset class="invisiblefieldset">';
         $o .= '          <input type="submit" value="' . $this->str['yes'] . '" /></fieldset></form></div>';
         $o .= '      </td><td>';
         $o .= '      <div class="singlebutton">';
         $o .= '        <form action="index.php?action=main_view#lastused" method="post"><fieldset class="invisiblefieldset">';
         $o .= '          <input type="submit" value="' . $this->str['no'] . '" /></fieldset></form></div>';
         $o .= '      </td></tr>';
         $o .= '    </table>';
         $o .= '  </td></tr>';
         $o .= '</table>';
         $this->output = $o;
     } else {
         /// Get the original dir and delete some elements
         if (!empty($XMLDB->dbdirs)) {
             if (isset($XMLDB->dbdirs[$dirpath])) {
                 $dbdir =& $XMLDB->dbdirs[$dirpath];
                 if ($dbdir) {
                     unset($dbdir->xml_changed);
                 }
             }
         }
         /// Get the edited dir and delete it completely
         if (!empty($XMLDB->editeddirs)) {
             if (isset($XMLDB->editeddirs[$dirpath])) {
                 unset($XMLDB->editeddirs[$dirpath]);
             }
         }
     }
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
예제 #10
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     /// Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . stripslashes_safe($dirpath);
     /// Get the correct dirs
     if (!empty($XMLDB->dbdirs)) {
         $dbdir =& $XMLDB->dbdirs[$dirpath];
     } else {
         return false;
     }
     if (!empty($XMLDB->editeddirs)) {
         $editeddir =& $XMLDB->editeddirs[$dirpath];
         $structure =& $editeddir->xml_file->getStructure();
     }
     /// ADD YOUR CODE HERE
     $statementparam = required_param('statement', PARAM_CLEAN);
     $basesentenceparam = optional_param('basesentence', NULL, PARAM_CLEAN);
     $statement =& $structure->getStatement($statementparam);
     $sentences =& $statement->getSentences();
     $sentence = NULL;
     /// If some sentence has been specified, create the new one
     /// based on it
     if (!empty($basesentenceparam)) {
         $sentence = $sentences[$basesentenceparam];
     }
     /// Else, try to create the new one based in the last
     if (empty($sentence) && !empty($sentences)) {
         $sentence = end($sentences);
     }
     /// Else, create one sentence by hand
     if (empty($sentence)) {
         $sentence = "(list, of, fields) VALUES ('list', 'of', 'values')";
     }
     /// Add the sentence to the statement
     $statement->addSentence($sentence);
     /// We have one new sentence, so the statement and the structure has changed
     $statement->setChanged(true);
     $structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
     $structure->setChanged(true);
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
예제 #11
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     /// Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . $dirpath;
     $statementparam = required_param('statement', PARAM_CLEAN);
     $confirmed = optional_param('confirmed', false, PARAM_BOOL);
     /// If  not confirmed, show confirmation box
     if (!$confirmed) {
         $o = '<table width="60" class="generalbox" border="0" cellpadding="5" cellspacing="0" id="notice">';
         $o .= '  <tr><td class="generalboxcontent">';
         $o .= '    <p class="centerpara">' . $this->str['confirmdeletestatement'] . '<br /><br />' . $statementparam . '</p>';
         $o .= '    <table class="boxaligncenter" cellpadding="20"><tr><td>';
         $o .= '      <div class="singlebutton">';
         $o .= '        <form action="index.php?action=delete_statement&amp;confirmed=yes&amp;postaction=edit_xml_file&amp;statement=' . $statementparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '" method="post"><fieldset class="invisiblefieldset">';
         $o .= '          <input type="submit" value="' . $this->str['yes'] . '" /></fieldset></form></div>';
         $o .= '      </td><td>';
         $o .= '      <div class="singlebutton">';
         $o .= '        <form action="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '" method="post"><fieldset class="invisiblefieldset">';
         $o .= '          <input type="submit" value="' . $this->str['no'] . '" /></fieldset></form></div>';
         $o .= '      </td></tr>';
         $o .= '    </table>';
         $o .= '  </td></tr>';
         $o .= '</table>';
         $this->output = $o;
     } else {
         /// Get the edited dir
         if (!empty($XMLDB->editeddirs)) {
             if (isset($XMLDB->editeddirs[$dirpath])) {
                 $dbdir =& $XMLDB->dbdirs[$dirpath];
                 $editeddir =& $XMLDB->editeddirs[$dirpath];
                 if ($editeddir) {
                     $structure =& $editeddir->xml_file->getStructure();
                     /// Remove the table
                     $structure->deleteStatement($statementparam);
                 }
             }
         }
     }
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting $result as needed
     /// Add link back to home
     $b = ' <p class="centerpara buttons">';
     $b .= '&nbsp;<a href="index.php?action=main_view#lastused">[' . $this->str['backtomainview'] . ']</a>';
     $b .= '</p>';
     $this->output = $b;
     $c = ' <p class="centerpara">';
     $c .= $this->str['documentationintro'];
     $c .= '</p>';
     $this->output .= $c;
     $this->docs = '';
     if (class_exists('XSLTProcessor')) {
         $doc = new DOMDocument();
         $xsl = new XSLTProcessor();
         $doc->load(dirname(__FILE__) . '/../generate_documentation/xmldb.xsl');
         $xsl->importStyleSheet($doc);
         $dbdirs = get_db_directories();
         sort($dbdirs);
         $index = $this->str['docindex'] . ' ';
         foreach ($dbdirs as $path) {
             if (!file_exists($path . '/install.xml')) {
                 continue;
             }
             $dir = trim(dirname(str_replace($CFG->dirroot, '', $path)), '/');
             $index .= '<a href="#file_' . str_replace('/', '_', $dir) . '">' . $dir . '</a>, ';
             $this->docs .= '<div class="file" id="file_' . str_replace('/', '_', $dir) . '">';
             $this->docs .= '<h2>' . $dir . '</h2>';
             $doc->load($path . '/install.xml');
             $this->docs .= $xsl->transformToXML($doc);
             $this->docs .= '</div>';
         }
         $this->output .= '<div id="file_idex">' . trim($index, ' ,') . '</div>' . $this->docs;
         $this->output .= $b;
     } else {
         $this->output .= get_string('extensionrequired', 'tool_xmldb', 'xsl');
     }
     /// Launch postaction if exists (leave this unmodified)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     return $result;
 }
예제 #13
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     /// Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . stripslashes_safe($dirpath);
     /// Get the correct dirs
     if (!empty($XMLDB->dbdirs)) {
         $dbdir =& $XMLDB->dbdirs[$dirpath];
     } else {
         return false;
     }
     if (!empty($XMLDB->editeddirs)) {
         $editeddir =& $XMLDB->editeddirs[$dirpath];
         $structure =& $editeddir->xml_file->getStructure();
     }
     /// ADD YOUR CODE HERE
     $tableparam = required_param('table', PARAM_CLEAN);
     $table =& $structure->getTable($tableparam);
     /// If the changeme field exists, just get it and continue
     $changeme_exists = false;
     if ($fields =& $table->getFields()) {
         if ($field =& $table->getField('changeme')) {
             $changeme_exists = true;
         }
     }
     if (!$changeme_exists) {
         /// Lets create the field
         $field = new XMLDBField('changeme');
         $field->setComment('Default comment for the field, please edit me');
         $table->addField($field);
         /// We have one new field, so the structure has changed
         $structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
         $structure->setChanged(true);
     }
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     // Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     // These are always here
     global $CFG, $XMLDB;
     // Do the job, setting result as needed
     // Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $plugintype = $this->get_plugin_type($dirpath);
     $dirpath = $CFG->dirroot . $dirpath;
     $file = $dirpath . '/install.xml';
     // Some variables
     $xmlpath = dirname(str_replace($CFG->dirroot . '/', '', $file));
     $xmlversion = userdate(time(), '%Y%m%d', 99, false);
     $xmlcomment = 'XMLDB file for Moodle ' . dirname($xmlpath);
     $xmltable = strtolower(basename(dirname($xmlpath)));
     if ($plugintype && $plugintype != 'mod') {
         $xmltable = $plugintype . '_' . $xmltable;
     }
     // Initial contents
     $c = '<?xml version="1.0" encoding="UTF-8" ?>' . "\n";
     $c .= '  <XMLDB PATH="' . $xmlpath . '" VERSION="' . $xmlversion . '" COMMENT="' . $xmlcomment . '">' . "\n";
     $c .= '    <TABLES>' . "\n";
     $c .= '      <TABLE NAME="' . $xmltable . '" COMMENT="Default comment for ' . $xmltable . ', please edit me">' . "\n";
     $c .= '        <FIELDS>' . "\n";
     $c .= '          <FIELD NAME="id" TYPE="int" LENGTH="10" UNSIGNED="true" NOTNULL="true" SEQUENCE="true" />' . "\n";
     $c .= '        </FIELDS>' . "\n";
     $c .= '        <KEYS>' . "\n";
     $c .= '          <KEY NAME="primary" TYPE="primary" FIELDS="id" />' . "\n";
     $c .= '        </KEYS>' . "\n";
     $c .= '      </TABLE>' . "\n";
     $c .= '    </TABLES>' . "\n";
     $c .= '  </XMLDB>';
     if (!file_put_contents($file, $c)) {
         $errormsg = 'Error creando fichero ' . $file;
         $result = false;
     }
     // Launch postaction if exists
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     // Return ok if arrived here
     return $result;
 }
예제 #15
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     // Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     // These are always here
     global $CFG, $XMLDB;
     // Do the job, setting result as needed
     // Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . $dirpath;
     // Get the correct dirs
     if (!empty($XMLDB->dbdirs)) {
         $dbdir = $XMLDB->dbdirs[$dirpath];
     } else {
         return false;
     }
     if (!empty($XMLDB->editeddirs)) {
         $editeddir = $XMLDB->editeddirs[$dirpath];
         $structure = $editeddir->xml_file->getStructure();
     }
     $tableparam = required_param('table', PARAM_CLEAN);
     $table = $structure->getTable($tableparam);
     // If the changeme index exists, just get it and continue
     $changeme_exists = false;
     if ($indexes = $table->getIndexes()) {
         if ($index = $table->getIndex('changeme')) {
             $changeme_exists = true;
         }
     }
     if (!$changeme_exists) {
         // Lets create the Index
         $index = new xmldb_index('changeme');
         $table->addIndex($index);
         // We have one new key, so the structure has changed
         $structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
         $structure->setChanged(true);
     }
     // Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     // Return ok if arrived here
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     /// Get parameters
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . stripslashes_safe($dirpath);
     $statementparam = strtolower(required_param('statement', PARAM_CLEAN));
     $name = trim(strtolower(required_param('name', PARAM_CLEAN)));
     $comment = required_param('comment', PARAM_CLEAN);
     $comment = stripslashes_safe($comment);
     $editeddir =& $XMLDB->editeddirs[$dirpath];
     $structure =& $editeddir->xml_file->getStructure();
     $statement =& $structure->getStatement($statementparam);
     $errors = array();
     /// To store all the errors found
     /// If there is one name change, do it, changing the prev and next
     /// atributes of the adjacent tables
     if ($statementparam != $name) {
         $statement->setName($name);
         if ($statement->getPrevious()) {
             $prev =& $structure->getStatement($statement->getPrevious());
             $prev->setNext($name);
             $prev->setChanged(true);
         }
         if ($statement->getNext()) {
             $next =& $structure->getStatement($statement->getNext());
             $next->setPrevious($name);
             $next->setChanged(true);
         }
     }
     /// Set comment
     $statement->setComment($comment);
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     // Set own core attributes
     $this->does_generate = ACTION_GENERATE_HTML;
     // These are always here
     global $CFG, $XMLDB;
     // Do the job, setting $result as needed
     // Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . $dirpath;
     $path = $dirpath . '/install.xml';
     if (!file_exists($path) || !is_readable($path)) {
         return false;
     }
     // Add link back to home
     $b = ' <p class="centerpara buttons">';
     $b .= '&nbsp;<a href="index.php?action=main_view#lastused">[' . $this->str['backtomainview'] . ']</a>';
     $b .= '</p>';
     $this->output = $b;
     $c = ' <p class="centerpara">';
     $c .= $this->str['documentationintro'];
     $c .= '</p>';
     $this->output .= $c;
     if (class_exists('XSLTProcessor')) {
         // Transform XML file and display it
         $doc = new DOMDocument();
         $xsl = new XSLTProcessor();
         $doc->load(__DIR__ . '/xmldb.xsl');
         $xsl->importStyleSheet($doc);
         $doc->load($path);
         $this->output .= $xsl->transformToXML($doc);
         $this->output .= $b;
     } else {
         $this->output .= get_string('extensionrequired', 'tool_xmldb', 'xsl');
     }
     // Launch postaction if exists (leave this unmodified)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     return $result;
 }
예제 #18
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting $result as needed
     /// Iterate over $XMLDB->dbdirs, loading their XML data to memory
     if ($XMLDB->dbdirs) {
         $dbdirs =& $XMLDB->dbdirs;
         foreach ($dbdirs as $dbdir) {
             /// Set some defaults
             $dbdir->xml_exists = false;
             $dbdir->xml_writeable = false;
             $dbdir->xml_loaded = false;
             ///Only if the directory exists
             if (!$dbdir->path_exists) {
                 continue;
             }
             $xmldb_file = new xmldb_file($dbdir->path . '/install.xml');
             /// Set dbdir as necessary
             if ($xmldb_file->fileExists()) {
                 $dbdir->xml_exists = true;
             }
             if ($xmldb_file->fileWriteable()) {
                 $dbdir->xml_writeable = true;
             }
             /// Load the XML contents to structure
             $loaded = $xmldb_file->loadXMLStructure();
             if ($loaded && $xmldb_file->isLoaded()) {
                 $dbdir->xml_loaded = true;
             }
             $dbdir->xml_file = $xmldb_file;
         }
     }
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     if (!data_submitted()) {
         ///Basic prevention
         print_error('wrongcall', 'error');
     }
     /// Get parameters
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . $dirpath;
     $comment = required_param('comment', PARAM_CLEAN);
     $comment = $comment;
     /// Set comment and recalculate hash
     $editeddir =& $XMLDB->editeddirs[$dirpath];
     $structure =& $editeddir->xml_file->getStructure();
     $structure->setComment($comment);
     $structure->calculateHash(true);
     /// If the hash has changed from the original one, change the version
     /// and mark the structure as changed
     $origdir =& $XMLDB->dbdirs[$dirpath];
     $origstructure =& $origdir->xml_file->getStructure();
     if ($structure->getHash() != $origstructure->getHash()) {
         $structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
         $structure->setChanged(true);
     }
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     /// Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . stripslashes_safe($dirpath);
     /// Get the original dir and delete some elements
     if (!empty($XMLDB->dbdirs)) {
         if (isset($XMLDB->dbdirs[$dirpath])) {
             $dbdir =& $XMLDB->dbdirs[$dirpath];
             if ($dbdir) {
                 unset($dbdir->xml_file);
                 unset($dbdir->xml_loaded);
                 unset($dbdir->xml_changed);
                 unset($dbdir->xml_exists);
                 unset($dbdir->xml_writeable);
             }
         }
     }
     /// Get the edited dir and delete it completely
     if (!empty($XMLDB->editeddirs)) {
         if (isset($XMLDB->editeddirs[$dirpath])) {
             unset($XMLDB->editeddirs[$dirpath]);
         }
     }
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
예제 #21
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     // Set own core attributes
     $this->does_generate = ACTION_GENERATE_HTML;
     // These are always here
     global $CFG, $XMLDB, $DB, $OUTPUT;
     // Do the job, setting result as needed
     // Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . $dirpath;
     // Get the correct dirs
     if (!empty($XMLDB->dbdirs)) {
         $dbdir = $XMLDB->dbdirs[$dirpath];
     } else {
         return false;
     }
     if (!empty($XMLDB->editeddirs)) {
         $editeddir = $XMLDB->editeddirs[$dirpath];
         $structure = $editeddir->xml_file->getStructure();
     }
     $tableparam = optional_param('table', NULL, PARAM_CLEAN);
     // If no table, show form
     if (!$tableparam) {
         // No postaction here
         $this->postaction = NULL;
         // Get list of tables
         $dbtables = $DB->get_tables();
         $selecttables = array();
         foreach ($dbtables as $dbtable) {
             $i = $structure->findTableInArray($dbtable);
             if ($i === NULL) {
                 $selecttables[$dbtable] = $dbtable;
             }
         }
         // Get list of after tables
         $aftertables = array();
         if ($tables = $structure->getTables()) {
             foreach ($tables as $aftertable) {
                 $aftertables[$aftertable->getName()] = $aftertable->getName();
             }
         }
         if (!$selecttables) {
             $this->errormsg = 'No tables available to be retrofitted';
             return false;
         }
         // Now build the form
         $o = '<form id="form" action="index.php" method="post">';
         $o .= '<div>';
         $o .= '    <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
         $o .= '    <input type="hidden" name ="action" value="new_table_from_mysql" />';
         $o .= '    <input type="hidden" name ="postaction" value="edit_table" />';
         $o .= '    <input type="hidden" name ="sesskey" value="' . sesskey() . '" />';
         $o .= '    <table id="formelements" class="boxaligncenter" cellpadding="5">';
         $o .= '      <tr><td><label for="menutable" accesskey="t">' . $this->str['createtable'] . ' </label>' . html_writer::select($selecttables, 'table') . '<label for="menuafter" accesskey="a">' . $this->str['aftertable'] . ' </label>' . html_writer::select($aftertables, 'after') . '</td></tr>';
         $o .= '      <tr><td colspan="2" align="center"><input type="submit" value="' . $this->str['create'] . '" /></td></tr>';
         $o .= '      <tr><td colspan="2" align="center"><a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a></td></tr>';
         $o .= '    </table>';
         $o .= '</div></form>';
         $this->output = $o;
         // If table, retrofit information and, if everything works,
         // go to the table edit action
     } else {
         // Get some params (table is mandatory here)
         $tableparam = required_param('table', PARAM_CLEAN);
         $afterparam = required_param('after', PARAM_CLEAN);
         // Create one new xmldb_table
         $table = new xmldb_table(strtolower(trim($tableparam)));
         $table->setComment($table->getName() . ' table retrofitted from MySQL');
         // Get fields info from ADODb
         $dbfields = $DB->get_columns($tableparam);
         if ($dbfields) {
             foreach ($dbfields as $dbfield) {
                 // Create new XMLDB field
                 $field = new xmldb_field($dbfield->name);
                 // Set field with info retrofitted
                 $field->setFromADOField($dbfield);
                 // Add field to the table
                 $table->addField($field);
             }
         }
         // Get PK, UK and indexes info from ADODb
         $dbindexes = $DB->get_indexes($tableparam);
         if ($dbindexes) {
             $lastkey = NULL;
             //To temp store the last key processed
             foreach ($dbindexes as $indexname => $dbindex) {
                 // Add the indexname to the array
                 $dbindex['name'] = $indexname;
                 // We are handling one xmldb_key (primaries + uniques)
                 if ($dbindex['unique']) {
                     $key = new xmldb_key(strtolower($dbindex['name']));
                     // Set key with info retrofitted
                     $key->setFromADOKey($dbindex);
                     // Set default comment to PKs
                     if ($key->getType() == XMLDB_KEY_PRIMARY) {
                     }
                     // Add key to the table
                     $table->addKey($key);
                     // We are handling one xmldb_index (non-uniques)
                 } else {
                     $index = new xmldb_index(strtolower($dbindex['name']));
                     // Set index with info retrofitted
                     $index->setFromADOIndex($dbindex);
                     // Add index to the table
                     $table->addIndex($index);
                 }
             }
         }
         // Finally, add the whole retroffited table to the structure
         // in the place specified
         $structure->addTable($table, $afterparam);
     }
     // Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     // Return ok if arrived here
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     //$this->does_generate = ACTION_NONE;
     $this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting $result as needed
     /// Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . stripslashes_safe($dirpath);
     /// Get the correct dir
     if (!empty($XMLDB->dbdirs)) {
         $dbdir =& $XMLDB->dbdirs[$dirpath];
         if ($dbdir) {
             /// Only if the directory exists and it has been loaded
             if (!$dbdir->path_exists || !$dbdir->xml_loaded) {
                 return false;
             }
             /// Check if the in-memory object exists and create it
             if (empty($XMLDB->editeddirs)) {
                 $XMLDB->editeddirs = array();
             }
             /// Check if the dir exists and copy it from dbdirs
             if (!isset($XMLDB->editeddirs[$dirpath])) {
                 $XMLDB->editeddirs[$dirpath] = unserialize(serialize($dbdir));
             }
             /// Get it
             $editeddir =& $XMLDB->editeddirs[$dirpath];
             $structure =& $editeddir->xml_file->getStructure();
             /// Add the main form
             $o = '<form id="form" action="index.php" method="post">';
             $o .= '<div>';
             $o .= '    <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
             $o .= '    <input type="hidden" name ="action" value="edit_xml_file_save" />';
             $o .= '    <input type="hidden" name ="postaction" value="edit_xml_file" />';
             $o .= '    <input type="hidden" name ="path" value="' . s($structure->getPath()) . '" />';
             $o .= '    <input type="hidden" name ="version" value="' . s($structure->getVersion()) . '" />';
             $o .= '    <table id="formelements" class="boxaligncenter">';
             $o .= '      <tr valign="top"><td>Path:</td><td>' . s($structure->getPath()) . '</td></tr>';
             $o .= '      <tr valign="top"><td>Version:</td><td>' . s($structure->getVersion()) . '</td></tr>';
             $o .= '      <tr valign="top"><td><label for="comment" accesskey="c">Comment:</label></td><td><textarea name="comment" rows="3" cols="80" id="comment">' . $structure->getComment() . '</textarea></td></tr>';
             $o .= '      <tr><td>&nbsp;</td><td><input type="submit" value="' . $this->str['change'] . '" /></td></tr>';
             $o .= '    </table>';
             $o .= '</div></form>';
             /// Calculate the buttons
             $b = ' <p class="centerpara buttons">';
             /// The view original XML button
             $b .= '&nbsp;<a href="index.php?action=view_structure_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=original">[' . $this->str['vieworiginal'] . ']</a>';
             /// The view edited XML button
             if ($structure->hasChanged()) {
                 $b .= '&nbsp;<a href="index.php?action=view_structure_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=edited">[' . $this->str['viewedited'] . ']</a>';
             } else {
                 $b .= '&nbsp;[' . $this->str['viewedited'] . ']';
             }
             /// The new table button
             $b .= '&nbsp;<a href="index.php?action=new_table&amp;postaction=edit_table&amp;table=changeme&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newtable'] . ']</a>';
             /// The new from MySQL button
             if ($CFG->dbfamily == 'mysql') {
                 $b .= '&nbsp;<a href="index.php?action=new_table_from_mysql&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newtablefrommysql'] . ']</a>';
             } else {
                 $b .= '&nbsp;[' . $this->str['newtablefrommysql'] . ']';
             }
             /// The new statement button
             $b .= '&nbsp;<a href="index.php?action=new_statement&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newstatement'] . ']</a>';
             /// The back to main menu button
             $b .= '&nbsp;<a href="index.php?action=main_view#lastused">[' . $this->str['backtomainview'] . ']</a>';
             $b .= '</p>';
             $b .= ' <p class="centerpara buttons">';
             /// The view sql code button
             $b .= '<a href="index.php?action=view_structure_sql&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['viewsqlcode'] . ']</a>';
             /// The view php code button
             $b .= '&nbsp;<a href="index.php?action=view_structure_php&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['viewphpcode'] . ']</a>';
             $b .= '</p>';
             $o .= $b;
             /// Join all the reserved words into one big array
             /// Calculate list of available SQL generators
             $plugins = get_list_of_plugins('lib/xmldb/classes/generators');
             $reserved_words = array();
             foreach ($plugins as $plugin) {
                 $classname = 'XMLDB' . $plugin;
                 $generator = new $classname();
                 $reserved_words = array_merge($reserved_words, $generator->getReservedWords());
             }
             sort($reserved_words);
             $reserved_words = array_unique($reserved_words);
             /// Add the tables list
             $tables =& $structure->getTables();
             if ($tables) {
                 $o .= '<h3 class="main">' . $this->str['tables'] . '</h3>';
                 $o .= '<table id="listtables" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">';
                 $row = 0;
                 foreach ($tables as $table) {
                     /// Calculate buttons
                     $b = '</td><td class="button cell">';
                     /// The edit button
                     $b .= '<a href="index.php?action=edit_table&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>';
                     $b .= '</td><td class="button cell">';
                     /// The up button
                     if ($table->getPrevious()) {
                         $b .= '<a href="index.php?action=move_updown_table&amp;direction=up&amp;table=' . $table->getName() . '&amp;postaction=edit_xml_file' . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['up'] . ']</a>';
                     } else {
                         $b .= '[' . $this->str['up'] . ']';
                     }
                     $b .= '</td><td class="button cell">';
                     /// The down button
                     if ($table->getNext()) {
                         $b .= '<a href="index.php?action=move_updown_table&amp;direction=down&amp;table=' . $table->getName() . '&amp;postaction=edit_xml_file' . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['down'] . ']</a>';
                     } else {
                         $b .= '[' . $this->str['down'] . ']';
                     }
                     $b .= '</td><td class="button cell">';
                     /// The delete button (if we have more than one and it isn't used)
                     if (count($tables) > 1 && !$structure->getTableUses($table->getName())) {
                         ///!$structure->getTableUses($table->getName())) {
                         $b .= '<a href="index.php?action=delete_table&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>';
                     } else {
                         $b .= '[' . $this->str['delete'] . ']';
                     }
                     /// Detect if the table name is a reserved word
                     if (in_array($table->getName(), $reserved_words)) {
                         $b .= '&nbsp;<a href="index.php?action=view_reserved_words"><span class="error">' . $this->str['reserved'] . '</span></a>';
                     }
                     $b .= '</td>';
                     /// Print table row
                     $o .= '<tr class="r' . $row . '"><td class="table cell"><a href="index.php?action=view_table_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;table=' . $table->getName() . '&amp;select=edited">' . $table->getName() . '</a>' . $b . '</tr>';
                     $row = ($row + 1) % 2;
                 }
                 $o .= '</table>';
             }
             ///Add the statements list
             $statements =& $structure->getStatements();
             if ($statements) {
                 $o .= '<h3 class="main">' . $this->str['statements'] . '</h3>';
                 $o .= '<table id="liststatements" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">';
                 $row = 0;
                 foreach ($statements as $statement) {
                     /// Calculate buttons
                     $b = '</td><td class="button cell">';
                     /// The edit button
                     $b .= '<a href="index.php?action=edit_statement&amp;statement=' . $statement->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>';
                     $b .= '</td><td class="button cell">';
                     /// The up button
                     if ($statement->getPrevious()) {
                         $b .= '<a href="index.php?action=move_updown_statement&amp;direction=up&amp;statement=' . $statement->getName() . '&amp;postaction=edit_xml_file' . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['up'] . ']</a>';
                     } else {
                         $b .= '[' . $this->str['up'] . ']';
                     }
                     $b .= '</td><td class="button cell">';
                     /// The down button
                     if ($statement->getNext()) {
                         $b .= '<a href="index.php?action=move_updown_statement&amp;direction=down&amp;statement=' . $statement->getName() . '&amp;postaction=edit_xml_file' . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['down'] . ']</a>';
                     } else {
                         $b .= '[' . $this->str['down'] . ']';
                     }
                     $b .= '</td><td class="button cell">';
                     /// The delete button
                     $b .= '<a href="index.php?action=delete_statement&amp;statement=' . $statement->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>';
                     $b .= '</td>';
                     /// Print statement row
                     $o .= '<tr class="r' . $row . '"><td class="statement cell"><a href="index.php?action=view_statement_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;statement=' . $statement->getName() . '&amp;select=edited">' . $statement->getName() . '</a>' . $b . '</tr>';
                     $row = ($row + 1) % 2;
                 }
                 $o .= '</table>';
             }
             ///Add the back to main
             $this->output = $o;
         }
     }
     /// Launch postaction if exists (leave this unmodified)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB, $db;
     /// Do the job, setting result as needed
     /// Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . stripslashes_safe($dirpath);
     /// Get the correct dirs
     if (!empty($XMLDB->dbdirs)) {
         $dbdir =& $XMLDB->dbdirs[$dirpath];
     } else {
         return false;
     }
     if (!empty($XMLDB->editeddirs)) {
         $editeddir =& $XMLDB->editeddirs[$dirpath];
         $structure =& $editeddir->xml_file->getStructure();
     }
     /// ADD YOUR CODE HERE
     $tableparam = optional_param('table', NULL, PARAM_CLEAN);
     $typeparam = optional_param('type', NULL, PARAM_CLEAN);
     /// If no table or type, show form
     if (!$tableparam || !$typeparam) {
         /// No postaction here
         $this->postaction = NULL;
         /// Get list of tables
         $dbtables = $db->MetaTables('TABLES');
         $selecttables = array();
         foreach ($dbtables as $dbtable) {
             $dbtable = str_replace($CFG->prefix, '', $dbtable);
             $selecttables[$dbtable] = $dbtable;
         }
         /// Get list of statement types
         $typeoptions = array(XMLDB_STATEMENT_INSERT => XMLDBStatement::getXMLDBStatementName(XMLDB_STATEMENT_INSERT), XMLDB_STATEMENT_UPDATE => XMLDBStatement::getXMLDBStatementName(XMLDB_STATEMENT_UPDATE), XMLDB_STATEMENT_DELETE => XMLDBStatement::getXMLDBStatementName(XMLDB_STATEMENT_DELETE), XMLDB_STATEMENT_CUSTOM => XMLDBStatement::getXMLDBStatementName(XMLDB_STATEMENT_CUSTOM));
         if (!$selecttables) {
             $this->errormsg = 'No tables available to create statements';
             return false;
         }
         /// Now build the form
         $o = '<form id="form" action="index.php" method="post">';
         $o .= '<div>';
         $o .= '    <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
         $o .= '    <input type="hidden" name ="action" value="new_statement" />';
         $o .= '    <input type="hidden" name ="postaction" value="edit_statement" />';
         $o .= '    <input type="hidden" name ="sesskey" value="' . sesskey() . '" />';
         $o .= '    <table id="formelements" class="boxaligncenter" cellpadding="5">';
         $o .= '      <tr><td><label for="type" accesskey="t">' . $this->str['statementtype'] . ' </label>' . choose_from_menu($typeoptions, 'type', '', 'choose', '', 0, true) . '<label for="table" accesskey="a">' . $this->str['statementtable'] . ' </label>' . choose_from_menu($selecttables, 'table', '', 'choose', '', 0, true) . '</td></tr>';
         $o .= '      <tr><td colspan="2" align="center"><input type="submit" value="' . $this->str['create'] . '" /></td></tr>';
         $o .= '      <tr><td colspan="2" align="center"><a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a></td></tr>';
         $o .= '    </table>';
         $o .= '</div></form>';
         $this->output = $o;
         /// If table, retrofit information and, if everything works,
         /// go to the table edit action
     } else {
         /// Get some params (table is mandatory here)
         $tableparam = required_param('table', PARAM_CLEAN);
         $typeparam = required_param('type', PARAM_CLEAN);
         /// Only insert is allowed :-/
         if ($typeparam != XMLDB_STATEMENT_INSERT) {
             $this->errormsg = 'Only insert of records is supported';
             return false;
         }
         /// Calculate the name of the statement
         $typename = XMLDBStatement::getXMLDBStatementName($typeparam);
         $name = trim(strtolower($typename . ' ' . $tableparam));
         /// Check that this Statement hasn't been created before
         if ($structure->getStatement($name)) {
             $this->errormsg = 'The statement "' . $name . '" already exists, please use it to add more sentences';
             return false;
         }
         /// Create one new XMLDBStatement
         $statement = new XMLDBStatement($name);
         $statement->setType($typeparam);
         $statement->setTable($tableparam);
         $statement->setComment('Initial ' . $typename . ' of records on table ' . $tableparam);
         /// Finally, add the whole retroffited table to the structure
         /// in the place specified
         $structure->addStatement($statement);
     }
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     /// Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . stripslashes_safe($dirpath);
     /// Get the correct dirs
     if (!empty($XMLDB->dbdirs)) {
         $dbdir =& $XMLDB->dbdirs[$dirpath];
     } else {
         return false;
     }
     if (!empty($XMLDB->editeddirs)) {
         $editeddir =& $XMLDB->editeddirs[$dirpath];
         $structure =& $editeddir->xml_file->getStructure();
     }
     /// ADD YOUR CODE HERE
     $prev = NULL;
     $next = NULL;
     $tableparam = required_param('table', PARAM_CLEAN);
     $indexparam = required_param('index', PARAM_CLEAN);
     $direction = required_param('direction', PARAM_ALPHA);
     $tables =& $structure->getTables();
     $table =& $structure->getTable($tableparam);
     $indexes =& $table->getIndexes();
     if ($direction == 'down') {
         $index =& $table->getIndex($indexparam);
         $swap =& $table->getIndex($index->getNext());
     } else {
         $swap =& $table->getIndex($indexparam);
         $index =& $table->getIndex($swap->getPrevious());
     }
     /// Change the index before the pair
     if ($index->getPrevious()) {
         $prev =& $table->getIndex($index->getPrevious());
         $prev->setNext($swap->getName());
         $swap->setPrevious($prev->getName());
         $prev->setChanged(true);
     } else {
         $swap->setPrevious(NULL);
     }
     /// Change the field after the pair
     if ($swap->getNext()) {
         $next =& $table->getIndex($swap->getNext());
         $next->setPrevious($index->getName());
         $index->setNext($next->getName());
         $next->setChanged(true);
     } else {
         $index->setNext(NULL);
     }
     /// Swap the indexes
     $index->setPrevious($swap->getName());
     $swap->setNext($index->getName());
     /// Mark indexes as changed
     $index->setChanged(true);
     $swap->setChanged(true);
     /// Table has changed
     $table->setChanged(true);
     /// Reorder the indexes
     $table->orderIndexes($indexes);
     /// Recalculate the hash
     $structure->calculateHash(true);
     /// If the hash has changed from the original one, change the version
     /// and mark the structure as changed
     $origstructure =& $dbdir->xml_file->getStructure();
     if ($structure->getHash() != $origstructure->getHash()) {
         $structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
         $structure->setChanged(true);
     }
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB, $DB;
     /// Calculate list of available SQL generators
     require_once "{$CFG->libdir}/ddl/sql_generator.php";
     $reserved_words = sql_generator::getAllReservedWords();
     /// Now, calculate, looking into current DB (with AdoDB Metadata), which fields are
     /// in the list of reserved words
     $wronguses = array();
     $dbtables = $DB->get_tables();
     if ($dbtables) {
         foreach ($dbtables as $table) {
             if (array_key_exists($table, $reserved_words)) {
                 $wronguses[] = $this->str['table'] . ' - ' . $table . ' (' . implode(', ', $reserved_words[$table]) . ')';
             }
             $dbfields = $DB->get_columns($table);
             if ($dbfields) {
                 foreach ($dbfields as $dbfield) {
                     if (array_key_exists($dbfield->name, $reserved_words)) {
                         $wronguses[] = $this->str['field'] . ' - ' . $table . '->' . $dbfield->name . ' (' . implode(', ', $reserved_words[$dbfield->name]) . ')';
                     }
                 }
             }
         }
     }
     /// Sort the wrong uses
     sort($wronguses);
     /// The back to edit table button
     $b = ' <p class="centerpara buttons">';
     $b .= '<a href="index.php">[' . $this->str['back'] . ']</a>';
     $b .= '</p>';
     $o = $b;
     /// The list of currently wrong field names
     if ($wronguses) {
         $o .= '    <table id="formelements" class="boxaligncenter" cellpadding="5">';
         $o .= '      <tr><td align="center"><font color="red">' . $this->str['wrongreservedwords'] . '</font></td></tr>';
         $o .= '      <tr><td>';
         $o .= '        <ul><li>' . implode('</li><li>', $wronguses) . '</li></ul>';
         $o .= '      </td></tr>';
         $o .= '    </table>';
     }
     /// The textarea showing all the reserved words
     $o .= '    <table id="formelements" class="boxaligncenter" cellpadding="5">';
     $o .= '      <tr><td align="center">' . $this->str['listreservedwords'] . '</td></tr>';
     $o .= '      <tr><td><textarea cols="80" rows="32">';
     $o .= s(implode(', ', array_keys($reserved_words)));
     $o .= '</textarea></td></tr>';
     $o .= '    </table>';
     $this->output = $o;
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
예제 #26
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     /// Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . $dirpath;
     $tableparam = required_param('table', PARAM_PATH);
     $keyparam = required_param('key', PARAM_PATH);
     $confirmed = optional_param('confirmed', false, PARAM_BOOL);
     /// If  not confirmed, show confirmation box
     if (!$confirmed) {
         $o = '<table width="60" class="generalbox" border="0" cellpadding="5" cellspacing="0" id="notice">';
         $o .= '  <tr><td class="generalboxcontent">';
         $o .= '    <p class="centerpara">' . $this->str['confirmdeletekey'] . '<br /><br />' . $keyparam . '</p>';
         $o .= '    <table class="boxaligncenter" cellpadding="20"><tr><td>';
         $o .= '      <div class="singlebutton">';
         $o .= '        <form action="index.php?action=delete_key&amp;confirmed=yes&amp;postaction=edit_table&amp;key=' . $keyparam . '&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '" method="post"><fieldset class="invisiblefieldset">';
         $o .= '          <input type="submit" value="' . $this->str['yes'] . '" /></fieldset></form></div>';
         $o .= '      </td><td>';
         $o .= '      <div class="singlebutton">';
         $o .= '        <form action="index.php?action=edit_table&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '" method="post"><fieldset class="invisiblefieldset">';
         $o .= '          <input type="submit" value="' . $this->str['no'] . '" /></fieldset></form></div>';
         $o .= '      </td></tr>';
         $o .= '    </table>';
         $o .= '  </td></tr>';
         $o .= '</table>';
         $this->output = $o;
     } else {
         /// Get the edited dir
         if (!empty($XMLDB->editeddirs)) {
             if (isset($XMLDB->editeddirs[$dirpath])) {
                 $dbdir =& $XMLDB->dbdirs[$dirpath];
                 $editeddir =& $XMLDB->editeddirs[$dirpath];
                 if ($editeddir) {
                     $structure =& $editeddir->xml_file->getStructure();
                     /// Move adjacent keys prev and next attributes
                     $tables =& $structure->getTables();
                     $table =& $structure->getTable($tableparam);
                     $keys =& $table->getKeys();
                     $key =& $table->getKey($keyparam);
                     if ($key->getPrevious()) {
                         $prev =& $table->getKey($key->getPrevious());
                         $prev->setNext($key->getNext());
                     }
                     if ($key->getNext()) {
                         $next =& $table->getKey($key->getNext());
                         $next->setPrevious($key->getPrevious());
                     }
                     /// Remove the key
                     $table->deleteKey($keyparam);
                     /// Recalculate the hash
                     $structure->calculateHash(true);
                     /// If the hash has changed from the original one, change the version
                     /// and mark the structure as changed
                     $origstructure =& $dbdir->xml_file->getStructure();
                     if ($structure->getHash() != $origstructure->getHash()) {
                         $structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
                         $structure->setChanged(true);
                     }
                 }
             }
         }
     }
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
예제 #27
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB, $SESSION, $DB;
     /// Get lastused
     $o = '';
     if (isset($SESSION->lastused)) {
         if ($lastused = $SESSION->lastused) {
             /// Print link
             $o .= '<p class="centerpara"><a href="#lastused">' . $this->str['gotolastused'] . '</a></p>';
         }
     } else {
         $lastused = NULL;
     }
     /// Calculate the buttons
     $b = '<p class="centerpara buttons">';
     /// The reserved_words button
     $b .= '&nbsp;<a href="index.php?action=view_reserved_words">[' . $this->str['reservedwords'] . ']</a>';
     /// The docs button
     $b .= '&nbsp;<a href="index.php?action=generate_all_documentation">[' . $this->str['doc'] . ']</a>';
     /// The check indexes button
     $b .= '&nbsp;<a href="index.php?action=check_indexes&amp;sesskey=' . sesskey() . '">[' . $this->str['checkindexes'] . ']</a>';
     /// The check defaults button
     $b .= '&nbsp;<a href="index.php?action=check_defaults&amp;sesskey=' . sesskey() . '">[' . $this->str['checkdefaults'] . ']</a>';
     /// The check bigints button (only for MySQL and PostgreSQL) MDL-11038a
     if ($DB->get_dbfamily() == 'mysql' || $DB->get_dbfamily() == 'postgres') {
         $b .= '&nbsp;<a href="index.php?action=check_bigints&amp;sesskey=' . sesskey() . '">[' . $this->str['checkbigints'] . ']</a>';
     }
     $b .= '&nbsp;<a href="index.php?action=check_foreign_keys&amp;sesskey=' . sesskey() . '">[' . $this->str['checkforeignkeys'] . ']</a>';
     $b .= '</p>';
     /// Send buttons to output
     $o .= $b;
     /// Do the job
     /// Get the list of DB directories
     $result = $this->launch('get_db_directories');
     /// Display list of DB directories if everything is ok
     if ($result && !empty($XMLDB->dbdirs)) {
         $o .= '<table id="listdirectories" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">';
         $row = 0;
         foreach ($XMLDB->dbdirs as $key => $dbdir) {
             /// Detect if this is the lastused dir
             $hithis = false;
             if (str_replace($CFG->dirroot, '', $key) == $lastused) {
                 $hithis = true;
             }
             $elementtext = str_replace($CFG->dirroot . '/', '', $key);
             /// Calculate the dbdir has_changed field if needed
             if (!isset($dbdir->has_changed) && isset($dbdir->xml_loaded)) {
                 $dbdir->xml_changed = false;
                 if (isset($XMLDB->editeddirs[$key])) {
                     $editeddir =& $XMLDB->editeddirs[$key];
                     if (isset($editeddir->xml_file)) {
                         $structure =& $editeddir->xml_file->getStructure();
                         if ($structure->hasChanged()) {
                             $dbdir->xml_changed = true;
                             $editeddir->xml_changed = true;
                         }
                     }
                 }
             }
             /// The file name (link to edit if the file is loaded)
             if ($dbdir->path_exists && file_exists($key . '/install.xml') && is_readable($key . '/install.xml') && is_readable($key) && !empty($dbdir->xml_loaded)) {
                 $f = '<a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">' . $elementtext . '</a>';
             } else {
                 $f = $elementtext;
             }
             /// Calculate the buttons
             $b = ' <td class="button cell">';
             /// The create button
             if ($dbdir->path_exists && !file_exists($key . '/install.xml') && is_writeable($key)) {
                 $b .= '<a href="index.php?action=create_xml_file&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '&amp;time=' . time() . '&amp;postaction=main_view#lastused">[' . $this->str['create'] . ']</a>';
             } else {
                 $b .= '[' . $this->str['create'] . ']';
             }
             $b .= '</td><td class="button cell">';
             /// The load button
             if ($dbdir->path_exists && file_exists($key . '/install.xml') && is_readable($key . '/install.xml') && empty($dbdir->xml_loaded)) {
                 $b .= '<a href="index.php?action=load_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '&amp;time=' . time() . '&amp;postaction=main_view#lastused">[' . $this->str['load'] . ']</a>';
             } else {
                 $b .= '[' . $this->str['load'] . ']';
             }
             $b .= '</td><td class="button cell">';
             /// The edit button
             if ($dbdir->path_exists && file_exists($key . '/install.xml') && is_readable($key . '/install.xml') && is_readable($key) && !empty($dbdir->xml_loaded)) {
                 $b .= '<a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">[' . $this->str['edit'] . ']</a>';
             } else {
                 $b .= '[' . $this->str['edit'] . ']';
             }
             $b .= '</td><td class="button cell">';
             /// The save button
             if ($dbdir->path_exists && file_exists($key . '/install.xml') && is_writeable($key . '/install.xml') && is_writeable($key) && !empty($dbdir->xml_loaded) && !empty($dbdir->xml_changed)) {
                 $b .= '<a href="index.php?action=save_xml_file&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '&amp;time=' . time() . '&amp;postaction=main_view#lastused">[' . $this->str['save'] . ']</a>';
                 /// Check if the file has been manually edited while being modified in the editor
                 if ($dbdir->filemtime != filemtime($key . '/install.xml')) {
                     /// File manually modified. Add to errors.
                     if ($structure =& $dbdir->xml_file->getStructure()) {
                         $structure->errormsg = 'Warning: File locally modified while using the XMLDB Editor. Saving will overwrite local changes';
                     }
                 }
             } else {
                 $b .= '[' . $this->str['save'] . ']';
             }
             $b .= '</td><td class="button cell">';
             /// The document button
             if ($dbdir->path_exists && file_exists($key . '/install.xml') && is_readable($key . '/install.xml') && is_readable($key)) {
                 $b .= '<a href="index.php?action=generate_documentation&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">[' . $this->str['doc'] . ']</a>';
             } else {
                 $b .= '[' . $this->str['doc'] . ']';
             }
             $b .= '</td><td class="button cell">';
             /// The view xml button
             if ($dbdir->path_exists && file_exists($key . '/install.xml') && is_readable($key . '/install.xml')) {
                 $b .= '<a href="index.php?action=view_xml&amp;file=' . urlencode(str_replace($CFG->dirroot, '', $key) . '/install.xml') . '">[' . $this->str['viewxml'] . ']</a>';
             } else {
                 $b .= '[' . $this->str['viewxml'] . ']';
             }
             $b .= '</td><td class="button cell">';
             /// The revert button
             if ($dbdir->path_exists && file_exists($key . '/install.xml') && is_readable($key . '/install.xml') && is_writeable($key) && !empty($dbdir->xml_loaded) && !empty($dbdir->xml_changed)) {
                 $b .= '<a href="index.php?action=revert_changes&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">[' . $this->str['revert'] . ']</a>';
             } else {
                 $b .= '[' . $this->str['revert'] . ']';
             }
             $b .= '</td><td class="button cell">';
             /// The unload button
             if ($dbdir->path_exists && file_exists($key . '/install.xml') && is_readable($key . '/install.xml') && !empty($dbdir->xml_loaded) && empty($dbdir->xml_changed)) {
                 $b .= '<a href="index.php?action=unload_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '&amp;time=' . time() . '&amp;postaction=main_view#lastused">[' . $this->str['unload'] . ']</a>';
             } else {
                 $b .= '[' . $this->str['unload'] . ']';
             }
             $b .= '</td><td class="button cell">';
             /// The delete button
             if ($dbdir->path_exists && file_exists($key . '/install.xml') && is_readable($key . '/install.xml') && is_writeable($key) && empty($dbdir->xml_loaded)) {
                 $b .= '<a href="index.php?action=delete_xml_file&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">[' . $this->str['delete'] . ']</a>';
             } else {
                 $b .= '[' . $this->str['delete'] . ']';
             }
             $b .= '</td>';
             /// include the higlight
             if ($hithis) {
                 $o .= '<tr class="highlight"><td class="directory cell"><a name="lastused" />' . $f . '</td>' . $b . '</tr>';
             } else {
                 $o .= '<tr class="r' . $row . '"><td class="directory cell">' . $f . '</td>' . $b . '</tr>';
             }
             $row = ($row + 1) % 2;
             /// show errors if they exist
             if (isset($dbdir->xml_file)) {
                 if ($structure =& $dbdir->xml_file->getStructure()) {
                     if ($errors = $structure->getAllErrors()) {
                         if ($hithis) {
                             $o .= '<tr class="highlight"><td class="error cell" colspan="10">' . implode(', ', $errors) . '</td></tr>';
                         } else {
                             $o .= '<tr class="r' . $row . '"><td class="error cell" colspan="10">' . implode(', ', $errors) . '</td></tr>';
                         }
                     }
                 }
             }
             /// TODO: Drop this check in Moodle 2.1
             /// Intercept loaded structure here and look for ENUM fields
             if (isset($dbdir->xml_file)) {
                 if ($structure =& $dbdir->xml_file->getStructure()) {
                     if ($tables = $structure->getTables()) {
                         foreach ($tables as $table) {
                             if ($fields = $table->getFields()) {
                                 foreach ($fields as $field) {
                                     if (!empty($field->hasenums)) {
                                         if ($hithis) {
                                             $o .= '<tr class="highlight"><td class="error cell" colspan="10">';
                                         } else {
                                             $o .= '<tr class="r' . $row . '"><td class="error cell" colspan="10">';
                                         }
                                         $o .= 'Table ' . $table->getName() . ', field ' . $field->getName() . ' has ENUM info';
                                         if (!empty($field->hasenumsenabled)) {
                                             $o .= ' that seems to be active (true). ENUMs support has been dropped in Moodle 2.0, ' . ' the XMLDB Editor will delete any ENUM reference next time you save this file' . ' and you MUST provide  one upgrade block in your code to drop them from DB. See' . ' <a href="http://docs.moodle.org/dev/DB_layer_2.0_migration_docs#The_changes">' . ' Moodle Docs</a> for more info and examples.';
                                         } else {
                                             $o .= ' that seem to be inactive (false). ENUMs support has been dropped in Moodle 2.0,' . ' the XMLDB Editor will, simply, delete any ENUM reference next time you save this file.' . ' No further action is necessary.';
                                         }
                                         $o .= '</td></tr>';
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             /// If there are changes pending to be saved, but the file cannot be written... inform here
             if ($dbdir->path_exists && file_exists($key . '/install.xml') && !empty($dbdir->xml_loaded) && !empty($dbdir->xml_changed) && (!is_writeable($key . '/install.xml') || !is_writeable($key))) {
                 if ($hithis) {
                     $o .= '<tr class="highlight"><td class="error cell" colspan="10">';
                 } else {
                     $o .= '<tr class="r' . $row . '"><td class="error cell" colspan="10">';
                 }
                 $o .= $this->str['pendingchangescannotbesavedreload'];
                 $o .= '</td></tr>';
             }
         }
         $o .= '</table>';
         /// Set the output
         $this->output = $o;
     }
     /// Finally, return result
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB, $db;
     /// And we nedd some ddl suff
     require_once $CFG->libdir . '/ddllib.php';
     /// Here we'll acummulate all the wrong fields found
     $wrong_fields = array();
     /// Correct fields must be type bigint for MySQL and int8 for PostgreSQL
     switch ($CFG->dbfamily) {
         case 'mysql':
             $correct_type = 'bigint';
             break;
         case 'postgres':
             $correct_type = 'int8';
             break;
         default:
             $correct_type = NULL;
     }
     /// Do the job, setting $result as needed
     /// Get the confirmed to decide what to do
     $confirmed = optional_param('confirmed', false, PARAM_BOOL);
     /// If  not confirmed, show confirmation box
     if (!$confirmed) {
         $o = '<table class="generalbox" border="0" cellpadding="5" cellspacing="0" id="notice">';
         $o .= '  <tr><td class="generalboxcontent">';
         $o .= '    <p class="centerpara">' . $this->str['confirmcheckbigints'] . '</p>';
         if ($CFG->dbfamily == 'mysql') {
             $o .= '    <p class="centerpara">' . $this->str['mysqlextracheckbigints'] . '</p>';
         }
         $o .= '    <table class="boxaligncenter" cellpadding="20"><tr><td>';
         $o .= '      <div class="singlebutton">';
         $o .= '        <form action="index.php?action=check_bigints&amp;sesskey=' . sesskey() . '&amp;confirmed=yes" method="post"><fieldset class="invisiblefieldset">';
         $o .= '          <input type="submit" value="' . $this->str['yes'] . '" /></fieldset></form></div>';
         $o .= '      </td><td>';
         $o .= '      <div class="singlebutton">';
         $o .= '        <form action="index.php?action=main_view" method="post"><fieldset class="invisiblefieldset">';
         $o .= '          <input type="submit" value="' . $this->str['no'] . '" /></fieldset></form></div>';
         $o .= '      </td></tr>';
         $o .= '    </table>';
         $o .= '  </td></tr>';
         $o .= '</table>';
         $this->output = $o;
     } else {
         /// The back to edit table button
         $b = ' <p class="centerpara buttons">';
         $b .= '<a href="index.php">[' . $this->str['back'] . ']</a>';
         $b .= '</p>';
         /// Iterate over $XMLDB->dbdirs, loading their XML data to memory
         if ($XMLDB->dbdirs) {
             $dbdirs =& $XMLDB->dbdirs;
             $o = '<ul>';
             foreach ($dbdirs as $dbdir) {
                 /// Only if the directory exists
                 if (!$dbdir->path_exists) {
                     continue;
                 }
                 /// Load the XML file
                 $xmldb_file = new XMLDBFile($dbdir->path . '/install.xml');
                 /// Load the needed XMLDB generator
                 $classname = 'XMLDB' . $CFG->dbtype;
                 $generator = new $classname();
                 $generator->setPrefix($CFG->prefix);
                 /// Only if the file exists
                 if (!$xmldb_file->fileExists()) {
                     continue;
                 }
                 /// Load the XML contents to structure
                 $loaded = $xmldb_file->loadXMLStructure();
                 if (!$loaded || !$xmldb_file->isLoaded()) {
                     notify('Errors found in XMLDB file: ' . $dbdir->path . '/install.xml');
                     continue;
                 }
                 /// Arriving here, everything is ok, get the XMLDB structure
                 $structure = $xmldb_file->getStructure();
                 $o .= '    <li>' . str_replace($CFG->dirroot . '/', '', $dbdir->path . '/install.xml');
                 /// Getting tables
                 if ($xmldb_tables = $structure->getTables()) {
                     $o .= '        <ul>';
                     /// Foreach table, process its fields
                     foreach ($xmldb_tables as $xmldb_table) {
                         /// Skip table if not exists
                         if (!table_exists($xmldb_table)) {
                             continue;
                         }
                         /// Fetch metadata from phisical DB. All the columns info.
                         if ($metacolumns = $db->MetaColumns($CFG->prefix . $xmldb_table->getName())) {
                             $metacolumns = array_change_key_case($metacolumns, CASE_LOWER);
                         } else {
                             //// Skip table if no metacolumns is available for it
                             continue;
                         }
                         /// Table processing starts here
                         $o .= '            <li>' . $xmldb_table->getName();
                         /// Get and process XMLDB fields
                         if ($xmldb_fields = $xmldb_table->getFields()) {
                             $o .= '        <ul>';
                             foreach ($xmldb_fields as $xmldb_field) {
                                 /// If the field isn't integer(10), skip
                                 if ($xmldb_field->getType() != XMLDB_TYPE_INTEGER || $xmldb_field->getLength() != 10) {
                                     continue;
                                 }
                                 /// If the metadata for that column doesn't exist, skip
                                 if (!isset($metacolumns[$xmldb_field->getName()])) {
                                     continue;
                                 }
                                 /// To variable for better handling
                                 $metacolumn = $metacolumns[$xmldb_field->getName()];
                                 /// Going to check this field in DB
                                 $o .= '            <li>' . $this->str['field'] . ': ' . $xmldb_field->getName() . ' ';
                                 /// Detect if the phisical field is wrong and, under mysql, check for incorrect signed fields too
                                 if ($metacolumn->type != $correct_type || $CFG->dbfamily == 'mysql' && $xmldb_field->getUnsigned() && !$metacolumn->unsigned) {
                                     $o .= '<font color="red">' . $this->str['wrong'] . '</font>';
                                     /// Add the wrong field to the list
                                     $obj = new object();
                                     $obj->table = $xmldb_table;
                                     $obj->field = $xmldb_field;
                                     $wrong_fields[] = $obj;
                                 } else {
                                     $o .= '<font color="green">' . $this->str['ok'] . '</font>';
                                 }
                                 $o .= '</li>';
                             }
                             $o .= '        </ul>';
                         }
                         $o .= '    </li>';
                         /// Give the script some more time (resetting to current if exists)
                         if ($currenttl = @ini_get('max_execution_time')) {
                             @ini_set('max_execution_time', $currenttl);
                         }
                     }
                     $o .= '        </ul>';
                 }
                 $o .= '    </li>';
             }
             $o .= '</ul>';
         }
         /// We have finished, let's show the results of the search
         $s = '';
         $r = '<table class="generalbox boxaligncenter boxwidthwide" border="0" cellpadding="5" cellspacing="0" id="results">';
         $r .= '  <tr><td class="generalboxcontent">';
         $r .= '    <h2 class="main">' . $this->str['searchresults'] . '</h2>';
         $r .= '    <p class="centerpara">' . $this->str['wrongints'] . ': ' . count($wrong_fields) . '</p>';
         $r .= '  </td></tr>';
         $r .= '  <tr><td class="generalboxcontent">';
         /// If we have found wrong integers inform about them
         if (count($wrong_fields)) {
             $r .= '    <p class="centerpara">' . $this->str['yeswrongintsfound'] . '</p>';
             $r .= '        <ul>';
             foreach ($wrong_fields as $obj) {
                 $xmldb_table = $obj->table;
                 $xmldb_field = $obj->field;
                 /// MySQL directly supports this
                 if ($CFG->dbfamily == 'mysql') {
                     $sqlarr = $xmldb_table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $xmldb_field, true);
                     /// PostgreSQL (XMLDB implementation) is a bit, er... imperfect.
                 } else {
                     if ($CFG->dbfamily == 'postgres') {
                         $sqlarr = array('ALTER TABLE ' . $CFG->prefix . $xmldb_table->getName() . ' ALTER COLUMN ' . $xmldb_field->getName() . ' TYPE BIGINT;');
                     }
                 }
                 $r .= '            <li>' . $this->str['table'] . ': ' . $xmldb_table->getName() . '. ' . $this->str['field'] . ': ' . $xmldb_field->getName() . '</li>';
                 /// Add to output if we have sentences
                 if ($sqlarr) {
                     $s .= '<code>' . str_replace("\n", '<br />', implode('<br />', $sqlarr)) . '</code><br />';
                 }
             }
             $r .= '        </ul>';
             /// Add the SQL statements (all together)
             $r .= '<hr />' . $s;
         } else {
             $r .= '    <p class="centerpara">' . $this->str['nowrongintsfound'] . '</p>';
         }
         $r .= '  </td></tr>';
         $r .= '  <tr><td class="generalboxcontent">';
         /// Add the complete log message
         $r .= '    <p class="centerpara">' . $this->str['completelogbelow'] . '</p>';
         $r .= '  </td></tr>';
         $r .= '</table>';
         $this->output = $b . $r . $o;
     }
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     if (!data_submitted('nomatch')) {
         ///Basic prevention
         error('Wrong action call');
     }
     /// Get parameters
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . stripslashes_safe($dirpath);
     $tableparam = strtolower(required_param('table', PARAM_PATH));
     $name = substr(trim(strtolower(required_param('name', PARAM_PATH))), 0, 28);
     $comment = required_param('comment', PARAM_CLEAN);
     $comment = stripslashes_safe($comment);
     $editeddir =& $XMLDB->editeddirs[$dirpath];
     $structure =& $editeddir->xml_file->getStructure();
     $table =& $structure->getTable($tableparam);
     $errors = array();
     /// To store all the errors found
     /// Perform some checks
     /// Check empty name
     if (empty($name)) {
         $errors[] = $this->str['tablenameempty'];
     }
     /// Check incorrect name
     if ($name == 'changeme') {
         $errors[] = $this->str['incorrecttablename'];
     }
     /// Check duplicatename
     if ($tableparam != $name && $structure->getTable($name)) {
         $errors[] = $this->str['duplicatetablename'];
     }
     if (!empty($errors)) {
         $temptable = new XMLDBTable($name);
         /// Prepare the output
         $site = get_site();
         $navlinks = array();
         $navlinks[] = array('name' => $this->str['administration'], 'link' => '../index.php', 'type' => 'misc');
         $navlinks[] = array('name' => 'XMLDB', 'link' => 'index.php', 'type' => 'misc');
         $navigation = build_navigation($navlinks);
         print_header("{$site->shortname}: XMLDB", "{$site->fullname}", $navigation);
         notice('<p>' . implode(', ', $errors) . '</p>
                  <p>' . $temptable->readableInfo(), 'index.php?action=edit_table&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)));
         die;
         /// re-die :-P
     }
     /// If there is one name change, do it, changing the prev and next
     /// atributes of the adjacent tables
     if ($tableparam != $name) {
         $table->setName($name);
         if ($table->getPrevious()) {
             $prev =& $structure->getTable($table->getPrevious());
             $prev->setNext($name);
             $prev->setChanged(true);
         }
         if ($table->getNext()) {
             $next =& $structure->getTable($table->getNext());
             $next->setPrevious($name);
             $next->setChanged(true);
         }
     }
     /// Set comment
     $table->setComment($comment);
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $CFG, $XMLDB;
     /// Do the job, setting result as needed
     if (!data_submitted()) {
         ///Basic prevention
         print_error('wrongcall', 'error');
     }
     /// Get parameters
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . $dirpath;
     $tableparam = strtolower(required_param('table', PARAM_PATH));
     $indexparam = strtolower(required_param('index', PARAM_PATH));
     $name = trim(strtolower(optional_param('name', $indexparam, PARAM_PATH)));
     $comment = required_param('comment', PARAM_CLEAN);
     $comment = trim($comment);
     $unique = required_param('unique', PARAM_INT);
     $fields = required_param('fields', PARAM_CLEAN);
     $fields = str_replace(' ', '', trim(strtolower($fields)));
     $editeddir =& $XMLDB->editeddirs[$dirpath];
     $structure =& $editeddir->xml_file->getStructure();
     $table =& $structure->getTable($tableparam);
     $index =& $table->getIndex($indexparam);
     $oldhash = $index->getHash();
     $errors = array();
     /// To store all the errors found
     /// Perform some checks
     /// Check empty name
     if (empty($name)) {
         $errors[] = $this->str['indexnameempty'];
     }
     /// Check incorrect name
     if ($name == 'changeme') {
         $errors[] = $this->str['incorrectindexname'];
     }
     /// Check duplicate name
     if ($indexparam != $name && $table->getIndex($name)) {
         $errors[] = $this->str['duplicateindexname'];
     }
     $fieldsarr = explode(',', $fields);
     /// Check the fields isn't empty
     if (empty($fieldsarr[0])) {
         $errors[] = $this->str['nofieldsspecified'];
     } else {
         /// Check that there aren't duplicate column names
         $uniquearr = array_unique($fieldsarr);
         if (count($fieldsarr) != count($uniquearr)) {
             $errors[] = $this->str['duplicatefieldsused'];
         }
         /// Check that all the fields in belong to the table
         foreach ($fieldsarr as $field) {
             if (!$table->getField($field)) {
                 $errors[] = $this->str['fieldsnotintable'];
                 break;
             }
         }
         /// Check that there isn't any key using exactly the same fields
         $tablekeys = $table->getKeys();
         if ($tablekeys) {
             foreach ($tablekeys as $tablekey) {
                 $keyfieldsarr = $tablekey->getFields();
                 /// Compare both arrays, looking for diferences
                 $diferences = array_merge(array_diff($fieldsarr, $keyfieldsarr), array_diff($keyfieldsarr, $fieldsarr));
                 if (empty($diferences)) {
                     $errors[] = $this->str['fieldsusedinkey'];
                     break;
                 }
             }
         }
         /// Check that there isn't any index using exactlt the same fields
         $tableindexes = $table->getIndexes();
         if ($tableindexes) {
             foreach ($tableindexes as $tableindex) {
                 /// Skip checking against itself
                 if ($indexparam == $tableindex->getName()) {
                     continue;
                 }
                 $indexfieldsarr = $tableindex->getFields();
                 /// Compare both arrays, looking for diferences
                 $diferences = array_merge(array_diff($fieldsarr, $indexfieldsarr), array_diff($indexfieldsarr, $fieldsarr));
                 if (empty($diferences)) {
                     $errors[] = $this->str['fieldsusedinindex'];
                     break;
                 }
             }
         }
     }
     if (!empty($errors)) {
         $tempindex = new xmldb_index($name);
         $tempindex->setUnique($unique);
         $tempindex->setFields($fieldsarr);
         /// Prepare the output
         $site = get_site();
         $navlinks = array();
         $navlinks[] = array('name' => $this->str['administration'], 'link' => '../index.php', 'type' => 'misc');
         $navlinks[] = array('name' => 'XMLDB', 'link' => 'index.php', 'type' => 'misc');
         $navigation = build_navigation($navlinks);
         print_header("{$site->shortname}: XMLDB", "{$site->fullname}", $navigation);
         notice('<p>' . implode(', ', $errors) . '</p>
                  <p>' . $tempindex->readableInfo() . '</p>', 'index.php?action=edit_index&amp;index=' . $index->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)));
         die;
         /// re-die :-P
     }
     /// Continue if we aren't under errors
     if (empty($errors)) {
         /// If there is one name change, do it, changing the prev and next
         /// atributes of the adjacent fields
         if ($indexparam != $name) {
             $index->setName($name);
             if ($index->getPrevious()) {
                 $prev =& $table->getIndex($index->getPrevious());
                 $prev->setNext($name);
                 $prev->setChanged(true);
             }
             if ($index->getNext()) {
                 $next =& $table->getIndex($index->getNext());
                 $next->setPrevious($name);
                 $next->setChanged(true);
             }
         }
         /// Set comment
         $index->setComment($comment);
         /// Set the rest of fields
         $index->setUnique($unique);
         $index->setFields($fieldsarr);
         /// If the hash has changed from the old one, change the version
         /// and mark the structure as changed
         $index->calculateHash(true);
         if ($oldhash != $index->getHash()) {
             $index->setChanged(true);
             $table->setChanged(true);
             /// Recalculate the structure hash
             $structure->calculateHash(true);
             $structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
             /// Mark as changed
             $structure->setChanged(true);
         }
         /// Launch postaction if exists (leave this here!)
         if ($this->getPostAction() && $result) {
             return $this->launch($this->getPostAction());
         }
     }
     /// Return ok if arrived here
     return $result;
 }