upgrade
This commit is contained in:
172
plugin/userremoteservice/Entity/UserRemoteService.php
Normal file
172
plugin/userremoteservice/Entity/UserRemoteService.php
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
namespace Chamilo\PluginBundle\UserRemoteService;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* UserRemoteService.
|
||||
*
|
||||
* @ORM\Table(name="plugin_user_remote_service")
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class UserRemoteService
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="title", type="string", length=255, nullable=false)
|
||||
*/
|
||||
protected $title;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="url", type="string", length=255, nullable=false)
|
||||
*/
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*
|
||||
* @return UserRemoteService
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getURL()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @return UserRemoteService
|
||||
*/
|
||||
public function setURL($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAccessURL($pluginName)
|
||||
{
|
||||
$accessUrl = api_get_path(WEB_PLUGIN_PATH).$pluginName."/redirect.php?serviceId=".$this->getId();
|
||||
|
||||
return $accessUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a user-specific URL, with two extra query string parameters : 'username' and 'hash'.
|
||||
* 'hash' is generated using $salt and $userId.
|
||||
*
|
||||
* @param string $username the URL query parameter 'username'
|
||||
* @param string $userId the user identifier, to build the hash
|
||||
* @param string $salt the salt, to build the hash
|
||||
*
|
||||
* @throws Exception on hash generation failure
|
||||
*
|
||||
* @return string the custom user URL
|
||||
*/
|
||||
public function getCustomUserURL($username, $userId, $salt)
|
||||
{
|
||||
$hash = password_hash($salt.$userId, PASSWORD_BCRYPT);
|
||||
if (false === $hash) {
|
||||
throw new Exception('hash generation failed');
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'%s%s%s',
|
||||
$this->url,
|
||||
false === strpos($this->url, '?') ? '?' : '&',
|
||||
http_build_query(
|
||||
[
|
||||
'username' => $username,
|
||||
'hash' => $hash,
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a user-specific URL, with two extra query string parameters : 'uid' and 'hash'.
|
||||
* 'hash' is generated using $salt and $userId.
|
||||
*
|
||||
* @param string $userId the user identifier, to build the hash and to include for the uid parameter
|
||||
* @param string $salt the salt, to build the hash
|
||||
*
|
||||
* @throws Exception on hash generation failure
|
||||
*
|
||||
* @return string the custom user redirect URL
|
||||
*/
|
||||
public function getCustomUserRedirectURL($userId, $salt)
|
||||
{
|
||||
$hash = password_hash($salt.$userId, PASSWORD_BCRYPT);
|
||||
if (false === $hash) {
|
||||
throw new Exception('hash generation failed');
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'%s%s%s',
|
||||
$this->url,
|
||||
false === strpos($this->url, '?') ? '?' : '&',
|
||||
http_build_query(
|
||||
[
|
||||
'uid' => $userId,
|
||||
'hash' => $hash,
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
10
plugin/userremoteservice/README.md
Normal file
10
plugin/userremoteservice/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
User Remote Service Plugin
|
||||
==========================
|
||||
|
||||
Appends site-specific iframe-targeted user-identifying links to the menu bar.
|
||||
You can also hide the link from the menu and use the redirect link to use it as a link in a course.
|
||||
|
||||
After activation, configure a __salt__ then select region __menu_administrator__.
|
||||
|
||||
In the __Administration__ menu, in block __Plugins__,
|
||||
you will find a link __User Remote Services__ to manage the services in the main menu (title and URL) and also get the redirect URL to use in a course.
|
||||
18
plugin/userremoteservice/admin.php
Normal file
18
plugin/userremoteservice/admin.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/config.php';
|
||||
|
||||
api_protect_admin_script(true);
|
||||
|
||||
$plugin = UserRemoteServicePlugin::create();
|
||||
|
||||
Display::display_header($plugin->get_title());
|
||||
|
||||
echo $plugin->getCreationForm()->returnForm();
|
||||
|
||||
echo $plugin->getDeletionForm()->returnForm();
|
||||
|
||||
echo $plugin->getServiceHTMLTable();
|
||||
|
||||
Display::display_footer();
|
||||
4
plugin/userremoteservice/config.php
Normal file
4
plugin/userremoteservice/config.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/../../main/inc/global.inc.php';
|
||||
16
plugin/userremoteservice/iframe.php
Normal file
16
plugin/userremoteservice/iframe.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/config.php';
|
||||
|
||||
if (!api_user_is_login()) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
$plugin = UserRemoteServicePlugin::create();
|
||||
|
||||
Display::display_header();
|
||||
|
||||
echo $plugin->getIFrame();
|
||||
|
||||
Display::display_footer();
|
||||
10
plugin/userremoteservice/index.php
Normal file
10
plugin/userremoteservice/index.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/config.php';
|
||||
|
||||
if ('true' !== UserRemoteServicePlugin::create()->get_hide_link_from_navigation_menu()) {
|
||||
foreach (UserRemoteServicePlugin::create()->getNavigationMenu() as $key => $menu) {
|
||||
$template->params['menu'][$key] = $menu;
|
||||
}
|
||||
}
|
||||
6
plugin/userremoteservice/install.php
Normal file
6
plugin/userremoteservice/install.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/config.php';
|
||||
|
||||
UserRemoteServicePlugin::create()->install();
|
||||
24
plugin/userremoteservice/lang/english.php
Normal file
24
plugin/userremoteservice/lang/english.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
$strings['plugin_title'] = 'User Remote Services';
|
||||
$strings['plugin_comment'] = 'Appends site-specific iframe-targeted user-identifying links to the menu bar.';
|
||||
|
||||
$strings['salt'] = 'Salt';
|
||||
$strings['salt_help'] =
|
||||
'Secret character string, used to generate the <em>hash</em> URL parameter. The longest, the best.
|
||||
<br/>Remote user services can check the generated URL authenticity with the following PHP expression :
|
||||
<br/><code class="php">password_verify($salt.$userId, $hash)</code>
|
||||
<br/>Where
|
||||
<br/><code>$salt</code> is this input value,
|
||||
<br/><code>$userId</code> is the number of the user referenced by the <em>username</em> URL parameter value and
|
||||
<br/><code>$hash</code> contains the <em>hash</em> URL parameter value.';
|
||||
$strings['hide_link_from_navigation_menu'] = 'hide links from the menu';
|
||||
|
||||
// Please keep alphabetically sorted
|
||||
$strings['CreateService'] = 'Add service to menu bar';
|
||||
$strings['DeleteServices'] = 'Remove services from menu bar';
|
||||
$strings['ServicesToDelete'] = 'Services to remove from menu bar';
|
||||
$strings['ServiceTitle'] = 'Service title';
|
||||
$strings['ServiceURL'] = 'Service web site location (URL)';
|
||||
$strings['RedirectAccessURL'] = "URL to use in Chamilo to redirect user to the service (URL)";
|
||||
26
plugin/userremoteservice/lang/french.php
Normal file
26
plugin/userremoteservice/lang/french.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
$strings['plugin_title'] = "Services distants pour l'utilisateur";
|
||||
$strings['plugin_comment'] =
|
||||
"Ajoute à la barre de menu des liens spécifiques qui identifient l'utilisateur et qui s'ouvrent dans une iframe.";
|
||||
|
||||
/* Strings for settings */
|
||||
$strings['salt'] = "Sel";
|
||||
$strings['salt_help'] =
|
||||
'Chaine de caractère secrète, utilisée pour générer le paramètre d\'URL <em>hash</em>. Plus il est long et mieux c\'est.
|
||||
<br/>Les services distants peuvent vérifier la validité de l\'URL générée avec l\'expression PHP suivante :
|
||||
<br/><code class="php">password_verify($salt.$userId, $hash)</code>
|
||||
<br/>Où
|
||||
<br/><code>$salt</code> est la valeur saisie ici,
|
||||
<br/><code>$userId</code> est le numéro de l\'utilisateur auquel fait référence le paramètre d\'URL <em>username</em> et
|
||||
<br/><code>$hash</code> représente la valeur du paramètre d\'URL <em>hash</em>.';
|
||||
$strings['hide_link_from_navigation_menu'] = 'Masquer les liens dans le menu';
|
||||
|
||||
// Please keep alphabetically sorted
|
||||
$strings['CreateService'] = "Ajouter le service au menu";
|
||||
$strings['DeleteServices'] = "Retirer les services du menu";
|
||||
$strings['ServicesToDelete'] = "Services à retirer du menu";
|
||||
$strings['ServiceTitle'] = "Titre du service";
|
||||
$strings['ServiceURL'] = "Adresse web du service (URL)";
|
||||
$strings['RedirectAccessURL'] = "Adresse à utiliser pour rediriger l'utilisateur au service (URL)";
|
||||
6
plugin/userremoteservice/plugin.php
Normal file
6
plugin/userremoteservice/plugin.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/config.php';
|
||||
|
||||
$plugin_info = UserRemoteServicePlugin::create()->get_info();
|
||||
13
plugin/userremoteservice/redirect.php
Normal file
13
plugin/userremoteservice/redirect.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/config.php';
|
||||
|
||||
if (!api_user_is_login()) {
|
||||
api_not_allowed(true);
|
||||
}
|
||||
|
||||
$plugin = UserRemoteServicePlugin::create();
|
||||
|
||||
header('Location: '.$plugin->getActiveServiceSpecificUserUrl());
|
||||
exit;
|
||||
@@ -0,0 +1,309 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use Chamilo\PluginBundle\UserRemoteService\UserRemoteService;
|
||||
use Doctrine\ORM\OptimisticLockException;
|
||||
|
||||
class UserRemoteServicePlugin extends Plugin
|
||||
{
|
||||
public const TABLE = 'plugin_user_remote_service';
|
||||
|
||||
/**
|
||||
* UserRemoteServicePlugin constructor.
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
parent::__construct(
|
||||
'1.0',
|
||||
'Sébastien Ducoulombier',
|
||||
[
|
||||
'salt' => 'text',
|
||||
'hide_link_from_navigation_menu' => 'boolean',
|
||||
]
|
||||
);
|
||||
$this->isAdminPlugin = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches and returns a single instance.
|
||||
*
|
||||
* @return UserRemoteServicePlugin
|
||||
*/
|
||||
public static function create()
|
||||
{
|
||||
static $result = null;
|
||||
|
||||
return $result ? $result : $result = new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the plugin table.
|
||||
*/
|
||||
public function install()
|
||||
{
|
||||
Database::query(
|
||||
sprintf(
|
||||
'create table if not exists %s (
|
||||
id int unsigned not null auto_increment primary key,
|
||||
title varchar(255) not null,
|
||||
url varchar(255) not null
|
||||
)',
|
||||
Database::get_main_table(self::TABLE)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the plugin table.
|
||||
*/
|
||||
public function uninstall()
|
||||
{
|
||||
Database::query('drop table if exists '.Database::get_main_table(self::TABLE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the salt setting
|
||||
*/
|
||||
public function salt()
|
||||
{
|
||||
return $this->get('salt');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool the value of hide_link_from_navigation_menu setting
|
||||
*/
|
||||
public function get_hide_link_from_navigation_menu()
|
||||
{
|
||||
return $this->get('hide_link_from_navigation_menu');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of all services.
|
||||
*
|
||||
* @return UserRemoteService[]
|
||||
*/
|
||||
public function getServices()
|
||||
{
|
||||
return Database::getManager()->getRepository(
|
||||
'Chamilo\PluginBundle\UserRemoteService\UserRemoteService'
|
||||
)->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new service.
|
||||
*
|
||||
* @param string $title
|
||||
* @param string $url
|
||||
*
|
||||
* @throws OptimisticLockException
|
||||
*/
|
||||
public function addService($title, $url)
|
||||
{
|
||||
$service = new UserRemoteService();
|
||||
$service->setTitle($title);
|
||||
$service->setURL($url);
|
||||
Database::getManager()->persist($service);
|
||||
Database::getManager()->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a service.
|
||||
*
|
||||
* @param UserRemoteService $service
|
||||
*
|
||||
* @throws OptimisticLockException
|
||||
*/
|
||||
public function removeService($service)
|
||||
{
|
||||
Database::getManager()->remove($service);
|
||||
Database::getManager()->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a service.
|
||||
*
|
||||
* @param UserRemoteService $service
|
||||
*
|
||||
* @throws OptimisticLockException
|
||||
*/
|
||||
public function updateService($service)
|
||||
{
|
||||
Database::getManager()->persist($service);
|
||||
Database::getManager()->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the active service id.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getActiveServiceId()
|
||||
{
|
||||
return array_key_exists('serviceId', $_REQUEST) ? intval($_REQUEST['serviceId']) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the menu items to be appended to the navigation array.
|
||||
*
|
||||
* @see \return_navigation_array
|
||||
*
|
||||
* @return array menu items
|
||||
*/
|
||||
public function getNavigationMenu()
|
||||
{
|
||||
$menu = [];
|
||||
$activeServiceId = $this->getActiveServiceId();
|
||||
foreach ($this->getServices() as $service) {
|
||||
$key = 'service_'.$service->getId();
|
||||
$current = $service->getId() == $activeServiceId;
|
||||
$menu[$key] = [
|
||||
'key' => $key,
|
||||
'current' => $current ? 'active' : '',
|
||||
'url' => sprintf(
|
||||
'%s%s/iframe.php?serviceId=%d',
|
||||
api_get_path(WEB_PLUGIN_PATH),
|
||||
$this->get_name(),
|
||||
$service->getId()
|
||||
),
|
||||
'title' => $service->getTitle(),
|
||||
];
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates and handles submission of the creation form.
|
||||
*
|
||||
* @throws OptimisticLockException
|
||||
*
|
||||
* @return FormValidator
|
||||
*/
|
||||
public function getCreationForm()
|
||||
{
|
||||
$form = new FormValidator('creationForm');
|
||||
$titleText = $form->addText('title', get_lang('ServiceTitle'));
|
||||
$urlText = $form->addText('url', get_lang('ServiceURL'));
|
||||
$form->addButtonCreate(get_lang('CreateService'));
|
||||
if ($form->validate()) {
|
||||
$this->addService($titleText->getValue(), $urlText->getValue());
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates and handles submission of the service deletion form.
|
||||
*
|
||||
* @throws OptimisticLockException
|
||||
*
|
||||
* @return FormValidator
|
||||
*/
|
||||
public function getDeletionForm()
|
||||
{
|
||||
$form = new FormValidator('deletionForm');
|
||||
$services = $this->getServices();
|
||||
$options = [];
|
||||
foreach ($services as $service) {
|
||||
$options[$service->getId()] = $service->getTitle();
|
||||
}
|
||||
$serviceIdSelect = $form->addSelect('serviceId', get_lang('ServicesToDelete'), $options);
|
||||
$serviceIdSelect->setMultiple(true);
|
||||
$form->addButtonDelete(get_lang('DeleteServices'));
|
||||
if ($form->validate()) {
|
||||
foreach ($serviceIdSelect->getValue() as $serviceId) {
|
||||
foreach ($services as $service) {
|
||||
if ($service->getId() == $serviceId) {
|
||||
$this->removeService($service);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the service HTML table.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceHTMLTable()
|
||||
{
|
||||
$html = '';
|
||||
$services = $this->getServices();
|
||||
if (!empty($services)) {
|
||||
$table = new HTML_Table('class="table"');
|
||||
$table->addRow(
|
||||
[
|
||||
get_lang('ServiceTitle'),
|
||||
get_lang('ServiceURL'),
|
||||
get_lang('RedirectAccessURL'),
|
||||
],
|
||||
null,
|
||||
'th'
|
||||
);
|
||||
foreach ($services as $service) {
|
||||
$table->addRow([
|
||||
$service->getTitle(),
|
||||
$service->getURL(),
|
||||
$service->getAccessURL($this->get_name()),
|
||||
]);
|
||||
}
|
||||
$html = $table->toHtml();
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves one service.
|
||||
*
|
||||
* @param int $id the service identifier
|
||||
*
|
||||
* @return UserRemoteService the service
|
||||
*/
|
||||
public function getService($id)
|
||||
{
|
||||
return Database::getManager()->getRepository(
|
||||
'Chamilo\PluginBundle\UserRemoteService\UserRemoteService'
|
||||
)->find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the iframe HTML element to load a service URL.
|
||||
*
|
||||
* @throws Exception on hash generation failure
|
||||
*
|
||||
* @return string the iframe HTML element
|
||||
*/
|
||||
public function getIFrame()
|
||||
{
|
||||
$userInfo = api_get_user_info();
|
||||
|
||||
return sprintf(
|
||||
'<div class="embed-responsive embed-responsive-16by9">
|
||||
<iframe class="embed-responsive-item" src="%s"></iframe>
|
||||
</div>',
|
||||
$this->getService(
|
||||
$this->getActiveServiceId()
|
||||
)->getCustomUserURL($userInfo['username'], $userInfo['id'], $this->salt())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the redirect user specific URL for redirection.
|
||||
*
|
||||
* @throws Exception on hash generation failure
|
||||
*
|
||||
* @return string the specific user redirect URL
|
||||
*/
|
||||
public function getActiveServiceSpecificUserUrl()
|
||||
{
|
||||
$userInfo = api_get_user_info();
|
||||
|
||||
return $this->getService(
|
||||
$this->getActiveServiceId()
|
||||
)->getCustomUserRedirectURL($userInfo['id'], $this->salt());
|
||||
}
|
||||
}
|
||||
6
plugin/userremoteservice/uninstall.php
Normal file
6
plugin/userremoteservice/uninstall.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
require_once __DIR__.'/config.php';
|
||||
|
||||
UserRemoteServicePlugin::create()->uninstall();
|
||||
Reference in New Issue
Block a user