diff --git a/plugin/ims_lti/Entity/ImsLtiTool.php b/plugin/ims_lti/Entity/ImsLtiTool.php new file mode 100644 index 0000000000..6c4ba10ea0 --- /dev/null +++ b/plugin/ims_lti/Entity/ImsLtiTool.php @@ -0,0 +1,221 @@ +id; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @param string $name + * @return ImsLtiTool + */ + public function setName($name) + { + $this->name = $name; + + return $this; + } + + /** + * @return null|string + */ + public function getDescription() + { + return $this->description; + } + + /** + * @param null|string $description + * @return ImsLtiTool + */ + public function setDescription($description) + { + $this->description = $description; + + return $this; + } + + /** + * @return string + */ + public function getLaunchUrl() + { + return $this->launchUrl; + } + + /** + * @param string $launchUrl + * @return ImsLtiTool + */ + public function setLaunchUrl($launchUrl) + { + $this->launchUrl = $launchUrl; + + return $this; + } + + /** + * @return string + */ + public function getConsumerKey() + { + return $this->consumerKey; + } + + /** + * @param string $consumerKey + * @return ImsLtiTool + */ + public function setConsumerKey($consumerKey) + { + $this->consumerKey = $consumerKey; + + return $this; + } + + /** + * @return string + */ + public function getSharedSecret() + { + return $this->sharedSecret; + } + + /** + * @param string $sharedSecret + * @return ImsLtiTool + */ + public function setSharedSecret($sharedSecret) + { + $this->sharedSecret = $sharedSecret; + + return $this; + } + + /** + * @return null|string + */ + public function getCustomParams() + { + return $this->customParams; + } + + /** + * @param null|string $customParams + * @return ImsLtiTool + */ + public function setCustomParams($customParams) + { + $this->customParams = $customParams; + + return $this; + } + + /** + * @return bool + */ + public function isGlobal() + { + return $this->isGlobal; + } + + /** + * @param bool $isGlobal + * @return ImsLtiTool + */ + public function setIsGlobal($isGlobal) + { + $this->isGlobal = $isGlobal; + + return $this; + } + + /** + * @return array + */ + public function parseCustomParams() + { + $strings = explode($this->customParams, "\n"); + $pairs = explode('=', $strings); + + return [ + 'key' => 'custom_'.$pairs[0], + 'value' => $pairs[1] + ]; + } +} diff --git a/plugin/ims_lti/ImsLtiPlugin.php b/plugin/ims_lti/ImsLtiPlugin.php index 9c0dfcc396..07e45725d2 100644 --- a/plugin/ims_lti/ImsLtiPlugin.php +++ b/plugin/ims_lti/ImsLtiPlugin.php @@ -6,6 +6,8 @@ use Chamilo\CoreBundle\Entity\Course; use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\DBALException; +use Symfony\Component\Filesystem\Filesystem; +use Chamilo\PluginBundle\Entity\ImsLti\ImsLtiTool; /** * Description of MsiLti @@ -14,7 +16,7 @@ use Doctrine\DBAL\DBALException; */ class ImsLtiPlugin extends Plugin { - const TABLE_TOOL = 'plugin_msi_lti_tool'; + const TABLE_TOOL = 'plugin_ims_lti_tool'; public $isAdminPlugin = true; @@ -23,7 +25,7 @@ class ImsLtiPlugin extends Plugin */ protected function __construct() { - $version = '1.0'; + $version = '1.0 (beta)'; $author = 'Angel Fernando Quiroz Campos'; parent::__construct($version, $author, ['enabled' => 'boolean']); @@ -56,11 +58,23 @@ class ImsLtiPlugin extends Plugin */ public function install() { - try { - $this->setupDatabase(); - } catch (DBALException $e) { - error_log('Error while installing IMS/LTI plugin: '.$e->getMessage()); + $pluginEntityPath = $this->getEntityPath(); + + if (!is_dir($pluginEntityPath)) { + if (!is_writable(dirname($pluginEntityPath))) { + $message = get_lang('ErrorCreatingDir').': '.$pluginEntityPath; + Display::addFlash(Display::return_message($message, 'error')); + + return false; + } + + mkdir($pluginEntityPath, api_get_permissions_for_new_directories()); } + + $fs = new Filesystem(); + $fs->mirror(__DIR__.'/Entity/', $pluginEntityPath, null, ['override']); + + $this->createPluginTables(); } /** @@ -68,8 +82,15 @@ class ImsLtiPlugin extends Plugin */ public function uninstall() { + $pluginEntityPath = $this->getEntityPath(); + $fs = new Filesystem(); + + if ($fs->exists($pluginEntityPath)) { + $fs->remove($pluginEntityPath); + } + try { - $this->clearDatabase(); + $this->dropPluginTables(); $this->removeTools(); } catch (DBALException $e) { error_log('Error while uninstalling IMS/LTI plugin: '.$e->getMessage()); @@ -81,7 +102,7 @@ class ImsLtiPlugin extends Plugin * @return boolean * @throws \Doctrine\DBAL\DBALException */ - private function setupDatabase() + private function createPluginTables() { $entityManager = Database::getManager(); $connection = $entityManager->getConnection(); @@ -99,7 +120,7 @@ class ImsLtiPlugin extends Plugin $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('custom_params', Type::TEXT)->setNotnull(false); $toolTable->addColumn('is_global', Type::BOOLEAN); $toolTable->setPrimaryKey(['id']); @@ -117,7 +138,7 @@ class ImsLtiPlugin extends Plugin * @return boolean * @throws \Doctrine\DBAL\DBALException */ - private function clearDatabase() + private function dropPluginTables() { $entityManager = Database::getManager(); $connection = $entityManager->getConnection(); @@ -166,14 +187,13 @@ class ImsLtiPlugin extends Plugin * Add the course tool * @param Course $course * @param ImsLtiTool $tool + * @throws \Doctrine\ORM\OptimisticLockException */ public function addCourseTool(Course $course, ImsLtiTool $tool) { $em = Database::getManager(); - $cToolId = AddCourse::generateToolId($course->getId()); $cTool = new CTool(); $cTool - ->setId($cToolId) ->setCId($course->getId()) ->setName($tool->getName()) ->setLink($this->get_name().'/start.php?'.http_build_query(['id' => $tool->getId()])) @@ -188,6 +208,11 @@ class ImsLtiPlugin extends Plugin $em->persist($cTool); $em->flush(); + + $cTool->setId($cTool->getIid()); + + $em->persist($cTool); + $em->flush(); } /** @@ -203,4 +228,12 @@ class ImsLtiPlugin extends Plugin return $text; } + + /** + * @return string + */ + public function getEntityPath() + { + return api_get_path(SYS_PATH).'src/Chamilo/PluginBundle/Entity/'.$this->getCamelCaseName(); + } } diff --git a/plugin/ims_lti/ImsLtiTool.php b/plugin/ims_lti/ImsLtiTool.php deleted file mode 100644 index 31865c83b4..0000000000 --- a/plugin/ims_lti/ImsLtiTool.php +++ /dev/null @@ -1,185 +0,0 @@ - - */ -class ImsLtiTool -{ - private $id = 0; - private $name = ''; - private $description = null; - private $launchUrl = ''; - private $consumerKey = ''; - private $sharedSecret = ''; - private $customParams = null; - private $isGlobal = false; - - public function getId() - { - return $this->id; - } - - public function getName() - { - return $this->name; - } - - public function getDescription() - { - return $this->description; - } - - public function getLaunchUrl() - { - return $this->launchUrl; - } - - public function getConsumerKey() - { - return $this->consumerKey; - } - - public function getSharedSecret() - { - return $this->sharedSecret; - } - - public function getCustomParams() - { - return $this->customParams; - } - - public function setId($id) - { - $this->id = $id; - - return $this; - } - - public function setName($name) - { - $this->name = $name; - - return $this; - } - - public function setDescription($description) - { - $this->description = $description; - - return $this; - } - - public function setLaunchUrl($launchUrl) - { - $this->launchUrl = $launchUrl; - - return $this; - } - - public function setConsumerKey($consumerKey) - { - $this->consumerKey = $consumerKey; - - return $this; - } - - public function setSharedSecret($sharedSecret) - { - $this->sharedSecret = $sharedSecret; - - return $this; - } - - public function setCustomParams($customParams) - { - $this->customParams = $customParams; - - return $this; - } - - 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, - $parameters, - ['id' => $this->id] - ); - - return; - } - - $this->id = Database::insert(ImsLtiPlugin::TABLE_TOOL, $parameters); - } - - public static function fetch($id) - { - $result = Database::select( - '*', - ImsLtiPlugin::TABLE_TOOL, - ['where' => [ - 'id = ?' => intval($id) - ]], - 'first' - ); - - if (empty($result)) { - return null; - } - - $tool = new self(); - $tool->id = $result['id']; - $tool->name = $result['name']; - $tool->description = $result['description']; - $tool->launchUrl = $result['launch_url']; - $tool->consumerKey = $result['consumer_key']; - $tool->sharedSecret = $result['shared_secret']; - $tool->customParams = $result['custom_params']; - $tool->isGlobal = (boolean) $result['is_global']; - - return $tool; - } - - public static function fetchAll() - { - return Database::select( - '*', - ImsLtiPlugin::TABLE_TOOL - ); - } - - public function parseCustomParams() - { - $strings = $this->customParams; - - $foo = explode('=', $strings); - - return [ - 'key' => 'custom_'.$foo[0], - 'value' => $foo[1] - ]; - } - - public function setIsGlobal($isGlobal = true) - { - $this->isGlobal = $isGlobal; - } - - public function isGlobal() - { - return $this->isGlobal; - } -} diff --git a/plugin/ims_lti/README.md b/plugin/ims_lti/README.md index d8f9c96f37..b8515c3dc8 100644 --- a/plugin/ims_lti/README.md +++ b/plugin/ims_lti/README.md @@ -1,6 +1,14 @@ IMS/LTI plugin === +Version 1.0 (beta) + +Installation +------------ +1. Install the plugin from Plugin page +2. Enable the plugin from Plugin Settings page +3. Assign to the Administrator region. + This plugin is meant to be later integrated into Chamilo (in a major version release). IMS/LTI defines the possibility to integrate tools or content into Chamilo. diff --git a/plugin/ims_lti/add.php b/plugin/ims_lti/add.php index 597a7780da..4be534257d 100644 --- a/plugin/ims_lti/add.php +++ b/plugin/ims_lti/add.php @@ -1,6 +1,9 @@ getRepository('ChamiloPluginBundle:ImsLti\ImsLtiTool'); -$type = isset($_GET['type']) ? intval($_GET['type']) : 0; +/** @var ImsLtiTool $baseTool */ +$baseTool = isset($_REQUEST['type']) ? $toolsRepo->find(intval($_REQUEST['type'])) : null; +/** @var Course $course */ $course = $em->find('ChamiloCoreBundle:Course', api_get_course_int_id()); -$tools = array_filter( - ImsLtiTool::fetchAll(), - function ($tool) { - return (boolean) $tool['is_global']; - } -); +$globalTools = $toolsRepo->findBy(['isGlobal' => true]); -$isGlobalTool = $type ? array_key_exists($type, $tools) : true; - -if (!$isGlobalTool) { +if ($baseTool && !$baseTool->isGlobal()) { Display::addFlash( Display::return_message($plugin->get_lang('ToolNotAvailable'), 'warning') ); @@ -31,16 +30,22 @@ if (!$isGlobalTool) { } $form = new FormValidator('ims_lti_add_tool'); -$form->addText('name', $plugin->get_lang('ToolName')); -if (!$type) { - $form->addHtml('
'.Security::remove_XSS($baseTool->getDescription()).'
'); +} + +$form->addText('name', get_lang('Title')); +$form->addTextarea('description', get_lang('Description'), ['rows' => 10]); + +if (!$baseTool) { $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('{{ tool.description }}
+{% endif %}