diff --git a/.gitignore b/.gitignore index b1a74061cf..ece8fb8ced 100755 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,9 @@ +# Chamilo 1.x + +app +courses +web/assets/* + # Cache directories var/cache/* @@ -9,15 +15,8 @@ var/log/* /node_modules/ # Chamilo configuration -/app/config/parameters.yml -/app/config/add_course.conf.php -/app/config/auth.conf.php -/app/config/course_info.conf.php -/app/config/events.conf.php -/app/config/mail.conf.php -/app/config/profile.conf.php /config/configuration.php -/app/config/configuration.php + /main/inc/conf/configuration.php # Courses @@ -25,7 +24,6 @@ var/courses/* !var/courses/.gitkeep # Home -app/home/* components/* # Upload content @@ -53,7 +51,6 @@ plugin/vchamilo/templates/* # Stuff updated through composer - Remove just before release vendor -web/assets/* ###> symfony/framework-bundle ### .env diff --git a/composer.json b/composer.json index 4eae94cc80..4d4f4532f7 100755 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "E-learning and collaboration software", "type": "project", "homepage": "http://www.chamilo.org", - "license": "GPL-3.0", + "license": "GPL-3.0-or-later", "support": { "forum": "https://chamilo.org/forum", "irc": "irc://irc.freenode.org/chamilo", @@ -13,8 +13,7 @@ }, "autoload": { "psr-4": { - "Chamilo\\": "src/", - "Application\\": "app/" + "Chamilo\\": "src/" }, "classmap": [ "main/auth", @@ -71,7 +70,6 @@ "symfony/annotations-pack": "^1.0", "symfony/webpack-encore-pack": "^1.0", "symfony/apache-pack": "^1.0", - "symfony/var-dumper": "^4.0", "apy/datagrid-bundle" : "dev-master", @@ -103,7 +101,6 @@ "sunra/php-simple-html-dom-parser": "~1.5.0", "sylius/resource-bundle": "1.2.*", - "friendsofsymfony/jsrouting-bundle": "~2.0", "gedmo/doctrine-extensions": "~2.4", "gregwar/captcha-bundle": "^2.0", @@ -160,6 +157,7 @@ "firebase/php-jwt": "^5.0" }, "require-dev": { + "symfony/var-dumper": "^4.0", "friendsofphp/php-cs-fixer": "^2.7", "symfony/browser-kit": "^4.0", "symfony/css-selector": "^4.0", diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index b71e2cd9cc..053b838333 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -1,4 +1,5 @@ framework: + form: ~ secret: '%env(APP_SECRET)%' default_locale: '%env(APP_LOCALE)%' translator: diff --git a/main/admin/access_urls.php b/main/admin/access_urls.php index 804a92013b..b30e7e2a9f 100755 --- a/main/admin/access_urls.php +++ b/main/admin/access_urls.php @@ -102,7 +102,8 @@ if ($current_access_url_id == -1) { ); if ($quant == 0) { echo Display::return_message( - ''.get_lang('ClickToRegisterAdmin').'', + ''. + get_lang('ClickToRegisterAdmin').'', 'warning', false ); @@ -139,23 +140,22 @@ echo Display::url( echo ''; -$sortable_data = UrlManager::get_url_data(); +$data = UrlManager::get_url_data(); $urls = []; -foreach ($sortable_data as $row) { - //title +foreach ($data as $row) { + // Title $url = Display::url($row['url'], $row['url'], ['target' => '_blank']); $description = $row['description']; + $createdAt = api_get_local_time($row['tms']); //Status $active = $row['active']; + $action = 'unlock'; + $image = 'wrong'; if ($active == '1') { $action = 'lock'; $image = 'right'; } - if ($active == '0') { - $action = 'unlock'; - $image = 'wrong'; - } // you cannot lock the default if ($row['id'] == '1') { $status = Display::return_icon($image.'.gif', get_lang(ucfirst($action))); @@ -165,12 +165,15 @@ foreach ($sortable_data as $row) { } // Actions $url_id = $row['id']; - $actions = Display::url(Display::return_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_SMALL), "access_url_edit.php?url_id=$url_id"); + $actions = Display::url( + Display::return_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_SMALL), + "access_url_edit.php?url_id=$url_id" + ); if ($url_id != '1') { $actions .= ''. Display::return_icon('delete.png', get_lang('Delete'), [], ICON_SIZE_SMALL).''; } - $urls[] = [$url, $description, $status, $actions]; + $urls[] = [$url, $description, $status, $createdAt, $actions]; } $table = new SortableTableFromArrayConfig($urls, 2, 50, 'urls'); @@ -178,7 +181,8 @@ $table->set_additional_parameters($parameters); $table->set_header(0, 'URL'); $table->set_header(1, get_lang('Description')); $table->set_header(2, get_lang('Active')); -$table->set_header(3, get_lang('Modify'), false); +$table->set_header(3, get_lang('CreatedAt')); +$table->set_header(4, get_lang('Modify'), false); $table->display(); Display :: display_footer(); diff --git a/main/admin/configure_homepage.php b/main/admin/configure_homepage.php index f952027f19..655eef1081 100755 --- a/main/admin/configure_homepage.php +++ b/main/admin/configure_homepage.php @@ -217,56 +217,6 @@ if (!empty($action)) { // for news file, $topf for top file, $noticef for noticefile, // $ext for '.html' switch ($action) { - case 'edit_top': - // Filter - $home_top = trim(stripslashes($_POST['home_top'])); - - // Write - if (is_writable($homep)) { - // Default - if (is_writable($homep.$topf.'_'.$lang.$ext)) { - $fp = fopen($homep.$topf.'_'.$lang.$ext, 'w'); - fputs($fp, $home_top); - fclose($fp); - - // Language - foreach ($_languages['name'] as $key => $value) { - $lang_name = $_languages['folder'][$key]; - if (isset($_POST[$lang_name])) { - $fp = fopen($homep.$topf.'_'.$lang_name.$ext, 'w'); - fputs($fp, $home_top); - fclose($fp); - } - } - } else { - $errorMsg = get_lang('HomePageFilesNotWritable'); - } - } else { - //File does not exist - $fp = fopen($homep.$topf.'_'.$lang.$ext, 'w'); - fputs($fp, $home_top); - fclose($fp); - - foreach ($_languages['name'] as $key => $value) { - $lang_name = $_languages['folder'][$key]; - if (isset($_POST[$lang_name])) { - if (file_exists($homep.$topf.'_'.$lang_name.$ext)) { - $fp = fopen($homep.$topf.'_'.$lang_name.$ext, 'w'); - fputs($fp, $home_top); - fclose($fp); - } - } - } - } - - Event::addEvent( - LOG_HOMEPAGE_CHANGED, - 'edit_top', - cut(strip_tags($home_top), 254), - api_get_utc_datetime(), - api_get_user_id() - ); - break; case 'edit_notice': // Filter $notice_title = trim(strip_tags(stripslashes($_POST['notice_title']))); @@ -1009,7 +959,6 @@ switch ($action) {
-
diff --git a/main/admin/configure_plugin.php b/main/admin/configure_plugin.php index 013ce31e45..c13a7f0343 100755 --- a/main/admin/configure_plugin.php +++ b/main/admin/configure_plugin.php @@ -43,12 +43,13 @@ if (isset($pluginInfo['settings_form'])) { Display::return_message(get_lang('NoConfigurationSettingsForThisPlugin'), 'warning') ); } + if (isset($form)) { if ($form->validate()) { $values = $form->getSubmitValues(); // Fix only for bbb - if ($pluginName === 'bbb') { + if ($pluginName == 'bbb') { if (!isset($values['global_conference_allow_roles'])) { $values['global_conference_allow_roles'] = []; } diff --git a/main/admin/settings.lib.php b/main/admin/settings.lib.php index 122e7d664e..43a8a7ddc4 100755 --- a/main/admin/settings.lib.php +++ b/main/admin/settings.lib.php @@ -197,12 +197,12 @@ function handlePlugins() $pluginRow .= Display::url( ' '.get_lang('Configure'), 'configure_plugin.php?name='.$pluginName, - ['class' => 'btn btn-secondary'] + ['class' => 'btn btn-default'] ); $pluginRow .= Display::url( ' '.get_lang('Regions'), 'settings.php?category=Regions&name='.$pluginName, - ['class' => 'btn btn-secondary'] + ['class' => 'btn btn-default'] ); } @@ -211,7 +211,7 @@ function handlePlugins() " readme.txt", api_get_path(WEB_PLUGIN_PATH).$pluginName."/readme.txt", [ - 'class' => 'btn btn-secondary ajax', + 'class' => 'btn btn-default ajax', 'data-title' => $plugin_info['title'], 'data-size' => 'lg', '_target' => '_blank', @@ -225,7 +225,7 @@ function handlePlugins() " README.md", api_get_path(WEB_AJAX_PATH).'plugin.ajax.php?a=md_to_html&plugin='.$pluginName, [ - 'class' => 'btn btn-secondary ajax', + 'class' => 'btn btn-default ajax', 'data-title' => $plugin_info['title'], 'data-size' => 'lg', '_target' => '_blank', diff --git a/main/admin/user_add.php b/main/admin/user_add.php index 7c2dc98eb3..2f9c1afeeb 100755 --- a/main/admin/user_add.php +++ b/main/admin/user_add.php @@ -245,7 +245,7 @@ $form->addElement( ); //drh list (display only if student) -$display = isset($_POST['status']) && $_POST['status'] == STUDENT || !isset($_POST['status']) ? 'block' : 'none'; +$display = (isset($_POST['status']) && $_POST['status'] == STUDENT) || !isset($_POST['status']) ? 'block' : 'none'; //@todo remove the drh list here. This code is unused $form->addElement('html', '
'); diff --git a/main/announcements/announcements.php b/main/announcements/announcements.php index 4a193d654f..2a371da855 100755 --- a/main/announcements/announcements.php +++ b/main/announcements/announcements.php @@ -450,7 +450,7 @@ switch ($action) { ); // when we want to remind the users who have never been active // then we have a different subject and content for the announcement - if ($_GET['since'] == 'never') { + if ($_GET['since'] === 'never') { $title_to_modify = sprintf( get_lang('RemindInactiveLearnersMailSubject'), api_get_setting('siteName') @@ -475,6 +475,7 @@ switch ($action) { $announcementInfo = AnnouncementManager::get_by_id($courseId, $id); if (isset($announcementInfo) && !empty($announcementInfo)) { $to = AnnouncementManager::load_edit_users('announcement', $id); + $defaults = [ 'title' => $announcementInfo['title'], 'content' => $announcementInfo['content'], @@ -545,6 +546,8 @@ switch ($action) { $form->addCheckBox('send_to_hrm_users', null, get_lang('SendAnnouncementCopyToDRH')); } + $form->addCheckBox('send_me_a_copy_by_email', null, get_lang('SendAnnouncementCopyToMyself')); + $defaults['send_me_a_copy_by_email'] = true; $form->addButtonSave(get_lang('ButtonPublishAnnouncement')); $form->setDefaults($defaults); @@ -552,6 +555,7 @@ switch ($action) { $data = $form->getSubmitValues(); $data['users'] = isset($data['users']) ? $data['users'] : []; $sendToUsersInSession = isset($data['send_to_users_in_session']) ? true : false; + $sendMeCopy = isset($data['send_me_a_copy_by_email']) ? true : false; if (isset($id) && $id) { // there is an Id => the announcement already exists => update mode @@ -570,8 +574,9 @@ switch ($action) { ); // Send mail + $messageSentTo = []; if (isset($_POST['email_ann']) && empty($_POST['onlyThoseMails'])) { - AnnouncementManager::sendEmail( + $messageSentTo = AnnouncementManager::sendEmail( api_get_course_info(), api_get_session_id(), $id, @@ -580,6 +585,11 @@ switch ($action) { ); } + if ($sendMeCopy && !in_array(api_get_user_id(), $messageSentTo)) { + $email = new AnnouncementEmail(api_get_course_info(), api_get_session_id(), $id); + $email->sendAnnouncementEmailToMySelf(); + } + Display::addFlash( Display::return_message( get_lang('AnnouncementModified'), @@ -612,13 +622,14 @@ switch ($action) { $insert_id = AnnouncementManager::add_group_announcement( $data['title'], $data['content'], - ['GROUP:'.$group_id], + $group_id, $data['users'], $file, $file_comment, $sendToUsersInSession ); } + if ($insert_id) { Display::addFlash( Display::return_message( @@ -628,14 +639,21 @@ switch ($action) { ); // Send mail + $messageSentTo = []; if (isset($data['email_ann']) && $data['email_ann']) { - AnnouncementManager::sendEmail( + $messageSentTo = AnnouncementManager::sendEmail( api_get_course_info(), api_get_session_id(), $insert_id, $sendToUsersInSession ); } + + if ($sendMeCopy && !in_array(api_get_user_id(), $messageSentTo)) { + $email = new AnnouncementEmail(api_get_course_info(), api_get_session_id(), $insert_id); + $email->sendAnnouncementEmailToMySelf(); + } + Security::clear_token(); header('Location: '.$homeUrl); exit; diff --git a/main/course_info/about.php b/main/course_info/about.php index e0f23720e1..f0b3775400 100644 --- a/main/course_info/about.php +++ b/main/course_info/about.php @@ -154,7 +154,7 @@ $courseItem = [ $metaInfo = ''; $metaInfo .= ''; $metaInfo .= ''; -$metaInfo .= ''; +$metaInfo .= ''; $metaInfo .= ''; $htmlHeadXtra[] = $metaInfo; diff --git a/main/cron/import_csv.php b/main/cron/import_csv.php index 8ef13dc8bd..8ca905a81c 100755 --- a/main/cron/import_csv.php +++ b/main/cron/import_csv.php @@ -240,11 +240,11 @@ class ImportCsv 'teachers-static', 'courses-static', 'sessions-static', - 'calendar-static', 'sessionsextid-static', 'unsubscribe-static', 'unsubsessionsextid-static', 'subsessionsextid-static', + 'calendar-static', ]; foreach ($sections as $section) { @@ -667,6 +667,10 @@ class ImportCsv false //$send_mail = false ); + $row['extra_mail_notify_invitation'] = 1; + $row['extra_mail_notify_message'] = 1; + $row['extra_mail_notify_group_message'] = 1; + if ($userId) { foreach ($row as $key => $value) { if (substr($key, 0, 6) == 'extra_') { @@ -832,6 +836,10 @@ class ImportCsv false //$send_mail = false ); + $row['extra_mail_notify_invitation'] = 1; + $row['extra_mail_notify_message'] = 1; + $row['extra_mail_notify_group_message'] = 1; + if ($result) { foreach ($row as $key => $value) { if (substr($key, 0, 6) === 'extra_') { @@ -1026,6 +1034,11 @@ class ImportCsv if (empty($courseInfo)) { $this->logger->addInfo("Course '$courseCode' does not exists"); + } else { + if ($courseInfo['visibility'] == COURSE_VISIBILITY_HIDDEN) { + $this->logger->addInfo("Course '".$courseInfo['code']."' has hidden visiblity. Skip"); + $errorFound = true; + } } if (empty($sessionId)) { @@ -1035,7 +1048,6 @@ class ImportCsv $sessionInfo = []; if (!empty($sessionId) && !empty($courseInfo)) { $sessionInfo = api_get_session_info($sessionId); - $courseIncluded = SessionManager::relation_session_course_exist( $sessionId, $courseInfo['real_id'] diff --git a/main/document/show_content.php b/main/document/show_content.php index c713f1cabe..e57db36c59 100755 --- a/main/document/show_content.php +++ b/main/document/show_content.php @@ -94,7 +94,7 @@ header('Last-Modified: Wed, 01 Jan 2100 00:00:00 GMT'); header('Cache-Control: no-cache, must-revalidate'); header('Pragma: no-cache'); $browser_display_title = 'Documents - '.Security::remove_XSS($_GET['cidReq']).' - '.$file; -$file_url_web = api_get_path(WEB_COURSE_PATH).$_course['path'].'/document'.$header_file.'?'.api_get_cidreq(); +$file_url_web = api_get_path(WEB_COURSE_PATH).$course_info['path'].'/document'.$header_file.'?'.api_get_cidreq(); $pathinfo = pathinfo($header_file); if ($pathinfo['extension'] == 'swf') { diff --git a/main/exercise/exercise.class.php b/main/exercise/exercise.class.php index 598f807504..a1ad081824 100755 --- a/main/exercise/exercise.class.php +++ b/main/exercise/exercise.class.php @@ -962,29 +962,38 @@ class Exercise $result['question_list'] = isset($question_list) ? $question_list : []; $result['category_with_questions_list'] = isset($questions_by_category) ? $questions_by_category : []; + $parentsLoaded = []; // Adding category info in the category list with question list: if (!empty($questions_by_category)) { $newCategoryList = []; $em = Database::getManager(); + foreach ($questions_by_category as $categoryId => $questionList) { $cat = new TestCategory(); $cat = $cat->getCategory($categoryId); - $cat = (array) $cat; - $cat['iid'] = $cat['id']; + if ($cat) { + $cat = (array) $cat; + $cat['iid'] = $cat['id']; + } + $categoryParentInfo = null; // Parent is not set no loop here - if (!empty($cat['parent_id'])) { + if (isset($cat['parent_id']) && !empty($cat['parent_id'])) { + /** @var \Chamilo\CourseBundle\Entity\CQuizCategory $categoryEntity */ if (!isset($parentsLoaded[$cat['parent_id']])) { $categoryEntity = $em->find('ChamiloCoreBundle:CQuizCategory', $cat['parent_id']); $parentsLoaded[$cat['parent_id']] = $categoryEntity; } else { $categoryEntity = $parentsLoaded[$cat['parent_id']]; } + $repo = $em->getRepository('ChamiloCoreBundle:CQuizCategory'); $path = $repo->getPath($categoryEntity); + $index = 0; if ($this->categoryMinusOne) { //$index = 1; } + /** @var \Chamilo\CourseBundle\Entity\CQuizCategory $categoryParent */ foreach ($path as $categoryParent) { $visibility = $categoryParent->getVisibility(); @@ -3229,7 +3238,11 @@ class Exercise */ public function showTimeControlJS($time_left) { - $time_left = intval($time_left); + $time_left = (int) $time_left; + $script = "redirectExerciseToResult();"; + if ($this->type == ALL_ON_ONE_PAGE) { + $script = "save_now_all('validate');"; + } return "