Actualización
This commit is contained in:
142
plugin/xapi/tincan/launch.php
Normal file
142
plugin/xapi/tincan/launch.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\PluginBundle\Entity\XApi\ToolLaunch;
|
||||
use Symfony\Component\HttpFoundation\Request as HttpRequest;
|
||||
use Xabbuh\XApi\Common\Exception\NotFoundException;
|
||||
use Xabbuh\XApi\Model\Activity;
|
||||
use Xabbuh\XApi\Model\Agent;
|
||||
use Xabbuh\XApi\Model\DocumentData;
|
||||
use Xabbuh\XApi\Model\InverseFunctionalIdentifier;
|
||||
use Xabbuh\XApi\Model\IRI;
|
||||
use Xabbuh\XApi\Model\State;
|
||||
use Xabbuh\XApi\Model\StateDocument;
|
||||
use Xabbuh\XApi\Serializer\Symfony\Serializer;
|
||||
|
||||
require_once __DIR__.'/../../../main/inc/global.inc.php';
|
||||
|
||||
api_block_anonymous_users();
|
||||
api_protect_course_script(true);
|
||||
|
||||
$request = HttpRequest::createFromGlobals();
|
||||
|
||||
$user = api_get_user_entity(api_get_user_id());
|
||||
|
||||
$em = Database::getManager();
|
||||
|
||||
$attemptId = $request->request->get('attempt_id');
|
||||
$toolLaunch = $em->find(
|
||||
ToolLaunch::class,
|
||||
$request->request->getInt('id')
|
||||
);
|
||||
|
||||
if (empty($attemptId)
|
||||
|| null === $toolLaunch
|
||||
|| $toolLaunch->getCourse()->getId() !== api_get_course_entity()->getId()
|
||||
) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
$plugin = XApiPlugin::create();
|
||||
|
||||
$activity = new Activity(
|
||||
IRI::fromString($toolLaunch->getActivityId())
|
||||
);
|
||||
$actor = new Agent(
|
||||
InverseFunctionalIdentifier::withMbox(
|
||||
IRI::fromString('mailto:'.$user->getEmail())
|
||||
),
|
||||
$user->getCompleteName()
|
||||
);
|
||||
$state = new State(
|
||||
$activity,
|
||||
$actor,
|
||||
$plugin->generateIri('tool-'.$toolLaunch->getId(), 'state')->getValue()
|
||||
);
|
||||
|
||||
$nowDate = api_get_utc_datetime(null, false, true)->format('c');
|
||||
|
||||
try {
|
||||
$stateDocument = $plugin
|
||||
->getXApiStateClient(
|
||||
$toolLaunch->getLrsUrl(),
|
||||
$toolLaunch->getLrsAuthUsername(),
|
||||
$toolLaunch->getLrsAuthPassword()
|
||||
)
|
||||
->getDocument($state);
|
||||
|
||||
$data = $stateDocument->getData()->getData();
|
||||
|
||||
if ($stateDocument->offsetExists($attemptId)) {
|
||||
$data[$attemptId][XApiPlugin::STATE_LAST_LAUNCH] = $nowDate;
|
||||
} else {
|
||||
$data[$attemptId] = [
|
||||
XApiPlugin::STATE_FIRST_LAUNCH => $nowDate,
|
||||
XApiPlugin::STATE_LAST_LAUNCH => $nowDate,
|
||||
];
|
||||
}
|
||||
|
||||
uasort(
|
||||
$data,
|
||||
function ($attemptA, $attemptB) {
|
||||
$timeA = strtotime($attemptA[XApiPlugin::STATE_LAST_LAUNCH]);
|
||||
$timeB = strtotime($attemptB[XApiPlugin::STATE_LAST_LAUNCH]);
|
||||
|
||||
return $timeB - $timeA;
|
||||
}
|
||||
);
|
||||
|
||||
$documentData = new DocumentData($data);
|
||||
} catch (NotFoundException $notFoundException) {
|
||||
$documentData = new DocumentData(
|
||||
[
|
||||
$attemptId => [
|
||||
XApiPlugin::STATE_FIRST_LAUNCH => $nowDate,
|
||||
XApiPlugin::STATE_LAST_LAUNCH => $nowDate,
|
||||
],
|
||||
]
|
||||
);
|
||||
} catch (Exception $exception) {
|
||||
Display::addFlash(
|
||||
Display::return_message($exception->getMessage(), 'error')
|
||||
);
|
||||
|
||||
header('Location: '.api_get_course_url());
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$plugin
|
||||
->getXApiStateClient()
|
||||
->createOrReplaceDocument(
|
||||
new StateDocument($state, $documentData)
|
||||
);
|
||||
} catch (Exception $exception) {
|
||||
Display::addFlash(
|
||||
Display::return_message($exception->getMessage(), 'error')
|
||||
);
|
||||
|
||||
header('Location: '.api_get_course_url());
|
||||
exit;
|
||||
}
|
||||
|
||||
$lrsUrl = $toolLaunch->getLrsUrl() ?: $plugin->get(XApiPlugin::SETTING_LRS_URL);
|
||||
$lrsAuthUsername = $toolLaunch->getLrsAuthUsername() ?: $plugin->get(XApiPlugin::SETTING_LRS_AUTH_USERNAME);
|
||||
$lrsAuthPassword = $toolLaunch->getLrsAuthPassword() ?: $plugin->get(XApiPlugin::SETTING_LRS_AUTH_PASSWORD);
|
||||
|
||||
$activityLaunchUrl = $toolLaunch->getLaunchUrl().'?'
|
||||
.http_build_query(
|
||||
[
|
||||
'endpoint' => trim($lrsUrl, "/ \t\n\r\0\x0B"),
|
||||
'auth' => 'Basic '.base64_encode(trim($lrsAuthUsername).':'.trim($lrsAuthPassword)),
|
||||
'actor' => Serializer::createSerializer()->serialize($actor, 'json'),
|
||||
'registration' => $attemptId,
|
||||
'activity_id' => $toolLaunch->getActivityId(),
|
||||
],
|
||||
null,
|
||||
'&',
|
||||
PHP_QUERY_RFC3986
|
||||
);
|
||||
|
||||
header("Location: $activityLaunchUrl");
|
||||
163
plugin/xapi/tincan/stats.php
Normal file
163
plugin/xapi/tincan/stats.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\PluginBundle\Entity\XApi\ToolLaunch;
|
||||
use Knp\Component\Pager\Paginator;
|
||||
use Symfony\Component\HttpFoundation\Request as HttpRequest;
|
||||
|
||||
require_once __DIR__.'/../../../main/inc/global.inc.php';
|
||||
|
||||
api_protect_course_script(true);
|
||||
api_protect_teacher_script();
|
||||
|
||||
$request = HttpRequest::createFromGlobals();
|
||||
|
||||
$em = Database::getManager();
|
||||
|
||||
$toolLaunch = $em->find(
|
||||
ToolLaunch::class,
|
||||
$request->query->getInt('id')
|
||||
);
|
||||
|
||||
if (null === $toolLaunch) {
|
||||
header('Location: '.api_get_course_url());
|
||||
exit;
|
||||
}
|
||||
|
||||
$course = api_get_course_entity();
|
||||
$session = api_get_session_entity();
|
||||
|
||||
$cidReq = api_get_cidreq();
|
||||
|
||||
$plugin = XApiPlugin::create();
|
||||
|
||||
$length = 20;
|
||||
$page = $request->query->getInt('page', 1);
|
||||
$start = ($page - 1) * $length;
|
||||
$countStudentList = CourseManager::get_student_list_from_course_code(
|
||||
$course->getCode(),
|
||||
(bool) $session,
|
||||
$session ? $session->getId() : 0,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
0,
|
||||
true
|
||||
);
|
||||
|
||||
$statsUrl = api_get_self().'?'.api_get_cidreq().'&id='.$toolLaunch->getId();
|
||||
|
||||
$paginator = new Paginator();
|
||||
$pagination = $paginator->paginate([]);
|
||||
$pagination->setTotalItemCount($countStudentList);
|
||||
$pagination->setItemNumberPerPage($length);
|
||||
$pagination->setCurrentPageNumber($page);
|
||||
$pagination->renderer = function ($data) use ($statsUrl) {
|
||||
$render = '';
|
||||
if ($data['pageCount'] > 1) {
|
||||
$render = '<ul class="pagination">';
|
||||
for ($i = 1; $i <= $data['pageCount']; $i++) {
|
||||
$pageContent = '<li><a href="'.$statsUrl.'&page='.$i.'">'.$i.'</a></li>';
|
||||
if ($data['current'] == $i) {
|
||||
$pageContent = '<li class="active"><a href="#" >'.$i.'</a></li>';
|
||||
}
|
||||
$render .= $pageContent;
|
||||
}
|
||||
$render .= '</ul>';
|
||||
}
|
||||
|
||||
return $render;
|
||||
};
|
||||
|
||||
$students = CourseManager::get_student_list_from_course_code(
|
||||
$course->getCode(),
|
||||
(bool) $session,
|
||||
$session ? $session->getId() : 0,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
0,
|
||||
false,
|
||||
$start,
|
||||
$length
|
||||
);
|
||||
|
||||
$content = '';
|
||||
$content .= '<div class="xapi-students">';
|
||||
|
||||
$loadingMessage = Display::returnFontAwesomeIcon('spinner', '', true, 'fa-pulse').' '.get_lang('Loading');
|
||||
|
||||
foreach ($students as $studentInfo) {
|
||||
$content .= Display::panelCollapse(
|
||||
api_get_person_name($studentInfo['firstname'], $studentInfo['lastname']),
|
||||
$loadingMessage,
|
||||
"pnl-student-{$studentInfo['id']}",
|
||||
[
|
||||
'class' => 'pnl-student',
|
||||
'data-student' => $studentInfo['id'],
|
||||
'data-tool' => $toolLaunch->getId(),
|
||||
],
|
||||
"pnl-student-{$studentInfo['id']}-accordion",
|
||||
"pnl-student-{$studentInfo['id']}-collapse",
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
$content .= '</div>';
|
||||
$content .= $pagination;
|
||||
|
||||
// View
|
||||
$interbreadcrumb[] = [
|
||||
'name' => $plugin->get_title(),
|
||||
'url' => '../start.php',
|
||||
];
|
||||
|
||||
$htmlHeadXtra[] = "<script>
|
||||
$(function () {
|
||||
$('.pnl-student').on('show.bs.collapse', function (e) {
|
||||
var \$self = \$(this);
|
||||
var \$body = \$self.find('.panel-body');
|
||||
|
||||
if (!\$self.data('loaded')) {
|
||||
$.post(
|
||||
'stats_attempts.ajax.php?' + _p.web_cid_query,
|
||||
\$self.data(),
|
||||
function (response) {
|
||||
\$self.data('loaded', true);
|
||||
\$body.html(response);
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
$('.xapi-students').on('click', '.btn_xapi_attempt_detail', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var \$self = \$(this)
|
||||
.addClass('disabled')
|
||||
.html('".$loadingMessage."');
|
||||
|
||||
$.post(
|
||||
'stats_statements.ajax.php?' + _p.web_cid_query,
|
||||
\$self.data(),
|
||||
function (response) {
|
||||
\$self.replaceWith(response);
|
||||
}
|
||||
);
|
||||
});
|
||||
})
|
||||
</script>";
|
||||
|
||||
$actions = Display::url(
|
||||
Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM),
|
||||
"../start.php?$cidReq"
|
||||
);
|
||||
|
||||
$view = new Template($toolLaunch->getTitle());
|
||||
$view->assign(
|
||||
'actions',
|
||||
Display::toolbarAction('xapi_actions', [$actions])
|
||||
);
|
||||
$view->assign('header', $toolLaunch->getTitle());
|
||||
$view->assign('content', $content);
|
||||
$view->display_one_col_template();
|
||||
131
plugin/xapi/tincan/stats_attempts.ajax.php
Normal file
131
plugin/xapi/tincan/stats_attempts.ajax.php
Normal file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\PluginBundle\Entity\XApi\ToolLaunch;
|
||||
use Symfony\Component\HttpFoundation\Request as HttpRequest;
|
||||
use Xabbuh\XApi\Common\Exception\NotFoundException;
|
||||
use Xabbuh\XApi\Common\Exception\XApiException;
|
||||
use Xabbuh\XApi\Model\Activity;
|
||||
use Xabbuh\XApi\Model\Agent;
|
||||
use Xabbuh\XApi\Model\InverseFunctionalIdentifier;
|
||||
use Xabbuh\XApi\Model\IRI;
|
||||
use Xabbuh\XApi\Model\State;
|
||||
|
||||
require_once __DIR__.'/../../../main/inc/global.inc.php';
|
||||
|
||||
$request = HttpRequest::createFromGlobals();
|
||||
|
||||
$course = api_get_course_entity();
|
||||
$session = api_get_session_entity();
|
||||
|
||||
if (!$request->isXmlHttpRequest()
|
||||
|| !api_is_allowed_to_edit()
|
||||
|| !$course
|
||||
) {
|
||||
echo Display::return_message(get_lang('NotAllowed'), 'error');
|
||||
exit;
|
||||
}
|
||||
|
||||
$plugin = XApiPlugin::create();
|
||||
$em = Database::getManager();
|
||||
|
||||
$toolLaunch = $em->find(
|
||||
ToolLaunch::class,
|
||||
$request->request->getInt('tool')
|
||||
);
|
||||
|
||||
$student = api_get_user_entity($request->request->getInt('student'));
|
||||
|
||||
if (!$toolLaunch || !$student) {
|
||||
echo Display::return_message(get_lang('NotAllowed'), 'error');
|
||||
exit;
|
||||
}
|
||||
|
||||
$userIsSubscribedToCourse = CourseManager::is_user_subscribed_in_course(
|
||||
$student->getId(),
|
||||
$course->getCode(),
|
||||
(bool) $session,
|
||||
$session ? $session->getId() : 0
|
||||
);
|
||||
|
||||
if (!$userIsSubscribedToCourse) {
|
||||
echo Display::return_message(get_lang('NotAllowed'), 'error');
|
||||
exit;
|
||||
}
|
||||
|
||||
$cidReq = api_get_cidreq();
|
||||
|
||||
$xApiStateClient = $plugin->getXApiStateClient(
|
||||
$toolLaunch->getLrsUrl(),
|
||||
$toolLaunch->getLrsAuthUsername(),
|
||||
$toolLaunch->getLrsAuthPassword()
|
||||
);
|
||||
|
||||
$activity = new Activity(
|
||||
IRI::fromString($toolLaunch->getActivityId())
|
||||
);
|
||||
|
||||
$actor = new Agent(
|
||||
InverseFunctionalIdentifier::withMbox(
|
||||
IRI::fromString('mailto:'.$student->getEmail())
|
||||
),
|
||||
$student->getCompleteName()
|
||||
);
|
||||
|
||||
try {
|
||||
$stateDocument = $xApiStateClient->getDocument(
|
||||
new State(
|
||||
$activity,
|
||||
$actor,
|
||||
$plugin->generateIri('tool-'.$toolLaunch->getId(), 'state')->getValue()
|
||||
)
|
||||
);
|
||||
} catch (NotFoundException $notFoundException) {
|
||||
echo Display::return_message(get_lang('NoResults'), 'warning');
|
||||
exit;
|
||||
} catch (XApiException $exception) {
|
||||
echo Display::return_message($exception->getMessage(), 'error');
|
||||
exit;
|
||||
}
|
||||
|
||||
$content = '';
|
||||
|
||||
if ($stateDocument) {
|
||||
$i = 1;
|
||||
|
||||
foreach ($stateDocument->getData()->getData() as $attemptId => $attempt) {
|
||||
$firstLaunch = api_convert_and_format_date(
|
||||
$attempt[XApiPlugin::STATE_FIRST_LAUNCH],
|
||||
DATE_TIME_FORMAT_LONG
|
||||
);
|
||||
$lastLaunch = api_convert_and_format_date(
|
||||
$attempt[XApiPlugin::STATE_LAST_LAUNCH],
|
||||
DATE_TIME_FORMAT_LONG
|
||||
);
|
||||
|
||||
$content .= '<dl class="dl-horizontal">'
|
||||
.'<dt>'.$plugin->get_lang('ActivityFirstLaunch').'</dt>'
|
||||
.'<dd>'.$firstLaunch.'</dd>'
|
||||
.'<dt>'.$plugin->get_lang('ActivityLastLaunch').'</dt>'
|
||||
.'<dd>'.$lastLaunch.'</dd>'
|
||||
.'</dl>'
|
||||
.Display::toolbarButton(
|
||||
get_lang('ShowAllAttempts'),
|
||||
'#',
|
||||
'th-list',
|
||||
'default',
|
||||
[
|
||||
'class' => 'btn_xapi_attempt_detail',
|
||||
'data-attempt' => $attemptId,
|
||||
'data-tool' => $toolLaunch->getId(),
|
||||
'style' => 'margin-bottom: 20px; margin-left: 180px;',
|
||||
'role' => 'button',
|
||||
]
|
||||
);
|
||||
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
echo $content;
|
||||
113
plugin/xapi/tincan/stats_statements.ajax.php
Normal file
113
plugin/xapi/tincan/stats_statements.ajax.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\PluginBundle\Entity\XApi\ToolLaunch;
|
||||
use Symfony\Component\HttpFoundation\Request as HttpRequest;
|
||||
use Xabbuh\XApi\Common\Exception\XApiException;
|
||||
use Xabbuh\XApi\Model\Activity;
|
||||
use Xabbuh\XApi\Model\IRI;
|
||||
use Xabbuh\XApi\Model\StatementsFilter;
|
||||
|
||||
require_once __DIR__.'/../../../main/inc/global.inc.php';
|
||||
|
||||
$request = HttpRequest::createFromGlobals();
|
||||
|
||||
$course = api_get_course_entity();
|
||||
$session = api_get_session_entity();
|
||||
|
||||
if (!$request->isXmlHttpRequest()
|
||||
|| !api_is_allowed_to_edit()
|
||||
|| !$course
|
||||
) {
|
||||
echo Display::return_message(get_lang('NotAllowed'), 'error');
|
||||
exit;
|
||||
}
|
||||
|
||||
$plugin = XApiPlugin::create();
|
||||
$em = Database::getManager();
|
||||
|
||||
$toolLaunch = $em->find(
|
||||
ToolLaunch::class,
|
||||
$request->request->getInt('tool')
|
||||
);
|
||||
|
||||
$attempt = $request->request->get('attempt');
|
||||
|
||||
if (!$toolLaunch || !$attempt) {
|
||||
echo Display::return_message(get_lang('NoResults'), 'error');
|
||||
exit;
|
||||
}
|
||||
|
||||
$cidReq = api_get_cidreq();
|
||||
|
||||
$xapiStatementClient = $plugin->getXApiStatementClient();
|
||||
|
||||
$activity = new Activity(
|
||||
IRI::fromString($toolLaunch->getActivityId())
|
||||
);
|
||||
|
||||
$filter = new StatementsFilter();
|
||||
$filter
|
||||
->byRegistration($attempt);
|
||||
|
||||
try {
|
||||
$result = $xapiStatementClient->getStatements($filter);
|
||||
} catch (XApiException $xApiException) {
|
||||
echo Display::return_message($xApiException->getMessage(), 'error');
|
||||
exit;
|
||||
} catch (Exception $exception) {
|
||||
echo Display::return_message($exception->getMessage(), 'error');
|
||||
exit;
|
||||
}
|
||||
|
||||
$statements = $result->getStatements();
|
||||
|
||||
if (count($statements) <= 0) {
|
||||
echo Display::return_message(get_lang('NoResults'), 'warning');
|
||||
exit;
|
||||
}
|
||||
|
||||
$table = new HTML_Table(['class' => 'table table-condensed table-bordered table-striped table-hover']);
|
||||
$table->setHeaderContents(0, 0, get_lang('CreatedAt'));
|
||||
$table->setHeaderContents(0, 1, $plugin->get_lang('Actor'));
|
||||
$table->setHeaderContents(0, 2, $plugin->get_lang('Verb'));
|
||||
$table->setHeaderContents(0, 3, $plugin->get_lang('ActivityId'));
|
||||
|
||||
$i = 1;
|
||||
|
||||
$languageIso = api_get_language_isocode(api_get_interface_language());
|
||||
|
||||
foreach ($statements as $statement) {
|
||||
$timestampStored = $statement->getCreated() ? api_convert_and_format_date($statement->getCreated()) : '-';
|
||||
$actor = $statement->getActor()->getName();
|
||||
$verb = XApiPlugin::extractVerbInLanguage($statement->getVerb()->getDisplay(), $languageIso);
|
||||
$activity = '';
|
||||
|
||||
$statementObject = $statement->getObject();
|
||||
|
||||
if ($statementObject instanceof Activity) {
|
||||
if (null !== $statementObject->getDefinition()) {
|
||||
$definition = $statementObject->getDefinition();
|
||||
|
||||
if (null !== $definition->getName()) {
|
||||
$activity = XApiPlugin::extractVerbInLanguage($definition->getName(), $languageIso).'<br>';
|
||||
}
|
||||
}
|
||||
|
||||
$activity .= Display::tag(
|
||||
'small',
|
||||
$statementObject->getId()->getValue(),
|
||||
['class' => 'text-muted']
|
||||
);
|
||||
}
|
||||
|
||||
$table->setCellContents($i, 0, $timestampStored);
|
||||
$table->setCellContents($i, 1, $actor);
|
||||
$table->setCellContents($i, 2, $verb);
|
||||
$table->setCellContents($i, 3, $activity);
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
$table->display();
|
||||
192
plugin/xapi/tincan/view.php
Normal file
192
plugin/xapi/tincan/view.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\PluginBundle\Entity\XApi\ToolLaunch;
|
||||
use Symfony\Component\HttpFoundation\Request as HttpRequest;
|
||||
use Xabbuh\XApi\Common\Exception\NotFoundException;
|
||||
use Xabbuh\XApi\Model\Activity;
|
||||
use Xabbuh\XApi\Model\Agent;
|
||||
use Xabbuh\XApi\Model\InverseFunctionalIdentifier;
|
||||
use Xabbuh\XApi\Model\IRI;
|
||||
use Xabbuh\XApi\Model\State;
|
||||
use Xabbuh\XApi\Model\Uuid;
|
||||
|
||||
require_once __DIR__.'/../../../main/inc/global.inc.php';
|
||||
|
||||
api_block_anonymous_users();
|
||||
api_protect_course_script(true);
|
||||
|
||||
$request = HttpRequest::createFromGlobals();
|
||||
|
||||
$originIsLearnpath = api_get_origin() === 'learnpath';
|
||||
|
||||
$user = api_get_user_entity(api_get_user_id());
|
||||
|
||||
$em = Database::getManager();
|
||||
|
||||
$toolLaunch = $em->find(
|
||||
ToolLaunch::class,
|
||||
$request->query->getInt('id')
|
||||
);
|
||||
|
||||
if (null === $toolLaunch
|
||||
|| $toolLaunch->getCourse()->getId() !== api_get_course_entity()->getId()
|
||||
) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
$plugin = XApiPlugin::create();
|
||||
|
||||
$activity = new Activity(
|
||||
IRI::fromString($toolLaunch->getActivityId())
|
||||
);
|
||||
$actor = new Agent(
|
||||
InverseFunctionalIdentifier::withMbox(
|
||||
IRI::fromString('mailto:'.$user->getEmail())
|
||||
),
|
||||
$user->getCompleteName()
|
||||
);
|
||||
$state = new State(
|
||||
$activity,
|
||||
$actor,
|
||||
$plugin->generateIri('tool-'.$toolLaunch->getId(), 'state')->getValue()
|
||||
);
|
||||
|
||||
$cidReq = api_get_cidreq();
|
||||
|
||||
try {
|
||||
$stateDocument = $plugin
|
||||
->getXApiStateClient(
|
||||
$toolLaunch->getLrsUrl(),
|
||||
$toolLaunch->getLrsAuthUsername(),
|
||||
$toolLaunch->getLrsAuthPassword()
|
||||
)
|
||||
->getDocument($state);
|
||||
} catch (NotFoundException $notFoundException) {
|
||||
$stateDocument = null;
|
||||
} catch (Exception $exception) {
|
||||
Display::addFlash(
|
||||
Display::return_message($exception->getMessage(), 'error')
|
||||
);
|
||||
|
||||
header('Location: '.api_get_course_url());
|
||||
exit;
|
||||
}
|
||||
|
||||
$formTarget = $originIsLearnpath ? '_self' : '_blank';
|
||||
|
||||
$frmNewRegistration = new FormValidator(
|
||||
'launch_new',
|
||||
'post',
|
||||
"launch.php?$cidReq",
|
||||
'',
|
||||
['target' => $formTarget],
|
||||
FormValidator::LAYOUT_INLINE
|
||||
);
|
||||
$frmNewRegistration->addHidden('attempt_id', Uuid::uuid4());
|
||||
$frmNewRegistration->addHidden('id', $toolLaunch->getId());
|
||||
$frmNewRegistration->addButton(
|
||||
'submit',
|
||||
$plugin->get_lang('LaunchNewAttempt'),
|
||||
'external-link fa-fw',
|
||||
'success'
|
||||
);
|
||||
|
||||
if ($stateDocument) {
|
||||
$row = 0;
|
||||
|
||||
$table = new HTML_Table(['class' => 'table table-hover table-striped']);
|
||||
$table->setHeaderContents($row, 0, $plugin->get_lang('ActivityFirstLaunch'));
|
||||
$table->setHeaderContents($row, 1, $plugin->get_lang('ActivityLastLaunch'));
|
||||
$table->setHeaderContents($row, 2, get_lang('Actions'));
|
||||
|
||||
$row++;
|
||||
|
||||
$langActivityLaunch = $plugin->get_lang('ActivityLaunch');
|
||||
|
||||
foreach ($stateDocument->getData()->getData() as $attemptId => $attempt) {
|
||||
$firstLaunch = api_convert_and_format_date(
|
||||
$attempt[XApiPlugin::STATE_FIRST_LAUNCH],
|
||||
DATE_TIME_FORMAT_LONG
|
||||
);
|
||||
$lastLaunch = api_convert_and_format_date(
|
||||
$attempt[XApiPlugin::STATE_LAST_LAUNCH],
|
||||
DATE_TIME_FORMAT_LONG
|
||||
);
|
||||
|
||||
$frmLaunch = new FormValidator(
|
||||
"launch_$row",
|
||||
'post',
|
||||
"launch.php?$cidReq",
|
||||
'',
|
||||
['target' => $formTarget],
|
||||
FormValidator::LAYOUT_INLINE
|
||||
);
|
||||
$frmLaunch->addHidden('attempt_id', $attemptId);
|
||||
$frmLaunch->addHidden('id', $toolLaunch->getId());
|
||||
$frmLaunch->addButton(
|
||||
'submit',
|
||||
$langActivityLaunch,
|
||||
'external-link fa-fw',
|
||||
'default'
|
||||
);
|
||||
|
||||
$table->setCellContents($row, 0, $firstLaunch);
|
||||
$table->setCellContents($row, 1, $lastLaunch);
|
||||
$table->setCellContents($row, 2, $frmLaunch->returnForm());
|
||||
|
||||
$row++;
|
||||
}
|
||||
|
||||
$table->setColAttributes(0, ['class' => 'text-center']);
|
||||
$table->setColAttributes(1, ['class' => 'text-center']);
|
||||
$table->setColAttributes(2, ['class' => 'text-center']);
|
||||
}
|
||||
|
||||
$interbreadcrumb[] = ['url' => '../start.php', 'name' => $plugin->get_lang('ToolTinCan')];
|
||||
|
||||
$pageTitle = $toolLaunch->getTitle();
|
||||
$pageContent = '';
|
||||
|
||||
if ($toolLaunch->getDescription()) {
|
||||
$pageContent .= PHP_EOL;
|
||||
$pageContent .= "<p class='lead'>{$toolLaunch->getDescription()}</p>";
|
||||
}
|
||||
|
||||
if ($toolLaunch->isAllowMultipleAttempts()
|
||||
|| empty($stateDocument)
|
||||
) {
|
||||
$pageContent .= Display::div(
|
||||
$frmNewRegistration->returnForm(),
|
||||
['class' => 'exercise_overview_options']
|
||||
);
|
||||
}
|
||||
|
||||
if ($stateDocument) {
|
||||
$pageContent .= $table->toHtml();
|
||||
}
|
||||
|
||||
$actions = '';
|
||||
|
||||
if (!$originIsLearnpath) {
|
||||
$actions = Display::url(
|
||||
Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM),
|
||||
'../start.php?'.api_get_cidreq()
|
||||
);
|
||||
}
|
||||
|
||||
$view = new Template($pageTitle);
|
||||
$view->assign('header', $pageTitle);
|
||||
|
||||
if ($actions) {
|
||||
$view->assign(
|
||||
'actions',
|
||||
Display::toolbarAction(
|
||||
'xapi_actions',
|
||||
[$actions]
|
||||
)
|
||||
);
|
||||
}
|
||||
$view->assign('content', $pageContent);
|
||||
$view->display_one_col_template();
|
||||
Reference in New Issue
Block a user