WIP - Improving LTI plugin - refs BT#13469

pull/2458/head
Angel Fernando Quiroz Campos 8 years ago
parent 16d13b7a07
commit a3e18eed59
  1. 45
      plugin/ims_lti/ImsLtiPlugin.php
  2. 53
      plugin/ims_lti/ImsLtiTool.php
  3. 82
      plugin/ims_lti/add.php
  4. 3
      plugin/ims_lti/form.php
  5. 4
      plugin/ims_lti/lang/english.php
  6. 19
      plugin/ims_lti/view/add.tpl

@ -3,6 +3,9 @@
use Chamilo\CourseBundle\Entity\CTool; use Chamilo\CourseBundle\Entity\CTool;
use Chamilo\CoreBundle\Entity\Course; use Chamilo\CoreBundle\Entity\Course;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\DBALException;
/** /**
* Description of MsiLti * Description of MsiLti
@ -53,7 +56,11 @@ class ImsLtiPlugin extends Plugin
*/ */
public function install() public function install()
{ {
try {
$this->setupDatabase(); $this->setupDatabase();
} catch (DBALException $e) {
error_log('Error while installing IMS/LTI plugin: '.$e->getMessage());
}
} }
/** /**
@ -61,37 +68,39 @@ class ImsLtiPlugin extends Plugin
*/ */
public function uninstall() public function uninstall()
{ {
try {
$this->clearDatabase(); $this->clearDatabase();
$this->removeTools();
} catch (DBALException $e) {
error_log('Error while uninstalling IMS/LTI plugin: '.$e->getMessage());
}
} }
/** /**
* Creates the plugin tables on database * Creates the plugin tables on database
* @return boolean * @return boolean
* @throws \Doctrine\DBAL\DBALException
*/ */
private function setupDatabase() private function setupDatabase()
{ {
$entityManager = Database::getManager(); $entityManager = Database::getManager();
$connection = $entityManager->getConnection(); $connection = $entityManager->getConnection();
$chamiloSchema = $connection->getSchemaManager(); $pluginSchema = new Schema();
$pluginSchema = new \Doctrine\DBAL\Schema\Schema();
$platform = $connection->getDatabasePlatform(); $platform = $connection->getDatabasePlatform();
if ($chamiloSchema->tablesExist([self::TABLE_TOOL])) {
return false;
}
$toolTable = $pluginSchema->createTable(self::TABLE_TOOL); $toolTable = $pluginSchema->createTable(self::TABLE_TOOL);
$toolTable->addColumn( $toolTable->addColumn(
'id', 'id',
\Doctrine\DBAL\Types\Type::INTEGER, \Doctrine\DBAL\Types\Type::INTEGER,
['autoincrement' => true, 'unsigned' => true] ['autoincrement' => true, 'unsigned' => true]
); );
$toolTable->addColumn('name', \Doctrine\DBAL\Types\Type::STRING); $toolTable->addColumn('name', Type::STRING);
$toolTable->addColumn('description', \Doctrine\DBAL\Types\Type::TEXT, ['notnull' => false]); $toolTable->addColumn('description', Type::TEXT)->setNotnull(false);
$toolTable->addColumn('launch_url', \Doctrine\DBAL\Types\Type::TEXT); $toolTable->addColumn('launch_url', Type::TEXT);
$toolTable->addColumn('consumer_key', \Doctrine\DBAL\Types\Type::STRING); $toolTable->addColumn('consumer_key', Type::STRING);
$toolTable->addColumn('shared_secret', \Doctrine\DBAL\Types\Type::STRING); $toolTable->addColumn('shared_secret', Type::STRING);
$toolTable->addColumn('custom_params', \Doctrine\DBAL\Types\Type::TEXT); $toolTable->addColumn('custom_params', Type::TEXT);
$toolTable->addColumn('is_global', Type::BOOLEAN);
$toolTable->setPrimaryKey(['id']); $toolTable->setPrimaryKey(['id']);
$queries = $pluginSchema->toSql($platform); $queries = $pluginSchema->toSql($platform);
@ -106,6 +115,7 @@ class ImsLtiPlugin extends Plugin
/** /**
* Drops the plugin tables on database * Drops the plugin tables on database
* @return boolean * @return boolean
* @throws \Doctrine\DBAL\DBALException
*/ */
private function clearDatabase() private function clearDatabase()
{ {
@ -123,6 +133,15 @@ class ImsLtiPlugin extends Plugin
return true; return true;
} }
/**
* @throws \Doctrine\DBAL\DBALException
*/
private function removeTools()
{
$sql = "DELETE FROM c_tool WHERE link LIKE 'ims_lti/start.php%' AND category = 'plugin'";
Database::query($sql);
}
/** /**
* Set the course settings * Set the course settings
*/ */
@ -130,7 +149,7 @@ class ImsLtiPlugin extends Plugin
{ {
$button = Display::toolbarButton( $button = Display::toolbarButton(
$this->get_lang('AddExternalTool'), $this->get_lang('AddExternalTool'),
api_get_path(WEB_PLUGIN_PATH).'ims_lti/add.php', api_get_path(WEB_PLUGIN_PATH).'ims_lti/add.php?'.api_get_cidreq(),
'cog', 'cog',
'primary' 'primary'
); );

@ -7,13 +7,14 @@
*/ */
class ImsLtiTool class ImsLtiTool
{ {
private $id; private $id = 0;
private $name; private $name = '';
private $description; private $description = null;
private $launchUrl; private $launchUrl = '';
private $consumerKey; private $consumerKey = '';
private $sharedSecret; private $sharedSecret = '';
private $customParams; private $customParams = null;
private $isGlobal = false;
public function getId() public function getId()
{ {
@ -101,34 +102,27 @@ class ImsLtiTool
public function save() public function save()
{ {
if (!empty($this->id)) { $parameters = [
Database::update(
ImsLtiPlugin::TABLE_TOOL,
[
'name' => $this->name, 'name' => $this->name,
'description' => $this->description, 'description' => $this->description,
'launch_url' => $this->launchUrl, 'launch_url' => $this->launchUrl,
'consumer_key' => $this->consumerKey, 'consumer_key' => $this->consumerKey,
'shared_secret' => $this->sharedSecret, 'shared_secret' => $this->sharedSecret,
'custom_params' => $this->customParams 'custom_params' => $this->customParams,
], 'is_global' => $this->isGlobal
];
if (!empty($this->id)) {
Database::update(
ImsLtiPlugin::TABLE_TOOL,
$parameters,
['id' => $this->id] ['id' => $this->id]
); );
return; return;
} }
$this->id = Database::insert( $this->id = Database::insert(ImsLtiPlugin::TABLE_TOOL, $parameters);
ImsLtiPlugin::TABLE_TOOL,
[
'name' => $this->name,
'description' => $this->description,
'launch_url' => $this->launchUrl,
'consumer_key' => $this->consumerKey,
'shared_secret' => $this->sharedSecret,
'custom_params' => $this->customParams
]
);
} }
public static function fetch($id) public static function fetch($id)
@ -154,6 +148,7 @@ class ImsLtiTool
$tool->consumerKey = $result['consumer_key']; $tool->consumerKey = $result['consumer_key'];
$tool->sharedSecret = $result['shared_secret']; $tool->sharedSecret = $result['shared_secret'];
$tool->customParams = $result['custom_params']; $tool->customParams = $result['custom_params'];
$tool->isGlobal = (boolean) $result['is_global'];
return $tool; return $tool;
} }
@ -177,4 +172,14 @@ class ImsLtiTool
'value' => $foo[1] 'value' => $foo[1]
]; ];
} }
public function setIsGlobal($isGlobal = true)
{
$this->isGlobal = $isGlobal;
}
public function isGlobal()
{
return $this->isGlobal;
}
} }

@ -9,49 +9,85 @@ api_protect_teacher_script();
$plugin = ImsLtiPlugin::create(); $plugin = ImsLtiPlugin::create();
$em = Database::getManager(); $em = Database::getManager();
$type = isset($_GET['type']) ? intval($_GET['type']) : 0;
$course = $em->find('ChamiloCoreBundle:Course', api_get_course_int_id()); $course = $em->find('ChamiloCoreBundle:Course', api_get_course_int_id());
$tools = ImsLtiTool::fetchAll(); $tools = array_filter(
ImsLtiTool::fetchAll(),
function ($tool) {
return (boolean) $tool['is_global'];
}
);
$isGlobalTool = $type ? array_key_exists($type, $tools) : true;
$types = [ if (!$isGlobalTool) {
'0' => get_lang('None') Display::addFlash(
]; Display::return_message($plugin->get_lang('ToolNotAvailable'), 'warning')
);
foreach ($tools as $tool) { header('Location: '.api_get_self().'?'.api_get_cidreq());
$types[$tool['id']] = $tool['name']; exit;
} }
$form = new FormValidator('ims_lti_add_tool'); $form = new FormValidator('ims_lti_add_tool');
$form->addText('tool_name', $plugin->get_lang('ToolName')); $form->addText('name', $plugin->get_lang('ToolName'));
$form->addSelect('type', $plugin->get_lang('Type'), $types);
$form->addRule('type', get_lang('Required'), 'required'); if (!$type) {
$form->addHtml('<div id="show_advanced_options">'); $form->addHtml('<div id="show_advanced_options">');
$form->addElement('url', 'url', $plugin->get_lang('LaunchUrl')); $form->addElement('url', 'url', $plugin->get_lang('LaunchUrl'));
$form->addText('consumer_key', $plugin->get_lang('ConsumerKey'), false); $form->addText('consumer_key', $plugin->get_lang('ConsumerKey'), true);
$form->addText('shared_secret', $plugin->get_lang('SharedSecret'), false); $form->addText('shared_secret', $plugin->get_lang('SharedSecret'), true);
$form->addTextarea('custom_params', $plugin->get_lang('CustomParams')); $form->addTextarea('custom_params', $plugin->get_lang('CustomParams'));
$form->addHtml('</div>'); $form->addHtml('</div>');
$form->addRule('url', get_lang('Required'), 'required');
}
$form->addButtonCreate($plugin->get_lang('AddExternalTool')); $form->addButtonCreate($plugin->get_lang('AddExternalTool'));
if ($form->validate()) { if ($form->validate()) {
$formValues = $form->getSubmitValues(); $formValues = $form->getSubmitValues();
$tool = null;
if (!empty($formValues['type'])) { if ($type) {
$tool = ImsLtiTool::fetch($formValues['type']); $baseTool = ImsLtiTool::fetch($type);
if (!$tool) { if ($baseTool) {
Display::addFlash( $baseTool->setName($formValues['name']);
Display::return_message($plugin->get_lang('NoTool')) }
);
// redirect to course $tool = $baseTool;
exit; } else {
$tool = new ImsLtiTool();
$tool
->setName($formValues['name'])
->setLaunchUrl($formValues['url'])
->setConsumerKey($formValues['consumer_key'])
->setSharedSecret($formValues['shared_secret'])
->setCustomParams($formValues['custom_params'])
->isGlobal(false);
$tool->save();
} }
if ($tool) {
$plugin->addCourseTool($course, $tool); $plugin->addCourseTool($course, $tool);
Display::addFlash(
Display::return_message($plugin->get_lang('ToolAdded'), 'success')
);
} else {
Display::addFlash(
Display::return_message($plugin->get_lang('NoTool'), 'error')
);
} }
header('Location: '.api_get_course_url());
exit;
} }
$template = new Template($plugin->get_lang('AddExternalTool')); $template = new Template($plugin->get_lang('AddExternalTool'));
$template->assign('type', $type);
$template->assign('tools', $tools);
$template->assign('form', $form->returnForm()); $template->assign('form', $form->returnForm());
$content = $template->fetch('ims_lti/view/add.tpl'); $content = $template->fetch('ims_lti/view/add.tpl');

@ -33,6 +33,7 @@ $params = [
'resource_link_id' => $tool->getId(), 'resource_link_id' => $tool->getId(),
'resource_link_title' => $tool->getName(), 'resource_link_title' => $tool->getName(),
'resource_link_description' => $tool->getDescription(),
'user_id' => $toolUserId, 'user_id' => $toolUserId,
'roles' => api_is_teacher() ? 'Instructor' : 'Student', 'roles' => api_is_teacher() ? 'Instructor' : 'Student',
@ -55,8 +56,6 @@ $params = [
'tool_consumer_instance_name' => $siteName, 'tool_consumer_instance_name' => $siteName,
'tool_consumer_instance_url' => api_get_path(WEB_PATH), 'tool_consumer_instance_url' => api_get_path(WEB_PATH),
'tool_consumer_instance_contact_email' => api_get_setting('emailAdministrator'), 'tool_consumer_instance_contact_email' => api_get_setting('emailAdministrator'),
'resource_link_description' => 'A quick revision PowerPoint about the Water cycle. Make sure you\'re clear about it!',
]; ];
$oauth = new OAuthSimple( $oauth = new OAuthSimple(

@ -14,3 +14,7 @@ $strings['ConsumerKey'] = 'Consumer key';
$strings['SharedSecret'] = 'Shared secret'; $strings['SharedSecret'] = 'Shared secret';
$strings['CustomParams'] = 'Custom params'; $strings['CustomParams'] = 'Custom params';
$strings['ToolName'] = 'Tool name'; $strings['ToolName'] = 'Tool name';
$strings['ToolNotAdded'] = 'Tool not added';
$strings['AvailableTools'] = 'Available tools';
$strings['ToolSettings'] = 'Tool settings';
$strings['ToolNotAvailable'] = 'Tool not available';

@ -1,4 +1,21 @@
{{ form }} <div class="row">
{% if tools|length %}
<div class="col-sm-3">
<h2 class="page-header">{{ 'AvailableTools'|get_plugin_lang('ImsLtiPlugin') }}</h2>
<ul class="nav nav-pills nav-stacked">
{% for tool in tools %}
<li class="{{ type == tool.id ? 'active' : '' }}">
<a href="{{ _p.web_self }}?type={{ tool.id }}&{{ _p.web_cid_query }}">{{ tool.name }}</a>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="col-sm-9 {{ tools|length ? '' : 'col-sm-offset-3' }}">
<h2 class="page-header">{{ 'ToolSettings'|get_plugin_lang('ImsLtiPlugin') }}</h2>
{{ form }}
</div>
</div>
<script> <script>
$(document).on('ready', function () { $(document).on('ready', function () {

Loading…
Cancel
Save