/** * Creates a new model. * If creation is successful, the browser will be redirected to the 'view' page. */ public function actionCreate() { $model = new Exercise(); // Uncomment the following line if AJAX validation is needed // $this->performAjaxValidation($model); if (isset($_POST['Exercise'])) { $model->attributes = $_POST['Exercise']; if ($model->save()) { $this->redirect(array('view', 'id' => $model->id)); } } $this->render('create', array('model' => $model)); }
/** * Function rewritten based on old_add_item() from Yannick Warnier. Due the fact that users can decide where the item should come, I had to overlook this function and * I found it better to rewrite it. Old function is still available. Added also the possibility to add a description. * * @param int $parent * @param int $previous * @param string $type * @param int resource ID (ref) * @param string $title * @param string $description * @return int */ public function add_item($parent, $previous, $type = 'dokeos_chapter', $id, $title, $description, $prerequisites = 0, $max_time_allowed = 0) { $course_id = api_get_course_int_id(); if ($this->debug > 0) { error_log('New LP - In learnpath::add_item(' . $parent . ',' . $previous . ',' . $type . ',' . $id . ',' . $title . ')', 0); } $tbl_lp_item = Database::get_course_table(TABLE_LP_ITEM); $parent = intval($parent); $previous = intval($previous); $type = Database::escape_string($type); $id = intval($id); $max_time_allowed = Database::escape_string($max_time_allowed); if (empty($max_time_allowed)) { $max_time_allowed = 0; } $title = Database::escape_string($title); $description = Database::escape_string($description); $sql_count = "\tSELECT COUNT(id) AS num\n FROM {$tbl_lp_item}\n WHERE c_id = {$course_id} AND lp_id = " . $this->get_id() . " AND parent_item_id = " . $parent; $res_count = Database::query($sql_count); $row = Database::fetch_array($res_count); $num = $row['num']; if ($num > 0) { if ($previous == 0) { $sql = "SELECT id, next_item_id, display_order\n FROM " . $tbl_lp_item . "\n WHERE c_id = {$course_id} AND\n lp_id = " . $this->get_id() . " AND\n parent_item_id = " . $parent . " AND\n previous_item_id = 0 OR previous_item_id=" . $parent; $result = Database::query($sql); $row = Database::fetch_array($result); $tmp_previous = 0; $next = $row['id']; $display_order = 0; } else { $previous = (int) $previous; $sql = "SELECT id, previous_item_id, next_item_id, display_order\n\t\t\t\t\t\tFROM {$tbl_lp_item}\n WHERE c_id = {$course_id} AND lp_id = " . $this->get_id() . " AND id = " . $previous; $result = Database::query($sql); $row = Database::fetch_array($result); $tmp_previous = $row['id']; $next = $row['next_item_id']; $display_order = $row['display_order']; } } else { $tmp_previous = 0; $next = 0; $display_order = 0; } $new_item_id = -1; $id = Database::escape_string($id); if ($type == 'quiz') { $sql = 'SELECT SUM(ponderation) FROM ' . Database::get_course_table(TABLE_QUIZ_QUESTION) . ' as quiz_question INNER JOIN ' . Database::get_course_table(TABLE_QUIZ_TEST_QUESTION) . ' as quiz_rel_question ON quiz_question.iid = quiz_rel_question.question_id WHERE quiz_rel_question.exercice_id = ' . $id . " AND\n\t \t\t\tquiz_question.c_id = {$course_id} AND\n\t \t\t\tquiz_rel_question.c_id = {$course_id} "; $rsQuiz = Database::query($sql); $max_score = Database::result($rsQuiz, 0, 0); //Disabling the exercise if we add it inside a LP $exercise = new Exercise(); $exercise->read($id); $exercise->disable(); $exercise->save(); } else { $max_score = 100; } if ($prerequisites != 0) { $sql_ins = "INSERT INTO " . $tbl_lp_item . " (\n \t\t\t\t\tc_id,\n lp_id, " . "item_type, " . "ref, " . "title, " . "description, " . "path, " . "max_score, " . "parent_item_id, " . "previous_item_id, " . "next_item_id, " . "display_order, " . "prerequisite, " . "max_time_allowed " . ") VALUES (\n \t{$course_id} ,\n " . $this->get_id() . ", " . "'" . $type . "', " . "'', " . "'" . $title . "', " . "'" . $description . "', " . "'" . $id . "', " . "'" . $max_score . "', " . $parent . ", " . $previous . ", " . $next . ", " . ($display_order + 1) . ", " . $prerequisites . ", " . $max_time_allowed . ")"; } else { // Insert new item. $sql_ins = "\n INSERT INTO " . $tbl_lp_item . " ( " . "c_id, " . "lp_id, " . "item_type, " . "ref, " . "title, " . "description, " . "path, " . "max_score, " . "parent_item_id, " . "previous_item_id, " . "next_item_id, " . "display_order, " . "max_time_allowed " . ") VALUES (" . $course_id . "," . $this->get_id() . "," . "'" . $type . "'," . "''," . "'" . $title . "'," . "'" . $description . "'," . "'" . $id . "'," . "'" . $max_score . "'," . $parent . "," . $previous . "," . $next . "," . ($display_order + 1) . "," . $max_time_allowed . ")"; } if ($this->debug > 2) { error_log('New LP - Inserting dokeos_chapter: ' . $sql_ins, 0); } $res_ins = Database::query($sql_ins); if ($res_ins) { $new_item_id = Database::insert_id(); // Update the item that should come after the new item. $sql_update_next = "\n UPDATE " . $tbl_lp_item . "\n SET previous_item_id = " . $new_item_id . "\n WHERE c_id = {$course_id} AND id = " . $next; Database::query($sql_update_next); // Update the item that should be before the new item. $sql_update_previous = "\n UPDATE " . $tbl_lp_item . "\n SET next_item_id = " . $new_item_id . "\n WHERE c_id = {$course_id} AND id = " . $tmp_previous; Database::query($sql_update_previous); // Update all the items after the new item. $sql_update_order = "\n UPDATE " . $tbl_lp_item . "\n SET display_order = display_order + 1\n WHERE\n c_id = {$course_id} AND\n lp_id = " . $this->get_id() . " AND\n id <> " . $new_item_id . " AND\n parent_item_id = " . $parent . " AND\n display_order > " . $display_order; Database::query($sql_update_order); // Update the item that should come after the new item. $sql_update_ref = "UPDATE " . $tbl_lp_item . "\n SET ref = " . $new_item_id . "\n WHERE c_id = {$course_id} AND id = " . $new_item_id; Database::query($sql_update_ref); } // Upload audio. if (!empty($_FILES['mp3']['name'])) { // Create the audio folder if it does not exist yet. $_course = api_get_course_info(); $filepath = api_get_path(SYS_COURSE_PATH) . $_course['path'] . '/document/'; if (!is_dir($filepath . 'audio')) { mkdir($filepath . 'audio', api_get_permissions_for_new_directories()); $audio_id = FileManager::add_document($_course, '/audio', 'folder', 0, 'audio'); api_item_property_update($_course, TOOL_DOCUMENT, $audio_id, 'FolderCreated', api_get_user_id(), null, null, null, null, api_get_session_id()); api_item_property_update($_course, TOOL_DOCUMENT, $audio_id, 'invisible', api_get_user_id(), null, null, null, null, api_get_session_id()); } // Upload the file in the documents tool. $file_path = FileManager::handle_uploaded_document($_course, $_FILES['mp3'], api_get_path(SYS_COURSE_PATH) . $_course['path'] . '/document', '/audio', api_get_user_id(), '', '', '', '', false); // Getting the filename only. $file_components = explode('/', $file_path); $file = $file_components[count($file_components) - 1]; // Store the mp3 file in the lp_item table. $sql_insert_audio = "UPDATE {$tbl_lp_item} SET audio = '" . Database::escape_string($file) . "' WHERE id = '" . Database::escape_string($new_item_id) . "'"; Database::query($sql_insert_audio); } return $new_item_id; }
/** * Fills the course database with some required content and example content. * @param int Course (int) ID * @param string Course directory name (e.g. 'ABC') * @param string Language used for content (e.g. 'spanish') * @param bool Whether to fill the course with example content * @return bool False on error, true otherwise * @version 1.2 * @assert (null, '', '', null) === false * @assert (1, 'ABC', null, null) === false * @assert (1, 'TEST', 'spanish', true) === true */ public static function fill_db_course($course_id, $course_repository, $language, $fill_with_exemplary_content = null) { if (is_null($fill_with_exemplary_content)) { $fill_with_exemplary_content = api_get_setting('course.example_material_course_creation') != 'false'; } $course_id = intval($course_id); if (empty($course_id)) { return false; } $entityManager = Database::getManager(); $course = $entityManager->getRepository('ChamiloCoreBundle:Course')->find($course_id); $tools = array(); $settingsManager = CourseManager::getCourseSettingsManager(); $settingsManager->setCourse($course); $toolList = CourseManager::getToolList(); $toolList = $toolList->getTools(); /** @var Chamilo\CourseBundle\Tool\BaseTool $tool */ foreach ($toolList as $tool) { $visibility = self::string2binary(api_get_setting_in_list('course.active_tools_on_create', $tool->getName())); $toolObject = new CTool(); $toolObject->setName($tool->getName())->setCategory($tool->getCategory())->setLink($tool->getLink())->setImage($tool->getImage())->setVisibility($visibility)->setAdmin(0)->setTarget($tool->getTarget()); $tools[] = $toolObject; $settings = $settingsManager->loadSettings($tool->getName()); $settingsManager->saveSettings($tool->getName(), $settings); } $course->setTools($tools); $entityManager->persist($course); $entityManager->flush($course); $courseInfo = api_get_course_info_by_id($course_id); $now = api_get_utc_datetime(time()); $tbl_course_homepage = Database::get_course_table(TABLE_TOOL_LIST); $TABLEINTROS = Database::get_course_table(TABLE_TOOL_INTRO); $TABLEGROUPCATEGORIES = Database::get_course_table(TABLE_GROUP_CATEGORY); $TABLEITEMPROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY); $TABLETOOLAGENDA = Database::get_course_table(TABLE_AGENDA); $TABLETOOLANNOUNCEMENTS = Database::get_course_table(TABLE_ANNOUNCEMENT); $TABLETOOLDOCUMENT = Database::get_course_table(TABLE_DOCUMENT); $TABLETOOLLINK = Database::get_course_table(TABLE_LINK); $TABLEQUIZ = Database::get_course_table(TABLE_QUIZ_TEST); $TABLEQUIZQUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION); $TABLEQUIZQUESTIONLIST = Database::get_course_table(TABLE_QUIZ_QUESTION); $TABLEQUIZANSWERSLIST = Database::get_course_table(TABLE_QUIZ_ANSWER); $TABLESETTING = Database::get_course_table(TABLE_COURSE_SETTING); $TABLEFORUMCATEGORIES = Database::get_course_table(TABLE_FORUM_CATEGORY); $TABLEFORUMS = Database::get_course_table(TABLE_FORUM); $TABLEFORUMTHREADS = Database::get_course_table(TABLE_FORUM_THREAD); $TABLEFORUMPOSTS = Database::get_course_table(TABLE_FORUM_POST); $TABLEGRADEBOOK = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY); $TABLEGRADEBOOKLINK = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK); $TABLEGRADEBOOKCERT = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE); $visible_for_all = 1; $visible_for_course_admin = 0; $visible_for_platform_admin = 2; /* Course tools */ $alert = api_get_setting('exercise.email_alert_manager_on_new_quiz'); if ($alert === 'true') { $defaultEmailExerciseAlert = 1; } else { $defaultEmailExerciseAlert = 0; } /* course_setting table (courseinfo tool) */ $settings = ['email_alert_manager_on_new_doc' => ['default' => 0, 'category' => 'work'], 'email_alert_on_new_doc_dropbox' => ['default' => 0, 'category' => 'dropbox'], 'allow_user_edit_agenda' => ['default' => 0, 'category' => 'agenda'], 'allow_user_edit_announcement' => ['default' => 0, 'category' => 'announcement'], 'email_alert_manager_on_new_quiz' => ['default' => $defaultEmailExerciseAlert, 'category' => 'quiz'], 'allow_user_image_forum' => ['default' => 1, 'category' => 'forum'], 'course_theme' => ['default' => '', 'category' => 'theme'], 'allow_learning_path_theme' => ['default' => 1, 'category' => 'theme'], 'allow_open_chat_window' => ['default' => 1, 'category' => 'chat'], 'email_alert_to_teacher_on_new_user_in_course' => ['default' => 0, 'category' => 'registration'], 'allow_user_view_user_list' => ['default' => 1, 'category' => 'user'], 'display_info_advance_inside_homecourse' => ['default' => 1, 'category' => 'thematic_advance'], 'email_alert_students_on_new_homework' => ['default' => 0, 'category' => 'work'], 'enable_lp_auto_launch' => ['default' => 0, 'category' => 'learning_path'], 'pdf_export_watermark_text' => ['default' => '', 'category' => 'learning_path'], 'allow_public_certificates' => ['default' => api_get_setting('course.allow_public_certificates') === 'true' ? 1 : '', 'category' => 'certificates'], 'documents_default_visibility' => ['default' => 'visible', 'category' => 'document']]; /*$counter = 1; foreach ($settings as $variable => $setting) { Database::query( "INSERT INTO $TABLESETTING (id, c_id, variable, value, category) VALUES ($counter, $course_id, '".$variable."', '".$setting['default']."', '".$setting['category']."')" ); $counter++; }*/ /* Course homepage tools for platform admin only */ /* Group tool */ Database::query("INSERT INTO {$TABLEGROUPCATEGORIES} (c_id, id, title , description, max_student, self_reg_allowed, self_unreg_allowed, groups_per_user, display_order)\n VALUES ({$course_id}, '2', '" . self::lang2db(get_lang('DefaultGroupCategory')) . "', '', '8', '0', '0', '0', '0');"); /* Example Material */ $language_interface = !empty($language_interface) ? $language_interface : api_get_setting('language.platform_language'); // Example material should be in the same language as the course is. $language_interface_original = $language_interface; $now = api_get_utc_datetime(); $files = [['path' => '/shared_folder', 'title' => get_lang('UserFolders'), 'filetype' => 'folder', 'size' => 0], ['path' => '/chat_files', 'title' => get_lang('ChatFiles'), 'filetype' => 'folder', 'size' => 0]]; $counter = 1; foreach ($files as $file) { self::insertDocument($course_id, $counter, $file); $counter++; } $sys_course_path = api_get_path(SYS_COURSE_PATH); $perm = api_get_permissions_for_new_directories(); $perm_file = api_get_permissions_for_new_files(); $chat_path = $sys_course_path . $course_repository . '/document/chat_files'; if (!is_dir($chat_path)) { @mkdir($chat_path, api_get_permissions_for_new_directories()); } /* Documents */ if ($fill_with_exemplary_content) { $files = [['path' => '/images', 'title' => get_lang('Images'), 'filetype' => 'folder', 'size' => 0], ['path' => '/images/gallery', 'title' => get_lang('DefaultCourseImages'), 'filetype' => 'folder', 'size' => 0], ['path' => '/audio', 'title' => get_lang('Audio'), 'filetype' => 'folder', 'size' => 0], ['path' => '/flash', 'title' => get_lang('Flash'), 'filetype' => 'folder', 'size' => 0], ['path' => '/video', 'title' => get_lang('Video'), 'filetype' => 'folder', 'size' => 0], ['path' => '/certificates', 'title' => get_lang('Certificates'), 'filetype' => 'folder', 'size' => 0]]; foreach ($files as $file) { self::insertDocument($course_id, $counter, $file); $counter++; } // FILL THE COURSE DOCUMENT WITH DEFAULT COURSE PICTURES $folders_to_copy_from_default_course = array('images', 'audio', 'flash', 'video', 'certificates'); $default_course_path = api_get_path(SYS_CODE_PATH) . 'default_course_document/'; $default_document_array = array(); foreach ($folders_to_copy_from_default_course as $folder) { $default_course_folder_path = $default_course_path . $folder . '/'; $files = self::browse_folders($default_course_folder_path, array(), $folder); $sorted_array = self::sort_pictures($files, 'dir'); $sorted_array = array_merge($sorted_array, self::sort_pictures($files, 'file')); $default_document_array[$folder] = $sorted_array; } //Light protection (adding index.html in every document folder) $htmlpage = "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <title>Not authorized</title>\n </head>\n <body>\n </body>\n</html>"; $example_cert_id = 0; if (is_array($default_document_array) && count($default_document_array) > 0) { foreach ($default_document_array as $media_type => $array_media) { $path_documents = "/{$media_type}/"; //hack until feature #5242 is implemented if ($media_type == 'images') { $media_type = 'images/gallery'; $images_folder = $sys_course_path . $course_repository . "/document/images/"; if (!is_dir($images_folder)) { //Creating index.html mkdir($images_folder, $perm); $fd = fopen($images_folder . 'index.html', 'w'); fwrite($fd, $htmlpage); @chmod($images_folder . 'index.html', $perm_file); } } $course_documents_folder = $sys_course_path . $course_repository . "/document/{$media_type}/"; $default_course_path = api_get_path(SYS_CODE_PATH) . 'default_course_document' . $path_documents; if (!is_dir($course_documents_folder)) { // Creating index.html mkdir($course_documents_folder, $perm); $fd = fopen($course_documents_folder . 'index.html', 'w'); fwrite($fd, $htmlpage); @chmod($course_documents_folder . 'index.html', $perm_file); } if (is_array($array_media) && count($array_media) > 0) { foreach ($array_media as $key => $value) { if (isset($value['dir']) && !empty($value['dir'])) { if (!is_dir($course_documents_folder . $value['dir'])) { //Creating folder mkdir($course_documents_folder . $value['dir'], $perm); //Creating index.html (for light protection) $index_html = $course_documents_folder . $value['dir'] . '/index.html'; $fd = fopen($index_html, 'w'); fwrite($fd, $htmlpage); @chmod($index_html, $perm_file); //Inserting folder in the DB $folder_path = substr($value['dir'], 0, strlen($value['dir']) - 1); $temp = explode('/', $folder_path); $title = $temp[count($temp) - 1]; //hack until feature #5242 is implemented if ($title == 'gallery') { $title = get_lang('DefaultCourseImages'); } if ($media_type == 'images/gallery') { $folder_path = 'gallery/' . $folder_path; } Database::query("INSERT INTO {$TABLETOOLDOCUMENT} (c_id, path,title,filetype,size)\n VALUES ({$course_id},'{$path_documents}" . $folder_path . "','" . $title . "','folder','0')"); $image_id = Database::insert_id(); Database::query("INSERT INTO {$TABLEITEMPROPERTY} (c_id, tool,insert_user_id,insert_date,lastedit_date,ref,lastedit_type,lastedit_user_id,to_group_id,to_user_id,visibility)\n VALUES ({$course_id},'document',1,'{$now}','{$now}',{$image_id},'DocumentAdded',1,NULL,NULL,0)"); } } if (isset($value['file']) && !empty($value['file'])) { if (!file_exists($course_documents_folder . $value['file'])) { //Copying file copy($default_course_path . $value['file'], $course_documents_folder . $value['file']); chmod($course_documents_folder . $value['file'], $perm_file); //echo $default_course_path.$value['file']; echo ' - '; echo $course_documents_folder.$value['file']; echo '<br />'; $temp = explode('/', $value['file']); $file_size = filesize($course_documents_folder . $value['file']); //hack until feature #5242 is implemented if ($media_type == 'images/gallery') { $value["file"] = 'gallery/' . $value["file"]; } //Inserting file in the DB Database::query("INSERT INTO {$TABLETOOLDOCUMENT} (c_id, path,title,filetype,size)\n VALUES ({$course_id},'{$path_documents}" . $value["file"] . "','" . $temp[count($temp) - 1] . "','file','{$file_size}')"); $image_id = Database::insert_id(); if ($image_id) { $sql = "UPDATE {$TABLETOOLDOCUMENT} SET id = iid WHERE iid = {$image_id}"; Database::query($sql); if ($path_documents . $value['file'] == '/certificates/default.html') { $example_cert_id = $image_id; } Database::query("INSERT INTO {$TABLEITEMPROPERTY} (c_id, tool,insert_user_id,insert_date,lastedit_date,ref,lastedit_type,lastedit_user_id,to_group_id,to_user_id,visibility)\n VALUES ({$course_id},'document',1,'{$now}','{$now}',{$image_id},'DocumentAdded',1,NULL,NULL,1)"); $docId = Database::insert_id(); if ($docId) { $sql = "UPDATE {$TABLEITEMPROPERTY} SET id = iid WHERE iid = {$docId}"; Database::query($sql); } } } } } } } } $agenda = new Agenda(); $agenda->setType('course'); $agenda->set_course($courseInfo); $agenda->addEvent($now, $now, 0, get_lang('AgendaCreationTitle'), get_lang('AgendaCreationContenu')); /* Links tool */ $link = new Link(); $link->setCourse($courseInfo); $links = [['c_id' => $course_id, 'url' => 'http://www.google.com', 'title' => 'Google', 'description' => get_lang('Google'), 'category_id' => 0, 'on_homepage' => 0, 'target' => '_self', 'session_id' => 0], ['c_id' => $course_id, 'url' => 'http://www.wikipedia.org', 'title' => 'Wikipedia', 'description' => get_lang('Wikipedia'), 'category_id' => 0, 'on_homepage' => 0, 'target' => '_self', 'session_id' => 0]]; foreach ($links as $params) { $link->save($params); } /* Announcement tool */ AnnouncementManager::add_announcement(get_lang('AnnouncementExampleTitle'), get_lang('AnnouncementEx'), ['everyone' => 'everyone'], null, null, $now); $manager = Database::getManager(); /* Introduction text */ $intro_text = '<p style="text-align: center;"> <img src="' . api_get_path(REL_CODE_PATH) . 'img/mascot.png" alt="Mr. Chamilo" title="Mr. Chamilo" /> <h2>' . self::lang2db(get_lang('IntroductionText')) . '</h2> </p>'; $toolIntro = new Chamilo\CourseBundle\Entity\CToolIntro(); $toolIntro->setCId($course_id)->setId(TOOL_COURSE_HOMEPAGE)->setSessionId(0)->setIntroText($intro_text); $manager->persist($toolIntro); $toolIntro = new Chamilo\CourseBundle\Entity\CToolIntro(); $toolIntro->setCId($course_id)->setId(TOOL_STUDENTPUBLICATION)->setSessionId(0)->setIntroText(get_lang('IntroductionTwo')); $manager->persist($toolIntro); $toolIntro = new Chamilo\CourseBundle\Entity\CToolIntro(); $toolIntro->setCId($course_id)->setId(TOOL_WIKI)->setSessionId(0)->setIntroText(get_lang('IntroductionWiki')); $manager->persist($toolIntro); $manager->flush(); /* Exercise tool */ $exercise = new Exercise($course_id); $exercise->exercise = get_lang('ExerciceEx'); $html = '<table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr> <td width="110" valign="top" align="left"> <img src="' . api_get_path(WEB_CODE_PATH) . 'default_course_document/images/mr_dokeos/thinking.jpg"> </td> <td valign="top" align="left">' . get_lang('Antique') . '</td></tr> </table>'; $exercise->type = 1; $exercise->setRandom(0); $exercise->active = 1; $exercise->results_disabled = 0; $exercise->description = $html; $exercise->save(); $exercise_id = $exercise->id; $question = new MultipleAnswer(); $question->question = get_lang('SocraticIrony'); $question->description = get_lang('ManyAnswers'); $question->weighting = 10; $question->position = 1; $question->course = $courseInfo; $question->save($exercise_id); $questionId = $question->id; $answer = new Answer($questionId, $courseInfo['real_id']); $answer->createAnswer(get_lang('Ridiculise'), 0, get_lang('NoPsychology'), -5, 1); $answer->createAnswer(get_lang('AdmitError'), 0, get_lang('NoSeduction'), -5, 2); $answer->createAnswer(get_lang('Force'), 1, get_lang('Indeed'), 5, 3); $answer->createAnswer(get_lang('Contradiction'), 1, get_lang('NotFalse'), 5, 4); $answer->save(); /* Forum tool */ require_once api_get_path(SYS_CODE_PATH) . 'forum/forumfunction.inc.php'; $params = ['forum_category_title' => get_lang('ExampleForumCategory'), 'forum_category_comment' => '']; $forumCategoryId = store_forumcategory($params, $courseInfo, false); $params = ['forum_category' => $forumCategoryId, 'forum_title' => get_lang('ExampleForum'), 'forum_comment' => '', 'default_view_type_group' => ['default_view_type' => 'flat']]; $forumId = store_forum($params, $courseInfo, true); $forumInfo = get_forum_information($forumId, $courseInfo['real_id']); $params = ['post_title' => get_lang('ExampleThread'), 'forum_id' => $forumId, 'post_text' => get_lang('ExampleThreadContent'), 'calification_notebook_title' => '', 'numeric_calification' => '', 'weight_calification' => '', 'forum_category' => $forumCategoryId, 'thread_peer_qualify' => 0]; store_thread($forumInfo, $params, $courseInfo, false); /* Gradebook tool */ $course_code = $courseInfo['code']; // father gradebook Database::query("INSERT INTO {$TABLEGRADEBOOK} (name, description, user_id, course_code, parent_id, weight, visible, certif_min_score, session_id, document_id)\n VALUES ('{$course_code}','',1,'{$course_code}',0,100,0,75,NULL,{$example_cert_id})"); $gbid = Database::insert_id(); Database::query("INSERT INTO {$TABLEGRADEBOOK} (name, description, user_id, course_code, parent_id, weight, visible, certif_min_score, session_id, document_id)\n VALUES ('{$course_code}','',1,'{$course_code}',{$gbid},100,1,75,NULL,{$example_cert_id})"); $gbid = Database::insert_id(); Database::query("INSERT INTO {$TABLEGRADEBOOKLINK} (type, ref_id, user_id, course_code, category_id, created_at, weight, visible, locked)\n VALUES (1,{$exercise_id},1,'{$course_code}',{$gbid},'{$now}',100,1,0)"); } //Installing plugins in course $app_plugin = new AppPlugin(); $app_plugin->install_course_plugins($course_id); $language_interface = $language_interface_original; return true; }
/** * @todo Fix tool_visible_by_default_at_creation labels * @todo Add sessionId parameter to avoid using context * * @param int $item_id * @param int $tool_id * @param int $group_id * @param array $courseInfo */ function api_set_default_visibility($item_id, $tool_id, $group_id = 0, $courseInfo = array()) { $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo; $courseId = $courseInfo['real_id']; $courseCode = $courseInfo['code']; $original_tool_id = $tool_id; switch ($tool_id) { case TOOL_LINK: case TOOL_LINK_CATEGORY: $tool_id = 'links'; break; case TOOL_DOCUMENT: $tool_id = 'documents'; break; case TOOL_LEARNPATH: $tool_id = 'learning'; break; case TOOL_ANNOUNCEMENT: $tool_id = 'announcements'; break; case TOOL_FORUM: case TOOL_FORUM_CATEGORY: case TOOL_FORUM_THREAD: $tool_id = 'forums'; break; case TOOL_QUIZ: $tool_id = 'quiz'; break; } $setting = api_get_setting('document.tool_visible_by_default_at_creation'); $visibility = 'invisible'; if (empty($group_id)) { $group_id = api_get_group_id(); } if (isset($setting[$tool_id])) { if ($setting[$tool_id] == 'true') { $visibility = 'visible'; } } // Read the portal and course default visibility if ($tool_id == 'documents') { $visibility = DocumentManager::getDocumentDefaultVisibility($courseCode); } api_item_property_update($courseInfo, $original_tool_id, $item_id, $visibility, api_get_user_id(), $group_id, null, null, null, api_get_session_id()); // Fixes default visibility for tests switch ($original_tool_id) { case TOOL_QUIZ: $objExerciseTmp = new Exercise($courseId); $objExerciseTmp->read($item_id); if ($visibility == 'visible') { $objExerciseTmp->enable(); $objExerciseTmp->save(); } else { $objExerciseTmp->disable(); $objExerciseTmp->save(); } break; } }
case 'delete': // deletes an exercise if ($exercise_action_locked == false) { $objExerciseTmp->delete(); require_once api_get_path(SYS_CODE_PATH) . 'gradebook/lib/gradebook_functions.inc.php'; $link_info = is_resource_in_course_gradebook(api_get_course_id(), 1, $exerciseId, api_get_session_id()); if ($link_info !== false) { remove_resource_from_course_gradebook($link_info['id']); } Display::display_confirmation_message(get_lang('ExerciseDeleted')); } break; case 'enable': // enables an exercise $objExerciseTmp->enable(); $objExerciseTmp->save(); api_item_property_update($course_info, TOOL_QUIZ, $objExerciseTmp->id, 'visible', api_get_user_id()); // "WHAT'S NEW" notification: update table item_property (previously last_tooledit) Display::display_confirmation_message(get_lang('VisibilityChanged')); break; case 'disable': // disables an exercise $objExerciseTmp->disable(); $objExerciseTmp->save(); api_item_property_update($course_info, TOOL_QUIZ, $objExerciseTmp->id, 'invisible', api_get_user_id()); Display::display_confirmation_message(get_lang('VisibilityChanged')); break; case 'disable_results': //disable the results for the learners $objExerciseTmp->disable_results(); $objExerciseTmp->save();
public function createExercises($ids) { $result = array('added' => array(), 'found' => array()); foreach ($ids as $id) { $exercise = new Exercise(); $exercise->assignment_id = $this->id; $exercise->student_id = $id; $exercise->duedate = $this->duedate; // it can be customized later for each student separately $exercise->status = Exercise::STATUS_ASSIGNED; $done = false; while (!$done) { $s = sprintf('%05d%04d', floor(rand(10000, 99999)), $this->id); // first, we generate a string with a 5-digit random value and a 4-digit id $s = sprintf('%s-%s-%s', $s[0] . $s[5] . $s[1], $s[6] . $s[2] . $s[7], $s[3] . $s[8] . $s[4]); // second, we split the 9 digits in 3 pieces, mixing them up and adding two minus signs $exercise->code = $s; try { $exercise->save(); $result['added'][] = $id; $done = true; } catch (Exception $e) { // we can fail for one of these two reasons: // 1: the exercise is already there if (strpos($e->getMessage(), "key 'assignment_student'") !== false) { $result['found'][] = $id; $done = true; } // 2: we generated the same code twice // we don't need to do anything, since we are in a loop and the code will get regenerated } } // end while } // end foreach return $result; }
/** * Imports an exercise in QTI format if the XML structure can be found in it * @param array $file * @return an array as a backlog of what was really imported, and error or debug messages to display */ function import_exercise($file) { global $exercise_info; global $element_pile; global $non_HTML_tag_to_avoid; global $record_item_body; // used to specify the question directory where files could be found in relation in any question global $questionTempDir; $archive_path = api_get_path(SYS_ARCHIVE_PATH) . 'qti2'; $baseWorkDir = $archive_path; if (!is_dir($baseWorkDir)) { mkdir($baseWorkDir, api_get_permissions_for_new_directories(), true); } $uploadPath = '/'; // set some default values for the new exercise $exercise_info = array(); $exercise_info['name'] = preg_replace('/.zip$/i', '', $file); $exercise_info['question'] = array(); $element_pile = array(); // create parser and array to retrieve info from manifest $element_pile = array(); //pile to known the depth in which we are //$module_info = array (); //array to store the info we need // if file is not a .zip, then we cancel all if (!preg_match('/.zip$/i', $file)) { return 'UplZipCorrupt'; } // unzip the uploaded file in a tmp directory if (!get_and_unzip_uploaded_exercise($baseWorkDir, $uploadPath)) { return 'UplZipCorrupt'; } // find the different manifests for each question and parse them. $exerciseHandle = opendir($baseWorkDir); //$question_number = 0; $file_found = false; $operation = false; $result = false; $filePath = null; // parse every subdirectory to search xml question files while (false !== ($file = readdir($exerciseHandle))) { if (is_dir($baseWorkDir . '/' . $file) && $file != "." && $file != "..") { // Find each manifest for each question repository found $questionHandle = opendir($baseWorkDir . '/' . $file); while (false !== ($questionFile = readdir($questionHandle))) { if (preg_match('/.xml$/i', $questionFile)) { $result = parse_file($baseWorkDir, $file, $questionFile); $filePath = $baseWorkDir . $file; $file_found = true; } } } elseif (preg_match('/.xml$/i', $file)) { // Else ignore file $result = parse_file($baseWorkDir, '', $file); $filePath = $baseWorkDir . '/' . $file; $file_found = true; } } if (!$file_found) { return 'NoXMLFileFoundInTheZip'; } if ($result == false) { return false; } $doc = new DOMDocument(); $doc->load($filePath); $encoding = $doc->encoding; // 1. Create exercise. $exercise = new Exercise(); $exercise->exercise = $exercise_info['name']; $exercise->save(); $last_exercise_id = $exercise->selectId(); if (!empty($last_exercise_id)) { // For each question found... foreach ($exercise_info['question'] as $question_array) { //2. Create question $question = new Ims2Question(); $question->type = $question_array['type']; $question->setAnswer(); $question->updateTitle(formatText($question_array['title'])); //$question->updateDescription($question_array['title']); $type = $question->selectType(); $question->type = constant($type); $question->save($last_exercise_id); $last_question_id = $question->selectId(); //3. Create answer $answer = new Answer($last_question_id); $answer->new_nbrAnswers = count($question_array['answer']); $totalCorrectWeight = 0; foreach ($question_array['answer'] as $key => $answers) { $split = explode('_', $key); $i = $split[1]; // Answer $answer->new_answer[$i] = formatText($answers['value']); // Comment $answer->new_comment[$i] = isset($answers['feedback']) ? formatText($answers['feedback']) : null; // Position $answer->new_position[$i] = $i; // Correct answers if (in_array($key, $question_array['correct_answers'])) { $answer->new_correct[$i] = 1; } else { $answer->new_correct[$i] = 0; } $answer->new_weighting[$i] = $question_array['weighting'][$key]; if ($answer->new_correct[$i]) { $totalCorrectWeight = $answer->new_weighting[$i]; } } $question->updateWeighting($totalCorrectWeight); $question->save($last_exercise_id); $answer->save(); } // delete the temp dir where the exercise was unzipped my_delete($baseWorkDir . $uploadPath); return $last_exercise_id; } return false; }
$exercise->setStartDate(mktime($_REQUEST['startHour'], $_REQUEST['startMinute'], 0, $_REQUEST['startMonth'], $_REQUEST['startDay'], $_REQUEST['startYear'])); if (isset($_REQUEST['useEndDate']) && $_REQUEST['useEndDate']) { $exercise->setEndDate(mktime($_REQUEST['endHour'], $_REQUEST['endMinute'], 0, $_REQUEST['endMonth'], $_REQUEST['endDay'], $_REQUEST['endYear'])); } else { $exercise->setEndDate(null); } if (isset($_REQUEST['useTimeLimit']) && $_REQUEST['useTimeLimit']) { $exercise->setTimeLimit($_REQUEST['timeLimitMin'] * 60 + $_REQUEST['timeLimitSec']); } else { $exercise->setTimeLimit(0); } $exercise->setAttempts($_REQUEST['attempts']); $exercise->setAnonymousAttempts($_REQUEST['anonymousAttempts']); $exercise->setQuizEndMessage($_REQUEST['quizEndMessage']); if ($exercise->validate()) { if ($insertedId = $exercise->save()) { if (is_null($exId)) { $dialogBox->success(get_lang('Exercise added')); $eventNotifier->notifyCourseEvent("exercise_added", claro_get_current_course_id(), claro_get_current_tool_id(), $insertedId, claro_get_current_group_id(), "0"); $exId = $insertedId; } else { $dialogBox->success(get_lang('Exercise modified')); $eventNotifier->notifyCourseEvent("exercise_updated", claro_get_current_course_id(), claro_get_current_tool_id(), $insertedId, claro_get_current_group_id(), "0"); } $displaySettings = true; } else { // sql error in save() ? $cmd = 'rqEdit'; } } else { if (claro_failure::get_last_failure() == 'exercise_no_title') {
/** * This function sets the default visibility for any given content, using the * default visibility setting of the corresponding tool. For example, if we * create a new quiz and call this function, if the quiz tool is * invisible/disabled at course creation, the quiz itself will be set to * invisible. * @param array|\Entity\Course $course * @param int The ID of the item in its own table * @param string The string identifier of the tool * @param int The group ID, in case we want to specify it * @param int The integer course ID, in case we cannot get it from the context * @todo Fix tool_visible_by_default_at_creation labels */ function api_set_default_visibility($course, $item_id, $tool_id, $group_id = null) { $original_tool_id = $tool_id; switch ($tool_id) { case TOOL_LINK: $tool_id = 'links'; break; case TOOL_DOCUMENT: $tool_id = 'documents'; break; case TOOL_LEARNPATH: $tool_id = 'learning'; break; case TOOL_ANNOUNCEMENT: $tool_id = 'announcements'; break; case TOOL_FORUM: case TOOL_FORUM_CATEGORY: case TOOL_FORUM_THREAD: $tool_id = 'forums'; break; case TOOL_QUIZ: $tool_id = 'quiz'; break; } $setting = api_get_setting('tool_visible_by_default_at_creation'); if (is_array($course)) { $courseId = $course['real_id']; } else { if ($course instanceof Course) { $courseId = $course->getId(); } } if (isset($setting[$tool_id])) { $visibility = 'invisible'; if ($setting[$tool_id] == 'true') { $visibility = 'visible'; } if (empty($group_id)) { $group_id = api_get_group_id(); } api_item_property_update($course, $original_tool_id, $item_id, $visibility, api_get_user_id(), $group_id, null, null, null, api_get_session_id()); // Fixes default visibility for tests switch ($original_tool_id) { case TOOL_QUIZ: $objExerciseTmp = new Exercise($courseId); $objExerciseTmp->read($item_id); if ($visibility == 'visible') { $objExerciseTmp->enable(); $objExerciseTmp->save(); } else { $objExerciseTmp->disable(); $objExerciseTmp->save(); } break; } } }
/** * Main function to import the Aiken exercise * @return mixed True on success, error message on failure */ function aiken_import_exercise($file) { global $exercise_info; global $element_pile; global $non_HTML_tag_to_avoid; global $record_item_body; // used to specify the question directory where files could be found in relation in any question global $questionTempDir; $archive_path = api_get_path(SYS_ARCHIVE_PATH) . 'aiken'; $baseWorkDir = $archive_path; if (!is_dir($baseWorkDir)) { mkdir($baseWorkDir, api_get_permissions_for_new_directories(), true); } $uploadPath = '/'; // set some default values for the new exercise $exercise_info = array(); $exercise_info['name'] = preg_replace('/.(zip|txt)$/i', '', $file); $exercise_info['question'] = array(); $element_pile = array(); // create parser and array to retrieve info from manifest $element_pile = array(); //pile to known the depth in which we are // if file is not a .zip, then we cancel all if (!preg_match('/.(zip|txt)$/i', $file)) { //Display :: display_error_message(get_lang('YouMustUploadAZipOrTxtFile')); return 'YouMustUploadAZipOrTxtFile'; } // unzip the uploaded file in a tmp directory if (preg_match('/.(zip|txt)$/i', $file)) { if (!get_and_unzip_uploaded_exercise($baseWorkDir, $uploadPath)) { return 'ThereWasAProblemWithYourFile'; } } // find the different manifests for each question and parse them $exerciseHandle = opendir($baseWorkDir); $file_found = false; $operation = false; $result = false; // Parse every subdirectory to search txt question files while (false !== ($file = readdir($exerciseHandle))) { if (is_dir($baseWorkDir . '/' . $file) && $file != "." && $file != "..") { //find each manifest for each question repository found $questionHandle = opendir($baseWorkDir . '/' . $file); while (false !== ($questionFile = readdir($questionHandle))) { if (preg_match('/.txt$/i', $questionFile)) { $result = aiken_parse_file($exercise_info, $baseWorkDir, $file, $questionFile); $file_found = true; } } } elseif (preg_match('/.txt$/i', $file)) { $result = aiken_parse_file($exercise_info, $baseWorkDir, '', $file); $file_found = true; } // else ignore file } if (!$file_found) { $result = 'NoTxtFileFoundInTheZip'; } if ($result !== true) { return $result; } // Add exercise in tool // 1.create exercise $exercise = new Exercise(); $exercise->exercise = $exercise_info['name']; $exercise->save(); $last_exercise_id = $exercise->selectId(); if (!empty($last_exercise_id)) { // For each question found... foreach ($exercise_info['question'] as $key => $question_array) { //2.create question $question = new Aiken2Question(); $question->type = $question_array['type']; $question->setAnswer(); $question->updateTitle($question_array['title']); $question->updateDescription($question_array['description']); $type = $question->selectType(); $question->type = constant($type); $question->save($last_exercise_id); $last_question_id = $question->selectId(); //3.create answer $answer = new Answer($last_question_id); $answer->new_nbrAnswers = count($question_array['answer']); $max_score = 0; foreach ($question_array['answer'] as $key => $answers) { $key++; $answer->new_answer[$key] = $answers['value']; $answer->new_position[$key] = $key; // Correct answers ... if (in_array($key, $question_array['correct_answers'])) { $answer->new_correct[$key] = 1; $answer->new_comment[$key] = $question_array['feedback']; } else { $answer->new_correct[$key] = 0; } $answer->new_weighting[$key] = $question_array['weighting'][$key - 1]; $max_score += $question_array['weighting'][$key - 1]; } $answer->save(); // Now that we know the question score, set it! $question->updateWeighting($max_score); $question->save(); } // delete the temp dir where the exercise was unzipped my_delete($baseWorkDir . $uploadPath); $operation = $last_exercise_id; } return $operation; }
/** * Function rewritten based on old_add_item() from Yannick Warnier. * Due the fact that users can decide where the item should come, I had to overlook this function and * I found it better to rewrite it. Old function is still available. * Added also the possibility to add a description. * * @param int $parent * @param int $previous * @param string $type * @param int resource ID (ref) * @param string $title * @param string $description * @param int $prerequisites * @param int $max_time_allowed * @param int $userId * * @return int */ public function add_item($parent, $previous, $type = 'dokeos_chapter', $id, $title, $description, $prerequisites = 0, $max_time_allowed = 0, $userId = 0) { $course_id = $this->course_info['real_id']; if ($this->debug > 0) { error_log('New LP - In learnpath::add_item(' . $parent . ',' . $previous . ',' . $type . ',' . $id . ',' . $title . ')', 0); } if (empty($course_id)) { // Sometimes Oogie doesn't catch the course info but sets $this->cc $this->course_info = api_get_course_info($this->cc); $course_id = $this->course_info['real_id']; } $userId = empty($userId) ? api_get_user_id() : $userId; $sessionId = api_get_session_id(); $tbl_lp_item = Database::get_course_table(TABLE_LP_ITEM); $_course = $this->course_info; $parent = intval($parent); $previous = intval($previous); $id = intval($id); $max_time_allowed = htmlentities($max_time_allowed); if (empty($max_time_allowed)) { $max_time_allowed = 0; } $sql = "SELECT COUNT(id) AS num\n FROM {$tbl_lp_item}\n WHERE\n c_id = {$course_id} AND\n lp_id = " . $this->get_id() . " AND\n parent_item_id = " . $parent; $res_count = Database::query($sql); $row = Database::fetch_array($res_count); $num = $row['num']; if ($num > 0) { if ($previous == 0) { $sql = "SELECT id, next_item_id, display_order\n FROM " . $tbl_lp_item . "\n WHERE\n c_id = {$course_id} AND\n lp_id = " . $this->get_id() . " AND\n parent_item_id = " . $parent . " AND\n previous_item_id = 0 OR\n previous_item_id=" . $parent; $result = Database::query($sql); $row = Database::fetch_array($result); $tmp_previous = 0; $next = $row['id']; $display_order = 0; } else { $previous = (int) $previous; $sql = "SELECT id, previous_item_id, next_item_id, display_order\n\t\t\t\t\t\tFROM {$tbl_lp_item}\n WHERE\n c_id = {$course_id} AND\n lp_id = " . $this->get_id() . " AND\n id = " . $previous; $result = Database::query($sql); $row = Database::fetch_array($result); $tmp_previous = $row['id']; $next = $row['next_item_id']; $display_order = $row['display_order']; } } else { $tmp_previous = 0; $next = 0; $display_order = 0; } $id = intval($id); $typeCleaned = Database::escape_string($type); if ($type == 'quiz') { $sql = 'SELECT SUM(ponderation) FROM ' . Database::get_course_table(TABLE_QUIZ_QUESTION) . ' as quiz_question INNER JOIN ' . Database::get_course_table(TABLE_QUIZ_TEST_QUESTION) . ' as quiz_rel_question ON quiz_question.id = quiz_rel_question.question_id AND quiz_question.c_id = quiz_rel_question.c_id WHERE quiz_rel_question.exercice_id = ' . $id . " AND\n quiz_question.c_id = {$course_id} AND\n quiz_rel_question.c_id = {$course_id} "; $rsQuiz = Database::query($sql); $max_score = Database::result($rsQuiz, 0, 0); // Disabling the exercise if we add it inside a LP $exercise = new Exercise($course_id); $exercise->read($id); $exercise->disable(); $exercise->save(); } else { $max_score = 100; } $params = array("c_id" => $course_id, "lp_id" => $this->get_id(), "item_type" => $typeCleaned, "ref" => '', "title" => $title, "description" => $description, "path" => $id, "max_score" => $max_score, "parent_item_id" => $parent, "previous_item_id" => $previous, "next_item_id" => intval($next), "display_order" => $display_order + 1, "prerequisite" => $prerequisites, "max_time_allowed" => $max_time_allowed, 'min_score' => 0, 'launch_data' => ''); if ($prerequisites != 0) { $params['prerequisite'] = $prerequisites; } $new_item_id = Database::insert($tbl_lp_item, $params); if ($this->debug > 2) { error_log('New LP - Inserting chapter: ' . $new_item_id, 0); } if ($new_item_id) { $sql = "UPDATE {$tbl_lp_item} SET id = iid WHERE iid = {$new_item_id}"; Database::query($sql); // Update the item that should come after the new item. $sql = " UPDATE {$tbl_lp_item} SET\n previous_item_id = {$new_item_id},\n next_item_id = {$new_item_id},\n id = {$new_item_id}\n WHERE iid = {$new_item_id}"; Database::query($sql); // Update all the items after the new item. $sql = "UPDATE " . $tbl_lp_item . "\n SET display_order = display_order + 1\n WHERE\n c_id = {$course_id} AND\n lp_id = " . $this->get_id() . " AND\n id <> " . $new_item_id . " AND\n parent_item_id = " . $parent . " AND\n display_order > " . $display_order; Database::query($sql); // Update the item that should come after the new item. $sql = "UPDATE " . $tbl_lp_item . "\n SET ref = " . $new_item_id . "\n WHERE c_id = {$course_id} AND id = " . $new_item_id; Database::query($sql); // Upload audio. if (!empty($_FILES['mp3']['name'])) { // Create the audio folder if it does not exist yet. $filepath = api_get_path(SYS_COURSE_PATH) . $_course['path'] . '/document/'; if (!is_dir($filepath . 'audio')) { mkdir($filepath . 'audio', api_get_permissions_for_new_directories()); $audio_id = add_document($_course, '/audio', 'folder', 0, 'audio', '', 0, true, null, $sessionId, $userId); api_item_property_update($_course, TOOL_DOCUMENT, $audio_id, 'FolderCreated', $userId, null, null, null, null, $sessionId); api_item_property_update($_course, TOOL_DOCUMENT, $audio_id, 'invisible', $userId, null, null, null, null, $sessionId); } $file_path = handle_uploaded_document($_course, $_FILES['mp3'], api_get_path(SYS_COURSE_PATH) . $_course['path'] . '/document', '/audio', $userId, '', '', '', '', false); // Getting the filename only. $file_components = explode('/', $file_path); $file = $file_components[count($file_components) - 1]; // Store the mp3 file in the lp_item table. $sql = "UPDATE {$tbl_lp_item} SET\n audio = '" . Database::escape_string($file) . "'\n WHERE id = '" . intval($new_item_id) . "'"; Database::query($sql); } } return $new_item_id; }
public function welcome_intro() { if (!$this->valid_logged_in) { redirect('users/login'); } $this->load->library('form_validation'); $this->load->helper('form'); $default_exercises = array(array('name' => 'run', 'label' => 'Run'), array('name' => 'bike', 'label' => 'Bike'), array('name' => 'swim', 'label' => 'Swim'), array('name' => 'walk', 'label' => 'Walk')); // TODO : this needs to be handled better if ($this->form_validation->run('exercises_welcome_intro') == FALSE) { $data['default_exercises'] = $default_exercises; } else { $user = new User($this->user_id); $run = $this->input->post('run'); $bike = $this->input->post('bike'); $swim = $this->input->post('swim'); $walk = $this->input->post('walk'); if ($run) { $run = new Exercise(); $run->name = 'Run'; $run->save($user); } if ($bike) { $bike = new Exercise(); $bike->name = 'Bike'; $bike->save($user); } if ($swim) { $swim = new Exercise(); $swim->name = 'Swim'; $swim->save($user); } if ($walk) { $walk = new Exercise(); $walk->name = 'Walk'; $walk->save($user); } // TODO : Change redirecet after welcome_intro redirect('exercises/view'); } $data['title'] = 'Welcome'; $data['content'] = 'exercises/welcome_intro'; $this->load->view('master', $data); }
/** * Main function to import an exercise. * * @param string $file path of the file * @param array $backlog_message * * @return the id of the created exercise or false if the operation failed */ function import_exercise($file, &$backlog) { global $exercise_info; global $element_pile; global $non_HTML_tag_to_avoid; global $record_item_body; // used to specify the question directory where files could be found in relation in any question global $questionTempDir; // get required table names $tbl_cdb_names = get_module_course_tbl(array('qwz_exercise', 'qwz_question'), claro_get_current_course_id()); $tbl_quiz_exercise = $tbl_cdb_names['qwz_exercise']; $tbl_quiz_question = $tbl_cdb_names['qwz_question']; // paths $baseWorkDir = get_path('rootSys') . get_conf('tmpPathSys') . 'upload/'; // create temp dir for upload if (!file_exists($baseWorkDir)) { claro_mkdir($baseWorkDir, CLARO_FILE_PERMISSIONS); } $uploadDir = claro_mkdir_tmp($baseWorkDir); // this function should return the dir name and not the full path ... $uploadPath = str_replace($baseWorkDir, '', $uploadDir); // set some default values for the new exercise $exercise_info = array(); $exercise_info['name'] = preg_replace('/.zip$/i', '', $file); $exercise_info['description'] = ''; $exercise_info['question'] = array(); // create parser and array to retrieve info from manifest $element_pile = array(); //pile to known the depth in which we are $module_info = array(); //array to store the info we need // if file is not a .zip, then we cancel all if (!preg_match('/.zip$/i', $_FILES['uploadedExercise']['name'])) { $backlog->failure(get_lang('You must upload a zip file')); return false; } //unzip the uploaded file in a tmp directory if (!get_and_unzip_uploaded_exercise($baseWorkDir, $uploadPath)) { $backlog->failure(get_lang('Upload failed')); return false; } // find the different manifests for each question and parse them. $exerciseHandle = opendir($uploadDir); $question_number = 0; $file_found = false; // parse every subdirectory to search xml question files while (false !== ($file = readdir($exerciseHandle))) { if (is_dir($uploadDir . '/' . $file) && $file != "." && $file != "..") { //find each manifest for each question repository found $questionHandle = opendir($uploadDir . '/' . $file); while (false !== ($questionFile = readdir($questionHandle))) { if (preg_match('/.xml$/i', $questionFile)) { list($parsingBacklog, $success) = parse_file($uploadDir, $file, $questionFile); $backlog->append($parsingBacklog); $file_found = true; } } } elseif (preg_match('/.xml$/i', $file)) { list($parsingBacklog, $success) = parse_file($uploadDir, '', $file); $backlog->append($parsingBacklog); $file_found = true; } // else ignore file } if (!$file_found) { $backlog->failure(get_lang('No XML file found in the zip')); return false; } //--------------------- //add exercise in tool //--------------------- //1.create exercise $exercise = new Exercise(); $exercise->setTitle($exercise_info['name']); $exercise->setDescription($exercise_info['description']); if ($exercise->validate()) { $exercise_id = $exercise->save(); } else { $backlog->failure(get_lang('There is an error in exercise data of imported file.')); return false; } ksort($exercise_info['question'], SORT_NUMERIC); //For each question found... foreach ($exercise_info['question'] as $key => $question_array) { //2.create question $question = new Qti2Question(); $question->import($question_array); if ($question->validate()) { // I need to save the question after the answer because I need question id in answers $question_id = $question->save(); //3.create answers $question->setAnswer(); $question->answer->import($question_array); if ($question->answer->validate()) { $question->setGrade($question->answer->getGrade()); $question->save(); // save computed grade $question->answer->save(); $exercise->addQuestion($question_id); } else { $backlog->failure(get_lang('Invalid answer') . ' : ' . $key); } } else { $backlog->failure(get_lang('Invalid question') . ' : ' . $key); } } // delete the temp dir where the exercise was unzipped claro_delete_file($uploadDir); return $exercise_id; }
/** * Copies an exercise (duplicate all questions and answers) */ public function copy_exercise() { $original_exercise = $this; $exercise_obj = new Exercise(); $exercise_obj->setCategoriesGrouping(false); $exercise_obj->read($this->id); // force the creation of a new exercise $exercise_obj->updateTitle($exercise_obj->selectTitle() . ' - ' . get_lang('Copy')); //Hides the new exercise $exercise_obj->updateStatus(false); $exercise_obj->updateId(0); $exercise_obj->save(); $exercise_obj->save_exercise_list_order($this->course['real_id'], api_get_session_id()); $new_exercise_id = $exercise_obj->selectId(); if ($new_exercise_id) { $original_exercise->copy_exercise_categories($exercise_obj); $question_list = $exercise_obj->getQuestionListWithMediasUncompressed(); if (!empty($question_list)) { //Question creation foreach ($question_list as $old_question_id) { $old_question_obj = Question::read($old_question_id); $new_id = $old_question_obj->duplicate(); if ($new_id) { $new_question_obj = Question::read($new_id); if (isset($new_question_obj) && $new_question_obj) { $new_question_obj->addToList($new_exercise_id); // This should be moved to the duplicate function $new_answer_obj = new Answer($old_question_id); //$new_answer_obj->read(); $new_answer_obj->duplicate($new_id); } } } } } }
/** * main function to import an exercise, * * @return an array as a backlog of what was really imported, and error or debug messages to display */ function import_exercise($file) { global $exercise_info; global $element_pile; global $non_HTML_tag_to_avoid; global $record_item_body; // used to specify the question directory where files could be found in relation in any question global $questionTempDir; $archive_path = api_get_path(SYS_ARCHIVE_PATH) . 'qti2'; $baseWorkDir = $archive_path; if (!is_dir($baseWorkDir)) { mkdir($baseWorkDir, api_get_permissions_for_new_directories(), true); } $uploadPath = '/'; // set some default values for the new exercise $exercise_info = array(); $exercise_info['name'] = preg_replace('/.zip$/i', '', $file); $exercise_info['question'] = array(); $element_pile = array(); // create parser and array to retrieve info from manifest $element_pile = array(); //pile to known the depth in which we are //$module_info = array (); //array to store the info we need // if file is not a .zip, then we cancel all if (!preg_match('/.zip$/i', $file)) { Display::display_error_message(get_lang('You must upload a zip file')); return false; } // unzip the uploaded file in a tmp directory if (!get_and_unzip_uploaded_exercise($baseWorkDir, $uploadPath)) { Display::display_error_message(get_lang('You must upload a zip file')); return false; } // find the different manifests for each question and parse them. $exerciseHandle = opendir($baseWorkDir); //$question_number = 0; $file_found = false; $operation = false; $result = false; // parse every subdirectory to search xml question files while (false !== ($file = readdir($exerciseHandle))) { if (is_dir($baseWorkDir . '/' . $file) && $file != "." && $file != "..") { //find each manifest for each question repository found $questionHandle = opendir($baseWorkDir . '/' . $file); while (false !== ($questionFile = readdir($questionHandle))) { if (preg_match('/.xml$/i', $questionFile)) { $result = parse_file($baseWorkDir, $file, $questionFile); $file_found = true; } } } elseif (preg_match('/.xml$/i', $file)) { $result = parse_file($baseWorkDir, '', $file); $file_found = true; } // else ignore file } if (!$file_found) { Display::display_error_message(get_lang('No XML file found in the zip')); return false; } if ($result == false) { return false; } //add exercise in tool //1.create exercise $exercise = new Exercise(); $exercise->exercise = $exercise_info['name']; $exercise->save(); $last_exercise_id = $exercise->selectId(); if (!empty($last_exercise_id)) { //For each question found... foreach ($exercise_info['question'] as $key => $question_array) { //2.create question $question = new Ims2Question(); $question->type = $question_array['type']; $question->setAnswer(); $question->updateTitle($question_array['title']); // question ... $type = $question->selectType(); $question->type = constant($type); // type ... $question->save($last_exercise_id); // save computed grade $last_question_id = $question->selectId(); //3.create answer $answer = new Answer($last_question_id); $answer->new_nbrAnswers = count($question_array['answer']); foreach ($question_array['answer'] as $key => $answers) { $split = explode('_', $key); $i = $split[1]; $answer->new_answer[$i] = $answers['value']; // answer ... $answer->new_comment[$i] = $answers['feedback']; // comment ... $answer->new_position[$i] = $i; // position ... // correct answers ... if (in_array($key, $question_array['correct_answers'])) { $answer->new_correct[$i] = 1; } else { $answer->new_correct[$i] = 0; } $answer->new_weighting[$i] = $question_array['weighting'][$key]; } $answer->save(); } // delete the temp dir where the exercise was unzipped FileManager::my_delete($baseWorkDir . $uploadPath); $operation = true; } return $operation; }
/** * Loads the data and injects it into the Chamilo database, using the Chamilo * internal functions. * @return array List of user IDs for the users that have just been inserted */ function fill_exe() { $qc = 5000; //how many questions to create per exercise $eol = PHP_EOL; $courses = array(); //declare only to avoid parsing notice $qst = array(); require_once 'data_exe.php'; //fill the $users array $output = array(); $output[] = array('title' => 'Exe Filling Report: '); $i = 1; $lib = api_get_path(SYS_CODE_PATH); require_once $lib . 'exercice/exercise.class.php'; require_once $lib . 'exercice/question.class.php'; require_once $lib . 'exercice/answer.class.php'; foreach ($courses as $i => $course) { //first check that the first item doesn't exist already $output[$i]['line-init'] = $course['title']; $res = CourseManager::create_course($course); $output[$i]['line-info'] = $res ? $res : get_lang('NotInserted'); $i++; if (is_array($res)) { //now insert an exercise foreach ($course['exes'] as $exe) { $objExercise = new Exercise($res['real_id']); $objExercise->id = 0; $objExercise->course_id = $res['real_id']; $objExercise->exercise = $exe['title']; $objExercise->type = 1; $objExercise->attempts = $exe['attempts']; $objExercise->random = $exe['random']; $objExercise->active = 1; $objExercise->propagate_neg = 0; $objExercise->pass_percentage = $exe['pass_percentage']; $objExercise->session_id = 0; $objExercise->results_disabled = 0; $objExercise->expired_time = $exe['time']; $objExercise->review_answers = $exe['review_answers']; $objExercise->save(); $id = $objExercise->id; if (!empty($id)) { $qi = 0; while ($qi < $qc) { foreach ($qst as $q) { error_log('Created ' . $qi . ' questions'); $question = Question::getInstance($q['type']); $question->id = 0; $question->question = $q['title'] . ' ' . $qi; $question->description = $q['desc']; $question->type = $q['type']; $question->course = $res; $r = $question->save($id); if ($r === false) { continue; } $qid = $question->id; $objExercise->addToList($qid); $objExercise->update_question_positions(); $aid = 1; foreach ($q['answers'] as $asw) { $answer = new UniqueAnswer($qid); $answer->create_answer($aid, $qid, $asw['title'], '', $asw['score'], $asw['correct'], $res['real_id']); $aid++; } $qi++; } } } } } } return $output; }