ContextualController.php 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. <?php
  2. namespace Drupal\contextual;
  3. use Drupal\Component\Utility\Crypt;
  4. use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
  5. use Drupal\Core\Render\RendererInterface;
  6. use Drupal\Core\Site\Settings;
  7. use Symfony\Component\DependencyInjection\ContainerInterface;
  8. use Symfony\Component\HttpFoundation\JsonResponse;
  9. use Symfony\Component\HttpFoundation\Request;
  10. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  11. /**
  12. * Returns responses for Contextual module routes.
  13. */
  14. class ContextualController implements ContainerInjectionInterface {
  15. /**
  16. * The renderer.
  17. *
  18. * @var \Drupal\Core\Render\RendererInterface
  19. */
  20. protected $renderer;
  21. /**
  22. * Constructors a new ContextualController.
  23. *
  24. * @param \Drupal\Core\Render\RendererInterface $renderer
  25. * The renderer.
  26. */
  27. public function __construct(RendererInterface $renderer) {
  28. $this->renderer = $renderer;
  29. }
  30. /**
  31. * {@inheritdoc}
  32. */
  33. public static function create(ContainerInterface $container) {
  34. return new static(
  35. $container->get('renderer')
  36. );
  37. }
  38. /**
  39. * Returns the requested rendered contextual links.
  40. *
  41. * Given a list of contextual links IDs, render them. Hence this must be
  42. * robust to handle arbitrary input.
  43. *
  44. * @param \Symfony\Component\HttpFoundation\Request $request
  45. * The Symfony request object.
  46. *
  47. * @return \Symfony\Component\HttpFoundation\JsonResponse
  48. * The JSON response.
  49. *
  50. * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
  51. * Thrown when the request contains no ids.
  52. *
  53. * @see contextual_preprocess()
  54. */
  55. public function render(Request $request) {
  56. $ids = $request->request->get('ids');
  57. if (!isset($ids)) {
  58. throw new BadRequestHttpException(t('No contextual ids specified.'));
  59. }
  60. $tokens = $request->request->get('tokens');
  61. if (!isset($tokens)) {
  62. throw new BadRequestHttpException(t('No contextual ID tokens specified.'));
  63. }
  64. $rendered = [];
  65. foreach ($ids as $key => $id) {
  66. if (!isset($tokens[$key]) || !Crypt::hashEquals($tokens[$key], Crypt::hmacBase64($id, Settings::getHashSalt() . \Drupal::service('private_key')->get()))) {
  67. throw new BadRequestHttpException('Invalid contextual ID specified.');
  68. }
  69. $element = [
  70. '#type' => 'contextual_links',
  71. '#contextual_links' => _contextual_id_to_links($id),
  72. ];
  73. $rendered[$id] = $this->renderer->renderRoot($element);
  74. }
  75. return new JsonResponse($rendered);
  76. }
  77. }