User: Improve terms and conditions, fix warning errors and auto-register - refs BT#19044

pull/4020/head
Christian 4 years ago
parent ce0ad53824
commit 036998d802
  1. 32
      public/main/admin/legal_add.php
  2. 10
      public/main/admin/legal_list.php
  3. 10
      public/main/inc/ajax/model.ajax.php
  4. 1
      public/main/inc/lib/api.lib.php
  5. 2
      public/main/inc/lib/extra_field.lib.php
  6. 35
      public/main/inc/lib/extra_field_value.lib.php
  7. 17
      public/main/inc/lib/legal.lib.php
  8. 182
      public/main/inc/lib/sessionmanager.lib.php
  9. 42
      public/main/mySpace/myStudents.php
  10. 49
      public/main/search/load_search.php
  11. 7
      public/main/template/default/my_space/user_details.html.twig
  12. 6
      public/main/template/default/session/resume_session.html.twig
  13. 89
      src/CoreBundle/Controller/CourseController.php
  14. 12
      src/CoreBundle/EventListener/CourseListener.php
  15. 3
      src/CoreBundle/EventListener/TwigListener.php
  16. 12
      src/CoreBundle/Framework/Container.php
  17. 96
      src/CoreBundle/Repository/LegalRepository.php
  18. 22
      src/CoreBundle/Resources/views/Macros/box.html.twig
  19. 18
      tests/CoreBundle/Controller/CourseControllerTest.php

@ -18,7 +18,7 @@ if ('true' !== api_get_setting('allow_terms_conditions')) {
$form = new FormValidator('addlegal');
$defaults = [];
$term_preview = [
$termPreview = [
'type' => 0,
'content' => '',
'changes' => '',
@ -86,19 +86,19 @@ if ($form->validate()) {
$defaults['type'] = $type;
$defaults['content'] = $content;
$defaults['changes'] = $changes;
$term_preview = $defaults;
$term_preview['type'] = (int) $_POST['type'];
$termPreview = $defaults;
$termPreview['type'] = (int) $_POST['type'];
} else {
$my_lang = $_POST['language'];
$myLang = $_POST['language'];
if (isset($_POST['language'])) {
$all_langs = api_get_languages();
if (in_array($my_lang, $all_langs['folder'])) {
$language = api_get_language_id($my_lang);
$term_preview = LegalManager::get_last_condition($language);
$defaults = $term_preview;
if (!$term_preview) {
$allLangs = api_get_languages();
if (in_array($myLang, array_keys($allLangs))) {
$language = api_get_language_id($myLang);
$termPreview = LegalManager::get_last_condition($language);
$defaults = $termPreview;
if (!$termPreview) {
// there are not terms and conditions
$term_preview['type'] = -1;
$termPreview['type'] = -1;
$defaults['type'] = 0;
}
}
@ -134,14 +134,14 @@ if (isset($_POST['language'])) {
$form->addElement('radio', 'type', '', get_lang('HTML'), '0');
$form->addElement('radio', 'type', '', get_lang('Page Link'), '1');
$preview = LegalManager::show_last_condition($term_preview);
$preview = LegalManager::show_last_condition($termPreview);
if (-1 != $term_preview['type']) {
if (-1 != $termPreview['type']) {
$preview = LegalManager::replaceTags($preview);
$form->addElement('label', get_lang('Preview'), $preview);
}
$termId = isset($term_preview['id']) ? $term_preview['id'] : 0;
$termId = isset($termPreview['id']) ? $termPreview['id'] : 0;
$returnParams = $extraField->addElements(
$form,
$termId,
@ -180,7 +180,7 @@ if (isset($_POST['language'])) {
$form->addButtonSearch(get_lang('Load'), 'send');
}
$tool_name = get_lang('Add terms and conditions');
$toolName = get_lang('Add terms and conditions');
$interbreadcrumb[] = ['url' => 'index.php', 'name' => get_lang('Administration')];
// the $jquery_ready_content variable collects all functions that will be load in the $(document).ready javascript function
@ -190,7 +190,7 @@ $(function () {
});
</script>';
Display::display_header($tool_name);
Display::display_header($toolName);
echo '<script>
function sendlang() {

@ -33,12 +33,12 @@ $em = Database::getManager();
$legalTermsRepo = $em->getRepository(Legal::class);
$legalCount = $legalTermsRepo->countAllActiveLegalTerms();
$languages = api_get_languages();
$available_languages = count($languages['folder']);
if ($legalCount != $available_languages) {
$availableLanguages = count($languages);
if ($legalCount != $availableLanguages) {
echo Display::return_message(get_lang('You should create the "Term and Conditions" for all the available languages.'), 'warning');
}
$table = new SortableTable('conditions', 'count_mask', 'get_legal_data_mask', 2);
$table = new SortableTable('conditions', 'countMask', 'getLegalDataMask', 2);
$table->set_additional_parameters($parameters);
$table->set_header(0, get_lang('Version'), false, 'width="15px"');
$table->set_header(1, get_lang('Language'), false, 'width="30px"');
@ -49,12 +49,12 @@ $table->set_header(5, get_lang('Date'), false, 'width="50px"');
$table->display();
// this 2 "mask" function are here just because the SortableTable
function get_legal_data_mask($id, $params = null, $row = null)
function getLegalDataMask($id, $params = null, $row = null)
{
return LegalManager::get_legal_data($id, $params, $row);
}
function count_mask()
function countMask()
{
return LegalManager::count();
}

@ -798,8 +798,9 @@ switch ($action) {
}
break;
case 'get_sessions':
$listType = isset($_REQUEST['list_type']) ? $_REQUEST['list_type'] : SessionManager::getDefaultSessionTab();
$listType = isset($_REQUEST['list_type']) ? $_REQUEST['list_type'] : 'simple';
$language = isset($_REQUEST['lang']) ? $_REQUEST['lang'] : '';
$order = isset($_REQUEST['order']) ? $_REQUEST['order'] : '';
$sessionColumns = SessionManager::getGridColumns($listType);
$columns = $sessionColumns['simple_column_name'];
@ -832,9 +833,9 @@ switch ($action) {
['where' => $whereCondition, 'extra' => $extra_fields],
true,
[],
$extraFieldsToLoad,
$listType,
$extraFieldsToLoad
$extraFieldsToLoad,
$search
);
break;
case 'active':
@ -1963,7 +1964,8 @@ switch ($action) {
false,
$sessionColumns,
$listType,
$extraFieldsToLoad
$extraFieldsToLoad,
$search
);
break;
case 'active':

@ -1298,6 +1298,7 @@ function _api_format_user($user, $add_password = false, $loadAvatars = true)
'expiration_date',
'last_login',
'user_is_online',
'profile_completed',
];
if ('true' === api_get_setting('extended_profile')) {

@ -407,7 +407,7 @@ class ExtraField extends Model
$('#map_extra_{$variable}')
.html('<div class=\"alert alert-info\">"
.addslashes(get_lang('YouNeedToActivateTheGoogleMapsPluginInAdminPlatformToSeeTheMap'))
.addslashes(get_lang('You need to activate the GoogleMaps plugin in adminPlatform to see the Map'))
."</div>');
});

@ -8,6 +8,7 @@ use Chamilo\CoreBundle\Entity\ExtraFieldRelTag;
use Chamilo\CoreBundle\Entity\ExtraFieldValues;
use Chamilo\CoreBundle\Entity\Tag;
use Chamilo\CoreBundle\Framework\Container;
use ChamiloSession as Session;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
@ -119,6 +120,7 @@ class ExtraFieldValue extends Model
$extraField = new ExtraField($this->type);
$extraFields = $extraField->get_all(null, 'option_order');
$resultsExist = [];
$em = Database::getManager();
// Parse params.
@ -158,6 +160,8 @@ class ExtraFieldValue extends Model
if (isset($params[$fieldVariableWithExtra])) {
$value = $params[$fieldVariableWithExtra];
}
$resultsExist[$field_variable] = isset($value) && '' !== $value ? true : false;
$extraFieldInfo = $this->getExtraField()->get_handler_field_info_by_field_variable($field_variable);
if (!$extraFieldInfo) {
@ -376,6 +380,37 @@ class ExtraFieldValue extends Model
$this->save($newParams, $showQuery);
}
}
// ofaj
// Set user.profile_completed = 1
if ('user' === $this->type) {
if ('true' === api_get_setting('show_terms_if_profile_completed')) {
$justTermResults = [];
foreach ($resultsExist as $term => $value) {
if (false !== strpos($term, 'terms_')) {
$justTermResults[$term] = $value;
}
}
$profileCompleted = 0;
if (!in_array(false, $justTermResults)) {
$profileCompleted = 1;
}
$userId = $params['item_id'];
// Check if user has a photo
$userInfo = api_get_user_info($userId);
if (empty($userInfo['picture_uri'])) {
$profileCompleted = 0;
}
$table = Database::get_main_table(TABLE_MAIN_USER);
$sql = "UPDATE $table SET profile_completed = $profileCompleted WHERE id = $userId";
Database::query($sql);
Session::write('profile_completed_result', $justTermResults);
}
}
}
/**

@ -29,6 +29,11 @@ class LegalManager
{
$legalTable = Database::get_main_table(TABLE_MAIN_LEGAL);
$last = self::get_last_condition($language);
if (false === $last) {
return 0;
}
$type = (int) $type;
$time = time();
@ -187,9 +192,9 @@ class LegalManager
}
$sql = "SELECT version FROM $table
WHERE
language_id = $language AND
version = $version
WHERE
language_id = $language AND
version = $version
LIMIT 1 ";
$result = Database::query($sql);
if (Database::num_rows($result) > 0) {
@ -309,10 +314,10 @@ class LegalManager
$column = (int) $column;
$sql = "SELECT version, original_name as language, content, changes, type, FROM_UNIXTIME(date)
FROM $table
FROM $table
INNER JOIN $lang_table l
ON (language_id = l.id)
ORDER BY language, version ASC
ON (language_id = l.id)
ORDER BY language, version ASC
LIMIT $from, $number_of_items ";
$result = Database::query($sql);

@ -458,11 +458,13 @@ class SessionManager
/**
* Get session list for a session admin or platform admin.
*
* @param int $userId User Id for the session admin.
* @param array $options Order and limit keys.
* @param bool $getCount Whether to get all the results or only the count.
* @param array $columns Columns from jqGrid.
* @param int $userId User Id for the session admin.
* @param array $options Order and limit keys.
* @param bool $getCount Whether to get all the results or only the count.
* @param array $columns Columns from jqGrid.
* @param string $listType
* @param array $extraFieldsToLoad
* @param bool $formatted
*
* @return array
*/
@ -472,7 +474,8 @@ class SessionManager
$getCount = false,
$columns = [],
$listType = 'all',
$extraFieldsToLoad = []
$extraFieldsToLoad = [],
$formatted = false
) {
$tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
$sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
@ -489,7 +492,7 @@ class SessionManager
$where .= $conditions['where'];
$sqlInjectWhere = $conditions['inject_where'];
$injectExtraFields = $conditions['inject_extra_fields'];
$order = empty($conditions['order']) ? ' ORDER BY position ASC' : $conditions['order'];
$order = empty($conditions['order']) ? ' ORDER BY s.name ASC' : $conditions['order'];
$limit = $conditions['limit'];
$isMakingOrder = false;
@ -627,27 +630,166 @@ class SessionManager
$query .= $order;
$query .= $limit;
$result = Database::query($query);
$sessions = Database::store_result($result, 'ASSOC');
if ($showCountUsers && !$getCount) {
foreach ($sessions as &$session) {
$result = Database::query("SELECT COUNT(1) AS nbr
if (!$formatted) {
$result = Database::query($query);
$sessions = Database::store_result($result, 'ASSOC');
if ($showCountUsers && !$getCount) {
foreach ($sessions as &$session) {
$result = Database::query("SELECT COUNT(session_id) AS nbr
FROM session_rel_user WHERE session_id = {$session['id']} AND relation_type = ".Session::STUDENT);
$session['users'] = Database::fetch_assoc($result)['nbr'];
$session['users'] = Database::fetch_assoc($result)['nbr'];
}
}
if ('all' === $listType) {
if ($getCount) {
return $sessions[0]['total_rows'];
}
return $sessions;
}
return $sessions;
}
if ('all' === $listType) {
// For search diagnosis format (Ofaj)
$categories = self::get_all_session_category();
$orderedCategories = [];
if (!empty($categories)) {
foreach ($categories as $category) {
$orderedCategories[$category['id']] = $category['name'];
}
}
$result = Database::query($query);
$formattedSessions = [];
if (Database::num_rows($result)) {
$sessions = Database::store_result($result, 'ASSOC');
if ($getCount) {
return $sessions[0]['total_rows'];
}
return $sessions;
$activeIcon = Display::return_icon(
'accept.png',
get_lang('Active'),
[],
ICON_SIZE_SMALL
);
$inactiveIcon = Display::return_icon(
'error.png',
get_lang('Inactive'),
[],
ICON_SIZE_SMALL
);
foreach ($sessions as $session) {
$session_id = $session['id'];
if ($showCountUsers) {
$session['users'] = self::get_users_by_session(
$session['id'],
null,
true
);
$courses = self::getCoursesInSession($session_id);
$teachers = '';
foreach ($courses as $courseId) {
$courseInfo = api_get_course_info_by_id($courseId);
// Ofaj
$teachers = CourseManager::get_coachs_from_course_to_string($session_id, $courseInfo['real_id']);
/*$teachers .= CourseManager::get_teacher_list_from_course_code_to_string(
$courseInfo['code']
);*/
}
// ofaj
$session['teachers'] = '';
if (!empty($teachers)) {
$session['teachers'] = Display::return_icon('teacher.png', addslashes($teachers));
}
}
$url = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$session['id'];
if (api_is_drh()) {
$url = api_get_path(WEB_CODE_PATH).'session/about.php?session_id='.$session['id'];
}
if (api_is_platform_admin()) {
$url = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$session['id'];
}
if ($extraFieldsToLoad) {
$url = api_get_path(WEB_CODE_PATH).'session/about.php?session_id='.$session['id'];
}
$session['name'] = Display::url($session['name'], $url);
if (isset($session['session_active']) && $session['session_active'] == 1) {
$session['session_active'] = $activeIcon;
} else {
$session['session_active'] = $inactiveIcon;
}
$session = self::convert_dates_to_local($session, true);
switch ($session['visibility']) {
case SESSION_VISIBLE_READ_ONLY: //1
$session['visibility'] = get_lang('ReadOnly');
break;
case SESSION_VISIBLE: //2
case SESSION_AVAILABLE: //4
$session['visibility'] = get_lang('Visible');
break;
case SESSION_INVISIBLE: //3
$session['visibility'] = api_ucfirst(get_lang('Invisible'));
break;
}
if (!empty($extraFieldsToLoad)) {
foreach ($extraFieldsToLoad as $field) {
$extraFieldValue = new ExtraFieldValue('session');
$fieldData = $extraFieldValue->getAllValuesByItemAndField(
$session['id'],
$field['id']
);
$fieldDataArray = [];
if (!empty($fieldData)) {
foreach ($fieldData as $data) {
$fieldDataArray[] = $data['value'];
}
$fieldDataToString = implode(', ', $fieldDataArray);
}
$session[$field['variable']] = $fieldDataToString;
}
}
// Cleaning double selects.
foreach ($session as $key => &$value) {
if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
$options = explode('::', $value);
}
$original_key = $key;
if (strpos($key, '_second') === false) {
} else {
$key = str_replace('_second', '', $key);
}
if (isset($options_by_double[$key])) {
if (isset($options[0])) {
if (isset($options_by_double[$key][$options[0]])) {
if (strpos($original_key, '_second') === false) {
$value = $options_by_double[$key][$options[0]]['option_display_text'];
} else {
$value = $options_by_double[$key][$options[1]]['option_display_text'];
}
}
}
}
}
$categoryName = isset($orderedCategories[$session['session_category_id']]) ? $orderedCategories[$session['session_category_id']] : '';
$session['category_name'] = $categoryName;
if (isset($session['status'])) {
$session['status'] = self::getStatusLabel($session['status']);
}
$formattedSessions[] = $session;
}
}
return $sessions;
return $formattedSessions;
}
/**
@ -3390,7 +3532,7 @@ class SessionManager
$resultRow = Database::fetch_assoc($res);
// If the user is only connected to a course coach then deleted it.
if (1 === (int) $resultRow['count']) {
$sql = "DELETE FROM $tblSessionRelUser
$sql = "DELETE FROM $tblSessionRelUser
WHERE
session_id = $sessionId AND
user_id = $userId ";
@ -3424,7 +3566,7 @@ class SessionManager
// Then update or insert.
if (Database::num_rows($rs_check) > 0) {
$sql = "UPDATE $tblSessionRelCourseRelUser
$sql = "UPDATE $tblSessionRelCourseRelUser
SET status = ".Session::COURSE_COACH."
WHERE
session_id = $sessionId AND
@ -8069,7 +8211,7 @@ class SessionManager
FROM $extraFieldTables $tbl_session s
LEFT JOIN $tbl_session_category sc
ON s.session_category_id = sc.id
INNER JOIN $tblSessionRelUser sru
INNER JOIN $tblSessionRelUser sru
ON s.id = sru.session_id
INNER JOIN $tbl_user u
ON sru.user_id = u.id

@ -550,24 +550,29 @@ switch ($action) {
if ($myCertificate) {
$certificate = new Certificate($myCertificate['id'], $studentId);
$certificate->deleteCertificate(true);
// Create new one
$certificate = new Certificate(0, $studentId);
$certificate->generatePdfFromCustomCertificate();
exit;
}
// Create new one
$certificate = new Certificate(0, $studentId);
$certificate->generatePdfFromCustomCertificate();
exit;
break;
case 'send_legal':
$isBoss = UserManager::userIsBossOfStudent(api_get_user_id(), $studentId);
if ($isBoss || api_is_platform_admin()) {
$subject = get_lang('Legal conditions');
$content = sprintf(
get_lang(
'Hello,<br />Your tutor sent you your terms and conditions. You can sign it following this URL: %s'
),
api_get_path(WEB_PATH)
);
MessageManager::send_message_simple($studentId, $subject, $content);
Display::addFlash(Display::return_message(get_lang('Sent')));
LegalManager::sendLegal($studentId);
/*
$currentUserInfo = api_get_user_info();
$subject = get_lang('SendLegalSubject');
$linkLegal = api_get_path(WEB_PATH)."courses/FORUMDAIDE/index.php";
$content = sprintf(
get_lang('SendTermsDescriptionToUrlX'),
$user_info['complete_name'],
"<a href=\"".$linkLegal."\">".$linkLegal."</a>",
$currentUserInfo['complete_name']
);
MessageManager::send_message_simple($student_id, $subject, $content);
Display::addFlash(Display::return_message(get_lang('Sent')));
*/
}
break;
case 'delete_legal':
@ -998,11 +1003,20 @@ if ('true' === api_get_setting('allow_terms_conditions')) {
}
}
$userInfoExtra['legal'] = [
'icon' => $icon,
'label' => get_lang('Legal accepted').$icon,
'datetime' => $timeLegalAccept,
'url_send' => $btn,
];
}
$iconCertificate = ' '.Display::url(
get_lang('Generate'),
api_get_self().'?action=generate_certificate&student='.$studentId.'&cid='.$courseId.'&course='.$courseCode,
['class' => 'btn btn-primary btn-xs']
);
$userInfoExtra['certificate'] = [
'label' => get_lang('Certificate'),
'content' => $iconCertificate,
];
if (isset($_GET['action']) && 'all_attendance' === $_GET['action']) {
/* Display all attendances */

@ -520,7 +520,7 @@ if (!empty($extraFieldsToFilter)) {
$extraFieldListToString = implode(',', $extraFieldToSearch);
$result = SessionManager::getGridColumns('simple', $extraFieldsToFilter);
$columns = $result['columns'];
$column_model = $result['column_model'];
$columnModel = $result['column_model'];
$form->setDefaults($defaults);
@ -982,7 +982,7 @@ $extra_params['autowidth'] = 'true';
// height auto
$extra_params['height'] = 'auto';
$extra_params['postData'] = [
$extraParams['postData'] = [
'filters' => [
'groupOp' => 'AND',
'rules' => $result['rules'],
@ -997,7 +997,8 @@ if (!empty($sessionByUserList)) {
$sessionUserList[] = (string) $sessionByUser['session_id'];
}
}
$action_links = 'function action_formatter(cellvalue, options, rowObject) {
$actionLinks = 'function action_formatter(cellvalue, options, rowObject) {
var sessionList = '.json_encode($sessionUserList).';
var id = options.rowId.toString();
if (sessionList.indexOf(id) == -1) {
@ -1025,10 +1026,10 @@ $griJs = Display::grid_js(
'sessions',
$url,
$columns,
$column_model,
$extra_params,
$columnModel,
$extraParams,
[],
$action_links,
$actionLinks,
true
);
@ -1056,9 +1057,9 @@ $table = new HTML_Table(['class' => 'data_table']);
$column = 0;
$row = 0;
$total = '0';
$sumHours = '0';
$numHours = '0';
$total = 0;
$sumHours = 0;
$numHours = 0;
$field = 'heures_disponibilite_par_semaine';
$data = null;
@ -1074,6 +1075,10 @@ function dateDiffInWeeks($date1, $date2)
if (empty($date1) || empty($date2)) {
return 0;
}
// it validates a correct date format Y-m-d
if (false === DateTime::createFromFormat('Y-m-d', $date1) || false === DateTime::createFromFormat('Y-m-d', $date2)) {
return 0;
}
if ($date1 > $date2) {
return dateDiffInWeeks($date2, $date1);
@ -1085,7 +1090,7 @@ function dateDiffInWeeks($date1, $date2)
}
if ($data) {
$availableHoursPerWeek = $data['value'];
$availableHoursPerWeek = (int) $data['value'];
$numberWeeks = 0;
if ($form->validate()) {
$formData = $form->getSubmitValues();
@ -1113,12 +1118,12 @@ if ($data) {
foreach ($sessions as $session) {
$sessionId = $session['id'];
$data = $sessionFieldValue->get_values_by_handler_and_field_variable(
$dataTravails = $sessionFieldValue->get_values_by_handler_and_field_variable(
$sessionId,
'temps_de_travail'
);
if ($data) {
$sumHours += $data['value'];
if ($dataTravails) {
$sumHours += (int) $dataTravails['value'];
}
}
}
@ -1138,21 +1143,21 @@ foreach ($headers as $header => $value) {
}
$button = '';
$userReportButton = '';
if ($userToLoad) {
/*$button = Display::url(
$button = Display::url(
get_lang('Ofaj End Of LearnPath'),
api_get_path(WEB_CODE_PATH).'messages/new_message.php?prefill=ofaj&send_to_user='.$userToLoad,
api_get_path(WEB_PATH).'resources/messages/new',
['class' => 'btn btn-default']
);
$button .= '<br /><br />';*/
$button .= '<br /><br />';
$userReportButton = Display::url(
get_lang('Diagnostic Validate LearningPath'),
api_get_path(WEB_CODE_PATH).'mySpace/myStudents.php?student='.$userToLoad,
['class' => 'btn btn-primary']
);
}
$userReportButton = Display::url(
get_lang('Diagnostic Validate LearningPath'),
api_get_path(WEB_CODE_PATH).'mySpace/myStudents.php?student='.$userToLoad,
['class' => 'btn btn-primary']
);
$tpl->assign('grid', $grid.$button.$table->toHtml().$userReportButton);
$tpl->assign('grid_js', $griJs);
$templateName = $tpl->get_template('search/search_extra_field.html.twig');

@ -31,8 +31,11 @@
{{ display.card_widget('First login in platform'|trans, user_extra.first_connection, 'calendar') }}
{{ display.card_widget('Latest login in platform'|trans, user_extra.last_connection, 'calendar') }}
{% if user_extra.legal %}
{{ display.card_widget('Legal accepted'|trans, user_extra.legal.datetime, 'gavel', user_extra.legal.icon) }}
{% if user_extra.legal is defined %}
{{ display.card_widget(user_extra.legal.label, user_extra.legal.url_send, user_extra.legal.datetime) }}
{% endif %}
{% if user_extra.certificate is defined %}
{{ display.card_widget(user_extra.certificate.label, user_extra.certificate.content) }}
{% endif %}
</div>
</div>

@ -108,7 +108,11 @@
{% for extra_field in extra_fields %}
<tr>
<td>{{ extra_field.text }}</td>
<td>{{ extra_field.value }}</td>
{% if extra_field.value is iterable %}
<td>{{ extra_field.value.value }}</td>
{% else %}
<td>{{ extra_field.value }}</td>
{% endif %}
</tr>
{% endfor %}

@ -11,6 +11,8 @@ use Chamilo\CoreBundle\Entity\ExtraField;
use Chamilo\CoreBundle\Entity\ExtraFieldRelTag;
use Chamilo\CoreBundle\Framework\Container;
use Chamilo\CoreBundle\Repository\ExtraFieldRelTagRepository;
use Chamilo\CoreBundle\Repository\LanguageRepository;
use Chamilo\CoreBundle\Repository\LegalRepository;
use Chamilo\CoreBundle\Repository\Node\IllustrationRepository;
use Chamilo\CoreBundle\Security\Authorization\Voter\CourseVoter;
use Chamilo\CoreBundle\Tool\ToolChain;
@ -46,6 +48,93 @@ use UserManager;
#[Route('/course')]
class CourseController extends ToolBaseController
{
#[Route('/{cid}/checkLegal.json', name: 'chamilo_core_course_check_legal_json')]
public function checkTermsAndConditionJson(Request $request, LegalRepository $legalTermsRepo, LanguageRepository $languageRepository): Response
{
$user = $this->getUser();
$course = $this->getCourse();
$responseData = [
'redirect' => false,
'url' => '#',
];
$termAndConditionStatus = $legalTermsRepo->checkTermCondition($user);
if (false === $termAndConditionStatus) {
$request->getSession()->set('term_and_condition', ['user_id' => $user->getId()]);
} else {
$request->getSession()->remove('term_and_condition');
}
$termsAndCondition = $request->getSession()->get('term_and_condition');
if (null !== $termsAndCondition) {
// user id
$userId = $termsAndCondition['user_id'];
// Update the terms & conditions
$legalType = null;
// Verify type of terms and conditions
if (null !== $request->get('legal_info')) {
$infoLegal = explode(':', $request->get('legal_info'));
$legalId = (int) $infoLegal[0];
$languageId = (int) $infoLegal[1];
$legal = $legalTermsRepo->find($legalId);
$language = $languageRepository->find($languageId);
$legalType = $legalTermsRepo->getTypeOfTermsAndConditions($legal, $language);
}
$legalOption = (empty($legalType));
// is necessary verify check
if (1 === $legalType) {
$legalOption = (null !== $request->get('legal_accept') && 1 === (int) $request->get('legal_accept'));
}
if (null !== $request->get('legal_accept_type') && true === $legalOption) {
$condArray = explode(':', $request->get('legal_accept_type'));
if (!empty($condArray[0]) && !empty($condArray[1])) {
$time = time();
$conditionToSave = intval($condArray[0]).':'.intval($condArray[1]).':'.$time;
UserManager::update_extra_field_value(
$userId,
'legal_accept',
$conditionToSave
);
}
}
$redirect = true;
$allow = api_get_configuration_value('allow_public_course_with_no_terms_conditions');
if (true === $allow &&
null !== $course->getVisibility() &&
COURSE_VISIBILITY_OPEN_WORLD == $course->getVisibility()
) {
$redirect = false;
}
if ($redirect && !$this->isGranted('ROLE_ADMIN')) {
$url = '/main/auth/inscription.php';
$responseData = [
'redirect' => $redirect,
'url' => $url,
];
}
}
$json = $this->get('serializer')->serialize(
$responseData,
'json',
[
'groups' => ['course:read', 'ctool:read', 'tool:read', 'cshortcut:read'],
]
);
return new Response(
$json,
Response::HTTP_OK,
[
'Content-type' => 'application/json',
]
);
}
#[Route('/{cid}/home.json', name: 'chamilo_core_course_home_json')]
#[Entity('course', expr: 'repository.find(cid)')]
public function indexJson(Request $request, CToolRepository $toolRepository, CShortcutRepository $shortcutRepository, ToolChain $toolChain): Response

@ -26,6 +26,9 @@ use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\User\UserInterface;
use Twig\Environment;
use Chamilo\CoreBundle\Repository\LegalRepository;
use Chamilo\CoreBundle\Settings\SettingsManager;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* Class CourseListener.
@ -37,11 +40,16 @@ class CourseListener
private Environment $twig;
private AuthorizationCheckerInterface $authorizationChecker;
private SettingsManager $settingsManager;
public function __construct(Environment $twig, AuthorizationCheckerInterface $authorizationChecker)
{
public function __construct(
Environment $twig,
AuthorizationCheckerInterface $authorizationChecker,
SettingsManager $settingsManager
) {
$this->twig = $twig;
$this->authorizationChecker = $authorizationChecker;
$this->settingsManager= $settingsManager;
}
/**

@ -69,7 +69,8 @@ class TwigListener
'editor.enabled_mathjax',
'editor.translate_html',
'platform.load_term_conditions_section',
'registration.allow_terms_conditions',
'agenda.personal_calendar_show_sessions_occupation',
];

@ -13,6 +13,8 @@ use Chamilo\CoreBundle\Repository\CareerRepository;
use Chamilo\CoreBundle\Repository\CourseCategoryRepository;
use Chamilo\CoreBundle\Repository\ExtraFieldRepository;
use Chamilo\CoreBundle\Repository\GradeBookCategoryRepository;
use Chamilo\CoreBundle\Repository\LanguageRepository;
use Chamilo\CoreBundle\Repository\LegalRepository;
use Chamilo\CoreBundle\Repository\MessageRepository;
use Chamilo\CoreBundle\Repository\Node\AccessUrlRepository;
use Chamilo\CoreBundle\Repository\Node\CourseRepository;
@ -561,6 +563,16 @@ class Container
return self::$container->get(CToolIntroRepository::class);
}
public static function getLegalRepository(): LegalRepository
{
return self::$container->get(LegalRepository::class);
}
public static function getLanguageRepository(): LanguageRepository
{
return self::$container->get(LanguageRepository::class);
}
public static function getFormFactory(): FormFactory
{
return self::$container->get('form.factory');

@ -6,8 +6,11 @@ declare(strict_types=1);
namespace Chamilo\CoreBundle\Repository;
use Chamilo\CoreBundle\Entity\Language;
use Chamilo\CoreBundle\Entity\Legal;
use Chamilo\CoreBundle\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Persistence\ManagerRegistry;
use Exception;
@ -58,4 +61,97 @@ class LegalRepository extends ServiceEntityRepository
return $qb->getQuery()->getResult();
}
/**
* Get type of terms and conditions.
* Type 0 is HTML Text
* Type 1 is a link to a different terms and conditions page.
*
* @return mixed The current type of terms and conditions (int) or false on error
*/
public function getTypeOfTermsAndConditions(Legal $legal, Language $language)
{
$qb = $this->createQueryBuilder('l');
$qb->select('l.type')
->where($qb->expr()->eq('l.id', $legal->getId()))
->andWhere($qb->expr()->eq('l.languageId', $language->getId()))
;
return $qb->getQuery()->getResult();
}
/**
* Checks whether we already approved the last version term and condition.
*
* @return bool true if we pass false otherwise
*/
public function checkTermCondition(User $user)
{
if ('true' === api_get_setting('allow_terms_conditions')) {
// Check if exists terms and conditions
if (0 == $this->countTerms()) {
return true;
}
$extraFieldValue = new \ExtraFieldValue('user');
$data = $extraFieldValue->get_values_by_handler_and_field_variable(
$user->getId(),
'legal_accept'
);
if (!empty($data) && isset($data['value']) && !empty($data['value'])) {
$result = $data['value'];
$userConditions = explode(':', $result);
$version = $userConditions[0];
$langId = (int) $userConditions[1];
$realVersion = $this->getLastVersion($langId);
return $version >= $realVersion;
}
return false;
}
return false;
}
/**
* Gets the number of terms and conditions available.
*
* @return int
*/
public function countTerms()
{
$qb = $this->createQueryBuilder('l');
$qb->select('COUNT(l.id)');
return \count($qb->getQuery()->getResult());
}
/**
* Gets the last version of a Term and condition by language.
*
* @return bool | int the version or false if does not exist
*/
public function getLastVersion(int $languageId)
{
$qb = $this->createQueryBuilder('l');
$result = $qb
->select('l.version')
->where(
$qb->expr()->eq('l.language_id', $languageId)
)
->setMaxResults(1)
->orderBy('l.version', Criteria::DESC)
->getQuery()
->getOneOrNullResult()
;
if (!empty($result)) {
$version = explode(':', $result);
return $version[0];
}
return false;
}
}

@ -106,12 +106,12 @@
</div>
<div class="stat-content">
<div class="text-left">
<div class="stat-text">
{{ content }}
</div>
<div class="stat-heading">
{{ name }}
</div>
<div class="stat-text">
{{ content }}
</div>
</div>
</div>
</div>
@ -152,18 +152,12 @@
<dt>{{ 'Timezone'|trans }}</dt>
<dd>{{ user.timezone }}</dd>
{% endif %}
</dl>
{# {% if user.created %}#}
{# <div class="create">{{ user.created }}</div>#}
{# {% endif %}#}
{# {% if user.url_access or user.legal.url_send %}#}
{# <div class="access">#}
{# {{ user.url_access }}#}
{# {{ user.legal.url_send }}#}
{# </div>#}
{# {% endif %}#}
{% if user.legal is defined %}
<dt>{{ 'Legal'|trans }}</dt>
<dd>{{ user.legal.url_send }}</dd>
{% endif %}
</dl>
</div>
{% endautoescape %}
{% endmacro %}

@ -18,6 +18,24 @@ class CourseControllerTest extends WebTestCase
{
use ChamiloTestTrait;
public function testCheckTermsAndConditionJson(): void
{
$client = static::createClient();
$course = $this->createCourse('course 1');
$admin = $this->getUser('admin');
$client->loginUser($admin);
// Test as admin.
$client->request(
'GET',
'/course/'.$course->getId().'/checkLegal.json'
);
$this->assertResponseIsSuccessful();
$this->assertResponseStatusCodeSame(200);
}
public function testIndexJson(): void
{
$client = static::createClient();

Loading…
Cancel
Save