From 24e0a60f532d1d98b5d35557fa57357265245bfb Mon Sep 17 00:00:00 2001 From: christianbeeznst Date: Thu, 29 Aug 2024 22:08:07 -0500 Subject: [PATCH] Learnpath: Enable survey access in LP without invitation - refs #5713 --- public/main/inc/lib/api.lib.php | 7 +- public/main/lp/learnpath.class.php | 24 +++- public/main/lp/lp_view.php | 2 +- public/main/survey/fillsurvey.php | 75 +++++++++--- public/main/survey/survey.lib.php | 79 ++++++++---- public/main/survey/surveyUtil.class.php | 153 +++++++++++++++++++----- 6 files changed, 265 insertions(+), 75 deletions(-) diff --git a/public/main/inc/lib/api.lib.php b/public/main/inc/lib/api.lib.php index 2845901625..db3738294a 100644 --- a/public/main/inc/lib/api.lib.php +++ b/public/main/inc/lib/api.lib.php @@ -2438,7 +2438,12 @@ function api_check_password($password) */ function api_get_session_id() { - return (int) Session::read('sid', 0); + $sessionId = (int) Session::read('sid', 0); + if (empty($sessionId) && !empty($_REQUEST['sid'])) { + $sessionId = (int) $_REQUEST['sid']; + } + + return $sessionId; } /** diff --git a/public/main/lp/learnpath.class.php b/public/main/lp/learnpath.class.php index 1abc7a0e42..d85050acd7 100644 --- a/public/main/lp/learnpath.class.php +++ b/public/main/lp/learnpath.class.php @@ -10,6 +10,7 @@ use Chamilo\CoreBundle\ServiceHelper\ThemeHelper; use Chamilo\CourseBundle\Entity\CLpRelUser; use Chamilo\CoreBundle\Framework\Container; use Chamilo\CoreBundle\Repository\Node\CourseRepository; +use Chamilo\CourseBundle\Entity\CSurvey; use Chamilo\CourseBundle\Repository\CLpRelUserRepository; use Chamilo\CourseBundle\Component\CourseCopy\CourseArchiver; use Chamilo\CourseBundle\Component\CourseCopy\CourseBuilder; @@ -2767,7 +2768,7 @@ class learnpath // then change the lp type to thread it as a normal Chamilo LP not a SCO. if (in_array( $lp_item_type, - ['quiz', 'document', 'final_item', 'link', 'forum', 'thread', 'student_publication'] + ['quiz', 'document', 'final_item', 'link', 'forum', 'thread', 'student_publication', 'survey'] ) ) { $lp_type = CLp::LP_TYPE; @@ -8015,6 +8016,27 @@ class learnpath } return $main_dir_path.'work/work.php?'.api_get_cidreq().'&id='.$rowItem->getPath().'&'.$extraParams; + case TOOL_SURVEY: + + $surveyId = (int) $id; + $repo = Container::getSurveyRepository(); + if (!empty($surveyId)) { + /** @var CSurvey $survey */ + $survey = $repo->find($surveyId); + $autoSurveyLink = SurveyUtil::generateFillSurveyLink( + $survey, + 'auto', + api_get_course_entity($course_id), + $session_id + ); + $lpParams = [ + 'lp_id' => $learningPathId, + 'lp_item_id' => $id_in_path, + 'origin' => 'learnpath', + ]; + + return $autoSurveyLink.'&'.http_build_query($lpParams).'&'.$extraParams; + } } return $link; diff --git a/public/main/lp/lp_view.php b/public/main/lp/lp_view.php index ad57931829..34fb44afe6 100644 --- a/public/main/lp/lp_view.php +++ b/public/main/lp/lp_view.php @@ -565,7 +565,7 @@ $frameReady = Display::getFrameReadyBlock( '#content_id, #content_id_blank', $itemType, 'function () { - var arr = ["link", "sco", "xapi", "quiz", "h5p", "forum"]; + var arr = ["link", "sco", "xapi", "quiz", "h5p", "forum", "survey"]; return $.inArray(olms.lms_item_type, arr) !== -1; }' diff --git a/public/main/survey/fillsurvey.php b/public/main/survey/fillsurvey.php index 287344ab4d..720985bd2e 100644 --- a/public/main/survey/fillsurvey.php +++ b/public/main/survey/fillsurvey.php @@ -60,6 +60,8 @@ if (empty($courseInfo)) { $courseId = $courseInfo['real_id']; $userInfo = api_get_user_info(); $sessionId = isset($_GET['sid']) ? (int) $_GET['sid'] : api_get_session_id(); +$lpItemId = isset($_GET['lp_item_id']) ? (int) $_GET['lp_item_id'] : 0; +$allowSurveyInLp = true; if (!empty($userInfo)) { $interbreadcrumb[] = [ @@ -89,6 +91,16 @@ if (null === $survey) { $surveyId = $survey->getIid(); $invitationCode = $_GET['invitationcode'] ?? null; +$lpItemCondition = ''; +if ($allowSurveyInLp && !empty($lpItemId)) { + $lpItemCondition = " AND c_lp_item_id = $lpItemId"; +} + +$sessionCondition = ''; +if (true === api_get_setting('survey.show_surveys_base_in_sessions')) { + $sessionCondition = api_get_session_condition($sessionId); +} + /*$surveyCode = isset($_GET['scode']) ? Database::escape_string($_GET['scode']) : ''; if ('' != $surveyCode) { // Firstly we check if this survey is ready for anonymous use: @@ -122,7 +134,9 @@ if ('auto' === $invitationCode) { $userid, $surveyCode, $courseId, - $sessionId + $sessionId, + 0, + $lpItemId ); $lastInvitation = current($invitations); @@ -142,7 +156,9 @@ if ('auto' === $invitationCode) { FROM $table_survey_invitation WHERE c_id = $courseId AND - invitation_code = '".Database::escape_string($autoInvitationCode)."'"; + invitation_code = '".Database::escape_string($autoInvitationCode)."' + $sessionCondition + $lpItemCondition"; $result = Database::query($sql); $now = api_get_utc_datetime(); if (0 == Database::num_rows($result)) { @@ -153,7 +169,7 @@ if ('auto' === $invitationCode) { 'invitation_code' => $autoInvitationCode, 'invitation_date' => $now, 'answered' => 0, - 'c_lp_item_id' => 0, + 'c_lp_item_id' => $lpItemId, ]; Database::insert($table_survey_invitation, $params); } @@ -167,7 +183,9 @@ if ('auto' === $invitationCode) { $sql = "SELECT * FROM $table_survey_invitation WHERE c_id = $courseId AND - invitation_code = '".Database::escape_string($invitationCode)."'"; + invitation_code = '".Database::escape_string($invitationCode)."' + $sessionCondition + $lpItemCondition"; $result = Database::query($sql); if (Database::num_rows($result) < 1) { api_not_allowed(true, get_lang('Wrong invitation code')); @@ -256,7 +274,8 @@ if (count($_POST) > 0) { SurveyUtil::remove_answer( $survey_invitation['user_id'], $surveyId, - $survey_question_id + $survey_question_id, + $lpItemId ); foreach ($value as $answer_key => &$answer_value) { @@ -273,7 +292,9 @@ if (count($_POST) > 0) { $survey, $question, $option_id, - $option_value + $option_value, + '', + $lpItemId ); } } else { @@ -298,7 +319,8 @@ if (count($_POST) > 0) { SurveyUtil::remove_answer( $survey_invitation['user_id'], $surveyId, - $survey_question_id + $survey_question_id, + $lpItemId ); SurveyUtil::saveAnswer( @@ -307,7 +329,8 @@ if (count($_POST) > 0) { $question, $value, $option_value, - $other + $other, + $lpItemId ); } } @@ -358,15 +381,24 @@ if (count($_POST) > 0) { SurveyUtil::remove_answer( $survey_invitation['user_id'], $survey_invitation['survey_id'], - $survey_question_id + $survey_question_id, + api_get_course_int_id(), + $lpItemId ); + + $surveyId = (int) $survey_invitation['survey_id']; + $repo = Container::getSurveyRepository(); + $survey = $repo->find($surveyId); + SurveyUtil::saveAnswer( - $survey_invitation['user_id'], - $survey_invitation['survey_id'], + api_get_user_entity($survey_invitation['user_id']), + $survey, $questionList[$survey_question_id], $value, - $option_value + $option_value, + '', + $lpItemId ); } } @@ -398,12 +430,16 @@ if ('' != $survey->getFormFields() && } } - $url = api_get_self().'?cid='.$courseId.'&sid='.$sessionId; + $url = api_get_self().'?'.api_get_cidreq(); $listQueryParams = explode('&', $_SERVER['QUERY_STRING']); foreach ($listQueryParams as $param) { $url .= '&'.Security::remove_XSS($param); } + if (!empty($lpItemId)) { + $url .= '&lp_item_id='.$lpItemId; + } + // We use the same form as in auth/profile.php $form = new FormValidator('profile', 'post', $url); if (api_is_western_name_order()) { @@ -611,10 +647,10 @@ if ($survey->getFormFields() && if (isset($_POST['finish_survey'])) { echo Display::return_message(get_lang('You have finished this survey.'), 'confirm'); echo Security::remove_XSS($survey->getSurveythanks()); - SurveyManager::updateSurveyAnswered($survey, $survey_invitation['user_id']); + SurveyManager::updateSurveyAnswered($survey, $survey_invitation['user_id'], $lpItemId); SurveyUtil::flagSurveyAsAnswered($survey->getCode(), $survey_invitation['c_id']); - if ($courseInfo && !api_is_anonymous()) { + if ($courseInfo && !api_is_anonymous() && 'learnpath' !== api_get_origin()) { echo '

'; echo Display::toolbarButton( get_lang('Return to Course Homepage'), @@ -1179,7 +1215,7 @@ $g_ic = isset($_GET['invitationcode']) ? Security::remove_XSS($_GET['invitationc $g_cr = isset($_GET['cidReq']) ? Security::remove_XSS($_GET['cidReq']) : ''; $p_l = isset($_POST['language']) ? Security::remove_XSS($_POST['language']) : ''; $add_parameters = isset($_GET['user_id']) ? '&user_id='.intval($_GET['user_id']) : ''; -$url = api_get_self().'?cid='.$courseId.'&sid='.$sessionId.$add_parameters. +$url = api_get_self().'?'.api_get_cidreq().$add_parameters. '&course='.$g_c. '&invitationcode='.$g_ic. '&show='.$show. @@ -1189,6 +1225,11 @@ if (!empty($_GET['language'])) { $lang = Security::remove_XSS($_GET['language']); $url .= '&language='.$lang; } + +if (!empty($lpItemId)) { + $url .= '&lp_item_id='.$lpItemId; +} + $form = new FormValidator( 'question', 'post', @@ -1256,7 +1297,7 @@ if (isset($questions) && is_array($questions)) { } $form->addHtml('
'.Security::remove_XSS($question['survey_question']).'
'); - $userAnswerData = SurveyUtil::get_answers_of_question_by_user($question['survey_id'], $question['question_id']); + $userAnswerData = SurveyUtil::get_answers_of_question_by_user($question['survey_id'], $question['question_id'], $lpItemId); $finalAnswer = null; if (!empty($userAnswerData[$user_id])) { diff --git a/public/main/survey/survey.lib.php b/public/main/survey/survey.lib.php index 1e33493eb4..7d2b8fdd20 100644 --- a/public/main/survey/survey.lib.php +++ b/public/main/survey/survey.lib.php @@ -769,7 +769,7 @@ class SurveyManager /** * Updates c_survey.answered: number of people who have taken the survey (=filled at least one question). */ - public static function updateSurveyAnswered(CSurvey $survey, $user) + public static function updateSurveyAnswered(CSurvey $survey, $user, $lpItemId = 0): void { $em = Database::getManager(); $surveyId = $survey->getIid(); @@ -780,6 +780,15 @@ class SurveyManager $em->persist($survey); $em->flush(); + $lpItemCondition = ''; + if (!empty($lpItemId)) { + $lpItemCondition = " AND c_lp_item_id = $lpItemId"; + } + $sessionCondition = ''; + if (true === api_get_configuration_value('show_surveys_base_in_sessions')) { + $sessionCondition = api_get_session_condition($sessionId); + } + $table = Database::get_course_table(TABLE_SURVEY_INVITATION); // Storing that the user has finished the survey. $sql = "UPDATE $table @@ -787,10 +796,11 @@ class SurveyManager answered_at = '".api_get_utc_datetime()."', answered = 1 WHERE - c_id = $courseId AND session_id = $sessionId AND user_id ='".Database::escape_string($user)."' AND - survey_id ='".$surveyId."'"; + survey_id ='".$surveyId."' + $sessionCondition + $lpItemCondition"; Database::query($sql); } @@ -2154,39 +2164,39 @@ class SurveyManager } } - /** - * @param int $userId - * @param string $surveyCode - * @param int $courseId - * @param int $sessionId - * @param int $groupId - * - * @return array|CSurveyInvitation[] - */ public static function getUserInvitationsForSurveyInCourse( - $userId, - $surveyCode, - $courseId, - $sessionId = 0, - $groupId = 0 - ) { + int $userId, + string $surveyCode, + int $courseId, + int $sessionId = 0, + int $groupId = 0, + int $lpItemId = 0 + ): array { + $em = Database::getManager(); $invitationRepo = $em->getRepository(CSurveyInvitation::class); $surveyRepo = $em->getRepository(CSurvey::class); $survey = $surveyRepo->findBy(['code' => $surveyCode]); + $criteria = [ + 'user' => api_get_user_entity($userId), + 'course' => api_get_course_entity($courseId), + 'session' => api_get_session_entity($sessionId), + 'group' => api_get_group_entity($groupId), + 'survey' => $survey, + ]; + + if (is_int($lpItemId) && $lpItemId > 0) { + $criteria['lpItemId'] = $lpItemId; + } + return $invitationRepo->findBy( - [ - 'user' => api_get_user_entity($userId), - 'course' => api_get_course_entity($courseId), - 'session' => api_get_session_entity($sessionId), - 'group' => api_get_group_entity($groupId), - 'survey' => $survey, - ], + $criteria, ['invitationDate' => 'DESC'] ); } + /** * @param array $userInfo * @param int $answered (1 = answered 0 = not answered) @@ -2352,4 +2362,23 @@ class SurveyManager return false; } + + public static function getInvitationsAnswered( + $surveyCode, + $courseId, + $sessionId = 0 + ): array + { + $invitationRepo = Database::getManager()->getRepository(CSurveyInvitation::class); + + return $invitationRepo->findBy( + [ + 'cId' => $courseId, + 'sessionId' => $sessionId, + 'answered' => true, + 'surveyCode' => $surveyCode, + ], + ['invitationDate' => 'DESC'] + ); + } } diff --git a/public/main/survey/surveyUtil.class.php b/public/main/survey/surveyUtil.class.php index 046cae3ed9..796bbb9368 100644 --- a/public/main/survey/surveyUtil.class.php +++ b/public/main/survey/surveyUtil.class.php @@ -78,14 +78,29 @@ class SurveyUtil * * @version January 2007 */ - public static function remove_answer($user, $survey_id, $question_id) + public static function remove_answer($user, $survey_id, $question_id, $course_id, $lpItemId = 0): void { + $sessionId = api_get_session_id(); + $course_id = intval($course_id); + // table definition $table = Database::get_course_table(TABLE_SURVEY_ANSWER); + + $lpItemCondition = ''; + if (!empty($lpItemId)) { + $lpItemCondition = " AND c_lp_item_id = $lpItemId"; + } + $sessionCondition = ''; + if (true === api_get_configuration_value('show_surveys_base_in_sessions')) { + $sessionCondition = api_get_session_condition($sessionId); + } + $sql = "DELETE FROM $table WHERE user = '".Database::escape_string($user)."' AND survey_id = '".intval($survey_id)."' AND - question_id = '".intval($question_id)."'"; + question_id = '".intval($question_id)."' + $sessionCondition + $lpItemCondition"; Database::query($sql); } @@ -95,8 +110,10 @@ class SurveyUtil CSurveyQuestion $question, $optionId, $optionValue, - $otherOption = '' - ) { + $otherOption = '', + $lpItemId = 0 + ): bool { + // Make the survey anonymous if (1 == $survey->getAnonymous()) { $surveyUser = Session::read('surveyuser'); @@ -120,6 +137,7 @@ class SurveyUtil ->setQuestion($question) ->setOptionId($optionId) ->setValue((int) $optionValue) + ->setLpItemId((int) $lpItemId) ->setSessionId($sessionId ?: null) ; @@ -223,10 +241,19 @@ class SurveyUtil self::display_comparative_report(); break; case 'completereport': - echo self::displayCompleteReport($survey); + if (true === api_get_configuration_value('allow_survey_tool_in_lp')) { + $surveysAnswered = SurveyManager::getInvitationsAnswered($survey->getCode(), api_get_course_int_id(), api_get_session_id()); + if (count($surveysAnswered) > 0) { + foreach ($surveysAnswered as $survey) { + echo self::displayCompleteReport($survey, 0, true, true, !$survey->getAnonymous(), $survey->getLpItemId()); + } + } + } else { + echo self::displayCompleteReport($survey, 0, true, true, !$survey->getAnonymous()); + } break; case 'deleteuserreport': - self::delete_user_report($survey, $_GET['user']); + self::delete_user_report($survey->getIid(), $_GET['user']); break; } } @@ -252,9 +279,16 @@ class SurveyUtil $user_id = Database::escape_string($user_id); if (!empty($survey_id) && !empty($user_id)) { + + $sessionCondition = ''; + if (true === api_get_configuration_value('show_surveys_base_in_sessions')) { + $sessionId = api_get_session_id(); + $sessionCondition = api_get_session_condition($sessionId); + } + // delete data from survey_answer by user_id and survey_id $sql = "DELETE FROM $table_survey_answer - WHERE c_id = $course_id AND survey_id = '".$survey_id."' AND user = '".$user_id."'"; + WHERE c_id = $course_id AND survey_id = '".$survey_id."' AND user = '".$user_id."' $sessionCondition"; Database::query($sql); // update field answered from survey_invitation by user_id and survey_id $sql = "UPDATE $table_survey_invitation SET answered = '0' @@ -265,7 +299,7 @@ class SurveyUtil WHERE iid = '".$survey_id."' ) AND - user_id = '".$user_id."'"; + user_id = '".$user_id."' $sessionCondition"; $result = Database::query($sql); } @@ -379,11 +413,17 @@ class SurveyUtil } } + $sessionCondition = ''; + if (true === api_get_configuration_value('show_surveys_base_in_sessions')) { + $sessionId = api_get_session_id(); + $sessionCondition = api_get_session_condition($sessionId); + } + // Getting all the answers of the user $sql = "SELECT * FROM $table_survey_answer WHERE survey_id = '".$surveyId."' AND - user = '".$userId."'"; + user = '".$userId."' $sessionCondition"; $result = Database::query($sql); while ($row = Database::fetch_assoc($result)) { $answers[$row['question_id']][] = $row['option_id']; @@ -514,6 +554,15 @@ class SurveyUtil $surveyId = $survey->getIid(); $action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : ''; $course_id = api_get_course_int_id(); + + $sessionCondition = ''; + if (true === api_get_configuration_value('show_surveys_base_in_sessions')) { + $sessionId = api_get_session_id(); + $sessionCondition = api_get_session_condition($sessionId); + } + + // Database table definitions + $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION); $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION); $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER); @@ -781,7 +830,7 @@ class SurveyUtil WHERE c_id = $course_id AND option_id = '".Database::escape_string($_GET['viewoption'])."' - $sql_restriction"; + $sql_restriction $sessionCondition"; $result = Database::query($sql); echo '