Kaynağa Gözat

WIP - Improving LTI plugin - refs BT#13469

Angel Fernando Quiroz Campos 7 yıl önce
ebeveyn
işleme
a3e18eed59

+ 34 - 15
plugin/ims_lti/ImsLtiPlugin.php

@@ -3,6 +3,9 @@
 
 use Chamilo\CourseBundle\Entity\CTool;
 use Chamilo\CoreBundle\Entity\Course;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Types\Type;
+use Doctrine\DBAL\DBALException;
 
 /**
  * Description of MsiLti
@@ -53,7 +56,11 @@ class ImsLtiPlugin extends Plugin
      */
     public function install()
     {
-        $this->setupDatabase();
+        try {
+            $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()
     {
-        $this->clearDatabase();
+        try {
+            $this->clearDatabase();
+            $this->removeTools();
+        } catch (DBALException $e) {
+            error_log('Error while uninstalling IMS/LTI plugin: '.$e->getMessage());
+        }
     }
 
     /**
      * Creates the plugin tables on database
      * @return boolean
+     * @throws \Doctrine\DBAL\DBALException
      */
     private function setupDatabase()
     {
         $entityManager = Database::getManager();
         $connection = $entityManager->getConnection();
-        $chamiloSchema = $connection->getSchemaManager();
-        $pluginSchema = new \Doctrine\DBAL\Schema\Schema();
+        $pluginSchema = new Schema();
         $platform = $connection->getDatabasePlatform();
 
-        if ($chamiloSchema->tablesExist([self::TABLE_TOOL])) {
-            return false;
-        }
-
         $toolTable = $pluginSchema->createTable(self::TABLE_TOOL);
         $toolTable->addColumn(
             'id',
             \Doctrine\DBAL\Types\Type::INTEGER,
             ['autoincrement' => true, 'unsigned' => true]
         );
-        $toolTable->addColumn('name', \Doctrine\DBAL\Types\Type::STRING);
-        $toolTable->addColumn('description', \Doctrine\DBAL\Types\Type::TEXT, ['notnull' => false]);
-        $toolTable->addColumn('launch_url', \Doctrine\DBAL\Types\Type::TEXT);
-        $toolTable->addColumn('consumer_key', \Doctrine\DBAL\Types\Type::STRING);
-        $toolTable->addColumn('shared_secret', \Doctrine\DBAL\Types\Type::STRING);
-        $toolTable->addColumn('custom_params', \Doctrine\DBAL\Types\Type::TEXT);
+        $toolTable->addColumn('name', Type::STRING);
+        $toolTable->addColumn('description', Type::TEXT)->setNotnull(false);
+        $toolTable->addColumn('launch_url', Type::TEXT);
+        $toolTable->addColumn('consumer_key', Type::STRING);
+        $toolTable->addColumn('shared_secret', Type::STRING);
+        $toolTable->addColumn('custom_params', Type::TEXT);
+        $toolTable->addColumn('is_global', Type::BOOLEAN);
         $toolTable->setPrimaryKey(['id']);
 
         $queries = $pluginSchema->toSql($platform);
@@ -106,6 +115,7 @@ class ImsLtiPlugin extends Plugin
     /**
      * Drops the plugin tables on database
      * @return boolean
+     * @throws \Doctrine\DBAL\DBALException
      */
     private function clearDatabase()
     {
@@ -123,6 +133,15 @@ class ImsLtiPlugin extends Plugin
         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
      */
@@ -130,7 +149,7 @@ class ImsLtiPlugin extends Plugin
     {
         $button = Display::toolbarButton(
             $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',
             'primary'
         );

+ 31 - 26
plugin/ims_lti/ImsLtiTool.php

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

+ 60 - 24
plugin/ims_lti/add.php

@@ -9,49 +9,85 @@ api_protect_teacher_script();
 $plugin = ImsLtiPlugin::create();
 $em = Database::getManager();
 
+$type = isset($_GET['type']) ? intval($_GET['type']) : 0;
+
 $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 = [
-    '0' => get_lang('None')
-];
+if (!$isGlobalTool) {
+    Display::addFlash(
+        Display::return_message($plugin->get_lang('ToolNotAvailable'), 'warning')
+    );
 
-foreach ($tools as $tool) {
-    $types[$tool['id']] = $tool['name'];
+    header('Location: '.api_get_self().'?'.api_get_cidreq());
+    exit;
 }
 
 $form = new FormValidator('ims_lti_add_tool');
-$form->addText('tool_name', $plugin->get_lang('ToolName'));
-$form->addSelect('type', $plugin->get_lang('Type'), $types);
-$form->addRule('type', get_lang('Required'), 'required');
-$form->addHtml('<div id="show_advanced_options">');
-$form->addElement('url', 'url', $plugin->get_lang('LaunchUrl'));
-$form->addText('consumer_key', $plugin->get_lang('ConsumerKey'), false);
-$form->addText('shared_secret', $plugin->get_lang('SharedSecret'), false);
-$form->addTextarea('custom_params', $plugin->get_lang('CustomParams'));
-$form->addHtml('</div>');
+$form->addText('name', $plugin->get_lang('ToolName'));
+
+if (!$type) {
+    $form->addHtml('<div id="show_advanced_options">');
+    $form->addElement('url', 'url', $plugin->get_lang('LaunchUrl'));
+    $form->addText('consumer_key', $plugin->get_lang('ConsumerKey'), true);
+    $form->addText('shared_secret', $plugin->get_lang('SharedSecret'), true);
+    $form->addTextarea('custom_params', $plugin->get_lang('CustomParams'));
+    $form->addHtml('</div>');
+    $form->addRule('url', get_lang('Required'), 'required');
+}
+
 $form->addButtonCreate($plugin->get_lang('AddExternalTool'));
 
 if ($form->validate()) {
     $formValues = $form->getSubmitValues();
+    $tool = null;
 
-    if (!empty($formValues['type'])) {
-        $tool = ImsLtiTool::fetch($formValues['type']);
+    if ($type) {
+        $baseTool = ImsLtiTool::fetch($type);
 
-        if (!$tool) {
-            Display::addFlash(
-                Display::return_message($plugin->get_lang('NoTool'))
-            );
-
-            // redirect to course
-            exit;
+        if ($baseTool) {
+            $baseTool->setName($formValues['name']);
         }
 
+        $tool = $baseTool;
+    } 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);
+
+        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->assign('type', $type);
+$template->assign('tools', $tools);
 $template->assign('form', $form->returnForm());
 
 $content = $template->fetch('ims_lti/view/add.tpl');

+ 1 - 2
plugin/ims_lti/form.php

@@ -33,6 +33,7 @@ $params = [
 
     'resource_link_id' => $tool->getId(),
     'resource_link_title' => $tool->getName(),
+    'resource_link_description' => $tool->getDescription(),
 
     'user_id' => $toolUserId,
     'roles' => api_is_teacher() ? 'Instructor' : 'Student',
@@ -55,8 +56,6 @@ $params = [
     'tool_consumer_instance_name' => $siteName,
     'tool_consumer_instance_url' => api_get_path(WEB_PATH),
     '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(

+ 4 - 0
plugin/ims_lti/lang/english.php

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

+ 18 - 1
plugin/ims_lti/view/add.tpl

@@ -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>
     $(document).on('ready', function () {