Merge branch '1.11.x.ims-lti-plugin-add-tool-to-sessions' into 1.11.x

pull/4141/head
Angel Fernando Quiroz Campos 4 years ago
commit 656ec67a0f
  1. 3
      main/inc/lib/plugin.class.php
  2. 32
      plugin/ims_lti/Entity/ImsLtiTool.php
  3. 36
      plugin/ims_lti/ImsLtiPlugin.php
  4. 13
      plugin/ims_lti/README.md
  5. 17
      plugin/ims_lti/admin.php
  6. 3
      plugin/ims_lti/gradebook/add_eval.php
  7. 1
      plugin/ims_lti/lang/english.php
  8. 1
      plugin/ims_lti/lang/spanish.php
  9. 164
      plugin/ims_lti/multiply_session.php
  10. 92
      plugin/ims_lti/session.php
  11. 35
      plugin/ims_lti/view/admin.tpl
  12. 1
      plugin/toplinks/src/TopLinksPlugin.php
  13. 1
      plugin/xapi/src/XApiPlugin.php

@ -1085,6 +1085,7 @@ class Plugin
$courseId,
$iconName = null,
$link = null,
$sessionId = 0,
$category = 'plugin'
) {
if (!$this->addCourseTool) {
@ -1120,7 +1121,7 @@ class Plugin
->setAddedTool(false)
->setTarget('_self')
->setCategory($category)
->setSessionId(0);
->setSessionId($sessionId);
$em->persist($tool);
$em->flush();

@ -4,6 +4,7 @@
namespace Chamilo\PluginBundle\Entity\ImsLti;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\GradebookEvaluation;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
@ -87,6 +88,13 @@ class ImsLtiTool
* @ORM\JoinColumn(name="c_id", referencedColumnName="id")
*/
private $course = null;
/**
* @var Session|null
*
* @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Session")
* @ORM\JoinColumn(name="session_id", referencedColumnName="id")
*/
private $session = null;
/**
* @var GradebookEvaluation|null
*
@ -435,6 +443,30 @@ class ImsLtiTool
return $this;
}
/**
* Get session.
*
* @return Session|null
*/
public function getSession()
{
return $this->session;
}
/**
* Set session.
*
* @param Session|null $course
*
* @return ImsLtiTool
*/
public function setSession(Session $session = null)
{
$this->session = $session;
return $this;
}
/**
* Get gradebookEval.
*

@ -185,9 +185,11 @@ class ImsLtiPlugin extends Plugin
version VARCHAR(255) DEFAULT 'lti1p1' NOT NULL,
launch_presentation LONGTEXT NOT NULL COMMENT '(DC2Type:json)',
replacement_params LONGTEXT NOT NULL COMMENT '(DC2Type:json)',
session_id INT DEFAULT NULL,
INDEX IDX_C5E47F7C91D79BD3 (c_id),
INDEX IDX_C5E47F7C82F80D8B (gradebook_eval_id),
INDEX IDX_C5E47F7C727ACA70 (parent_id),
INDEX IDX_C5E47F7C613FECDF (session_id),
PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB",
"CREATE TABLE plugin_ims_lti_platform (
@ -233,7 +235,9 @@ class ImsLtiPlugin extends Plugin
"ALTER TABLE plugin_ims_lti_lineitem ADD CONSTRAINT FK_BA81BBF08F7B22CC FOREIGN KEY (tool_id)
REFERENCES plugin_ims_lti_tool (id) ON DELETE CASCADE",
"ALTER TABLE plugin_ims_lti_lineitem ADD CONSTRAINT FK_BA81BBF01323A575 FOREIGN KEY (evaluation)
REFERENCES gradebook_evaluation (id) ON DELETE CASCADE "
REFERENCES gradebook_evaluation (id) ON DELETE CASCADE ",
"ALTER TABLE plugin_ims_lti_tool ADD CONSTRAINT FK_C5E47F7C613FECDF FOREIGN KEY (session_id)
REFERENCES session (id)",
];
foreach ($queries as $query) {
@ -367,6 +371,36 @@ class ImsLtiPlugin extends Plugin
$em->flush();
}
/**
* Add the course session tool.
*
* @param Course $course
* @param Session $session
* @param ImsLtiTool $ltiTool
* @param bool $isVisible
*
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function addCourseSessionTool(Course $course, Session $session, ImsLtiTool $ltiTool, $isVisible = true)
{
$cTool = $this->createLinkToCourseTool(
$ltiTool->getName(),
$course->getId(),
null,
self::generateToolLink($ltiTool),
$session->getId()
);
$cTool
->setTarget(
$ltiTool->getDocumentTarget() === 'iframe' ? '_self' : '_blank'
)
->setVisibility($isVisible);
$em = Database::getManager();
$em->persist($cTool);
$em->flush();
}
/**
* @return string
*/

@ -1,7 +1,7 @@
IMS/LTI plugin
===
Version 1.8.0
Version 1.9.0
> This plugin is meant to be later integrated into Chamilo (in a major version
release).
@ -25,6 +25,10 @@ external tool.
# Changelog
## v1.9
> Requires DB changes to upgrade, see [v1.9](#to-v190).
* Add option to add LTI tool to sessions
## v1.8
> Requires DB changes to upgrade, see [v1.8](#to-v180).
* Add option to add replacements for launch params
@ -74,6 +78,13 @@ external tool.
Run this changes on database:
## To v1.9.0
```sql
ALTER TABLE plugin_ims_lti_tool ADD session_id INT DEFAULT NULL;
ALTER TABLE plugin_ims_lti_tool ADD CONSTRAINT FK_C5E47F7C613FECDF FOREIGN KEY (session_id) REFERENCES session (id);
CREATE INDEX IDX_C5E47F7C613FECDF ON plugin_ims_lti_tool (session_id);
```
## To v1.8.0
```sql
ALTER TABLE plugin_ims_lti_tool ADD replacement_params LONGTEXT NOT NULL COMMENT '(DC2Type:json)';

@ -24,6 +24,22 @@ $criteria = Criteria::create()
$tools = $em->getRepository('ChamiloPluginBundle:ImsLti\ImsLtiTool')->matching($criteria);
$categoriesGradeBook = [];
foreach($tools as $tool) {
foreach($tool->getChildren() as $childTool) {
$categories = [];
if($childTool->getSession() != null) {
$categories = Category::load(null, null, $childTool->getCourse()->getCode(), null, null, $childTool->getSession()->getId());
}
else {
$categories = Category::load(null, null, $childTool->getCourse()->getCode());
}
if ($categories != null){
array_push($categoriesGradeBook, $categories[0]);
}
}
}
$interbreadcrumb[] = ['url' => api_get_path(WEB_CODE_PATH).'admin/index.php', 'name' => get_lang('PlatformAdmin')];
$htmlHeadXtra[] = api_get_css(
@ -32,6 +48,7 @@ $htmlHeadXtra[] = api_get_css(
$template = new Template($plugin->get_title());
$template->assign('tools', $tools);
$template->assign('categories', $categoriesGradeBook);
$content = $template->fetch('ims_lti/view/admin.tpl');

@ -17,6 +17,7 @@ api_block_anonymous_users();
GradebookUtils::block_students();
$select_cat = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
$sessionId = isset($_GET['id_session']) ? (int) $_GET['id_session'] : null;
$is_allowedToEdit = $is_courseAdmin;
$em = Database::getManager();
@ -24,7 +25,7 @@ $em = Database::getManager();
$course = $em->find('ChamiloCoreBundle:Course', api_get_course_int_id());
$ltiToolRepo = $em->getRepository('ChamiloPluginBundle:ImsLti\ImsLtiTool');
$categories = Category::load(null, null, $course->getCode());
$categories = Category::load(null, null, $course->getCode(), null, null, $sessionId);
if (empty($categories)) {
$message = Display::return_message(

@ -70,3 +70,4 @@ $strings['ReplacementUserId'] = 'Replacement for user_id (sub)';
$strings['ReplacementUserIdHelp'] = 'The current user_id (sub) in launch params will be formed from platform settings and user ID.<br>You can set a replacement for it using some variables like <code>$User.id</code> or <code>$User.username</code>.';
$strings['AddInCourses'] = 'Add in courses';
$strings['AddInAllCourses'] = 'Add in all courses';
$strings['AddInSessions'] = 'Add in sessions';

@ -39,3 +39,4 @@ $strings['SupportDeppLinkingHelp'] = 'Contacte a su Proveedor de Herramienta par
$strings['NoAccessToUrl'] = 'Sin acceso a la URL';
$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';
$strings['AddInSessions'] = 'Añadir a sesiones';

@ -0,0 +1,164 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\PluginBundle\Entity\ImsLti\ImsLtiTool;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
$cidReset = true;
require_once __DIR__.'/../../main/inc/global.inc.php';
api_protect_admin_script(false);
$plugin = ImsLtiPlugin::create();
$webPluginPath = api_get_path(WEB_PLUGIN_PATH).'ims_lti/';
$em = Database::getManager();
try {
if ($plugin->get('enabled') !== 'true') {
throw new Exception(get_lang('NotAllowed'));
}
$request = Request::createFromGlobals();
$ltiToolId = $request->query->getInt('id');
$sessionId = $request->query->getInt('session_id');
/** @var ImsLtiTool $tool */
$tool = $em->find('ChamiloPluginBundle:ImsLti\ImsLtiTool', $ltiToolId);
if (!$tool) {
throw new Exception($plugin->get_lang('NoTool'));
}
if ($tool->getParent()) {
throw new Exception($plugin->get_lang('NoAllowed'));
}
$session = api_get_session_entity($sessionId);
if (!$session) {
api_not_allowed(true);
}
$content = '';
$courses = ImsLtiPlugin::getCoursesForParentTool($tool);
$slctCourses = [];
/** @var \Chamilo\CoreBundle\Entity\Course $course */
foreach ($courses as $course) {
$slctCourses[$course->getId()] = $course->getName();
}
$selectedCoursesIds = array_keys($slctCourses);
$form = new FormValidator('frm_multiply', 'post', api_get_self().'?id='.$tool->getId().'&session_id='.$sessionId);
$form->addLabel(get_lang('SessionName'), $session);
$form->addLabel($plugin->get_lang('Tool'), $tool->getName());
$form->addSelectAjax(
'courses',
get_lang('Courses'),
$slctCourses,
[
'url' => api_get_path(WEB_AJAX_PATH).'course.ajax.php?'.http_build_query(
[
'a' => 'search_course_by_session_all',
'session_id' => $sessionId
]
),
'multiple' => true
]
);
$form->addCheckBox('tool_visible', get_lang('SetVisible'), get_lang('ToolIsNowVisible'));
$form->addButtonExport(get_lang('Save'));
if ($form->validate()) {
$em = Database::getManager();
$formValues = $form->exportValues();
$formValues['courses'] = empty($formValues['courses']) ? [] : $formValues['courses'];
$formValues['tool_visible'] = !empty($formValues['tool_visible']);
$courseIdsToDelete = array_diff($selectedCoursesIds, $formValues['courses']);
$newSelectedCourseIds = array_diff($formValues['courses'], $selectedCoursesIds);
if ($courseIdsToDelete) {
$toolLinks = [];
/** @var ImsLtiTool $childInCourse */
foreach ($tool->getChildrenInCourses($courseIdsToDelete) as $childInCourse) {
$toolLinks[] = "ims_lti/start.php?id={$childInCourse->getId()}";
$em->remove($childInCourse);
}
$em->flush();
if (!empty($toolLinks)) {
$em
->createQuery(
"DELETE FROM ChamiloCourseBundle:CTool ct WHERE ct.category = :category AND ct.link IN (:links) AND ct.session_id = :sessionId"
)
->execute(['category' => 'plugin', 'links' => $toolLinks, 'sessionId' => $sessionId]);
}
}
if ($newSelectedCourseIds) {
foreach ($newSelectedCourseIds as $newSelectedCourseId) {
$newSelectedCourse = api_get_course_entity($newSelectedCourseId);
$newTool = clone $tool;
$newTool->setParent($tool);
$newTool->setCourse($newSelectedCourse);
$newTool->setSession($session);
$em->persist($newTool);
$em->flush();
if ($tool->isActiveDeepLinking()) {
continue;
}
$plugin->addCourseSessionTool(
$newSelectedCourse,
$session,
$newTool,
$formValues['tool_visible']
);
}
}
Display::addFlash(
Display::return_message(get_lang('ItemUpdated'))
);
header('Location: '.api_get_path(WEB_PLUGIN_PATH).'ims_lti/admin.php');
exit;
}
$form->setDefaults(
[
'courses' => $selectedCoursesIds,
'tool_visible' => true,
]
);
$form->protect();
$content = $form->returnForm();
$interbreadcrumb[] = ['url' => api_get_path(WEB_CODE_PATH).'admin/index.php', 'name' => get_lang('PlatformAdmin')];
$interbreadcrumb[] = ['url' => api_get_path(WEB_PLUGIN_PATH).'ims_lti/admin.php', 'name' => $plugin->get_title()];
$template = new Template($plugin->get_lang('AddInCourses'));
$template->assign('header', $plugin->get_lang('AddInCourses'));
$template->assign('content', $content);
$template->display_one_col_template();
} catch (Exception $exception) {
Display::addFlash(
Display::return_message($exception->getMessage(), 'error')
);
header('Location: '.api_get_path(WEB_PLUGIN_PATH).'ims_lti/admin.php');
}

@ -0,0 +1,92 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\PluginBundle\Entity\ImsLti\ImsLtiTool;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
$cidReset = true;
require_once __DIR__.'/../../main/inc/global.inc.php';
api_protect_admin_script(false);
$plugin = ImsLtiPlugin::create();
$webPluginPath = api_get_path(WEB_PLUGIN_PATH).'ims_lti/';
$request = Request::createFromGlobals();
$ltiToolId = $request->query->getInt('id');
$em = Database::getManager();
try {
if ($plugin->get('enabled') !== 'true') {
throw new Exception(get_lang('NotAllowed'));
}
/** @var ImsLtiTool $tool */
$tool = $em->find('ChamiloPluginBundle:ImsLti\ImsLtiTool',$ltiToolId);
if (!$tool) {
throw new Exception($plugin->get_lang('NoTool'));
}
if ($tool->getParent()) {
throw new Exception($plugin->get_lang('NoAllowed'));
}
$content = '';
$form = new FormValidator('frm_multiply', 'post', api_get_self().'?id='.$tool->getId());
$form->addLabel($plugin->get_lang('Tool'), $tool->getName());
$form->addSelectAjax(
'sessions',
get_lang('Sessions'),
[],
[
'url' => api_get_path(WEB_AJAX_PATH).'session.ajax.php?'.http_build_query(
[
'a' => 'search_session'
]
)
]
);
$form->addHidden('tool_id', $tool->getId());
$form->addButtonExport(get_lang('Next'));
if ($form->validate()) {
$em = Database::getManager();
$formValues = $form->exportValues();
$formValues['sessions'] = empty($formValues['sessions']) ? [] : $formValues['sessions'];
if (!$formValues['sessions']) {
Display::addFlash(
Display::return_message($plugin->get_lang('NeedToSelectASession'), 'error', false)
);
header('Location:'.api_get_self());
exit;
}
header('Location: '.api_get_path(WEB_PLUGIN_PATH).'ims_lti/multiply_session.php?id='.$formValues['tool_id'].'&session_id='.$formValues['sessions']);
exit;
}
$form->protect();
$content = $form->returnForm();
$interbreadcrumb[] = ['url' => api_get_path(WEB_CODE_PATH).'admin/index.php', 'name' => get_lang('PlatformAdmin')];
$interbreadcrumb[] = ['url' => api_get_path(WEB_PLUGIN_PATH).'ims_lti/admin.php', 'name' => $plugin->get_title()];
$template = new Template($plugin->get_lang('AddInSessions'));
$template->assign('header', $plugin->get_lang('AddInSessions'));
$template->assign('content', $content);
$template->display_one_col_template();
} catch (Exception $exception) {
Display::addFlash(
Display::return_message($exception->getMessage(), 'error')
);
header('Location: '.api_get_path(WEB_PLUGIN_PATH).'ims_lti/admin.php');
}

@ -1,6 +1,6 @@
{% import _self as table_tool %}
{% macro row_tool(tool, is_child, _p) %}
{% macro row_tool(tool, is_child, categories, _p) %}
{% set url_params = {'id': tool.id}|url_encode() %}
<tr class="{{ is_child ? 'child' : '' }}">
<td {% if is_child %} colspan="2" {% endif %}>
@ -16,6 +16,9 @@
{% if tool.course is not empty %}
{{ tool.course.title }}
{% endif %}
{% if tool.session is not empty %}
({{ tool.session.name }})
{% endif %}
</td>
<td class="text-right">
{% if not is_child and tool.version == 'lti1p3' %}
@ -31,6 +34,32 @@
</a>
{% endif %}
{% if not is_child %}
<a href="{{ _p.web_plugin }}ims_lti/session.php?{{ url_params }}">
{{ 'session.png'|img(22, 'AddInSessions'|get_plugin_lang('ImsLtiPlugin')) }}
</a>
{% endif %}
{% if is_child %}
{% for category in categories %}
{% set url_eval_params = null %}
{% if tool.session is not empty %}
{% if category.get_course_code == tool.course.code and category.get_session_id == tool.session.id %}
{% set url_eval_params = {'selectcat': category.get_id, 'cidReq': tool.course.code, 'id_session': tool.session.id, 'gidReq': 0, 'gradebook': 0}|url_encode() %}
{% endif %}
{% else %}
{% if category.get_course_code == tool.course.code %}
{% set url_eval_params = {'selectcat': category.get_id, 'cidReq': tool.course.code, 'id_session': 0, 'gidReq': 0, 'gradebook': 0}|url_encode() %}
{% endif %}
{% endif %}
{% if url_eval_params is not null %}
<a href="{{ _p.web_plugin }}ims_lti/gradebook/add_eval.php?{{ url_eval_params }}">
{{ 'gradebook.png'|img(22, 'MakeQualifiable'|get_lang) }}
</a>
{% endif %}
{% endfor %}
{% endif %}
<a href="{{ _p.web_plugin }}ims_lti/edit.php?{{ url_params }}">
{{ 'edit.png'|img(22, 'Edit'|get_lang) }}
</a>
@ -64,9 +93,9 @@
</thead>
<tbody>
{% for tool in tools %}
{{ table_tool.row_tool(tool, false, _p) }}
{{ table_tool.row_tool(tool, false, categories, _p) }}
{% for child_tool in tool.getChildren %}
{{ table_tool.row_tool(child_tool, true, _p) }}
{{ table_tool.row_tool(child_tool, true, categories, _p) }}
{% endfor %}
{% endfor %}
</tbody>

@ -55,6 +55,7 @@ class TopLinksPlugin extends Plugin implements HookPluginInterface
$courseId,
'external_link.png',
'../plugin/toplinks/start.php?'.http_build_query(['link' => $link->getId()]),
0,
'authoring'
);

@ -326,6 +326,7 @@ class XApiPlugin extends Plugin implements HookPluginInterface
$courseId,
'sessions_category.png',
'../plugin/xapi/start.php',
0,
'authoring'
);
}

Loading…
Cancel
Save