Browse Source

Some fixes in the vchamilo plugin

jmontoyaa 9 years ago
parent
commit
b15461d1d0

+ 9 - 15
plugin/vchamilo/install.php

@@ -1,18 +1,18 @@
 <?php
-/* PHP code to install the plugin 
+/* PHP code to install the plugin
  * For example:
- * 
+ *
     // To query something to the database
-  
+
     $table = Database::get_main_table(TABLE_MAIN_USER); // TABLE_MAIN_USER is a constant check the main/inc/database.constants.inc.php
     $sql = "SELECT firstname, lastname FROM $table_users ";
-    $users = Database::query($sql); 
-  
-    You can also use the Chamilo classes 
+    $users = Database::query($sql);
+
+    You can also use the Chamilo classes
     $users = UserManager::get_user_list();
-    
+
  */
- 
+
 $table = 'vchamilo';
 $tablename = Database::get_main_table($table);
 $sql = "CREATE TABLE IF NOT EXISTS $tablename (
@@ -20,18 +20,12 @@ $sql = "CREATE TABLE IF NOT EXISTS $tablename (
   `sitename` varchar(80) NOT NULL,
   `institution` varchar(80) NOT NULL,
   `root_web` varchar(120),
-
   `db_host` varchar(80) NOT NULL,
   `db_user` varchar(16) DEFAULT 'root',
-  `db_password` varchar(32),
-  `tracking_enabled` int(1) DEFAULT 0,
-  `single_database` int(1) DEFAULT 1,
+  `db_password` varchar(32),  
   `table_prefix` varchar(16),
   `db_prefix` varchar(16),
   `main_database` varchar(60) DEFAULT 'chamilo',
-  `statistics_database` varchar(60) DEFAULT 'chamilo',
-  `user_personal_database` varchar(60) DEFAULT 'chamilo',
-
   `url_append` varchar(32),
   `course_folder` varchar(80),
   `visible` int(1),

+ 527 - 33
plugin/vchamilo/lib.php

@@ -23,7 +23,7 @@ function vchamilo_hook_configuration(&$_configuration) {
     $side_cnx = vchamilo_boot_connection($_configuration, 'main');
 
     $table = 'vchamilo';
-    
+
     $query = "
         SELECT * FROM $table WHERE root_web = '{$_configuration['vchamilo_web_root']}'
     ";
@@ -64,7 +64,7 @@ function vchamilo_get_hostname(&$_configuration) {
     } else {
         $protocol = 'http';
     }
-    
+
     if (defined('CLI_VCHAMILO_OVERRIDE')) {
         $_configuration['vchamilo_web_root'] = CLI_VCHAMILO_OVERRIDE;
         $_configuration['vchamilo_name'] = preg_replace('#https?://#', '', CLI_VCHAMILO_OVERRIDE); // remove radical from override for name
@@ -107,7 +107,7 @@ function vchamilo_boot_connection(&$_configuration, $binddb = false) {
     }
     mysql_set_charset('utf8', $mysql_side_cnx);
     if (!empty($binddb)) {
-        if (!in_array($binddb, array('main', 'statistics', 'user_personal'), true)) {
+        if (!in_array($binddb, array('main'), true)) {
             echo('Not a chamilo database. should be one of "main", "statistics" or "user_personal"');
             mysql_close($mysql_side_cnx);
             return false;
@@ -175,7 +175,7 @@ function vchamilo_template_exists($template) {
     $absolute_templatesdir = $_configuration['root_sys'].$templatefoldername;
     $relative_datadir    =    $templatefoldername.$separator.$template.'_sql';
     $absolute_datadir    =    $_configuration['root_sys'].$relative_datadir;
-    
+
     return is_dir($absolute_datadir);
 }
 
@@ -187,7 +187,7 @@ function vchamilo_template_exists($template) {
 */
 function vchamilo_drop_databases(&$vchamilo){
     global $plugininstance;
-    
+
     if (is_array($vchamilo)) $vchamilo = (object)$vchamilo;
 
     // Drop databases you need to drop
@@ -245,10 +245,11 @@ function vchamilo_create_databases($vchamilo, $cnx = null) {
     foreach($dbs as $adb){
         ctrace("Creating DB $adb ");
         $sql = str_replace('%DATABASE%', $adb, $createstatement);
-        if(!$DB->execute_sql($sql)){
+        Database::query($sql);
+        /*if(!$DB->execute_sql($sql)){
             print_error('noexecutionfor','block_vmoodle', $sql);
             return false;
-        }
+        }*/
 
     }
     return true;
@@ -257,7 +258,7 @@ function vchamilo_create_databases($vchamilo, $cnx = null) {
 /**
 * get a proper SQLdump command
 * @param object $vmoodledata the complete new host information
-* @return string the shell command 
+* @return string the shell command
 */
 function vchamilo_get_database_dump_cmd($vchamilodata){
     global $CFG;
@@ -309,7 +310,7 @@ function vchamilo_load_db_template($vchamilo, $dbtemplate, $template){
     $absolute_templatesdir = $_configuration['root_sys'].$templatefoldername;
     $relative_datadir    =    $templatefoldername.$separator.$template.'_sql';
     $absolute_datadir    =    $_configuration['root_sys'].$relative_datadir;
-    
+
     $filerad = preg_replace('/_database$/', '', $dbtemplate);
     $sqlfile = 'chamilo_master_'.$filerad.'.sql';
 
@@ -326,7 +327,7 @@ function vchamilo_load_db_template($vchamilo, $dbtemplate, $template){
     ctrace("load_database_from_dump : executing feeding sql as \n $import ");
 
     if (!defined('CLI_SCRIPT')){
-        putenv('LANG=en_US.utf-8'); 
+        putenv('LANG=en_US.utf-8');
     }
     // ensure utf8 is correctly handled by php exec()
     // @see http://stackoverflow.com/questions/10028925/call-a-program-via-shell-exec-with-utf-8-text-input
@@ -353,7 +354,7 @@ function vchamilo_execute_db_sql(&$vchamilo, $bulkfile, $cnx = null, $vars=null,
         $erroritems[] = $erroritem;
         return $erroritem;
     }
- 
+
     $local_cnx = 0;
     if (is_null($cnx)){
         $cnx = vchamilo_make_connection($vchamilo, true);
@@ -412,7 +413,7 @@ function vchamilo_execute_db_sql(&$vchamilo, $bulkfile, $cnx = null, $vars=null,
     if ($local_cnx){
         vchamilo_close_connection($vchamilo, $cnx);
     }
-    
+
     if (!empty($erroritems)){
         return $erroritems;
     }
@@ -439,7 +440,7 @@ function vchamilo_dump_databases($vchamilo, $outputfilerad){
     // By default, empty password.
     $pass = '';
     $pgm = null;
-  
+
     if (empty($port)){
         $port = 3306;
     }
@@ -479,7 +480,7 @@ function vchamilo_dump_databases($vchamilo, $outputfilerad){
             $cmds[] = $cmd_user . ' > ' . escapeshellarg($outputfilerad.'_user_personal.sql');
         }
     }
-    
+
     $mysqldumpcmd = vchamilo_get_config('vchamilo', 'cmd_mysqldump', true);
 
     $pgm = (!empty($mysqldumpcmd)) ? stripslashes($mysqldumpcmd) : false ;
@@ -510,7 +511,7 @@ function vchamilo_dump_databases($vchamilo, $outputfilerad){
             if ($LOG = fopen(dirname($outputfilerad).'/cmd.log', 'a')){
                 fwrite($LOG, $cmd."\n");
             }
-    
+
             // Executes the SQL command.
             exec($cmd, $execoutput, $returnvalue);
             if ($LOG){
@@ -551,12 +552,9 @@ function vchamilo_make_this(){
     $thischamilo->db_user = $_configuration['db_user'];
     $thischamilo->db_password = $_configuration['db_password'];
     $thischamilo->db_prefix = $_configuration['db_prefix'];
-    $thischamilo->main_database = $_configuration['main_databse'];
-    $thischamilo->statistics_database = $_configuration['statistics_databse'];
-    $thischamilo->user_personal_database = $_configuration['user_personal_databse'];
+    $thischamilo->main_database = $_configuration['main_database'];    ;
     $thischamilo->table_prefix = $_configuration['table_prefix'];
-    $thischamilo->single_database = $_configuration['single_database'];
-    $thischamilo->tracking_enabled = $_configuration['tracking_enabled'];
+
     return $thischamilo;
 }
 
@@ -606,30 +604,33 @@ function vchamilo_print_error($errortrace, $return = false){
         $str .= '</pre>';
         $str .= '</div>';
     }
-    
+
     if ($return) return $str;
     echo $str;
 }
 
 /**
 * this function set will map standard moodle API calls to chamilo
-* internal primitives. This avoids too many changes to do in imported 
+* internal primitives. This avoids too many changes to do in imported
 * code
 *
 */
-function vchamilo_get_config($module, $key, $isplugin = true){
-    global $_configuration, $DB;
-    
-    if ($isplugin){
+function vchamilo_get_config($module, $key, $isplugin = true)
+{
+    if ($isplugin) {
         $key = $module.'_'.$key;
     }
-    if($configrec = $DB->get_record(TABLE_MAIN_SETTINGS_CURRENT, array('variable' => $key, 'subkey' => $module))){
-        return $configrec->selected_value;
+
+    $params = array('variable = ? AND subkey = ?' => [$key, $module]);
+    $result = api_get_settings_params_simple($params);
+    if ($result) {
+        return $result['selected_value'];
     }
     return false;
 }
 
-function vchamilo_load_files_from_template($vchamilo, $template){
+function vchamilo_load_files_from_template($vchamilo, $template)
+{
     global $_configuration;
 
     // Make template directory (files and SQL).
@@ -646,12 +647,12 @@ function vchamilo_load_files_from_template($vchamilo, $template){
     $vcoursepath = api_get_path(TO_SYS, SYS_COURSE_PATH, (array)$vchamilo);
     $vhomepath = api_get_path(TO_SYS, SYS_HOME_PATH, (array)$vchamilo);
     $varchivepath = api_get_path(TO_SYS, SYS_ARCHIVE_PATH, (array)$vchamilo);
-    
+
     echo "archiveapth : $varchivepath";
 
     // Rename some dirs top match instance requirements
     $manifest = vchamilo_get_vmanifest($template);
-        
+
     // get the protocol free hostname
     $originarchivedir = preg_replace('/https?:\/\//', '', $manifest->templatewwwroot);
     $originhomedir = preg_replace('/https?:\/\//', '', $manifest->templatewwwroot);
@@ -663,10 +664,10 @@ function vchamilo_load_files_from_template($vchamilo, $template){
     copyDirContentTo(chop_last_slash($absolute_template_datadir.'/'.$manifest->coursefolder), chop_last_slash($vcoursepath), false);
     copyDirContentTo(chop_last_slash($absolute_template_datadir.'/archive/'.$originarchivedir), chop_last_slash($varchivepath), false);
     copyDirContentTo(chop_last_slash($absolute_template_datadir.'/home/'.$originhomedir), chop_last_slash($vhomepath), false);
-
 }
 
-function chop_last_slash($path){
+function chop_last_slash($path)
+{
     return preg_replace('/\/$/', '', $path);
 }
 
@@ -718,3 +719,496 @@ function copyDirContentTo($source, $destination, $move = true) {
     }
 }
 
+
+
+// from moot
+
+
+define('PARAM_BOOL', 1);
+define('PARAM_INT', 2);
+define('PARAM_TEXT', 3);
+define('PARAM_RAW', 4);
+
+/**
+ * this function set will map standard moodle API calls to chamilo
+ * internal primitives. This avoids too many changes to do in imported
+ * code
+ *
+ */
+function get_config($module, $key = false, $isplugin = true) {
+    global $_configuration, $DB;
+    static $static_settings;
+
+    if (!isset($static_settings)) {
+        include_once $_configuration['root_sys'].'local/ent_installer/static_settings.php';
+    }
+
+    if ($isplugin){
+        $configkey = $module.'_'.$key;
+    } else {
+        $configkey = $key;
+    }
+
+    if ($module == 'ent_installer') {
+        $dyna_setting = $DB->get_field(TABLE_MAIN_SETTINGS_CURRENT, 'selected_value', array('subkey' => 'ent_installer', 'variable' => $configkey));
+        if (!is_null($dyna_setting)) {
+            return $dyna_setting;
+        }
+
+        if(empty($config)){
+            ctrace("Wrap to static setting $module,$configkey ");
+            if (array_key_exists($key, $static_settings)){
+                return $static_settings[$key];
+            }
+        }
+    } else {
+        if (!$module) {
+            return $DB->get_field(TABLE_MAIN_SETTINGS_CURRENT, 'selected_value', array('variable' => $configkey));
+        }
+        if ($key) {
+            return $DB->get_field(TABLE_MAIN_SETTINGS_CURRENT, 'selected_value', array('variable' => $configkey, 'subkey' => $module));
+        } else {
+            // Get all config from a subkey as an object
+            $configs = $DB->get_records(TABLE_MAIN_SETTINGS_CURRENT, array('subkey' => $module));
+            if (!empty($configs)) {
+                $config = new StdClass;
+                foreach ($configs as $cf) {
+                    $key = str_replace($module.'_', '', $cf->variable);
+                    $config->$key = $cf->selected_value;
+                }
+                return $config;
+            }
+            return null;
+        }
+    }
+}
+
+function set_config($key, $value, $module, $isplugin = false) {
+
+    if ($isplugin) {
+        $key = $module.'_'.$key;
+    }
+
+    if ($isplugin) {
+        // ensure setting is actually in database
+        api_update_setting($value, $key, $module);
+    } else {
+        api_update_setting($value, $module, $key);
+    }
+}
+
+/**
+ * gets a string from a component
+ *
+ */
+function get_string($key, $component = 'local_ent_installer', $a = ''){
+    global $_configuration;
+    static $strings;
+    static $fallbackstrings;
+
+    if ($component == 'local_ent_installer') {
+        $fallbackpath = $_configuration['root_sys'].'local/ent_installer/lang/english/local_ent_installer.php';
+
+        if (!isset($strings)) {
+            $lang = api_get_language_from_type('platform_lang');
+            if (empty($lang)) $lang = 'english';
+            $path = $_configuration['root_sys'].'local/ent_installer/lang/'.$lang.'/local_ent_installer.php';
+
+            if (!file_exists($path)) {
+                if (!file_exists($path)) {
+                    print_error('missinglang', null);
+                    die;
+                }
+
+                if (!isset($fallbackstrings)) {
+                    include $fallbackpath;
+                    $fallbackstrings = $string;
+                }
+            }
+
+            include $path;
+            $strings = $string;
+        }
+
+        if (!array_key_exists($key, $strings)) {
+            if (!isset($fallbackstrings)) {
+                include $fallbackpath;
+                $fallbackstrings = $string;
+            }
+            if (!array_key_exists($key, $fallbackstrings)) {
+                return "[[$key]]";
+            }
+            if (is_scalar($a)) {
+                return str_replace('{$a}', $a, $fallbackstrings[$key]);
+            }
+            if (is_array($a)) {
+                $a = (object)$a;
+            }
+            if (is_object($a)) {
+                return replace_string_vars($a, $fallbackstrings[$key]);
+            }
+            debugging('String insertion not supported', 1);
+            die;
+        }
+
+        if (is_scalar($a)) {
+            return str_replace('{$a}', $a, $strings[$key]);
+        }
+        if (is_array($a)){
+            $a = (object)$a;
+        }
+        if (is_object($a)){
+            return replace_string_vars($a, $strings[$key]);
+        }
+        debugging('String insertion not supported', 1);
+        die;
+    } else {
+        return get_lang($key);
+    }
+}
+
+function replace_string_vars($a, $str){
+    preg_match_all('/{\$a-\>(.+?)}/', $str, $matches);
+    if (!empty($matches[1])){
+        foreach($matches[1] as $replacekey){
+            $str = str_replace('{$a->'.$replacekey.'}', $a->$replacekey, $str);
+        }
+    }
+    return $str;
+}
+
+function print_error($key, $component = '', $passthru = false, $extrainfo = ''){
+    global $debuglevel;
+    global $debugdisplay;
+
+    if ($component === null){
+        $str = $key;
+    } else {
+        $str = get_string($string, $component);
+    }
+    ctrace('ERROR: '. $str);
+    if (!empty($extrainfo)){
+        ctrace('Extra: '. $extrainfo);
+    }
+    if ($debugdisplay >= 3){
+        debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+    }
+    if (!$passthru) die;
+}
+
+function debugging($message, $level) {
+    global $debuglevel;
+    global $debugdisplay;
+
+    if ($level <= $debuglevel) {
+        ctrace('DEBUG: '.$message);
+        if ($debugdisplay >= 3){
+            debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+        }
+    }
+}
+
+/**
+ * Wrap moodle to chamilo side
+ *
+ */
+function mtrace($message){
+    ctrace($message);
+}
+
+function ctrace($str) {
+    if (!defined('CLI_SCRIPT')) echo "<pre>";
+    echo $str;
+    if (!defined('CLI_SCRIPT')) echo "</pre>";
+}
+
+/**
+ * Sets a platform configuration setting to a given value, creating it if necessary
+ * @param string    The value we want to record
+ * @param string    The variable name we want to insert
+ * @param string    The subkey for the variable we want to insert
+ * @param string    The type for the variable we want to insert
+ * @param string    The category for the variable we want to insert
+ * @param string    The title
+ * @param string    The comment
+ * @param string    The scope
+ * @param string    The subkey text
+ * @param int       The access_url for which this parameter is valid
+ * @param int       The changeability of this setting for non-master urls
+ * @return boolean  true on success, false on failure
+ */
+function api_update_setting($val, $var, $sk = null, $type = 'textfield', $c = null, $title = '', $com = '', $sc = null, $skt = null, $a = 1, $v = 0) {
+    global $_setting;
+
+    if (empty($var) || !isset($val)) {
+        return false;
+    }
+
+    $t_settings = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
+    $var = Database::escape_string($var);
+    $val = Database::escape_string($val);
+    $a = (int) $a;
+
+    if (empty($a)) { $a = 1; }
+
+    // Check if this variable doesn't exist already
+    $select = "SELECT id FROM $t_settings WHERE variable = '$var' ";
+
+    if (!empty($sk)) {
+        $sk = Database::escape_string($sk);
+        $select .= " AND subkey = '$sk'";
+    }
+
+    if ($a > 1) {
+        $select .= " AND access_url = $a";
+    } else {
+        $select .= " AND access_url = 1 ";
+    }
+
+    $res = Database::query($select);
+    if (Database::num_rows($res) > 0) { // Found item for this access_url.
+        $row = Database::fetch_array($res);
+        // update value
+        $update['selected_value'] = $val;
+        Database::update($t_settings, $update, array('id = ?' => $row['id']));
+        return $row['id'];
+
+        // update in memory setting value
+        $_setting[$var][$sk] = $val;
+    }
+
+    // Item not found for this access_url, we have to check if the whole thing is missing
+    // (in which case we ignore the insert) or if there *is* a record but just for access_url = 1
+    $insert = "INSERT INTO $t_settings " .
+        "(variable,selected_value," .
+        "type,category," .
+        "subkey,title," .
+        "comment,scope," .
+        "subkeytext,access_url,access_url_changeable)" .
+        " VALUES ('$var','$val',";
+    if (isset($type)) {
+        $type = Database::escape_string($type);
+        $insert .= "'$type',";
+    } else {
+        $insert .= "NULL,";
+    }
+    if (isset($c)) { // Category
+        $c = Database::escape_string($c);
+        $insert .= "'$c',";
+    } else {
+        $insert .= "NULL,";
+    }
+    if (isset($sk)) { // Subkey
+        $sk = Database::escape_string($sk);
+        $insert .= "'$sk',";
+    } else {
+        $insert .= "NULL,";
+    }
+    if (isset($title)) { // Title
+        $title = Database::escape_string($title);
+        $insert .= "'$title',";
+    } else {
+        $insert .= "NULL,";
+    }
+    if (isset($com)) { // Comment
+        $com = Database::escape_string($com);
+        $insert .= "'$com',";
+    } else {
+        $insert .= "NULL,";
+    }
+    if (isset($sc)) { // Scope
+        $sc = Database::escape_string($sc);
+        $insert .= "'$sc',";
+    } else {
+        $insert .= "NULL,";
+    }
+    if (isset($skt)) { // Subkey text
+        $skt = Database::escape_string($skt);
+        $insert .= "'$skt',";
+    } else {
+        $insert .= "NULL,";
+    }
+    $insert .= "$a,$v)";
+    $res = Database::query($insert);
+
+    // update in memory setting value
+    $_setting[$var][$sk] = $value;
+
+    return $res;
+}
+
+/**
+ * converts a timestamp to sql tms
+ * @param lint $time a unix timestamp
+ */
+function make_tms($time) {
+    $tms = date('Y-m-d H:i:s', $time);
+    return $tms;
+}
+
+/**
+ * Makes sure the data is using valid utf8, invalid characters are discarded.
+ *
+ * Note: this function is not intended for full objects with methods and private properties.
+ *
+ * @param mixed $value
+ * @return mixed with proper utf-8 encoding
+ */
+function fix_utf8($value) {
+    if (is_null($value) or $value === '') {
+        return $value;
+
+    } else if (is_string($value)) {
+        if ((string)(int)$value === $value) {
+            // shortcut
+            return $value;
+        }
+
+        // Lower error reporting because glibc throws bogus notices.
+        $olderror = error_reporting();
+        if ($olderror & E_NOTICE) {
+            error_reporting($olderror ^ E_NOTICE);
+        }
+
+        // Note: this duplicates min_fix_utf8() intentionally.
+        static $buggyiconv = null;
+        if ($buggyiconv === null) {
+            $buggyiconv = (!function_exists('iconv') or iconv('UTF-8', 'UTF-8//IGNORE', '100'.chr(130).'\80') !== '100\80');
+        }
+
+        if ($buggyiconv) {
+            if (function_exists('mb_convert_encoding')) {
+                $subst = mb_substitute_character();
+                mb_substitute_character('');
+                $result = mb_convert_encoding($value, 'utf-8', 'utf-8');
+                mb_substitute_character($subst);
+
+            } else {
+                // Warn admins on admin/index.php page.
+                $result = $value;
+            }
+
+        } else {
+            $result = iconv('UTF-8', 'UTF-8//IGNORE', $value);
+        }
+
+        if ($olderror & E_NOTICE) {
+            error_reporting($olderror);
+        }
+
+        return $result;
+
+    } else if (is_array($value)) {
+        foreach ($value as $k=>$v) {
+            $value[$k] = fix_utf8($v);
+        }
+        return $value;
+
+    } else if (is_object($value)) {
+        $value = clone($value); // do not modify original
+        foreach ($value as $k=>$v) {
+            $value->$k = fix_utf8($v);
+        }
+        return $value;
+
+    } else {
+        // this is some other type, no utf-8 here
+        return $value;
+    }
+}
+
+function print_object($obj) {
+    echo '<pre>';
+    print_r($obj);
+    echo '</pre>';
+}
+
+function require_js($file, $component, $return = false) {
+    global $_configuration, $htmlHeadXtra;
+
+    if (preg_match('/^local_/', $component)) {
+        $component = str_replace('local_', '', $component);
+        $path = 'local/';
+    } else {
+        $path = 'plugin/';
+    }
+
+    // Secure the postslashing of the roots.
+    $root_web = $_configuration['root_web'].'/';
+    $root_web = preg_replace('#//$#', '/', $root_web);
+
+    $str = '<script type="text/javascript" src="'.$root_web.$path.$component.'/js/'.$file.'"></script>'."\n";
+    if ($return === 'head') {
+        $htmlHeadXtra[] = $str;
+    }
+    if ($return) {
+        return $str;
+    }
+    echo $str;
+}
+
+function require_css($file, $component, $return = false) {
+    global $_configuration, $htmlHeadXtra;
+
+    if (preg_match('/^local_/', $component)) {
+        $component = str_replace('local_', '', $component);
+        $path = 'local/';
+    } else {
+        $path = 'plugin/';
+    }
+
+    // Secure the postslashing of the roots.
+    $root_web = $_configuration['root_web'].'/';
+    $root_web = preg_replace('#//$#', '/', $root_web);
+
+    $str = '<link rel="stylesheet" type="text/css" href="'.$root_web.$path.$component.'/'.$file.'.css" />'."\n";
+    if ($return === 'head') {
+        $htmlHeadXtra[] = $str;
+    }
+    if ($return) {
+        return $str;
+    }
+    echo $str;
+}
+
+/**
+ *
+ */
+function required_param($key, $type = 0) {
+    if (array_key_exists($key, $_REQUEST)) {
+        $value = $_REQUEST[$key];
+        $value = param_filter_type($value, $type);
+        return $value;
+    }
+    die("Missing expected param $key in request input");
+}
+
+function optional_param($key, $default, $type = 0) {
+    if (array_key_exists($key, $_REQUEST)) {
+        $value = $_REQUEST[$key];
+        $value = param_filter_type($value, $type);
+        return $value;
+    }
+    return $default;
+}
+
+function param_filter_type($value, $type) {
+    switch($type) {
+        case 0:
+            return $value; // no filtering
+        case PARAM_BOOL:
+            return $value == 0; // forces outputing boolean
+        case PARAM_INT:
+            if (preg_match('/^([1-90]+)/', $value, $matches)) {
+                return $matches[1];
+            }
+            return 0;
+        case PARAM_TEXT:
+            // TODO more filtering here
+            return $value;
+    }
+}
+
+function redirect($url) {
+    header("Location: $url\n\n");
+}

+ 4 - 9
plugin/vchamilo/plugin.php

@@ -11,11 +11,6 @@ require_once(api_get_path(SYS_PLUGIN_PATH).'vchamilo/lib/vchamilo_plugin.class.p
 require_once(api_get_path(SYS_PLUGIN_PATH).'vchamilo/lib.php');
 
 global $_configuration;
-require_once($_configuration['root_sys'].'/local/classes/database.class.php');
-
-// replace chamilo Database API with stronger DB api
-global $DB;
-$DB = new DatabaseManager();
 
 /**
  * Plugin details (must be present)
@@ -33,10 +28,10 @@ $plugin_info['version']     = '1.0';
 $plugin_info['author']      = 'Valery Fremaux';
 
 
-/* Plugin optional settings */ 
+/* Plugin optional settings */
 
-/* 
- * This form will be showed in the plugin settings once the plugin was installed 
+/*
+ * This form will be showed in the plugin settings once the plugin was installed
  * in the plugin/hello_world/index.php you can have access to the value: $plugin_info['settings']['hello_world_show_type']
 */
 
@@ -83,7 +78,7 @@ $form->addElement('header', $plugininstance->get_lang('mysqlcmds'));
 $form->addElement('text', 'cmd_mysql', $plugininstance->get_lang('mysqlcmd'));
 $form->addElement('text', 'cmd_mysqldump', $plugininstance->get_lang('mysqldumpcmd'));
 
-$form->addElement('style_submit_button', 'submit_button', $plugininstance->get_lang('Save'));  
+$form->addButtonSave($plugininstance->get_lang('Save'));
 
 $plugin_info['settings_form'] = $form;
 

+ 24 - 26
plugin/vchamilo/views/editinstance.controller.php

@@ -9,6 +9,10 @@ if ($data->what == 'addinstance' || $data->what == 'registerinstance') {
     unset($data->what);
     unset($data->submitbutton);
     unset($data->id);
+    unset($data->vid);
+    unset($data->testconnection);
+    unset($data->testdatapath);
+
     $registeronly = $data->registeronly;
     unset($data->registeronly);
     $data->lastcron = 0;
@@ -19,13 +23,18 @@ if ($data->what == 'addinstance' || $data->what == 'registerinstance') {
         $template = $data->template;
         unset($data->template);
     }
-    
+
     ctrace("Registering VChamilo ");
     $tablename = Database::get_main_table('vchamilo');
-    if ($DB->record_exists('vchamilo', array('root_web' => $data->root_web))) {
-        $DB->update_record('vchamilo', $data, 'root_web');
+    $sql = "SELECT * FROM $tablename WHERE root_web = '".Database::escape_string($data->root_web)."'";
+    $result = Database::query($sql);
+
+    if (Database::num_rows($result)) {
+        $sql = "SELECT * FROM $tablename WHERE root_web = '".Database::escape_string($data->root_web)."'";
+        Database::update($tablename, $data, ['root_web = ?' => $data->root_web]);
+        //$DB->update_record('vchamilo', $data, 'root_web');
     } else {
-        $DB->insert_record('vchamilo', $data);
+        Database::insert($tablename, (array) $data);
     }
 
     if ($registeronly){
@@ -33,9 +42,9 @@ if ($data->what == 'addinstance' || $data->what == 'registerinstance') {
         ctrace("Registering only. out.");
         vchamilo_redirect(api_get_path(WEB_PLUGIN_PATH).'vchamilo/views/manage.php');
     }
-    
+
     // or we continue with physical creation
-    
+
     // Create course directory for operations.
     // this is very important here (DO NOT USE api_get_path() !!) because storage may be remotely located
     $absalternatecourse = vchamilo_get_config('vchamilo', 'course_real_root');
@@ -54,7 +63,7 @@ if ($data->what == 'addinstance' || $data->what == 'registerinstance') {
         $INDEX = fopen($coursedir.'/index.html', 'w');
         fputs($INDEX, vchamilo_get_default_course_index_fragment());
         fclose($INDEX);
-        
+
         $HTACCESS = fopen($coursedir.'/.htaccess', 'w');
         fputs($HTACCESS, vchamilo_get_htaccess_fragment($data->course_folder));
         fclose($HTACCESS);
@@ -79,9 +88,9 @@ if ($data->what == 'addinstance' || $data->what == 'registerinstance') {
     }
 
     // create homedir
-    
+
     // Structure of virtualized home folders :
-    
+
     /*
      * {LegacyHomeContainer} => {VChamiloSubcontainer} => {BrandedAccessUrlHome}
      *
@@ -92,12 +101,12 @@ if ($data->what == 'addinstance' || $data->what == 'registerinstance') {
     $archive_folder = $matches[1]; // prepare it now but use it later
     if ($absalternatehome = vchamilo_get_config('vchamilo', 'home_real_root')){
         // absalternatehome is a vchamilo config setting that tells where the
-        // real physical storage for home pages are. 
+        // real physical storage for home pages are.
         $homedir = str_replace('//', '/', $absalternatehome.'/'.$home_folder);
     } else {
         // homedir is the home container at install level. This may contains
         // in reality home subdirs from branding suburls.
-        // In straight installs, this should be located as a hostname subrouted 
+        // In straight installs, this should be located as a hostname subrouted
         // dir in home dir of the chamilo install.
         // In delocated installs (clustered installations), the root 'home' directory
         // may be a symbolic link to a delocated path.
@@ -165,40 +174,29 @@ if ($data->what == 'addinstance' || $data->what == 'registerinstance') {
         // deploy template database
 
         ctrace("Creating databases from template $template ");
-
         vchamilo_create_databases($data);
-
         ctrace("Loading data template $template ");
-
         vchamilo_load_db_template($data, 'main_database', $template);
-        if (!empty($data->statistics_database) && $data->main_database != $data->statistics_database) {
-            vchamilo_load_db_template($data, 'statistics_database', $template);
-        }
-        if (!empty($data->user_personal_database) && ($data->main_database != $data->user_personal_database) && ($data->user_personal_database != $data->statistics_database)) {
-            vchamilo_load_db_template($data, 'user_personal_database', $template);
-        }
-
         ctrace("Coying files from template $template ");
-
         vchamilo_load_files_from_template($data, $template);
     }
 
     ctrace("Fixing records");
 
     // Builds a new database manager on new instance to operate records
-    $NDB = new DatabaseManager($data);
+//    $NDB = new DatabaseManager($data);
 
     // pluging in site name institution
-    $settingstable = $NDB->format_table_name(TABLE_MAIN_SETTINGS_CURRENT);
+    $settingstable = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
     $sitename = str_replace("'", "''", $data->sitename);
     $institution = str_replace("'", "''", $data->institution);
     $sqls[] = " UPDATE {$settingstable} SET selected_value = '{$sitename}' WHERE variable = 'siteName' AND category = 'Platform' ";
     $sqls[] = " UPDATE {$settingstable} SET selected_value = '{$institution}' WHERE variable = 'institution' AND category = 'Platform' ";
-    $accessurltable = $NDB->format_table_name('access_url');
+    $accessurltable = Database::get_main_table(TABLE_MAIN_ACCESS_URL);
     $sqls[] = " UPDATE {$accessurltable} SET url = '{$data->root_web}' WHERE id = '1' ";
 
     foreach ($sqls as $sql) {
-        $NDB->execute_sql($sql);
+        Database::query($sql);
     }
 
     ctrace("Finished. ");

+ 12 - 19
plugin/vchamilo/views/editinstance.php

@@ -4,16 +4,10 @@ define('CHAMILO_INTERNAL', true);
 
 global $plugininstance;
 
-require_once('../../../main/inc/global.inc.php');
-require_once($_configuration['root_sys'].'/local/classes/mootochamlib.php');
-require_once($_configuration['root_sys'].'/local/classes/database.class.php');
-
-global $DB;
-$DB = new DatabaseManager();
-
-require_once(api_get_path(SYS_PLUGIN_PATH).'vchamilo/lib/vchamilo_plugin.class.php');
-require_once(api_get_path(SYS_PLUGIN_PATH).'vchamilo/views/editinstance_form.php');
-HTML_QuickForm::registerElementType('cancel', api_get_path(SYS_PLUGIN_PATH).'vchamilo/lib/QuickForm/cancel.php', 'HTML_QuickForm_cancel');
+require_once '../../../main/inc/global.inc.php';
+require_once api_get_path(SYS_PLUGIN_PATH).'vchamilo/lib.php';
+require_once api_get_path(SYS_PLUGIN_PATH).'vchamilo/lib/vchamilo_plugin.class.php';
+require_once api_get_path(SYS_PLUGIN_PATH).'vchamilo/views/editinstance_form.php';
 
 $htmlHeadXtra[] = '<script src="'.api_get_path(WEB_PLUGIN_PATH).'vchamilo/js/host_form.js" type="text/javascript" language="javascript"></script>';
 
@@ -27,7 +21,6 @@ $thisurl = api_get_path(WEB_PLUGIN_PATH).'vchamilo/views/manage.php';
 // security
 api_protect_admin_script();
 
-
 if ($id) {
     $mode = 'update';
 } else {
@@ -39,18 +32,18 @@ $form->definition();
 
 $actions = '';
 $message = '';
-
-// call controller
-// $data = $form->get_data();
-if ($data = $form->get_data()){
+if ($data = $form->get_data()) {
     include(api_get_path(SYS_PLUGIN_PATH).'vchamilo/views/editinstance.controller.php');
 }
 
 if ($id){
-    $vhost = $DB->get_record('vchamilo', array('id' => $id));
-    $vhost->vid = $vhost->id;
-    unset($vhost->id);
-    $form->set_data((array)$vhost);
+//    $vhost = $DB->get_record('vchamilo', array('id' => $id));
+    $sql = "SELECT * FROM vchamilo WHERE id = $id";
+    $result = Database::query($sql);
+    $vhost = Database::fetch_array($result);
+    $vhost['vid'] = $vhost['id'];
+    unset($vhost['id']);
+    $form->set_data($vhost);
 } else {
     $data = array();
     $data['db_host'] = 'localhost';

+ 321 - 23
plugin/vchamilo/views/editinstance_form.php

@@ -1,14 +1,325 @@
 <?php
 
-require_once(api_get_path(SYS_CODE_PATH).'inc/lib/pear/HTML/QuickForm.php');
-require_once(api_get_path(SYS_CODE_PATH).'inc/lib/formvalidator/FormValidator.class.php');
-require_once($_configuration['root_sys'].'local/classes/formslib.php');
+abstract class ChamiloForm
+{
+    protected $_form;
+    protected $_mode;
+    protected $_cancelurl;
+    protected $_customdata;
+
+    public function __construct($mode, $returnurl, $cancelurl, $customdata)
+    {
+        $this->_mode = $mode;
+        $this->_cancelurl = $cancelurl;
+        $this->_customdata = $customdata;
+
+        $attributes = array('style' => 'width: 60%; float: '.($text_dir == 'rtl' ? 'right;' : 'left;'));
+        // $this->_form = new FormValidator($mode.'_instance', 'post', $returnurl, '', $attributes, true);
+        $this->_form = new FormValidator($mode.'_instance', 'post', $returnurl, '', $attributes);
+    }
+
+    abstract function definition();
+    abstract function validation($data, $files = null);
+
+    function validate() {
+        return $this->_form->validate();
+    }
+
+    function display() {
+        return $this->_form->display();
+    }
+
+    function definition_after_data(){
+    }
+
+    function return_form(){
+        return $this->_form->toHtml();
+    }
+
+    function is_in_add_mode(){
+        return $this->_mode == 'add';
+    }
+
+    /**
+     * Use this method to a cancel and submit button to the end of your form. Pass a param of false
+     * if you don't want a cancel button in your form. If you have a cancel button make sure you
+     * check for it being pressed using is_cancelled() and redirecting if it is true before trying to
+     * get data with get_data().
+     *
+     * @param boolean $cancel whether to show cancel button, default true
+     * @param string $submitlabel label for submit button, defaults to get_string('savechanges')
+     */
+    public function add_action_buttons($cancel = true, $submitlabel = null, $cancellabel = null)
+    {
+        // TODO : refine lang fetch to effective global strings.
+        if (is_null($submitlabel)){
+            $submitlabel = get_lang('save');
+        }
+
+        if (is_null($cancellabel)){
+            $submitlabel = get_lang('cancel');
+        }
+
+        $cform =& $this->_form;
+        if ($cancel){
+            //when two elements we need a group
+            $buttonarray = array();
+            $buttonarray[] = &$cform->createElement('submit', 'submitbutton', $submitlabel);
+            //$buttonarray[] = &$cform->createElement('cancel', $cancellabel, $this->_cancelurl);
+            $cform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
+        } else {
+            //no group needed
+            $cform->addElement('submit', 'submitbutton', $submitlabel);
+        }
+    }
+
+    /**
+     * Return submitted data if properly submitted or returns NULL if validation fails or
+     * if there is no submitted data.
+     *
+     * @param bool $slashed true means return data with addslashes applied
+     * @return object submitted data; NULL if not valid or not submitted
+     */
+    public function get_data($slashed=true)
+    {
+        $cform =& $this->_form;
+
+        if ($this->is_submitted() and $this->is_validated()) {
+            $data = $cform->exportValues(null, $slashed);
+            unset($data['sesskey']); // we do not need to return sesskey
+            unset($data['_qf__'.$this->_formname]);   // we do not need the submission marker too
+            if (empty($data)) {
+                return NULL;
+            } else {
+                return (object)$data;
+            }
+        } else {
+            return NULL;
+        }
+    }
+
+    /**
+     * Return submitted data without validation or NULL if there is no submitted data.
+     *
+     * @param bool $slashed true means return data with addslashes applied
+     * @return object submitted data; NULL if not submitted
+     */
+    public function get_submitted_data($slashed=true)
+    {
+        $cform =& $this->_form;
+
+        if ($this->is_submitted()) {
+            $data = $cform->exportValues(null, $slashed);
+            unset($data['sesskey']); // we do not need to return sesskey
+            unset($data['_qf__'.$this->_formname]);   // we do not need the submission marker too
+            if (empty($data)) {
+                return NULL;
+            } else {
+                return (object)$data;
+            }
+        } else {
+            return NULL;
+        }
+    }
+
+    /**
+     * Check that form was submitted. Does not check validity of submitted data.
+     *
+     * @return bool true if form properly submitted
+     */
+    public function is_submitted()
+    {
+        return $this->_form->isSubmitted();
+    }
+
+    /**
+     * Return true if a cancel button has been pressed resulting in the form being submitted.
+     *
+     * @return bool true if a cancel button has been pressed
+     */
+    public function is_cancelled()
+    {
+        $cform =& $this->_form;
+        if ($cform->isSubmitted()){
+            foreach ($cform->_cancelButtons as $cancelbutton){
+                if (optional_param($cancelbutton, 0, PARAM_RAW)){
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
 
-class InstanceForm extends ChamiloForm{
+    /**
+     * Check that form data is valid.
+     * You should almost always use this, rather than {@see validate_defined_fields}
+     *
+     * @return bool true if form data valid
+     */
+    public function is_validated()
+    {
+        //finalize the form definition before any processing
+        if (!$this->_definition_finalized) {
+            $this->_definition_finalized = true;
+            $this->definition_after_data();
+        }
+        return $this->validate_defined_fields();
+    }
+
+    /**
+     * Validate the form.
+     *
+     * You almost always want to call {@see is_validated} instead of this
+     * because it calls {@see definition_after_data} first, before validating the form,
+     * which is what you want in 99% of cases.
+     *
+     * This is provided as a separate function for those special cases where
+     * you want the form validated before definition_after_data is called
+     * for example, to selectively add new elements depending on a no_submit_button press,
+     * but only when the form is valid when the no_submit_button is pressed,
+     *
+     * @param boolean $validateonnosubmit optional, defaults to false.  The default behaviour
+     *                is NOT to validate the form when a no submit button has been pressed.
+     *                pass true here to override this behaviour
+     *
+     * @return bool true if form data valid
+     */
+    public function validate_defined_fields($validateonnosubmit=false)
+    {
+        static $validated = null; // one validation is enough
+        $cform =& $this->_form;
+
+        if ($this->no_submit_button_pressed() && empty($validateonnosubmit)){
+            return false;
+        } elseif ($validated === null) {
+            $internal_val = $cform->validate();
+
+            $files = array();
+            $file_val = $this->_validate_files($files);
+            if ($file_val !== true) {
+                if (!empty($file_val)) {
+                    foreach ($file_val as $element => $msg) {
+                        $cform->setElementError($element, $msg);
+                    }
+                }
+                $file_val = false;
+            }
+
+            $data = $cform->exportValues(null, true);
+            $chamilo_val = $this->validation($data, $files);
+            if ((is_array($chamilo_val) && count($chamilo_val)!==0)) {
+                // non-empty array means errors
+                foreach ($chamilo_val as $element => $msg) {
+                    $cform->setElementError($element, $msg);
+                }
+                $chamilo_val = false;
+
+            } else {
+                // anything else means validation ok
+                $chamilo_val = true;
+            }
+
+            $validated = ($internal_val and $chamilo_val and $file_val);
+        }
+        return $validated;
+    }
+
+    public function no_submit_button_pressed()
+    {
+        static $nosubmit = null; // one check is enough
+
+        if (!is_null($nosubmit)){
+            return $nosubmit;
+        }
+
+        $cform =& $this->_form;
+        $nosubmit = false;
+        if (!$this->is_submitted()){
+            return false;
+        }
+        /*
+        foreach ($cform->_noSubmitButtons as $nosubmitbutton){
+            if (optional_param($nosubmitbutton, 0, PARAM_RAW)){
+                $nosubmit = true;
+                break;
+            }
+        }
+        return $nosubmit;
+        */
+        return false;
+    }
+
+    /**
+     * Load in existing data as form defaults. Usually new entry defaults are stored directly in
+     * form definition (new entry form); this function is used to load in data where values
+     * already exist and data is being edited (edit entry form).
+     *
+     * @param mixed $default_values object or array of default values
+     * @param bool $slashed true if magic quotes applied to data values
+     */
+    public function set_data($default_values, $slashed=false)
+    {
+        if (is_object($default_values)) {
+            $default_values = (array)$default_values;
+        }
+        $filter = $slashed ? 'stripslashes' : NULL;
+        $this->_form->setDefaults($default_values, $filter);
+    }
+
+    /**
+     * Internal method. Validates all uploaded files.
+     */
+    public function _validate_files(&$files)
+    {
+        $files = array();
+
+        if (empty($_FILES)) {
+            // we do not need to do any checks because no files were submitted
+            // note: server side rules do not work for files - use custom verification in validate() instead
+            return true;
+        }
+        $errors = array();
+        $mform =& $this->_form;
+
+        // check the files
+        $status = $this->_upload_manager->preprocess_files();
+
+        // now check that we really want each file
+        foreach ($_FILES as $elname=>$file) {
+            if ($mform->elementExists($elname) and $mform->getElementType($elname)=='file') {
+                $required = $mform->isElementRequired($elname);
+                if (!empty($this->_upload_manager->files[$elname]['uploadlog']) and empty($this->_upload_manager->files[$elname]['clear'])) {
+                    if (!$required and $file['error'] == UPLOAD_ERR_NO_FILE) {
+                        // file not uploaded and not required - ignore it
+                        continue;
+                    }
+                    $errors[$elname] = $this->_upload_manager->files[$elname]['uploadlog'];
+
+                } else if (!empty($this->_upload_manager->files[$elname]['clear'])) {
+                    $files[$elname] = $this->_upload_manager->files[$elname]['tmp_name'];
+                }
+            } else {
+                error('Incorrect upload attempt!');
+            }
+        }
 
-    var $_plugin;
+        // return errors if found
+        if ($status and 0 == count($errors)){
+            return true;
 
-    function __construct($plugin, $mode = 'add', $returnurl = null, $cancelurl = null){
+        } else {
+            $files = array();
+            return $errors;
+        }
+    }
+}
+
+class InstanceForm extends ChamiloForm
+{
+    public $_plugin;
+
+    public function __construct($plugin, $mode = 'add', $returnurl = null, $cancelurl = null)
+    {
         global $_configuration;
 
         $this->_plugin = $plugin;
@@ -18,7 +329,8 @@ class InstanceForm extends ChamiloForm{
         parent::__construct($mode, $returnurl, $cancelurl);
     }
 
-    function definition(){
+    function definition()
+    {
         global $_configuration;
 
         $cform = $this->_form;
@@ -40,12 +352,10 @@ class InstanceForm extends ChamiloForm{
         $cform->addElement('header', $this->_plugin->get_lang('hostdefinition'));
         // Name.
         $cform->addElement('text', 'sitename', $this->_plugin->get_lang('sitename'), $size_input_text);
-        $cform->applyFilter('sitename', 'html_filter');
         $cform->applyFilter('sitename', 'trim');
 
         // Shortname.
         $cform->addElement('text', 'institution', $this->_plugin->get_lang('institution'), ($this->mode == 'edit' ? 'disabled="disabled" ' : ''));
-        $cform->applyFilter('institution', 'html_filter');
         $cform->applyFilter('institution', 'trim');
 
         // Host's name.
@@ -74,18 +384,6 @@ class InstanceForm extends ChamiloForm{
         // Database name.
         $cform->addElement('text', 'main_database', $this->_plugin->get_lang('maindatabase'));
 
-        // Database name.
-        $cform->addElement('text', 'statistics_database', $this->_plugin->get_lang('statisticsdatabase'));
-
-        // Database name.
-        $cform->addElement('text', 'user_personal_database', $this->_plugin->get_lang('userpersonaldatabase'));
-
-        // tracking_enabled
-        $yesnooptions = array('0' => $this->_plugin->get_lang('no'), '1' => $this->_plugin->get_lang('yes'));
-        $cform->addElement('select', 'tracking_enabled', $this->_plugin->get_lang('trackingenabled'), $yesnooptions);
-
-        // Single database
-        $cform->addElement('select', 'single_database', $this->_plugin->get_lang('singledatabase'), $yesnooptions);
 
         // Table's prefix.
         $cform->addElement('text', 'table_prefix', $this->_plugin->get_lang('tableprefix'));
@@ -130,11 +428,11 @@ class InstanceForm extends ChamiloForm{
         }
     }
 
-    function validation($data, $files = null){
+    function validation($data, $files = null)
+    {
         global $plugininstance;
 
         $errors = array();
-        var_dump($data);
         if (!preg_match('/^courses[_-]/', $data['course_folder'])){
             $errors['course_folder'] = $plugininstance->get_lang('errormuststartwithcourses');
         }

+ 6 - 18
plugin/vchamilo/views/manage.php

@@ -1,12 +1,8 @@
 <?php
 
-require_once('../../../main/inc/global.inc.php');
-require_once($_configuration['root_sys'].'local/classes/mootochamlib.php');
-require_once($_configuration['root_sys'].'local/classes/database.class.php');
-require_once(api_get_path(SYS_PLUGIN_PATH).'vchamilo/lib/vchamilo_plugin.class.php');
-
-global $DB;
-$DB = new DatabaseManager();
+require_once '../../../main/inc/global.inc.php';
+require_once api_get_path(SYS_PLUGIN_PATH).'vchamilo/lib.php';
+require_once api_get_path(SYS_PLUGIN_PATH).'vchamilo/lib/vchamilo_plugin.class.php';
 
 $action = $_GET['what'];
 define('CHAMILO_INTERNAL', true);
@@ -16,23 +12,16 @@ $thisurl = api_get_path(WEB_PLUGIN_PATH).'vchamilo/views/manage.php';
 
 api_protect_admin_script();
 
-require_js('host_list.js', 'vchamilo');
+//require_js('host_list.js', 'vchamilo');
 
-if ($action){
+if ($action) {
     require_once(api_get_path(SYS_PLUGIN_PATH).'vchamilo/views/manage.controller.php');
 }
 
 $content = Display::page_header('VChamilo Instances');
 
 $table = 'vchamilo';
-
-$query = "
-    SELECT
-        *
-    FROM
-        $table
-";
-
+$query = "SELECT * FROM $table";
 $result = Database::query($query);
 $instances = array();
 while ($instance = Database::fetch_object($result)) {
@@ -101,4 +90,3 @@ $tpl->assign('actions', $actions);
 $tpl->assign('message', $message);
 $tpl->assign('content', $content);
 $tpl->display_one_col_template();
-