Add CKEditor plugin Quiz Markers Rolls - refs BT#15389

This plugin allows set quizzes markers in video with mediaelement
pull/2874/head
Angel Fernando Quiroz Campos 7 years ago
parent 6d60d6409c
commit d9b6639348
  1. 2
      main/exercise/exercise.class.php
  2. 48
      main/exercise/exercise_result.php
  3. 28
      main/exercise/exercise_submit.php
  4. 2
      main/exercise/overview.php
  5. 2
      main/exercise/result.php
  6. 29
      main/inc/ajax/exercise.ajax.php
  7. 3
      main/inc/global.inc.php
  8. 2
      main/inc/lib/display.lib.php
  9. 45
      main/inc/lib/exercise.lib.php
  10. 388
      main/inc/lib/javascript/ckeditor/plugins/qmarkersrolls/dialogs/qmarkersrolls.js
  11. BIN
      main/inc/lib/javascript/ckeditor/plugins/qmarkersrolls/images/icon.png
  12. 19
      main/inc/lib/javascript/ckeditor/plugins/qmarkersrolls/lang/en.js
  13. 20
      main/inc/lib/javascript/ckeditor/plugins/qmarkersrolls/lang/es.js
  14. 51
      main/inc/lib/javascript/ckeditor/plugins/qmarkersrolls/plugin.js
  15. 2
      main/template/default/javascript/editor/ckeditor/config_js.tpl
  16. 2
      main/template/default/layout/main.js.tpl
  17. 1
      src/Chamilo/CoreBundle/Component/Editor/CkEditor/Toolbar/Basic.php
  18. 40
      src/Chamilo/CoreBundle/Component/Utils/ChamiloApi.php

@ -8400,7 +8400,7 @@ class Exercise
$msg = str_replace("#mail#", $user_info['email'], $msg1);
$msg = str_replace("#course#", $courseInfo['name'], $msg1);
if ($origin != 'learnpath') {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
$msg .= '<br /><a href="#url#">'.get_lang('ClickToCommentAndGiveFeedback').'</a>';
}
$msg1 = str_replace("#url#", $url_email, $msg);

@ -75,7 +75,7 @@ if (api_get_configuration_value('quiz_prevent_copy_paste')) {
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_JS_PATH).'jquery.nocopypaste.js"></script>';
}
if ($origin != 'learnpath') {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
// So we are not in learnpath tool
Display::display_header($nameTools, get_lang('Exercise'));
} else {
@ -88,7 +88,7 @@ if ($origin != 'learnpath') {
}
// I'm in a preview mode as course admin. Display the action menu.
if (api_is_course_admin() && $origin != 'learnpath') {
if (api_is_course_admin() && !in_array($origin, ['learnpath', 'embeddable'])) {
echo '<div class="actions">';
echo '<a href="admin.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id.'">'.
Display::return_icon('back.png', get_lang('GoBackToQuestionList'), [], 32).'</a>';
@ -121,17 +121,21 @@ if ($origin == 'learnpath') {
$i = $total_score = $max_score = 0;
$remainingMessage = '';
$attemptButton = Display::toolbarButton(
get_lang('AnotherAttempt'),
api_get_path(WEB_CODE_PATH).'exercise/overview.php?'.api_get_cidreq().'&'.http_build_query([
'exerciseId' => $objExercise->id,
'learnpath_id' => $learnpath_id,
'learnpath_item_id' => $learnpath_item_id,
'learnpath_item_view_id' => $learnpath_item_view_id,
]),
'pencil-square-o',
'info'
);
$attemptButton = '';
if ($origin !== 'embeddable') {
$attemptButton = Display::toolbarButton(
get_lang('AnotherAttempt'),
api_get_path(WEB_CODE_PATH).'exercise/overview.php?'.api_get_cidreq().'&'.http_build_query([
'exerciseId' => $objExercise->id,
'learnpath_id' => $learnpath_id,
'learnpath_item_id' => $learnpath_item_id,
'learnpath_item_view_id' => $learnpath_item_view_id,
]),
'pencil-square-o',
'info'
);
}
// We check if the user attempts before sending to the exercise_result.php
if ($objExercise->selectAttempts() > 0) {
@ -148,7 +152,7 @@ if ($objExercise->selectAttempts() > 0) {
'warning',
false
);
if ($origin != 'learnpath') {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
//we are not in learnpath tool
Display::display_footer();
}
@ -163,7 +167,7 @@ if ($objExercise->selectAttempts() > 0) {
}
}
} else {
$remainingMessage = "<p>$attemptButton</p>";
$remainingMessage = $attemptButton ? "<p>$attemptButton</p>" : '';
}
$total_score = 0;
@ -192,7 +196,7 @@ ExerciseLib::exercise_time_control_delete(
ExerciseLib::delete_chat_exercise_session($exe_id);
if ($origin != 'learnpath') {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
echo '<div class="question-return">';
echo Display::url(
get_lang('ReturnToCourseHomepage'),
@ -209,6 +213,18 @@ if ($origin != 'learnpath') {
Session::erase('duration_time');
}
Display::display_footer();
} elseif ($origin == 'embeddable') {
if (api_is_allowed_to_session_edit()) {
Session::erase('objExercise');
Session::erase('exe_id');
Session::erase('calculatedAnswerId');
Session::erase('duration_time_previous');
Session::erase('duration_time');
}
Session::write('attempt_remaining', $remainingMessage);
Display::display_reduced_footer();
} else {
$lp_mode = Session::read('lp_mode');
$url = '../lp/lp_controller.php?'.api_get_cidreq().'&action=view&lp_id='.$learnpath_id.'&lp_item_id='.$learnpath_item_id.'&exeId='.$exercise_stat_info['exe_id'].'&fb_type='.$objExercise->feedback_type.'#atoc_'.$learnpath_item_id;

@ -134,7 +134,7 @@ if (!isset($exerciseInSession) || isset($exerciseInSession) && ($exerciseInSessi
// if the specified exercise doesn't exist or is disabled
if (!$objExercise->read($exerciseId) ||
(!$objExercise->selectStatus() && !$is_allowedToEdit && $origin != 'learnpath')
(!$objExercise->selectStatus() && !$is_allowedToEdit && !in_array($origin, ['learnpath', 'embeddable']))
) {
if ($debug) {
error_log('1.1. Error while reading the exercise');
@ -235,7 +235,7 @@ if ($objExercise->selectAttempts() > 0) {
if ($attempt_count >= $objExercise->selectAttempts()) {
$show_clock = false;
if (!api_is_allowed_to_edit(null, true)) {
if ($objExercise->results_disabled == 0 && $origin != 'learnpath') {
if ($objExercise->results_disabled == 0 && !in_array($origin, ['learnpath', 'embeddable'])) {
// Showing latest attempt according with task BT#1628
$exercise_stat_info = Event::getExerciseResultsByUser(
$user_id,
@ -263,7 +263,7 @@ if ($objExercise->selectAttempts() > 0) {
)
);
if ($origin == 'learnpath') {
if (in_array($origin, ['learnpath', 'embeddable'])) {
Display::display_reduced_header();
Display::display_reduced_footer();
} else {
@ -319,7 +319,7 @@ if ($objExercise->selectAttempts() > 0) {
$attempt_html .= $messageReachedMax;
}
if ($origin == 'learnpath') {
if (in_array($origin, ['learnpath', 'embeddable'])) {
Display::display_reduced_header();
} else {
Display::display_header(get_lang('Exercises'));
@ -327,7 +327,7 @@ if ($objExercise->selectAttempts() > 0) {
echo $attempt_html;
if ($origin != 'learnpath') {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
Display::display_footer();
}
exit;
@ -724,7 +724,7 @@ if ($formSent && isset($_POST)) {
'warning',
false
);
if ($origin != 'learnpath') {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
//so we are not in learnpath tool
echo '</div>'; //End glossary div
Display::display_footer();
@ -797,7 +797,7 @@ if ($question_count != 0) {
'warning',
false
);
if ($origin != 'learnpath') {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
//so we are not in learnpath tool
echo '</div>'; //End glossary div
Display::display_footer();
@ -860,7 +860,7 @@ $interbreadcrumb[] = [
];
$interbreadcrumb[] = ["url" => "#", "name" => $objExercise->selectTitle(true)];
if ($origin != 'learnpath') { //so we are not in learnpath tool
if (!in_array($origin, ['learnpath', 'embeddable'])) { //so we are not in learnpath tool
if (!api_is_allowed_to_session_edit()) {
Display::addFlash(
Display::return_message(get_lang('SessionIsReadOnly'), 'warning')
@ -877,7 +877,7 @@ if ($origin != 'learnpath') { //so we are not in learnpath tool
$show_quiz_edition = $objExercise->added_in_lp();
// I'm in a preview mode
if (api_is_course_admin() && $origin != 'learnpath') {
if (api_is_course_admin() && !in_array($origin, ['learnpath', 'embeddable'])) {
echo '<div class="actions">';
if ($show_quiz_edition == false) {
echo '<a href="exercise_admin.php?'.api_get_cidreq().'&modifyExercise=yes&exerciseId='.$objExercise->id.'">'.
@ -897,7 +897,7 @@ $is_visible_return = $objExercise->is_visible(
if ($is_visible_return['value'] == false) {
echo $is_visible_return['message'];
if ($origin != 'learnpath') {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
Display :: display_footer();
}
exit;
@ -933,7 +933,7 @@ if ($limit_time_exists) {
),
'warning'
);
if ($origin != 'learnpath') {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
Display::display_footer();
}
exit;
@ -965,7 +965,7 @@ if (isset($_custom['exercises_hidden_when_no_start_date']) &&
),
'warning'
);
if ($origin != 'learnpath') {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
Display :: display_footer();
}
}
@ -978,7 +978,7 @@ if ($time_control) {
get_lang('ExerciseExpiredTimeMessage').'</div>';
}
if ($origin != 'learnpath') {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
echo '<div id="highlight-plugin" class="glossary-content">';
}
@ -1546,7 +1546,7 @@ if (!empty($error)) {
echo '</form>';
}
if ($origin != 'learnpath') {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
// So we are not in learnpath tool
echo '</div>'; //End glossary div
}

@ -72,7 +72,7 @@ if ($time_control) {
$htmlHeadXtra[] = $objExercise->showTimeControlJS($time_left);
}
if ($origin != 'learnpath') {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
Display::display_header();
} else {
$htmlHeadXtra[] = "

@ -14,7 +14,7 @@ $id = isset($_REQUEST['id']) ? (int) $_GET['id'] : null; //exe id
$show_headers = isset($_REQUEST['show_headers']) ? (int) $_REQUEST['show_headers'] : null;
$origin = api_get_origin();
if ($origin == 'learnpath') {
if (in_array($origin, ['learnpath', 'embeddable'])) {
$show_headers = false;
}

@ -762,6 +762,35 @@ switch ($action) {
true
);
break;
case 'get_quiz_embeddable':
$exercises = ExerciseLib::get_all_exercises_for_course_id(
api_get_course_info(),
api_get_session_id(),
api_get_course_int_id(),
false
);
$exercises = array_filter(
$exercises,
function (array $exercise) {
return ExerciseLib::isQuizEmbeddable($exercise);
}
);
$result = [];
$codePath = api_get_path(WEB_CODE_PATH);
foreach ($exercises as $exercise) {
$result[] = [
'id' => $exercise['iid'],
'title' => Security::remove_XSS($exercise['title']),
];
}
header('Content-Type: application/json');
echo json_encode($result);
break;
default:
echo '';
}

@ -16,6 +16,8 @@
*/
// Showing/hiding error codes in global error messages.
use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
define('SHOW_ERROR_CODES', false);
// Include the libraries that are necessary everywhere
@ -666,6 +668,7 @@ if (!empty($language_interface)) {
// if portal is in test mode always generate the file
if (!file_exists($file) || api_get_setting('server_type') === 'test') {
$template = new Template();
$template->assign('quiz_markers_rolls_js', ChamiloApi::getQuizMarkersRollsJS());
// Force use of default to avoid problems
$tpl = 'default/layout/main.js.tpl';
$contents = $template->fetch($tpl);

@ -1,6 +1,7 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
use Chamilo\CoreBundle\Entity\ExtraField;
use ChamiloSession as Session;
@ -2856,6 +2857,7 @@ HTML;
pluginPath: "'.$webPublicPath.'assets/mediaelement/build/",
features: [\''.$defaultFeatures.'\'],
success: function(mediaElement, originalNode, instance) {
'.ChamiloApi::getQuizMarkersRollsJS().'
},
vrPath: "'.$webPublicPath.'assets/vrview/build/vrview.js"
});

@ -5340,4 +5340,49 @@ EOT;
return ($answeredQuestionsCount + $numberOfQuestions) > $questionsLimitPerDay;
}
/**
* Check if an exercise complies with the requirements to be embedded in the mobile app or a video. By making sure
* it is set on one question per page and it only contains unique-answer or multiple-answer questions
*
* @param array $exercise Exercise info
*
* @return bool
* @throws \Doctrine\ORM\Query\QueryException
*/
public static function isQuizEmbeddable(array $exercise)
{
$em = Database::getManager();
if (2 != $exercise['type']) {
return false;
}
$countAll = $em
->createQuery('SELECT COUNT(qq)
FROM ChamiloCourseBundle:CQuizQuestion qq
INNER JOIN ChamiloCourseBundle:CQuizRelQuestion qrq
WITH qq.iid = qrq.questionId
WHERE qrq.exerciceId = :id'
)
->setParameter('id', $exercise['iid'])
->getSingleScalarResult();
$countOfAllowed = $em
->createQuery('SELECT COUNT(qq)
FROM ChamiloCourseBundle:CQuizQuestion qq
INNER JOIN ChamiloCourseBundle:CQuizRelQuestion qrq
WITH qq.iid = qrq.questionId
WHERE qrq.exerciceId = :id AND qq.type IN (:types)'
)
->setParameters(
[
'id' => $exercise['iid'],
'types' => [UNIQUE_ANSWER, MULTIPLE_ANSWER, UNIQUE_ANSWER_IMAGE],
]
)
->getSingleScalarResult();
return $countAll === $countOfAllowed;
}
}

@ -0,0 +1,388 @@
/**
* Plugin created by BeezNest Latino S.A.C
*
* For licensing terms, see /license.txt
*
* This plugin allows set quizzes markers in video with mediaelement.
*/
CKEDITOR.dialog.add('qMarkersrollsDialog', function (editor) {
var lang = editor.lang.qmarkersrolls,
player = null,
pgbProgress = null,
fakeImage = null,
videoNode = null,
quizzesList = [],
currentMarkers = [],
colorDialog = editor.plugins.colordialog;
function initPlayer(selectedElement) {
fakeImage = selectedElement;
if (!fakeImage ||
!fakeImage.data( 'cke-real-element-type' ) ||
fakeImage.data( 'cke-real-element-type' ) != 'video'
) {
return;
}
videoNode = editor.restoreRealElement(fakeImage);
var sourcesList = videoNode.getElementsByTag('source', '');
if (sourcesList.count() === 0) {
sourcesList = videoNode.getElementsByTag('source', 'cke');
}
if (sourcesList.count() === 0) {
return;
}
var sourceNode = sourcesList.getItem(0);
if (!sourceNode) {
return;
}
pgbProgress = document.getElementById('ck-qmr-progress');
pgbProgress.value = 0;
pgbProgress.min = 0;
pgbProgress.step = 1;
pgbProgress.onchange = function () {
player.currentTime = this.value;
document.getElementById('ck-qmr-current-time').textContent = encodeTime(this.value);
};
var playerContainer = document.getElementById('ck-qmr-player-container');
playerContainer.innerHTML = '';
player = document.createElement('video');
player.className = 'skip';
player.controls = false;
player.style.maxWidth = '100%';
player.style.minWidth = '100%';
player.onloadedmetadata = function () {
pgbProgress.max = Math.floor(player.duration);
playerContainer.appendChild(player);
};
player.src = sourceNode.getAttribute('src');
}
function decodeTime(time) {
var parts = time.split(':');
if (parts.length != 3) {
return 0;
}
var hours = parseInt(parts[0]),
minutes = parseInt(parts[1]),
seconds = parseInt(parts[2]);
if (seconds > 59 || minutes > 59) {
return 0;
}
hours *= 60 * 60;
minutes *= 60;
return hours + minutes + seconds;
}
function encodeTime(time) {
if (time < 60) {
if (time < 10) {
time = '0' + time;
}
return '00:00:' + time;
}
var hours = 0,
minutes = Math.floor(time / 60),
seconds = Math.floor(time % 60);
if (minutes > 60) {
hours = Math.floor(minutes / 60);
minutes = minutes - (hours * 60);
}
return (hours < 10 ? '0' + hours : hours) + ':'
+ (minutes < 10 ? '0' + minutes : minutes) + ':'
+ (seconds < 10 ? '0' + seconds : seconds);
}
function displayQuizzes() {
var container = document.getElementById('ck-qmr-quizzes-container');
container.innerHTML = '';
quizzesList.forEach(function (quiz) {
var alreadyAdded = false;
currentMarkers.forEach(function (markerRoll) {
if (quiz.id == markerRoll[1]) {
alreadyAdded = true;
}
});
if (alreadyAdded) {
return;
}
var label = document.createElement('label');
label.textContent = quiz.title;
label.htmlFor = 'ck-qmr-quiz-' + quiz.id;
label.style.verticalAlign = 'super';
var radio = document.createElement('input');
radio.type = 'radio';
radio.name = 'ck_qmr_quiz';
radio.id = 'ck-qmr-quiz-' + quiz.id;
radio.value = quiz.id;
var row = document.createElement('div');
row.appendChild(radio);
row.appendChild(label);
container.appendChild(row);
});
}
function displayCurrentMarkersList() {
var quizzesAddedContainer = document.getElementById('ck-qmr-quizzes-added-container');
quizzesAddedContainer.innerHTML = '';
currentMarkers.forEach(function (markerRoll) {
var makerForQuiz = null;
quizzesList.forEach(function (quiz) {
if (markerRoll[1] == quiz.id) {
makerForQuiz = quiz;
}
});
if (!makerForQuiz) {
return;
}
var btnRemove = document.createElement('a');
btnRemove.className = 'cke_dialog_ui_button';
btnRemove.type = 'button';
btnRemove.innerHTML = '<span class="cke_dialog_ui_button">' + lang.delete + '</span>';
btnRemove.setAttribute('role', 'button');
btnRemove.addEventListener('click', function (e) {
e.preventDefault();
e.stopPropagation();
for (var i = 0; i < currentMarkers.length; i++) {
if (currentMarkers[i][1] == markerRoll[1]) {
currentMarkers.splice(i, 1);
i--;
}
}
displayQuizzes();
displayCurrentMarkersList();
}, false);
var divMarker = document.createElement('span');
divMarker.innerHTML = ' <strong>' + encodeTime(markerRoll[0]) + '</strong> &mdash; '
+ makerForQuiz.title;
var pMarker = document.createElement('p');
pMarker.appendChild(btnRemove);
pMarker.appendChild(divMarker);
quizzesAddedContainer.appendChild(pMarker);
});
}
return {
title: lang.dialogTitle,
minWidth: 400,
minHeight: 500,
resizable: CKEDITOR.DIALOG_RESIZE_NONE,
contents: [
{
id: 'tab-markers',
label: lang.markers,
elements: [
{
type: 'vbox',
width: '100%',
children: [
{
type: 'html',
id: 'html',
html: '<div id="ck-qmr-player-container"></div>'
},
{
type: 'hbox',
widths: ['100%', '200px'],
children: [
{
type: 'html',
html: '<input type="range" min="0" step="1" id="ck-qmr-progress">'
},
{
type: 'html',
title: 'Current Time',
html: '<span id="ck-qmr-current-time">00:00:00</span>'
},
]
},
{
type: 'hbox',
widths: ['100%', '200px'],
children: [
{
type: 'html',
html: lang.embeddableQuizzes + ' '
+ '<div id="ck-qmr-quizzes-container" '
+ 'style="max-height: 110px; overflow: hidden auto;"></div>'
},
{
type: 'button',
id: 'btn-assign',
label: lang.assignQuiz,
title: lang.assignQuiz,
onClick: function () {
var radioQuizzes = document.getElementsByName('ck_qmr_quiz'),
selected = null;
radioQuizzes.forEach(function (radio) {
if (!radio.checked) {
return;
}
selected = radio;
});
if (!selected) {
return;
}
currentMarkers.push([
parseInt(pgbProgress.value),
parseInt(selected.value)
]);
displayCurrentMarkersList();
selected.parentElement.remove();
}
}
]
},
{
type: 'html',
html: lang.currentMarkers + ' '
+ '<div id="ck-qmr-quizzes-added-container" '
+ 'style="max-height: 140px; overflow: hidden auto;"></div>'
}
]
},
]
},
{
id: 'tab-settings',
label: lang.settings,
elements: [
{
type: 'hbox',
widths: ['200px', '100%'],
children: [
{
type: 'text',
id: 'markerColor',
label: lang.markerColor,
'default': '',
setup: function (widget) {
this.setValue(widget.getAttribute('data-q-markersrolls-color'));
},
commit: function (widget) {
widget.setAttribute('data-q-markersrolls-color', this.getValue());
}
},
colorDialog ? {
type: 'button',
id: 'markerColorChoose',
'class': 'colorChooser',
label: lang.choose,
onLoad: function() {
// Stick the element to the bottom
this.getElement()
.getParent()
.setStyle('vertical-align', 'bottom');
},
onClick: function () {
editor.getColorFromDialog(function (color) {
if (color) {
this.getDialog()
.getContentElement('tab-settings', 'markerColor')
.setValue(color);
}
this.focus();
}, this)
}
} : {
type: 'html',
html: '&nbsp;'
}
]
},
]
},
],
onShow: function () {
var dialog = this;
document.getElementById('ck-qmr-quizzes-container').innerHTML = '';
initPlayer(
dialog.getSelectedElement()
);
currentMarkers = JSON.parse(
videoNode.getAttribute('data-q-markersrolls') || '[]'
);
CKEDITOR.ajax.load(
editor.config.qMarkersRollsUrl,
function (response) {
quizzesList = JSON.parse(response);
displayQuizzes();
displayCurrentMarkersList();
dialog.setupContent(videoNode);
}
);
},
onHide: function () {
player = null;
pgbProgress = null;
},
onOk: function () {
if (!fakeImage) {
return;
}
this.commitContent(videoNode);
videoNode.setAttribute('data-q-markersrolls', JSON.stringify(currentMarkers));
var newFakeImage = editor.createFakeElement(videoNode, 'cke_video', 'video', false);
newFakeImage.setStyles({
width: fakeImage.getStyle('width'),
height: fakeImage.getStyle('height')
});
newFakeImage.replace(fakeImage);
editor.getSelection().selectElement(newFakeImage);
}
};
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,19 @@
/**
* Plugin created by BeezNest Latino S.A.C
*
* For licensing terms, see /license.txt
*
* This plugin allows set quizzes markers in video with mediaelement.
*/
CKEDITOR.plugins.setLang('qmarkersrolls', 'en', {
dialogTitle: 'Quizzes Marker Rolls',
setQuizMarkersRolls: 'Set Quiz Markers Rolls',
delete: 'Delete',
markers: 'Markers',
settings: 'Settings',
embeddableQuizzes: 'Embeddable quizzes',
assignQuiz: 'Assign quiz',
currentMarkers: 'Current Markers',
markerColor: 'Marker color',
choose: 'Choose'
});

@ -0,0 +1,20 @@
/**
* Plugin created by BeezNest Latino S.A.C
*
* For licensing terms, see /license.txt
*
* This plugin allows set quizzes markers in video with mediaelement.
*/
CKEDITOR.plugins.setLang('qmarkersrolls', 'es', {
dialogTitle: 'Marcadores de exámenes',
setQuizMarkersRolls: 'Agregar marcadores de exámenes',
delete: 'Eliminar',
markers: 'Marcadores',
settings: 'Configuración',
embeddableQuizzes: 'Exámenes integrables',
assignQuiz: 'Asignar examen',
currentMarkers: 'Marcadores actuales',
markerColor: 'Color del marcador',
choose: 'Elegir'
});

@ -0,0 +1,51 @@
/**
* Plugin created by BeezNest Latino S.A.C
*
* For licensing terms, see /license.txt
*
* This plugin allows set quizzes markers in video with mediaelement.
*/
(function () {
CKEDITOR.plugins.add('qmarkersrolls', {
lang: [
'en',
'es',
],
requires: ['video'],
init: function (editor) {
var lang = editor.lang.qmarkersrolls;
editor
.addCommand(
'qmarkersrolls',
new CKEDITOR.dialogCommand('qMarkersrollsDialog')
);
if (editor.contextMenu) {
editor.addMenuGroup('qMarkersRollsGroup');
editor.addMenuItem('qMarkersRollsItem', {
label: lang.setQuizMarkersRolls,
icon: this.path + 'images/icon.png',
command: 'qmarkersrolls',
group: 'qMarkersRollsGroup'
});
editor.contextMenu.addListener(function (element) {
if (element &&
element.is('img') &&
!element.isReadOnly() &&
element.data('cke-real-element-type') == 'video'
) {
return {
qMarkersRollsItem: CKEDITOR.TRISTATE_OFF
};
}
});
}
CKEDITOR.dialog.add('qMarkersrollsDialog', this.path + 'dialogs/qmarkersrolls.js');
}
});
})();

@ -116,6 +116,8 @@ CKEDITOR.editorConfig = function (config) {
];
config.language_list = ['{{ language_list }}'];
config.qMarkersRollsUrl = '{{ _p.web_ajax }}exercise.ajax.php?a=get_quiz_embeddable';
};
// Sets default target to "_blank" in link plugin

@ -268,6 +268,7 @@ $(function() {
//renderers: ['html5', 'flash_video', 'native_flv'],
features: ['{{ video_features }}'],
success: function(mediaElement, originalNode, instance) {
{{ quiz_markers_rolls_js }}
},
vrPath: _p.web + 'web/assets/vrview/build/vrview.js'
});
@ -570,6 +571,7 @@ if (typeof CKEDITOR !== 'undefined') {
'youtube',
'flash',
'inserthtml',
'qmarkersrolls',
'image2_chamilo'
];

@ -63,6 +63,7 @@ class Basic extends Toolbar
'wordcount',
'inserthtml',
'xml',
'qmarkersrolls',
];
/**

@ -355,4 +355,44 @@ class ChamiloApi
return $localMidnight;
}
/**
* Get JavaScript code necessary to load quiz markers-rolls in medialement's Markers Rolls plugin
*
* @return string
*/
public static function getQuizMarkersRollsJS()
{
$webCodePath = api_get_path(WEB_CODE_PATH);
$colorPalette = self::getColorPalette(false, true);
return "
var \$originalNode = $(originalNode),
qMarkersRolls = \$originalNode.data('q-markersrolls') || [],
qMarkersColor = \$originalNode.data('q-markersrolls-color') || '{$colorPalette[0]}';
if (0 == qMarkersRolls.length) {
return;
}
instance.options.markersRollsColor = qMarkersColor;
instance.options.markersRollsWidth = 2;
instance.options.markersRolls = {};
qMarkersRolls.forEach(function (qMarkerRoll) {
var url = '{$webCodePath}exercise/exercise_submit.php?{{ _p.web_cid_query }}&'
+ $.param({
exerciseId: qMarkerRoll[1],
learnpath_id: 0,
learnpath_item_id: 0,
learnpath_item_view_id: 0,
origin: 'embeddable'
});
instance.options.markersRolls[qMarkerRoll[0]] = url;
});
instance.buildmarkersrolls(instance, instance.controls, instance.layers, instance.media);
";
}
}

Loading…
Cancel
Save