diff --git a/.env.dist b/.env.dist
index 23c1e2f8a34..88c3bbbe289 100644
--- a/.env.dist
+++ b/.env.dist
@@ -62,3 +62,10 @@ JWT_PASSPHRASE=your_secret_passphrase
# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
###< symfony/messenger ###
+
+###< additional settings ###
+DB_MANAGER_ENABLED='{{DB_MANAGER_ENABLED}}'
+SOFTWARE_NAME='{{SOFTWARE_NAME}}'
+SOFTWARE_URL='{{SOFTWARE_URL}}'
+DENY_DELETE_USERS='{{DENY_DELETE_USERS}}'
+HOSTING_TOTAL_SIZE_LIMIT='{{HOSTING_TOTAL_SIZE_LIMIT}}'
diff --git a/config/hosting_limits.yml b/config/hosting_limits.yml
new file mode 100644
index 00000000000..d1f3ca72749
--- /dev/null
+++ b/config/hosting_limits.yml
@@ -0,0 +1,11 @@
+parameters:
+ hosting_limits:
+ urls:
+ 1:
+ - hosting_limit_users: 0
+ - hosting_limit_teachers: 0
+ - hosting_limit_courses: 0
+ - hosting_limit_sessions: 0
+ - hosting_limit_disk_space: 0
+ - hosting_limit_active_courses: 0
+ - hosting_total_size_limit: 0
diff --git a/config/services.yaml b/config/services.yaml
index c3930249dd8..5f98b8f3e35 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -117,3 +117,4 @@ cocur_slugify:
imports:
- {resource: ../src/CoreBundle/Resources/config/services.yml}
- {resource: ../src/LtiBundle/Resources/config/services.yml}
+ - {resource: ./hosting_limits.yml}
diff --git a/public/main/admin/user_list.php b/public/main/admin/user_list.php
index a3cbd30ebce..d7c35d05b4b 100644
--- a/public/main/admin/user_list.php
+++ b/public/main/admin/user_list.php
@@ -718,7 +718,7 @@ function modify_filter($user_id, $url_params, $row): string
);
}
- $deleteAllowed = !api_get_configuration_value('deny_delete_users');
+ $deleteAllowed = api_get_env_variable('DENY_DELETE_USERS', false);
if ($deleteAllowed) {
if ($user_id != $currentUserId &&
!$user_is_anonymous &&
@@ -1297,14 +1297,14 @@ function($from, $number_of_items, $column, $direction) use ($showDeletedUsers) {
$table->set_column_filter(11, 'modify_deleted_filter');
$actionsList['restore'] = get_lang('Restore');
if (api_is_platform_admin() &&
- !api_get_configuration_value('deny_delete_users')
+ !api_get_env_variable('DENY_DELETE_USERS', false)
) {
$actionsList['destroy'] = get_lang('Destroy');
}
} else {
$table->set_column_filter(11, 'modify_filter');
if (api_is_platform_admin() &&
- !api_get_configuration_value('deny_delete_users')
+ !api_get_env_variable('DENY_DELETE_USERS', false)
) {
$actionsList['delete'] = get_lang('Remove from portal');
}
diff --git a/public/main/admin/user_list_consent.php b/public/main/admin/user_list_consent.php
index 1bbddaed728..01f7b87f28e 100644
--- a/public/main/admin/user_list_consent.php
+++ b/public/main/admin/user_list_consent.php
@@ -613,7 +613,7 @@ function status_filter($status)
// Only show empty actions bar if delete users has been blocked
$actionsList = [];
if (api_is_platform_admin() &&
- !api_get_configuration_value('deny_delete_users')
+ !api_get_env_variable('DENY_DELETE_USERS', false)
) {
$actionsList['delete'] = get_lang('Remove from portal');
}
diff --git a/public/main/course_info/infocours.php b/public/main/course_info/infocours.php
index 907dc76e8c3..73c1caf25c5 100644
--- a/public/main/course_info/infocours.php
+++ b/public/main/course_info/infocours.php
@@ -949,15 +949,14 @@
$illustrationRepo->deleteIllustration($courseEntity);
}
- $limitCourses = api_get_configuration_value('hosting_limit_active_courses');
- if ($limitCourses > 0) {
+ $access_url_id = api_get_current_access_url_id();
+
+ $limitCourses = get_hosting_limit($access_url_id, 'hosting_limit_active_courses');
+ if ($limitCourses !== null && $limitCourses > 0) {
$courseInfo = api_get_course_info_by_id($courseId);
- // Check if
- if (COURSE_VISIBILITY_HIDDEN == $courseInfo['visibility'] &&
- $visibility != $courseInfo['visibility']
- ) {
- $num = CourseManager::countActiveCourses($urlId);
+ if (COURSE_VISIBILITY_HIDDEN == $courseInfo['visibility'] && $visibility != $courseInfo['visibility']) {
+ $num = CourseManager::countActiveCourses($access_url_id);
if ($num >= $limitCourses) {
api_warn_hosting_contact('hosting_limit_active_courses');
diff --git a/public/main/cron/user_import/client.php b/public/main/cron/user_import/client.php
index 3c9ffdfe63d..57033490086 100644
--- a/public/main/cron/user_import/client.php
+++ b/public/main/cron/user_import/client.php
@@ -28,7 +28,7 @@
'import_users',
[
'filepath' => api_get_path(SYS_UPLOAD_PATH)."users_import.csv",
- 'security_key' => api_get_configuration_value('security_key'),
+ 'security_key' => api_get_env_variable('kernel.secret'),
]
);
echo $response;
diff --git a/public/main/inc/global.inc.php b/public/main/inc/global.inc.php
index 3e4268f19b1..f446c1adde3 100644
--- a/public/main/inc/global.inc.php
+++ b/public/main/inc/global.inc.php
@@ -95,10 +95,8 @@
}
try {
- // Load legacy configuration.php
- if ($kernel->isInstalled()) {
- require_once $kernel->getConfigurationFile();
- } else {
+
+ if (!$kernel->isInstalled()) {
throw new Exception('Chamilo is not installed');
}
diff --git a/public/main/inc/lib/api.lib.php b/public/main/inc/lib/api.lib.php
index 1d4946877f6..2845901625d 100644
--- a/public/main/inc/lib/api.lib.php
+++ b/public/main/inc/lib/api.lib.php
@@ -24,6 +24,7 @@
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
+use Symfony\Component\Yaml\Yaml;
use ZipStream\Option\Archive;
use ZipStream\ZipStream;
use Chamilo\CoreBundle\Component\Utils\ActionIcon;
@@ -4307,12 +4308,8 @@ function api_get_version()
*/
function api_get_software_name()
{
- $name = api_get_configuration_value('software_name');
- if (!empty($name)) {
- return $name;
- } else {
- return 'Chamilo';
- }
+ $name = api_get_env_variable('SOFTWARE_NAME', 'Chamilo');
+ return $name;
}
function api_get_status_list()
@@ -5213,7 +5210,7 @@ function api_is_valid_secret_key($original_key_secret, $security_key)
return false;
}
- return (string) $original_key_secret === sha1($security_key);
+ return (string) $original_key_secret === hash('sha512', $security_key);
}
/**
@@ -6816,6 +6813,65 @@ function api_get_configuration_value($variable)
return false;
}
+/**
+ * Loads hosting limits from the YAML file.
+ *
+ * @return array The hosting limits.
+ */
+function load_hosting_limits(): array
+{
+ $container = Container::$container;
+
+ $hostingLimits = $container->getParameter('hosting_limits');
+
+ return $hostingLimits['urls'] ?? [];
+}
+
+/**
+ * Gets a specific hosting limit.
+ *
+ * @param int $urlId The URL ID.
+ * @param string $limitName The name of the limit.
+ * @return mixed The value of the limit, or null if not found.
+ */
+function get_hosting_limit(int $urlId, string $limitName): mixed
+{
+ $limits = load_hosting_limits();
+
+ foreach ($limits[$urlId] as $limitArray) {
+ if (isset($limitArray[$limitName])) {
+ return $limitArray[$limitName];
+ }
+ }
+
+ return null;
+}
+
+
+/**
+ * Retrieves an environment variable value with validation and handles boolean conversion.
+ *
+ * @param string $variable The name of the environment variable.
+ * @param mixed $default The default value to return if the variable is not set.
+ * @return mixed The value of the environment variable, converted to boolean if necessary, or the default value.
+ */
+function api_get_env_variable(string $variable, mixed $default = null): mixed
+{
+ if (Container::$container->hasParameter($variable)) {
+ $value = Container::$container->getParameter($variable);
+
+ if ($value === '0') {
+ return false;
+ }
+ if ($value === '1') {
+ return true;
+ }
+
+ return $value;
+ }
+
+ return $default;
+}
/**
* Retreives and returns a value in a hierarchical configuration array
* api_get_configuration_sub_value('a/b/c') returns api_get_configuration_value('a')['b']['c'].
diff --git a/public/main/inc/lib/course.lib.php b/public/main/inc/lib/course.lib.php
index 3bee001c685..9ad143e9ab3 100644
--- a/public/main/inc/lib/course.lib.php
+++ b/public/main/inc/lib/course.lib.php
@@ -6709,20 +6709,22 @@ public static function addVisibilityOptions(FormValidator $form): void
*
* @return bool|string
*/
- private static function checkCreateCourseAccessUrlParam($_configuration, $accessUrlId, $param, $msgLabel)
+ private static function checkCreateCourseAccessUrlParam($accessUrlId, $param, $msgLabel)
{
- if (isset($_configuration[$accessUrlId][$param]) && $_configuration[$accessUrlId][$param] > 0) {
+ $hostingLimit = get_hosting_limit($accessUrlId, $param);
+
+ if ($hostingLimit !== null && $hostingLimit > 0) {
$num = null;
switch ($param) {
case 'hosting_limit_courses':
- $num = self::count_courses($accessUrlId);
+ $num = self::count_courses($accessUrlId);
break;
case 'hosting_limit_active_courses':
$num = self::countActiveCourses($accessUrlId);
break;
}
- if ($num && $num >= $_configuration[$accessUrlId][$param]) {
+ if ($num && $num >= $hostingLimit) {
api_warn_hosting_contact($param);
Display::addFlash(
diff --git a/public/main/inc/lib/diagnoser.lib.php b/public/main/inc/lib/diagnoser.lib.php
index ee013a65562..e0518470307 100644
--- a/public/main/inc/lib/diagnoser.lib.php
+++ b/public/main/inc/lib/diagnoser.lib.php
@@ -213,24 +213,22 @@ public function get_chamilo_data()
if (1 === $access_url_id) {
$size = '-';
- global $_configuration;
$message2 = '';
- if (1 === $access_url_id) {
- if (api_is_windows_os()) {
- $message2 .= get_lang('The space used on disk cannot be measured properly on Windows-based systems.');
- } else {
- $dir = api_get_path(SYS_PATH);
- $du = exec('du -sh '.$dir, $err);
- list($size, $none) = explode("\t", $du);
- unset($none);
+
+ if (api_is_windows_os()) {
+ $message2 .= get_lang('The space used on disk cannot be measured properly on Windows-based systems.');
+ } else {
+ $dir = api_get_path(SYS_PATH);
+ $du = exec('du -sh ' . $dir, $err);
+ list($size, $none) = explode("\t", $du);
+ unset($none);
+
+ $limit = get_hosting_limit($access_url_id, 'hosting_limit_disk_space');
+ if ($limit === null) {
$limit = 0;
- if (isset($_configuration[$access_url_id])) {
- if (isset($_configuration[$access_url_id]['hosting_limit_disk_space'])) {
- $limit = $_configuration[$access_url_id]['hosting_limit_disk_space'];
- }
- }
- $message2 .= sprintf(get_lang('Total space used by portal %s limit is %s MB'), $size, $limit);
}
+
+ $message2 .= sprintf(get_lang('Total space used by portal %s limit is %s MB'), $size, $limit);
}
$array[] = $this->build_setting(
diff --git a/public/main/inc/lib/sessionmanager.lib.php b/public/main/inc/lib/sessionmanager.lib.php
index f1df9146807..d5a8952ba07 100644
--- a/public/main/inc/lib/sessionmanager.lib.php
+++ b/public/main/inc/lib/sessionmanager.lib.php
@@ -167,13 +167,11 @@ public static function create_session(
? (empty($accessUrlId) ? api_get_current_access_url_id() : (int) $accessUrlId)
: 1;
- if (isset($_configuration[$accessUrlId]) &&
- is_array($_configuration[$accessUrlId]) &&
- isset($_configuration[$accessUrlId]['hosting_limit_sessions']) &&
- $_configuration[$accessUrlId]['hosting_limit_sessions'] > 0
- ) {
+ $hostingLimitSessions = get_hosting_limit($accessUrlId, 'hosting_limit_sessions');
+
+ if ($hostingLimitSessions !== null && $hostingLimitSessions > 0) {
$num = self::count_sessions();
- if ($num >= $_configuration[$accessUrlId]['hosting_limit_sessions']) {
+ if ($num >= $hostingLimitSessions) {
api_warn_hosting_contact('hosting_limit_sessions');
return get_lang('The number of sessions limit for this portal has been reached');
diff --git a/public/main/inc/lib/usermanager.lib.php b/public/main/inc/lib/usermanager.lib.php
index 5ee3d639b6f..477221d43e8 100644
--- a/public/main/inc/lib/usermanager.lib.php
+++ b/public/main/inc/lib/usermanager.lib.php
@@ -183,12 +183,11 @@ public static function create_user(
}
}
- if (isset($_configuration[$access_url_id]) &&
- is_array($_configuration[$access_url_id]) &&
- isset($_configuration[$access_url_id]['hosting_limit_users']) &&
- $_configuration[$access_url_id]['hosting_limit_users'] > 0) {
+ $hostingLimitUsers = get_hosting_limit($access_url_id, 'hosting_limit_users');
+
+ if ($hostingLimitUsers !== null && $hostingLimitUsers > 0) {
$num = self::get_number_of_users();
- if ($num >= $_configuration[$access_url_id]['hosting_limit_users']) {
+ if ($num >= $hostingLimitUsers) {
api_warn_hosting_contact('hosting_limit_users');
Display::addFlash(
Display::return_message(
@@ -201,23 +200,22 @@ public static function create_user(
}
}
- if (1 === $status &&
- isset($_configuration[$access_url_id]) &&
- is_array($_configuration[$access_url_id]) &&
- isset($_configuration[$access_url_id]['hosting_limit_teachers']) &&
- $_configuration[$access_url_id]['hosting_limit_teachers'] > 0
- ) {
- $num = self::get_number_of_users(1);
- if ($num >= $_configuration[$access_url_id]['hosting_limit_teachers']) {
- Display::addFlash(
- Display::return_message(
- get_lang('Sorry, this installation has a teachers limit, which has now been reached. To increase the number of teachers allowed on this Chamilo installation, please contact your hosting provider or, if available, upgrade to a superior hosting plan.'),
- 'warning'
- )
- );
- api_warn_hosting_contact('hosting_limit_teachers');
+ if (1 === $status) {
+ $hostingLimitTeachers = get_hosting_limit($access_url_id, 'hosting_limit_teachers');
- return false;
+ if ($hostingLimitTeachers !== null && $hostingLimitTeachers > 0) {
+ $num = self::get_number_of_users(1);
+ if ($num >= $hostingLimitTeachers) {
+ Display::addFlash(
+ Display::return_message(
+ get_lang('Sorry, this installation has a teachers limit, which has now been reached. To increase the number of teachers allowed on this Chamilo installation, please contact your hosting provider or, if available, upgrade to a superior hosting plan.'),
+ 'warning'
+ )
+ );
+ api_warn_hosting_contact('hosting_limit_teachers');
+
+ return false;
+ }
}
}
@@ -612,7 +610,7 @@ public static function create_user(
*/
public static function canDeleteUser($user_id)
{
- $deny = api_get_configuration_value('deny_delete_users');
+ $deny = api_get_env_variable('DENY_DELETE_USERS', false);
if ($deny) {
return false;
diff --git a/public/main/install/configuration.dist.php b/public/main/install/configuration.dist.php
deleted file mode 100644
index 1f7e7ce978b..00000000000
--- a/public/main/install/configuration.dist.php
+++ /dev/null
@@ -1,63 +0,0 @@
- 1,
'{{APP_ENCRYPT_METHOD}}' => $encryptPassForm,
'{{APP_SECRET}}' => generateRandomToken(),
+ '{{DB_MANAGER_ENABLED}}' => '0',
+ '{{SOFTWARE_NAME}}' => 'Chamilo',
+ '{{SOFTWARE_URL}}' => $institutionUrlForm,
+ '{{DENY_DELETE_USERS}}' => '0',
+ '{{HOSTING_TOTAL_SIZE_LIMIT}}' => '0',
];
error_log('Update env file');
updateEnvFile($distFile, $envFile, $params);
@@ -568,6 +573,11 @@
'{{APP_INSTALLED}}' => 1,
'{{APP_ENCRYPT_METHOD}}' => $encryptPassForm,
'{{APP_SECRET}}' => generateRandomToken(),
+ '{{DB_MANAGER_ENABLED}}' => '0',
+ '{{SOFTWARE_NAME}}' => 'Chamilo',
+ '{{SOFTWARE_URL}}' => $institutionUrlForm,
+ '{{DENY_DELETE_USERS}}' => '0',
+ '{{HOSTING_TOTAL_SIZE_LIMIT}}' => '0',
];
updateEnvFile($distFile, $envFile, $params);
@@ -620,7 +630,6 @@
$allowSelfRegProf,
$installationProfile
);
- writeSystemConfigFile(api_get_path(SYMFONY_SYS_PATH).'config/configuration.php');
error_log('Finish installation');
} else {
error_log('ERROR during installation.');
diff --git a/public/main/install/install.lib.php b/public/main/install/install.lib.php
index 0cd06264921..ee539b2a249 100644
--- a/public/main/install/install.lib.php
+++ b/public/main/install/install.lib.php
@@ -245,45 +245,6 @@ function set_file_folder_permissions()
@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 writeSystemConfigFile($path)
-{
- $content = file_get_contents(__DIR__.'/'.SYSTEM_CONFIG_FILENAME);
- $config['{DATE_GENERATED}'] = date('r');
- $config['{SECURITY_KEY}'] = md5(uniqid(rand().time()));
-
- 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:
-