='); } /** * This function checks if a php extension exists or not and returns an HTML status string. * * @param string $extensionName Name of the PHP extension to be checked * @param string $returnSuccess Text to show when extension is available (defaults to 'Yes') * @param string $returnFailure Text to show when extension is available (defaults to 'No') * @param boolean $optional Whether this extension is optional (then show unavailable text in orange rather than red) * @param string $enabledTerm If this string is not null, then use to check if the corresponding parameter is = 1. If not, mention it's present but not enabled. For example, for opcache, this should be 'opcache.enable' * @return string HTML string reporting the status of this extension. Language-aware. * @author Christophe Gesch?? * @author Patrick Cool , Ghent University * @author Yannick Warnier */ function checkExtension($extensionName, $returnSuccess = 'Yes', $returnFailure = 'No', $optional = false, $enabledTerm = '') { if (extension_loaded($extensionName)) { if (!empty($enabledTerm)) { $isEnabled = ini_get($enabledTerm); if ($isEnabled == '1') { return Display::label($returnSuccess, 'success'); } else { if ($optional) { return Display::label(get_lang('ExtensionInstalledButNotEnabled'), 'warning'); } else { return Display::label(get_lang('ExtensionInstalledButNotEnabled'), 'important'); } } } else { return Display::label($returnSuccess, 'success'); } } else { if ($optional) { return Display::label($returnFailure, 'warning'); } else { return Display::label($returnFailure, 'important'); } } } /** * This function checks whether a php setting matches the recommended value * @param string $phpSetting A PHP setting to check * @param string $recommendedValue A recommended value to show on screen * @param mixed $returnSuccess What to show on success * @param mixed $returnFailure What to show on failure * @return string A label to show * @author Patrick Cool , Ghent University */ function checkPhpSetting($phpSetting, $recommendedValue, $returnSuccess = false, $returnFailure = false) { $currentPhpValue = getPhpSetting($phpSetting); if ($currentPhpValue == $recommendedValue) { return Display::label($currentPhpValue.' '.$returnSuccess, 'success'); } else { return Display::label($currentPhpValue.' '.$returnSuccess, 'important'); } } /** * This function return the value of a php.ini setting if not "" or if exists, * otherwise return false * @param string $phpSetting The name of a PHP setting * @return mixed The value of the setting, or false if not found */ function checkPhpSettingExists($phpSetting) { if (ini_get($phpSetting) != "") { return ini_get($phpSetting); } return false; } /** * Check if the current url is the same root_web when the multiple_access_url is enabled * @return bool */ function checkAccessUrl() { if (api_get_configuration_value('multiple_access_urls') !== true) { return true; } $currentWebPath = api_get_path(WEB_PATH); $rootWeb = api_get_configuration_value('root_web'); return $currentWebPath === $rootWeb; } /** * Returns a textual value ('ON' or 'OFF') based on a requester 2-state ini- configuration setting. * * @param string $val a php ini value * @return boolean: ON or OFF * @author Joomla */ function getPhpSetting($val) { return ini_get($val) == '1' ? 'ON' : 'OFF'; } /** * This function returns a string "true" or "false" according to the passed parameter. * * @param integer $var The variable to present as text * @return string the string "true" or "false" * @author Christophe Gesch?? */ function trueFalse($var) { return $var ? 'true' : 'false'; } /** * Removes memory and time limits as much as possible. */ function remove_memory_and_time_limits() { if (function_exists('ini_set')) { ini_set('memory_limit', -1); ini_set('max_execution_time', 0); error_log('Update-db script: memory_limit set to -1', 0); error_log('Update-db script: max_execution_time 0', 0); } else { error_log('Update-db script: could not change memory and time limits', 0); } } /** * Detects browser's language. * @return string Returns a language identificator, i.e. 'english', 'spanish', ... * @author Ivan Tcholakov, 2010 */ function detect_browser_language() { static $language_index = array( 'ar' => 'arabic', 'ast' => 'asturian', 'bg' => 'bulgarian', 'bs' => 'bosnian', 'ca' => 'catalan', 'zh' => 'simpl_chinese', 'zh-tw' => 'trad_chinese', 'cs' => 'czech', 'da' => 'danish', 'prs' => 'dari', 'de' => 'german', 'el' => 'greek', 'en' => 'english', 'es' => 'spanish', 'eo' => 'esperanto', 'eu' => 'basque', 'fa' => 'persian', 'fr' => 'french', 'fur' => 'friulian', 'gl' => 'galician', 'ka' => 'georgian', 'hr' => 'croatian', 'he' => 'hebrew', 'hi' => 'hindi', 'id' => 'indonesian', 'it' => 'italian', 'ko' => 'korean', 'lv' => 'latvian', 'lt' => 'lithuanian', 'mk' => 'macedonian', 'hu' => 'hungarian', 'ms' => 'malay', 'nl' => 'dutch', 'ja' => 'japanese', 'no' => 'norwegian', 'oc' => 'occitan', 'ps' => 'pashto', 'pl' => 'polish', 'pt' => 'portuguese', 'pt-br' => 'brazilian', 'ro' => 'romanian', 'qu' => 'quechua_cusco', 'ru' => 'russian', 'sk' => 'slovak', 'sl' => 'slovenian', 'sr' => 'serbian', 'fi' => 'finnish', 'sv' => 'swedish', 'th' => 'thai', 'tr' => 'turkish', 'uk' => 'ukrainian', 'vi' => 'vietnamese', 'sw' => 'swahili', 'yo' => 'yoruba' ); $system_available_languages = & get_language_folder_list(); $accept_languages = strtolower(str_replace('_', '-', $_SERVER['HTTP_ACCEPT_LANGUAGE'])); foreach ($language_index as $code => $language) { if (strpos($accept_languages, $code) === 0) { if (!empty($system_available_languages[$language])) { return $language; } } } $user_agent = strtolower(str_replace('_', '-', $_SERVER['HTTP_USER_AGENT'])); foreach ($language_index as $code => $language) { if (@preg_match("/[\[\( ]{$code}[;,_\-\)]/", $user_agent)) { if (!empty($system_available_languages[$language])) { return $language; } } } return 'english'; } /* FILESYSTEM RELATED FUNCTIONS */ /** * This function checks if the given folder is writable * @param string $folder Full path to a folder * @param bool $suggestion Whether to show a suggestion or not * @return string */ function check_writable($folder, $suggestion = false) { if (is_writable($folder)) { return Display::label(get_lang('Writable'), 'success'); } else { if ($suggestion) { return Display::label(get_lang('NotWritable'), 'info'); } else { return Display::label(get_lang('NotWritable'), 'important'); } } } /** * This function checks if the given folder is readable * @param string $folder Full path to a folder * @param bool $suggestion Whether to show a suggestion or not * * @return string */ function checkReadable($folder, $suggestion = false) { if (is_readable($folder)) { return Display::label(get_lang('Readable'), 'success'); } else { if ($suggestion) { return Display::label(get_lang('NotReadable'), 'info'); } else { return Display::label(get_lang('NotReadable'), 'important'); } } } /** * This function is similar to the core file() function, except that it * works with line endings in Windows (which is not the case of file()) * @param string $filename * * @return array The lines of the file returned as an array */ function file_to_array($filename) { if (!is_readable($filename) || is_dir($filename)) { return array(); } $fp = fopen($filename, 'rb'); $buffer = fread($fp, filesize($filename)); fclose($fp); return explode('
', nl2br($buffer)); } /** * We assume this function is called from install scripts that reside inside the install folder. */ function set_file_folder_permissions() { @chmod('.', 0755); //set permissions on install dir @chmod('..', 0755); //set permissions on parent dir of install dir } /** * Write the main system config file * @param string $path Path to the config file */ function write_system_config_file($path) { global $dbHostForm; global $dbPortForm; global $dbUsernameForm; global $dbPassForm; global $dbNameForm; global $urlForm; global $pathForm; global $urlAppendPath; global $languageForm; global $encryptPassForm; global $session_lifetime; global $new_version; global $new_version_stable; $root_sys = api_add_trailing_slash(str_replace('\\', '/', realpath($pathForm))); $content = file_get_contents(__DIR__.'/'.SYSTEM_CONFIG_FILENAME); $config['{DATE_GENERATED}'] = date('r'); $config['{DATABASE_HOST}'] = $dbHostForm; $config['{DATABASE_PORT}'] = $dbPortForm; $config['{DATABASE_USER}'] = $dbUsernameForm; $config['{DATABASE_PASSWORD}'] = $dbPassForm; $config['{DATABASE_MAIN}'] = $dbNameForm; $config['{ROOT_WEB}'] = $urlForm; $config['{ROOT_SYS}'] = $root_sys; $config['{URL_APPEND_PATH}'] = $urlAppendPath; $config['{PLATFORM_LANGUAGE}'] = $languageForm; $config['{SECURITY_KEY}'] = md5(uniqid(rand().time())); $config['{ENCRYPT_PASSWORD}'] = $encryptPassForm; $config['SESSION_LIFETIME'] = $session_lifetime; $config['{NEW_VERSION}'] = $new_version; $config['NEW_VERSION_STABLE'] = trueFalse($new_version_stable); foreach ($config as $key => $value) { $content = str_replace($key, $value, $content); } $fp = @ fopen($path, 'w'); if (!$fp) { echo 'Your script doesn\'t have write access to the config directory
('.str_replace('\\', '/', realpath($path)).')

You probably do not have write access on Chamilo root directory, i.e. you should CHMOD 777 or 755 or 775.

Your problems can be related on two possible causes:
  • Permission problems.
    Try initially with chmod -R 777 and increase restrictions gradually.
  • PHP is running in Safe-Mode. If possible, try to switch it off.
Read about this problem in Support Forum

Please go back to step 5.

'; exit; } fwrite($fp, $content); fclose($fp); } /** * Returns a list of language directories. */ function & get_language_folder_list() { static $result; if (!is_array($result)) { $result = array(); $exceptions = array('.', '..', 'CVS', '.svn'); $search = array('_latin', '_unicode', '_corporate', '_org', '_KM', '_'); $replace_with = array(' (Latin)', ' (unicode)', ' (corporate)', ' (org)', ' (KM)', ' '); $dirname = api_get_path(SYS_LANG_PATH); $handle = opendir($dirname); while ($entries = readdir($handle)) { if (in_array($entries, $exceptions)) { continue; } if (is_dir($dirname.$entries)) { if (is_file($dirname.$entries.'/install_disabled')) { // Skip all languages that have this file present, just for // the install process (languages incomplete) continue; } $result[$entries] = ucwords(str_replace($search, $replace_with, $entries)); } } closedir($handle); asort($result); } return $result; } /** * TODO: my_directory_to_array() - maybe within the main API there is already a suitable function? * @param string $directory Full path to a directory * @return array A list of files and dirs in the directory */ function my_directory_to_array($directory) { $array_items = array(); if ($handle = opendir($directory)) { while (false !== ($file = readdir($handle))) { if ($file != "." && $file != "..") { if (is_dir($directory."/".$file)) { $array_items = array_merge($array_items, my_directory_to_array($directory.'/'.$file)); $file = $directory."/".$file; $array_items[] = preg_replace("/\/\//si", '/', $file); } } } closedir($handle); } return $array_items; } /** * This function returns the value of a parameter from the configuration file * * WARNING - this function relies heavily on global variables $updateFromConfigFile * and $configFile, and also changes these globals. This can be rewritten. * * @param string $param the parameter of which the value is returned * @param string If we want to give the path rather than take it from POST * @return string the value of the parameter * @author Olivier Brouckaert * @author Reworked by Ivan Tcholakov, 2010 */ function get_config_param($param, $updatePath = '') { global $configFile, $updateFromConfigFile; // Look if we already have the queried parameter. if (is_array($configFile) && isset($configFile[$param])) { return $configFile[$param]; } if (empty($updatePath) && !empty($_POST['updatePath'])) { $updatePath = $_POST['updatePath']; } if (empty($updatePath)) { $updatePath = api_get_path(SYS_PATH); } $updatePath = api_add_trailing_slash(str_replace('\\', '/', realpath($updatePath))); $updateFromInstalledVersionFile = ''; if (empty($updateFromConfigFile)) { // If update from previous install was requested, // try to recover config file from Chamilo 1.9.x if (file_exists($updatePath.'main/inc/conf/configuration.php')) { $updateFromConfigFile = 'main/inc/conf/configuration.php'; } elseif (file_exists($updatePath.'app/config/configuration.php')) { $updateFromConfigFile = 'app/config/configuration.php'; } else { // Give up recovering. //error_log('Chamilo Notice: Could not find previous config file at '.$updatePath.'main/inc/conf/configuration.php nor at '.$updatePath.'claroline/inc/conf/claro_main.conf.php in get_config_param(). Will start new config (in '.__FILE__.', line '.__LINE__.')', 0); return null; } } if (file_exists($updatePath.$updateFromConfigFile) && !is_dir($updatePath.$updateFromConfigFile) ) { require $updatePath.$updateFromConfigFile; $config = new Zend\Config\Config($_configuration); return $config->get($param); } error_log('Config array could not be found in get_config_param()', 0); return null; /*if (file_exists($updatePath.$updateFromConfigFile)) { return $val; } else { error_log('Config array could not be found in get_config_param()', 0); return null; }*/ } /* DATABASE RELATED FUNCTIONS */ /** * Gets a configuration parameter from the database. Returns returns null on failure. * @param string $param Name of param we want * @return mixed The parameter value or null if not found */ function get_config_param_from_db($param = '') { if (($res = Database::query("SELECT * FROM settings_current WHERE variable = '$param'")) !== false) { if (Database::num_rows($res) > 0) { $row = Database::fetch_array($res); return $row['selected_value']; } } return null; } /** * Connect to the database and returns the entity manager * @param string $dbHostForm DB host * @param string $dbUsernameForm DB username * @param string $dbPassForm DB password * @param string $dbNameForm DB name * @param int $dbPortForm DB port * * @return EntityManager */ function connectToDatabase($dbHostForm, $dbUsernameForm, $dbPassForm, $dbNameForm, $dbPortForm = 3306) { $dbParams = array( 'driver' => 'pdo_mysql', 'host' => $dbHostForm, 'port' => $dbPortForm, 'user' => $dbUsernameForm, 'password' => $dbPassForm, 'dbname' => $dbNameForm ); $database = new \Database(); $database->connect($dbParams); return $database->getManager(); } /* DISPLAY FUNCTIONS */ /** * This function prints class=active_step $current_step=$param * @param int $param A step in the installer process * @author Patrick Cool , Ghent University */ function step_active($param) { global $current_step; if ($param == $current_step) { echo 'class="current-step" '; } } /** * This function displays the Step X of Y - * @return string String that says 'Step X of Y' with the right values */ function display_step_sequence() { global $current_step; return get_lang('Step'.$current_step).' – '; } /** * Displays a drop down box for selection the preferred language. */ function display_language_selection_box($name = 'language_list', $default_language = 'english') { // Reading language list. $language_list = get_language_folder_list(); /* // Reduction of the number of languages shown. Enable this fragment of code for customization purposes. // Modify the language list according to your preference. Don't exclude the 'english' item. $language_to_display = array('asturian', 'bulgarian', 'english', 'italian', 'french', 'slovenian', 'slovenian_unicode', 'spanish'); foreach ($language_list as $key => & $value) { if (!in_array($key, $language_to_display)) { unset($language_list[$key]); } } */ // Sanity checks due to the possibility for customizations. if (!is_array($language_list) || empty($language_list)) { $language_list = array('english' => 'English'); } // Sorting again, if it is necessary. //asort($language_list); // More sanity checks. if (!array_key_exists($default_language, $language_list)) { if (array_key_exists('english', $language_list)) { $default_language = 'english'; } else { $language_keys = array_keys($language_list); $default_language = $language_keys[0]; } } // Displaying the box. $html = ''; $html .= "\t\t
, Ghent University */ function display_requirements( $installType, $badUpdatePath, $updatePath = '', $update_from_version_8 = array() ) { global $_setting; echo '

'.display_step_sequence().get_lang('Requirements')."

"; echo '
'; echo ''.get_lang('ReadThoroughly').'
'; echo get_lang('MoreDetails').' '.get_lang('ReadTheInstallationGuide').'.
'."\n"; if ($installType == 'update') { echo get_lang('IfYouPlanToUpgradeFromOlderVersionYouMightWantToHaveAlookAtTheChangelog').'
'; } echo '
'; $properlyAccessUrl = checkAccessUrl(); if (!$properlyAccessUrl) { echo '
' . Display::return_icon('error.png', get_lang('Error'), [], ICON_SIZE_MEDIUM, true, false, true). ' '. sprintf(get_lang('InstallMultiURLDetectedNotMainURL'), api_get_configuration_value('root_web')).'
'; } // SERVER REQUIREMENTS echo '

'.get_lang('ServerRequirements').'

'; $timezone = checkPhpSettingExists("date.timezone"); if (!$timezone) { echo "
". Display::return_icon( 'warning.png', get_lang('Warning'), '', ICON_SIZE_MEDIUM, true, false, false ). get_lang("DateTimezoneSettingNotSet")."
"; } echo '
'.get_lang('ServerRequirementsInfo').'
'; echo '
'; echo '
'.get_lang('PHPVersion').' >= '.REQUIRED_PHP_VERSION.' '; if (phpversion() < REQUIRED_PHP_VERSION) { echo ''.get_lang('PHPVersionError').''; } else { echo ''.get_lang('PHPVersionOK').' '.phpversion().''; } echo '
Session '.get_lang('Support').' '.checkExtension('session', get_lang('Yes'), get_lang('ExtensionSessionsNotAvailable')).'
pdo_mysql '.get_lang('Support').' '.checkExtension('pdo_mysql', get_lang('Yes'), get_lang('ExtensionMySQLNotAvailable')).'
Zip '.get_lang('Support').' '.checkExtension('zip', get_lang('Yes'), get_lang('ExtensionNotAvailable')).'
Zlib '.get_lang('Support').' '.checkExtension('zlib', get_lang('Yes'), get_lang('ExtensionZlibNotAvailable')).'
Perl-compatible regular expressions '.get_lang('Support').' '.checkExtension('pcre', get_lang('Yes'), get_lang('ExtensionPCRENotAvailable')).'
XML '.get_lang('Support').' '.checkExtension('xml', get_lang('Yes'), get_lang('No')).'
Internationalization '.get_lang('Support').' '.checkExtension('intl', get_lang('Yes'), get_lang('No')).'
JSON '.get_lang('Support').' '.checkExtension('json', get_lang('Yes'), get_lang('No')).'
GD '.get_lang('Support').' '.checkExtension('gd', get_lang('Yes'), get_lang('ExtensionGDNotAvailable')).'
cURL'.get_lang('Support').' '.checkExtension('curl', get_lang('Yes'), get_lang('No')).'
Multibyte string '.get_lang('Support').' ('.get_lang('Optional').') '.checkExtension('mbstring', get_lang('Yes'), get_lang('ExtensionMBStringNotAvailable'), true).'
Zend OpCache '.get_lang('Support').' ('.get_lang('Optional').') '.checkExtension('Zend OPcache', get_lang('Yes'), get_lang('No'), true, 'opcache.enable').'
APCu '.get_lang('Support').' ('.get_lang('Optional').') '.checkExtension('apcu', get_lang('Yes'), get_lang('No'), true, 'apc.enabled').'
Iconv '.get_lang('Support').' ('.get_lang('Optional').') '.checkExtension('iconv', get_lang('Yes'), get_lang('No'), true).'
LDAP '.get_lang('Support').' ('.get_lang('Optional').') '.checkExtension('ldap', get_lang('Yes'), get_lang('ExtensionLDAPNotAvailable'), true).'
Xapian '.get_lang('Support').' ('.get_lang('Optional').') '.checkExtension('xapian', get_lang('Yes'), get_lang('No'), true).'
'; echo '
'; echo '
'; // RECOMMENDED SETTINGS // Note: these are the settings for Joomla, does this also apply for Chamilo? // Note: also add upload_max_filesize here so that large uploads are possible echo '

'.get_lang('RecommendedSettings').'

'; echo '
'.get_lang('RecommendedSettingsInfo').'
'; echo '
'; echo '
'.get_lang('Setting').' '.get_lang('Recommended').' '.get_lang('Actual').'
Safe Mode '.checkPhpSetting('safe_mode', 'OFF').'
Display Errors '.checkPhpSetting('display_errors', 'OFF').'
File Uploads '.checkPhpSetting('file_uploads', 'ON').'
Magic Quotes GPC '.checkPhpSetting('magic_quotes_gpc', 'OFF').'
Magic Quotes Runtime '.checkPhpSetting('magic_quotes_runtime', 'OFF').'
Register Globals '.checkPhpSetting('register_globals', 'OFF').'
Session auto start '.checkPhpSetting('session.auto_start', 'OFF').'
Short Open Tag '.checkPhpSetting('short_open_tag', 'OFF').'
Cookie HTTP Only '.checkPhpSetting('session.cookie_httponly', 'ON').'
Maximum upload file size '.compare_setting_values(ini_get('upload_max_filesize'), REQUIRED_MIN_UPLOAD_MAX_FILESIZE).'
Maximum post size '.compare_setting_values(ini_get('post_max_size'), REQUIRED_MIN_POST_MAX_SIZE).'
Memory Limit '.compare_setting_values(ini_get('memory_limit'), REQUIRED_MIN_MEMORY_LIMIT).'
'; echo '
'; echo '
'; // DIRECTORY AND FILE PERMISSIONS echo '

'.get_lang('DirectoryAndFilePermissions').'

'; echo '
'.get_lang('DirectoryAndFilePermissionsInfo').'
'; echo '
'; $course_attempt_name = '__XxTestxX__'; $course_dir = api_get_path(SYS_COURSE_PATH).$course_attempt_name; //Just in case @unlink($course_dir.'/test.php'); @rmdir($course_dir); $perms_dir = array(0777, 0755, 0775, 0770, 0750, 0700); $perms_fil = array(0666, 0644, 0664, 0660, 0640, 0600); $course_test_was_created = false; $dir_perm_verified = 0777; foreach ($perms_dir as $perm) { $r = @mkdir($course_dir, $perm); if ($r === true) { $dir_perm_verified = $perm; $course_test_was_created = true; break; } } $fil_perm_verified = 0666; $file_course_test_was_created = false; if (is_dir($course_dir)) { foreach ($perms_fil as $perm) { if ($file_course_test_was_created == true) { break; } $r = @touch($course_dir.'/test.php', $perm); if ($r === true) { $fil_perm_verified = $perm; if (check_course_script_interpretation($course_dir, $course_attempt_name, 'test.php')) { $file_course_test_was_created = true; } } } } @unlink($course_dir.'/test.php'); @rmdir($course_dir); $_SESSION['permissions_for_new_directories'] = $_setting['permissions_for_new_directories'] = $dir_perm_verified; $_SESSION['permissions_for_new_files'] = $_setting['permissions_for_new_files'] = $fil_perm_verified; $dir_perm = Display::label('0'.decoct($dir_perm_verified), 'info'); $file_perm = Display::label('0'.decoct($fil_perm_verified), 'info'); $courseTestLabel = Display::label(get_lang('No'), 'important'); if ($course_test_was_created && $file_course_test_was_created) { $courseTestLabel = Display::label(get_lang('Yes'), 'success'); } if ($course_test_was_created && !$file_course_test_was_created) { $courseTestLabel = Display::label(get_lang('Warning'), 'warning'); $courseTestLabel .= '
'.sprintf( get_lang('InstallWarningCouldNotInterpretPHP'), api_get_path(WEB_COURSE_PATH).$course_attempt_name.'/test.php' ); } if (!$course_test_was_created && !$file_course_test_was_created) { $courseTestLabel = Display::label(get_lang('No'), 'important'); } $oldConf = ''; if (file_exists(api_get_path(SYS_CODE_PATH).'inc/conf/configuration.php')) { $oldConf = ' '.api_get_path(SYS_CODE_PATH).'inc/conf '.check_writable(api_get_path(SYS_CODE_PATH).'inc/conf').' '; } echo ' '.$oldConf.'
'.api_get_path(SYS_APP_PATH).' '.check_writable(api_get_path(SYS_APP_PATH)).'
'.api_get_path(SYS_CODE_PATH).'default_course_document/images/ '.check_writable(api_get_path(SYS_CODE_PATH).'default_course_document/images/').'
'.api_get_path(SYS_CODE_PATH).'lang/ '.check_writable(api_get_path(SYS_CODE_PATH).'lang/', true).'
('.get_lang('SuggestionOnlyToEnableSubLanguageFeatureOrUpgradeProcess').')
'.api_get_path(SYS_PATH).'vendor/ '.checkReadable(api_get_path(SYS_PATH).'vendor').'
'.api_get_path(SYS_PUBLIC_PATH).' '.check_writable(api_get_path(SYS_PUBLIC_PATH)).'
'.get_lang('CourseTestWasCreated').' '.$courseTestLabel.'
'.get_lang('PermissionsForNewDirs').' '.$dir_perm.'
'.get_lang('PermissionsForNewFiles').' '.$file_perm.'
'; echo '
'; echo '
'; if ($installType == 'update' && (empty($updatePath) || $badUpdatePath)) { if ($badUpdatePath) { ?>
!
Chamilo .
'; } ?>

:

The user would have to adjust the permissions manually if (count($notWritable) > 0) { $error = true; ?>

', ''); ?>

'; foreach ($notWritable as $value) { echo '
  • '.$value.'
  • '; } echo ''; } elseif (file_exists(api_get_path(CONFIGURATION_PATH).'configuration.php')) { // Check wether a Chamilo configuration file already exists. echo '

    '; echo get_lang('WarningExistingLMSInstallationDetected'); echo '

    '; } $deprecated = [ api_get_path(SYS_CODE_PATH).'exercice/', api_get_path(SYS_CODE_PATH).'newscorm/', api_get_path(SYS_PLUGIN_PATH).'ticket/' ]; $deprecatedToRemove = []; foreach ($deprecated as $deprecatedDirectory) { if (!is_dir($deprecatedDirectory)) { continue; } $deprecatedToRemove[] = $deprecatedDirectory; } if (count($deprecatedToRemove) > 0) { $error = true; ?>

    '.display_step_sequence().get_lang('Licence').'

    '; echo '

    '.get_lang('LMSLicenseInfo').'

    '; echo '

    '.get_lang('PrintVers').'

    '; echo ''; ?>
                    
                


    '.get_countries_list_from_array(true).'
     
     
    *'.get_lang('FieldRequired').'
    '; return $html; } /** * Displays a parameter in a table row. * Used by the display_database_settings_form function. * @param string Type of install * @param string Name of parameter * @param string Field name (in the HTML form) * @param string Field value * @param string Extra notice (to show on the right side) * @param boolean Whether to display in update mode * @param string Additional attribute for the element * @return void Direct output */ function displayDatabaseParameter( $installType, $parameterName, $formFieldName, $parameterValue, $extra_notice, $displayWhenUpdate = true, $tr_attribute = '' ) { //echo ""; echo ""; if ($installType == INSTALL_TYPE_UPDATE && $displayWhenUpdate) { echo ''.$parameterValue; } else { $inputType = $formFieldName == 'dbPassForm' ? 'password' : 'text'; //Slightly limit the length of the database prefix to avoid having to cut down the databases names later on $maxLength = $formFieldName == 'dbPrefixForm' ? '15' : MAX_FORM_FIELD_LENGTH; if ($installType == INSTALL_TYPE_UPDATE) { echo ''; echo api_htmlentities($parameterValue); } else { echo '
    '."
    "; echo '
    '.$extra_notice.'
    '; } } } /** * Displays step 3 - a form where the user can enter the installation settings * regarding the databases - login and password, names, prefixes, single * or multiple databases, tracking or not... * @param string $installType * @param string $dbHostForm * @param string $dbUsernameForm * @param string $dbPassForm * @param string $dbNameForm * @param int $dbPortForm * @param string $installationProfile */ function display_database_settings_form( $installType, $dbHostForm, $dbUsernameForm, $dbPassForm, $dbNameForm, $dbPortForm = 3306, $installationProfile = '' ) { if ($installType == 'update') { global $_configuration; $dbHostForm = $_configuration['db_host']; $dbUsernameForm = $_configuration['db_user']; $dbPassForm = $_configuration['db_password']; $dbNameForm = $_configuration['main_database']; $dbPortForm = isset($_configuration['db_port']) ? $_configuration['db_port'] : ''; echo '

    '.display_step_sequence().get_lang('DBSetting').'

    '; echo '
    '; echo get_lang('DBSettingUpgradeIntro'); echo '
    '; } else { echo '

    '.display_step_sequence().get_lang('DBSetting').'

    '; echo '
    '; echo get_lang('DBSettingIntro'); echo '
    '; } ?>
    getConnection()->getSchemaManager()->listDatabases(); if (in_array($dbNameForm, $databases)) { $database_exists_text = '
    '.get_lang('ADatabaseWithTheSameNameAlreadyExists').'
    '; } } catch (Exception $e) { $database_exists_text = $e->getMessage(); } if ($manager && $manager->getConnection()->isConnected()): ?>
    Database host: getConnection()->getHost(); ?>
    Database port: getConnection()->getPort(); ?>
    Database driver: getConnection()->getDriver()->getName(); ?>

    'panel-heading')); $panelBody = Display::div($content, array('class' => 'panel-body')); $panelParent = Display::div($panelTitle.$panelBody, array('id' => $id, 'class' => 'panel panel-'.$style)); } else { $panelBody = Display::div($html, array('class' => 'panel-body')); $panelParent = Display::div($panelBody, array('id' => $id, 'class' => 'panel panel-'.$style)); } $html .= $panelParent; return $html; } /** * Displays a parameter in a table row. * Used by the display_configuration_settings_form function. * @param string $installType * @param string $parameterName * @param string $formFieldName * @param string $parameterValue * @param string $displayWhenUpdate */ function display_configuration_parameter( $installType, $parameterName, $formFieldName, $parameterValue, $displayWhenUpdate = 'true' ) { $html = '
    '; $html .= ''; if ($installType == INSTALL_TYPE_UPDATE && $displayWhenUpdate) { $html .= ''.$parameterValue; } else { $html .= '
    '."
    "; } $html .= "
    "; return $html; } /** * Displays step 4 of the installation - configuration settings about Chamilo itself. * @param string $installType * @param string $urlForm * @param string $languageForm * @param string $emailForm * @param string $adminFirstName * @param string $adminLastName * @param string $adminPhoneForm * @param string $campusForm * @param string $institutionForm * @param string $institutionUrlForm * @param string $encryptPassForm * @param bool $allowSelfReg * @param bool $allowSelfRegProf * @param string $loginForm * @param string $passForm */ function display_configuration_settings_form( $installType, $urlForm, $languageForm, $emailForm, $adminFirstName, $adminLastName, $adminPhoneForm, $campusForm, $institutionForm, $institutionUrlForm, $encryptPassForm, $allowSelfReg, $allowSelfRegProf, $loginForm, $passForm ) { if ($installType != 'update' && empty($languageForm)) { $languageForm = $_SESSION['install_language']; } echo '
    '; echo "

    ".display_step_sequence().get_lang("CfgSetting")."

    "; echo '
    '; echo '

    '.get_lang('ConfigSettingsInfo').' app/config/configuration.php

    '; // Parameter 1: administrator's login $html = ''; $html .= display_configuration_parameter($installType, get_lang('AdminLogin'), 'loginForm', $loginForm, $installType == 'update'); // Parameter 2: administrator's password if ($installType != 'update') { $html .= display_configuration_parameter($installType, get_lang('AdminPass'), 'passForm', $passForm, false); } // Parameters 3 and 4: administrator's names $html .= display_configuration_parameter($installType, get_lang('AdminFirstName'), 'adminFirstName', $adminFirstName); $html .= display_configuration_parameter($installType, get_lang('AdminLastName'), 'adminLastName', $adminLastName); //Parameter 3: administrator's email $html .= display_configuration_parameter($installType, get_lang('AdminEmail'), 'emailForm', $emailForm); //Parameter 6: administrator's telephone $html .= display_configuration_parameter($installType, get_lang('AdminPhone'), 'adminPhoneForm', $adminPhoneForm); echo panel($html, get_lang('Administrator'), 'administrator'); //echo ''; //First parameter: language $html = '
    '; $html .= '"; if ($installType == 'update') { $html .= ''.$languageForm; } else { // new installation $html .= '
    '; $html .= display_language_selection_box('languageForm', $languageForm); $html .= '
    '; } $html .= "
    "; //Second parameter: Chamilo URL $html .= '
    '; $html .= ''; if ($installType == 'update') { $html .= api_htmlentities($urlForm, ENT_QUOTES)."\n"; } else { $html .= '
    '; $html .= ''; $html .= '
    '; } $html .= '
    '; //Parameter 9: campus name $html .= display_configuration_parameter($installType, get_lang('CampusName'), 'campusForm', $campusForm); //Parameter 10: institute (short) name $html .= display_configuration_parameter($installType, get_lang('InstituteShortName'), 'institutionForm', $institutionForm); //Parameter 11: institute (short) name $html .= display_configuration_parameter($installType, get_lang('InstituteURL'), 'institutionUrlForm', $institutionUrlForm); $html .= '
    '; if ($installType == 'update') { $html .= ''.$encryptPassForm; } else { $html .= '
    '; $html .= ''; $html .= ''; $html .= ''; $html .= '
    '; } $html .= '
    '; $html .= '
    '; if ($installType == 'update') { if ($allowSelfReg == 'true') { $label = get_lang('Yes'); } elseif ($allowSelfReg == 'false') { $label = get_lang('No'); } else { $label = get_lang('AfterApproval'); } $html .= ''.$label; } else { $html .= '
    '; $html .= ''; $html .= ''; $html .= ''; $html .= '
    '; } $html .= '
    '; $html .= '
    '; $html .= '
    '; $html .= '
    '; if ($installType == 'update') { if ($allowSelfRegProf == 'true') { $label = get_lang('Yes'); } else { $label = get_lang('No'); } $html .= ''.$label; } else { $html .= '
    '; $html .= ''; $html .= '
    '; } $html .= '
    '; echo panel($html, get_lang('Platform'), 'platform'); ?>
    '.get_lang('FirstUseTip').''; echo '
    '; echo ''.get_lang('SecurityAdvice').''; echo ': '; printf(get_lang('ToProtectYourSiteMakeXReadOnlyAndDeleteY'), 'app/config/', 'main/install/'); echo '
    '; ?>
    '; $country_select .= ''; foreach ($a_countries as $country) { $country_select .= ''; } $country_select .= ''; return $country_select; } return $a_countries; } /** * Lock settings that can't be changed in other portals */ function lockSettings() { $access_url_locked_settings = api_get_locked_settings(); $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT); foreach ($access_url_locked_settings as $setting) { $sql = "UPDATE $table SET access_url_locked = 1 WHERE variable = '$setting'"; Database::query($sql); } } /** * Update dir values */ function updateDirAndFilesPermissions() { $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT); $permissions_for_new_directories = isset($_SESSION['permissions_for_new_directories']) ? $_SESSION['permissions_for_new_directories'] : 0770; $permissions_for_new_files = isset($_SESSION['permissions_for_new_files']) ? $_SESSION['permissions_for_new_files'] : 0660; // use decoct() to store as string $sql = "UPDATE $table SET selected_value = '0".decoct($permissions_for_new_directories)."' WHERE variable = 'permissions_for_new_directories'"; Database::query($sql); $sql = "UPDATE $table SET selected_value = '0".decoct($permissions_for_new_files)."' WHERE variable = 'permissions_for_new_files'"; Database::query($sql); if (isset($_SESSION['permissions_for_new_directories'])) { unset($_SESSION['permissions_for_new_directories']); } if (isset($_SESSION['permissions_for_new_files'])) { unset($_SESSION['permissions_for_new_files']); } } /** * @param $current_value * @param $wanted_value * @return string */ function compare_setting_values($current_value, $wanted_value) { $current_value_string = $current_value; $current_value = (float) $current_value; $wanted_value = (float) $wanted_value; if ($current_value >= $wanted_value) { return Display::label($current_value_string, 'success'); } else { return Display::label($current_value_string, 'important'); } } /** * @param $course_dir * @param $course_attempt_name * @param string $file * @return bool */ function check_course_script_interpretation($course_dir, $course_attempt_name, $file = 'test.php') { $output = false; //Write in file $file_name = $course_dir.'/'.$file; $content = ' $organizationName, 'InstitutionUrl' => $organizationUrl, 'siteName' => $siteName, 'emailAdministrator' => $adminEmail, 'administratorSurname' => $adminLastName, 'administratorName' => $adminFirstName, 'platformLanguage' => $language, 'allow_registration' => $allowRegistration, 'allow_registration_as_teacher' => $allowTeacherSelfRegistration, ); foreach ($settings as $variable => $value) { $sql = "UPDATE settings_current SET selected_value = '$value' WHERE variable = '$variable'"; Database::query($sql); } installProfileSettings($installationProfile); } /** * Executes DB changes based in the classes defined in * src/Chamilo/CoreBundle/Migrations/Schema/* * * @param string $chamiloVersion * @param EntityManager $manager * @throws \Doctrine\DBAL\DBALException */ function migrate($chamiloVersion, EntityManager $manager) { $debug = true; $connection = $manager->getConnection(); $config = new \Doctrine\DBAL\Migrations\Configuration\Configuration($connection); // Table name that will store migrations log (will be created automatically, // default name is: doctrine_migration_versions) $config->setMigrationsTableName('version'); // Namespace of your migration classes, do not forget escape slashes, do not add last slash $config->setMigrationsNamespace('Application\Migrations\Schema\V'.$chamiloVersion); // Directory where your migrations are located $config->setMigrationsDirectory(api_get_path(SYS_PATH).'app/Migrations/Schema/V'.$chamiloVersion); // Load your migrations $config->registerMigrationsFromDirectory($config->getMigrationsDirectory()); $migration = new \Doctrine\DBAL\Migrations\Migration($config); $versions = $config->getMigrations(); /** @var Doctrine\DBAL\Migrations\Version $migrationItem */ foreach ($versions as $version) { $version->getMigration()->setEntityManager($manager); } $to = null; // if $to == null then schema will be migrated to latest version echo "
    ";
    
        try {
            // Execute migration!
            $migratedSQL = $migration->migrate($to);
    
            if ($debug) {
                foreach ($migratedSQL as $version => $sqlList) {
                    echo "VERSION: $version
    "; echo "----------------------------------------------
    "; $total = count($sqlList); error_log("VERSION: $version"); error_log("# queries: ".$total); $counter = 1; foreach ($sqlList as $sql) { echo "$sql
    "; error_log("$counter/$total : $sql"); $counter++; } } echo "
    DONE!
    "; } return true; } catch (Exception $ex) { if ($debug) { echo "ERROR: {$ex->getMessage()}
    "; return false; } } echo "
    "; return false; } /** * @param EntityManager $em * * @throws \Doctrine\DBAL\DBALException */ function fixIds(EntityManager $em) { $connection = $em->getConnection(); $database = new Database(); $database->setManager($em); $debug = true; if ($debug) { error_log('fixIds'); } // Create temporary indexes to increase speed of the following operations // Adding and removing indexes will usually take much less time than // the execution without indexes of the queries in this function, particularly // for large tables $sql = "ALTER TABLE c_document ADD INDEX tmpidx_doc(c_id, id)"; $connection->executeQuery($sql); $sql = "ALTER TABLE c_student_publication ADD INDEX tmpidx_stud (c_id, id)"; $connection->executeQuery($sql); $sql = "ALTER TABLE c_quiz ADD INDEX tmpidx_quiz (c_id, id)"; $connection->executeQuery($sql); $sql = "ALTER TABLE c_item_property ADD INDEX tmpidx_ip (to_group_id)"; $connection->executeQuery($sql); $sql = "SELECT * FROM c_lp_item"; $result = $connection->fetchAll($sql); foreach ($result as $item) { $courseId = $item['c_id']; $iid = isset($item['iid']) ? intval($item['iid']) : 0; $ref = isset($item['ref']) ? intval($item['ref']) : 0; $sql = null; $newId = ''; switch ($item['item_type']) { case TOOL_LINK: $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref"; $data = $connection->fetchAssoc($sql); if ($data) { $newId = $data['iid']; } break; case TOOL_STUDENTPUBLICATION: $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref"; $data = $connection->fetchAssoc($sql); if ($data) { $newId = $data['iid']; } break; case TOOL_QUIZ: $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref"; $data = $connection->fetchAssoc($sql); if ($data) { $newId = $data['iid']; } break; case TOOL_DOCUMENT: $sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref"; $data = $connection->fetchAssoc($sql); if ($data) { $newId = $data['iid']; } break; case TOOL_FORUM: $sql = "SELECT * FROM c_forum_forum WHERE c_id = $courseId AND forum_id = $ref"; $data = $connection->fetchAssoc($sql); if ($data) { $newId = $data['iid']; } break; case 'thread': $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND thread_id = $ref"; $data = $connection->fetchAssoc($sql); if ($data) { $newId = $data['iid']; } break; } if (!empty($sql) && !empty($newId) && !empty($iid)) { $sql = "UPDATE c_lp_item SET ref = $newId WHERE iid = $iid"; $connection->executeQuery($sql); } } // Set NULL if session = 0 $sql = "UPDATE c_item_property SET session_id = NULL WHERE session_id = 0"; $connection->executeQuery($sql); // Set NULL if group = 0 $sql = "UPDATE c_item_property SET to_group_id = NULL WHERE to_group_id = 0"; $connection->executeQuery($sql); // Set NULL if insert_user_id = 0 $sql = "UPDATE c_item_property SET insert_user_id = NULL WHERE insert_user_id = 0"; $connection->executeQuery($sql); // Delete session data of sessions that don't exist. $sql = "DELETE FROM c_item_property WHERE session_id IS NOT NULL AND session_id NOT IN (SELECT id FROM session)"; $connection->executeQuery($sql); // Delete group data of groups that don't exist. $sql = "DELETE FROM c_item_property WHERE to_group_id IS NOT NULL AND to_group_id NOT IN (SELECT DISTINCT id FROM c_group_info)"; $connection->executeQuery($sql); // This updates the group_id with c_group_info.iid instead of c_group_info.id if ($debug) { error_log('update iids'); } $groupTableToFix = [ 'c_group_rel_user', 'c_group_rel_tutor', 'c_permission_group', 'c_role_group', 'c_survey_invitation', 'c_attendance_calendar_rel_group' ]; foreach ($groupTableToFix as $table) { $sql = "SELECT * FROM $table"; $result = $connection->fetchAll($sql); foreach ($result as $item) { $iid = $item['iid']; $courseId = $item['c_id']; $groupId = intval($item['group_id']); // Fix group id if (!empty($groupId)) { $sql = "SELECT * FROM c_group_info WHERE c_id = $courseId AND id = $groupId LIMIT 1"; $data = $connection->fetchAssoc($sql); if (!empty($data)) { $newGroupId = $data['iid']; $sql = "UPDATE $table SET group_id = $newGroupId WHERE iid = $iid"; $connection->executeQuery($sql); } else { // The group does not exists clean this record $sql = "DELETE FROM $table WHERE iid = $iid"; $connection->executeQuery($sql); } } } } // Fix c_item_property if ($debug) { error_log('update c_item_property'); } $sql = "SELECT * FROM course"; $courseList = $connection->fetchAll($sql); if ($debug) { error_log('Getting course list'); } $totalCourse = count($courseList); $counter = 0; foreach ($courseList as $courseData) { $courseId = $courseData['id']; if ($debug) { error_log('Updating course: '.$courseData['code']); } $sql = "SELECT * FROM c_item_property WHERE c_id = $courseId"; $result = $connection->fetchAll($sql); foreach ($result as $item) { $sessionId = intval($item['session_id']); $groupId = intval($item['to_group_id']); $iid = $item['iid']; $ref = $item['ref']; // Fix group id if (!empty($groupId)) { $sql = "SELECT * FROM c_group_info WHERE c_id = $courseId AND id = $groupId"; $data = $connection->fetchAssoc($sql); if (!empty($data)) { $newGroupId = $data['iid']; $sql = "UPDATE c_item_property SET to_group_id = $newGroupId WHERE iid = $iid"; $connection->executeQuery($sql); } else { // The group does not exists clean this record $sql = "DELETE FROM c_item_property WHERE iid = $iid"; $connection->executeQuery($sql); } } $sql = ''; $newId = ''; switch ($item['tool']) { case TOOL_LINK: $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref "; break; case TOOL_STUDENTPUBLICATION: $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref"; break; case TOOL_QUIZ: $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref"; break; case TOOL_DOCUMENT: $sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref"; break; case TOOL_FORUM: $sql = "SELECT * FROM c_forum_forum WHERE c_id = $courseId AND id = $ref"; break; case 'thread': $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND id = $ref"; break; } if (!empty($sql) && !empty($newId)) { $data = $connection->fetchAssoc($sql); if (isset($data['iid'])) { $newId = $data['iid']; } $sql = "UPDATE c_item_property SET ref = $newId WHERE iid = $iid"; error_log($sql); $connection->executeQuery($sql); } } if ($debug) { // Print a status in the log once in a while error_log("Course process #$counter/$totalCourse"); } $counter++; } if ($debug) { error_log('update gradebook_link'); } // Fix gradebook_link $sql = "SELECT * FROM gradebook_link"; $result = $connection->fetchAll($sql); foreach ($result as $item) { $courseCode = $item['course_code']; $sql = "SELECT * FROM course WHERE code = '$courseCode'"; $courseInfo = $connection->fetchAssoc($sql); if (empty($courseInfo)) { continue; } $courseId = $courseInfo['id']; $ref = $item['ref_id']; $iid = $item['id']; $sql = ''; switch ($item['type']) { case LINK_LEARNPATH: $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref "; break; case LINK_STUDENTPUBLICATION: $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref"; break; case LINK_EXERCISE: $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref"; break; case LINK_ATTENDANCE: //$sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref"; break; case LINK_FORUM_THREAD: $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND thread_id = $ref"; break; } if (!empty($sql)) { $data = $connection->fetchAssoc($sql); if (isset($data) && isset($data['iid'])) { $newId = $data['iid']; $sql = "UPDATE gradebook_link SET ref_id = $newId WHERE id = $iid"; $connection->executeQuery($sql); } } } if ($debug) { error_log('update groups'); } $sql = "SELECT * FROM groups"; $result = $connection->executeQuery($sql); $groups = $result->fetchAll(); $oldGroups = array(); if (!empty($groups)) { foreach ($groups as $group) { if (empty($group['name'])) { continue; } $params = [ 'name' => $group['name'], 'description' => $group['description'], 'group_type' => 1, 'picture' => $group['picture_uri'], 'url' => $group['url'], 'visibility' => $group['visibility'], 'updated_at' => $group['updated_on'], 'created_at' => $group['created_on'] ]; $connection->insert('usergroup', $params); $id = $connection->lastInsertId('id'); $oldGroups[$group['id']] = $id; } } if (!empty($oldGroups)) { error_log('Moving group files'); foreach ($oldGroups as $oldId => $newId) { $path = get_group_picture_path_by_id( $oldId, 'system' ); if (!empty($path)) { $newPath = str_replace( "groups/$oldId/", "groups/$newId/", $path['dir'] ); $command = "mv {$path['dir']} $newPath "; error_log("Executing $command"); system($command); } } $sql = "SELECT * FROM group_rel_user"; $result = $connection->executeQuery($sql); $dataList = $result->fetchAll(); if (!empty($dataList)) { foreach ($dataList as $data) { if (isset($oldGroups[$data['group_id']])) { $data['group_id'] = $oldGroups[$data['group_id']]; $userId = $data['user_id']; $sql = "SELECT id FROM user WHERE user_id = $userId"; $userResult = $connection->executeQuery($sql); $userInfo = $userResult->fetch(); if (empty($userInfo)) { continue; } $sql = "INSERT INTO usergroup_rel_user (usergroup_id, user_id, relation_type) VALUES ('{$data['group_id']}', '{$userId}', '{$data['relation_type']}')"; $connection->executeQuery($sql); } } } $sql = "SELECT * FROM group_rel_group"; $result = $connection->executeQuery($sql); $dataList = $result->fetchAll(); if (!empty($dataList)) { foreach ($dataList as $data) { if (isset($oldGroups[$data['group_id']]) && isset($oldGroups[$data['subgroup_id']])) { $data['group_id'] = $oldGroups[$data['group_id']]; $data['subgroup_id'] = $oldGroups[$data['subgroup_id']]; $sql = "INSERT INTO usergroup_rel_usergroup (group_id, subgroup_id, relation_type) VALUES ('{$data['group_id']}', '{$data['subgroup_id']}', '{$data['relation_type']}')"; $connection->executeQuery($sql); } } } $sql = "SELECT * FROM announcement_rel_group"; $result = $connection->executeQuery($sql); $dataList = $result->fetchAll(); if (!empty($dataList)) { foreach ($dataList as $data) { if (isset($oldGroups[$data['group_id']])) { // Deleting relation $sql = "DELETE FROM announcement_rel_group WHERE group_id = {$data['group_id']}"; $connection->executeQuery($sql); // Add new relation $data['group_id'] = $oldGroups[$data['group_id']]; $sql = "INSERT INTO announcement_rel_group(group_id, announcement_id) VALUES ('{$data['group_id']}', '{$data['announcement_id']}')"; $connection->executeQuery($sql); } } } $sql = "SELECT * FROM group_rel_tag"; $result = $connection->executeQuery($sql); $dataList = $result->fetchAll(); if (!empty($dataList)) { foreach ($dataList as $data) { if (isset($oldGroups[$data['group_id']])) { $data['group_id'] = $oldGroups[$data['group_id']]; $sql = "INSERT INTO usergroup_rel_tag (tag_id, usergroup_id) VALUES ('{$data['tag_id']}', '{$data['group_id']}')"; $connection->executeQuery($sql); } } } } if ($debug) { error_log('update extra fields'); } // Extra fields $extraFieldTables = [ ExtraField::USER_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_USER_FIELD), ExtraField::COURSE_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_COURSE_FIELD), //ExtraField::LP_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_LP_FIELD), ExtraField::SESSION_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_SESSION_FIELD), //ExtraField::CALENDAR_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_FIELD), //ExtraField::QUESTION_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_FIELD), //ExtraField::USER_FIELD_TYPE => //Database::get_main_table(TABLE_MAIN_SPECIFIC_FIELD), ]; foreach ($extraFieldTables as $type => $table) { $sql = "SELECT * FROM $table "; if ($debug) { error_log($sql); } $result = $connection->query($sql); $fields = $result->fetchAll(); foreach ($fields as $field) { if ($debug) { error_log("Loading field: ".$field['field_variable']); } $originalId = $field['id']; $params = [ 'extra_field_type' => $type, 'variable' => $field['field_variable'], 'field_type' => $field['field_type'], 'display_text' => $field['field_display_text'], 'default_value' => $field['field_default_value'], 'field_order' => $field['field_order'], 'visible' => $field['field_visible'], 'changeable' => $field['field_changeable'], 'filter' => $field['field_filter'] ]; $connection->insert('extra_field', $params); $newExtraFieldId = $connection->lastInsertId(); $values = array(); $handlerId = null; switch ($type) { case ExtraField::USER_FIELD_TYPE: $optionTable = Database::get_main_table( TABLE_MAIN_USER_FIELD_OPTIONS ); $valueTable = Database::get_main_table( TABLE_MAIN_USER_FIELD_VALUES ); $handlerId = 'user_id'; break; case ExtraField::COURSE_FIELD_TYPE: $optionTable = Database::get_main_table( TABLE_MAIN_COURSE_FIELD_OPTIONS ); $valueTable = Database::get_main_table( TABLE_MAIN_COURSE_FIELD_VALUES ); $handlerId = 'c_id'; break; case ExtraField::SESSION_FIELD_TYPE: $optionTable = Database::get_main_table( TABLE_MAIN_SESSION_FIELD_OPTIONS ); $valueTable = Database::get_main_table( TABLE_MAIN_SESSION_FIELD_VALUES ); $handlerId = 'session_id'; break; } if (!empty($optionTable)) { $sql = "SELECT * FROM $optionTable WHERE field_id = $originalId "; $result = $connection->query($sql); $options = $result->fetchAll(); foreach ($options as $option) { $params = [ 'display_text' => $option['option_display_text'], 'field_id' => $newExtraFieldId, 'option_order' => $option['option_order'], 'option_value' => $option['option_value'] ]; $connection->insert('extra_field_options', $params); } $sql = "SELECT * FROM $valueTable WHERE field_id = $originalId "; $result = $connection->query($sql); $values = $result->fetchAll(); if ($debug) { error_log("Fetch all values for field"); } } if (!empty($values)) { if ($debug) { error_log("Saving field value in new table"); } $k = 0; foreach ($values as $value) { if (isset($value[$handlerId])) { // Insert without the use of the entity as it reduces // speed to 2 records per second (much too slow) $params = [ 'field_id' => $newExtraFieldId, 'value' => $value['field_value'], 'item_id' => $value[$handlerId] ]; $connection->insert('extra_field_values', $params); if ($debug && ($k % 10000 == 0)) { error_log("Saving field $k"); } $k++; } } } } } if ($debug) { error_log('Remove index'); } // Drop temporary indexes added to increase speed of this function's queries $sql = "ALTER TABLE c_document DROP INDEX tmpidx_doc"; $connection->executeQuery($sql); $sql = "ALTER TABLE c_student_publication DROP INDEX tmpidx_stud"; $connection->executeQuery($sql); $sql = "ALTER TABLE c_quiz DROP INDEX tmpidx_quiz"; $connection->executeQuery($sql); $sql = "ALTER TABLE c_item_property DROP INDEX tmpidx_ip"; $connection->executeQuery($sql); if ($debug) { error_log('Finish fixId function'); } } /** * * After the schema was created (table creation), the function adds * admin/platform information. * * @param EntityManager $manager * @param string $sysPath * @param string $encryptPassForm * @param string $passForm * @param string $adminLastName * @param string $adminFirstName * @param string $loginForm * @param string $emailForm * @param string $adminPhoneForm * @param string $languageForm * @param string $institutionForm * @param string $institutionUrlForm * @param string $siteName * @param string $allowSelfReg * @param string $allowSelfRegProf * @param string $installationProfile Installation profile, if any was provided */ function finishInstallation( $manager, $sysPath, $encryptPassForm, $passForm, $adminLastName, $adminFirstName, $loginForm, $emailForm, $adminPhoneForm, $languageForm, $institutionForm, $institutionUrlForm, $siteName, $allowSelfReg, $allowSelfRegProf, $installationProfile = '' ) { $sysPath = !empty($sysPath) ? $sysPath : api_get_path(SYS_PATH); $connection = $manager->getConnection(); // Add version table $connection->executeQuery('CREATE TABLE IF NOT EXISTS version (id int unsigned NOT NULL AUTO_INCREMENT, version varchar(20), PRIMARY KEY(id), UNIQUE(version))'); // Add tickets defaults $ticketProject = new TicketProject(); $ticketProject ->setId(1) ->setName('Ticket System') ->setInsertUserId(1); $manager->persist($ticketProject); $manager->flush(); $categories = array( get_lang('TicketEnrollment') => get_lang('TicketsAboutEnrollment'), get_lang('TicketGeneralInformation') => get_lang('TicketsAboutGeneralInformation'), get_lang('TicketRequestAndPapework') => get_lang('TicketsAboutRequestAndPapework'), get_lang('TicketAcademicIncidence') => get_lang('TicketsAboutAcademicIncidence'), get_lang('TicketVirtualCampus') => get_lang('TicketsAboutVirtualCampus'), get_lang('TicketOnlineEvaluation') => get_lang('TicketsAboutOnlineEvaluation') ); $i = 1; /** * @var string $category * @var string $description */ foreach ($categories as $category => $description) { // Online evaluation requires a course $ticketCategory = new TicketCategory(); $ticketCategory ->setId($i) ->setName($category) ->setDescription($description) ->setProject($ticketProject) ->setInsertUserId(1); $isRequired = $i == 6; $ticketCategory->setCourseRequired($isRequired); $manager->persist($ticketCategory); $manager->flush(); $i++; } // Default Priorities $defaultPriorities = array( TicketManager::PRIORITY_NORMAL => get_lang('PriorityNormal'), TicketManager::PRIORITY_HIGH => get_lang('PriorityHigh'), TicketManager::PRIORITY_LOW => get_lang('PriorityLow') ); $table = Database::get_main_table(TABLE_TICKET_PRIORITY); $i = 1; foreach ($defaultPriorities as $code => $priority) { $ticketPriority = new TicketPriority(); $ticketPriority ->setId($i) ->setName($priority) ->setCode($code) ->setInsertUserId(1); $manager->persist($ticketPriority); $manager->flush(); $i++; } $table = Database::get_main_table(TABLE_TICKET_STATUS); // Default status $defaultStatus = array( TicketManager::STATUS_NEW => get_lang('StatusNew'), TicketManager::STATUS_PENDING => get_lang('StatusPending'), TicketManager::STATUS_UNCONFIRMED => get_lang('StatusUnconfirmed'), TicketManager::STATUS_CLOSE => get_lang('StatusClose'), TicketManager::STATUS_FORWARDED => get_lang('StatusForwarded') ); $i = 1; foreach ($defaultStatus as $code => $status) { $attributes = array( 'id' => $i, 'code' => $code, 'name' => $status ); Database::insert($table, $attributes); $i++; } // Inserting data.sql $data = file_get_contents($sysPath.'main/install/data.sql'); $result = $manager->getConnection()->prepare($data); $result->execute(); $result->closeCursor(); UserManager::setPasswordEncryption($encryptPassForm); // Create admin user. @UserManager::create_user( $adminFirstName, $adminLastName, 1, $emailForm, $loginForm, $passForm, 'ADMIN', //$official_code = '', $languageForm, $adminPhoneForm, '', //$picture_uri = '', PLATFORM_AUTH_SOURCE, '', //$expirationDate, 1, 0, null, '', false, //$send_mail = false, true //$isAdmin = false ); // Create anonymous user. @UserManager::create_user( 'Joe', 'Anonymous', 6, 'anonymous@localhost', 'anon', 'anon', 'anonymous', //$official_code = '', $languageForm, '', '', //$picture_uri = '', PLATFORM_AUTH_SOURCE, '', 1, 0, null, '', false, //$send_mail = false, false //$isAdmin = false ); // Set default language $sql = "UPDATE language SET available = 1 WHERE dokeos_folder = '$languageForm'"; Database::query($sql); // Install settings installSettings( $institutionForm, $institutionUrlForm, $siteName, $emailForm, $adminLastName, $adminFirstName, $languageForm, $allowSelfReg, $allowSelfRegProf, $installationProfile ); lockSettings(); updateDirAndFilesPermissions(); // Set the latest version $path = $sysPath.'app/Migrations/Schema/V111/'; $finder = new \Symfony\Component\Finder\Finder(); $files = $finder->files()->in($path); // Needed for chash $sql = 'CREATE TABLE IF NOT EXISTS version (id int unsigned NOT NULL AUTO_INCREMENT, version varchar(255), PRIMARY KEY(id), UNIQUE(version));'; Database::query($sql); foreach ($files as $version) { $version = str_replace(['Version', '.php'], '', $version->getFilename()); $sql = "INSERT INTO version (version) VALUES ('$version')"; Database::query($sql); } } /** * Update settings based on installation profile defined in a JSON file * @param string $installationProfile The name of the JSON file in main/install/profiles/ folder * * @return bool false on failure (no bad consequences anyway, just ignoring profile) */ function installProfileSettings($installationProfile = '') { if (empty($installationProfile)) { return false; } $jsonPath = api_get_path(SYS_PATH).'main/install/profiles/'.$installationProfile.'.json'; // Make sure the path to the profile is not hacked if (!Security::check_abs_path($jsonPath, api_get_path(SYS_PATH).'main/install/profiles/')) { return false; } if (!is_file($jsonPath)) { return false; } if (!is_readable($jsonPath)) { return false; } if (!function_exists('json_decode')) { // The php-json extension is not available. Ignore profile. return false; } $json = file_get_contents($jsonPath); $params = json_decode($json); if ($params === false or $params === null) { return false; } $settings = $params->params; if (!empty($params->parent)) { installProfileSettings($params->parent); } foreach ($settings as $id => $param) { $sql = "UPDATE settings_current SET selected_value = '".$param->selected_value."' WHERE variable = '".$param->variable."'"; if (!empty($param->subkey)) { $sql .= " AND subkey='".$param->subkey."'"; } Database::query($sql); } return true; } /** * Quick function to remove a directory with its subdirectories * @param $dir */ function rrmdir($dir) { if (is_dir($dir)) { $objects = scandir($dir); foreach ($objects as $object) { if ($object != "." && $object != "..") { if (filetype($dir."/".$object) == "dir") { @rrmdir($dir."/".$object); } else { @unlink($dir."/".$object); } } } reset($objects); rmdir($dir); } } function get_group_picture_path_by_id($id, $type = 'web', $preview = false, $anonymous = false) { switch ($type) { case 'system': // Base: absolute system path. $base = api_get_path(SYS_UPLOAD_PATH); break; case 'web': // Base: absolute web path. default: $base = api_get_path(WEB_UPLOAD_PATH); break; } $noPicturePath = array('dir' => $base.'img/', 'file' => 'unknown.jpg'); if (empty($id) || empty($type)) { return $anonymous ? $noPicturePath : array('dir' => '', 'file' => ''); } $id = intval($id); //$group_table = Database::get_main_table(TABLE_MAIN_GROUP); $group_table = 'groups'; $sql = "SELECT picture_uri FROM $group_table WHERE id=".$id; $res = Database::query($sql); if (!Database::num_rows($res)) { return $anonymous ? $noPicturePath : array('dir' => '', 'file' => ''); } $user = Database::fetch_array($res); $picture_filename = trim($user['picture_uri']); if (api_get_setting('split_users_upload_directory') === 'true') { if (!empty($picture_filename)) { $dir = $base.'groups/'.substr($picture_filename, 0, 1).'/'.$id.'/'; } elseif ($preview) { $dir = $base.'groups/'.substr((string) $id, 0, 1).'/'.$id.'/'; } else { $dir = $base.'groups/'.$id.'/'; } } else { $dir = $base.'groups/'.$id.'/'; } if (empty($picture_filename) && $anonymous) { return $noPicturePath; } return array('dir' => $dir, 'file' => $picture_filename); } /** * Control the different steps of the migration through a big switch * @param string $fromVersion * @param EntityManager $manager * @param bool $processFiles * @return bool Always returns true except if the process is broken */ function migrateSwitch($fromVersion, $manager, $processFiles = true) { error_log('Starting migration process from '.$fromVersion.' ('.date('Y-m-d H:i:s').')'); echo ''.get_lang('Details').'
    '; echo ''; return true; }