subman-1.0.x-dev/src/Controller/SubmanWebhook.php
src/Controller/SubmanWebhook.php
<?php
namespace Drupal\subman\Controller;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\subman\Event\SubmanIncomingWebhook;
use Drupal\subman\Exception\SubmanWebhookException;
use Drupal\subman\SubmanUtilities;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* A class for catching a webhook and supplying its payload to the sync service.
*/
class SubmanWebhook extends ControllerBase
{
/**
* The event_dispatcher service.
*
* @var EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* Drupal\subman\SubmanUtilities definition.
*
* @var \Drupal\subman\SubmanUtilities
*/
protected $utils;
/**
* Constructs a new SubmanWebhook object.
*
* @param \Drupal\subman\SubmanUtilities $subman_utilities
* The subman utilities service.
* @param \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher $event_dispatcher
* The injected event_dispatcher service.
*/
public function __construct(SubmanUtilities $subman_utilities, EventDispatcherInterface $event_dispatcher)
{
$this->eventDispatcher = $event_dispatcher;
$this->utils = $subman_utilities;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container)
{
return new static(
$container->get('subman.utilities'),
$container->get('event_dispatcher')
);
}
/**
* Receives an incoming webhook and passes its payload to the sync service.
*
* @param string $service
* The service part of the webhook URL usable to describe the SaaS's name.
* @param string $webhook
* The webhook part of the webhook URL usable to describe the webhook type.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object which triggered the controller.
*
* @return \Symfony\Component\HttpFoundation\Response
* The response.
*/
public function receive(string $service, string $webhook, Request $request)
{
$status = 200;
$message = 'Data successfully received.';
// Extract payload.
$data_raw = $request->getContent();
if (empty($data_raw)) {
$data_raw = file_get_contents("php://input");
}
// Prepare a hash for this request just to be able to identify it in log
// messages.
$request_hash = substr(md5($data_raw), 0, 8) . '@' . date('H:i:s');
// Log receiving of webhook.
$this->utils->log(
'receive(): @service webhook @webhook received (start of @request_hash).',
$data_raw,
[
'@request_hash' => $request_hash,
'@service' => $service,
'@webhook' => $webhook,
'@status' => $status,
'@message' => $message,
],
$status == 200 ? 'debug' : 'error'
);
// Trigger SubmanIncomingWebhook event to let specific integration modules
// act upon the webhook.
try {
$data_json = Json::decode($data_raw);
$event = new SubmanIncomingWebhook($service, $webhook, $data_raw, $data_json);
$this->utils->dispatchEvent(SubmanIncomingWebhook::EVENT_NAME, $event);
} catch (SubmanWebhookException $exception) {
$status = $exception->getCode();
$message = $exception->getMessage();
}
// Log receiving of webhook.
$this->utils->log(
'receive(): @service webhook @webhook received (end of @request_hash): Responding with status @status and message "@message".',
$data_raw,
[
'@request_hash' => $request_hash,
'@service' => $service,
'@webhook' => $webhook,
'@status' => $status,
'@message' => $message,
], $status == 200 ? 'debug' : 'error'
);
// Return response.
return new Response($message, $status);
}
}
