Browse Source

Merge branch '1.11.x' of https://github.com/chamilo/chamilo-lms into 1.11.x

Alex Aragon 8 years ago
parent
commit
8dd9439e33

+ 39 - 0
app/Migrations/Schema/V111/Version20160713180000.php

@@ -0,0 +1,39 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V111;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Types\Type;
+
+/**
+ * Class Version20160713180000
+ * Add option to use SVG icons instead of their PNG version
+ * @package Application\Migrations\Schema\V111
+ */
+class Version20160713180000 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     * @throws \Doctrine\DBAL\DBALException
+     * @throws \Doctrine\DBAL\Schema\SchemaException
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql("DELETE FROM settings_current WHERE variable = 'allow_browser_sniffer'");
+        $this->addSql("DELETE FROM settings_options WHERE variable = 'allow_browser_sniffer'");
+    }
+
+    /**
+     * @param Schema $schema
+     * @throws \Doctrine\DBAL\DBALException
+     * @throws \Doctrine\DBAL\Schema\SchemaException
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql("INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES ('allow_browser_sniffer', NULL, 'radio', 'Tuning', 'false', 'AllowBrowserSnifferTitle','AllowBrowserSnifferComment',NULL,NULL, 0)");
+        $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_browser_sniffer','true','Yes') ");
+        $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_browser_sniffer','false','No') ");
+    }
+}

+ 46 - 6
app/Resources/public/css/base.css

@@ -772,6 +772,32 @@ a.personal_agenda:hover, a.personal_agenda:hover {
 .social-home-anonymous-online {
 .social-home-anonymous-online {
     width: 200px;
     width: 200px;
 }
 }
+.social-thumbnail {
+    padding: 0px;
+}
+.social-title {
+    font-size: 18px;
+    font-family: helvetica, arial, sans-serif;
+    color: #000;
+}
+.social-description {
+    padding: 8px;
+    color: #000;
+}
+.social-image {
+    max-height: 300px;
+}
+.social-post-answers {
+    padding-right: 0px;
+    padding-left: 0px;
+}
+.social-host p {;
+    padding: 10px;
+    margin-top: 5px;
+    margin-bottom: 5px;
+    line-height: 22px;
+    color: #999;
+}
 .menulist {
 .menulist {
     margin: 0px;
     margin: 0px;
     list-style: none;
     list-style: none;
@@ -3829,6 +3855,16 @@ i.size-32.icon-new-work{
   max-width: 50px;
   max-width: 50px;
   max-height: 50px;
   max-height: 50px;
 }
 }
+.top-mediapost {
+    border-bottom: 1px solid #ECF0F1;
+}
+.popularity-mediapost {
+    margin-bottom: 30px;
+    font-size: 1.2em;
+}
+.popularity-vote-found {
+    color: #FFD700;
+}
 .top-mediapost .user-image,
 .top-mediapost .user-image,
 .sub-mediapost .user-image
 .sub-mediapost .user-image
 {
 {
@@ -3856,13 +3892,13 @@ i.size-32.icon-new-work{
 }
 }
 .top-mediapost .msg-content p,
 .top-mediapost .msg-content p,
 .sub-mediapost .rep-post .msg-content p{
 .sub-mediapost .rep-post .msg-content p{
-  border-top:1px solid #ECF0F1;
-  padding-top: 10px;
-  padding-bottom: 10px;
+  /* border-top:1px solid #ECF0F1; */
+  /* padding-top: 10px; */
+  /* padding-bottom: 20px; */
   margin-top: 5px;
   margin-top: 5px;
-  margin-bottom: 5px;
+  margin-bottom: 20px;
   line-height: 22px;
   line-height: 22px;
-  padding-left: 10px;
+  /* padding-left: 10px; */
   padding-right: 10px;
   padding-right: 10px;
   color: #666666;
   color: #666666;
 }
 }
@@ -5985,4 +6021,8 @@ footer{
     border: 2px dashed #bbbbbb;
     border: 2px dashed #bbbbbb;
     font-size: 120%;
     font-size: 120%;
     margin-bottom: 0;
     margin-bottom: 0;
-}
+}
+
+#upload_form .fa-plus-square-o, #upload_form .fa-minus-square-o {
+    cursor:pointer;
+}

+ 3 - 0
main/course_info/maintenance.php

@@ -30,6 +30,9 @@ echo Display::page_header($nameTools);
         <li><a href="../coursecopy/import_backup.php?<?php echo api_get_cidreq(); ?>"><?php echo get_lang('ImportBackup'); ?></a><br/>
         <li><a href="../coursecopy/import_backup.php?<?php echo api_get_cidreq(); ?>"><?php echo get_lang('ImportBackup'); ?></a><br/>
         <?php echo get_lang('ImportBackupInfo'); ?>
         <?php echo get_lang('ImportBackupInfo'); ?>
         </li>
         </li>
+        <li><a href="../coursecopy/import_moodle.php?<?php echo api_get_cidreq(); ?>"><?php echo get_lang('ImportFromMoodle'); ?></a><br/>
+            <?php echo get_lang('ImportFromMoodleInfo'); ?>
+        </li>
     </ul>
     </ul>
 </div>
 </div>
 
 

+ 58 - 0
main/coursecopy/import_moodle.php

@@ -0,0 +1,58 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+/**
+ * Import a backup from moodle system.
+ *
+ * @author José Loguercio <jose.loguercio@beeznest.com>
+ * @package chamilo.backup
+ */
+
+require_once '../inc/global.inc.php';
+require_once '../inc/lib/MoodleImport.class.php';
+
+$current_course_tool = TOOL_COURSE_MAINTENANCE;
+api_protect_course_script(true);
+
+// Check access rights (only teachers are allowed here)
+if (!api_is_allowed_to_edit()) {
+    api_not_allowed(true);
+}
+
+// Remove memory and time limits as much as possible as this might be a long process...
+if (function_exists('ini_set')) {
+    api_set_memory_limit('256M');
+    ini_set('max_execution_time', 1800);
+}
+
+// Section for the tabs
+$this_section = SECTION_COURSES;
+
+// Breadcrumbs
+$interbreadcrumb[] = array(
+    'url' => '../course_info/maintenance.php',
+    'name' => get_lang('Maintenance')
+);
+
+$form = new FormValidator('import_moodle');
+$form->addFile('moodle_file', get_lang('MoodleFile'));
+$form->addButtonImport(get_lang('Import'));
+
+if ($form->validate()) {
+    $file = $_FILES['moodle_file'];
+    $moodleImport = new MoodleImport();
+    $moodleImport->readMoodleFile($file);
+}
+
+$templateName = get_lang('ImportFromMoodle');
+
+$template = new Template($templateName);
+$infoMsg = Display::return_message(get_lang('ImportFromMoodleInstructions'));
+$template->assign('info_msg', $infoMsg);
+$template->assign('form', $form->returnForm());
+$content = $template->fetch('default/coursecopy/import_moodle.tpl');
+
+$template->assign('header', $templateName);
+$template->assign('content', $content);
+
+$template->display_one_col_template();

+ 5 - 2
main/inc/ajax/social.ajax.php

@@ -225,14 +225,17 @@ switch ($action) {
         // Read the Url using OpenGraph and returns the hyperlinks content
         // Read the Url using OpenGraph and returns the hyperlinks content
     case 'readUrlWithOpenGraph':
     case 'readUrlWithOpenGraph':
         $url = isset($_POST['social_wall_new_msg_main']) ? $_POST['social_wall_new_msg_main'] : '';
         $url = isset($_POST['social_wall_new_msg_main']) ? $_POST['social_wall_new_msg_main'] : '';
+        $url = trim($url);
         $html = '';
         $html = '';
-        if (SocialManager::verifyUrl($url) == true){
+        if (SocialManager::verifyUrl($url) == true) {
             $html = Security::remove_XSS(
             $html = Security::remove_XSS(
                 SocialManager::readContentWithOpenGraph($url)
                 SocialManager::readContentWithOpenGraph($url)
             );
             );
         }
         }
-        echo utf8_decode($html);
+        echo $html;
         break;
         break;
+    case 'voteMsg':
+
     default:
     default:
         echo '';
         echo '';
 }
 }

+ 733 - 0
main/inc/lib/MoodleImport.class.php

@@ -0,0 +1,733 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+/**
+ * Class MoodleImport
+ *
+ * @author José Loguercio <jose.loguercio@beeznest.com>
+ * @package chamilo.library
+ */
+
+class MoodleImport
+{
+    /**
+     * Read and validate the moodleFile
+     *
+     * @param resource $uploadedFile *.* mbz file moodle course backup
+     * @return bool
+     */
+    public function readMoodleFile($uploadedFile)
+    {
+        $file = $uploadedFile['tmp_name'];
+
+        if (is_file($file) && is_readable($file)) {
+            $package = new PclZip($file);
+            $packageContent = $package->listContent();
+            $mainFileKey = 0;
+            foreach ($packageContent as $index => $value) {
+                if ($value['filename'] == 'moodle_backup.xml') {
+                    $mainFileKey = $index;
+                    break;
+                }
+            }
+
+            if (!$mainFileKey) {
+                Display::addFlash(Display::return_message(get_lang('FailedToImportThisIsNotAMoodleFile'), 'error'));
+            }
+
+            $folder = api_get_unique_id();
+            $destinationDir = api_get_path(SYS_ARCHIVE_PATH).$folder;
+            $coursePath = api_get_path(SYS_COURSE_PATH).api_get_course_path().'/';
+            $courseInfo = api_get_course_info();
+
+            mkdir($destinationDir, api_get_permissions_for_new_directories(), true);
+
+            $package->extract(
+                PCLZIP_OPT_PATH,
+                $destinationDir
+            );
+
+            $xml = @file_get_contents($destinationDir.'/moodle_backup.xml');
+
+            $doc = new DOMDocument();
+            $res = @$doc->loadXML($xml);
+            if ($res) {
+                $activities = $doc->getElementsByTagName('activity');
+                foreach ($activities as $activity) {
+                    if ($activity->childNodes->length) {
+                        $currentItem = [];
+
+                        foreach ($activity->childNodes as $item) {
+                            $currentItem[$item->nodeName] = $item->nodeValue;
+                        }
+
+                        $moduleName = isset($currentItem['modulename']) ? $currentItem['modulename'] : false;
+                        switch ($moduleName) {
+                            case 'forum':
+                                require_once '../forum/forumfunction.inc.php';
+                                $catForumValues = [];
+
+                                // Read the current forum module xml.
+                                $moduleDir = $currentItem['directory'];
+                                $moduleXml = @file_get_contents($destinationDir.'/'.$moduleDir.'/'.$moduleName.'.xml');
+                                $moduleValues = $this->readForumModule($moduleXml);
+
+                                // Create a Forum category based on Moodle forum type.
+                                $catForumValues['forum_category_title'] = $moduleValues['type'];
+                                $catForumValues['forum_category_comment'] = '';
+                                $catId = store_forumcategory($catForumValues);
+                                $forumValues = [];
+                                $forumValues['forum_title'] = $moduleValues['name'];
+                                $forumValues['forum_image'] = '';
+                                $forumValues['forum_comment'] = $moduleValues['intro'];
+                                $forumValues['forum_category'] = $catId;
+
+                                store_forum($forumValues);
+                                break;
+                            case 'quiz':
+
+                                // Read the current quiz module xml.
+                                // The quiz case is the very complicate process of all the import.
+                                // Please if you want to review the script, try to see the readingXML functions.
+                                // The readingXML functions in this clases do all the mayor work here.
+
+                                $moduleDir = $currentItem['directory'];
+                                $moduleXml = @file_get_contents($destinationDir.'/'.$moduleDir.'/'.$moduleName.'.xml');
+                                $questionsXml = @file_get_contents($destinationDir.'/questions.xml');
+                                $moduleValues = $this->readQuizModule($moduleXml);
+
+                                // At this point we got all the prepared resources from Moodle file
+                                // $moduleValues variable contains all the necesary info to the quiz import
+                                // var_dump($moduleValues); // <-- uncomment this to see the final array
+
+                                // Lets do this ...
+                                $exercise = new Exercise();
+                                $exercise->updateTitle(Exercise::format_title_variable($moduleValues['name']));
+                                $exercise->updateDescription($moduleValues['intro']);
+                                $exercise->updateAttempts($moduleValues['attempts_number']);
+                                $exercise->updateFeedbackType(0);
+
+                                // Match shuffle question with chamilo
+                                switch ($moduleValues['shufflequestions']) {
+                                    case '0':
+                                        $exercise->setRandom(0);
+                                        break;
+                                    case '1':
+                                        $exercise->setRandom(-1);
+                                        break;
+                                    default:
+                                        $exercise->setRandom(0);
+                                }
+                                $exercise->updateRandomAnswers($moduleValues['shuffleanswers']);
+                                // @todo divide to minutes
+                                $exercise->updateExpiredTime($moduleValues['timelimit']);
+
+                                if ($moduleValues['questionsperpage'] == 1) {
+                                    $exercise->updateType(2);
+                                } else {
+                                    $exercise->updateType(1);
+                                }
+
+                                // Create the new Quiz
+                                $exercise->save();
+
+                                // Ok, we got the Quiz and create it, now its time to add the Questions
+                                foreach ($moduleValues['question_instances'] as $index => $question) {
+                                    $questionsValues = $this->readMainQuestionsXml($questionsXml, $question['questionid']);
+                                    $moduleValues['question_instances'][$index] = $questionsValues;
+                                    // Set Question Type from Moodle XML element <qtype>
+                                    $qType = $moduleValues['question_instances'][$index]['qtype'];
+                                    // Add the matched chamilo question type to the array
+                                    $moduleValues['question_instances'][$index]['chamilo_qtype'] = $this->matchMoodleChamiloQuestionTypes($qType);
+                                    $questionInstance = Question::getInstance($moduleValues['question_instances'][$index]['chamilo_qtype']);
+                                    if ($questionInstance) {
+                                        $questionInstance->updateTitle($moduleValues['question_instances'][$index]['name']);
+                                        $questionInstance->updateDescription($moduleValues['question_instances'][$index]['questiontext']);
+                                        $questionInstance->updateLevel(1);
+                                        $questionInstance->updateCategory(0);
+
+                                        //Save normal question if NOT media
+                                        if ($questionInstance->type != MEDIA_QUESTION) {
+                                            $questionInstance->save($exercise->id);
+
+                                            // modify the exercise
+                                            $exercise->addToList($questionInstance->id);
+                                            $exercise->update_question_positions();
+                                        }
+
+                                        $questionList = $moduleValues['question_instances'][$index]['plugin_qtype_'.$qType.'_question'];
+                                        $currentQuestion = $moduleValues['question_instances'][$index];
+
+                                        $result = $this->processAnswers($questionList, $qType, $questionInstance, $currentQuestion);
+                                    }
+                                }
+
+                                break;
+                            case 'resource':
+                                // Read the current resource module xml.
+                                $moduleDir = $currentItem['directory'];
+                                $moduleXml = @file_get_contents($destinationDir.'/'.$moduleDir.'/'.$moduleName.'.xml');
+                                $filesXml = @file_get_contents($destinationDir.'/files.xml');
+                                $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) {
+                                    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,
+                                            '/',
+                                            $fileInfo['title'],
+                                            '',
+                                            null,
+                                            null,
+                                            true,
+                                            true
+                                        );
+                                    }
+                                }
+
+                                break;
+                            case 'url':
+                                // Read the current url module xml.
+                                $moduleDir = $currentItem['directory'];
+                                $moduleXml = @file_get_contents($destinationDir.'/'.$moduleDir.'/'.$moduleName.'.xml');
+                                $moduleValues = $this->readUrlModule($moduleXml);
+                                $_POST['title'] = $moduleValues['name'];
+                                $_POST['url'] = $moduleValues['externalurl'];
+                                $_POST['description'] = $moduleValues['intro'];
+                                $_POST['category_id'] = 0;
+                                $_POST['target'] = '_blank';
+
+                                Link::addlinkcategory("link");
+                                break;
+                        }
+                    }
+                }
+            } else {
+                return false;
+            }
+        } else {
+            return false;
+        }
+
+        removeDir($destinationDir);
+        return $packageContent[$mainFileKey];
+    }
+
+    /**
+     * Read and validate the forum module XML
+     *
+     * @param resource $moduleXml XML file
+     * @return mixed | array if is a valid xml file, false otherwise
+     */
+    public function readForumModule($moduleXml)
+    {
+        $moduleDoc = new DOMDocument();
+        $moduleRes = @$moduleDoc->loadXML($moduleXml);
+        if ($moduleRes) {
+            $activities = $moduleDoc->getElementsByTagName('forum');
+            $currentItem = [];
+            foreach ($activities as $activity) {
+                if ($activity->childNodes->length) {
+                    foreach ($activity->childNodes as $item) {
+                        $currentItem[$item->nodeName] = $item->nodeValue;
+                    }
+                }
+            }
+
+            return $currentItem;
+        }
+
+        return false;
+    }
+
+    /**
+     * Read and validate the resource module XML
+     *
+     * @param resource $moduleXml XML file
+     * @return mixed | array if is a valid xml file, false otherwise
+     */
+    public function readResourceModule($moduleXml)
+    {
+        $moduleDoc = new DOMDocument();
+        $moduleRes = @$moduleDoc->loadXML($moduleXml);
+        if ($moduleRes) {
+            $activities = $moduleDoc->getElementsByTagName('resource');
+            $mainActivity = $moduleDoc->getElementsByTagName('activity');
+            $contextId = $mainActivity->item(0)->getAttribute('contextid');
+            $currentItem = [];
+            foreach ($activities as $activity) {
+                if ($activity->childNodes->length) {
+                    foreach ($activity->childNodes as $item) {
+                        $currentItem[$item->nodeName] = $item->nodeValue;
+                    }
+                }
+            }
+
+            $currentItem['contextid'] = $contextId;
+            return $currentItem;
+        }
+
+        return false;
+    }
+
+    /**
+     * Read and validate the url module XML
+     *
+     * @param resource $moduleXml XML file
+     * @return mixed | array if is a valid xml file, false otherwise
+     */
+    public function readUrlModule($moduleXml)
+    {
+        $moduleDoc = new DOMDocument();
+        $moduleRes = @$moduleDoc->loadXML($moduleXml);
+        if ($moduleRes) {
+            $activities = $moduleDoc->getElementsByTagName('url');
+            $currentItem = [];
+            foreach ($activities as $activity) {
+                if ($activity->childNodes->length) {
+                    foreach ($activity->childNodes as $item) {
+                        $currentItem[$item->nodeName] = $item->nodeValue;
+                    }
+                }
+            }
+
+            return $currentItem;
+        }
+
+        return false;
+    }
+
+    /**
+     * Read and validate the quiz module XML
+     *
+     * @param resource $moduleXml XML file
+     * @return mixed | array if is a valid xml file, false otherwise
+     */
+    public function readQuizModule($moduleXml)
+    {
+        $moduleDoc = new DOMDocument();
+        $moduleRes = @$moduleDoc->loadXML($moduleXml);
+        if ($moduleRes) {
+            $activities = $moduleDoc->getElementsByTagName('quiz');
+            $currentItem = [];
+            foreach ($activities as $activity) {
+                if ($activity->childNodes->length) {
+                    foreach ($activity->childNodes as $item) {
+                        $currentItem[$item->nodeName] = $item->nodeValue;
+                    }
+                }
+            }
+
+            $questions = $moduleDoc->getElementsByTagName('question_instance');
+
+            $questionList = [];
+            $counter = 0;
+            foreach ($questions as $question) {
+                if ($question->childNodes->length) {
+                    foreach ($question->childNodes as $item) {
+                        $questionList[$counter][$item->nodeName] = $item->nodeValue;
+                    }
+                    $counter++;
+                }
+
+            }
+            $currentItem['question_instances'] = $questionList;
+            return $currentItem;
+        }
+
+        return false;
+    }
+
+    /**
+     * Search the current file resource in main Files XML
+     *
+     * @param resource $filesXml XML file
+     * @param int $contextId
+     * @return mixed | array if is a valid xml file, false otherwise
+     */
+    public function readMainFilesXml($filesXml, $contextId)
+    {
+        $moduleDoc = new DOMDocument();
+        $moduleRes = @$moduleDoc->loadXML($filesXml);
+        if ($moduleRes) {
+            $activities = $moduleDoc->getElementsByTagName('file');
+            $currentItem = [];
+            foreach ($activities as $activity) {
+                if ($activity->childNodes->length) {
+                    $isThisItemThatIWant = false;
+                    foreach ($activity->childNodes as $item) {
+                        if (!$isThisItemThatIWant && $item->nodeName == 'contenthash') {
+                            $currentItem['contenthash'] = $item->nodeValue;
+                        }
+                        if ($item->nodeName == 'contextid' && intval($item->nodeValue) == intval($contextId) && !$isThisItemThatIWant) {
+                            $isThisItemThatIWant = true;
+                            continue;
+                        }
+
+                        if ($isThisItemThatIWant && $item->nodeName == 'filename') {
+                            $currentItem['filename'] = $item->nodeValue;
+                        }
+
+                        if ($isThisItemThatIWant && $item->nodeName == 'filesize') {
+                            $currentItem['filesize'] = $item->nodeValue;
+                        }
+
+                        if ($isThisItemThatIWant && $item->nodeName == 'mimetype' && $item->nodeValue == 'document/unknown') {
+                            break;
+                        }
+
+                        if ($isThisItemThatIWant && $item->nodeName == 'mimetype' && $item->nodeValue !== 'document/unknown') {
+                            $currentItem['mimetype'] = $item->nodeValue;
+                            break 2;
+                        }
+                    }
+                }
+            }
+
+            return $currentItem;
+        }
+
+        return false;
+    }
+
+    /**
+     * Search the current quiestion resource in main Questions XML
+     *
+     * @param resource $questionsXml XML file
+     * @param int $questionId
+     * @return mixed | array if is a valid xml file, false otherwise
+     */
+    public function readMainQuestionsXml($questionsXml, $questionId)
+    {
+        $moduleDoc = new DOMDocument();
+        $moduleRes = @$moduleDoc->loadXML($questionsXml);
+        if ($moduleRes) {
+            $questions = $moduleDoc->getElementsByTagName('question');
+            $currentItem = [];
+            foreach ($questions as $question) {
+                if (intval($question->getAttribute('id')) == $questionId) {
+                    if ($question->childNodes->length) {
+                        $currentItem['questionid'] = $questionId;
+                        $questionType = '';
+                        foreach ($question->childNodes as $item) {
+                            $currentItem[$item->nodeName] = $item->nodeValue;
+                            if ($item->nodeName == 'qtype') {
+                                $questionType = $item->nodeValue;
+                            }
+
+                            if ($item->nodeName == 'plugin_qtype_'.$questionType.'_question') {
+                                $answer = $item->getElementsByTagName($this->getQuestionTypeAnswersTag($questionType));
+                                $currentItem['plugin_qtype_'.$questionType.'_question'] = [];
+                                for ($i = 0; $i <= $answer->length - 1; $i++) {
+                                    $currentItem['plugin_qtype_'.$questionType.'_question'][$i]['answerid'] = $answer->item($i)->getAttribute('id');
+                                    foreach ($answer->item($i)->childNodes as $properties) {
+                                        $currentItem['plugin_qtype_'.$questionType.'_question'][$i][$properties->nodeName] = $properties->nodeValue;
+                                    }
+                                }
+
+                                $typeValues = $item->getElementsByTagName($this->getQuestionTypeOptionsTag($questionType));
+                                for ($i = 0; $i <= $typeValues->length - 1; $i++) {
+                                    foreach ($typeValues->item($i)->childNodes as $properties) {
+                                        $currentItem[$questionType.'_values'][$properties->nodeName] = $properties->nodeValue;
+                                        if ($properties->nodeName == 'sequence') {
+                                            $sequence = $properties->nodeValue;
+                                            $sequenceIds = explode(',', $sequence);
+                                            foreach ($sequenceIds as $qId) {
+                                                $questionMatch = $this->readMainQuestionsXml($questionsXml, $qId);
+                                                $currentItem['plugin_qtype_'.$questionType.'_question'][] = $questionMatch;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            $this->traverseArray($currentItem, ['#text', 'question_hints', 'tags']);
+            return $currentItem;
+        }
+
+        return false;
+    }
+
+    /**
+     * return the correct question type options tag
+     *
+     * @param string $questionType name
+     * @return string question type tag
+     */
+    public function getQuestionTypeOptionsTag($questionType)
+    {
+        switch ($questionType) {
+            case 'match':
+            case 'ddmatch':
+                return 'matchoptions';
+                break;
+            default:
+                return $questionType;
+                break;
+        }
+    }
+
+    /**
+     * return the correct question type answers tag
+     *
+     * @param string $questionType name
+     * @return string question type tag
+     */
+    public function getQuestionTypeAnswersTag($questionType)
+    {
+        switch ($questionType) {
+            case 'match':
+            case 'ddmatch':
+                return 'match';
+                break;
+            default:
+                return 'answer';
+                break;
+        }
+    }
+
+    /**
+     *
+     * @param string $moodleQuestionType
+     * @return integer Chamilo question type
+     */
+    public function matchMoodleChamiloQuestionTypes($moodleQuestionType)
+    {
+        switch ($moodleQuestionType) {
+            case 'multichoice':
+                return UNIQUE_ANSWER;
+                break;
+            case 'multianswer':
+            case 'shortanswer':
+            case 'match':
+                return FILL_IN_BLANKS;
+                break;
+            case 'essay':
+                return FREE_ANSWER;
+                break;
+            case 'truefalse':
+                return MULTIPLE_ANSWER_TRUE_FALSE;
+            break;
+        }
+    }
+
+    /**
+     * Process Moodle Answers to Chamilo
+     *
+     * @param array $questionList
+     * @param string $questionType
+     * @param object $questionInstance Question/Answer instance
+     * @param array $currentQuestion
+     * @return integer db response
+     */
+    public function processAnswers($questionList, $questionType, $questionInstance, $currentQuestion)
+    {
+        switch ($questionType) {
+            case 'multichoice':
+                $objAnswer = new Answer($questionInstance->id);
+                $questionWeighting = 0;
+                foreach ($questionList as $slot => $answer) {
+                    $this->processUniqueAnswer($objAnswer, $answer, $slot + 1, $questionWeighting);
+                }
+
+                // saves the answers into the data base
+                $objAnswer->save();
+                // sets the total weighting of the question
+                $questionInstance->updateWeighting($questionWeighting);
+                $questionInstance->save();
+
+                return true;
+                break;
+            case 'multianswer':
+                $objAnswer = new Answer($questionInstance->id);
+
+                $placeholder = $currentQuestion['questiontext'];
+
+                $optionsValues = [];
+
+                foreach ($questionList as $slot => $subQuestion) {
+                    $qtype = $subQuestion['qtype'];
+                    $optionsValues[] = $this->processFillBlanks($objAnswer, $subQuestion, $subQuestion['plugin_qtype_'.$qtype.'_question'], $placeholder, $slot + 1);
+                }
+
+                $answerOptionsWeight = '::';
+                $answerOptionsSize = '';
+                $questionWeighting = 0;
+                foreach ($optionsValues as $index => $value) {
+                    $questionWeighting += $value['weight'];
+                    $answerOptionsWeight .= $value['weight'].',';
+                    $answerOptionsSize .= $value['size'].',';
+                }
+
+                $answerOptionsWeight = substr($answerOptionsWeight, 0, -1);
+                $answerOptionsSize = substr($answerOptionsSize, 0, -1);
+
+                $suffleAnswers = isset($subQuestion[$qtype.'_values']['shuffleanswers']) ? $subQuestion[$qtype.'_values']['shuffleanswers'] : false;
+
+                if ($suffleAnswers) {
+                    $answerOptions = $answerOptionsWeight.':'.$answerOptionsSize.':0@'.$suffleAnswers;
+                } else {
+                    $answerOptions = $answerOptionsWeight.':'.$answerOptionsSize.':0@';
+                }
+
+                $placeholder = $placeholder.$answerOptions;
+
+                $questionInstance->updateWeighting($questionWeighting);
+                $questionInstance->updateDescription('');
+                $questionInstance->save();
+                $objAnswer->createAnswer($placeholder, 0, '', 0, 1);
+                $objAnswer->save();
+            case 'shortanswer':
+            case 'match':
+            case 'ddmatch':
+                // Not Supported Yet
+                return false;
+                break;
+            case 'essay':
+                $questionWeighting = $currentQuestion['defaultmark'];
+                $questionInstance->updateWeighting($questionWeighting);
+                $questionInstance->save();
+                break;
+            case 'truefalse':
+                // Not Supported Yet
+                return false;
+                break;
+            default:
+                return false;
+                break;
+        }
+    }
+
+    /**
+     * Process Chamilo Unique Answer
+     *
+     * @param object $objAnswer
+     * @param array $answerValues
+     * @param integer $position
+     * @param integer $questionWeighting
+     * @return integer db response
+     */
+    public function processUniqueAnswer($objAnswer, $answerValues, $position, &$questionWeighting)
+    {
+        $correct = intval($answerValues['fraction']) ? intval($answerValues['fraction']) : 0;
+        $answer = $answerValues['answertext'];
+        $comment = $answerValues['feedback'];
+        $weighting = $answerValues['fraction'];
+        $weighting = abs($weighting);
+        if ($weighting > 0) {
+            $questionWeighting += $weighting;
+        }
+        $goodAnswer =  $correct ? true : false;
+
+        $objAnswer->createAnswer(
+            $answer,
+            $goodAnswer,
+            $comment,
+            $weighting,
+            $position,
+            null,
+            null,
+            ''
+        );
+    }
+
+    /**
+     * Process Chamilo FillBlanks
+     *
+     * @param object $objAnswer
+     * @param array $question
+     * @param array $answerValues
+     * @param string $placeholder
+     * @param integer $position
+     * @return integer db response
+     */
+    public function processFillBlanks($objAnswer, $question, $answerValues, &$placeholder, $position)
+    {
+        switch ($question['qtype']) {
+            case 'multichoice':
+                $optionsValues = [];
+
+                $correctAnswer = '';
+                $othersAnswer = '';
+                foreach ($answerValues as $answer) {
+                    $correct = intval($answer['fraction']);
+                    if ($correct) {
+                        $correctAnswer .= $answer['answertext'].'|';
+                        $optionsValues['weight'] = $answer['fraction'];
+                        $optionsValues['size'] = '200';
+                    } else {
+                        $othersAnswer .= $answer['answertext'].'|';
+                    }
+                }
+                $currentAnswers = $correctAnswer.$othersAnswer;
+                $currentAnswers = '['.substr($currentAnswers, 0, -1).']';
+                $placeholder = str_replace("{#$position}", $currentAnswers, $placeholder);
+
+                return $optionsValues;
+
+                break;
+            case 'shortanswer':
+                $optionsValues = [];
+
+                $correctAnswer = '';
+
+                foreach ($answerValues as $answer) {
+                    $correct = intval($answer['fraction']);
+                    if ($correct) {
+                        $correctAnswer .= $answer['answertext'];
+                        $optionsValues['weight'] = $answer['fraction'];
+                        $optionsValues['size'] = '200';
+                    }
+                }
+
+                $currentAnswers = '['.$correctAnswer.']';
+                $placeholder = str_replace("{#$position}", $currentAnswers, $placeholder);
+
+                return $optionsValues;
+
+                break;
+            default:
+                return false;
+                break;
+        }
+    }
+
+
+    /**
+     * Litle utility to delete the unuseful tags
+     *
+     * @param $array
+     * @param $keys
+     */
+    public function traverseArray(&$array, $keys) {
+        foreach ($array as $key => &$value) {
+            if (is_array($value)) {
+                $this->traverseArray($value, $keys);
+            } else {
+                if (in_array($key, $keys)){
+                    unset($array[$key]);
+                }
+            }
+        }
+    }
+
+}

+ 36 - 7
main/inc/lib/api.lib.php

@@ -3583,6 +3583,8 @@ function api_item_property_update(
         return false;
         return false;
     }
     }
 
 
+    $em = Database::getManager();
+
     // Definition of variables.
     // Definition of variables.
     $tool = Database::escape_string($tool);
     $tool = Database::escape_string($tool);
     $item_id = intval($item_id);
     $item_id = intval($item_id);
@@ -3802,14 +3804,41 @@ function api_item_property_update(
 
 
     // Insert if no entries are found (can only happen in case of $last_edit_type switch is 'default').
     // Insert if no entries are found (can only happen in case of $last_edit_type switch is 'default').
     if ($result == false || Database::affected_rows($result) == 0) {
     if ($result == false || Database::affected_rows($result) == 0) {
-        $sessionCondition = empty($session_id) ? "NULL" : "'$session_id'";
-        $sql = "INSERT INTO $tableItemProperty (c_id, tool,ref,insert_date,insert_user_id,lastedit_date,lastedit_type, lastedit_user_id, $to_field, visibility, start_visible, end_visible, session_id)
-                VALUES ($course_id, '$tool', $item_id, '$time', $user_id, '$time', '$last_edit_type', $user_id, $toValueCondition, $visibility, $startVisible, $endVisible, $sessionCondition)";
-        Database::query($sql);
-        $id = Database::insert_id();
+        $objCourse = $em->find('ChamiloCoreBundle:Course', intval($course_id));
+        $objTime = new DateTime('now', new DateTimeZone('UTC'));
+        $objUser = $em->find('ChamiloUserBundle:User', intval($user_id));
+        $objGroup = $em->find('ChamiloCourseBundle:CGroupInfo', intval($to_group_id));
+        $objToUser = $em->find('ChamiloUserBundle:User', intval($to_user_id));
+        $objSession = $em->find('ChamiloCoreBundle:Session', intval($session_id));
+
+        $startVisibleDate = !empty($start_visible) ? new DateTime($start_visible, new DateTimeZone('UTC')) : null;
+        $endVisibleDate = !empty($endVisibleDate) ? new DateTime($endVisibleDate, new DateTimeZone('UTC')) : null;
+
+        $cItemProperty = new \Chamilo\CourseBundle\Entity\CItemProperty($objCourse);
+        $cItemProperty
+            ->setTool($tool)
+            ->setRef($item_id)
+            ->setInsertDate($objTime)
+            ->setInsertUser($objUser)
+            ->setLasteditDate($objTime)
+            ->setLasteditType($last_edit_type)
+            ->setGroup($objGroup)
+            ->setToUser($objToUser)
+            ->setVisibility($visibility)
+            ->setStartVisible($startVisibleDate)
+            ->setEndVisible($endVisibleDate)
+            ->setSession($objSession);
+
+        $em->persist($cItemProperty);
+        $em->flush();
+
+        $id = $cItemProperty->getIid();
+
         if ($id) {
         if ($id) {
-            $sql = "UPDATE $tableItemProperty SET id = iid WHERE iid = $id";
-            Database::query($sql);
+            $cItemProperty->setId($id);
+            $em->merge($cItemProperty);
+            $em->flush();
+
             return false;
             return false;
         }
         }
     }
     }

+ 38 - 10
main/inc/lib/fileUpload.lib.php

@@ -582,16 +582,30 @@ function handle_uploaded_document(
 
 
                         // Display success message to user
                         // Display success message to user
                         if ($output) {
                         if ($output) {
-                            Display::display_confirmation_message(
-                                get_lang('UplUploadSucceeded') . '<br />' . get_lang('UplFileSavedAs') .' '.$documentTitle,
-                                false
-                            );
+                            if (isset($_POST['moodle_import'])) {
+                                Display::addFlash(
+                                    Display::display_confirmation_message(
+                                        get_lang('UplUploadSucceeded') . '<br />' . get_lang('UplFileSavedAs') . ' ' . $documentTitle,
+                                        false,
+                                        true
+                                    )
+                                );
+                            } else {
+                                Display::display_confirmation_message(
+                                    get_lang('UplUploadSucceeded') . '<br />' . get_lang('UplFileSavedAs') . ' ' . $documentTitle,
+                                    false
+                                );
+                            }
                         }
                         }
 
 
                         return $filePath;
                         return $filePath;
                     } else {
                     } else {
                         if ($output) {
                         if ($output) {
-                            Display::display_error_message(get_lang('UplUnableToSaveFile'));
+                            if (isset($_POST['moodle_import'])) {
+                                Display::addFlash(Display::display_error_message(get_lang('UplUnableToSaveFile'), false, true));
+                            } else {
+                                Display::display_error_message(get_lang('UplUnableToSaveFile'));
+                            }
                         }
                         }
 
 
                         return false;
                         return false;
@@ -601,7 +615,11 @@ function handle_uploaded_document(
                     // Only save the file if it doesn't exist or warn user if it does exist
                     // Only save the file if it doesn't exist or warn user if it does exist
                     if (file_exists($fullPath) && $docId) {
                     if (file_exists($fullPath) && $docId) {
                         if ($output) {
                         if ($output) {
-                            Display::display_error_message($cleanName.' '.get_lang('UplAlreadyExists'));
+                            if (isset($_POST['moodle_import'])) {
+                                Display::addFlash(Display::display_error_message($cleanName.' '.get_lang('UplAlreadyExists'), false, true));
+                            } else {
+                                Display::display_error_message($cleanName.' '.get_lang('UplAlreadyExists'));
+                            }
                         }
                         }
                     } else {
                     } else {
                         if (moveUploadedFile($uploadedFile, $fullPath)) {
                         if (moveUploadedFile($uploadedFile, $fullPath)) {
@@ -648,10 +666,20 @@ function handle_uploaded_document(
 
 
                             // Display success message to user
                             // Display success message to user
                             if ($output) {
                             if ($output) {
-                                Display::display_confirmation_message(
-                                    get_lang('UplUploadSucceeded').'<br /> '.$documentTitle,
-                                    false
-                                );
+                                if (isset($_POST['moodle_import'])) {
+                                    Display::addFlash(
+                                        Display::display_confirmation_message(
+                                            get_lang('UplUploadSucceeded') . '<br /> ' . $documentTitle,
+                                            false,
+                                            true
+                                        )
+                                    );
+                                } else {
+                                    Display::display_confirmation_message(
+                                        get_lang('UplUploadSucceeded') . '<br /> ' . $documentTitle,
+                                        false
+                                    );
+                                }
                             }
                             }
 
 
                             return $filePath;
                             return $filePath;

+ 33 - 27
main/inc/lib/social.lib.php

@@ -1424,23 +1424,28 @@ class SocialManager extends UserManager
             $url = api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$userIdLoop;
             $url = api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$userIdLoop;
             $media = '';
             $media = '';
             $media .= '<div class="rep-post">';
             $media .= '<div class="rep-post">';
-            if ($isOwnWall) {
-                $media .= '<div class="pull-right deleted-mgs">';
-                $media .= '<a title="'.get_lang("SocialMessageDelete").'" href="'.api_get_path(WEB_CODE_PATH).'social/profile.php?messageId='.
-                    $message['id'].'">x</a>';
-                $media .= '</div>';
-            }
-            $media .= '<div class="user-image">';
+            $media .= '<div class="col-md-2 col-xs-2 social-post-answers">';
+            $media .= '<div class="user-image pull-right">';
             $media .= '<a href="'.$url.'" ><img src="'. $users[$userIdLoop]['avatar'] .
             $media .= '<a href="'.$url.'" ><img src="'. $users[$userIdLoop]['avatar'] .
                        '" alt="'.$users[$userIdLoop]['complete_name'].'" class="avatar-thumb"></a>';
                        '" alt="'.$users[$userIdLoop]['complete_name'].'" class="avatar-thumb"></a>';
             $media .= '</div>';
             $media .= '</div>';
+            $media .= '</div>';
+            $media .= '<div class="col-md-9 col-xs-9 social-post-answers">';
             $media .= '<div class="user-data">';
             $media .= '<div class="user-data">';
-            $media .= '<div class="username">' . '<a href="'.$url.'">'.$nameComplete.'</a></div>';
+            $media .= '<div class="username">' . '<a href="'.$url.'">'.$nameComplete.'</a> <span>'.Security::remove_XSS($message['content']).'</span></div>';
             $media .= '<div class="time timeago" title="'.$date.'">'.$date.'</div>';
             $media .= '<div class="time timeago" title="'.$date.'">'.$date.'</div>';
+            $media .= '<br />';
+            $media .= '</div>';
+            $media .= '</div>';
             $media .= '</div>';
             $media .= '</div>';
-            $media .= '<div class="msg-content">';
-            $media .= '<p>'.Security::remove_XSS($message['content']).'</p>';
-            $media .= '</div></div>';
+            if ($isOwnWall) {
+                $media .= '<div class="col-md-1 col-xs-1 social-post-answers">';
+                $media .= '<div class="pull-right deleted-mgs">';
+                $media .= '<a title="'.get_lang("SocialMessageDelete").'" href="'.api_get_path(WEB_CODE_PATH).'social/profile.php?messageId='.
+                    $message['id'].'">x</a>';
+                $media .= '</div>';
+                $media .= '</div>';
+            }
 
 
             $formattedList .= $media;
             $formattedList .= $media;
         }
         }
@@ -1573,6 +1578,9 @@ class SocialManager extends UserManager
         $html .= '</div>';
         $html .= '</div>';
         $html .= '</div>'; // end mediaPost
         $html .= '</div>'; // end mediaPost
 
 
+        // Popularity post functionality
+        $html .= '<div class="popularity-mediapost"></div>';
+
         return $html;
         return $html;
     }
     }
 
 
@@ -1583,28 +1591,26 @@ class SocialManager extends UserManager
      */
      */
     public static function readContentWithOpenGraph($link)
     public static function readContentWithOpenGraph($link)
     {
     {
+        if (strpos($link, "://") === false && substr($link, 0, 1) != "/") {
+            $link = "http://".$link;
+        }
         $graph = OpenGraph::fetch($link);
         $graph = OpenGraph::fetch($link);
+        $link = parse_url($link);
+        $host = $link['host'] ? strtoupper($link['host']) : $link['path'];
         if (!$graph) {
         if (!$graph) {
             return false;
             return false;
         }
         }
         $url = $graph->url;
         $url = $graph->url;
         $image = $graph->image;
         $image = $graph->image;
-        $domain = empty($url) ? parse_url($link) : parse_url($url);
-        $domain = $domain['scheme'].'://'.$domain['host'];
-        // Trick to verify if the Image Url Exist because of some bad metatag dev
-        if (self::verifyUrl($image) == false){
-            if (!($image[0] == '/')){
-                $domain = $domain . '/';
-            }
-            $image = $domain . $image;
-        }
+        $description = $graph->description;
         $title = $graph->title;
         $title = $graph->title;
-
-        $html  = '<div class="thumbnail">';
-        $html .= '<a target="_blank" href="'.$link.'"><h3>'.$title.'</h3>';
-        $html .= empty($image) ? '' : '<img alt="" src="'.$image.'" /></a>';
-        $html .= empty($graph->description) ? '' : '<p class="description">'.$graph->description.'</p>';
-        $html .= '<a href="'.$link.'">'.$link.'</a>';
+        $html  = '<div class="thumbnail social-thumbnail">';
+        $html .= empty($image) ? '' : '<a target="_blank" href="'.$url.'"><img class="img-responsive social-image" src="'.$image.'" /></a>';
+        $html .= '<div class="social-description">';
+        $html .= '<a target="_blank" href="'.$url.'"><h5 class="social-title"><b>'.$title.'</b></h5></a>';
+        $html .= empty($description) ? '' : '<span>'.$description.'</span>';
+        $html .= empty($host) ? '' : '<p>'.$host.'</p>';
+        $html .= '</div>';
         $html .= '</div>';
         $html .= '</div>';
 
 
         return $html;
         return $html;
@@ -1927,7 +1933,7 @@ class SocialManager extends UserManager
             $post = $message['html'];
             $post = $message['html'];
             $comment = SocialManager::getWallMessagesHTML($userId, $friendId, $message['id']);
             $comment = SocialManager::getWallMessagesHTML($userId, $friendId, $message['id']);
 
 
-            $html .= $post.$comment;
+            $html .= Display::panel($post.$comment, '');
         }
         }
 
 
         return $html;
         return $html;

+ 0 - 3
main/install/data.sql

@@ -269,7 +269,6 @@ VALUES
 ('languagePriority4', NULL, 'radio', 'Languages', 'platform_lang','LanguagePriority4Title', 'LanguagePriority4Comment', NULL, NULL, 0),
 ('languagePriority4', NULL, 'radio', 'Languages', 'platform_lang','LanguagePriority4Title', 'LanguagePriority4Comment', NULL, NULL, 0),
 ('login_is_email', NULL, 'radio', 'Platform', 'false', 'LoginIsEmailTitle', 'LoginIsEmailComment', NULL, NULL, 0),
 ('login_is_email', NULL, 'radio', 'Platform', 'false', 'LoginIsEmailTitle', 'LoginIsEmailComment', NULL, NULL, 0),
 ('courses_default_creation_visibility', NULL, 'radio', 'Course', '2', 'CoursesDefaultCreationVisibilityTitle', 'CoursesDefaultCreationVisibilityComment', NULL, NULL, 1),
 ('courses_default_creation_visibility', NULL, 'radio', 'Course', '2', 'CoursesDefaultCreationVisibilityTitle', 'CoursesDefaultCreationVisibilityComment', NULL, NULL, 1),
-('allow_browser_sniffer', NULL, 'radio', 'Tuning', 'false', 'AllowBrowserSnifferTitle', 'AllowBrowserSnifferComment', NULL, NULL, 0),
 ('gradebook_enable_grade_model', NULL, 'radio', 'Gradebook', 'false', 'GradebookEnableGradeModelTitle', 'GradebookEnableGradeModelComment', NULL, NULL, 1),
 ('gradebook_enable_grade_model', NULL, 'radio', 'Gradebook', 'false', 'GradebookEnableGradeModelTitle', 'GradebookEnableGradeModelComment', NULL, NULL, 1),
 ('teachers_can_change_grade_model_settings', NULL, 'radio', 'Gradebook', 'true', 'TeachersCanChangeGradeModelSettingsTitle', 'TeachersCanChangeGradeModelSettingsComment', NULL, NULL, 1),
 ('teachers_can_change_grade_model_settings', NULL, 'radio', 'Gradebook', 'true', 'TeachersCanChangeGradeModelSettingsTitle', 'TeachersCanChangeGradeModelSettingsComment', NULL, NULL, 1),
 ('gradebook_default_weight', NULL, 'textfield', 'Gradebook', '100', 'GradebookDefaultWeightTitle', 'GradebookDefaultWeightComment', NULL, NULL, 0),
 ('gradebook_default_weight', NULL, 'textfield', 'Gradebook', '100', 'GradebookDefaultWeightTitle', 'GradebookDefaultWeightComment', NULL, NULL, 0),
@@ -596,8 +595,6 @@ VALUES
 ('courses_default_creation_visibility', '2', 'OpenToThePlatform'),
 ('courses_default_creation_visibility', '2', 'OpenToThePlatform'),
 ('courses_default_creation_visibility', '1', 'Private'),
 ('courses_default_creation_visibility', '1', 'Private'),
 ('courses_default_creation_visibility', '0', 'CourseVisibilityClosed'),
 ('courses_default_creation_visibility', '0', 'CourseVisibilityClosed'),
-('allow_browser_sniffer', 'true', 'Yes'),
-('allow_browser_sniffer', 'false', 'No'),
 ('teachers_can_change_score_settings', 'true', 'Yes'),
 ('teachers_can_change_score_settings', 'true', 'Yes'),
 ('teachers_can_change_score_settings', 'false', 'No'),
 ('teachers_can_change_score_settings', 'false', 'No'),
 ('teachers_can_change_grade_model_settings', 'true', 'Yes'),
 ('teachers_can_change_grade_model_settings', 'true', 'Yes'),

+ 6 - 6
main/install/index.php

@@ -258,8 +258,8 @@ if (!isset($_GET['running'])) {
     $checkEmailByHashSent = 0;
     $checkEmailByHashSent = 0;
     $ShowEmailNotCheckedToStudent = 1;
     $ShowEmailNotCheckedToStudent = 1;
     $userMailCanBeEmpty = 1;
     $userMailCanBeEmpty = 1;
-    $allowSelfReg = 1;
-    $allowSelfRegProf = 1;
+    $allowSelfReg = 'approval';
+    $allowSelfRegProf = 1; //by default, a user can register as teacher (but moderation might be in place)
     $encryptPassForm = 'bcrypt';
     $encryptPassForm = 'bcrypt';
     if (!empty($_GET['profile'])) {
     if (!empty($_GET['profile'])) {
         $installationProfile = api_htmlentities($_GET['profile'], ENT_QUOTES);
         $installationProfile = api_htmlentities($_GET['profile'], ENT_QUOTES);
@@ -570,7 +570,7 @@ if (@$_POST['step2']) {
             $encryptPassForm = 'none';
             $encryptPassForm = 'none';
         }
         }
 
 
-        $allowSelfReg = false;
+        $allowSelfReg = 'approval';
         $tmp = get_config_param_from_db('allow_registration');
         $tmp = get_config_param_from_db('allow_registration');
         if (!empty($tmp)) {
         if (!empty($tmp)) {
             $allowSelfReg = $tmp;
             $allowSelfReg = $tmp;
@@ -616,7 +616,7 @@ if (@$_POST['step2']) {
         echo get_lang('AdminLogin') . ' : <strong>' . $loginForm . '</strong><br />';
         echo get_lang('AdminLogin') . ' : <strong>' . $loginForm . '</strong><br />';
         echo get_lang('AdminPass') . ' : <strong>' . $passForm . '</strong><br /><br />'; /* TODO: Maybe this password should be hidden too? */
         echo get_lang('AdminPass') . ' : <strong>' . $passForm . '</strong><br /><br />'; /* TODO: Maybe this password should be hidden too? */
     }
     }
-
+    $allowSelfRegistrationLiteral = ($allowSelfReg == 'true') ? get_lang('Yes') : ($allowSelfReg == 'approval' ? get_lang('Approval') : get_lang('No'));
     echo get_lang('AdminFirstName').' : '.$adminFirstName, '<br />', get_lang('AdminLastName').' : '.$adminLastName, '<br />';
     echo get_lang('AdminFirstName').' : '.$adminFirstName, '<br />', get_lang('AdminLastName').' : '.$adminLastName, '<br />';
     echo get_lang('AdminEmail').' : '.$emailForm; ?><br />
     echo get_lang('AdminEmail').' : '.$emailForm; ?><br />
     <?php echo get_lang('AdminPhone').' : '.$adminPhoneForm; ?><br />
     <?php echo get_lang('AdminPhone').' : '.$adminPhoneForm; ?><br />
@@ -626,7 +626,7 @@ if (@$_POST['step2']) {
     <?php echo get_lang('DBLogin').' : '.$dbUsernameForm; ?><br />
     <?php echo get_lang('DBLogin').' : '.$dbUsernameForm; ?><br />
     <?php echo get_lang('DBPassword').' : '.str_repeat('*', api_strlen($dbPassForm)); ?><br />
     <?php echo get_lang('DBPassword').' : '.str_repeat('*', api_strlen($dbPassForm)); ?><br />
     <?php echo get_lang('MainDB').' : <strong>'.$dbNameForm; ?></strong><br />
     <?php echo get_lang('MainDB').' : <strong>'.$dbNameForm; ?></strong><br />
-    <?php echo get_lang('AllowSelfReg').' : '.($allowSelfReg ? get_lang('Yes') : get_lang('No')); ?><br />
+    <?php echo get_lang('AllowSelfReg').' : '. $allowSelfRegistrationLiteral; ?><br />
     <?php echo get_lang('EncryptMethodUserPass').' : ';
     <?php echo get_lang('EncryptMethodUserPass').' : ';
     echo $encryptPassForm;
     echo $encryptPassForm;
     ?>
     ?>
@@ -946,7 +946,7 @@ if (@$_POST['step2']) {
         $connection->executeQuery("ALTER TABLE faq_question ADD CONSTRAINT FK_4A55B05912469DE2 FOREIGN KEY (category_id) REFERENCES faq_category (id);");
         $connection->executeQuery("ALTER TABLE faq_question ADD CONSTRAINT FK_4A55B05912469DE2 FOREIGN KEY (category_id) REFERENCES faq_category (id);");
         */
         */
         // Add version table
         // Add version table
-        $connection->executeQuery('CREATE TABLE version (version varchar(255), PRIMARY KEY(version));');
+        $connection->executeQuery('CREATE TABLE version (id int unsigned NOT NULL AUTO_INCREMENT, version varchar(255), PRIMARY KEY(id));');
 
 
         // Tickets
         // Tickets
         $table = Database::get_main_table(TABLE_TICKET_PROJECT);
         $table = Database::get_main_table(TABLE_TICKET_PROJECT);

+ 6 - 5
main/install/install.lib.php

@@ -1671,13 +1671,13 @@ function display_configuration_settings_form(
     } else {
     } else {
         $html .= '<div class="control-group">';
         $html .= '<div class="control-group">';
         $html .= '<label class="checkbox-inline">
         $html .= '<label class="checkbox-inline">
-                        <input type="radio" name="allowSelfReg" value="1" id="allowSelfReg1" '. ($allowSelfReg == 'true' ? 'checked="checked" ' : '') . ' /> '. get_lang('Yes') .'
+                        <input type="radio" name="allowSelfReg" value="true" id="allowSelfReg1" '. ($allowSelfReg == 'true' ? 'checked="checked" ' : '') . ' /> '. get_lang('Yes') .'
                     </label>';
                     </label>';
         $html .= '<label class="checkbox-inline">
         $html .= '<label class="checkbox-inline">
-                        <input type="radio" name="allowSelfReg" value="0" id="allowSelfReg0" '. ($allowSelfReg == 'false' ? '' : 'checked="checked" ') .' /> '. get_lang('No') .'
+                        <input type="radio" name="allowSelfReg" value="false" id="allowSelfReg0" '. ($allowSelfReg == 'false' ? '' : 'checked="checked" ') .' /> '. get_lang('No') .'
                     </label>';
                     </label>';
          $html .= '<label class="checkbox-inline">
          $html .= '<label class="checkbox-inline">
-                    <input type="radio" name="allowSelfReg" value="0" id="allowSelfReg0" '. ($allowSelfReg == 'approval' ? '' : 'checked="checked" ') .' /> '. get_lang('AfterApproval') .'
+                    <input type="radio" name="allowSelfReg" value="approval" id="allowSelfReg2" '. ($allowSelfReg == 'approval' ? '' : 'checked="checked" ') .' /> '. get_lang('AfterApproval') .'
                 </label>';
                 </label>';
         $html .= '</div>';
         $html .= '</div>';
     }
     }
@@ -1965,9 +1965,10 @@ function installSettings(
     $allowTeacherSelfRegistration,
     $allowTeacherSelfRegistration,
     $installationProfile = ''
     $installationProfile = ''
 ) {
 ) {
-    $allowRegistration = $allowRegistration ? 'true' : 'false';
+    //$allowRegistration = $allowRegistration ? 'true' : 'false';
     $allowTeacherSelfRegistration = $allowTeacherSelfRegistration ? 'true' : 'false';
     $allowTeacherSelfRegistration = $allowTeacherSelfRegistration ? 'true' : 'false';
 
 
+    error_log($allowRegistration);
     // Use PHP 5.3 to avoid issue with weird peripherical auto-installers like travis-ci
     // Use PHP 5.3 to avoid issue with weird peripherical auto-installers like travis-ci
     $settings = array(
     $settings = array(
         'Institution' => $organizationName,
         'Institution' => $organizationName,
@@ -2197,7 +2198,7 @@ function finishInstallation(
     $files = $finder->files()->in($path);
     $files = $finder->files()->in($path);
     foreach ($files as $version) {
     foreach ($files as $version) {
         $version = str_replace(['Version',  '.php' ], '', $version->getFilename());
         $version = str_replace(['Version',  '.php' ], '', $version->getFilename());
-        $sql = "INSERT INTO version VALUES ('$version')";
+        $sql = "INSERT INTO version (version) VALUES ('$version')";
         Database::query($sql);
         Database::query($sql);
     }
     }
 }
 }

+ 8 - 1
main/lang/english/trad4all.inc.php

@@ -1459,7 +1459,7 @@ $UpgradeBase = "Upgrade database";
 $ErrorsFound = "errors found";
 $ErrorsFound = "errors found";
 $Maintenance = "Backup";
 $Maintenance = "Backup";
 $Upgrade = "Upgrade Chamilo";
 $Upgrade = "Upgrade Chamilo";
-$Website = "Chamilo website";
+$Website = "Website";
 $Documentation = "Documentation";
 $Documentation = "Documentation";
 $Contribute = "Contribute";
 $Contribute = "Contribute";
 $InfoServer = "Server Information";
 $InfoServer = "Server Information";
@@ -7814,8 +7814,15 @@ $CourseCreationSplashScreenComment = "The course splash screen show a series of
 $WorksReport = "Assignments report";
 $WorksReport = "Assignments report";
 $AccumulateScormTime = "Accumulate SCORM session time";
 $AccumulateScormTime = "Accumulate SCORM session time";
 $AccumulateScormTimeInfo = "When enabled, the session time for SCORM learning paths will be cumulative, otherwise, it will only be counted from the last update time.";
 $AccumulateScormTimeInfo = "When enabled, the session time for SCORM learning paths will be cumulative, otherwise, it will only be counted from the last update time.";
+$CalendarStartDate = "Start date";
 $DownloadTasksPackage = "Download assignments package";
 $DownloadTasksPackage = "Download assignments package";
 $UploadCorrectionsPackage = "Upload corrections package";
 $UploadCorrectionsPackage = "Upload corrections package";
 $IconsModeSVGTitle = "SVG icons mode";
 $IconsModeSVGTitle = "SVG icons mode";
 $IconsModeSVGComment = "By enabling this option, all icons that have an SVG version will prefer the SVG format to PNG. This will give a much better icons quality but some icons might still have some rendering size issue, and some browsers might not support it.";
 $IconsModeSVGComment = "By enabling this option, all icons that have an SVG version will prefer the SVG format to PNG. This will give a much better icons quality but some icons might still have some rendering size issue, and some browsers might not support it.";
+$FilterByTags = "Filter by tags";
+$ImportFromMoodle = "Import from Moodle";
+$ImportFromMoodleInfo = "Import a Moodle course backup file (.mbz) into this Chamilo course";
+$ImportFromMoodleInstructions = "The Moodle import feature might not support all content types from Moodle, given the fact that not all features are the same, and that Moodle and Chamilo both evolve continuously and rapidly. This import feature should be considered a work in progress. Please check https://support.chamilo.org/projects/chamilo-18/wiki/Moodle_import for more information.";
+$MoodleFile = "Moodle course file";
+$FailedToImportThisIsNotAMoodleFile = "Failed to import: this doesn't seem to be a Moodle course backup file (.mbz)";
 ?>
 ?>

+ 7 - 0
main/lang/french/trad4all.inc.php

@@ -7761,8 +7761,15 @@ $CourseCreationSplashScreenComment = "L'écran d'accueil de création de cours m
 $WorksReport = "Rapport";
 $WorksReport = "Rapport";
 $AccumulateScormTime = "Temps cumulatif SCORM";
 $AccumulateScormTime = "Temps cumulatif SCORM";
 $AccumulateScormTimeInfo = "Si activé, le temps de session pour les parcours SCORM sera cumulatif. Sinon, il sera uniquement compté depuis le dernier temps de connexion.";
 $AccumulateScormTimeInfo = "Si activé, le temps de session pour les parcours SCORM sera cumulatif. Sinon, il sera uniquement compté depuis le dernier temps de connexion.";
+$CalendarStartDate = "Date de début";
 $DownloadTasksPackage = "Télécharger tous les travaux";
 $DownloadTasksPackage = "Télécharger tous les travaux";
 $UploadCorrectionsPackage = "Envoyer un paquet de travaux";
 $UploadCorrectionsPackage = "Envoyer un paquet de travaux";
 $IconsModeSVGTitle = "Mode SVG des icônes";
 $IconsModeSVGTitle = "Mode SVG des icônes";
 $IconsModeSVGComment = "Cette option, lorsqu'elle est activée, préférera les icônes au format vectoriel SVG aux icônes bitmap PNG. Cela donnera un rendu beaucoup plus fin, mais certaines icônes pourraient avoir de petits problèmes de dimensions, et quelques navigateurs pourraient ne pas supporter ce format.";
 $IconsModeSVGComment = "Cette option, lorsqu'elle est activée, préférera les icônes au format vectoriel SVG aux icônes bitmap PNG. Cela donnera un rendu beaucoup plus fin, mais certaines icônes pourraient avoir de petits problèmes de dimensions, et quelques navigateurs pourraient ne pas supporter ce format.";
+$FilterByTags = "Filtrer par tag";
+$ImportFromMoodle = "Importer depuis Moodle";
+$ImportFromMoodleInfo = "Importer un fichier de backup de cours de Moodle (.mbz) dans ce cours de Chamilo";
+$ImportFromMoodleInstructions = "La fonctionnalité d'importation peut ne pas supporter tous les types de contenus de Moodle, étant donné le fait que les fonctionnalités ne sont pas toutes identiques, et que Moodle et Chamilo continuent d'évoluer continuellement et rapidement. Cette fonctionnalité d'import devrait être considérée comme un travail en cours. Merci de réviser la page suivante pour plus d'information: <a href='https://support.chamilo.org/projects/chamilo-18/wiki/Moodle_import'>https://support.chamilo.org/projects/chamilo-18/wiki/Moodle_import</a>";
+$MoodleFile = "Fichier de cours de Moodle";
+$FailedToImportThisIsNotAMoodleFile = "Problème rencontré lors de l'importation: le fichier soumis ne semble pas être un fichier de backup de cours de Moodle (.mbz)";
 ?>
 ?>

+ 8 - 0
main/lang/spanish/trad4all.inc.php

@@ -7833,7 +7833,15 @@ $CourseCreationSplashScreenComment = "La pantalla de bienvenida muestra una seri
 $WorksReport = "Reporte de tareas";
 $WorksReport = "Reporte de tareas";
 $AccumulateScormTime = "Acumular tiempo de sesión SCORM";
 $AccumulateScormTime = "Acumular tiempo de sesión SCORM";
 $AccumulateScormTimeInfo = "Cuando se activa, el tiempo de una sesión para una secuencia de aprendizaje SCORM será acumulativo, de lo contrario, sólo se contará desde el momento de la última actualización.";
 $AccumulateScormTimeInfo = "Cuando se activa, el tiempo de una sesión para una secuencia de aprendizaje SCORM será acumulativo, de lo contrario, sólo se contará desde el momento de la última actualización.";
+$CalendarStartDate = "Fecha de inicio";
 $DownloadTasksPackage = "Descargar tareas en paquete";
 $DownloadTasksPackage = "Descargar tareas en paquete";
+$UploadCorrectionsPackage = "Subir un paquete de correcciones";
 $IconsModeSVGTitle = "Modo SVG de iconos";
 $IconsModeSVGTitle = "Modo SVG de iconos";
 $IconsModeSVGComment = "Esta opción permite, si es activada, preferir el formato vectorial SVG al formato bitmap PNG para todos los iconos que tienen tal versión. Esto permite obtener una calidad de iconos mucho más fina, pero algunos iconos podrían tener problemas de tamaño, y algunos navegadores podrían no soportarlas.";
 $IconsModeSVGComment = "Esta opción permite, si es activada, preferir el formato vectorial SVG al formato bitmap PNG para todos los iconos que tienen tal versión. Esto permite obtener una calidad de iconos mucho más fina, pero algunos iconos podrían tener problemas de tamaño, y algunos navegadores podrían no soportarlas.";
+$FilterByTags = "Filtrar por tags";
+$ImportFromMoodle = "Importar desde Moodle";
+$ImportFromMoodleInfo = "Importar un archivo de backup de curso de Moodle (.mbz) dentro de este curso de Chamilo";
+$ImportFromMoodleInstructions = "La funcionalidad de importación desde Moodle podría no soportar todos los tipos de contenido de Moodle, dado el hecho que no todas las funcionalidades existen en ambas plataformas, y que Moodle y Chamilo siguen evolucionando contínuamente y rápidamente. Esta funcionalidad de importación debería ser considerada como un trabajo en progreso. Consulte la página siguiente para mayor información: <a href='https://support.chamilo.org/projects/chamilo-18/wiki/Moodle_import'>https://support.chamilo.org/projects/chamilo-18/wiki/Moodle_import</a>";
+$MoodleFile = "Archivo de curso de Moodle";
+$FailedToImportThisIsNotAMoodleFile = "La importación tuvo un problema: este archivo no parece ser un archivo de backup de curso de Moodle (.mbz)";
 ?>
 ?>

+ 51 - 20
main/session/add_users_to_session.php

@@ -51,11 +51,21 @@ $new_field_list = array();
 if (is_array($extra_field_list)) {
 if (is_array($extra_field_list)) {
     foreach ($extra_field_list as $extra_field) {
     foreach ($extra_field_list as $extra_field) {
         //if is enabled to filter and is a "<select>" field type
         //if is enabled to filter and is a "<select>" field type
-        if ($extra_field[8]==1 && $extra_field[2]==4) {
+        if ($extra_field[8] == 1 && $extra_field[2] == ExtraField::FIELD_TYPE_SELECT) {
             $new_field_list[] = array(
             $new_field_list[] = array(
-                'name'=> $extra_field[3],
-                'variable'=>$extra_field[1],
-                'data'=> $extra_field[9]
+                'name' => $extra_field[3],
+                'type' => $extra_field[2],
+                'variable' => $extra_field[1],
+                'data' => $extra_field[9],
+            );
+        }
+        if ($extra_field[8] == 1 && $extra_field[2] == ExtraField::FIELD_TYPE_TAG) {
+            $options = UserManager::get_extra_user_data_for_tags($extra_field[1]);
+            $new_field_list[] = array(
+                'name' => $extra_field[3],
+                'type' => $extra_field[2],
+                'variable' => $extra_field[1],
+                'data' => $options['options'],
             );
             );
         }
         }
     }
     }
@@ -386,19 +396,28 @@ if ($ajax_search) {
     unset($users); //clean to free memory
     unset($users); //clean to free memory
 } else {
 } else {
     //Filter by Extra Fields
     //Filter by Extra Fields
+    $extra_field_result = [];
     $use_extra_fields = false;
     $use_extra_fields = false;
     if (is_array($extra_field_list)) {
     if (is_array($extra_field_list)) {
-        if (is_array($new_field_list) && count($new_field_list)>0 ) {
-            $result_list=array();
+        if (is_array($new_field_list) && count($new_field_list) > 0) {
+            $result_list = array();
             foreach ($new_field_list as $new_field) {
             foreach ($new_field_list as $new_field) {
                 $varname = 'field_'.$new_field['variable'];
                 $varname = 'field_'.$new_field['variable'];
+                $fieldtype = $new_field['type'];
                 if (UserManager::is_extra_field_available($new_field['variable'])) {
                 if (UserManager::is_extra_field_available($new_field['variable'])) {
-                    if (isset($_POST[$varname]) && $_POST[$varname]!='0') {
+                    if (isset($_POST[$varname]) && $_POST[$varname] != '0') {
                         $use_extra_fields = true;
                         $use_extra_fields = true;
-                        $extra_field_result[] = UserManager::get_extra_user_data_by_value(
-                            $new_field['variable'],
-                            $_POST[$varname]
-                        );
+                        if ($fieldtype == ExtraField::FIELD_TYPE_TAG) {
+                            $extra_field_result[]= UserManager::get_extra_user_data_by_tags(
+                                intval($_POST['field_id']),
+                                $_POST[$varname]
+                            );
+                        } else {
+                            $extra_field_result[]= UserManager::get_extra_user_data_by_value(
+                                $new_field['variable'],
+                                $_POST[$varname]
+                            );
+                        }
                     }
                     }
                 }
                 }
             }
             }
@@ -567,19 +586,31 @@ if ($add_type=='multiple') {
 			foreach ($new_field_list as $new_field) {
 			foreach ($new_field_list as $new_field) {
 				echo $new_field['name'];
 				echo $new_field['name'];
 				$varname = 'field_'.$new_field['variable'];
 				$varname = 'field_'.$new_field['variable'];
+                $fieldtype = $new_field['type'];
 				echo '&nbsp;<select name="'.$varname.'">';
 				echo '&nbsp;<select name="'.$varname.'">';
 				echo '<option value="0">--'.get_lang('Select').'--</option>';
 				echo '<option value="0">--'.get_lang('Select').'--</option>';
 				foreach	($new_field['data'] as $option) {
 				foreach	($new_field['data'] as $option) {
 					$checked='';
 					$checked='';
-					if (isset($_POST[$varname])) {
-						if ($_POST[$varname]==$option[1]) {
-							$checked = 'selected="true"';
-						}
-					}
-					echo '<option value="'.$option[1].'" '.$checked.'>'.$option[1].'</option>';
-				}
-				echo '</select>';
-				echo '&nbsp;&nbsp;';
+                    if ($fieldtype == ExtraField::FIELD_TYPE_TAG) {
+                        if (isset($_POST[$varname])) {
+                            if ($_POST[$varname] == $option['tag']) {
+                                $checked = 'selected="true"';
+                            }
+                        }
+                        echo '<option value="'.$option['tag'].'" '.$checked.'>'.$option['tag'].'</option>';
+                    } else {
+                        if (isset($_POST[$varname])) {
+                            if ($_POST[$varname] == $option[1]) {
+                                $checked = 'selected="true"';
+                            }
+                        }
+                        echo '<option value="'.$option[1].'" '.$checked.'>'.$option[1].'</option>';
+                    }
+                }
+                echo '</select>';
+                $extraHidden = $fieldtype == ExtraField::FIELD_TYPE_TAG ? '<input type="hidden" name="field_id" value="'.$option['field_id'].'" />' : '';
+                echo $extraHidden;
+                echo '&nbsp;&nbsp;';
 			}
 			}
 			echo '<input type="button" value="'.get_lang('Filter').'" onclick="validate_filter()" />';
 			echo '<input type="button" value="'.get_lang('Filter').'" onclick="validate_filter()" />';
 			echo '<br /><br />';
 			echo '<br /><br />';

+ 6 - 4
main/social/profile.php

@@ -286,8 +286,7 @@ $social_wall_block = $wallSocialAddPost;
 // Social Post Wall
 // Social Post Wall
 $posts = SocialManager::getWallMessagesByUser($my_user_id, $friendId) ;
 $posts = SocialManager::getWallMessagesByUser($my_user_id, $friendId) ;
 
 
-$posts = empty($posts) ? '<p>'.get_lang("NoPosts").'</p>' : $posts;
-$social_post_wall_block = Display::panel($posts, get_lang('Posts'));
+$social_post_wall_block = empty($posts) ? '<p>'.get_lang("NoPosts").'</p>' : $posts;
 
 
 $socialAutoExtendLink = Display::url(
 $socialAutoExtendLink = Display::url(
     get_lang('SeeMore'),
     get_lang('SeeMore'),
@@ -300,8 +299,11 @@ $socialAutoExtendLink = Display::url(
 // Added a Jquery Function to return the Preview of OpenGraph URL Content
 // Added a Jquery Function to return the Preview of OpenGraph URL Content
 $htmlHeadXtra[] = '<script>
 $htmlHeadXtra[] = '<script>
 $(document).ready(function() {
 $(document).ready(function() {
-    
-    $("[name=\'social_wall_new_msg_main\']").on("paste", function(e) {
+
+    var getUrl = $("[name=\'social_wall_new_msg_main\']");
+    var matchUrl = /https?:\/\/w{0,3}\w*?\.(\w*?\.)?\w{2,3}\S*|www\.(\w*?\.)?\w*?\.\w{2,3}\S*|(\w*?\.)?\w*?\.\w{2,3}[\/\?]\S*/ ;
+
+    getUrl.on("paste", function(e) {
         $.ajax({
         $.ajax({
             contentType: "application/x-www-form-urlencoded",
             contentType: "application/x-www-form-urlencoded",
             beforeSend: function() {
             beforeSend: function() {

+ 4 - 0
main/template/default/coursecopy/import_moodle.tpl

@@ -0,0 +1,4 @@
+{{ info_msg }}
+<br />
+<br />
+{{ form }}

+ 5 - 0
main/work/upload.php

@@ -105,6 +105,11 @@ if ($form->validate()) {
         if ($is_allowed_to_edit) {
         if ($is_allowed_to_edit) {
             $script = 'work_list_all.php';
             $script = 'work_list_all.php';
         }
         }
+        if (!$result) {
+            Display::addFlash(Display::return_message(get_lang('UploadError'), 'error'));
+        } else {
+            Display::addFlash(Display::return_message(get_lang('UplUploadSucceeded'), 'success'));
+        }
         header('Location: '.api_get_path(WEB_CODE_PATH).'work/'.$script.'?'.api_get_cidreq().'&id='.$work_id);
         header('Location: '.api_get_path(WEB_CODE_PATH).'work/'.$script.'?'.api_get_cidreq().'&id='.$work_id);
         exit;
         exit;
     } else {
     } else {

+ 30 - 0
src/Chamilo/CoreBundle/Entity/Message.php

@@ -75,6 +75,13 @@ class Message
      */
      */
     private $updateDate;
     private $updateDate;
 
 
+    /**
+     * @var integer
+     *
+     * @ORM\Column(name="votes", type="integer", nullable=true)
+     */
+    private $votes;
+
     /**
     /**
      * @var integer
      * @var integer
      *
      *
@@ -302,4 +309,27 @@ class Message
     {
     {
         return $this->id;
         return $this->id;
     }
     }
+
+    /**
+     * Set votes
+     *
+     * @param integer $votes
+     * @return integer
+     */
+    public function setVotes($votes)
+    {
+        $this->votes = $votes;
+
+        return $this;
+    }
+
+    /**
+     * Get votes
+     *
+     * @return integer
+     */
+    public function getVotes()
+    {
+        return $this->votes;
+    }
 }
 }

File diff suppressed because it is too large
+ 516 - 518
src/Chamilo/CourseBundle/Component/CourseCopy/CourseRestorer.php


+ 15 - 5
src/Chamilo/CourseBundle/Entity/CItemProperty.php

@@ -126,12 +126,13 @@ class CItemProperty
 
 
     /**
     /**
      * CItemProperty constructor.
      * CItemProperty constructor.
+     * @param Course $course
      */
      */
     public function __construct(Course $course)
     public function __construct(Course $course)
     {
     {
         $this->course = $course;
         $this->course = $course;
-        $this->insertDate = new \DateTime();
-        $this->lasteditDate = new \DateTime();
+        $this->insertDate = new \DateTime('now', new \DateTimeZone('UTC'));
+        $this->lasteditDate = new \DateTime('now', new \DateTimeZone('UTC'));
     }
     }
 
 
     /**
     /**
@@ -189,7 +190,7 @@ class CItemProperty
      *
      *
      * @return CItemProperty
      * @return CItemProperty
      */
      */
-    public function setLasteditDate($lasteditDate)
+    public function setLasteditDate(\DateTime $lasteditDate)
     {
     {
         $this->lasteditDate = $lasteditDate;
         $this->lasteditDate = $lasteditDate;
 
 
@@ -309,7 +310,7 @@ class CItemProperty
      *
      *
      * @return CItemProperty
      * @return CItemProperty
      */
      */
-    public function setStartVisible($startVisible)
+    public function setStartVisible(\DateTime $startVisible = null)
     {
     {
         $this->startVisible = $startVisible;
         $this->startVisible = $startVisible;
 
 
@@ -333,7 +334,7 @@ class CItemProperty
      *
      *
      * @return CItemProperty
      * @return CItemProperty
      */
      */
-    public function setEndVisible($endVisible)
+    public function setEndVisible(\DateTime $endVisible = null)
     {
     {
         $this->endVisible = $endVisible;
         $this->endVisible = $endVisible;
 
 
@@ -474,4 +475,13 @@ class CItemProperty
 
 
         return $this;
         return $this;
     }
     }
+
+    /**
+     * Get iid
+     * @return int
+     */
+    public function getIid()
+    {
+        return $this->iid;
+    }
 }
 }

Some files were not shown because too many files changed in this diff