wayfinding-2.1.x-dev/src/Controller/Wayfinding.php
src/Controller/Wayfinding.php
<?php
namespace Drupal\wayfinding\Controller;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Render\AttachmentsInterface;
use Drupal\Core\Render\HtmlResponse;
use Drupal\Core\Render\HtmlResponseAttachmentsProcessor;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\wayfinding\Query;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\Writer\PngWriter;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Provides the Device controller.
*/
class Wayfinding implements ContainerInjectionInterface {
use StringTranslationTrait;
/**
* The query services.
*
* @var \Drupal\wayfinding\Query
*/
protected Query $query;
/**
* The html response attachment processor.
*
* @var \Drupal\Core\Render\HtmlResponseAttachmentsProcessor
*/
protected HtmlResponseAttachmentsProcessor $attachmentProcessor;
/**
* The configuration.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
protected ImmutableConfig $config;
/**
* The request.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected Request $request;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected EntityTypeManagerInterface $entityTypeManager;
/**
* Device constructor.
*
* @param \Drupal\wayfinding\Query $query
* The query services.
* @param \Drupal\Core\Render\HtmlResponseAttachmentsProcessor $attachment_processor
* The html response attachment processor.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
final public function __construct(Query $query, HtmlResponseAttachmentsProcessor $attachment_processor, ConfigFactoryInterface $config_factory, RequestStack $request_stack, EntityTypeManagerInterface $entity_type_manager) {
$this->query = $query;
$this->attachmentProcessor = $attachment_processor;
$this->config = $config_factory->get('wayfinding.settings');
$this->request = $request_stack->getCurrentRequest();
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): Wayfinding {
return new static(
$container->get('wayfinding.query'),
$container->get('html_response.attachments_processor'),
$container->get('config.factory'),
$container->get('request_stack'),
$container->get('entity_type.manager')
);
}
/**
* Tbd.
*
* @return \Drupal\Core\Access\AccessResultInterface
* Tbd.
*/
public function access(): AccessResultInterface {
return AccessResult::allowed();
}
/**
* Tbd.
*
* @return \Drupal\Core\Access\AccessResultInterface
* Tbd.
*/
public function accessWidgets(): AccessResultInterface {
$data = $this->request->query->get('data');
if ($data === NULL) {
return AccessResult::forbidden('No data provided.');
}
try {
json_decode($data, TRUE, 512, JSON_THROW_ON_ERROR);
}
catch (\JsonException) {
return AccessResult::forbidden('Invalid json data provided.');
}
return AccessResult::allowed();
}
/**
* Tbd.
*
* @return \Drupal\Core\Render\AttachmentsInterface
* Tbd.
*/
public function request(): AttachmentsInterface {
return $this->deliver(0);
}
/**
* Tbd.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* Tbd.
*/
public function popup(): AjaxResponse {
$output = $this->query->build(TRUE, 0);
$response = new AjaxResponse();
$response->addCommand(new HtmlCommand('#wayfinding-popup .wayfinding-popup-content', $output));
return $response;
}
/**
* Tbd.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* Tbd.
*
* @throws \JsonException
*/
public function widgets(): AjaxResponse {
// Provided data has already been verified in the access control.
// @see ::accessWidget().
$data = json_decode($this->request->query->get('data'), TRUE, 512, JSON_THROW_ON_ERROR);
$response = new AjaxResponse();
// Build route widgets.
if (!empty($data['position']['lat']) && !empty($data['position']['lng']) && $this->config->get('enable qr code')) {
$routeWidgets = '';
foreach ($data['destinations'] as $destination) {
if (!empty($destination['lat']) && !empty($destination['lng'])) {
$url = 'https://www.google.com/maps/dir/' . $data['position']['lat'] . ',' . $data['position']['lng'] . '/' . $destination['lat'] . ',' . $destination['lng'];
$qrCode = new QrCode($url);
$writer = new PngWriter();
$image = '<img alt="Open route in Google Maps" src="data:image/png;base64,' . base64_encode($writer->write($qrCode)->getString()) . '">';
if ($data['routeAsLink']) {
$routeWidgets .= '<a href="' . $url . '">' . $image . '</a>';
}
else {
$routeWidgets .= $image;
}
}
}
if (!empty($routeWidgets)) {
$response->addCommand(new HtmlCommand('#wayfinding .widgets .widget.route', $routeWidgets));
$response->addCommand(new InvokeCommand('#wayfinding .widgets .widget.route', 'addClass', ['show']));
}
}
return $response;
}
/**
* Tbd.
*
* @param float $perspective
* Tbd.
* @param float $lat
* Tbd.
* @param float $lng
* Tbd.
* @param int $did
* Tbd.
* @param string $eid
* Tbd.
*
* @return \Drupal\Core\Render\AttachmentsInterface
* Tbd.
*/
protected function deliver(float $perspective, float $lat = 0, float $lng = 0, int $did = 0, string $eid = 'undefined'): AttachmentsInterface {
$html_response = new HtmlResponse();
$html_response->setContent($this->query->build(FALSE, $perspective, $lat, $lng, $did, $eid));
return $this->attachmentProcessor->processAttachments($html_response);
}
}
