/** * Create new directories. * If in safe_mode, nothing happens. * @return boolean true if created, false otherwise. */ function processNewDir() { if ($this->config['safe_mode']) { return false; } if (isset($_GET['newDir']) && isset($_GET['dir'])) { $newDir = rawurldecode($_GET['newDir']); $dir = rawurldecode($_GET['dir']); $path = Files::makePath($this->getBaseDir(), $dir); $fullpath = Files::makePath($path, Files::escape($newDir)); if (is_dir($fullpath)) { return false; } else { //adding to the DB // now the create_unexisting_directory will create the folder //$result = Files::createFolder($fullpath); global $_course; if (isset($_course) && !empty($_course) && isset($_course['code'])) { //@todo make this str to functions $base_dir = substr($path, 0, strpos($path, '/document/') + 9); // $new_dir = substr($fullpath, strlen($base_dir), -1); // create_unexisting_directory($_course, api_get_user_id(), api_get_session_id(), 0, 0, $base_dir, $new_dir, $newDir); $doc_id = DocumentManager::get_document_id($_course, $new_dir); api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'invisible', api_get_user_id(), null, null, null, null, api_get_session_id()); } else { return Files::createFolder($fullpath); } return true; } } }
/** * @param string $courseCode * @param string $fileName * @return \Symfony\Component\HttpFoundation\BinaryFileResponse */ public function getFileAction($courseCode, $fileName) { $courseInfo = api_get_course_info($courseCode); $sessionId = $this->getRequest()->get('id_session'); $docId = \DocumentManager::get_document_id($courseInfo, "/" . $fileName); $filePath = null; if ($docId) { $isVisible = \DocumentManager::is_visible_by_id($docId, $courseInfo, $sessionId, api_get_user_id()); $documentData = \DocumentManager::get_document_data_by_id($docId, $courseCode); $filePath = $documentData['absolute_path']; event_download($filePath); } if (!api_is_allowed_to_edit() && !$isVisible) { $this->abort(500); } return $this->sendFile($filePath); }
$language_file = array('document'); //require_once '../inc/global.inc.php'; $_SESSION['whereami'] = 'document/createpaint'; $this_section = SECTION_COURSES; require_once 'document.inc.php'; $nameTools = get_lang('PhotoRetouching'); api_protect_course_script(); api_block_anonymous_users(); if (api_get_setting('enabled_support_paint') == 'false') { api_not_allowed(true); } $document_data = DocumentManager::get_document_data_by_id($_GET['id'], api_get_course_id(), true); if (empty($document_data)) { if (api_is_in_group()) { $group_properties = GroupManager::get_group_properties(api_get_group_id()); $document_id = DocumentManager::get_document_id(api_get_course_info(), $group_properties['directory']); $document_data = DocumentManager::get_document_data_by_id($document_id, api_get_course_id()); } } $document_id = $document_data['id']; $dir = $document_data['path']; //$dir = isset($_GET['dir']) ? Security::remove_XSS($_GET['dir']) : Security::remove_XSS($_POST['dir']); $is_allowed_to_edit = api_is_allowed_to_edit(null, true); //path for pixlr save $_SESSION['paint_dir'] = Security::remove_XSS($dir); if ($_SESSION['paint_dir'] == '/') { $_SESSION['paint_dir'] = ''; } $_SESSION['paint_file'] = get_lang('NewImage'); // Please, do not modify this dirname formatting if (strstr($dir, '..')) {
mkdir($filepath . 'css', api_get_permissions_for_new_directories()); $doc_id = FileManager::add_document($_course, $dir . 'css', 'folder', 0, 'css'); api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'FolderCreated', api_get_user_id(), null, null, null, null, $current_session_id); api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'invisible', api_get_user_id(), null, null, null, null, $current_session_id); } if (!is_file($filepath . 'css/frames.css')) { $platform_theme = api_get_setting('stylesheets'); if (file_exists(api_get_path(SYS_CSS_PATH) . 'themes/' . $platform_theme . '/frames.css')) { copy(api_get_path(SYS_CSS_PATH) . 'themes/' . $platform_theme . '/frames.css', $filepath . 'css/frames.css'); $doc_id = FileManager::add_document($_course, $dir . 'css/frames.css', 'file', filesize($filepath . 'css/frames.css'), 'frames.css'); api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'DocumentAdded', api_get_user_id(), null, null, null, null, $current_session_id); api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'invisible', api_get_user_id(), null, null, null, null, $current_session_id); } } // "WHAT'S NEW" notification: update table item_property $document_id = DocumentManager::get_document_id($_course, $file); if ($document_id) { FileManager::update_existing_document($_course, $document_id, $file_size, $read_only_flag); api_item_property_update($_course, TOOL_DOCUMENT, $document_id, 'DocumentUpdated', api_get_user_id(), null, null, null, null, $current_session_id); // Update parent folders FileManager::item_property_update_on_folder($_course, $dir, api_get_user_id()); header('Location: document.php?id=' . $document_data['parent_id']); exit; } else { $msgError = get_lang('Impossible'); } } else { $msgError = get_lang('Impossible'); } } else { if ($document_id) {
/** * Shows a question * * @param int $questionId question id * @param bool $only_questions if true only show the questions, no exercise title * @param bool $origin i.e = learnpath * @param string $current_item current item from the list of questions * @param bool $show_title * @param bool $freeze * @param array $user_choice * @param bool $show_comment * @param bool $exercise_feedback * @param bool $show_answers * */ public static function showQuestion($questionId, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false) { $course_id = api_get_course_int_id(); // Change false to true in the following line to enable answer hinting $debug_mark_answer = $show_answers; // Reads question information if (!($objQuestionTmp = Question::read($questionId))) { // Question not found return false; } if ($exercise_feedback != EXERCISE_FEEDBACK_TYPE_END) { $show_comment = false; } $answerType = $objQuestionTmp->selectType(); $pictureName = $objQuestionTmp->selectPicture(); $s = ''; if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) { // Question is not a hotspot if (!$only_questions) { $questionDescription = $objQuestionTmp->selectDescription(); if ($show_title) { TestCategory::displayCategoryAndTitle($objQuestionTmp->id); echo Display::div($current_item . '. ' . $objQuestionTmp->selectTitle(), array('class' => 'question_title')); } if (!empty($questionDescription)) { echo Display::div($questionDescription, array('class' => 'question_description')); } } if (in_array($answerType, array(FREE_ANSWER, ORAL_EXPRESSION)) && $freeze) { return ''; } echo '<div class="question_options row">'; // construction of the Answer object (also gets all answers details) $objAnswerTmp = new Answer($questionId); $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); $quiz_question_options = Question::readQuestionOption($questionId, $course_id); // For "matching" type here, we need something a little bit special // because the match between the suggestions and the answers cannot be // done easily (suggestions and answers are in the same table), so we // have to go through answers first (elems with "correct" value to 0). $select_items = array(); //This will contain the number of answers on the left side. We call them // suggestions here, for the sake of comprehensions, while the ones // on the right side are called answers $num_suggestions = 0; if (in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE])) { if ($answerType == DRAGGABLE) { $s .= '<div class="col-md-12 ui-widget ui-helper-clearfix"> <div class="clearfix"> <ul class="exercise-draggable-answer ui-helper-reset ui-helper-clearfix">'; } else { $s .= '<div id="drag' . $questionId . '_question" class="drag_question"> <table class="data_table">'; } // Iterate through answers $x = 1; //mark letters for each answer $letter = 'A'; $answer_matching = array(); $cpt1 = array(); for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answerCorrect = $objAnswerTmp->isCorrect($answerId); $numAnswer = $objAnswerTmp->selectAutoId($answerId); if ($answerCorrect == 0) { // options (A, B, C, ...) that will be put into the list-box // have the "correct" field set to 0 because they are answer $cpt1[$x] = $letter; $answer_matching[$x] = $objAnswerTmp->selectAnswerByAutoId($numAnswer); $x++; $letter++; } } $i = 1; $select_items[0]['id'] = 0; $select_items[0]['letter'] = '--'; $select_items[0]['answer'] = ''; foreach ($answer_matching as $id => $value) { $select_items[$i]['id'] = $value['id_auto']; $select_items[$i]['letter'] = $cpt1[$id]; $select_items[$i]['answer'] = $value['answer']; $i++; } $user_choice_array_position = array(); if (!empty($user_choice)) { foreach ($user_choice as $item) { $user_choice_array_position[$item['position']] = $item['answer']; } } $num_suggestions = $nbrAnswers - $x + 1; } elseif ($answerType == FREE_ANSWER) { $fck_content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer'] : null; $form = new FormValidator('free_choice_' . $questionId); $config = array('ToolbarSet' => 'TestFreeAnswer'); $form->addHtmlEditor("choice[" . $questionId . "]", null, false, false, $config); $form->setDefaults(array("choice[" . $questionId . "]" => $fck_content)); $s .= $form->returnForm(); } elseif ($answerType == ORAL_EXPRESSION) { // Add nanog if (api_get_setting('document.enable_nanogong') == 'true') { //@todo pass this as a parameter global $exercise_stat_info, $exerciseId, $exe_id; if (!empty($exercise_stat_info)) { $params = array('exercise_id' => $exercise_stat_info['exe_exo_id'], 'exe_id' => $exercise_stat_info['exe_id'], 'question_id' => $questionId); } else { $params = array('exercise_id' => $exerciseId, 'exe_id' => 'temp_exe', 'question_id' => $questionId); } $nano = new Nanogong($params); echo $nano->show_button(); } $form = new FormValidator('free_choice_' . $questionId); $config = array('ToolbarSet' => 'TestFreeAnswer'); $form->addHtmlEditor("choice[" . $questionId . "]", null, false, false, $config); //$form->setDefaults(array("choice[" . $questionId . "]" => $fck_content)); $s .= $form->returnForm(); } // Now navigate through the possible answers, using the max number of // answers for the question as a limiter $lines_count = 1; // a counter for matching-type answers if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $header = Display::tag('th', get_lang('Options')); foreach ($objQuestionTmp->options as $item) { if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { if (in_array($item, $objQuestionTmp->options)) { $header .= Display::tag('th', get_lang($item)); } else { $header .= Display::tag('th', $item); } } else { $header .= Display::tag('th', $item); } } if ($show_comment) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="table table-hover table-striped">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } if ($show_comment) { if (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION, GLOBAL_MULTIPLE_ANSWER))) { $header = Display::tag('th', get_lang('Options')); if ($exercise_feedback == EXERCISE_FEEDBACK_TYPE_END) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="table table-hover table-striped">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } } $matching_correct_answer = 0; $user_choice_array = array(); if (!empty($user_choice)) { foreach ($user_choice as $item) { $user_choice_array[] = $item['answer']; } } for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answer = $objAnswerTmp->selectAnswer($answerId); $answerCorrect = $objAnswerTmp->isCorrect($answerId); $numAnswer = $objAnswerTmp->selectAutoId($answerId); $comment = $objAnswerTmp->selectComment($answerId); $attributes = array(); // Unique answer if (in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, UNIQUE_ANSWER_IMAGE])) { $input_id = 'choice-' . $questionId . '-' . $answerId; if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } if ($show_comment) { $s .= '<tr><td>'; } if ($answerType == UNIQUE_ANSWER_IMAGE) { if ($show_comment) { if (empty($comment)) { $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image" style="text-align: center">'; } else { $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image col-xs-6 col-sm-12" style="text-align: center">'; } } else { $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image col-xs-6 col-md-3" style="text-align: center">'; } } $answer = Security::remove_XSS($answer, STUDENT); $s .= Display::input('hidden', 'choice2[' . $questionId . ']', '0'); $answer_input = null; if ($answerType == UNIQUE_ANSWER_IMAGE) { $attributes['style'] = 'display: none;'; $answer = '<div class="thumbnail">' . $answer . '</div>'; } $answer_input .= '<label class="radio">'; $answer_input .= Display::input('radio', 'choice[' . $questionId . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($answerType == UNIQUE_ANSWER_IMAGE) { $answer_input .= "</div>"; } if ($show_comment) { $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == GLOBAL_MULTIPLE_ANSWER) { $input_id = 'choice-' . $questionId . '-' . $answerId; $answer = Security::remove_XSS($answer, STUDENT); if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input = '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr><td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); $my_choice[$item[0]] = $item[1]; } } $s .= '<tr>'; $s .= Display::tag('td', $answer); if (!empty($quiz_question_options)) { foreach ($quiz_question_options as $id => $item) { if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($id == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $id, $attributes), array('style' => '')); } } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) { // multiple answers $input_id = 'choice-' . $questionId . '-' . $answerId; if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $answer = Security::remove_XSS($answer, STUDENT); $answer_input = '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input .= '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', 1, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr>'; $s .= '<td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); if (isset($item[1]) && isset($item[0])) { $my_choice[$item[0]] = $item[1]; } } } $answer = Security::remove_XSS($answer, STUDENT); $s .= '<tr>'; $s .= Display::tag('td', $answer); foreach ($objQuestionTmp->options as $key => $item) { if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($key == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $key, $attributes)); } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } elseif ($answerType == FILL_IN_BLANKS) { // display the question, with field empty, for student to fill it, // or filled to display the answer in the Question preview of the exercice/admin.php page $displayForStudent = true; $listAnswerInformations = FillBlanks::getAnswerInfo($answer); $separatorStartRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorstart']); $separatorEndRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorend']); list($answer) = explode('::', $answer); //Correct answers $correctAnswerList = $listAnswerInformations['tabwords']; //Student's answer $studentAnswerList = array(); if (isset($user_choice[0]['answer'])) { $arrayStudentAnswer = FillBlanks::getAnswerInfo($user_choice[0]['answer'], true); $studentAnswerList = $arrayStudentAnswer['studentanswer']; } // If the question must be shown with the answer (in page exercice/admin.php) for teacher preview // set the student-answer to the correct answer if ($debug_mark_answer) { $studentAnswerList = $correctAnswerList; $displayForStudent = false; } if (!empty($correctAnswerList) && !empty($studentAnswerList)) { $answer = ""; for ($i = 0; $i < count($listAnswerInformations["commonwords"]) - 1; $i++) { // display the common word $answer .= $listAnswerInformations["commonwords"][$i]; // display the blank word $correctItem = $listAnswerInformations["tabwords"][$i]; $correctItemRegexp = $correctItem; // replace / with \/ to allow the preg_replace bellow and all the regexp char $correctItemRegexp = FillBlanks::getRegexpProtected($correctItemRegexp); if (isset($studentAnswerList[$i])) { // If student already started this test and answered this question, // fill the blank with his previous answers // may be "" if student viewed the question, but did not fill the blanks $correctItem = $studentAnswerList[$i]; } $attributes["style"] = "width:" . $listAnswerInformations["tabinputsize"][$i] . "px"; $answer .= FillBlanks::getFillTheBlankHtml($separatorStartRegexp, $separatorEndRegexp, $correctItemRegexp, $questionId, $correctItem, $attributes, $answer, $listAnswerInformations, $displayForStudent, $i); } // display the last common word $answer .= $listAnswerInformations["commonwords"][$i]; } else { // display empty [input] with the right width for student to fill it $separatorStartRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorstart']); $separatorEndRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorend']); $answer = ""; for ($i = 0; $i < count($listAnswerInformations["commonwords"]) - 1; $i++) { // display the common words $answer .= $listAnswerInformations["commonwords"][$i]; // display the blank word $attributes["style"] = "width:" . $listAnswerInformations["tabinputsize"][$i] . "px"; $correctItem = $listAnswerInformations["tabwords"][$i]; $correctItemRegexp = $correctItem; // replace / with \/ to allow the preg_replace bellow and all the regexp char $correctItemRegexp = FillBlanks::getRegexpProtected($correctItemRegexp); $answer .= FillBlanks::getFillTheBlankHtml($separatorStartRegexp, $separatorEndRegexp, $correctItemRegexp, $questionId, '', $attributes, $answer, $listAnswerInformations, $displayForStudent, $i); } // display the last common word $answer .= $listAnswerInformations["commonwords"][$i]; } $s .= $answer; } elseif ($answerType == CALCULATED_ANSWER) { /* * In the CALCULATED_ANSWER test * you mustn't have [ and ] in the textarea * you mustn't have @@ in the textarea * the text to find mustn't be empty or contains only spaces * the text to find mustn't contains HTML tags * the text to find mustn't contains char " */ if ($origin !== null) { global $exe_id; $trackAttempts = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); $sql = 'SELECT answer FROM ' . $trackAttempts . ' WHERE exe_id=' . $exe_id . ' AND question_id=' . $questionId; $rsLastAttempt = Database::query($sql); $rowLastAttempt = Database::fetch_array($rsLastAttempt); $answer = $rowLastAttempt['answer']; if (empty($answer)) { $calculatedAnswerId = []; $calculatedAnswerId[$questionId] = mt_rand(1, $nbrAnswers); $answer = $objAnswerTmp->selectAnswer($calculatedAnswerId[$questionId]); Session::write('calculatedAnswerId', $calculatedAnswerId); } } list($answer) = explode('@@', $answer); // $correctAnswerList array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]] api_preg_match_all('/\\[[^]]+\\]/', $answer, $correctAnswerList); // get student answer to display it if student go back to previous calculated answer question in a test if (isset($user_choice[0]['answer'])) { api_preg_match_all('/\\[[^]]+\\]/', $answer, $studentAnswerList); $studentAnswerListTobecleaned = $studentAnswerList[0]; $studentAnswerList = array(); for ($i = 0; $i < count($studentAnswerListTobecleaned); $i++) { $answerCorrected = $studentAnswerListTobecleaned[$i]; $answerCorrected = api_preg_replace('| / <font color="green"><b>.*$|', '', $answerCorrected); $answerCorrected = api_preg_replace('/^\\[/', '', $answerCorrected); $answerCorrected = api_preg_replace('|^<font color="red"><s>|', '', $answerCorrected); $answerCorrected = api_preg_replace('|</s></font>$|', '', $answerCorrected); $answerCorrected = '[' . $answerCorrected . ']'; $studentAnswerList[] = $answerCorrected; } } // If display preview of answer in test view for exemple, set the student answer to the correct answers if ($debug_mark_answer) { // contain the rights answers surronded with brackets $studentAnswerList = $correctAnswerList[0]; } /* Split the response by bracket tabComments is an array with text surrounding the text to find we add a space before and after the answerQuestion to be sure to have a block of text before and after [xxx] patterns so we have n text to find ([xxx]) and n+1 block of texts before, between and after the text to find */ $tabComments = api_preg_split('/\\[[^]]+\\]/', ' ' . $answer . ' '); if (!empty($correctAnswerList) && !empty($studentAnswerList)) { $answer = ""; $i = 0; foreach ($studentAnswerList as $studentItem) { // remove surronding brackets $studentResponse = api_substr($studentItem, 1, api_strlen($studentItem) - 2); $size = strlen($studentItem); $attributes['class'] = self::detectInputAppropriateClass($size); $answer .= $tabComments[$i] . Display::input('text', "choice[{$questionId}][]", $studentResponse, $attributes); $i++; } $answer .= $tabComments[$i]; } else { // display exercise with empty input fields // every [xxx] are replaced with an empty input field foreach ($correctAnswerList[0] as $item) { $size = strlen($item); $attributes['class'] = self::detectInputAppropriateClass($size); $answer = str_replace($item, Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer); } } if ($origin !== null) { $s = $answer; break; } else { $s .= $answer; } } elseif ($answerType == MATCHING) { // matching type, showing suggestions and answers // TODO: replace $answerId by $numAnswer if ($answerCorrect != 0) { // only show elements to be answered (not the contents of // the select boxes, who are corrrect = 0) $s .= '<tr><td width="45%" valign="top">'; $parsed_answer = $answer; //left part questions $s .= '<p class="indent">' . $lines_count . '. ' . $parsed_answer . '</p></td>'; //middle part (matches selects) $s .= '<td width="10%" valign="top" align="center" > <div class="select-matching"> <select name="choice[' . $questionId . '][' . $numAnswer . ']">'; // fills the list-box foreach ($select_items as $key => $val) { // set $debug_mark_answer to true at function start to // show the correct answer with a suffix '-x' $selected = ''; if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selected = 'selected="selected"'; } } //$user_choice_array_position if (isset($user_choice_array_position[$numAnswer]) && $val['id'] == $user_choice_array_position[$numAnswer]) { $selected = 'selected="selected"'; } $s .= '<option value="' . $val['id'] . '" ' . $selected . '>' . $val['letter'] . '</option>'; } // end foreach() $s .= '</select></div></td><td width="5%" class="separate"> </td>'; $s .= '<td width="40%" valign="top" >'; if (isset($select_items[$lines_count])) { $s .= '<div class="text-right"><p class="indent">' . $select_items[$lines_count]['letter'] . '. ' . $select_items[$lines_count]['answer'] . '</p></div>'; } else { $s .= ' '; } $s .= '</td>'; $s .= '</tr>'; $lines_count++; //if the left side of the "matching" has been completely // shown but the right side still has values to show... if ($lines_count - 1 == $num_suggestions) { // if it remains answers to shown at the right side while (isset($select_items[$lines_count])) { $s .= '<tr> <td colspan="2"></td> <td valign="top">'; $s .= '<b>' . $select_items[$lines_count]['letter'] . '.</b> ' . $select_items[$lines_count]['answer']; $s .= "</td>\n </tr>"; $lines_count++; } // end while() } // end if() $matching_correct_answer++; } } elseif ($answerType == DRAGGABLE) { if ($answerCorrect != 0) { $parsed_answer = $answer; /*$lines_count = ''; $data = $objAnswerTmp->getAnswerByAutoId($numAnswer); $data = $objAnswerTmp->getAnswerByAutoId($data['correct']); $lines_count = $data['answer'];*/ $windowId = $questionId . '_' . $lines_count; $s .= '<li class="touch-items" id="' . $windowId . '">'; $s .= Display::div($parsed_answer, ['id' => "window_{$windowId}", 'class' => "window{$questionId}_question_draggable exercise-draggable-answer-option"]); $selectedValue = 0; $draggableSelectOptions = []; foreach ($select_items as $key => $val) { if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selectedValue = $val['id']; } } if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) { $selectedValue = $val['id']; } $draggableSelectOptions[$val['id']] = $val['letter']; } $s .= Display::select("choice[{$questionId}][{$numAnswer}]", $draggableSelectOptions, $selectedValue, ['id' => "window_{$windowId}_select", 'class' => 'select_option', 'style' => 'display: none;'], false); if (!empty($answerCorrect) && !empty($selectedValue)) { $s .= <<<JAVASCRIPT <script> \$(function() { DraggableAnswer.deleteItem( \$('#{$questionId}_{$selectedValue}'), \$('#drop_{$windowId}') ); }); </script> JAVASCRIPT; } if (isset($select_items[$lines_count])) { $s .= Display::div(Display::tag('b', $select_items[$lines_count]['letter']) . $select_items[$lines_count]['answer'], ['id' => "window_{$windowId}_answer", 'style' => 'display: none;']); } else { $s .= ' '; } $lines_count++; if ($lines_count - 1 == $num_suggestions) { while (isset($select_items[$lines_count])) { $s .= Display::tag('b', $select_items[$lines_count]['letter']); $s .= $select_items[$lines_count]['answer']; $lines_count++; } } $matching_correct_answer++; $s .= '</li>'; } } elseif ($answerType == MATCHING_DRAGGABLE) { if ($answerId == 1) { echo $objAnswerTmp->getJs(); } if ($answerCorrect != 0) { $parsed_answer = $answer; $windowId = "{$questionId}_{$lines_count}"; $s .= <<<HTML <tr> <td widht="45%"> <div id="window_{$windowId}" class="window window_left_question window{$questionId}_question"> <strong>{$lines_count}.</strong> {$parsed_answer} </div> </td> <td width="10%"> HTML; $selectedValue = 0; $selectedPosition = 0; $questionOptions = []; $iTempt = 0; foreach ($select_items as $key => $val) { if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selectedValue = $val['id']; $selectedPosition = $iTempt; } } if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) { $selectedValue = $val['id']; $selectedPosition = $iTempt; } $questionOptions[$val['id']] = $val['letter']; $iTempt++; } $s .= Display::select("choice[{$questionId}][{$numAnswer}]", $questionOptions, $selectedValue, ['id' => "window_{$windowId}_select", 'class' => 'hidden'], false); if (!empty($answerCorrect) && !empty($selectedValue)) { // Show connect if is not freeze (question preview) if (!$freeze) { $s .= <<<JAVASCRIPT <script> \$(document).on('ready', function () { jsPlumb.ready(function() { jsPlumb.connect({ source: 'window_{$windowId}', target: 'window_{$questionId}_{$selectedPosition}_answer', endpoint: ['Blank', {radius: 15}], anchors: ['RightMiddle', 'LeftMiddle'], paintStyle: {strokeStyle: '#8A8888', lineWidth: 8}, connector: [ MatchingDraggable.connectorType, {curvines: MatchingDraggable.curviness} ] }); }); }); </script> JAVASCRIPT; } } $s .= <<<HTML </td> <td width="45%"> HTML; if (isset($select_items[$lines_count])) { $s .= <<<HTML <div id="window_{$windowId}_answer" class="window window_right_question"> <strong>{$select_items[$lines_count]['letter']}.</strong> {$select_items[$lines_count]['answer']} </div> HTML; } else { $s .= ' '; } $s .= '</td></tr>'; $lines_count++; if ($lines_count - 1 == $num_suggestions) { while (isset($select_items[$lines_count])) { $s .= <<<HTML <tr> <td colspan="2"></td> <td> <strong>{$select_items[$lines_count]['letter']}</strong> {$select_items[$lines_count]['answer']} </td> </tr> HTML; $lines_count++; } } $matching_correct_answer++; } } } // end for() if ($show_comment) { $s .= '</table>'; } elseif (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE, UNIQUE_ANSWER_NO_OPTION, MULTIPLE_ANSWER_TRUE_FALSE, MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE])) { $s .= '</table>'; } if ($answerType == DRAGGABLE) { $s .= "</ul>"; $s .= "</div>"; //clearfix $counterAnswer = 1; $s .= '<div class="col-md-12"><div class="row">'; for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answerCorrect = $objAnswerTmp->isCorrect($answerId); $windowId = $questionId . '_' . $counterAnswer; if ($answerCorrect) { $s .= Display::div($counterAnswer, ['id' => "drop_{$windowId}", 'class' => 'droppable col-md-2']); $counterAnswer++; } } $s .= '</div>'; // row $s .= '</div>'; // col-md-12 $s .= '</div>'; // col-md-12 ui-widget ui-helper-clearfix } if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) { $s .= '</div>'; //drag_question } $s .= '</div>'; //question_options row // destruction of the Answer object unset($objAnswerTmp); // destruction of the Question object unset($objQuestionTmp); if ($origin != 'export') { echo $s; } else { return $s; } } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) { global $exerciseId, $exe_id; // Question is a HOT_SPOT //checking document/images visibility if (api_is_platform_admin() || api_is_course_admin()) { $course = api_get_course_info(); $doc_id = DocumentManager::get_document_id($course, '/images/' . $pictureName); if (is_numeric($doc_id)) { $images_folder_visibility = api_get_item_visibility($course, 'document', $doc_id, api_get_session_id()); if (!$images_folder_visibility) { //This message is shown only to the course/platform admin if the image is set to visibility = false Display::display_warning_message(get_lang('ChangeTheVisibilityOfTheCurrentImage')); } } } $questionName = $objQuestionTmp->selectTitle(); $questionDescription = $objQuestionTmp->selectDescription(); if ($freeze) { echo "\n <script>\n \$(document).on('ready', function () {\n new " . ($answerType == HOT_SPOT ? "HotspotQuestion" : "DelineationQuestion") . "({\n questionId: {$questionId},\n exerciseId: {$exerciseId},\n selector: '#hotspot-preview-{$questionId}',\n for: 'preview'\n });\n });\n </script>\n <div id=\"hotspot-preview-{$questionId}\"></div>\n "; return; } // Get the answers, make a list $objAnswerTmp = new Answer($questionId); $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); // get answers of hotpost $answers_hotspot = array(); for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answers = $objAnswerTmp->selectAnswerByAutoId($objAnswerTmp->selectAutoId($answerId)); $answers_hotspot[$answers['id']] = $objAnswerTmp->selectAnswer($answerId); } $answerList = ''; if ($answerType != HOT_SPOT_DELINEATION) { $answerList = ' <div class="well well-sm"> <h5 class="page-header">' . get_lang('HotspotZones') . '</h5> <ol> '; if (!empty($answers_hotspot)) { ksort($answers_hotspot); $countAnswers = 1; foreach ($answers_hotspot as $value) { $answerList .= "<li><p>{$countAnswers} - {$value}</p></li>"; $countAnswers++; } } $answerList .= ' </ol> </div> '; } if (!$only_questions) { if ($show_title) { TestCategory::displayCategoryAndTitle($objQuestionTmp->id); echo '<div class="question_title">' . $current_item . '. ' . $questionName . '</div>'; } //@todo I need to the get the feedback type echo <<<HOTSPOT <input type="hidden" name="hidden_hotspot_id" value="{$questionId}" /> <div class="exercise_questions"> {$questionDescription} <div class="row"> HOTSPOT; } $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1'); $s .= "\n <div class=\"col-sm-8 col-md-9\">\n <div class=\"hotspot-image\"></div>\n <script>\n \$(document).on('ready', function () {\n new " . ($answerType == HOT_SPOT_DELINEATION ? 'DelineationQuestion' : 'HotspotQuestion') . "({\n questionId: {$questionId},\n exerciseId: {$exe_id},\n selector: '#question_div_' + {$questionId} + ' .hotspot-image',\n for: 'user'\n });\n });\n </script>\n </div>\n <div class=\"col-sm-4 col-md-3\">\n {$answerList}\n </div>\n "; echo <<<HOTSPOT {$s} </div> </div> HOTSPOT; } return $nbrAnswers; }
/** * @param string $filePath * @param string $path * @param $courseInfo * @param string $whatIfFileExists overwrite|rename * @param null $userId * @param null $groupId * @param null $toUserId * @return bool|path */ public static function addFileToDocumentTool($filePath, $path, $courseInfo, $userId, $whatIfFileExists = 'overwrite', $groupId = null, $toUserId = null) { if (!file_exists($filePath)) { return false; } $fileInfo = pathinfo($filePath); $file = array('name' => $fileInfo['basename'], 'tmp_name' => $filePath, 'size' => filesize($filePath), 'from_file' => true); $course_dir = $courseInfo['path'] . '/document'; $baseWorkDir = api_get_path(SYS_COURSE_PATH) . $course_dir; $filePath = handle_uploaded_document($courseInfo, $file, $baseWorkDir, $path, $userId, $groupId, $toUserId, false, $whatIfFileExists, false); if ($filePath) { return DocumentManager::get_document_id($courseInfo, $filePath); } return false; }
/* INIT SECTION */ $language_file = array('document'); require_once '../inc/global.inc.php'; $_SESSION['whereami'] = 'document/editdraw'; $this_section = SECTION_COURSES; require_once api_get_path(SYS_CODE_PATH) . 'document/document.inc.php'; api_protect_course_script(); api_block_anonymous_users(); $document_data = DocumentManager::get_document_data_by_id($_GET['id'], api_get_course_id(), true); if (empty($document_data)) { api_not_allowed(); } else { $document_id = $document_data['id']; $file_path = $document_data['path']; $dir = dirname($document_data['path']); $parent_id = DocumentManager::get_document_id(api_get_course_info(), $dir); $my_cur_dir_path = Security::remove_XSS($_GET['curdirpath']); } $dir = str_replace('\\', '/', $dir); //and urlencode each url $curdirpath (hack clean $curdirpath under Windows - Bug #3261) /* Constants & Variables */ $current_session_id = api_get_session_id(); $group_id = api_get_group_id(); //path for svg-edit save $_SESSION['draw_dir'] = Security::remove_XSS($dir); if ($_SESSION['draw_dir'] == '/') { $_SESSION['draw_dir'] = ''; } $_SESSION['draw_file'] = basename(Security::remove_XSS($file_path)); $get_file = Security::remove_XSS($file_path); $file = basename($get_file);
} else { $basename_chat = 'messages-' . $date_now; } } if ($reset && $isMaster) { $i = 1; while (file_exists($chat_path . $basename_chat . '-' . $i . '.log.html')) { $i++; } @rename($chat_path . $basename_chat . '.log.html', $chat_path . $basename_chat . '-' . $i . '.log.html'); @fclose(fopen($chat_path . $basename_chat . '.log.html', 'w')); $doc_id = add_document($_course, $basepath_chat . '/' . $basename_chat . '-' . $i . '.log.html', 'file', filesize($chat_path . $basename_chat . '-' . $i . '.log.html'), $basename_chat . '-' . $i . '.log.html'); api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'DocumentAdded', $userId, $group_id, null, null, null, $session_id); api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'invisible', $userId, $group_id, null, null, null, $session_id); item_property_update_on_folder($_course, $basepath_chat, $userId); $doc_id = DocumentManager::get_document_id($_course, $basepath_chat . '/' . $basename_chat . '.log.html'); update_existing_document($_course, $doc_id, 0); } $remove = 0; $content = array(); if (file_exists($chat_path . $basename_chat . '.log.html')) { $content = file($chat_path . $basename_chat . '.log.html'); $nbr_lines = sizeof($content); $remove = $nbr_lines - 100; } if ($remove < 0) { $remove = 0; } array_splice($content, 0, $remove); require 'header_frame.inc.php'; if (isset($_GET['origin']) && $_GET['origin'] == 'whoisonline') {
/** * This function builds a form that asks for the missing images in a html file * maybe we should do this another way? * * @param array $missing_files * @param string $upload_path * @param string $file_name * @return string the form */ function build_missing_files_form($missing_files, $upload_path, $file_name) { // Do we need a / or not? $added_slash = $upload_path == '/' ? '' : '/'; $folder_id = DocumentManager::get_document_id(api_get_course_info(), $upload_path); // Build the form $form = "<p><strong>" . get_lang('MissingImagesDetected') . "</strong></p>" . "<form method=\"post\" action=\"" . api_get_self() . "\" enctype=\"multipart/form-data\">" . "<input type=\"hidden\" name=\"related_file\" value=\"" . $upload_path . $added_slash . $file_name . "\" />" . "<input type=\"hidden\" name=\"upload_path\" value=\"" . $upload_path . "\" />" . "<input type=\"hidden\" name=\"id\" value=\"" . $folder_id . "\" />" . "<table border=\"0\">"; foreach ($missing_files as &$this_img_file_path) { $form .= "<tr>" . "<td>" . basename($this_img_file_path) . " : </td>" . "<td>" . "<input type=\"file\" name=\"img_file[]\"/>" . "<input type=\"hidden\" name=\"img_file_path[]\" value=\"" . $this_img_file_path . "\" />" . "</td>" . "</tr>"; } $form .= "</table>" . "<button type='submit' name=\"cancel_submit_image\" value=\"" . get_lang('Cancel') . "\" class=\"cancel\">" . get_lang('Cancel') . "</button>" . "<button type='submit' name=\"submit_image\" value=\"" . get_lang('Ok') . "\" class=\"save\">" . get_lang('Ok') . "</button>" . "</form>"; return $form; }
/** * Restore documents * * @param int $session_id * @param bool $respect_base_content * @param string $destination_course_code */ public function restore_documents($session_id = 0, $respect_base_content = false, $destination_course_code = '') { $course_info = api_get_course_info($destination_course_code); if ($this->course->has_resources(RESOURCE_DOCUMENT)) { $table = Database::get_course_table(TABLE_DOCUMENT); $resources = $this->course->resources; $path = api_get_path(SYS_COURSE_PATH) . $this->course->destination_path . '/'; foreach ($resources[RESOURCE_DOCUMENT] as $id => $document) { if (empty($document->item_properties[0]['id_session'])) { $my_session_id = 0; } else { $my_session_id = $session_id; } if ($document->file_type == FOLDER) { $visibility = $document->item_properties[0]['visibility']; $new = substr($document->path, 8); $folderList = explode('/', $new); $tempFolder = ''; // Check if the parent path exists. foreach ($folderList as $folder) { $folderToCreate = $tempFolder . $folder; $sysFolderPath = $path . 'document' . $folderToCreate; $tempFolder .= $folder . '/'; if (empty($folderToCreate)) { continue; } $title = basename($sysFolderPath); // File doesn't exist in file system. if (!is_dir($sysFolderPath)) { // Creating directory create_unexisting_directory($course_info, api_get_user_id(), $my_session_id, 0, 0, $path . 'document', $folderToCreate, $title, $visibility); } else { // File exist in file system. $documentData = DocumentManager::get_document_id($course_info, $folderToCreate, $my_session_id); if (empty($documentData)) { /* This means the folder exists in the filesystem but not in the DB, trying to fix it */ add_document($course_info, $folderToCreate, 'folder', 0, $title, null, null, false, null, $my_session_id); } } } } elseif ($document->file_type == DOCUMENT) { //Checking if folder exists in the database otherwise we created it $dir_to_create = dirname($document->path); if (!empty($dir_to_create) && $dir_to_create != 'document' && $dir_to_create != '/') { if (is_dir($path . dirname($document->path))) { $sql = "SELECT id FROM {$table}\n WHERE\n c_id = " . $this->destination_course_id . " AND\n path = '/" . self::DBUTF8escapestring(substr(dirname($document->path), 9)) . "'"; $res = Database::query($sql); if (Database::num_rows($res) == 0) { //continue; $visibility = $document->item_properties[0]['visibility']; $new = '/' . substr(dirname($document->path), 9); $title = str_replace('/', '', $new); // This code fixes the possibility for a file without a directory entry to be $document_id = add_document($course_info, $new, 'folder', 0, $title, null, null, false); api_item_property_update($course_info, TOOL_DOCUMENT, $document_id, 'FolderCreated', $document->item_properties[0]['insert_user_id'], $document->item_properties[0]['to_group_id'], $document->item_properties[0]['to_user_id'], null, null, $my_session_id); } } } if (file_exists($path . $document->path)) { switch ($this->file_option) { case FILE_OVERWRITE: $origin_path = $this->course->backup_path . '/' . $document->path; if (file_exists($origin_path)) { copy($origin_path, $path . $document->path); $sql = "SELECT id FROM {$table}\n WHERE\n c_id = " . $this->destination_course_id . " AND\n path = '/" . self::DBUTF8escapestring(substr($document->path, 9)) . "'"; $res = Database::query($sql); $count = Database::num_rows($res); if ($count == 0) { $params = ['path' => "/" . self::DBUTF8(substr($document->path, 9)), 'c_id' => $this->destination_course_id, 'comment' => self::DBUTF8($document->comment), 'title' => self::DBUTF8($document->title), 'filetype' => self::DBUTF8($document->file_type), 'size' => self::DBUTF8($document->size), 'session_id' => $my_session_id]; $document_id = Database::insert($table, $params); if ($document_id) { $sql = "UPDATE {$table} SET id = iid WHERE iid = {$document_id}"; Database::query($sql); } $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id; api_item_property_update($course_info, TOOL_DOCUMENT, $document_id, 'DocumentAdded', $document->item_properties[0]['insert_user_id'], $document->item_properties[0]['to_group_id'], $document->item_properties[0]['to_user_id'], null, null, $my_session_id); } else { $obj = Database::fetch_object($res); $document_id = $obj->id; $params = ['path' => "/" . self::DBUTF8(substr($document->path, 9)), 'c_id' => $this->destination_course_id, 'comment' => self::DBUTF8($document->comment), 'title' => self::DBUTF8($document->title), 'filetype' => self::DBUTF8($document->file_type), 'size' => self::DBUTF8($document->size), 'session_id' => $my_session_id]; Database::update($table, $params, ['c_id = ? AND path = ?' => [$this->destination_course_id, "/" . self::DBUTF8escapestring(substr($document->path, 9))]]); $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $obj->id; api_item_property_update($course_info, TOOL_DOCUMENT, $obj->id, 'default', $document->item_properties[0]['insert_user_id'], $document->item_properties[0]['to_group_id'], $document->item_properties[0]['to_user_id'], null, null, $my_session_id); } // Replace old course code with the new destination code $file_info = pathinfo($path . $document->path); if (in_array($file_info['extension'], array('html', 'htm'))) { $content = file_get_contents($path . $document->path); if (UTF8_CONVERT) { $content = utf8_encode($content); } $content = DocumentManager::replace_urls_inside_content_html_from_copy_course($content, $this->course->code, $this->course->destination_path, $this->course->backup_path, $this->course->info['path']); file_put_contents($path . $document->path, $content); } $params = ['comment' => self::DBUTF8($document->comment), 'title' => self::DBUTF8($document->title), 'size' => self::DBUTF8($document->size)]; Database::update($table, $params, ['c_id = ? AND id = ?' => [$this->destination_course_id, $document_id]]); } break; case FILE_SKIP: $sql = "SELECT id FROM {$table}\n\t\t\t\t\t\t\t\t WHERE\n\t\t\t\t\t\t\t\t c_id = " . $this->destination_course_id . " AND\n\t\t\t\t\t\t\t\t path='/" . self::DBUTF8escapestring(substr($document->path, 9)) . "'"; $res = Database::query($sql); $obj = Database::fetch_object($res); $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $obj->id; break; case FILE_RENAME: $i = 1; $ext = explode('.', basename($document->path)); if (count($ext) > 1) { $ext = array_pop($ext); $file_name_no_ext = substr($document->path, 0, -(strlen($ext) + 1)); $ext = '.' . $ext; } else { $ext = ''; $file_name_no_ext = $document->path; } $new_file_name = $file_name_no_ext . '_' . $i . $ext; $file_exists = file_exists($path . $new_file_name); while ($file_exists) { $i++; $new_file_name = $file_name_no_ext . '_' . $i . $ext; $file_exists = file_exists($path . $new_file_name); } if (!empty($session_id)) { $document_path = explode('/', $document->path, 3); $course_path = $path; $orig_base_folder = $document_path[1]; $orig_base_path = $course_path . $document_path[0] . '/' . $document_path[1]; if (is_dir($orig_base_path)) { $new_base_foldername = $orig_base_folder; $new_base_path = $orig_base_path; $originalFolderName = Session::read('orig_base_foldername'); if ($originalFolderName != $new_base_foldername) { Session::erase('new_base_foldername'); Session::erase('orig_base_foldername'); Session::erase('new_base_path'); } $folder_exists = file_exists($new_base_path); if ($folder_exists) { Session::write('orig_base_foldername', $new_base_foldername); $x = ''; while ($folder_exists) { $x = $x + 1; $new_base_foldername = $document_path[1] . '_' . $x; $new_base_path = $orig_base_path . '_' . $x; $baseFolder = Session::read('new_base_foldername'); if ($baseFolder == $new_base_foldername) { break; } $folder_exists = file_exists($new_base_path); } Session::write('new_base_foldername', $new_base_foldername); Session::write('new_base_path', $new_base_path); } $sessionVar1 = Session::read('new_base_foldername'); $sessionVar2 = Session::read('new_base_path'); if (isset($sessionVar) && isset($sessionVar2)) { $new_base_foldername = Session::read('new_base_foldername'); $new_base_path = Session::read('new_base_path'); } $dest_document_path = $new_base_path . '/' . $document_path[2]; // e.g: "/var/www/wiener/courses/CURSO4/document/carpeta1_1/subcarpeta1/collaborative.png" $basedir_dest_path = dirname($dest_document_path); // e.g: "/var/www/wiener/courses/CURSO4/document/carpeta1_1/subcarpeta1" $base_path_document = $course_path . $document_path[0]; // e.g: "/var/www/wiener/courses/CURSO4/document" $path_title = '/' . $new_base_foldername . '/' . $document_path[2]; copy_folder_course_session($basedir_dest_path, $base_path_document, $session_id, $course_info, $document, $this->course_origin_id); if (file_exists($course_path . $document->path)) { copy($course_path . $document->path, $dest_document_path); } //Replace old course code with the new destination code see BT#1985 if (file_exists($dest_document_path)) { $file_info = pathinfo($dest_document_path); if (in_array($file_info['extension'], array('html', 'htm'))) { $content = file_get_contents($dest_document_path); if (UTF8_CONVERT) { $content = utf8_encode($content); } $content = DocumentManager::replace_urls_inside_content_html_from_copy_course($content, $this->course->code, $this->course->destination_path, $this->course->backup_path, $this->course->info['path']); file_put_contents($dest_document_path, $content); } } $params = ['path' => self::DBUTF8($path_title), 'c_id' => $this->destination_course_id, 'comment' => self::DBUTF8($document->comment), 'title' => self::DBUTF8(basename($path_title)), 'filetype' => self::DBUTF8($document->file_type), 'size' => self::DBUTF8($document->size), 'session_id' => $my_session_id]; $document_id = Database::insert($table, $params); if ($document_id) { $sql = "UPDATE {$table} SET id = iid WHERE iid = {$document_id}"; Database::query($sql); } $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id; api_item_property_update($course_info, TOOL_DOCUMENT, $document_id, 'DocumentAdded', $document->item_properties[0]['insert_user_id'], $document->item_properties[0]['to_group_id'], $document->item_properties[0]['to_user_id'], null, null, $my_session_id); } else { if (file_exists($path . $document->path)) { copy($path . $document->path, $path . $new_file_name); } //Replace old course code with the new destination code see BT#1985 if (file_exists($path . $new_file_name)) { $file_info = pathinfo($path . $new_file_name); if (in_array($file_info['extension'], array('html', 'htm'))) { $content = file_get_contents($path . $new_file_name); if (UTF8_CONVERT) { $content = utf8_encode($content); } $content = DocumentManager::replace_urls_inside_content_html_from_copy_course($content, $this->course->code, $this->course->destination_path, $this->course->backup_path, $this->course->info['path']); file_put_contents($path . $new_file_name, $content); } } $params = ['path' => "/" . self::DBUTF8escapestring(substr($new_file_name, 9)), 'c_id' => $this->destination_course_id, 'comment' => self::DBUTF8($document->comment), 'title' => self::DBUTF8($document->title), 'filetype' => self::DBUTF8($document->file_type), 'size' => self::DBUTF8($document->size), 'session_id' => $my_session_id]; $document_id = Database::insert($table, $params); if ($document_id) { $sql = "UPDATE {$table} SET id = iid WHERE iid = {$document_id}"; Database::query($sql); $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id; api_item_property_update($course_info, TOOL_DOCUMENT, $document_id, 'DocumentAdded', $document->item_properties[0]['insert_user_id'], $document->item_properties[0]['to_group_id'], $document->item_properties[0]['to_user_id'], null, null, $my_session_id); } } } else { copy($this->course->backup_path . '/' . $document->path, $path . $new_file_name); //Replace old course code with the new destination code see BT#1985 if (file_exists($path . $new_file_name)) { $file_info = pathinfo($path . $new_file_name); if (in_array($file_info['extension'], array('html', 'htm'))) { $content = file_get_contents($path . $new_file_name); if (UTF8_CONVERT) { $content = utf8_encode($content); } $content = DocumentManager::replace_urls_inside_content_html_from_copy_course($content, $this->course->code, $this->course->destination_path, $this->course->backup_path, $this->course->info['path']); file_put_contents($path . $new_file_name, $content); } } $params = ['c_id' => $this->destination_course_id, 'path' => "/" . self::DBUTF8escapestring(substr($new_file_name, 9)), 'comment' => self::DBUTF8($document->comment), 'title' => self::DBUTF8($document->title), 'filetype' => self::DBUTF8($document->file_type), 'size' => self::DBUTF8($document->size), 'session_id' => $my_session_id]; $document_id = Database::insert($table, $params); if ($document_id) { $sql = "UPDATE {$table} SET id = iid WHERE iid = {$document_id}"; Database::query($sql); } $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id; api_item_property_update($course_info, TOOL_DOCUMENT, $document_id, 'DocumentAdded', $document->item_properties[0]['insert_user_id'], $document->item_properties[0]['to_group_id'], $document->item_properties[0]['to_user_id'], null, null, $my_session_id); } break; } // end switch } else { // end if file exists //make sure the source file actually exists if (is_file($this->course->backup_path . '/' . $document->path) && is_readable($this->course->backup_path . '/' . $document->path) && is_dir(dirname($path . $document->path)) && is_writeable(dirname($path . $document->path))) { //echo 'Copying'; copy($this->course->backup_path . '/' . $document->path, $path . $document->path); //Replace old course code with the new destination code see BT#1985 if (file_exists($path . $document->path)) { $file_info = pathinfo($path . $document->path); if (in_array($file_info['extension'], array('html', 'htm'))) { $content = file_get_contents($path . $document->path); if (UTF8_CONVERT) { $content = utf8_encode($content); } $content = DocumentManager::replace_urls_inside_content_html_from_copy_course($content, $this->course->code, $this->course->destination_path, $this->course->backup_path, $this->course->info['path']); file_put_contents($path . $document->path, $content); } } $params = ['c_id' => $this->destination_course_id, 'path' => "/" . self::DBUTF8(substr($document->path, 9)), 'comment' => self::DBUTF8($document->comment), 'title' => self::DBUTF8($document->title), 'filetype' => self::DBUTF8($document->file_type), 'size' => self::DBUTF8($document->size), 'session_id' => $my_session_id]; $document_id = Database::insert($table, $params); if ($document_id) { $sql = "UPDATE {$table} SET id = iid WHERE iid = {$document_id}"; Database::query($sql); } $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id; api_item_property_update($course_info, TOOL_DOCUMENT, $document_id, 'DocumentAdded', $document->item_properties[0]['insert_user_id'], $document->item_properties[0]['to_group_id'], $document->item_properties[0]['to_user_id'], null, null, $my_session_id); } else { //echo 'not Copying'; if (is_file($this->course->backup_path . '/' . $document->path) && is_readable($this->course->backup_path . '/' . $document->path)) { error_log('Course copy generated an ignoreable error while trying to copy ' . $this->course->backup_path . '/' . $document->path . ': file not found'); } if (!is_dir(dirname($path . $document->path))) { error_log('Course copy generated an ignoreable error while trying to copy to ' . dirname($path . $document->path) . ': directory not found'); } if (!is_writeable(dirname($path . $document->path))) { error_log('Course copy generated an ignoreable error while trying to copy to ' . dirname($path . $document->path) . ': directory not writeable'); } } } // end file doesn't exist } } // end for each // Delete sessions for the copy the new folder in session Session::erase('new_base_foldername'); Session::erase('orig_base_foldername'); Session::erase('new_base_path'); } }
$documentPath = $saveDir . '/' . $drawFileName; //add new document to disk file_put_contents($documentPath, $contents); if ($currentTool == 'document/createdraw') { //add document to database $doc_id = add_document($_course, $relativeUrlPath . '/' . $drawFileName, 'file', filesize($documentPath), $title); api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'DocumentAdded', $_user['user_id'], $groupId, null, null, null, $current_session_id); } elseif ($currentTool == 'document/editdraw') { //check path if (!isset($_SESSION['draw_file'])) { api_not_allowed(); //from Chamilo die; } if ($_SESSION['draw_file'] == $drawFileName) { $document_id = DocumentManager::get_document_id($_course, $relativeUrlPath . '/' . $drawFileName); update_existing_document($_course, $document_id, filesize($documentPath), null); api_item_property_update($_course, TOOL_DOCUMENT, $document_id, 'DocumentUpdated', $_user['user_id'], $groupId, null, null, null, $current_session_id); } else { //add a new document $doc_id = add_document($_course, $relativeUrlPath . '/' . $drawFileName, 'file', filesize($documentPath), $title); api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'DocumentAdded', $_user['user_id'], $groupId, null, null, null, $current_session_id); } } //clean sessions and add messages and return to current document list unset($_SESSION['draw_dir']); unset($_SESSION['draw_file']); unset($_SESSION['whereami']); if ($suffix != 'png') { if ($relativeUrlPath == '') { $relativeUrlPath = '/';
/** * Uploads a document * * @param array the $_FILES variable * @param string $path * @param string title * @param string comment * @param int unzip or not the file * @param int if_exists overwrite, rename or warn if exists (default) * @param bool index document (search xapian module) * @param bool print html messages * @return unknown_type */ public static function upload_document($files, $path, $title = null, $comment = null, $unzip = 0, $if_exists = null, $index_document = false, $show_output = false) { $course_info = api_get_course_info(); $course_dir = $course_info['path'] . '/document'; $sys_course_path = api_get_path(SYS_COURSE_PATH); $base_work_dir = $sys_course_path . $course_dir; if (isset($files['file'])) { $upload_ok = FileManager::process_uploaded_file($files['file'], $show_output); if ($upload_ok) { // File got on the server without problems, now process it $new_path = FileManager::handle_uploaded_document($course_info, $files['file'], $base_work_dir, $path, api_get_user_id(), api_get_group_id(), null, $unzip, $if_exists, $show_output); if ($new_path) { $docid = DocumentManager::get_document_id($course_info, $new_path); if (!empty($docid)) { $table_document = Database::get_course_table(TABLE_DOCUMENT); $params = array(); if (!empty($title)) { $params['title'] = FileManager::get_document_title($title); } else { if (isset($if_exists) && $if_exists == 'rename') { $new_path = basename($new_path); $params['title'] = FileManager::get_document_title($new_path); } else { $params['title'] = FileManager::get_document_title($files['file']['name']); } } if (!empty($comment)) { $params['comment'] = trim($comment); } Database::update($table_document, $params, array('id = ? AND c_id = ? ' => array($docid, $course_info['real_id']))); } // Showing message when sending zip files if ($new_path === true && $unzip == 1 && $show_output) { Display::display_confirmation_message(get_lang('UplUploadSucceeded') . '<br />', false); } if ($index_document) { self::index_document($docid, $course_info['code'], null, $_POST['language'], $_REQUEST, $if_exists); } if (!empty($docid) && is_numeric($docid)) { $document_data = self::get_document_data_by_id($docid, $course_info['code']); return $document_data; } } } } return false; }
/** * This recursive function can be used during the upgrade process form older versions of Chamilo * It crawls the given directory, checks if the file is in the DB and adds it if it's not * * @param string $base_work_dir * @param string $current_path, needed for recursivity */ public static function add_all_documents_in_folder_to_database($_course, $user_id, $base_work_dir, $current_path = '', $to_group_id = 0) { $current_session_id = api_get_session_id(); $path = $base_work_dir . $current_path; // Open dir $handle = opendir($path); if (is_dir($path)) { // Run trough while ($file = readdir($handle)) { if ($file == '.' || $file == '..') { continue; } $completepath = "{$path}/{$file}"; // Directory? if (is_dir($completepath)) { $title = self::get_document_title($file); $safe_file = api_replace_dangerous_char($file); @rename($path . '/' . $file, $path . '/' . $safe_file); // If we can't find the file, add it if (!DocumentManager::get_document_id($_course, $current_path . '/' . $safe_file)) { $document_id = self::add_document($_course, $current_path . '/' . $safe_file, 'folder', 0, $title); api_item_property_update($_course, TOOL_DOCUMENT, $document_id, 'DocumentAdded', $user_id, $to_group_id, null, null, null, $current_session_id); //echo $current_path.'/'.$safe_file.' added!<br />'; } // Recursive self::add_all_documents_in_folder_to_database($_course, $user_id, $base_work_dir, $current_path . '/' . $safe_file, $to_group_id); } else { //Rename $safe_file = self::disable_dangerous_file(api_replace_dangerous_char($file, 'strict')); @rename($base_work_dir . $current_path . '/' . $file, $base_work_dir . $current_path . '/' . $safe_file); $document_id = DocumentManager::get_document_id($_course, $current_path . '/' . $safe_file); if (!$document_id) { $title = self::get_document_title($file); $size = filesize($base_work_dir . $current_path . '/' . $safe_file); $document_id = self::add_document($_course, $current_path . '/' . $safe_file, 'file', $size, $title); api_item_property_update($_course, TOOL_DOCUMENT, $document_id, 'DocumentAdded', $user_id, $to_group_id, null, null, null, $current_session_id); //echo $current_path.'/'.$safe_file.' added!<br />'; } else { api_item_property_update($_course, TOOL_DOCUMENT, $document_id, 'DocumentUpdated', $user_id, $to_group_id, null, null, null, $current_session_id); } } } } }
/** * Creates the row of edit icons for a file/folder * * @param string $curdirpath current path (cfr open folder) * @param string $type (file/folder) * @param string $path dbase path of file/folder * @param int $visibility (1/0) * @param int $id dbase id of the document * @return string html img tags with hyperlinks */ function build_edit_icons($document_data, $id, $is_template, $is_read_only = 0, $visibility) { if (isset($_SESSION['_gid'])) { $req_gid = '&gidReq=' . $_SESSION['_gid']; } else { $req_gid = ''; } $document_id = $document_data['id']; $type = $document_data['filetype']; $is_read_only = $document_data['readonly']; $path = $document_data['path']; $parent_id = DocumentManager::get_document_id(api_get_course_info(), dirname($path)); $curdirpath = dirname($document_data['path']); $is_certificate_mode = DocumentManager::is_certificate_mode($path); $curdirpath = urlencode($curdirpath); $extension = pathinfo($path, PATHINFO_EXTENSION); // Build URL-parameters for table-sorting $sort_params = array(); if (isset($_GET['column'])) { $sort_params[] = 'column=' . Security::remove_XSS($_GET['column']); } if (isset($_GET['page_nr'])) { $sort_params[] = 'page_nr=' . Security::remove_XSS($_GET['page_nr']); } if (isset($_GET['per_page'])) { $sort_params[] = 'per_page=' . Security::remove_XSS($_GET['per_page']); } if (isset($_GET['direction'])) { $sort_params[] = 'direction=' . Security::remove_XSS($_GET['direction']); } $sort_params = implode('&', $sort_params); $visibility_icon = $visibility == 0 ? 'invisible' : 'visible'; $visibility_command = $visibility == 0 ? 'set_visible' : 'set_invisible'; $modify_icons = ''; // If document is read only *or* we're in a session and the document // is from a non-session context, hide the edition capabilities if ($is_read_only) { if (api_is_course_admin() || api_is_platform_admin()) { if ($extension == 'svg' && api_browser_support('svg') && api_get_setting('enabled_support_svg') == 'true') { $modify_icons = '<a href="edit_draw.php?' . api_get_cidreq() . '&id=' . $document_id . $req_gid . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } elseif ($extension == 'png' || $extension == 'jpg' || $extension == 'jpeg' || $extension == 'bmp' || $extension == 'gif' || $extension == 'pxd' && api_get_setting('enabled_support_pixlr') == 'true') { $modify_icons = '<a href="edit_paint.php?' . api_get_cidreq() . '&id=' . $document_id . $req_gid . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } else { $modify_icons = '<a href="edit_document.php?' . api_get_cidreq() . '&id=' . $document_id . $req_gid . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } } else { $modify_icons = Display::return_icon('edit_na.png', get_lang('Modify'), '', ICON_SIZE_SMALL); } $modify_icons .= ' ' . Display::return_icon('move_na.png', get_lang('Move'), array(), ICON_SIZE_SMALL); if (api_is_allowed_to_edit() || api_is_platform_admin()) { $modify_icons .= ' ' . Display::return_icon($visibility_icon . '.png', get_lang('VisibilityCannotBeChanged'), '', ICON_SIZE_SMALL); } $modify_icons .= ' ' . Display::return_icon('delete_na.png', get_lang('Delete'), array(), ICON_SIZE_SMALL); } else { //Edit button if (in_array($path, DocumentManager::get_system_folders())) { $modify_icons = Display::return_icon('edit_na.png', get_lang('Modify'), '', ICON_SIZE_SMALL); } elseif ($is_certificate_mode) { // gradebook category doesn't seem to be taken into account $modify_icons = '<a href="edit_document.php?' . api_get_cidreq() . '&id=' . $document_id . $req_gid . '&curdirpath=/certificates">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } else { if (api_get_session_id()) { if ($document_data['session_id'] == api_get_session_id()) { if ($extension == 'svg' && api_browser_support('svg') && api_get_setting('enabled_support_svg') == 'true') { $modify_icons = '<a href="edit_draw.php?' . api_get_cidreq() . '&id=' . $document_id . $req_gid . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } elseif ($extension == 'png' || $extension == 'jpg' || $extension == 'jpeg' || $extension == 'bmp' || $extension == 'gif' || $extension == 'pxd' && api_get_setting('enabled_support_pixlr') == 'true') { $modify_icons = '<a href="edit_paint.php?' . api_get_cidreq() . '&id=' . $document_id . $req_gid . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } else { $modify_icons = '<a href="edit_document.php?' . api_get_cidreq() . '&id=' . $document_id . $req_gid . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } } else { $modify_icons .= ' ' . Display::return_icon('edit_na.png', get_lang('Edit'), array(), ICON_SIZE_SMALL) . '</a>'; } } else { if ($extension == 'svg' && api_browser_support('svg') && api_get_setting('enabled_support_svg') == 'true') { $modify_icons = '<a href="edit_draw.php?' . api_get_cidreq() . '&id=' . $document_id . $req_gid . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } elseif ($extension == 'png' || $extension == 'jpg' || $extension == 'jpeg' || $extension == 'bmp' || $extension == 'gif' || $extension == 'pxd' && api_get_setting('enabled_support_pixlr') == 'true') { $modify_icons = '<a href="edit_paint.php?' . api_get_cidreq() . '&id=' . $document_id . $req_gid . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } else { $modify_icons = '<a href="edit_document.php?' . api_get_cidreq() . '&id=' . $document_id . $req_gid . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } } } //Move button if ($is_certificate_mode || in_array($path, DocumentManager::get_system_folders())) { $modify_icons .= ' ' . Display::return_icon('move_na.png', get_lang('Move'), array(), ICON_SIZE_SMALL) . '</a>'; } else { if (api_get_session_id()) { if ($document_data['session_id'] == api_get_session_id()) { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&id=' . $parent_id . '&move=' . $document_id . $req_gid . '">' . Display::return_icon('move.png', get_lang('Move'), array(), ICON_SIZE_SMALL) . '</a>'; } else { $modify_icons .= ' ' . Display::return_icon('move_na.png', get_lang('Move'), array(), ICON_SIZE_SMALL) . '</a>'; } } else { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&id=' . $parent_id . '&move=' . $document_id . $req_gid . '">' . Display::return_icon('move.png', get_lang('Move'), array(), ICON_SIZE_SMALL) . '</a>'; } } //Visibility button if ($is_certificate_mode) { $modify_icons .= ' ' . Display::return_icon($visibility_icon . '.png', get_lang('VisibilityCannotBeChanged'), array(), ICON_SIZE_SMALL) . '</a>'; } else { if (api_is_allowed_to_edit() || api_is_platform_admin()) { if ($visibility_icon == 'invisible') { $tip_visibility = get_lang('Show'); } else { $tip_visibility = get_lang('Hide'); } $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&id=' . $parent_id . '&' . $visibility_command . '=' . $id . $req_gid . '&' . $sort_params . '">' . Display::return_icon($visibility_icon . '.png', $tip_visibility, '', ICON_SIZE_SMALL) . '</a>'; } } //Delete button if (in_array($path, DocumentManager::get_system_folders())) { $modify_icons .= ' ' . Display::return_icon('delete_na.png', get_lang('ThisFolderCannotBeDeleted'), array(), ICON_SIZE_SMALL); } else { if (isset($_GET['curdirpath']) && $_GET['curdirpath'] == '/certificates' && DocumentManager::get_default_certificate_id(api_get_course_id()) == $id) { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&delete=' . urlencode($path) . $req_gid . '&' . $sort_params . 'delete_certificate_id=' . $id . '" onclick="return confirmation(\'' . basename($path) . '\');">' . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>'; } else { if ($is_certificate_mode) { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&delete=' . urlencode($path) . $req_gid . '&' . $sort_params . '" onclick="return confirmation(\'' . basename($path) . '\');">' . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>'; } else { if (api_get_session_id()) { if ($document_data['session_id'] == api_get_session_id()) { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&delete=' . urlencode($path) . $req_gid . '&' . $sort_params . '" onclick="return confirmation(\'' . basename($path) . '\');">' . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>'; } else { $modify_icons .= ' ' . Display::return_icon('delete_na.png', get_lang('ThisFolderCannotBeDeleted'), array(), ICON_SIZE_SMALL); } } else { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&delete=' . urlencode($path) . $req_gid . '&' . $sort_params . '" onclick="return confirmation(\'' . basename($path) . '\');">' . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>'; } } } } } if ($type == 'file' && ($extension == 'html' || $extension == 'htm')) { if ($is_template == 0) { if (isset($_GET['curdirpath']) && $_GET['curdirpath'] != '/certificates' || !isset($_GET['curdirpath'])) { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&add_as_template=' . $id . $req_gid . '&' . $sort_params . '">' . Display::return_icon('wizard.png', get_lang('AddAsTemplate'), array(), ICON_SIZE_SMALL) . '</a>'; } if (isset($_GET['curdirpath']) && $_GET['curdirpath'] == '/certificates') { //allow attach certificate to course $visibility_icon_certificate = 'nocertificate'; if (DocumentManager::get_default_certificate_id(api_get_course_id()) == $id) { $visibility_icon_certificate = 'certificate'; $certificate = get_lang('DefaultCertificate'); $preview = get_lang('PreviewCertificate'); $is_preview = true; } else { $is_preview = false; $certificate = get_lang('NoDefaultCertificate'); } if (isset($_GET['selectcat'])) { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&selectcat=' . Security::remove_XSS($_GET['selectcat']) . '&set_certificate=' . $id . $req_gid . '&' . $sort_params . '"> ' . Display::return_icon($visibility_icon_certificate . '.png', $certificate) . ' </a>'; if ($is_preview) { $modify_icons .= ' <a target="_blank" href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&set_preview=' . $id . $req_gid . '&' . $sort_params . '" >' . Display::return_icon('preview_view.png', $preview, '', ICON_SIZE_SMALL) . '</a>'; } } } } else { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&remove_as_template=' . $id . $req_gid . '&' . $sort_params . '">' . Display::return_icon('wizard_na.png', get_lang('RemoveAsTemplate'), '', ICON_SIZE_SMALL) . '</a>'; } $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&action=export_to_pdf&id=' . $id . '">' . Display::return_icon('pdf.png', get_lang('Export2PDF'), array(), ICON_SIZE_SMALL) . '</a>'; } return $modify_icons; }
/** * Shows a question * * @param int $questionId question id * @param bool $only_questions if true only show the questions, no exercise title * @param bool $origin i.e = learnpath * @param string $current_item current item from the list of questions * @param bool $show_title * @param bool $freeze * @param array $user_choice * @param bool $show_comment * @param bool $exercise_feedback * @param bool $show_answers * */ function showQuestion($questionId, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false) { // Text direction for the current language $is_ltr_text_direction = api_get_text_direction() != 'rtl'; // Change false to true in the following line to enable answer hinting $debug_mark_answer = $show_answers; //api_is_allowed_to_edit() && false; // Reads question information if (!($objQuestionTmp = Question::read($questionId))) { // Question not found return false; } if ($exercise_feedback != EXERCISE_FEEDBACK_TYPE_END) { $show_comment = false; } $answerType = $objQuestionTmp->selectType(); $pictureName = $objQuestionTmp->selectPicture(); $s = ''; if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) { // Question is not a hotspot if (!$only_questions) { $questionDescription = $objQuestionTmp->selectDescription(); if ($show_title) { Testcategory::displayCategoryAndTitle($objQuestionTmp->id); echo Display::div($current_item . '. ' . $objQuestionTmp->selectTitle(), array('class' => 'question_title')); } if (!empty($questionDescription)) { echo Display::div($questionDescription, array('class' => 'question_description')); } } if (in_array($answerType, array(FREE_ANSWER, ORAL_EXPRESSION)) && $freeze) { return ''; } echo '<div class="question_options">'; // construction of the Answer object (also gets all answers details) $objAnswerTmp = new Answer($questionId); $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); $course_id = api_get_course_int_id(); $quiz_question_options = Question::readQuestionOption($questionId, $course_id); // For "matching" type here, we need something a little bit special // because the match between the suggestions and the answers cannot be // done easily (suggestions and answers are in the same table), so we // have to go through answers first (elems with "correct" value to 0). $select_items = array(); //This will contain the number of answers on the left side. We call them // suggestions here, for the sake of comprehensions, while the ones // on the right side are called answers $num_suggestions = 0; if ($answerType == MATCHING) { $s .= '<table class="data_table">'; // Iterate through answers $x = 1; //mark letters for each answer $letter = 'A'; $answer_matching = array(); $cpt1 = array(); for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answerCorrect = $objAnswerTmp->isCorrect($answerId); $numAnswer = $objAnswerTmp->selectAutoId($answerId); $answer = $objAnswerTmp->selectAnswer($answerId); if ($answerCorrect == 0) { // options (A, B, C, ...) that will be put into the list-box // have the "correct" field set to 0 because they are answer $cpt1[$x] = $letter; $answer_matching[$x] = $objAnswerTmp->selectAnswerByAutoId($numAnswer); $x++; $letter++; } } $i = 1; $select_items[0]['id'] = 0; $select_items[0]['letter'] = '--'; $select_items[0]['answer'] = ''; foreach ($answer_matching as $id => $value) { $select_items[$i]['id'] = $value['id']; $select_items[$i]['letter'] = $cpt1[$id]; $select_items[$i]['answer'] = $value['answer']; $i++; } $user_choice_array_position = array(); if (!empty($user_choice)) { foreach ($user_choice as $item) { $user_choice_array_position[$item['position']] = $item['answer']; } } $num_suggestions = $nbrAnswers - $x + 1; } elseif ($answerType == FREE_ANSWER) { $fck_content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer'] : null; $oFCKeditor = new FCKeditor("choice[" . $questionId . "]"); $oFCKeditor->ToolbarSet = 'TestFreeAnswer'; $oFCKeditor->Width = '100%'; $oFCKeditor->Height = '200'; $oFCKeditor->Value = $fck_content; $s .= $oFCKeditor->CreateHtml(); } elseif ($answerType == ORAL_EXPRESSION) { //Add nanog if (api_get_setting('enable_nanogong') == 'true') { require_once api_get_path(LIBRARY_PATH) . 'nanogong.lib.php'; //@todo pass this as a parameter global $exercise_stat_info, $exerciseId, $exe_id; if (!empty($exercise_stat_info)) { $params = array('exercise_id' => $exercise_stat_info['exe_exo_id'], 'exe_id' => $exercise_stat_info['exe_id'], 'question_id' => $questionId); } else { $params = array('exercise_id' => $exerciseId, 'exe_id' => 'temp_exe', 'question_id' => $questionId); } $nano = new Nanogong($params); echo $nano->show_button(); } $oFCKeditor = new FCKeditor("choice[" . $questionId . "]"); $oFCKeditor->ToolbarSet = 'TestFreeAnswer'; $oFCKeditor->Width = '100%'; $oFCKeditor->Height = '150'; $oFCKeditor->ToolbarStartExpanded = false; $oFCKeditor->Value = ''; $s .= $oFCKeditor->CreateHtml(); } // Now navigate through the possible answers, using the max number of // answers for the question as a limiter $lines_count = 1; // a counter for matching-type answers if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $header = Display::tag('th', get_lang('Options')); foreach ($objQuestionTmp->options as $item) { if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { if (in_array($item, $objQuestionTmp->options)) { $header .= Display::tag('th', get_lang($item)); } else { $header .= Display::tag('th', $item); } } else { $header .= Display::tag('th', $item); } } if ($show_comment) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="data_table">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } if ($show_comment) { if (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, GLOBAL_MULTIPLE_ANSWER))) { $header = Display::tag('th', get_lang('Options')); if ($exercise_feedback == EXERCISE_FEEDBACK_TYPE_END) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="data_table">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } } $matching_correct_answer = 0; $user_choice_array = array(); if (!empty($user_choice)) { foreach ($user_choice as $item) { $user_choice_array[] = $item['answer']; } } for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answer = $objAnswerTmp->selectAnswer($answerId); $answerCorrect = $objAnswerTmp->isCorrect($answerId); $numAnswer = $objAnswerTmp->selectAutoId($answerId); $comment = $objAnswerTmp->selectComment($answerId); $attributes = array(); // Unique answer if ($answerType == UNIQUE_ANSWER || $answerType == UNIQUE_ANSWER_NO_OPTION) { $input_id = 'choice-' . $questionId . '-' . $answerId; if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $answer = Security::remove_XSS($answer, STUDENT); $s .= Display::input('hidden', 'choice2[' . $questionId . ']', '0'); $answer_input = '<label class="radio">'; $answer_input .= Display::input('radio', 'choice[' . $questionId . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr><td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == GLOBAL_MULTIPLE_ANSWER) { $input_id = 'choice-' . $questionId . '-' . $answerId; $answer = Security::remove_XSS($answer, STUDENT); if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input = '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr><td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); $my_choice[$item[0]] = $item[1]; } } $s .= '<tr>'; $s .= Display::tag('td', $answer); if (!empty($quiz_question_options)) { foreach ($quiz_question_options as $id => $item) { if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($id == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $id, $attributes), array('style' => '')); } } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) { // multiple answers $input_id = 'choice-' . $questionId . '-' . $answerId; if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $answer = Security::remove_XSS($answer, STUDENT); $answer_input = '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input .= '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', 1, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr>'; $s .= '<td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); $my_choice[$item[0]] = $item[1]; } } $answer = Security::remove_XSS($answer, STUDENT); $s .= '<tr>'; $s .= Display::tag('td', $answer); foreach ($objQuestionTmp->options as $key => $item) { if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($key == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $key, $attributes)); } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } elseif ($answerType == FILL_IN_BLANKS) { /* * In the FILL_IN_BLANKS test * you mustn't have [ and ] in the textarea * you mustn't have :: in the textarea * the text to find mustn't be empty or contains only spaces * the text to find mustn't contains HTML tags * the text to find mustn't contains char " */ list($answer) = explode('::', $answer); // $correct_answer_list array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]] api_preg_match_all('/\\[[^]]+\\]/', $answer, $correct_answer_list); // get student answer to display it if student go back to previous fillBlank answer question in a test if (isset($user_choice[0]['answer'])) { api_preg_match_all('/\\[[^]]+\\]/', $user_choice[0]['answer'], $student_answer_list); $student_answer_list_tobecleaned = $student_answer_list[0]; $student_answer_list = array(); // here we got the student answer in a test // let's clean up the results /* Array ( [0] => Array ( [0] => [<font color="red"><s>yer</s></font> / <font color="green"><b>ici</b></font>] [1] => [<font color="red"><s>plop</s></font> / <font color="green"><b>/p</b></font>] ) ) */ for ($i = 0; $i < count($student_answer_list_tobecleaned); $i++) { $answer_corrected = $student_answer_list_tobecleaned[$i]; /* * we got if student answer is wrong * [<font color="red"><s>rrr</s></font> / <font color="green"><b>/p</b></font>] * or if student answer is good * [plop / <font color="green"><b>plop</b></font>] * or if student didn't answer [] */ $answer_corrected = api_preg_replace('| / <font color="green"><b>.*$|', '', $answer_corrected); /* * we got [<font color="red"><s>rrr</s></font> or [plop or [ */ $answer_corrected = api_preg_replace('/^\\[/', '', $answer_corrected); /* * we got <font color="red"><s>rrr</s></font> or plop * non breakable spaces from /main/exercice/exercise.class.php have been removed l 2391 and l 2370 */ $answer_corrected = api_preg_replace('|^<font color="red"><s>|', '', $answer_corrected); $answer_corrected = api_preg_replace('|</s></font>$|', '', $answer_corrected); $answer_corrected = '[' . $answer_corrected . ']'; /* * we got [rrr] or [plop] or [] */ $student_answer_list[] = $answer_corrected; } } // If display preview of answer in test view for exemple, set the student answer to the correct answers if ($debug_mark_answer) { // contain the rights answers surronded with brackets $student_answer_list = $correct_answer_list[0]; } /* Split the response by bracket tab_comments is an array with text surrounding the text to find we add a space before and after the answer_question to be sure to have a block of text before and after [xxx] patterns so we have n text to find ([xxx]) and n+1 block of texts before, between and after the text to find */ $tab_comments = api_preg_split('/\\[[^]]+\\]/', ' ' . $answer . ' '); if (!empty($correct_answer_list) && !empty($student_answer_list)) { $answer = ""; $i = 0; foreach ($student_answer_list as $student_item) { // remove surronding brackets $student_response = api_substr($student_item, 1, api_strlen($student_item) - 2); $size = strlen($student_item); $attributes['class'] = detectInputAppropriateClass($size); $answer .= $tab_comments[$i] . Display::input('text', "choice[{$questionId}][]", $student_response, $attributes); $i++; } $answer .= $tab_comments[$i]; } else { // display exercise with empty input fields // every [xxx] are replaced with an empty input field foreach ($correct_answer_list[0] as $item) { $size = strlen($item); $attributes['class'] = detectInputAppropriateClass($size); $answer = str_replace($item, Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer); } /*$answer = api_preg_replace( '/\[[^]]+\]/', Display::input( 'text', "choice[$questionId][]", '', $attributes ), $answer);*/ } $s .= $answer; } elseif ($answerType == CALCULATED_ANSWER) { /* * In the CALCULATED_ANSWER test * you mustn't have [ and ] in the textarea * you mustn't have @@ in the textarea * the text to find mustn't be empty or contains only spaces * the text to find mustn't contains HTML tags * the text to find mustn't contains char " */ if ($origin !== null) { global $exe_id; $trackAttempts = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); $sqlTrackAttempt = 'SELECT answer FROM ' . $trackAttempts . ' WHERE exe_id=' . $exe_id . ' AND question_id=' . $questionId; $rsLastAttempt = Database::query($sqlTrackAttempt); $rowLastAttempt = Database::fetch_array($rsLastAttempt); $answer = $rowLastAttempt['answer']; if (empty($answer)) { $_SESSION['calculatedAnswerId'][$questionId] = mt_rand(1, $nbrAnswers); $answer = $objAnswerTmp->selectAnswer($_SESSION['calculatedAnswerId'][$questionId]); } } list($answer) = explode('@@', $answer); // $correctAnswerList array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]] api_preg_match_all('/\\[[^]]+\\]/', $answer, $correctAnswerList); // get student answer to display it if student go back to previous calculated answer question in a test if (isset($user_choice[0]['answer'])) { api_preg_match_all('/\\[[^]]+\\]/', $answer, $studentAnswerList); $studentAnswerListTobecleaned = $studentAnswerList[0]; $studentAnswerList = array(); for ($i = 0; $i < count($studentAnswerListTobecleaned); $i++) { $answerCorrected = $studentAnswerListTobecleaned[$i]; $answerCorrected = api_preg_replace('| / <font color="green"><b>.*$|', '', $answerCorrected); $answerCorrected = api_preg_replace('/^\\[/', '', $answerCorrected); $answerCorrected = api_preg_replace('|^<font color="red"><s>|', '', $answerCorrected); $answerCorrected = api_preg_replace('|</s></font>$|', '', $answerCorrected); $answerCorrected = '[' . $answerCorrected . ']'; $studentAnswerList[] = $answerCorrected; } } // If display preview of answer in test view for exemple, set the student answer to the correct answers if ($debug_mark_answer) { // contain the rights answers surronded with brackets $studentAnswerList = $correctAnswerList[0]; } /* Split the response by bracket tabComments is an array with text surrounding the text to find we add a space before and after the answerQuestion to be sure to have a block of text before and after [xxx] patterns so we have n text to find ([xxx]) and n+1 block of texts before, between and after the text to find */ $tabComments = api_preg_split('/\\[[^]]+\\]/', ' ' . $answer . ' '); if (!empty($correctAnswerList) && !empty($studentAnswerList)) { $answer = ""; $i = 0; foreach ($studentAnswerList as $studentItem) { // remove surronding brackets $studentResponse = api_substr($studentItem, 1, api_strlen($studentItem) - 2); $size = strlen($studentItem); $attributes['class'] = detectInputAppropriateClass($size); $answer .= $tabComments[$i] . Display::input('text', "choice[{$questionId}][]", $studentResponse, $attributes); $i++; } $answer .= $tabComments[$i]; } else { // display exercise with empty input fields // every [xxx] are replaced with an empty input field foreach ($correctAnswerList[0] as $item) { $size = strlen($item); $attributes['class'] = detectInputAppropriateClass($size); $answer = str_replace($item, Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer); } } if ($origin !== null) { $s = $answer; break; } else { $s .= $answer; } } elseif ($answerType == MATCHING) { // matching type, showing suggestions and answers // TODO: replace $answerId by $numAnswer if ($answerCorrect != 0) { // only show elements to be answered (not the contents of // the select boxes, who are corrrect = 0) $s .= '<tr><td width="45%" valign="top">'; $parsed_answer = $answer; //left part questions $s .= ' <span style="float:left; width:8%;"><b>' . $lines_count . '</b>. </span> <span style="float:left; width:92%;">' . $parsed_answer . '</span></td>'; //middle part (matches selects) $s .= '<td width="10%" valign="top" align="center"> <select name="choice[' . $questionId . '][' . $numAnswer . ']">'; // fills the list-box foreach ($select_items as $key => $val) { // set $debug_mark_answer to true at function start to // show the correct answer with a suffix '-x' $selected = ''; if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selected = 'selected="selected"'; } } //$user_choice_array_position if (isset($user_choice_array_position[$numAnswer]) && $val['id'] == $user_choice_array_position[$numAnswer]) { $selected = 'selected="selected"'; } /*if (isset($user_choice_array[$matching_correct_answer]) && $val['id'] == $user_choice_array[$matching_correct_answer]['answer']) { $selected = 'selected="selected"'; }*/ $s .= '<option value="' . $val['id'] . '" ' . $selected . '>' . $val['letter'] . '</option>'; } // end foreach() $s .= '</select></td>'; $s .= '<td width="45%" valign="top" >'; if (isset($select_items[$lines_count])) { $s .= '<span style="float:left; width:5%;"><b>' . $select_items[$lines_count]['letter'] . '.</b></span>' . '<span style="float:left; width:95%;">' . $select_items[$lines_count]['answer'] . '</span>'; } else { $s .= ' '; } $s .= '</td>'; $s .= '</tr>'; $lines_count++; //if the left side of the "matching" has been completely // shown but the right side still has values to show... if ($lines_count - 1 == $num_suggestions) { // if it remains answers to shown at the right side while (isset($select_items[$lines_count])) { $s .= '<tr> <td colspan="2"></td> <td valign="top">'; $s .= '<b>' . $select_items[$lines_count]['letter'] . '.</b> ' . $select_items[$lines_count]['answer']; $s .= "</td>\n \t\t\t\t\t\t</tr>"; $lines_count++; } // end while() } // end if() $matching_correct_answer++; } } } // end for() if ($show_comment) { $s .= '</table>'; } else { if ($answerType == MATCHING || $answerType == UNIQUE_ANSWER_NO_OPTION || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $s .= '</table>'; } } $s .= '</div>'; // destruction of the Answer object unset($objAnswerTmp); // destruction of the Question object unset($objQuestionTmp); if ($origin != 'export') { echo $s; } else { return $s; } } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) { // Question is a HOT_SPOT //checking document/images visibility if (api_is_platform_admin() || api_is_course_admin()) { require_once api_get_path(LIBRARY_PATH) . 'document.lib.php'; $course = api_get_course_info(); $doc_id = DocumentManager::get_document_id($course, '/images/' . $pictureName); if (is_numeric($doc_id)) { $images_folder_visibility = api_get_item_visibility($course, 'document', $doc_id, api_get_session_id()); if (!$images_folder_visibility) { //This message is shown only to the course/platform admin if the image is set to visibility = false Display::display_warning_message(get_lang('ChangeTheVisibilityOfTheCurrentImage')); } } } $questionName = $objQuestionTmp->selectTitle(); $questionDescription = $objQuestionTmp->selectDescription(); if ($freeze) { echo Display::img($objQuestionTmp->selectPicturePath()); return; } // Get the answers, make a list $objAnswerTmp = new Answer($questionId); $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); // get answers of hotpost $answers_hotspot = array(); for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answers = $objAnswerTmp->selectAnswerByAutoId($objAnswerTmp->selectAutoId($answerId)); $answers_hotspot[$answers['id']] = $objAnswerTmp->selectAnswer($answerId); } // display answers of hotpost order by id $answer_list = '<div style="padding: 10px; margin-left: 0px; border: 1px solid #A4A4A4; height: 408px; width: 200px;"><b>' . get_lang('HotspotZones') . '</b><dl>'; if (!empty($answers_hotspot)) { ksort($answers_hotspot); foreach ($answers_hotspot as $key => $value) { $answer_list .= '<dt>' . $key . '.- ' . $value . '</dt><br />'; } } $answer_list .= '</dl></div>'; if ($answerType == HOT_SPOT_DELINEATION) { $answer_list = ''; $swf_file = 'hotspot_delineation_user'; $swf_height = 405; } else { $swf_file = 'hotspot_user'; $swf_height = 436; } if (!$only_questions) { if ($show_title) { Testcategory::displayCategoryAndTitle($objQuestionTmp->id); echo '<div class="question_title">' . $current_item . '. ' . $questionName . '</div>'; } //@todo I need to the get the feedback type echo '<input type="hidden" name="hidden_hotspot_id" value="' . $questionId . '" />'; echo '<table class="exercise_questions" > <tr> <td valign="top" colspan="2">'; echo $questionDescription; echo '</td></tr>'; } $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1'); $s .= '<script type="text/javascript" src="../plugin/hotspot/JavaScriptFlashGateway.js"></script> <script src="../plugin/hotspot/hotspot.js" type="text/javascript" ></script> <script type="text/javascript"> <!-- // Globals // Major version of Flash required var requiredMajorVersion = 7; // Minor version of Flash required var requiredMinorVersion = 0; // Minor version of Flash required var requiredRevision = 0; // the version of javascript supported var jsVersion = 1.0; // --> </script> <script language="VBScript" type="text/vbscript"> <!-- // Visual basic helper required to detect Flash Player ActiveX control version information Function VBGetSwfVer(i) on error resume next Dim swControl, swVersion swVersion = 0 set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i)) if (IsObject(swControl)) then swVersion = swControl.GetVariable("$version") end if VBGetSwfVer = swVersion End Function // --> </script> <script language="JavaScript1.1" type="text/javascript"> <!-- // Detect Client Browser type var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; jsVersion = 1.1; // JavaScript helper required to detect Flash Player PlugIn version information function JSGetSwfVer(i) { // NS/Opera version >= 3 check for Flash plugin in plugin array if (navigator.plugins != null && navigator.plugins.length > 0) { if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; descArray = flashDescription.split(" "); tempArrayMajor = descArray[2].split("."); versionMajor = tempArrayMajor[0]; versionMinor = tempArrayMajor[1]; if ( descArray[3] != "" ) { tempArrayMinor = descArray[3].split("r"); } else { tempArrayMinor = descArray[4].split("r"); } versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0; flashVer = versionMajor + "." + versionMinor + "." + versionRevision; } else { flashVer = -1; } } // MSN/WebTV 2.6 supports Flash 4 else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; // WebTV 2.5 supports Flash 3 else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; // older WebTV supports Flash 2 else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; // Can\'t detect in all other cases else { flashVer = -1; } return flashVer; } // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) { reqVer = parseFloat(reqMajorVer + "." + reqRevision); // loop backwards through the versions until we find the newest version for (i=25;i>0;i--) { if (isIE && isWin && !isOpera) { versionStr = VBGetSwfVer(i); } else { versionStr = JSGetSwfVer(i); } if (versionStr == -1 ) { return false; } else if (versionStr != 0) { if(isIE && isWin && !isOpera) { tempArray = versionStr.split(" "); tempString = tempArray[1]; versionArray = tempString .split(","); } else { versionArray = versionStr.split("."); } versionMajor = versionArray[0]; versionMinor = versionArray[1]; versionRevision = versionArray[2]; versionString = versionMajor + "." + versionRevision; // 7.0r24 == 7.24 versionNum = parseFloat(versionString); // is the major.revision >= requested major.revision AND the minor version >= requested minor if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) { return true; } else { return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false ); } } } } // --> </script>'; $s .= '<tr><td valign="top" colspan="2" width="520"><table><tr><td width="520"> <script> <!-- // Version check based upon the values entered above in "Globals" var hasReqestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision); // Check to see if the version meets the requirements for playback if (hasReqestedVersion) { // if we\'ve detected an acceptable version var oeTags = \'<object type="application/x-shockwave-flash" data="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" width="600" height="' . $swf_height . '">\' + \'<param name="wmode" value="transparent">\' + \'<param name="movie" value="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" />\' + \'<\\/object>\'; document.write(oeTags); // embed the Flash Content SWF when all tests are passed } else { // flash is too old or we can\'t detect the plugin var alternateContent = "Error<br \\/>" + "Hotspots requires Macromedia Flash 7.<br \\/>" + "<a href=\\"http://www.macromedia.com/go/getflash/\\">Get Flash<\\/a>"; document.write(alternateContent); // insert non-flash content } // --> </script> </td> <td valign="top" align="left">' . $answer_list . '</td></tr> </table> </td></tr>'; echo $s; echo '</table>'; } return $nbrAnswers; }
} elseif (is_file($full_old_path)) { $old_path = substr($full_old_path, strlen($mainPath) - strlen($full_old_path) - 1); if (!empty($group_properties['directory'])) { $old_path = $group_properties['directory'] . $old_path; //get Chamilo } $new_path = $chamiloFolder; //sample /images/book_highlight.jpg //update documents $dbTable = Database::get_course_table(TABLE_DOCUMENT); //Chamilo update_db_info('update', $old_path, $new_path); //Chamilo //update items $curdirpath = $new_path; $doc_id = DocumentManager::get_document_id($_course, $curdirpath); $current_session_id = api_get_session_id(); api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'DocumentMoved', api_get_user_id(), $to_group_id, null, null, null, $current_session_id); } } else { $current_session_id = api_get_session_id(); if ($tem['type'] == "folder") { //add to database the first folder to target $doc_id = add_document($_course, $chamiloFolder, 'folder', $chamiloFileSize, $chamiloFile); //get Chamilo api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'FolderCreated', api_get_user_id(), $to_group_id, null, null, null, $current_session_id); //get Chamilo // add to database inside subdirectories and files $course_dir = $_course['path'] . "/document"; //get Chamilo $sys_course_path = api_get_path(SYS_COURSE_PATH);
/** * @param string $message * @param array $_course * @param int $group_id * @param int $session_id * @param bool $preview */ function saveMessage($message, $userId, $_course, $session_id, $group_id, $preview = true) { $userInfo = api_get_user_info($userId); $fullName = $userInfo['complete_name']; $isMaster = (bool) api_is_course_admin(); $document_path = api_get_path(SYS_COURSE_PATH) . $_course['path'] . '/document'; if (!empty($group_id)) { $group_info = GroupManager::get_group_properties($group_id); $basepath_chat = $group_info['directory'] . '/chat_files'; } else { $basepath_chat = '/chat_files'; } $chat_path = $document_path . $basepath_chat . '/'; if (!is_dir($chat_path)) { if (is_file($chat_path)) { @unlink($chat_path); } } $date_now = date('Y-m-d'); $message = trim($message); $timeNow = date('d/m/y H:i:s'); if (!empty($group_id)) { $basename_chat = 'messages-' . $date_now . '_gid-' . $group_id; } elseif (!empty($session_id)) { $basename_chat = 'messages-' . $date_now . '_sid-' . $session_id; } else { $basename_chat = 'messages-' . $date_now; } if (!api_is_anonymous()) { if (!empty($message)) { Emojione\Emojione::$imagePathPNG = api_get_path(WEB_LIBRARY_PATH) . 'javascript/emojione/png/'; Emojione\Emojione::$ascii = true; // Parsing emojis $message = Emojione\Emojione::toImage($message); // Parsing text to understand markdown (code highlight) $message = MarkdownExtra::defaultTransform($message); // Security XSS $message = Security::remove_XSS($message); if ($preview == true) { return $message; } if (!file_exists($chat_path . $basename_chat . '.log.html')) { $doc_id = add_document($_course, $basepath_chat . '/' . $basename_chat . '.log.html', 'file', 0, $basename_chat . '.log.html'); api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'DocumentAdded', $userId, $group_id, null, null, null, $session_id); api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'invisible', $userId, $group_id, null, null, null, $session_id); item_property_update_on_folder($_course, $basepath_chat, $userId); } else { $doc_id = DocumentManager::get_document_id($_course, $basepath_chat . '/' . $basename_chat . '.log.html'); } $fp = fopen($chat_path . $basename_chat . '.log.html', 'a'); $userPhoto = Usermanager::getUserPicture($userId, USER_IMAGE_SIZE_MEDIUM); $filePhoto = '<img class="chat-image" src="' . $userPhoto . '"/>'; if ($isMaster) { fputs($fp, '<div class="message-teacher"><div class="content-message"><div class="chat-message-block-name">' . $fullName . '</div><div class="chat-message-block-content">' . $message . '</div><div class="message-date">' . $timeNow . '</div></div><div class="icon-message"></div>' . $filePhoto . '</div>' . "\n"); } else { fputs($fp, '<div class="message-student">' . $filePhoto . '<div class="icon-message"></div><div class="content-message"><div class="chat-message-block-name">' . $fullName . '</div><div class="chat-message-block-content">' . $message . '</div><div class="message-date">' . $timeNow . '</div></div></div>' . "\n"); } fclose($fp); $chat_size = filesize($chat_path . $basename_chat . '.log.html'); update_existing_document($_course, $doc_id, $chat_size); item_property_update_on_folder($_course, $basepath_chat, $userId); } } }
Display::display_header($nameTools, "Doc"); //show the title api_display_tool_title($nameTools . $add_group_to_title); /** * Process */ //user has submitted a file if (isset($_FILES['user_upload'])) { $upload_ok = process_uploaded_file($_FILES['user_upload']); if ($upload_ok) { //file got on the server without problems, now process it $new_path = handle_uploaded_document($_course, $_FILES['user_upload'], $base_work_dir, $_POST['curdirpath'], $_user['user_id'], $to_group_id, $to_user_id, $_POST['unzip'], $_POST['if_exists']); $new_comment = isset($_POST['comment']) ? trim($_POST['comment']) : ''; $new_title = isset($_POST['title']) ? trim($_POST['title']) : ''; if ($new_path && ($new_comment || $new_title)) { if ($docid = DocumentManager::get_document_id($_course, $new_path)) { $table_document = Database::get_course_table(TABLE_DOCUMENT); $ct = ''; if ($new_comment) { $ct .= ", comment='{$new_comment}'"; } if ($new_title) { $ct .= ", title='{$new_title}'"; } Database::query("UPDATE {$table_document} SET" . substr($ct, 1) . " WHERE id = '{$docid}'"); } } //check for missing images in html files $missing_files = check_for_missing_files($base_work_dir . $_POST['curdirpath'] . $new_path); if ($missing_files) { //show a form to upload the missing files
*/ require_once '../inc/global.inc.php'; api_protect_course_script(); $noPHP_SELF = true; $header_file = isset($_GET['file']) ? Security::remove_XSS($_GET['file']) : null; $document_id = intval($_GET['id']); $courseInfo = api_get_course_info(); $course_code = api_get_course_id(); $session_id = api_get_session_id(); if (empty($courseInfo)) { api_not_allowed(true); } $show_web_odf = false; // Generate path if (!$document_id) { $document_id = DocumentManager::get_document_id($courseInfo, $header_file); } $document_data = DocumentManager::get_document_data_by_id($document_id, $course_code, true, $session_id); if ($session_id != 0 and !$document_data) { $document_data = DocumentManager::get_document_data_by_id($document_id, $course_code, true, 0); } if (empty($document_data)) { api_not_allowed(true); } $header_file = $document_data['path']; $name_to_show = $document_data['title']; $path_array = explode('/', str_replace('\\', '/', $header_file)); $path_array = array_map('urldecode', $path_array); $header_file = implode('/', $path_array); $file = Security::remove_XSS(urldecode($document_data['path'])); $file_root = $courseInfo['path'] . '/document' . str_replace('%2F', '/', $file);
} // Group folder? $gid_req = $_GET['gidReq'] ? '&gidReq=' . Security::remove_XSS($_GET['gidReq']) : ''; // Create the path $document_explorer = api_get_path(WEB_CODE_PATH) . 'document/document.php?curdirpath=' . urlencode($doc_url) . '&cidReq=' . Security::remove_XSS($_GET['cidReq']) . $gid_req; // Redirect header('Location: ' . $document_explorer); } } //Fixes swf upload problem in chamilo 1.8.x. When uploading a file with //the character "-" the filename was changed from "-" to "_" in the DB for no reason $path_info = pathinfo($doc_url); $fix_file_name = false; if (isset($path_info['extension']) && $path_info['extension'] == 'swf') { $fixed_url = str_replace('-', '_', $doc_url); $doc_id = DocumentManager::get_document_id(api_get_course_info(), $doc_url); if (!$doc_id) { $fix_file_name = true; } } if (Security::check_abs_path($sys_course_path . $doc_url, $sys_course_path . '/')) { $full_file_name = $sys_course_path . $doc_url; if ($fix_file_name) { $doc_url = $fixed_url; } // Check visibility of document and paths $is_visible = DocumentManager::is_visible($doc_url, $_course, api_get_session_id()); //Document's slideshow thumbnails //correct $is_visible used in below and ??. Now the students can view the thumbnails too if (preg_match('/\\.thumbs\\/\\./', $doc_url)) { $doc_url_thumbs = str_replace('.thumbs/.', '', $doc_url);
api_protect_course_script(); $plugin = new AppPlugin(); $pluginList = $plugin->get_installed_plugins(); $capturePluginInstalled = in_array('jcapture', $pluginList); if (!$capturePluginInstalled) { exit; } if (!isset($_FILES['Filedata'])) { exit; } $courseInfo = api_get_course_info(); $folderName = 'captures'; $documentId = DocumentManager::get_document_id($courseInfo, '/'.$folderName); $path = null; if (empty($documentId)) { $course_dir = $courseInfo['path'] . '/document'; $sys_course_path = api_get_path(SYS_COURSE_PATH); $dir = $sys_course_path . $course_dir; $createdDir = create_unexisting_directory( $courseInfo, api_get_user_id(), api_get_session_id(), null, null, $dir, '/'.$folderName, $folderName );
} else { // What's the current path? // We will verify this a bit further down if (isset($_GET['curdirpath']) && $_GET['curdirpath'] != '') { $curdirpath = Security::remove_XSS($_GET['curdirpath']); } elseif (isset($_POST['curdirpath']) && $_POST['curdirpath'] != '') { $curdirpath = Security::remove_XSS($_POST['curdirpath']); } else { $curdirpath = '/'; } $curdirpathurl = urlencode($curdirpath); // Check the path // If the path is not found (no document id), set the path to / $document_id = DocumentManager::get_document_id($course_info, $curdirpath); if (!$document_id) { $document_id = DocumentManager::get_document_id($course_info, $curdirpath); } $document_data = DocumentManager::get_document_data_by_id($document_id, api_get_course_id(), true); $parent_id = $document_data['parent_id']; } $current_folder_id = $document_id; // Is the document tool visible? // Check whether the tool is actually visible $table_course_tool = Database::get_course_table(TABLE_TOOL_LIST); $course_id = api_get_course_int_id(); $tool_sql = 'SELECT visibility FROM ' . $table_course_tool . ' WHERE c_id = ' . $course_id . ' AND name = "' . TOOL_DOCUMENT . '" LIMIT 1'; $tool_result = Database::query($tool_sql); $tool_row = Database::fetch_array($tool_result); $tool_visibility = $tool_row['visibility']; if ($tool_visibility == '0' && $to_group_id == '0' && !($is_allowed_to_edit || $group_member_with_upload_rights)) { api_not_allowed(true);
/** * Shows a question * * @param int $questionId question id * @param bool $only_questions if true only show the questions, no exercise title * @param bool $origin i.e = learnpath * @param string $current_item current item from the list of questions * @param bool $show_title * @param bool $freeze * @param array $user_choice * @param bool $show_comment * @param bool $exercise_feedback * @param bool $show_answers * */ public static function showQuestion($questionId, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false) { $course_id = api_get_course_int_id(); // Change false to true in the following line to enable answer hinting $debug_mark_answer = $show_answers; // Reads question information if (!($objQuestionTmp = Question::read($questionId))) { // Question not found return false; } if ($exercise_feedback != EXERCISE_FEEDBACK_TYPE_END) { $show_comment = false; } $answerType = $objQuestionTmp->selectType(); $pictureName = $objQuestionTmp->selectPicture(); $s = ''; if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) { // Question is not a hotspot if (!$only_questions) { $questionDescription = $objQuestionTmp->selectDescription(); if ($show_title) { TestCategory::displayCategoryAndTitle($objQuestionTmp->id); echo Display::div($current_item . '. ' . $objQuestionTmp->selectTitle(), array('class' => 'question_title')); } if (!empty($questionDescription)) { echo Display::div($questionDescription, array('class' => 'question_description')); } } if (in_array($answerType, array(FREE_ANSWER, ORAL_EXPRESSION)) && $freeze) { return ''; } echo '<div class="question_options row">'; // construction of the Answer object (also gets all answers details) $objAnswerTmp = new Answer($questionId); $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); $quiz_question_options = Question::readQuestionOption($questionId, $course_id); // For "matching" type here, we need something a little bit special // because the match between the suggestions and the answers cannot be // done easily (suggestions and answers are in the same table), so we // have to go through answers first (elems with "correct" value to 0). $select_items = array(); //This will contain the number of answers on the left side. We call them // suggestions here, for the sake of comprehensions, while the ones // on the right side are called answers $num_suggestions = 0; if (in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE])) { if ($answerType == DRAGGABLE) { $s .= '<div class="col-md-12 ui-widget ui-helper-clearfix"> <div class="clearfix"> <ul class="exercise-draggable-answer ui-helper-reset ui-helper-clearfix">'; } else { $s .= <<<HTML <div id="drag{$questionId}_question" class="drag_question"> <table class="data_table"> HTML; } // Iterate through answers $x = 1; //mark letters for each answer $letter = 'A'; $answer_matching = array(); $cpt1 = array(); for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answerCorrect = $objAnswerTmp->isCorrect($answerId); $numAnswer = $objAnswerTmp->selectAutoId($answerId); if ($answerCorrect == 0) { // options (A, B, C, ...) that will be put into the list-box // have the "correct" field set to 0 because they are answer $cpt1[$x] = $letter; $answer_matching[$x] = $objAnswerTmp->selectAnswerByAutoId($numAnswer); $x++; $letter++; } } $i = 1; $select_items[0]['id'] = 0; $select_items[0]['letter'] = '--'; $select_items[0]['answer'] = ''; foreach ($answer_matching as $id => $value) { $select_items[$i]['id'] = $value['id']; $select_items[$i]['letter'] = $cpt1[$id]; $select_items[$i]['answer'] = $value['answer']; $i++; } $user_choice_array_position = array(); if (!empty($user_choice)) { foreach ($user_choice as $item) { $user_choice_array_position[$item['position']] = $item['answer']; } } $num_suggestions = $nbrAnswers - $x + 1; } elseif ($answerType == FREE_ANSWER) { $fck_content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer'] : null; $form = new FormValidator('free_choice_' . $questionId); $config = array('ToolbarSet' => 'TestFreeAnswer'); $form->addHtmlEditor("choice[" . $questionId . "]", null, false, false, $config); $form->setDefaults(array("choice[" . $questionId . "]" => $fck_content)); $s .= $form->returnForm(); } elseif ($answerType == ORAL_EXPRESSION) { // Add nanog if (api_get_setting('enable_nanogong') == 'true') { //@todo pass this as a parameter global $exercise_stat_info, $exerciseId, $exe_id; if (!empty($exercise_stat_info)) { $params = array('exercise_id' => $exercise_stat_info['exe_exo_id'], 'exe_id' => $exercise_stat_info['exe_id'], 'question_id' => $questionId); } else { $params = array('exercise_id' => $exerciseId, 'exe_id' => 'temp_exe', 'question_id' => $questionId); } $nano = new Nanogong($params); echo $nano->show_button(); } $form = new FormValidator('free_choice_' . $questionId); $config = array('ToolbarSet' => 'TestFreeAnswer'); $form->addHtmlEditor("choice[" . $questionId . "]", null, false, false, $config); //$form->setDefaults(array("choice[" . $questionId . "]" => $fck_content)); $s .= $form->return_form(); } // Now navigate through the possible answers, using the max number of // answers for the question as a limiter $lines_count = 1; // a counter for matching-type answers if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $header = Display::tag('th', get_lang('Options')); foreach ($objQuestionTmp->options as $item) { if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { if (in_array($item, $objQuestionTmp->options)) { $header .= Display::tag('th', get_lang($item)); } else { $header .= Display::tag('th', $item); } } else { $header .= Display::tag('th', $item); } } if ($show_comment) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="table table-hover table-striped">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } if ($show_comment) { if (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION, GLOBAL_MULTIPLE_ANSWER))) { $header = Display::tag('th', get_lang('Options')); if ($exercise_feedback == EXERCISE_FEEDBACK_TYPE_END) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="table table-hover table-striped">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } } $matching_correct_answer = 0; $user_choice_array = array(); if (!empty($user_choice)) { foreach ($user_choice as $item) { $user_choice_array[] = $item['answer']; } } for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answer = $objAnswerTmp->selectAnswer($answerId); $answerCorrect = $objAnswerTmp->isCorrect($answerId); $numAnswer = $objAnswerTmp->selectAutoId($answerId); $comment = $objAnswerTmp->selectComment($answerId); $attributes = array(); // Unique answer if (in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, UNIQUE_ANSWER_IMAGE])) { $input_id = 'choice-' . $questionId . '-' . $answerId; if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } if ($show_comment) { $s .= '<tr><td>'; } if ($answerType == UNIQUE_ANSWER_IMAGE) { if ($show_comment) { if (empty($comment)) { $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image" style="text-align: center">'; } else { $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image col-xs-6 col-sm-12" style="text-align: center">'; } } else { $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image col-xs-6 col-md-3" style="text-align: center">'; } } $answer = Security::remove_XSS($answer, STUDENT); $s .= Display::input('hidden', 'choice2[' . $questionId . ']', '0'); $answer_input = null; if ($answerType == UNIQUE_ANSWER_IMAGE) { $attributes['style'] = 'display: none;'; $answer = '<div class="thumbnail">' . $answer . '</div>'; } $answer_input .= '<label class="radio">'; $answer_input .= Display::input('radio', 'choice[' . $questionId . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($answerType == UNIQUE_ANSWER_IMAGE) { $answer_input .= "</div>"; } if ($show_comment) { $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == GLOBAL_MULTIPLE_ANSWER) { $input_id = 'choice-' . $questionId . '-' . $answerId; $answer = Security::remove_XSS($answer, STUDENT); if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input = '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr><td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); $my_choice[$item[0]] = $item[1]; } } $s .= '<tr>'; $s .= Display::tag('td', $answer); if (!empty($quiz_question_options)) { foreach ($quiz_question_options as $id => $item) { if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($id == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $id, $attributes), array('style' => '')); } } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) { // multiple answers $input_id = 'choice-' . $questionId . '-' . $answerId; if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $answer = Security::remove_XSS($answer, STUDENT); $answer_input = '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input .= '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', 1, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr>'; $s .= '<td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); if (isset($item[1]) && isset($item[0])) { $my_choice[$item[0]] = $item[1]; } } } $answer = Security::remove_XSS($answer, STUDENT); $s .= '<tr>'; $s .= Display::tag('td', $answer); foreach ($objQuestionTmp->options as $key => $item) { if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($key == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $key, $attributes)); } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } elseif ($answerType == FILL_IN_BLANKS) { // display the question, with field empty, for student to fill it, // or filled to display the answer in the Question preview of the exercice/admin.php page $displayForStudent = true; $listAnswerInformations = FillBlanks::getAnswerInfo($answer); $separatorStartRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorstart']); $separatorEndRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorend']); list($answer) = explode('::', $answer); //Correct answers $correctAnswerList = $listAnswerInformations['tabwords']; //Student's answer $studentAnswerList = array(); if (isset($user_choice[0]['answer'])) { $arrayStudentAnswer = FillBlanks::getAnswerInfo($user_choice[0]['answer'], true); $studentAnswerList = $arrayStudentAnswer['studentanswer']; } // If the question must be shown with the answer (in page exercice/admin.php) for teacher preview // set the student-answer to the correct answer if ($debug_mark_answer) { $studentAnswerList = $correctAnswerList; $displayForStudent = false; } if (!empty($correctAnswerList) && !empty($studentAnswerList)) { $answer = ""; for ($i = 0; $i < count($listAnswerInformations["commonwords"]) - 1; $i++) { // display the common word $answer .= $listAnswerInformations["commonwords"][$i]; // display the blank word $correctItem = $listAnswerInformations["tabwords"][$i]; $correctItemRegexp = $correctItem; // replace / with \/ to allow the preg_replace bellow and all the regexp char $correctItemRegexp = FillBlanks::getRegexpProtected($correctItemRegexp); if (isset($studentAnswerList[$i])) { // If student already started this test and answered this question, // fill the blank with his previous answers // may be "" if student viewed the question, but did not fill the blanks $correctItem = $studentAnswerList[$i]; } $attributes["style"] = "width:" . $listAnswerInformations["tabinputsize"][$i] . "px"; $answer .= FillBlanks::getFillTheBlankHtml($separatorStartRegexp, $separatorEndRegexp, $correctItemRegexp, $questionId, $correctItem, $attributes, $answer, $listAnswerInformations, $displayForStudent, $i); } // display the last common word $answer .= $listAnswerInformations["commonwords"][$i]; } else { // display empty [input] with the right width for student to fill it $separatorStartRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorstart']); $separatorEndRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorend']); $answer = ""; for ($i = 0; $i < count($listAnswerInformations["commonwords"]) - 1; $i++) { // display the common words $answer .= $listAnswerInformations["commonwords"][$i]; // display the blank word $attributes["style"] = "width:" . $listAnswerInformations["tabinputsize"][$i] . "px"; $correctItem = $listAnswerInformations["tabwords"][$i]; $correctItemRegexp = $correctItem; // replace / with \/ to allow the preg_replace bellow and all the regexp char $correctItemRegexp = FillBlanks::getRegexpProtected($correctItemRegexp); $answer .= FillBlanks::getFillTheBlankHtml($separatorStartRegexp, $separatorEndRegexp, $correctItemRegexp, $questionId, '', $attributes, $answer, $listAnswerInformations, $displayForStudent, $i); } // display the last common word $answer .= $listAnswerInformations["commonwords"][$i]; } $s .= $answer; } elseif ($answerType == CALCULATED_ANSWER) { /* * In the CALCULATED_ANSWER test * you mustn't have [ and ] in the textarea * you mustn't have @@ in the textarea * the text to find mustn't be empty or contains only spaces * the text to find mustn't contains HTML tags * the text to find mustn't contains char " */ if ($origin !== null) { global $exe_id; $trackAttempts = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); $sqlTrackAttempt = 'SELECT answer FROM ' . $trackAttempts . ' WHERE exe_id=' . $exe_id . ' AND question_id=' . $questionId; $rsLastAttempt = Database::query($sqlTrackAttempt); $rowLastAttempt = Database::fetch_array($rsLastAttempt); $answer = $rowLastAttempt['answer']; if (empty($answer)) { $_SESSION['calculatedAnswerId'][$questionId] = mt_rand(1, $nbrAnswers); $answer = $objAnswerTmp->selectAnswer($_SESSION['calculatedAnswerId'][$questionId]); } } list($answer) = explode('@@', $answer); // $correctAnswerList array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]] api_preg_match_all('/\\[[^]]+\\]/', $answer, $correctAnswerList); // get student answer to display it if student go back to previous calculated answer question in a test if (isset($user_choice[0]['answer'])) { api_preg_match_all('/\\[[^]]+\\]/', $answer, $studentAnswerList); $studentAnswerListTobecleaned = $studentAnswerList[0]; $studentAnswerList = array(); for ($i = 0; $i < count($studentAnswerListTobecleaned); $i++) { $answerCorrected = $studentAnswerListTobecleaned[$i]; $answerCorrected = api_preg_replace('| / <font color="green"><b>.*$|', '', $answerCorrected); $answerCorrected = api_preg_replace('/^\\[/', '', $answerCorrected); $answerCorrected = api_preg_replace('|^<font color="red"><s>|', '', $answerCorrected); $answerCorrected = api_preg_replace('|</s></font>$|', '', $answerCorrected); $answerCorrected = '[' . $answerCorrected . ']'; $studentAnswerList[] = $answerCorrected; } } // If display preview of answer in test view for exemple, set the student answer to the correct answers if ($debug_mark_answer) { // contain the rights answers surronded with brackets $studentAnswerList = $correctAnswerList[0]; } /* Split the response by bracket tabComments is an array with text surrounding the text to find we add a space before and after the answerQuestion to be sure to have a block of text before and after [xxx] patterns so we have n text to find ([xxx]) and n+1 block of texts before, between and after the text to find */ $tabComments = api_preg_split('/\\[[^]]+\\]/', ' ' . $answer . ' '); if (!empty($correctAnswerList) && !empty($studentAnswerList)) { $answer = ""; $i = 0; foreach ($studentAnswerList as $studentItem) { // remove surronding brackets $studentResponse = api_substr($studentItem, 1, api_strlen($studentItem) - 2); $size = strlen($studentItem); $attributes['class'] = self::detectInputAppropriateClass($size); $answer .= $tabComments[$i] . Display::input('text', "choice[{$questionId}][]", $studentResponse, $attributes); $i++; } $answer .= $tabComments[$i]; } else { // display exercise with empty input fields // every [xxx] are replaced with an empty input field foreach ($correctAnswerList[0] as $item) { $size = strlen($item); $attributes['class'] = self::detectInputAppropriateClass($size); $answer = str_replace($item, Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer); } } if ($origin !== null) { $s = $answer; break; } else { $s .= $answer; } } elseif ($answerType == MATCHING) { // matching type, showing suggestions and answers // TODO: replace $answerId by $numAnswer if ($answerCorrect != 0) { // only show elements to be answered (not the contents of // the select boxes, who are corrrect = 0) $s .= '<tr><td width="45%" valign="top">'; $parsed_answer = $answer; //left part questions $s .= '<p class="indent">' . $lines_count . '. ' . $parsed_answer . '</p></td>'; //middle part (matches selects) $s .= '<td width="10%" valign="top" align="center" > <div class="select-matching"> <select name="choice[' . $questionId . '][' . $numAnswer . ']">'; // fills the list-box foreach ($select_items as $key => $val) { // set $debug_mark_answer to true at function start to // show the correct answer with a suffix '-x' $selected = ''; if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selected = 'selected="selected"'; } } //$user_choice_array_position if (isset($user_choice_array_position[$numAnswer]) && $val['id'] == $user_choice_array_position[$numAnswer]) { $selected = 'selected="selected"'; } $s .= '<option value="' . $val['id'] . '" ' . $selected . '>' . $val['letter'] . '</option>'; } // end foreach() $s .= '</select></div></td><td width="5%" class="separate"> </td>'; $s .= '<td width="40%" valign="top" >'; if (isset($select_items[$lines_count])) { $s .= '<div class="text-right"><p class="indent">' . $select_items[$lines_count]['letter'] . '. ' . $select_items[$lines_count]['answer'] . '</p></div>'; } else { $s .= ' '; } $s .= '</td>'; $s .= '</tr>'; $lines_count++; //if the left side of the "matching" has been completely // shown but the right side still has values to show... if ($lines_count - 1 == $num_suggestions) { // if it remains answers to shown at the right side while (isset($select_items[$lines_count])) { $s .= '<tr> <td colspan="2"></td> <td valign="top">'; $s .= '<b>' . $select_items[$lines_count]['letter'] . '.</b> ' . $select_items[$lines_count]['answer']; $s .= "</td>\n </tr>"; $lines_count++; } // end while() } // end if() $matching_correct_answer++; } } elseif ($answerType == DRAGGABLE) { if ($answerCorrect != 0) { $parsed_answer = $answer; /*$lines_count = ''; $data = $objAnswerTmp->getAnswerByAutoId($numAnswer); $data = $objAnswerTmp->getAnswerByAutoId($data['correct']); $lines_count = $data['answer'];*/ $windowId = $questionId . '_' . $lines_count; $s .= '<li class="touch-items" id="' . $windowId . '">'; $s .= Display::div($parsed_answer, ['id' => "window_{$windowId}", 'class' => "window{$questionId}_question_draggable exercise-draggable-answer-option"]); $selectedValue = 0; $draggableSelectOptions = []; foreach ($select_items as $key => $val) { if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selectedValue = $val['id']; } } if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) { $selectedValue = $val['id']; } $draggableSelectOptions[$val['id']] = $val['letter']; } $s .= Display::select("choice[{$questionId}][{$numAnswer}]", $draggableSelectOptions, $selectedValue, ['id' => "window_{$windowId}_select", 'class' => 'select_option', 'style' => 'display: none;'], false); if (!empty($answerCorrect) && !empty($selectedValue)) { $s .= <<<JAVASCRIPT <script> \$(function() { DraggableAnswer.deleteItem( \$('#{$questionId}_{$selectedValue}'), \$('#drop_{$windowId}') ); }); </script> JAVASCRIPT; } if (isset($select_items[$lines_count])) { $s .= Display::div(Display::tag('b', $select_items[$lines_count]['letter']) . $select_items[$lines_count]['answer'], ['id' => "window_{$windowId}_answer", 'style' => 'display: none;']); } else { $s .= ' '; } $lines_count++; if ($lines_count - 1 == $num_suggestions) { while (isset($select_items[$lines_count])) { $s .= Display::tag('b', $select_items[$lines_count]['letter']); $s .= $select_items[$lines_count]['answer']; $lines_count++; } } $matching_correct_answer++; $s .= '</li>'; } } elseif ($answerType == MATCHING_DRAGGABLE) { if ($answerId == 1) { echo $objAnswerTmp->getJs(); } if ($answerCorrect != 0) { $parsed_answer = $answer; $windowId = "{$questionId}_{$lines_count}"; $s .= <<<HTML <tr> <td widht="45%"> <div id="window_{$windowId}" class="window window_left_question window{$questionId}_question"> <strong>{$lines_count}.</strong> {$parsed_answer} </div> </td> <td width="10%"> HTML; $selectedValue = 0; $questionOptions = []; foreach ($select_items as $key => $val) { if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selectedValue = $val['id']; } } if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) { $selectedValue = $val['id']; } $questionOptions[$val['id']] = $val['letter']; } $s .= Display::select("choice[{$questionId}][{$numAnswer}]", $questionOptions, $selectedValue, ['id' => "window_{$windowId}_select", 'class' => 'hidden'], false); if (!empty($answerCorrect) && !empty($selectedValue)) { // Show connect if is not freeze (question preview) if (!$freeze) { $s .= <<<JAVASCRIPT <script> jsPlumb.ready(function() { jsPlumb.connect({ source: 'window_{$windowId}', target: 'window_{$questionId}_{$selectedValue}_answer', endpoint: ['Blank', {radius: 15}], anchors: ['RightMiddle', 'LeftMiddle'], paintStyle: {strokeStyle: '#8A8888', lineWidth: 8}, connector: [ MatchingDraggable.connectorType, {curvines: MatchingDraggable.curviness} ] }); }); </script> JAVASCRIPT; } } $s .= <<<HTML </td> <td width="45%"> HTML; if (isset($select_items[$lines_count])) { $s .= <<<HTML <div id="window_{$windowId}_answer" class="window window_right_question"> <strong>{$select_items[$lines_count]['letter']}.</strong> {$select_items[$lines_count]['answer']} </div> HTML; } else { $s .= ' '; } $s .= '</td></tr>'; $lines_count++; if ($lines_count - 1 == $num_suggestions) { while (isset($select_items[$lines_count])) { $s .= <<<HTML <tr> <td colspan="2"></td> <td> <strong>{$select_items[$lines_count]['letter']}</strong> {$select_items[$lines_count]['answer']} </td> </tr> HTML; $lines_count++; } } $matching_correct_answer++; } } } // end for() if ($show_comment) { $s .= '</table>'; } elseif (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE, UNIQUE_ANSWER_NO_OPTION, MULTIPLE_ANSWER_TRUE_FALSE, MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE])) { $s .= '</table>'; } if ($answerType == DRAGGABLE) { $s .= "</ul></div>"; $counterAnswer = 1; $s .= '<div class="col-md-12"><div class="row">'; for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answerCorrect = $objAnswerTmp->isCorrect($answerId); $windowId = $questionId . '_' . $counterAnswer; if ($answerCorrect) { $s .= Display::div($counterAnswer, ['id' => "drop_{$windowId}", 'class' => 'droppable col-md-2']); $counterAnswer++; } } $s .= '</div></div>'; } if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) { $s .= '</div>'; } $s .= '</div>'; // destruction of the Answer object unset($objAnswerTmp); // destruction of the Question object unset($objQuestionTmp); if ($origin != 'export') { echo $s; } else { return $s; } } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) { // Question is a HOT_SPOT //checking document/images visibility if (api_is_platform_admin() || api_is_course_admin()) { $course = api_get_course_info(); $doc_id = DocumentManager::get_document_id($course, '/images/' . $pictureName); if (is_numeric($doc_id)) { $images_folder_visibility = api_get_item_visibility($course, 'document', $doc_id, api_get_session_id()); if (!$images_folder_visibility) { //This message is shown only to the course/platform admin if the image is set to visibility = false Display::display_warning_message(get_lang('ChangeTheVisibilityOfTheCurrentImage')); } } } $questionName = $objQuestionTmp->selectTitle(); $questionDescription = $objQuestionTmp->selectDescription(); if ($freeze) { echo Display::img($objQuestionTmp->selectPicturePath()); return; } // Get the answers, make a list $objAnswerTmp = new Answer($questionId); $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); // get answers of hotpost $answers_hotspot = array(); for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) { $answers = $objAnswerTmp->selectAnswerByAutoId($objAnswerTmp->selectAutoId($answerId)); $answers_hotspot[$answers['id']] = $objAnswerTmp->selectAnswer($answerId); } // display answers of hotpost order by id $answer_list = '<div style="padding: 10px; margin-left: 0px; border: 1px solid #A4A4A4; height: 408px; width: 200px;"><b>' . get_lang('HotspotZones') . '</b><dl>'; if (!empty($answers_hotspot)) { ksort($answers_hotspot); foreach ($answers_hotspot as $key => $value) { $answer_list .= '<dt>' . $key . '.- ' . $value . '</dt><br />'; } } $answer_list .= '</dl></div>'; if ($answerType == HOT_SPOT_DELINEATION) { $answer_list = ''; $swf_file = 'hotspot_delineation_user'; $swf_height = 405; } else { $swf_file = 'hotspot_user'; $swf_height = 436; } if (!$only_questions) { if ($show_title) { TestCategory::displayCategoryAndTitle($objQuestionTmp->id); echo '<div class="question_title">' . $current_item . '. ' . $questionName . '</div>'; } //@todo I need to the get the feedback type echo '<input type="hidden" name="hidden_hotspot_id" value="' . $questionId . '" />'; echo '<table class="exercise_questions" > <tr> <td valign="top" colspan="2">'; echo $questionDescription; echo '</td></tr>'; } $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1'); $s .= '<script type="text/javascript" src="../plugin/hotspot/JavaScriptFlashGateway.js"></script> <script src="../plugin/hotspot/hotspot.js" type="text/javascript" ></script> <script type="text/javascript"> <!-- // Globals // Major version of Flash required var requiredMajorVersion = 7; // Minor version of Flash required var requiredMinorVersion = 0; // Minor version of Flash required var requiredRevision = 0; // the version of javascript supported var jsVersion = 1.0; // --> </script> <script language="VBScript" type="text/vbscript"> <!-- // Visual basic helper required to detect Flash Player ActiveX control version information Function VBGetSwfVer(i) on error resume next Dim swControl, swVersion swVersion = 0 set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i)) if (IsObject(swControl)) then swVersion = swControl.GetVariable("$version") end if VBGetSwfVer = swVersion End Function // --> </script> <script language="JavaScript1.1" type="text/javascript"> <!-- // Detect Client Browser type var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; jsVersion = 1.1; // JavaScript helper required to detect Flash Player PlugIn version information function JSGetSwfVer(i) { // NS/Opera version >= 3 check for Flash plugin in plugin array if (navigator.plugins != null && navigator.plugins.length > 0) { if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; descArray = flashDescription.split(" "); tempArrayMajor = descArray[2].split("."); versionMajor = tempArrayMajor[0]; versionMinor = tempArrayMajor[1]; if ( descArray[3] != "" ) { tempArrayMinor = descArray[3].split("r"); } else { tempArrayMinor = descArray[4].split("r"); } versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0; flashVer = versionMajor + "." + versionMinor + "." + versionRevision; } else { flashVer = -1; } } // MSN/WebTV 2.6 supports Flash 4 else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; // WebTV 2.5 supports Flash 3 else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; // older WebTV supports Flash 2 else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; // Can\'t detect in all other cases else { flashVer = -1; } return flashVer; } // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) { reqVer = parseFloat(reqMajorVer + "." + reqRevision); // loop backwards through the versions until we find the newest version for (i=25;i>0;i--) { if (isIE && isWin && !isOpera) { versionStr = VBGetSwfVer(i); } else { versionStr = JSGetSwfVer(i); } if (versionStr == -1 ) { return false; } else if (versionStr != 0) { if(isIE && isWin && !isOpera) { tempArray = versionStr.split(" "); tempString = tempArray[1]; versionArray = tempString .split(","); } else { versionArray = versionStr.split("."); } versionMajor = versionArray[0]; versionMinor = versionArray[1]; versionRevision = versionArray[2]; versionString = versionMajor + "." + versionRevision; // 7.0r24 == 7.24 versionNum = parseFloat(versionString); // is the major.revision >= requested major.revision AND the minor version >= requested minor if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) { return true; } else { return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false ); } } } } // --> </script>'; $s .= '<tr><td valign="top" colspan="2" width="520"><table><tr><td width="520"> <script> <!-- // Version check based upon the values entered above in "Globals" var hasReqestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision); // Check to see if the version meets the requirements for playback if (hasReqestedVersion) { // if we\'ve detected an acceptable version var oeTags = \'<object type="application/x-shockwave-flash" data="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" width="600" height="' . $swf_height . '">\' + \'<param name="wmode" value="transparent">\' + \'<param name="movie" value="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" />\' + \'<\\/object>\'; document.write(oeTags); // embed the Flash Content SWF when all tests are passed } else { // flash is too old or we can\'t detect the plugin var alternateContent = "Error<br \\/>" + "Hotspots requires Macromedia Flash 7.<br \\/>" + "<a href=\\"http://www.macromedia.com/go/getflash/\\">Get Flash<\\/a>"; document.write(alternateContent); // insert non-flash content } // --> </script> </td> <td valign="top" align="left">' . $answer_list . '</td></tr> </table> </td></tr>'; echo $s; echo '</table>'; } return $nbrAnswers; }
/** * Shows a question * @param Question $objQuestionTmp * @param bool $only_questions if true only show the questions, no exercise title * @param bool $origin origin i.e = learnpath * @param string $current_item current item from the list of questions * @param bool $show_title * @param bool $freeze * @param array $user_choice * @param bool $show_comment * @param null $exercise_feedback * @param bool $show_answers * @param null $modelType * @param bool $categoryMinusOne * @return bool|null|string */ public function showQuestion(Question $objQuestionTmp, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false, $modelType = null, $categoryMinusOne = true) { // Text direction for the current language //$is_ltr_text_direction = api_get_text_direction() != 'rtl'; // Change false to true in the following line to enable answer hinting $debug_mark_answer = $show_answers; //api_is_allowed_to_edit() && false; // Reads question information if (!$objQuestionTmp) { // Question not found return false; } $html = null; $questionId = $objQuestionTmp->id; if ($exercise_feedback != EXERCISE_FEEDBACK_TYPE_END) { $show_comment = false; } $answerType = $objQuestionTmp->selectType(); $pictureName = $objQuestionTmp->selectPicture(); $s = null; $form = new FormValidator('question'); $renderer = $form->defaultRenderer(); $form_template = '{content}'; $renderer->setFormTemplate($form_template); if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) { // Question is not a hotspot if (!$only_questions) { $questionDescription = $objQuestionTmp->selectDescription(); if ($show_title) { $categoryName = TestCategory::getCategoryNamesForQuestion($objQuestionTmp->id, null, true, $categoryMinusOne); $html .= $categoryName; $html .= Display::div($current_item . '. ' . $objQuestionTmp->selectTitle(), array('class' => 'question_title')); if (!empty($questionDescription)) { $html .= Display::div($questionDescription, array('class' => 'question_description')); } } else { $html .= '<div class="media">'; $html .= '<div class="pull-left">'; $html .= '<div class="media-object">'; $html .= Display::div($current_item, array('class' => 'question_no_title')); $html .= '</div>'; $html .= '</div>'; $html .= '<div class="media-body">'; if (!empty($questionDescription)) { $html .= Display::div($questionDescription, array('class' => 'question_description')); } $html .= '</div>'; $html .= '</div>'; } } if (in_array($answerType, array(FREE_ANSWER, ORAL_EXPRESSION)) && $freeze) { return null; } $html .= '<div class="question_options">'; // construction of the Answer object (also gets all answers details) $objAnswerTmp = new Answer($questionId, null, $this); $nbrAnswers = $objAnswerTmp->selectNbrAnswers(); $course_id = api_get_course_int_id(); $quiz_question_options = Question::readQuestionOption($questionId, $course_id); // For "matching" type here, we need something a little bit special // because the match between the suggestions and the answers cannot be // done easily (suggestions and answers are in the same table), so we // have to go through answers first (elems with "correct" value to 0). $select_items = array(); //This will contain the number of answers on the left side. We call them // suggestions here, for the sake of comprehensions, while the ones // on the right side are called answers $num_suggestions = 0; if ($answerType == MATCHING || $answerType == DRAGGABLE) { if ($answerType == DRAGGABLE) { $s .= '<div class="ui-widget ui-helper-clearfix"> <ul class="drag_question ui-helper-reset ui-helper-clearfix">'; } else { $s .= '<div id="drag' . $questionId . '_question" class="drag_question">'; $s .= '<table class="data_table">'; } $j = 1; //iterate through answers $letter = 'A'; //mark letters for each answer $answer_matching = array(); $capital_letter = array(); //for ($answerId=1; $answerId <= $nbrAnswers; $answerId++) { foreach ($objAnswerTmp->answer as $answerId => $answer_item) { $answerCorrect = $objAnswerTmp->isCorrect($answerId); $answer = $objAnswerTmp->selectAnswer($answerId); if ($answerCorrect == 0) { // options (A, B, C, ...) that will be put into the list-box // have the "correct" field set to 0 because they are answer $capital_letter[$j] = $letter; //$answer_matching[$j]=$objAnswerTmp->selectAnswerByAutoId($numAnswer); $answer_matching[$j] = array('id' => $answerId, 'answer' => $answer); $j++; $letter++; } } $i = 1; $select_items[0]['id'] = 0; $select_items[0]['letter'] = '--'; $select_items[0]['answer'] = ''; foreach ($answer_matching as $id => $value) { $select_items[$i]['id'] = $value['id']; $select_items[$i]['letter'] = $capital_letter[$id]; $select_items[$i]['answer'] = $value['answer']; $i++; } $num_suggestions = $nbrAnswers - $j + 1; } elseif ($answerType == FREE_ANSWER) { $content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer'] : null; $toolBar = 'TestFreeAnswer'; if ($modelType == EXERCISE_MODEL_TYPE_COMMITTEE) { $toolBar = 'TestFreeAnswerStrict'; } $form->addElement('html_editor', "choice[" . $questionId . "]", null, array('id' => "choice[" . $questionId . "]"), array('ToolbarSet' => $toolBar)); $form->setDefaults(array("choice[" . $questionId . "]" => $content)); $s .= $form->return_form(); } elseif ($answerType == ORAL_EXPRESSION) { // Add nanogong if (api_get_setting('document.enable_nanogong') == 'true') { //@todo pass this as a parameter global $exercise_stat_info, $exerciseId; if (!empty($exercise_stat_info)) { $params = array('exercise_id' => $exercise_stat_info['exe_exo_id'], 'exe_id' => $exercise_stat_info['exe_id'], 'question_id' => $questionId); } else { $params = array('exercise_id' => $exerciseId, 'exe_id' => 'temp_exe', 'question_id' => $questionId); } $nano = new Nanogong($params); $s .= $nano->show_button(); } $form->addElement('html_editor', "choice[" . $questionId . "]", null, array('id' => "choice[" . $questionId . "]"), array('ToolbarSet' => 'TestFreeAnswer')); //$form->setDefaults(array("choice[".$questionId."]" => $content)); $s .= $form->return_form(); } // Now navigate through the possible answers, using the max number of // answers for the question as a limiter $lines_count = 1; // a counter for matching-type answers if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $header = Display::tag('th', get_lang('Options')); foreach ($objQuestionTmp->options as $item) { $header .= Display::tag('th', $item); } if ($show_comment) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="data_table">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } if ($show_comment) { if (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, GLOBAL_MULTIPLE_ANSWER))) { $header = Display::tag('th', get_lang('Options')); if ($exercise_feedback == EXERCISE_FEEDBACK_TYPE_END) { $header .= Display::tag('th', get_lang('Feedback')); } $s .= '<table class="data_table">'; $s .= Display::tag('tr', $header, array('style' => 'text-align:left;')); } } $matching_correct_answer = 0; $user_choice_array = array(); if (!empty($user_choice)) { foreach ($user_choice as $item) { $user_choice_array[] = $item['answer']; } } foreach ($objAnswerTmp->answer as $answerId => $answer_item) { $answer = $objAnswerTmp->selectAnswer($answerId); $answerCorrect = $objAnswerTmp->isCorrect($answerId); $comment = $objAnswerTmp->selectComment($answerId); //$numAnswer = $objAnswerTmp->selectAutoId($answerId); $numAnswer = $answerId; $attributes = array(); // Unique answer if (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION))) { $input_id = 'choice-' . $questionId . '-' . $answerId; if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $answer = Security::remove_XSS($answer); $s .= Display::input('hidden', 'choice2[' . $questionId . ']', '0'); $answer_input = null; if ($answerType == UNIQUE_ANSWER_IMAGE) { $attributes['style'] = 'display:none'; $answer_input .= '<div id="answer' . $questionId . $numAnswer . '" style="float:left" class="highlight_image_default highlight_image">'; } $answer_input .= '<label class="radio">'; $answer_input .= Display::input('radio', 'choice[' . $questionId . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($answerType == UNIQUE_ANSWER_IMAGE) { $answer_input .= "</div>"; } if ($show_comment) { $s .= '<tr><td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_TRUE_FALSE, GLOBAL_MULTIPLE_ANSWER))) { $input_id = 'choice-' . $questionId . '-' . $answerId; $answer = Security::remove_XSS($answer); if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input = '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', $numAnswer, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr><td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); $my_choice[$item[0]] = $item[1]; } } $s .= '<tr>'; $s .= Display::tag('td', $answer); if (!empty($quiz_question_options)) { foreach ($quiz_question_options as $id => $item) { $id = $item['iid']; if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($id == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $id, $attributes), array('style' => '')); } } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) { // multiple answers $input_id = 'choice-' . $questionId . '-' . $answerId; if (in_array($numAnswer, $user_choice_array)) { $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1); } else { $attributes = array('id' => $input_id); } if ($debug_mark_answer) { if ($answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $answer = Security::remove_XSS($answer); $answer_input = '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $answer_input .= '<label class="checkbox">'; $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', 1, $attributes); $answer_input .= $answer; $answer_input .= '</label>'; if ($show_comment) { $s .= '<tr>'; $s .= '<td>'; $s .= $answer_input; $s .= '</td>'; $s .= '<td>'; $s .= $comment; $s .= '</td>'; $s .= '</tr>'; } else { $s .= $answer_input; } } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />'; $my_choice = array(); if (!empty($user_choice_array)) { foreach ($user_choice_array as $item) { $item = explode(':', $item); $my_choice[$item[0]] = $item[1]; } } $answer = Security::remove_XSS($answer); $s .= '<tr>'; $s .= Display::tag('td', $answer); foreach ($objQuestionTmp->options as $key => $item) { if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) { $attributes = array('checked' => 1, 'selected' => 1); } else { $attributes = array(); } if ($debug_mark_answer) { if ($key == $answerCorrect) { $attributes['checked'] = 1; $attributes['selected'] = 1; } } $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $key, $attributes)); } if ($show_comment) { $s .= '<td>'; $s .= $comment; $s .= '</td>'; } $s .= '</tr>'; } elseif ($answerType == FILL_IN_BLANKS) { list($answer) = explode('::', $answer); //Correct answer api_preg_match_all('/\\[[^]]+\\]/', $answer, $correct_answer_list); //Student's answezr if (isset($user_choice[0]['answer'])) { api_preg_match_all('/\\[[^]]+\\]/', $user_choice[0]['answer'], $student_answer_list); $student_answer_list = $student_answer_list[0]; } //If debug if ($debug_mark_answer) { $student_answer_list = $correct_answer_list[0]; } if (!empty($correct_answer_list) && !empty($student_answer_list)) { $correct_answer_list = $correct_answer_list[0]; $i = 0; foreach ($correct_answer_list as $correct_item) { $value = null; if (isset($student_answer_list[$i]) && !empty($student_answer_list[$i])) { //Cleaning student answer list $value = strip_tags($student_answer_list[$i]); $value = api_substr($value, 1, api_strlen($value) - 2); $value = explode('/', $value); if (!empty($value[0])) { $value = str_replace(' ', '', trim($value[0])); } $correct_item = preg_quote($correct_item); $correct_item = api_preg_replace('|/|', '\\/', $correct_item); // to prevent error if there is a / in the text to find $answer = api_preg_replace('/' . $correct_item . '/', Display::input('text', "choice[{$questionId}][]", $value), $answer, 1); } $i++; } } else { $answer = api_preg_replace('/\\[[^]]+\\]/', Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer); } $s .= $answer; } elseif ($answerType == MATCHING) { // matching type, showing suggestions and answers // TODO: replace $answerId by $numAnswer if ($lines_count == 1) { $s .= $objAnswerTmp->getJs(); } if ($answerCorrect != 0) { // only show elements to be answered (not the contents of // the select boxes, who are correct = 0) $s .= '<tr><td width="45%">'; $parsed_answer = $answer; $windowId = $questionId . '_' . $lines_count; //left part questions $s .= ' <div id="window_' . $windowId . '" class="window window_left_question window' . $questionId . '_question"> <b>' . $lines_count . '</b>. ' . $parsed_answer . ' </div> </td>'; // middle part (matches selects) $s .= '<td width="10%" align="center"> '; $s .= '<div style="display:block">'; $s .= '<select id="window_' . $windowId . '_select" name="choice[' . $questionId . '][' . $numAnswer . ']">'; $selectedValue = 0; // fills the list-box $item = 0; foreach ($select_items as $val) { // set $debug_mark_answer to true at public static function start to // show the correct answer with a suffix '-x' $selected = ''; if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selected = 'selected="selected"'; $selectedValue = $val['id']; } } if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) { $selected = 'selected="selected"'; $selectedValue = $val['id']; } //$s .= '<option value="'.$val['id'].'" '.$selected.'>'.$val['letter'].'</option>'; $s .= '<option value="' . $item . '" ' . $selected . '>' . $val['letter'] . '</option>'; $item++; } if (!empty($answerCorrect) && !empty($selectedValue)) { $s .= '<script> jsPlumb.ready(function() { jsPlumb.connect({ source: "window_' . $windowId . '", target: "window_' . $questionId . '_' . $selectedValue . '_answer", endpoint:["Blank", { radius:15 }], anchor:["RightMiddle","LeftMiddle"], paintStyle:{ strokeStyle:"#8a8888" , lineWidth:8 }, connector: [connectorType, { curviness: curvinessValue } ], }) }); </script>'; } $s .= '</select></div></td>'; $s .= '<td width="45%" valign="top" >'; if (isset($select_items[$lines_count])) { $s .= '<div id="window_' . $windowId . '_answer" class="window window_right_question"> <b>' . $select_items[$lines_count]['letter'] . '.</b> ' . $select_items[$lines_count]['answer'] . ' </div>'; } else { $s .= ' '; } $s .= '</td>'; $s .= '</tr>'; $lines_count++; //if the left side of the "matching" has been completely // shown but the right side still has values to show... if ($lines_count - 1 == $num_suggestions) { // if it remains answers to shown at the right side while (isset($select_items[$lines_count])) { $s .= '<tr> <td colspan="2"></td> <td valign="top">'; $s .= '<b>' . $select_items[$lines_count]['letter'] . '.</b>'; $s .= $select_items[$lines_count]['answer']; $s .= "</td>\n </tr>"; $lines_count++; } // end while() } // end if() $matching_correct_answer++; } } elseif ($answerType == DRAGGABLE) { // matching type, showing suggestions and answers // TODO: replace $answerId by $numAnswer if ($answerCorrect != 0) { // only show elements to be answered (not the contents of // the select boxes, who are correct = 0) $s .= '<td>'; $parsed_answer = $answer; $windowId = $questionId . '_' . $numAnswer; //67_293 - 67_294 //left part questions $s .= '<li class="ui-state-default" id="' . $windowId . '">'; $s .= ' <div id="window_' . $windowId . '" class="window' . $questionId . '_question_draggable question_draggable"> ' . $parsed_answer . ' </div>'; $s .= '<div style="display:none">'; $s .= '<select id="window_' . $windowId . '_select" name="choice[' . $questionId . '][' . $numAnswer . ']" class="select_option">'; $selectedValue = 0; // fills the list-box $item = 0; foreach ($select_items as $val) { // set $debug_mark_answer to true at function start to // show the correct answer with a suffix '-x' $selected = ''; if ($debug_mark_answer) { if ($val['id'] == $answerCorrect) { $selected = 'selected="selected"'; $selectedValue = $val['id']; } } if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) { $selected = 'selected="selected"'; $selectedValue = $val['id']; } //$s .= '<option value="'.$val['id'].'" '.$selected.'>'.$val['letter'].'</option>'; $s .= '<option value="' . $item . '" ' . $selected . '>' . $val['letter'] . '</option>'; $item++; } $s .= '</select>'; if (!empty($answerCorrect) && !empty($selectedValue)) { $s .= '<script> $(function() { deleteItem($("#' . $questionId . '_' . $selectedValue . '"), $("#drop_' . $windowId . '")); }); </script>'; } if (isset($select_items[$lines_count])) { $s .= '<div id="window_' . $windowId . '_answer" class=""> <b>' . $select_items[$lines_count]['letter'] . '.</b> ' . $select_items[$lines_count]['answer'] . ' </div>'; } else { $s .= ' '; } $lines_count++; //if the left side of the "matching" has been completely // shown but the right side still has values to show... if ($lines_count - 1 == $num_suggestions) { // if it remains answers to shown at the right side while (isset($select_items[$lines_count])) { $s .= '<b>' . $select_items[$lines_count]['letter'] . '.</b>'; $s .= $select_items[$lines_count]['answer']; $lines_count++; } } $s .= '</div>'; $matching_correct_answer++; $s .= '</li>'; } } } // end for() if ($show_comment) { $s .= '</table>'; } else { if ($answerType == MATCHING || $answerType == UNIQUE_ANSWER_NO_OPTION || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { $s .= '</table>'; } } if ($answerType == DRAGGABLE) { $s .= '</ul><div class="clear"></div>'; $counterAnswer = 1; foreach ($objAnswerTmp->answer as $answerId => $answer_item) { $answerCorrect = $objAnswerTmp->isCorrect($answerId); $windowId = $questionId . '_' . $counterAnswer; if ($answerCorrect == 0) { $s .= '<div id="drop_' . $windowId . '" class="droppable ui-state-default">' . $counterAnswer . '</div>'; $counterAnswer++; } } } if ($answerType == MATCHING) { $s .= '</div>'; } $s .= '</div>'; // destruction of the Answer object unset($objAnswerTmp); // destruction of the Question object unset($objQuestionTmp); $html .= $s; return $html; } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) { // Question is a HOT_SPOT //checking document/images visibility if (api_is_platform_admin() || api_is_course_admin()) { $course = api_get_course_info(); $doc_id = DocumentManager::get_document_id($course, '/images/' . $pictureName); if (is_numeric($doc_id)) { $images_folder_visibility = api_get_item_visibility($course, 'document', $doc_id, api_get_session_id()); if (!$images_folder_visibility) { //This message is shown only to the course/platform admin if the image is set to visibility = false Display::display_warning_message(get_lang('ChangeTheVisibilityOfTheCurrentImage')); } } } $questionName = $objQuestionTmp->selectTitle(); $questionDescription = $objQuestionTmp->selectDescription(); if ($freeze) { $s .= Display::img($objQuestionTmp->selectPicturePath()); $html .= $s; return $html; } // Get the answers, make a list $objAnswerTmp = new Answer($questionId); // get answers of hotpost $answers_hotspot = array(); foreach ($objAnswerTmp->answer as $answerId => $answer_item) { //$answers = $objAnswerTmp->selectAnswerByAutoId($objAnswerTmp->selectAutoId($answerId)); $answers_hotspot[$answerId] = $objAnswerTmp->selectAnswer($answerId); } // display answers of hotpost order by id $answer_list = '<div style="padding: 10px; margin-left: 0px; border: 1px solid #A4A4A4; height: 408px; width: 200px;"><b>' . get_lang('HotspotZones') . '</b><dl>'; if (!empty($answers_hotspot)) { ksort($answers_hotspot); foreach ($answers_hotspot as $key => $value) { $answer_list .= '<dt>' . $key . '.- ' . $value . '</dt><br />'; } } $answer_list .= '</dl></div>'; if ($answerType == HOT_SPOT_DELINEATION) { $answer_list = ''; $swf_file = 'hotspot_delineation_user'; $swf_height = 405; } else { $swf_file = 'hotspot_user'; $swf_height = 436; } if (!$only_questions) { if ($show_title) { $html .= TestCategory::getCategoryNamesForQuestion($objQuestionTmp->id); $html .= '<div class="question_title">' . $current_item . '. ' . $questionName . '</div>'; $html .= $questionDescription; } else { $html .= '<div class="media">'; $html .= '<div class="pull-left">'; $html .= '<div class="media-object">'; $html .= Display::div($current_item . '. ', array('class' => 'question_no_title')); $html .= '</div>'; $html .= '</div>'; $html .= '<div class="media-body">'; if (!empty($questionDescription)) { $html .= Display::div($questionDescription, array('class' => 'question_description')); } $html .= '</div>'; $html .= '</div>'; } //@todo I need to the get the feedback type $html .= '<input type="hidden" name="hidden_hotspot_id" value="' . $questionId . '" />'; $html .= '<table class="exercise_questions"> <tr> <td valign="top" colspan="2">'; $html .= '</td></tr>'; } $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1'); $s .= ' <script type="text/javascript" src="../plugin/hotspot/JavaScriptFlashGateway.js"></script> <script src="../plugin/hotspot/hotspot.js" type="text/javascript" ></script> <script type="text/javascript"> <!-- // Globals // Major version of Flash required var requiredMajorVersion = 7; // Minor version of Flash required var requiredMinorVersion = 0; // Minor version of Flash required var requiredRevision = 0; // the version of javascript supported var jsVersion = 1.0; // --> </script> <script language="VBScript" type="text/vbscript"> <!-- // Visual basic helper required to detect Flash Player ActiveX control version information Function VBGetSwfVer(i) on error resume next Dim swControl, swVersion swVersion = 0 set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i)) if (IsObject(swControl)) then swVersion = swControl.GetVariable("$version") end if VBGetSwfVer = swVersion End Function // --> </script> <script language="JavaScript1.1" type="text/javascript"> <!-- // Detect Client Browser type var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; jsVersion = 1.1; // JavaScript helper required to detect Flash Player PlugIn version information function JSGetSwfVer(i) { // NS/Opera version >= 3 check for Flash plugin in plugin array if (navigator.plugins != null && navigator.plugins.length > 0) { if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; descArray = flashDescription.split(" "); tempArrayMajor = descArray[2].split("."); versionMajor = tempArrayMajor[0]; versionMinor = tempArrayMajor[1]; if ( descArray[3] != "" ) { tempArrayMinor = descArray[3].split("r"); } else { tempArrayMinor = descArray[4].split("r"); } versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0; flashVer = versionMajor + "." + versionMinor + "." + versionRevision; } else { flashVer = -1; } } // MSN/WebTV 2.6 supports Flash 4 else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; // WebTV 2.5 supports Flash 3 else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; // older WebTV supports Flash 2 else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; // Can\'t detect in all other cases else { flashVer = -1; } return flashVer; } // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) { reqVer = parseFloat(reqMajorVer + "." + reqRevision); // loop backwards through the versions until we find the newest version for (i=25;i>0;i--) { if (isIE && isWin && !isOpera) { versionStr = VBGetSwfVer(i); } else { versionStr = JSGetSwfVer(i); } if (versionStr == -1 ) { return false; } else if (versionStr != 0) { if(isIE && isWin && !isOpera) { tempArray = versionStr.split(" "); tempString = tempArray[1]; versionArray = tempString .split(","); } else { versionArray = versionStr.split("."); } versionMajor = versionArray[0]; versionMinor = versionArray[1]; versionRevision = versionArray[2]; versionString = versionMajor + "." + versionRevision; // 7.0r24 == 7.24 versionNum = parseFloat(versionString); // is the major.revision >= requested major.revision AND the minor version >= requested minor if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) { return true; } else { return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false ); } } } } // --> </script>'; $s .= '<tr><td valign="top" colspan="2" width="520"><table><tr><td width="520"> <script> // Version check based upon the values entered above in "Globals" var hasReqestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision); // Check to see if the version meets the requirements for playback if (hasReqestedVersion) { // if we\'ve detected an acceptable version var oeTags = \'<object type="application/x-shockwave-flash" data="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" width="600" height="' . $swf_height . '">\' + \'<param name="wmode" value="transparent">\' + \'<param name="movie" value="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" />\' + \'<\\/object>\'; document.write(oeTags); // embed the Flash Content SWF when all tests are passed } else { // flash is too old or we can\'t detect the plugin var alternateContent = "Error<br \\/>" + "Hotspots requires Macromedia Flash 7.<br \\/>" + "<a href=\\"http://www.macromedia.com/go/getflash/\\">Get Flash<\\/a>"; document.write(alternateContent); // insert non-flash content } </script> </td> <td valign="top" align="left">' . $answer_list . '</td></tr> </table> </td></tr>'; $html .= $s; $html .= '</table>'; return $html; } return $nbrAnswers; }
/** * Creates the row of edit icons for a file/folder * * @param string $curdirpath current path (cfr open folder) * @param string $type (file/folder) * @param string $path dbase path of file/folder * @param int $visibility (1/0) * @param int $id dbase id of the document * @return string html img tags with hyperlinks */ public static function build_edit_icons($document_data, $id, $is_template, $is_read_only = 0, $visibility) { $web_odf_extension_list = DocumentManager::get_web_odf_extension_list(); $document_id = $document_data['id']; $type = $document_data['filetype']; $is_read_only = $document_data['readonly']; $path = $document_data['path']; $parent_id = DocumentManager::get_document_id(api_get_course_info(), dirname($path)); $curdirpath = dirname($document_data['path']); $is_certificate_mode = DocumentManager::is_certificate_mode($path); $curdirpath = urlencode($curdirpath); $extension = pathinfo($path, PATHINFO_EXTENSION); //@todo Implement remote support for converter $usePpt2lp = api_get_setting('ppt_to_lp.active') == 'true' && api_get_setting('ppt_to_lp.host') == 'localhost'; $formatTypeList = DocumentManager::getFormatTypeListConvertor('from', $extension); $formatType = current($formatTypeList); // Build URL-parameters for table-sorting $sort_params = array(); if (isset($_GET['column'])) { $sort_params[] = 'column=' . Security::remove_XSS($_GET['column']); } if (isset($_GET['page_nr'])) { $sort_params[] = 'page_nr=' . Security::remove_XSS($_GET['page_nr']); } if (isset($_GET['per_page'])) { $sort_params[] = 'per_page=' . Security::remove_XSS($_GET['per_page']); } if (isset($_GET['direction'])) { $sort_params[] = 'direction=' . Security::remove_XSS($_GET['direction']); } $sort_params = implode('&', $sort_params); $visibility_icon = $visibility == 0 ? 'invisible' : 'visible'; $visibility_command = $visibility == 0 ? 'set_visible' : 'set_invisible'; $modify_icons = ''; // If document is read only *or* we're in a session and the document // is from a non-session context, hide the edition capabilities if ($is_read_only) { if (api_is_course_admin() || api_is_platform_admin()) { if ($extension == 'svg' && api_browser_support('svg') && api_get_setting('editor.enabled_support_svg') == 'true') { $modify_icons = '<a href="edit_draw.php?' . api_get_cidreq() . '&id=' . $document_id . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } elseif (in_array($extension, $web_odf_extension_list) && api_get_setting('enabled_support_odf') === true) { $modify_icons = '<a href="edit_odf.php?' . api_get_cidreq() . '&id=' . $document_id . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } elseif ($extension == 'png' || $extension == 'jpg' || $extension == 'jpeg' || $extension == 'bmp' || $extension == 'gif' || $extension == 'pxd' && api_get_setting('editor.enabled_support_pixlr') == 'true') { $modify_icons = '<a href="edit_paint.php?' . api_get_cidreq() . '&id=' . $document_id . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } else { $modify_icons = '<a href="edit_document.php?' . api_get_cidreq() . '&id=' . $document_id . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } } else { $modify_icons = Display::return_icon('edit_na.png', get_lang('Modify'), '', ICON_SIZE_SMALL); } $modify_icons .= ' ' . Display::return_icon('move_na.png', get_lang('Move'), array(), ICON_SIZE_SMALL); if (api_is_allowed_to_edit() || api_is_platform_admin()) { $modify_icons .= ' ' . Display::return_icon($visibility_icon . '.png', get_lang('VisibilityCannotBeChanged'), '', ICON_SIZE_SMALL); } $modify_icons .= ' ' . Display::return_icon('delete_na.png', get_lang('Delete'), array(), ICON_SIZE_SMALL); } else { //Edit button if (in_array($path, DocumentManager::get_system_folders())) { $modify_icons = Display::return_icon('edit_na.png', get_lang('Modify'), '', ICON_SIZE_SMALL); } elseif ($is_certificate_mode) { // gradebook category doesn't seem to be taken into account $modify_icons = '<a href="edit_document.php?' . api_get_cidreq() . '&id=' . $document_id . '&curdirpath=/certificates">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } else { if (api_get_session_id()) { if ($document_data['session_id'] == api_get_session_id()) { if ($extension == 'svg' && api_browser_support('svg') && api_get_setting('editor.enabled_support_svg') == 'true') { $modify_icons = '<a href="edit_draw.php?' . api_get_cidreq() . '&id=' . $document_id . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } elseif (in_array($extension, $web_odf_extension_list) && api_get_setting('enabled_support_odf') === true) { $modify_icons = '<a href="edit_odf.php?' . api_get_cidreq() . '&id=' . $document_id . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } elseif ($extension == 'png' || $extension == 'jpg' || $extension == 'jpeg' || $extension == 'bmp' || $extension == 'gif' || $extension == 'pxd' && api_get_setting('editor.enabled_support_pixlr') == 'true') { $modify_icons = '<a href="edit_paint.php?' . api_get_cidreq() . '&id=' . $document_id . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } else { $modify_icons = '<a href="edit_document.php?' . api_get_cidreq() . '&id=' . $document_id . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } } else { $modify_icons .= ' ' . Display::return_icon('edit_na.png', get_lang('Edit'), array(), ICON_SIZE_SMALL) . '</a>'; } } else { if ($extension == 'svg' && api_browser_support('svg') && api_get_setting('editor.enabled_support_svg') == 'true') { $modify_icons = '<a href="edit_draw.php?' . api_get_cidreq() . '&id=' . $document_id . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } elseif (in_array($extension, $web_odf_extension_list) && api_get_setting('enabled_support_odf') === true) { $modify_icons = '<a href="edit_odf.php?' . api_get_cidreq() . '&id=' . $document_id . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } elseif ($extension == 'png' || $extension == 'jpg' || $extension == 'jpeg' || $extension == 'bmp' || $extension == 'gif' || $extension == 'pxd' && api_get_setting('editor.enabled_support_pixlr') == 'true') { $modify_icons = '<a href="edit_paint.php?' . api_get_cidreq() . '&id=' . $document_id . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } else { $modify_icons = '<a href="edit_document.php?' . api_get_cidreq() . '&id=' . $document_id . '">' . Display::return_icon('edit.png', get_lang('Modify'), '', ICON_SIZE_SMALL) . '</a>'; } } } // Move button. if ($is_certificate_mode || in_array($path, DocumentManager::get_system_folders())) { $modify_icons .= ' ' . Display::return_icon('move_na.png', get_lang('Move'), array(), ICON_SIZE_SMALL) . '</a>'; } else { if (api_get_session_id()) { if ($document_data['session_id'] == api_get_session_id()) { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&id=' . $parent_id . '&move=' . $document_id . '">' . Display::return_icon('move.png', get_lang('Move'), array(), ICON_SIZE_SMALL) . '</a>'; } else { $modify_icons .= ' ' . Display::return_icon('move_na.png', get_lang('Move'), array(), ICON_SIZE_SMALL) . '</a>'; } } else { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&id=' . $parent_id . '&move=' . $document_id . '">' . Display::return_icon('move.png', get_lang('Move'), array(), ICON_SIZE_SMALL) . '</a>'; } } //Visibility button if ($is_certificate_mode) { $modify_icons .= ' ' . Display::return_icon($visibility_icon . '.png', get_lang('VisibilityCannotBeChanged'), array(), ICON_SIZE_SMALL) . '</a>'; } else { if (api_is_allowed_to_edit() || api_is_platform_admin()) { if ($visibility_icon == 'invisible') { $tip_visibility = get_lang('Show'); } else { $tip_visibility = get_lang('Hide'); } $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&id=' . $parent_id . '&' . $visibility_command . '=' . $id . '&' . $sort_params . '">' . Display::return_icon($visibility_icon . '.png', $tip_visibility, '', ICON_SIZE_SMALL) . '</a>'; } } // Delete button if (in_array($path, DocumentManager::get_system_folders())) { $modify_icons .= ' ' . Display::return_icon('delete_na.png', get_lang('ThisFolderCannotBeDeleted'), array(), ICON_SIZE_SMALL); } else { $titleToShow = addslashes(basename($document_data['title'])); if (isset($_GET['curdirpath']) && $_GET['curdirpath'] == '/certificates' && DocumentManager::get_default_certificate_id(api_get_course_id()) == $id) { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&action=delete_item&id=' . $parent_id . '&deleteid=' . $document_id . '&' . $sort_params . 'delete_certificate_id=' . $id . '" onclick="return confirmation(\'' . $titleToShow . '\');">' . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>'; } else { if ($is_certificate_mode) { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&action=delete_item&id=' . $parent_id . '&deleteid=' . $document_id . '&' . $sort_params . '" onclick="return confirmation(\'' . $titleToShow . '\');">' . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>'; } else { if (api_get_session_id()) { if ($document_data['session_id'] == api_get_session_id()) { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&action=delete_item&id=' . $parent_id . '&deleteid=' . $document_id . '&' . $sort_params . '" onclick="return confirmation(\'' . $titleToShow . '\');">' . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>'; } else { $modify_icons .= ' ' . Display::return_icon('delete_na.png', get_lang('ThisFolderCannotBeDeleted'), array(), ICON_SIZE_SMALL); } } else { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&action=delete_item&id=' . $parent_id . '&deleteid=' . $document_id . '&' . $sort_params . '" onclick="return confirmation(\'' . $titleToShow . '\');">' . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>'; } } } } // Add action to covert to PDF, will create a new document whit same filename but .pdf extension // @TODO: add prompt to select a format target if (in_array($path, DocumentManager::get_system_folders())) { // nothing to do } else { if ($usePpt2lp && $formatType) { $modify_icons .= ' <a class="convertAction" href="#" ' . 'data-documentId = ' . $document_id . ' data-formatType = ' . $formatType . '>' . Display::return_icon('convert.png', get_lang('Convert'), array(), ICON_SIZE_SMALL) . '</a>'; } } } if ($type == 'file' && ($extension == 'html' || $extension == 'htm')) { if ($is_template == 0) { if (isset($_GET['curdirpath']) && $_GET['curdirpath'] != '/certificates' || !isset($_GET['curdirpath'])) { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&add_as_template=' . $id . '&' . $sort_params . '">' . Display::return_icon('wizard.png', get_lang('AddAsTemplate'), array(), ICON_SIZE_SMALL) . '</a>'; } if (isset($_GET['curdirpath']) && $_GET['curdirpath'] == '/certificates') { //allow attach certificate to course $visibility_icon_certificate = 'nocertificate'; if (DocumentManager::get_default_certificate_id(api_get_course_id()) == $id) { $visibility_icon_certificate = 'certificate'; $certificate = get_lang('DefaultCertificate'); $preview = get_lang('PreviewCertificate'); $is_preview = true; } else { $is_preview = false; $certificate = get_lang('NoDefaultCertificate'); } if (isset($_GET['selectcat'])) { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&selectcat=' . Security::remove_XSS($_GET['selectcat']) . '&set_certificate=' . $id . '&' . $sort_params . '"> <img src="../img/' . $visibility_icon_certificate . '.png" border="0" title="' . $certificate . '" alt="" /></a>'; if ($is_preview) { $modify_icons .= ' <a target="_blank" href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&set_preview=' . $id . '&' . $sort_params . '" >' . Display::return_icon('preview_view.png', $preview, '', ICON_SIZE_SMALL) . '</a>'; } } } } else { $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&remove_as_template=' . $id . '&' . $sort_params . '">' . Display::return_icon('wizard_na.png', get_lang('RemoveAsTemplate'), '', ICON_SIZE_SMALL) . '</a>'; } $modify_icons .= ' <a href="' . api_get_self() . '?' . api_get_cidreq() . '&action=export_to_pdf&id=' . $id . '">' . Display::return_icon('pdf.png', get_lang('Export2PDF'), array(), ICON_SIZE_SMALL) . '</a>'; } return $modify_icons; }
$courseDir = $_course['path'] . '/document'; $sys_course_path = api_get_path(SYS_COURSE_PATH); $base_work_dir = $sys_course_path . $courseDir; $sessionId = api_get_session_id(); $selectcat = isset($_GET['selectcat']) ? Security::remove_XSS($_GET['selectcat']) : null; $document_data = DocumentManager::get_document_data_by_id($_REQUEST['id'], api_get_course_id(), true, $sessionId); if ($sessionId != 0 && !$document_data) { $document_data = DocumentManager::get_document_data_by_id($_REQUEST['id'], api_get_course_id(), true, 0); } if (empty($document_data)) { $document_id = $parent_id = 0; $path = '/'; } else { $document_id = $document_data['id']; $path = $document_data['path']; $parent_id = DocumentManager::get_document_id(api_get_course_info(), dirname($path)); } $group_properties = array(); $htmlHeadXtra[] = '<script> function check_unzip() { if (document.upload.unzip.checked){ document.upload.if_exists[0].disabled=true; document.upload.if_exists[1].checked=true; document.upload.if_exists[2].disabled=true; } else { document.upload.if_exists[0].checked=true; document.upload.if_exists[0].disabled=false; document.upload.if_exists[2].disabled=false; } }
if (substr($path, 0, strlen(VIDEOCONF_UPLOAD_PATH)) != VIDEOCONF_UPLOAD_PATH) { if ($debug > 0) { error_log("Delete from videoconf for " + $path + " NOT ALLOWED", 0); } die; } DocumentManager::delete_document($_course, $path, $coursePath); echo "<result>OK</result>"; // We have to return something to OpenLaszlo } } } else { if ($action == "download") { /*==== DOWNLOAD ====*/ //check if the document is in the database if (!DocumentManager::get_document_id($_course, $_REQUEST['file'])) { //file not found! if ($debug > 0) { error_log("404 " . $_REQUEST["file"]); } header("HTTP/1.0 404 Not Found"); $error404 = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">'; $error404 .= '<html><head>'; $error404 .= '<title>404 Not Found</title>'; $error404 .= '</head><body>'; $error404 .= '<h1>Not Found</h1>'; $error404 .= '<p>The requested URL was not found on this server.</p>'; $error404 .= '<hr>'; $error404 .= '</body></html>'; echo $error404; exit;
if (DocumentManager::is_my_shared_folder(api_get_user_id(), $curdirpath, $sessionId) && $curdirpath != '/' || api_is_allowed_to_edit() || api_is_platform_admin()) { $actionsLeft .= Display::url(Display::return_icon('save_pack.png', get_lang('Save') . ' (ZIP)', '', ICON_SIZE_MEDIUM), api_get_path(WEB_CODE_PATH) . 'document/document.php?' . api_get_cidreq() . '&action=downloadfolder&id=' . $document_id); } } } if (api_is_platform_admin()) { if (api_get_configuration_value('document_manage_deleted_files')) { $actionsLeft .= Display::url(get_lang('Recycle'), api_get_path(WEB_CODE_PATH) . 'document/recycle.php?' . api_get_cidreq(), array('class' => 'btn btn-default')); } } if (!empty($moveTo)) { $document_id = DocumentManager::get_document_id($courseInfo, $moveTo); } if (isset($_GET['createdir']) && isset($_POST['dirname']) && $_POST['dirname'] != '') { $post_dir_name = $_POST['dirname']; $document_id = DocumentManager::get_document_id($courseInfo, $_POST['dirname']); } $selector = null; if (!$is_certificate_mode) { $selector = DocumentManager::build_directory_selector($folders, $document_id, isset($group_properties['directory']) ? $group_properties['directory'] : array(), true); } if (($is_allowed_to_edit || $group_member_with_upload_rights) && count($documentAndFolders) > 1) { $column_show[] = 1; } $column_show[] = 1; $column_show[] = 1; $column_show[] = 1; $column_show[] = 1; if ($is_allowed_to_edit || $group_member_with_upload_rights || DocumentManager::is_my_shared_folder(api_get_user_id(), $curdirpath, $sessionId)) { $column_show[] = 1; }
/* MAIN CODE */ // Please, do not modify this dirname formatting if (strstr($dir, '..')) { $dir = '/'; } if ($dir[0] == '.') { $dir = substr($dir, 1); } if ($dir[0] != '/') { $dir = '/' . $dir; } if ($dir[strlen($dir) - 1] != '/') { $dir .= '/'; } if ($is_certificate_mode) { $document_id = DocumentManager::get_document_id(api_get_course_info(), '/certificates'); $document_data = DocumentManager::get_document_data_by_id($document_id, api_get_course_id(), true); $folder_id = $document_data['id']; $dir = '/certificates/'; } // Configuration for the FCKEDITOR $doc_tree = explode('/', $dir); $count_dir = count($doc_tree) - 2; // "2" because at the begin and end there are 2 "/" if (api_is_in_group()) { $group_properties = GroupManager::get_group_properties($groupId); // Level correction for group documents. if (!empty($group_properties['directory'])) { $count_dir = $count_dir > 0 ? $count_dir - 1 : 0; } }
/** * @param array $course * @param string $lp_name * @param int $creatorId * * @return array */ public function generate_lp_folder($course, $lp_name = '', $creatorId = 0) { $filepath = ''; $dir = '/learning_path/'; if (empty($lp_name)) { $lp_name = $this->name; } $creatorId = empty($creatorId) ? api_get_user_id() : $creatorId; $folder = self::generate_learning_path_folder($course, $creatorId); // Limits title size $title = api_substr(api_replace_dangerous_char($lp_name), 0, 80); $dir = $dir . $title; // Creating LP folder $documentId = null; if ($folder) { $filepath = api_get_path(SYS_COURSE_PATH) . $course['path'] . '/document'; if (!is_dir($filepath . '/' . $dir)) { $folderData = create_unexisting_directory($course, $creatorId, 0, 0, 0, $filepath, $dir, $lp_name); if (!empty($folderData)) { $folder = true; } $documentId = $folderData['id']; } else { $folder = true; } $dir = $dir . '/'; if ($folder) { $filepath = api_get_path(SYS_COURSE_PATH) . $course['path'] . '/document' . $dir; } } if (empty($documentId)) { $dir = api_remove_trailing_slash($dir); $documentId = DocumentManager::get_document_id($course, $dir, 0); } $array = array('dir' => $dir, 'filepath' => $filepath, 'folder' => $folder, 'id' => $documentId); return $array; }