diff --git a/main/cron/import_csv.php b/main/cron/import_csv.php
index 0bb0e7301f..7973d7a40b 100755
--- a/main/cron/import_csv.php
+++ b/main/cron/import_csv.php
@@ -1429,20 +1429,39 @@ class ImportCsv
$courseTitle = $courseInfo['title'];
+ // Get the value of the "careerid" extra field of this
+ // session
$sessionExtraFieldValue = new ExtraFieldValue('session');
- $values = $sessionExtraFieldValue->get_values_by_handler_and_field_variable(
+ $externalCareerIdList = $sessionExtraFieldValue->get_values_by_handler_and_field_variable(
$event['session_id'],
- $this->extraFieldIdNameList['session_career']
+ 'careerid'
);
+ $externalCareerIdList = $externalCareerIdList['value'];
+ $externalCareerIds = [];
+ if (substr($externalCareerIdList, 0, 1) === '[') {
+ $externalCareerIdList = substr($externalCareerIdList, 1, -1);
+ $externalCareerIds = preg_split('/,/',$externalCareerIdList);
+ } else {
+ $externalCareerIds = [$externalCareerIdList];
+ }
+ $careerExtraFieldValue = new ExtraFieldValue('career');
+ $career = new Career();
$careerName = '';
- if (!empty($values)) {
- foreach ($values as $value) {
- if (isset($value['value'])) {
- $careerName = $value['value'];
- }
- }
+
+ // Concat the names of each career linked to this session
+ foreach ($externalCareerIds as $externalCareerId) {
+ // Using the external_career_id field (from above),
+ // find the career ID
+ $careerValue = $careerExtraFieldValue->get_item_id_from_field_variable_and_field_value(
+ 'external_career_id',
+ $externalCareerId
+ );
+ $career = $career->find($careerValue['item_id']);
+ $careerName .= $career['name'].', ';
}
+ // Remove trailing comma
+ $careerName = substr($careerName, 0, -2);
$subject = sprintf(
get_lang('WelcomeToPortalXInCourseSessionX'),
diff --git a/main/exercise/exercise.class.php b/main/exercise/exercise.class.php
index b48f8c2a1b..98165974df 100755
--- a/main/exercise/exercise.class.php
+++ b/main/exercise/exercise.class.php
@@ -1048,18 +1048,18 @@ class Exercise
switch ($questionSelectionType) {
case EX_Q_SELECTION_ORDERED:
- $questionList = $this->getQuestionOrderedList();
+ $questionList = $this->getQuestionOrderedList($adminView);
break;
case EX_Q_SELECTION_RANDOM:
// Not a random exercise, or if there are not at least 2 questions
if ($this->random == 0 || $nbQuestions < 2) {
- $questionList = $this->getQuestionOrderedList();
+ $questionList = $this->getQuestionOrderedList($adminView);
} else {
$questionList = $this->getRandomList($adminView);
}
break;
default:
- $questionList = $this->getQuestionOrderedList();
+ $questionList = $this->getQuestionOrderedList($adminView);
$result = $this->getQuestionListWithCategoryListFilteredByCategorySettings(
$questionList,
$questionSelectionType
@@ -1730,9 +1730,6 @@ class Exercise
$this->save_categories_in_exercise($this->categories);
- // Updates the question position
- $this->update_question_positions();
-
return $this->iId;
}
@@ -9147,7 +9144,7 @@ class Exercise
}
$currentRow = [
- $row['iid'],
+ $row['id'],
$currentRow['title'],
$currentRow['count_questions'],
$actions,
@@ -9655,9 +9652,11 @@ class Exercise
/**
* Gets the question list ordered by the question_order setting (drag and drop).
*
+ * @param bool $adminView Optional.
+ *
* @return array
*/
- private function getQuestionOrderedList()
+ private function getQuestionOrderedList($adminView = false)
{
$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
@@ -9693,8 +9692,13 @@ class Exercise
$counter = 1;
$questionList = [];
while ($new_object = Database::fetch_object($result)) {
- // Correct order.
- $questionList[$new_object->question_order] = $new_object->question_id;
+ if (!$adminView) {
+ // Correct order.
+ $questionList[$new_object->question_order] = $new_object->question_id;
+ } else {
+ $questionList[$counter] = $new_object->question_id;
+ }
+
// Just in case we save the order in other array
$temp_question_list[$counter] = $new_object->question_id;
$counter++;
diff --git a/main/inc/lib/formvalidator/FormValidator.class.php b/main/inc/lib/formvalidator/FormValidator.class.php
index e2430b6430..cb7268922c 100755
--- a/main/inc/lib/formvalidator/FormValidator.class.php
+++ b/main/inc/lib/formvalidator/FormValidator.class.php
@@ -262,14 +262,17 @@ EOT;
* @param array $options
* @param array $attributes
*
- * @throws
+ * @throws Exception
+ *
+ * @return HTML_QuickForm_element
*/
public function addSelectAjax($name, $label, $options = [], $attributes = [])
{
if (!isset($attributes['url'])) {
throw new \Exception('select_ajax needs an URL');
}
- $this->addElement(
+
+ return $this->addElement(
'select_ajax',
$name,
$label,
diff --git a/main/inc/lib/javascript/ckeditor/plugins/oembed/plugin.js b/main/inc/lib/javascript/ckeditor/plugins/oembed/plugin.js
index 586f3ead5d..1f03e0caf5 100644
--- a/main/inc/lib/javascript/ckeditor/plugins/oembed/plugin.js
+++ b/main/inc/lib/javascript/ckeditor/plugins/oembed/plugin.js
@@ -148,6 +148,12 @@
}
function embedCode(url, instance, closeDialog, maxWidth, maxHeight, responsiveResize, widget) {
+ var extraProviderParams = {};
+
+ if (responsiveResize) {
+ extraProviderParams.responsive = true;
+ }
+
jQuery('body').oembed(url, {
onEmbed: function(e) {
var codeElement,
@@ -197,7 +203,7 @@
}
if (elementAdded) {
- if (closeDialog) {
+ if (closeDialog && CKEDITOR.dialog.getCurrent()) {
CKEDITOR.dialog.getCurrent().hide();
}
}
@@ -213,7 +219,8 @@
maxHeight: maxHeight,
maxWidth: maxWidth,
useResponsiveResize: responsiveResize,
- embedMethod: 'editor'
+ embedMethod: 'editor',
+ 'vimeo': extraProviderParams
});
}
@@ -223,9 +230,9 @@
minWidth: CKEDITOR.env.ie && CKEDITOR.env.quirks ? 568 : 550,
minHeight: 155,
onShow: function() {
- var resizetype = this.getContentElement('general', 'resizeType').getValue(),
- maxSizeBox = this.getContentElement('general', 'maxSizeBox').getElement(),
- sizeBox = this.getContentElement('general', 'sizeBox').getElement();
+ var resizetype = CKEDITOR.dialog.getCurrent().getContentElement('general', 'resizeType').getValue(),
+ maxSizeBox = CKEDITOR.dialog.getCurrent().getContentElement('general', 'maxSizeBox').getElement(),
+ sizeBox = CKEDITOR.dialog.getCurrent().getContentElement('general', 'sizeBox').getElement();
if (resizetype == 'noresize') {
maxSizeBox.hide();
@@ -284,19 +291,19 @@
responsiveResize = false;
} else {
if (resizetype == "responsive") {
- maxWidth = this.getContentElement('general', 'maxWidth').
+ maxWidth = CKEDITOR.dialog.getCurrent().getContentElement('general', 'maxWidth').
getInputElement().
getValue();
- maxHeight = this.getContentElement('general', 'maxHeight').
+ maxHeight = CKEDITOR.dialog.getCurrent().getContentElement('general', 'maxHeight').
getInputElement().
getValue();
responsiveResize = true;
} else if (resizetype == "custom") {
- maxWidth = this.getContentElement('general', 'width').
+ maxWidth = CKEDITOR.dialog.getCurrent().getContentElement('general', 'width').
getInputElement().
getValue();
- maxHeight = this.getContentElement('general', 'height').
+ maxHeight = CKEDITOR.dialog.getCurrent().getContentElement('general', 'height').
getInputElement().
getValue();
diff --git a/main/inc/lib/javascript/ckeditor/plugins/video/dialogs/video.js b/main/inc/lib/javascript/ckeditor/plugins/video/dialogs/video.js
index e2c05d696e..c08edb281b 100644
--- a/main/inc/lib/javascript/ckeditor/plugins/video/dialogs/video.js
+++ b/main/inc/lib/javascript/ckeditor/plugins/video/dialogs/video.js
@@ -38,14 +38,17 @@ CKEDITOR.dialog.add( 'video', function ( editor )
return;
switch( this.id )
{
+ case 'responsive':
+ videoNode.addClass('embed-responsive-item');
+ break;
case 'poster':
extraStyles.backgroundImage = 'url(' + value + ')';
break;
case 'width':
- extraStyles.width = value + 'px';
+ extraStyles.width = value.indexOf('%') > 0 ? '100%' : ( value + 'px');
break;
case 'height':
- extraStyles.height = value + 'px';
+ extraStyles.height = value.indexOf('%') > 0 ? '100%' : ( value + 'px');
break;
}
}
@@ -176,6 +179,15 @@ CKEDITOR.dialog.add( 'video', function ( editor )
}
var extraStyles = {}, videos = [];
+ var responsive = this.getValueOf('info', 'responsive');
+
+ videoNode.removeClass('embed-responsive-item');
+
+ if (responsive) {
+ this.setValueOf('info', 'width', '100%');
+ this.setValueOf('info', 'height', '100%');
+ }
+
this.commitContent( videoNode, extraStyles, videos );
var innerHtml = '', links = '',
@@ -191,6 +203,7 @@ CKEDITOR.dialog.add( 'video', function ( editor )
}
videoNode.setHtml( innerHtml + fallbackTemplate.replace( '%links%', links ) );
+ var responsiveParent = null;
// Refresh the fake image.
var newFakeImage = editor.createFakeElement( videoNode, 'cke_video', 'video', false );
newFakeImage.setStyles( extraStyles );
@@ -198,6 +211,13 @@ CKEDITOR.dialog.add( 'video', function ( editor )
{
newFakeImage.replace( this.fakeImage );
editor.getSelection().selectElement( newFakeImage );
+
+ if (responsive) {
+ responsiveParent = newFakeImage.getParent();
+ responsiveParent.removeClass('embed-responsive');
+ responsiveParent.removeClass('embed-responsive-16by9');
+ responsiveParent.removeClass('embed-responsive-4by3');
+ }
}
else
{
@@ -205,6 +225,21 @@ CKEDITOR.dialog.add( 'video', function ( editor )
var div = new CKEDITOR.dom.element( 'DIV', editor.document );
editor.insertElement( div );
div.append( newFakeImage );
+
+ responsiveParent = div;
+ }
+
+ if (responsive) {
+ responsiveParent.addClass('embed-responsive');
+
+ switch (responsive) {
+ case '16by9':
+ responsiveParent.addClass('embed-responsive-16by9');
+ break;
+ case '4by3':
+ responsiveParent.addClass('embed-responsive-4by3');
+ break;
+ }
}
},
onHide : function()
@@ -226,37 +261,6 @@ CKEDITOR.dialog.add( 'video', function ( editor )
label: lang.infoLabel,
elements :
[
- {
- type : 'hbox',
- widths: [ '33%', '33%', '33%'],
- children : [
- {
- type : 'text',
- id : 'width',
- label : editor.lang.common.width,
- 'default' : 400,
- validate : CKEDITOR.dialog.validate.notEmpty( lang.widthRequired ),
- commit : commitValue,
- setup : loadValue
- },
- {
- type : 'text',
- id : 'height',
- label : editor.lang.common.height,
- 'default' : 300,
- //validate : CKEDITOR.dialog.validate.notEmpty(lang.heightRequired ),
- commit : commitValue,
- setup : loadValue
- },
- {
- type : 'text',
- id : 'id',
- label : 'Id',
- commit : commitValue,
- setup : loadValue
- }
- ]
- },
{
type : 'hbox',
widths: [ '', '100px', '75px'],
@@ -375,6 +379,45 @@ CKEDITOR.dialog.add( 'video', function ( editor )
},
label : editor.lang.common.browseServer
}]
+ },
+ {
+ type : 'hbox',
+ widths: [ '33%', '33%', '33%'],
+ children : [
+ {
+ type : 'text',
+ id : 'width',
+ label : editor.lang.common.width,
+ 'default' : 400,
+ validate : CKEDITOR.dialog.validate.notEmpty( lang.widthRequired ),
+ commit : commitValue,
+ setup : loadValue
+ },
+ {
+ type : 'text',
+ id : 'height',
+ label : editor.lang.common.height,
+ 'default' : 300,
+ //validate : CKEDITOR.dialog.validate.notEmpty(lang.heightRequired ),
+ commit : commitValue,
+ setup : loadValue
+ },
+ {
+ type : 'text',
+ id : 'id',
+ label : 'Id',
+ commit : commitValue,
+ setup : loadValue
+ }
+ ]
+ },
+ {
+ type: 'radio',
+ id: 'responsive',
+ label: lang.responsive,
+ items: [ [ lang.ratio16by9, '16by9' ], [ lang.ratio4by3, '4by3' ] ],
+ commit : commitValue,
+ setup : loadValue
}
]
},
diff --git a/main/inc/lib/javascript/ckeditor/plugins/video/plugin.js b/main/inc/lib/javascript/ckeditor/plugins/video/plugin.js
index 17c12672c7..d70cf7e086 100644
--- a/main/inc/lib/javascript/ckeditor/plugins/video/plugin.js
+++ b/main/inc/lib/javascript/ckeditor/plugins/video/plugin.js
@@ -183,7 +183,10 @@ var en = {
infoLabel: 'Information',
html360: 'This feature (only MP4 videos) is currently still in BETA mode.
It only works on dynamic pages, not inside documents created
in the documents tool or seen through learning paths.
Please do not add more than one 360° video on a single page
as more than one on the same page might generate conflicts.',
video360: 'Enable 360° video player',
- video360stereo: 'Stereo video (1:1 aspect ratio)'
+ video360stereo: 'Stereo video (1:1 aspect ratio)',
+ responsive: 'Resposive size (mobile-optimized)',
+ ratio16by9: '16:9 aspect ratio',
+ ratio4by3: '4:3 aspect ratio'
};
var es = {
@@ -201,7 +204,10 @@ var es = {
infoLabel: 'Información',
html360: 'Esta funcionalidad (sólo MP4) todavía se encuentra en modo BETA.
Sólo funciona en páginas dinámicas, mas no dentro de documentos
creados en la herramienta de documentos o visualizados a través
de las lecciones.
Por favor no colocar más de un vídeo 360° en una misma página
ya que puede provocar conflictos y bloquearlos todos.',
video360: 'Habilitar reproductor de vídeo 360°',
- video360stereo: 'Vídeo estéreo (relación de aspecto 1:1)'
+ video360stereo: 'Vídeo estéreo (relación de aspecto 1:1)',
+ responsive: 'Tamaño adaptable (tamaño optimizado para móviles)',
+ ratio16by9: 'Relación de aspecto 16:9',
+ ratio4by3: 'Relación de aspecto 4:3'
};
var fr = {
@@ -219,7 +225,10 @@ var fr = {
infoLabel: 'Information',
html360: 'Cette fonctionnalité (MP4 uniquement) est actuellement en mode BETA.
Elle ne fonctionne que sur les pages dynamiques, et pas
dans les documents créés à partir de l\'outil document ou visualisés
au travers de l\'outil parcours.
Merci de ne pas placer plus d\'une vidéo 360° par page. Cela
peut causer des conflits et toutes les rendre inactives.',
video360: 'Activer la visualisation 360°',
- video360stereo: 'Vidéo stéréo (proportions 1:1 / apparence de 2 vidéos superposées)'
+ video360stereo: 'Vidéo stéréo (proportions 1:1 / apparence de 2 vidéos superposées)',
+ responsive: 'Resposive',
+ ratio16by9: '16:9 aspect ratio',
+ ratio4by3: '4:3 aspect ratio'
};
// v3
diff --git a/main/lp/learnpath.class.php b/main/lp/learnpath.class.php
index 14ecd220ef..7960ccb4e6 100755
--- a/main/lp/learnpath.class.php
+++ b/main/lp/learnpath.class.php
@@ -6535,7 +6535,7 @@ class learnpath
$sub_list = '';
if (isset($item['type']) && $item['type'] == 'dir') {
// empty value
- $sub_list = Display::tag('li', '', ['class' => 'sub_item empty record li_container']);
+ $sub_list = Display::tag('li', '', ['class' => 'sub_item empty']);
}
if (empty($item['children'])) {
$sub_list = Display::tag('ul', $sub_list, ['id' => 'UL_'.$key, 'class' => 'record li_container']);
diff --git a/main/lp/lp_controller.php b/main/lp/lp_controller.php
index 8589843d4a..26860fd3f0 100755
--- a/main/lp/lp_controller.php
+++ b/main/lp/lp_controller.php
@@ -102,36 +102,127 @@ $htmlHeadXtra[] = '
var jItems = $("#lp_item_list li.li_container");
var jItem = $("#"+ itemId);
var index = jItems.index(jItem);
- var total = jItems.length;
+ var total = jItems.length;
+
+ //console.log("total " + total);
+ //console.log("current " + index);
+
switch (dir) {
case "up":
if (index != 0 && jItems[index - 1]) {
- var subItems = $(jItems[index - 1]).find("li.sub_item");
+ /*var subItems = $(jItems[index - 1]).find("li.sub_item");
if (subItems.length >= 0) {
index = index - 1;
+ }*/
+ var subItems = $(jItems[index - 1]).find("li.sub_item");
+ var parentClass = $(jItems[index - 1]).parent().parent().attr("class");
+ var parentId = $(jItems[index]).parent().parent().attr("id");
+ var myParentId = $(jItems[index - 1]).parent().parent().attr("id");
+ //console.log(parentId + " - " + myParentId);
+
+ // We are brothers!
+ if (parentId == myParentId) {
+ console.log("Brothers");
+ console.log(subItems.length);
+ if (subItems.length > 0) {
+ var lastItem = $(jItems[index - 1]).find("li.sub_item");
+ parentIndex = jItems.index(lastItem);
+ console.log(parentIndex);
+ jItem.detach().insertAfter(lastItem);
+ //console.log("not classic");
+ } else {
+ //console.log("classic");
+ jItem.detach().insertBefore(jItems[index - 1]);
+ }
+ break;
}
- jItem.detach().insertBefore(jItems[index - 1]);
+
+ //console.log(parentClass);
+ if (parentClass == "record li_container") {
+ // previous is a chapter
+ var lastItem = $(jItems[index - 1]).parent().parent().find("li.li_container").last();
+ parentIndex = jItems.index(lastItem);
+ //console.log(parentIndex);
+ jItem.detach().insertAfter(jItems[parentIndex]);
+ } else {
+ jItem.detach().insertBefore(jItems[index - 1]);
+ }
}
break;
case "down":
- if (index != jItems.length - 1) {
+ if (index != total - 1) {
+ const originIndex = index;
+ // The element is a chapter with items
var subItems = jItem.find("li.li_container");
- if (subItems.length >= 0) {
+ if (subItems.length > 0) {
index = subItems.length + index;
- }
+ //console.log("element is a chapter with items");
+ //console.log("new index = " + index);
+ }
- // is a chapter?
var subItems = $(jItems[index + 1]).find("li.sub_item");
- if (subItems.length >= 0) {
- index = index + 1;
+ //console.log("next subItems.length: "+subItems.length);
+ // This is an element entering in a chapter
+ if (subItems.length > 0) {
+ // Check if im a child
+ var parentClass = jItem.parent().parent().attr("class");
+ //console.log(parentClass);
+ if (parentClass == "record li_container") {
+ // Parent position
+ var parentIndex = jItems.index(jItem.parent().parent());
+ //console.log(jItem.parent().parent().attr("id"));
+ //console.log(parentIndex);
+ jItem.detach().insertAfter(jItems[parentIndex]);
+ } else {
+ jItem.detach().insertAfter(subItems);
+ }
+ break;
+ }
+
+ var currentSubItems = $(jItems[index]).parent().find("li.sub_item");
+ //console.log("currentSubItems"+currentSubItems.length);
+
+ var parentId = $(jItems[originIndex]).parent().parent().attr("id");
+ var myParentId = $(jItems[index + 1]).parent().parent().attr("id");
+ //console.log("parent ids: "+ parentId + " - " + myParentId);
+
+ // We are brothers!
+ if (parentId == myParentId) {
+ if ((index + 1) < total) {
+ //console.log(index + 1);
+ //console.log("We are brothers");
+ jItem.detach().insertAfter(jItems[index + 1]);
+ }
+ break;
}
+
+ if (currentSubItems.length > 0) {
+ var parentIndex = jItems.index(jItem.parent().parent());
+ //console.log("has currentSubItems");
+ //console.log("id " + jItem.parent().parent().attr("id"));
+ //console.log("parentIndex: " + parentIndex);
+ if (parentIndex >= 0) {
+ jItem.detach().insertAfter(jItems[parentIndex]);
+ break;
+ }
+ //jItem.detach().insertAfter($(jItems[index]).parent().parent());
+ }
+
+ //var lastItem = $(jItems[index + 1]).parent().parent().find("li.li_container").last();
+ if (subItems.length > 0) {
+ index = originIndex;
+ }
+
if ((index + 1) < total) {
+ //console.log(index + 1);
+ //console.log("changed");
jItem.detach().insertAfter(jItems[index + 1]);
}
}
break;
}
+ //console.log("rebuild");
buildLPtree($("#lp_item_list"), 0);
var order = "new_order="+ newOrderData + "&a=update_lp_item_order";