Browse Source

Merge pull request #1352 from jloguercio/1.11.x

Fix question files import in moodle import - Refs BT#11209
José Loguercio 8 years ago
parent
commit
7f72706eb7

+ 2 - 1
main/coursecopy/import_moodle.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+use ChamiloSession as Session;
 
 /**
  * Import a backup from moodle system.
@@ -42,12 +43,12 @@ if ($form->validate()) {
     $file = $_FILES['moodle_file'];
     $moodleImport = new MoodleImport();
     $responseImport = $moodleImport->readMoodleFile($file);
+    Session::erase('flash_messages');
     if ($responseImport) {
         Display::addFlash(Display::return_message(get_lang('MoodleFileImportedSuccessfull'), 'success'));
     } else {
         Display::addFlash(Display::return_message(get_lang('ErrorImportingFile'), 'error'));
     }
-    header('Location: ' . api_get_self() . '?' . api_get_cidreq());
 }
 
 $templateName = get_lang('ImportFromMoodle');

+ 107 - 4
main/inc/lib/MoodleImport.class.php

@@ -37,7 +37,7 @@ class MoodleImport
 
             $folder = api_get_unique_id();
             $destinationDir = api_get_path(SYS_ARCHIVE_PATH).$folder;
-            $coursePath = api_get_path(SYS_COURSE_PATH).api_get_course_path().'/';
+            $coursePath = api_get_course_path();
             $courseInfo = api_get_course_info();
 
             mkdir($destinationDir, api_get_permissions_for_new_directories(), true);
@@ -75,12 +75,13 @@ class MoodleImport
                                 // Create a Forum category based on Moodle forum type.
                                 $catForumValues['forum_category_title'] = $moduleValues['type'];
                                 $catForumValues['forum_category_comment'] = '';
-                                $catId = store_forumcategory($catForumValues);
+                                $catId = store_forumcategory($catForumValues, [], false);
                                 $forumValues = [];
                                 $forumValues['forum_title'] = $moduleValues['name'];
                                 $forumValues['forum_image'] = '';
                                 $forumValues['forum_comment'] = $moduleValues['intro'];
                                 $forumValues['forum_category'] = $catId;
+                                $forumValues['moderated'] = 0;
 
                                 store_forum($forumValues);
                                 break;
@@ -142,6 +143,9 @@ class MoodleImport
                                     $questionInstance = Question::getInstance($moduleValues['question_instances'][$index]['chamilo_qtype']);
                                     if ($questionInstance) {
                                         $questionInstance->updateTitle($moduleValues['question_instances'][$index]['name']);
+
+                                        // Replace the path from @@PLUGINFILE@@ to a correct chamilo path
+                                        $moduleValues['question_instances'][$index]['questiontext'] = str_replace('@@PLUGINFILE@@', '/courses/' . $coursePath . '/document', $moduleValues['question_instances'][$index]['questiontext']);
                                         $questionInstance->updateDescription($moduleValues['question_instances'][$index]['questiontext']);
                                         $questionInstance->updateLevel(1);
                                         $questionInstance->updateCategory(0);
@@ -171,7 +175,6 @@ class MoodleImport
                                 $moduleValues = $this->readResourceModule($moduleXml);
                                 $mainFileModuleValues = $this->readMainFilesXml($filesXml, $moduleValues['contextid']);
                                 $fileInfo = array_merge($moduleValues, $mainFileModuleValues, $currentItem);
-                                $documentPath = $coursePath.'document/';
                                 $currentResourceFilePath = $destinationDir.'/files/';
                                 $dirs = new RecursiveDirectoryIterator($currentResourceFilePath);
                                 foreach (new RecursiveIteratorIterator($dirs) as $file) {
@@ -217,6 +220,44 @@ class MoodleImport
                         }
                     }
                 }
+
+                // This process will upload all question resource files
+                $filesXml = @file_get_contents($destinationDir.'/files.xml');
+                $mainFileModuleValues = $this->getAllQuestionFiles($filesXml);
+                $currentResourceFilePath = $destinationDir.'/files/';
+
+                foreach ($mainFileModuleValues as $fileInfo) {
+                    $dirs = new RecursiveDirectoryIterator($currentResourceFilePath);
+                    foreach (new RecursiveIteratorIterator($dirs) as $file) {
+                        if (is_file($file) && strpos($file, $fileInfo['contenthash']) !== false) {
+                            $files = [];
+                            $files['file']['name'] = $fileInfo['filename'];
+                            $files['file']['tmp_name'] = $file->getPathname();
+                            $files['file']['type'] = $fileInfo['mimetype'];
+                            $files['file']['error'] = 0;
+                            $files['file']['size'] = $fileInfo['filesize'];
+                            $files['file']['from_file'] = true;
+                            $files['file']['move_file'] = true;
+                            $_POST['language'] = $courseInfo['language'];
+                            $_POST['moodle_import'] = true;
+
+                            DocumentManager::upload_document(
+                                $files,
+                                '/',
+                                isset($fileInfo['title']) ? $fileInfo['title'] : pathinfo($fileInfo['filename'], PATHINFO_FILENAME),
+                                '',
+                                null,
+                                null,
+                                true,
+                                true,
+                                'file',
+                                // This is to validate spaces as hyphens
+                                false
+                            );
+                        }
+                    }
+                }
+
             } else {
                 removeDir($destinationDir);
                 return false;
@@ -562,7 +603,9 @@ class MoodleImport
             case 'multianswer':
                 $objAnswer = new Answer($questionInstance->id);
 
-                $placeholder = $currentQuestion['questiontext'];
+                $coursePath = api_get_course_path();
+
+                $placeholder = str_replace('@@PLUGINFILE@@', '/courses/' . $coursePath . '/document', $currentQuestion['questiontext']);
 
                 $optionsValues = [];
 
@@ -740,6 +783,9 @@ class MoodleImport
      */
     public function processFillBlanks($objAnswer, $questionType, $answerValues, &$placeholder, $position)
     {
+
+        $coursePath = api_get_course_path();
+
         switch ($questionType) {
             case 'multichoice':
                 $optionsValues = [];
@@ -808,6 +854,7 @@ class MoodleImport
 
                     $currentAnswers = $correctAnswer.$othersAnswers;
                     $currentAnswers = '['.substr($currentAnswers, 0, -1).'] ';
+                    $answer['questiontext'] = str_replace('@@PLUGINFILE@@', '/courses/' . $coursePath . '/document', $answer['questiontext']);
 
                     $placeholder .= '<p> ' . strip_tags($answer['questiontext']).' '.$currentAnswers . ' </p>';
                 }
@@ -821,6 +868,62 @@ class MoodleImport
         }
     }
 
+    /**
+     * get All files associated with a question
+     *
+     * @param $filesXml
+     * @return array
+     */
+    public function getAllQuestionFiles($filesXml)
+    {
+        $moduleDoc = new DOMDocument();
+        $moduleRes = @$moduleDoc->loadXML($filesXml);
+        $allFiles = [];
+        if ($moduleRes) {
+            $activities = $moduleDoc->getElementsByTagName('file');
+            foreach ($activities as $activity) {
+
+                $currentItem = [];
+
+                $thisIsAnInvalidItem = false;
+
+                if ($activity->childNodes->length) {
+                    foreach ($activity->childNodes as $item ) {
+                        if ($item->nodeName == 'component' && $item->nodeValue == 'mod_resource') {
+                            $thisIsAnInvalidItem = true;
+                        }
+
+                        if ($item->nodeName == 'contenthash') {
+                            $currentItem['contenthash'] = $item->nodeValue;
+                        }
+
+                        if ($item->nodeName == 'filename') {
+                            $currentItem['filename'] = $item->nodeValue;
+                        }
+
+                        if ($item->nodeName == 'filesize') {
+                            $currentItem['filesize'] = $item->nodeValue;
+                        }
+
+                        if ($item->nodeName == 'mimetype' && $item->nodeValue == 'document/unknown') {
+                            $thisIsAnInvalidItem = true;
+                        }
+
+                        if ($item->nodeName == 'mimetype' && $item->nodeValue !== 'document/unknown') {
+                            $currentItem['mimetype'] = $item->nodeValue;
+                        }
+                    }
+                }
+
+                if (!$thisIsAnInvalidItem) {
+                    $allFiles[] = $currentItem;
+                }
+            }
+        }
+
+        return $allFiles;
+    }
+
 
     /**
      * Litle utility to delete the unuseful tags

+ 3 - 2
main/inc/lib/api.lib.php

@@ -5611,12 +5611,13 @@ function api_is_element_in_the_session($tool, $element_id, $session_id = null) {
  * Replaces "forbidden" characters in a filename string.
  *
  * @param string $filename
+ * @param bool $treat_spaces_as_hyphens
  *
  * @return string
  */
-function api_replace_dangerous_char($filename)
+function api_replace_dangerous_char($filename, $treat_spaces_as_hyphens = true)
 {
-    return URLify::filter($filename, 250, '', true, true, false, false);
+    return URLify::filter($filename, 250, '', true, true, false, false, $treat_spaces_as_hyphens);
 }
 
 /**

+ 5 - 2
main/inc/lib/document.lib.php

@@ -2802,6 +2802,7 @@ class DocumentManager
      * @param bool $index_document index document (search xapian module)
      * @param bool $show_output print html messages
      * @param string $fileKey
+     * @param bool $treat_spaces_as_hyphens
      *
      * @return array|bool
      */
@@ -2814,7 +2815,8 @@ class DocumentManager
         $if_exists = null,
         $index_document = false,
         $show_output = false,
-        $fileKey = 'file'
+        $fileKey = 'file',
+        $treat_spaces_as_hyphens = true
     ) {
         $course_info = api_get_course_info();
         $sessionId = api_get_session_id();
@@ -2845,7 +2847,8 @@ class DocumentManager
                     $show_output,
                     false,
                     null,
-                    $sessionId
+                    $sessionId,
+                    $treat_spaces_as_hyphens
                 );
 
                 // Showing message when sending zip files

+ 4 - 2
main/inc/lib/fileUpload.lib.php

@@ -173,6 +173,7 @@ function process_uploaded_file($uploaded_file, $show_output = true)
  * @param bool $onlyUploadFile
  * @param string $comment
  * @param int $sessionId
+ * @param bool $treat_spaces_as_hyphens
  *
  * So far only use for unzip_uploaded_document function.
  * If no output wanted on success, set to false.
@@ -192,7 +193,8 @@ function handle_uploaded_document(
     $output = true,
     $onlyUploadFile = false,
     $comment = null,
-    $sessionId = null
+    $sessionId = null,
+    $treat_spaces_as_hyphens = true
 ) {
     if (!$userId) {
         return false;
@@ -246,7 +248,7 @@ function handle_uploaded_document(
         return false;
     } else {
         // Clean up the name, only ASCII characters should stay. (and strict)
-        $cleanName = api_replace_dangerous_char($uploadedFile['name']);
+        $cleanName = api_replace_dangerous_char($uploadedFile['name'], $treat_spaces_as_hyphens);
 
         // No "dangerous" files
         $cleanName = disable_dangerous_file($cleanName);