Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Plugin: External notification connect - refs BT#20443
- Loading branch information
Showing
14 changed files
with
717 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# External Notification Connect | ||
|
||
Activate external notification system |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?php | ||
|
||
/* For licensing terms, see /license.txt */ | ||
|
||
ExternalNotificationConnectPlugin::create()->install(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
/* For licensing terms, see /license.txt */ | ||
|
||
$strings['plugin_title'] = 'External Notification Connect'; | ||
$strings['plugin_comment'] = 'Activate external notification system'; | ||
|
||
$strings['tool_enable'] = 'Enabled'; | ||
$strings['auth_url'] = 'Authentication endpoint'; | ||
$strings['auth_url_help'] = 'URL for authentication API'; | ||
$strings['auth_username'] = 'Username for authentication'; | ||
$strings['auth_password'] = 'Password for authentication'; | ||
$strings['notification_url'] = 'Notification endpoint'; | ||
$strings['notification_url_help'] = 'URL for notification API'; | ||
$strings['notify_portfolio'] = 'Portfolio'; | ||
$strings['notify_portfolio_help'] = 'Put it to <i>Yes</i> to activate external notification for Portfolio tool actions'; | ||
$strings['notify_learnpath'] = 'Learning path'; | ||
$strings['notify_learnpath_help'] = 'Put it to <i>Yes</i> to activate external notification for learning path creation'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
/* For licensing terms, see /license.txt */ | ||
|
||
$strings['plugin_title'] = 'Conexión de notificación externa'; | ||
$strings['plugin_comment'] = 'Activar un sistema de notificaciones externo'; | ||
|
||
$strings['tool_enable'] = 'Activado'; | ||
$strings['auth_url'] = 'Punto de conexión de autenticación'; | ||
$strings['auth_url_help'] = 'URL para API de autenticación'; | ||
$strings['auth_username'] = 'Nombre de usuario para autenticación'; | ||
$strings['auth_password'] = 'Contraseña para autenticación'; | ||
$strings['notification_url'] = 'Punto de conexión de la notificación'; | ||
$strings['notification_url_help'] = 'URL para la API de notificación'; | ||
$strings['notify_portfolio'] = 'Portafolio'; | ||
$strings['notify_portfolio_help'] = 'Ponerlo a <i>Sí</i> para activar la notificación externa para las acciones de la herramienta Portafolio'; | ||
$strings['notify_learnpath'] = 'Lecciones'; | ||
$strings['notify_learnpath_help'] = 'Ponerlo a <i>Sí</i> para activar la notificación externa para la creación de lecciones'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?php | ||
|
||
/* For licensing terms, see /license.txt */ | ||
|
||
$plugin_info = ExternalNotificationConnectPlugin::create()->get_info(); |
71 changes: 71 additions & 0 deletions
71
plugin/externalnotificationconnect/src/Entity/AccessToken.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<?php | ||
|
||
/* For licensing terms, see /license.txt */ | ||
|
||
namespace Chamilo\PluginBundle\ExternalNotificationConnect\Entity; | ||
|
||
use Doctrine\ORM\Mapping as ORM; | ||
|
||
/** | ||
* @ORM\Table(name="plugin_ext_notif_conn_access_token") | ||
* @ORM\Entity() | ||
*/ | ||
class AccessToken | ||
{ | ||
/** | ||
* @var int | ||
* | ||
* @ORM\Id() | ||
* @ORM\GeneratedValue(strategy="IDENTITY") | ||
* @ORM\Column(name="id", type="integer") | ||
*/ | ||
private $id; | ||
/** | ||
* @var string | ||
* | ||
* @ORM\Column(name="access_token", type="text") | ||
*/ | ||
private $token; | ||
/** | ||
* @var bool | ||
* | ||
* @ORM\Column(name="is_valid", type="boolean") | ||
*/ | ||
private $isValid; | ||
|
||
public function getId(): int | ||
{ | ||
return $this->id; | ||
} | ||
|
||
public function setId(int $id): AccessToken | ||
{ | ||
$this->id = $id; | ||
|
||
return $this; | ||
} | ||
|
||
public function getToken(): string | ||
{ | ||
return $this->token; | ||
} | ||
|
||
public function setToken(string $token): AccessToken | ||
{ | ||
$this->token = $token; | ||
|
||
return $this; | ||
} | ||
|
||
public function isValid(): bool | ||
{ | ||
return $this->isValid; | ||
} | ||
|
||
public function setIsValid(bool $isValid): AccessToken | ||
{ | ||
$this->isValid = $isValid; | ||
|
||
return $this; | ||
} | ||
} |
234 changes: 234 additions & 0 deletions
234
plugin/externalnotificationconnect/src/ExternalNotificationConnectPlugin.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
<?php | ||
|
||
/* For licensing terms, see /license.txt */ | ||
|
||
use Chamilo\PluginBundle\ExternalNotificationConnect\Entity\AccessToken; | ||
use Doctrine\ORM\Tools\SchemaTool; | ||
use Doctrine\ORM\Tools\ToolsException; | ||
use Firebase\JWT\JWT; | ||
use GuzzleHttp\Client; | ||
use GuzzleHttp\Exception\ClientException; | ||
use GuzzleHttp\Exception\GuzzleException; | ||
use GuzzleHttp\Exception\ServerException; | ||
|
||
class ExternalNotificationConnectPlugin extends Plugin implements HookPluginInterface | ||
{ | ||
public const SETTING_AUTH_URL = 'auth_url'; | ||
public const SETTING_AUTH_USERNAME = 'auth_username'; | ||
public const SETTING_AUTH_PASSWORD = 'auth_password'; | ||
public const SETTING_NOTIFICATION_URL = 'notification_url'; | ||
public const SETTING_NOTIFY_PORTFOLIO = 'notify_portfolio'; | ||
public const SETTING_NOTIFY_LEARNPATH = 'notify_learnpath'; | ||
|
||
protected function __construct() | ||
{ | ||
$author = [ | ||
'Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>', | ||
]; | ||
|
||
$settings = [ | ||
'tool_enable' => 'boolean', | ||
self::SETTING_AUTH_URL => 'text', | ||
self::SETTING_AUTH_USERNAME => 'text', | ||
self::SETTING_AUTH_PASSWORD => 'text', | ||
self::SETTING_NOTIFICATION_URL => 'text', | ||
self::SETTING_NOTIFY_PORTFOLIO => 'boolean', | ||
self::SETTING_NOTIFY_LEARNPATH => 'boolean', | ||
]; | ||
|
||
parent::__construct( | ||
'1.0', | ||
implode('; ', $author), | ||
$settings | ||
); | ||
} | ||
|
||
public static function create(): ?ExternalNotificationConnectPlugin | ||
{ | ||
static $result = null; | ||
|
||
return $result ?: $result = new self(); | ||
} | ||
|
||
public function performActionsAfterConfigure(): ExternalNotificationConnectPlugin | ||
{ | ||
$portfolioItemAddedEvent = HookPortfolioItemAdded::create(); | ||
$portfolioItemEditedEvent = HookPortfolioItemEdited::create(); | ||
$portfolioItemDeletedEvent = HookPortfolioItemDeleted::create(); | ||
|
||
$portfolioItemAddedObserver = ExternalNotificationConnectPortfolioItemAddedHookObserver::create(); | ||
$portfolioItemEditedObserver = ExternalNotificationConnectPortfolioItemEditedHookObserver::create(); | ||
$portfolioItemDeletedObserver = ExternalNotificationConnectPortfolioItemDeletedHookObserver::create(); | ||
|
||
if ('true' === $this->get(self::SETTING_NOTIFY_PORTFOLIO)) { | ||
$portfolioItemAddedEvent->attach($portfolioItemAddedObserver); | ||
$portfolioItemEditedEvent->attach($portfolioItemEditedObserver); | ||
$portfolioItemDeletedEvent->attach($portfolioItemDeletedObserver); | ||
} else { | ||
$portfolioItemAddedEvent->detach($portfolioItemAddedObserver); | ||
$portfolioItemEditedEvent->detach($portfolioItemEditedObserver); | ||
$portfolioItemDeletedEvent->detach($portfolioItemDeletedObserver); | ||
} | ||
|
||
$lpCreatedEvent = HookLearningPathCreated::create(); | ||
|
||
$lpCreatedObserver = ExternalNotificationConnectLearningPathCreatedHookObserver::create(); | ||
|
||
if ('true' === $this->get(self::SETTING_NOTIFY_LEARNPATH)) { | ||
$lpCreatedEvent->attach($lpCreatedObserver); | ||
} else { | ||
$lpCreatedEvent->detach($lpCreatedObserver); | ||
} | ||
|
||
return $this; | ||
} | ||
|
||
public function installHook() | ||
{ | ||
} | ||
|
||
public function uninstallHook() | ||
{ | ||
$portfolioItemAddedEvent = HookPortfolioItemAdded::create(); | ||
$portfolioItemEditedEvent = HookPortfolioItemEdited::create(); | ||
$portfolioItemDeletedEvent = HookPortfolioItemDeleted::create(); | ||
$lpCreatedEvent = HookLearningPathCreated::create(); | ||
|
||
$portfolioItemAddedObserver = ExternalNotificationConnectPortfolioItemAddedHookObserver::create(); | ||
$portfolioItemEditedObserver = ExternalNotificationConnectPortfolioItemEditedHookObserver::create(); | ||
$portfolioItemDeletedObserver = ExternalNotificationConnectPortfolioItemDeletedHookObserver::create(); | ||
$lpCreatedObserver = ExternalNotificationConnectLearningPathCreatedHookObserver::create(); | ||
|
||
$portfolioItemAddedEvent->detach($portfolioItemAddedObserver); | ||
$portfolioItemEditedEvent->detach($portfolioItemEditedObserver); | ||
$portfolioItemDeletedEvent->detach($portfolioItemDeletedObserver); | ||
$lpCreatedEvent->detach($lpCreatedObserver); | ||
} | ||
|
||
public function install() | ||
{ | ||
$em = Database::getManager(); | ||
|
||
$schemaManager = $em->getConnection()->getSchemaManager(); | ||
|
||
$tableExists = $schemaManager->tablesExist(['plugin_ext_notif_conn_access_token']); | ||
|
||
if ($tableExists) { | ||
return; | ||
} | ||
|
||
$this->installDBTables(); | ||
$this->installHook(); | ||
} | ||
|
||
public function uninstall() | ||
{ | ||
$this->uninstallHook(); | ||
$this->uninstallDBTables(); | ||
} | ||
|
||
/** | ||
* @throws \Doctrine\ORM\OptimisticLockException | ||
* @throws \Doctrine\ORM\ORMException | ||
* @throws Exception | ||
*/ | ||
public function getAccessToken() | ||
{ | ||
$em = Database::getManager(); | ||
$tokenRepository = $em->getRepository(AccessToken::class); | ||
|
||
$accessToken = $tokenRepository->findOneBy(['isValid' => true]); | ||
|
||
if (!$accessToken) { | ||
$newToken = $this->requestAuthToken(); | ||
|
||
$accessToken = (new AccessToken()) | ||
->setToken($newToken) | ||
->setIsValid(true); | ||
|
||
$em->persist($accessToken); | ||
$em->flush(); | ||
} else { | ||
$tks = explode('.', $accessToken->getToken()); | ||
|
||
$payload = json_decode(JWT::urlsafeB64Decode($tks[1]), true); | ||
|
||
if (time() >= $payload['exp']) { | ||
$accessToken->setIsValid(false); | ||
|
||
$newToken = $this->requestAuthToken(); | ||
|
||
$accessToken = (new AccessToken()) | ||
->setToken($newToken) | ||
->setIsValid(true); | ||
|
||
$em->persist($accessToken); | ||
|
||
$em->flush(); | ||
} | ||
} | ||
|
||
return $accessToken->getToken(); | ||
} | ||
|
||
private function installDBTables() | ||
{ | ||
$em = Database::getManager(); | ||
|
||
try { | ||
(new SchemaTool($em)) | ||
->createSchema([ | ||
$em->getClassMetadata(AccessToken::class), | ||
]); | ||
} catch (ToolsException $e) { | ||
return; | ||
} | ||
} | ||
|
||
private function uninstallDBTables() | ||
{ | ||
$em = Database::getManager(); | ||
|
||
(new SchemaTool($em)) | ||
->dropSchema([ | ||
$em->getClassMetadata(AccessToken::class), | ||
]); | ||
} | ||
|
||
/** | ||
* @throws Exception | ||
*/ | ||
private function requestAuthToken(): string | ||
{ | ||
$client = new Client(); | ||
|
||
try { | ||
$response = $client->request( | ||
'POST', | ||
$this->get(ExternalNotificationConnectPlugin::SETTING_AUTH_URL), | ||
[ | ||
'json' => [ | ||
'email' => $this->get(ExternalNotificationConnectPlugin::SETTING_AUTH_USERNAME), | ||
'password' => $this->get(ExternalNotificationConnectPlugin::SETTING_AUTH_PASSWORD), | ||
], | ||
] | ||
); | ||
} catch (ClientException|ServerException $e) { | ||
if (!$e->hasResponse()) { | ||
throw new Exception($e->getMessage()); | ||
} | ||
|
||
$response = $e->getResponse(); | ||
} catch (GuzzleException $e) { | ||
throw new Exception($e->getMessage()); | ||
} | ||
|
||
$json = json_decode((string) $response->getBody(), true); | ||
|
||
if (201 !== $json['status']) { | ||
throw new Exception($json['message']); | ||
} | ||
|
||
return $json['data']['data']['token']; | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
plugin/externalnotificationconnect/src/Hook/ExternalNotificationConnectHookObserver.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
/* For licensing terms, see /license.txt */ | ||
|
||
abstract class ExternalNotificationConnectHookObserver extends HookObserver | ||
{ | ||
/** | ||
* @var ExternalNotificationConnectPlugin | ||
*/ | ||
protected $plugin; | ||
|
||
protected function __construct() | ||
{ | ||
parent::__construct( | ||
'plugin/externalnotificationconnect/src/ExternalNotificationConnectPlugin.php', | ||
'externalnotificationconnect' | ||
); | ||
|
||
$this->plugin = ExternalNotificationConnectPlugin::create(); | ||
} | ||
} |
Oops, something went wrong.