Merge pull request #3114 from AngelFQC/1.11.x

Fixes for LTI plugin
pull/3122/head
Angel Fernando Quiroz Campos 6 years ago committed by GitHub
commit 1aee459da2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 37
      plugin/ims_lti/Entity/ImsLtiTool.php
  2. 26
      plugin/ims_lti/ImsLtiPlugin.php
  3. 14
      plugin/ims_lti/README.md
  4. 10
      plugin/ims_lti/auth.php
  5. 16
      plugin/ims_lti/configure.php
  6. 1
      plugin/ims_lti/create.php
  7. 14
      plugin/ims_lti/delete.php
  8. 5
      plugin/ims_lti/edit.php
  9. 4
      plugin/ims_lti/form.php
  10. 1
      plugin/ims_lti/lang/english.php
  11. 1
      plugin/ims_lti/lang/french.php
  12. 3
      plugin/ims_lti/lang/spanish.php
  13. 50
      plugin/ims_lti/src/Form/FrmAdd.php
  14. 49
      plugin/ims_lti/src/Form/FrmEdit.php
  15. 5
      plugin/ims_lti/start.php

@ -147,6 +147,12 @@ class ImsLtiTool
* @ORM\Column(name="version", type="string", options={"default": "lti1p1"})
*/
private $version;
/**
* @var array
*
* @ORM\Column(name="launch_presentation", type="json")
*/
private $launchPresentation;
/**
* ImsLtiTool constructor.
@ -164,6 +170,9 @@ class ImsLtiTool
$this->sharedSecret = null;
$this->lineItems = new ArrayCollection();
$this->version = \ImsLti::V_1P1;
$this->launchPresentation = [
'document_target' => 'iframe',
];
}
/**
@ -794,4 +803,32 @@ class ImsLtiTool
{
return $this->children;
}
/**
* @param string $target
*
* @return $this
*/
public function setDocumenTarget($target)
{
$this->launchPresentation['document_target'] = in_array($target, ['iframe', 'window']) ? $target : 'iframe';
return $this;
}
/**
* @return string
*/
public function getDocumentTarget()
{
return $this->launchPresentation['document_target'] ?: 'iframe';
}
/**
* @return array
*/
public function getLaunchPresentation()
{
return $this->launchPresentation;
}
}

@ -31,7 +31,7 @@ class ImsLtiPlugin extends Plugin
*/
protected function __construct()
{
$version = '1.5.1';
$version = '1.7.0';
$author = 'Angel Fernando Quiroz Campos';
$message = Display::return_message($this->get_lang('GenerateKeyPairInfo'));
@ -186,6 +186,7 @@ class ImsLtiPlugin extends Plugin
redirect_url VARCHAR(255) DEFAULT NULL,
advantage_services LONGTEXT DEFAULT NULL COMMENT '(DC2Type:json)',
version VARCHAR(255) DEFAULT 'lti1p1' NOT NULL,
launch_presentation LONGTEXT NOT NULL COMMENT '(DC2Type:json),
INDEX IDX_C5E47F7C91D79BD3 (c_id),
INDEX IDX_C5E47F7C82F80D8B (gradebook_eval_id),
INDEX IDX_C5E47F7C727ACA70 (parent_id),
@ -337,19 +338,28 @@ class ImsLtiPlugin extends Plugin
}
/**
* Add the course tool
* Add the course tool.
*
* @param Course $course
* @param ImsLtiTool $tool
* @param Course $course
* @param ImsLtiTool $ltiTool
*
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function addCourseTool(Course $course, ImsLtiTool $tool)
public function addCourseTool(Course $course, ImsLtiTool $ltiTool)
{
$this->createLinkToCourseTool(
$tool->getName(),
$cTool = $this->createLinkToCourseTool(
$ltiTool->getName(),
$course->getId(),
null,
self::generateToolLink($tool)
self::generateToolLink($ltiTool)
);
$cTool->setTarget(
$ltiTool->getDocumentTarget() === 'iframe' ? '_self' : '_blank'
);
$em = Database::getManager();
$em->persist($cTool);
$em->flush();
}
/**

@ -1,7 +1,7 @@
IMS/LTI plugin
===
Version 1.5.1
Version 1.7.0
> This plugin is meant to be later integrated into Chamilo (in a major version
release).
@ -24,6 +24,13 @@ external tool.
# Changelog
## v1.7
* Fix auth params
* Add option to show LTI tool in iframe or new window.
## v1.6
* Add support to LTI 1.3 and Advantage Services
## v1.5
* Plugin has passed the tests from the LTI Certification suite.
* Add support for substitution of variable.
@ -55,6 +62,11 @@ external tool.
Run this changes on database:
## To v1.7.0
```sql
ALTER TABLE plugin_ims_lti_tool ADD launch_presentation LONGTEXT NOT NULL COMMENT '(DC2Type:json)';
```
## To v1.6.0
```sql
CREATE TABLE plugin_ims_lti_platform (

@ -101,7 +101,11 @@ try {
$jwtContent['aud'] = $tool->getClientId();
$jwtContent['iat'] = time();
$jwtContent['exp'] = time() + 60;
$jwtContent['nonce'] = md5(microtime().mt_rand());
$jwtContent['nonce'] = $nonce;
if (empty($nonce)) {
$jwtContent['nonce'] = md5(microtime().mt_rand());
}
// User info
if ($tool->isSharingName()) {
@ -150,7 +154,7 @@ try {
// Launch info
$jwtContent['https://purl.imsglobal.org/spec/lti/claim/launch_presentation'] = [
'locale' => api_get_language_isocode($user->getLanguage()),
'document_target' => 'iframe',
'document_target' => $tool->getDocumentTarget(),
//'height' => 320,
//'wdith' => 240,
//'return_url' => api_get_course_url(),
@ -173,7 +177,7 @@ try {
',',
['*/*', ':::asterisk:::/:::asterisk:::']
),
'accept_presentation_document_targets' => ['iframe'],
'accept_presentation_document_targets' => ['iframe', 'window'],
'accept_multiple' => true,
'auto_create' => true,
'title' => $tool->getName(),

@ -60,6 +60,7 @@ switch ($action) {
->setCustomParams(
empty($formValues['custom_params']) ? null : $formValues['custom_params']
)
->setDocumenTarget($formValues['document_target'])
->setCourse($course)
->setPrivacy(
!empty($formValues['share_name']),
@ -79,10 +80,13 @@ switch ($action) {
->setRedirectUrl($formValues['redirect_url'])
->setAdvantageServices(
[
'ags' => $formValues['1p3_ags'],
'ags' => isset($formValues['1p3_ags'])
? $formValues['1p3_ags']
: LtiAssignmentGradesService::AGS_NONE,
'nrps' => $formValues['1p3_nrps'],
]
);
)
->publicKey = $formValues['public_key'];
} elseif (ImsLti::V_1P1 === $formValues['version']) {
if (empty($formValues['consumer_key']) && empty($formValues['shared_secret'])) {
try {
@ -186,6 +190,7 @@ switch ($action) {
->setCustomParams(
empty($formValues['custom_params']) ? null : $formValues['custom_params']
)
->setDocumenTarget($formValues['document_target'])
->setPrivacy(
!empty($formValues['share_name']),
!empty($formValues['share_email']),
@ -200,10 +205,13 @@ switch ($action) {
->setRedirectUrl($formValues['redirect_url'])
->setAdvantageServices(
[
'ags' => $formValues['1p3_ags'],
'ags' => isset($formValues['1p3_ags'])
? $formValues['1p3_ags']
: LtiAssignmentGradesService::AGS_NONE,
'nrps' => $formValues['1p3_nrps'],
]
);
)
->publicKey = $formValues['public_key'];
} elseif ($tool->getVersion() === ImsLti::V_1P1) {
$tool
->setLaunchUrl($formValues['launch_url'])

@ -27,6 +27,7 @@ if ($form->validate()) {
->setCustomParams(
empty($formValues['custom_params']) ? null : $formValues['custom_params']
)
->setDocumenTarget($formValues['document_target'])
->setCourse(null)
->setActiveDeepLinking(
isset($formValues['deep_linking'])

@ -18,9 +18,23 @@ if (!$tool) {
api_not_allowed(true);
}
$links = [];
$links[] = 'ims_lti/start.php?id='.$tool->getId();
if (!$tool->getParent()) {
/** @var ImsLtiTool $child */
foreach ($tool->getChildren() as $child) {
$links[] = "ims_lti/start.php?id=".$child->getId();
}
}
$em->remove($tool);
$em->flush();
$em
->createQuery("DELETE FROM ChamiloCourseBundle:CTool ct WHERE ct.category = :category AND ct.link IN (:links)")
->execute(['category' => 'plugin', 'links' => $links]);
Display::addFlash(
Display::return_message($plugin->get_lang('ToolDeleted'), 'success')
);

@ -43,6 +43,7 @@ if ($form->validate()) {
->setCustomParams(
empty($formValues['custom_params']) ? null : $formValues['custom_params']
)
->setDocumenTarget($formValues['document_target'])
->setPrivacy(
!empty($formValues['share_name']),
!empty($formValues['share_email']),
@ -66,7 +67,9 @@ if ($form->validate()) {
->setRedirectUrl($formValues['redirect_url'])
->setAdvantageServices(
[
'ags' => $formValues['1p3_ags'],
'ags' => isset($formValues['1p3_ags'])
? $formValues['1p3_ags']
: LtiAssignmentGradesService::AGS_NONE,
'nrps' => $formValues['1p3_nrps'],
]
)

@ -42,7 +42,7 @@ if ($tool->isActiveDeepLinking()) {
$params['lti_message_type'] = 'ContentItemSelectionRequest';
$params['content_item_return_url'] = $pluginPath.'item_return.php';
$params['accept_media_types'] = '*/*';
$params['accept_presentation_document_targets'] = 'iframe';
$params['accept_presentation_document_targets'] = 'iframe,window';
//$params['accept_unsigned'];
//$params['accept_multiple'];
//$params['accept_copy_advice'];
@ -99,7 +99,7 @@ $params['context_type'] = 'CourseSection';
$params['context_label'] = $course->getCode();
$params['context_title'] = $course->getTitle();
$params['launch_presentation_locale'] = api_get_language_isocode();
$params['launch_presentation_document_target'] = 'iframe';
$params['launch_presentation_document_target'] = $tool->getDocumentTarget();
$params['tool_consumer_info_product_family_code'] = 'Chamilo LMS';
$params['tool_consumer_info_version'] = api_get_version();
$params['tool_consumer_instance_guid'] = $platformDomain;

@ -65,3 +65,4 @@ $strings['AuthUrl'] = 'OIDC Auth URL';
$strings['TokenUrl'] = 'OAuth2 Access Token URL';
$strings['KeySetUrl'] = 'Keyset URL';
$strings['NamesAndRoleProvisioningService'] = 'Names and Role Provisioning Service';
$strings['YouNeedCreateTheGradebokInCourseFirst'] = 'You must first create the course gradebook to use this service by following this link %s';

@ -36,3 +36,4 @@ $strings['ShareLauncherPicture'] = 'Share launcher\'s picture';
$strings['NoTool'] = 'Tool not exists';
$strings['ToolAddedOnCourseX'] = 'Tool addeed on course <strong>%s</strong>.';
$strings['SupportDeppLinkingHelp'] = 'Contact your Tool Provider to verify if Deep Linking support is mandatory';
$strings['YouNeedCreateTheGradebokInCourseFirst'] = 'You must first create the course gradebook to use this service by following this link %s';

@ -37,4 +37,5 @@ $strings['NoTool'] = 'La herramienta no existe';
$strings['ToolAddedOnCourseX'] = 'Herramienta agregada en el curso <strong>%s</strong>.';
$strings['SupportDeppLinkingHelp'] = 'Contacte a su Proveedor de Herramienta para verificar si el soporte a Deep Linking es obligatorio';
$strings['NoAccessToUrl'] = 'Sin acceso a la URL';
$strings['LaunchUrlNotFound'] = 'URL de lanzamiento no encontrada';
$strings['LaunchUrlNotFound'] = 'URL de lanzamiento no encontrada';
$strings['YouNeedCreateTheGradebokInCourseFirst'] = 'Debe crear el libro de calificaciones del curso para usar este servicio siguiendo este enlace %s';

@ -81,6 +81,11 @@ class FrmAdd extends FormValidator
'custom_params',
[$plugin->get_lang('CustomParams'), $plugin->get_lang('CustomParamsHelp')]
);
$this->addSelect(
'document_target',
get_lang('LinkTarget'),
['iframe' => 'iframe', 'window' => 'window']
);
if (null === $this->baseTool ||
($this->baseTool && !$this->baseTool->isActiveDeepLinking())
@ -92,16 +97,42 @@ class FrmAdd extends FormValidator
);
}
$showAGS = false;
if (api_get_course_int_id()) {
$caterories = Category::load(null, null, api_get_course_id());
if (!empty($caterories)) {
$showAGS = true;
}
} else {
$showAGS = true;
}
$this->addHtml('<div class="'.ImsLti::V_1P3.'" style="display: none;">');
$this->addRadio(
'1p3_ags',
$plugin->get_lang('AssigmentAndGradesService'),
[
LtiAssignmentGradesService::AGS_NONE => $plugin->get_lang('DontUseService'),
LtiAssignmentGradesService::AGS_SIMPLE => $plugin->get_lang('AGServiceSimple'),
LtiAssignmentGradesService::AGS_FULL => $plugin->get_lang('AGServiceFull'),
]
);
if ($showAGS) {
$this->addRadio(
'1p3_ags',
$plugin->get_lang('AssigmentAndGradesService'),
[
LtiAssignmentGradesService::AGS_NONE => $plugin->get_lang('DontUseService'),
LtiAssignmentGradesService::AGS_SIMPLE => $plugin->get_lang('AGServiceSimple'),
LtiAssignmentGradesService::AGS_FULL => $plugin->get_lang('AGServiceFull'),
]
);
} else {
$gradebookUrl = api_get_path(WEB_CODE_PATH).'gradebook/index.php?'.api_get_cidreq();
$this->addLabel(
$plugin->get_lang('AssigmentAndGradesService'),
sprintf(
$plugin->get_lang('YouNeedCreateTheGradebokInCourseFirst'),
Display::url($gradebookUrl, $gradebookUrl)
)
);
}
$this->addRadio(
'1p3_nrps',
$plugin->get_lang('NamesAndRoleProvisioningService'),
@ -132,6 +163,7 @@ class FrmAdd extends FormValidator
$defaults['name'] = $this->baseTool->getName();
$defaults['description'] = $this->baseTool->getDescription();
$defaults['custom_params'] = $this->baseTool->getCustomParams();
$defaults['document_target'] = $this->baseTool->getDocumentTarget();
$defaults['share_name'] = $this->baseTool->isSharingName();
$defaults['share_email'] = $this->baseTool->isSharingEmail();
$defaults['share_picture'] = $this->baseTool->isSharingPicture();

@ -92,6 +92,11 @@ class FrmEdit extends FormValidator
'custom_params',
[$plugin->get_lang('CustomParams'), $plugin->get_lang('CustomParamsHelp')]
);
$this->addSelect(
'document_target',
get_lang('LinkTarget'),
['iframe' => 'iframe', 'window' => 'window']
);
if (null === $parent ||
(null !== $parent && !$parent->isActiveDeepLinking())
@ -104,15 +109,40 @@ class FrmEdit extends FormValidator
}
if (null === $parent && $this->tool->getVersion() === ImsLti::V_1P3) {
$this->addRadio(
'1p3_ags',
$plugin->get_lang('AssigmentAndGradesService'),
[
LtiAssignmentGradesService::AGS_NONE => $plugin->get_lang('DontUseService'),
LtiAssignmentGradesService::AGS_SIMPLE => $plugin->get_lang('AGServiceSimple'),
LtiAssignmentGradesService::AGS_FULL => $plugin->get_lang('AGServiceFull'),
]
);
$showAGS = false;
if (api_get_course_int_id()) {
$caterories = Category::load(null, null, api_get_course_id());
if (!empty($caterories)) {
$showAGS = true;
}
} else {
$showAGS = true;
}
if ($showAGS) {
$this->addRadio(
'1p3_ags',
$plugin->get_lang('AssigmentAndGradesService'),
[
LtiAssignmentGradesService::AGS_NONE => $plugin->get_lang('DontUseService'),
LtiAssignmentGradesService::AGS_SIMPLE => $plugin->get_lang('AGServiceSimple'),
LtiAssignmentGradesService::AGS_FULL => $plugin->get_lang('AGServiceFull'),
]
);
} else {
$gradebookUrl = api_get_path(WEB_CODE_PATH).'gradebook/index.php?'.api_get_cidreq();
$this->addLabel(
$plugin->get_lang('AssigmentAndGradesService'),
sprintf(
$plugin->get_lang('YouNeedCreateTheGradebokInCourseFirst'),
Display::url($gradebookUrl, $gradebookUrl)
)
);
}
$this->addRadio(
'1p3_nrps',
$plugin->get_lang('NamesAndRoleProvisioningService'),
@ -162,6 +192,7 @@ class FrmEdit extends FormValidator
'redirect_url' => $this->tool->getRedirectUrl(),
'1p3_ags' => $advServices['ags'],
'1p3_nrps' => $advServices['nrps'],
'document_target' => $this->tool->getDocumentTarget(),
]
);
}

@ -33,6 +33,11 @@ if ($is1p3) {
$launchUrl = api_get_path(WEB_PLUGIN_PATH).'ims_lti/form.php?'.http_build_query(['id' => $tool->getId()]);
}
if ($tool->getDocumentTarget() == 'window') {
header("Location: $launchUrl");
exit;
}
$template = new Template($pageTitle);
$template->assign('tool', $tool);

Loading…
Cancel
Save