ContextualController.php 2.47 KB
Newer Older
1 2 3 4
<?php

namespace Drupal\contextual;

5
use Drupal\Component\Utility\Crypt;
6 7
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Render\RendererInterface;
8
use Drupal\Core\Site\Settings;
9
use Symfony\Component\DependencyInjection\ContainerInterface;
10 11 12 13 14 15 16
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

/**
 * Returns responses for Contextual module routes.
 */
17
class ContextualController implements ContainerInjectionInterface {
18

19 20
  /**
   * The renderer.
21
   *
22 23
   * @var \Drupal\Core\Render\RendererInterface
   */
24
  protected $renderer;
25 26

  /**
27
   * Constructors a new ContextualController.
28 29
   *
   * @param \Drupal\Core\Render\RendererInterface $renderer
30
   *   The renderer.
31 32 33 34 35 36 37 38 39 40 41 42 43
   */
  public function __construct(RendererInterface $renderer) {
    $this->renderer = $renderer;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('renderer')
    );
  }
44 45 46 47 48 49 50

  /**
   * Returns the requested rendered contextual links.
   *
   * Given a list of contextual links IDs, render them. Hence this must be
   * robust to handle arbitrary input.
   *
51 52
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The Symfony request object.
53 54 55
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   The JSON response.
56 57 58 59 60
   *
   * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
   *   Thrown when the request contains no ids.
   *
   * @see contextual_preprocess()
61 62 63 64 65 66 67
   */
  public function render(Request $request) {
    $ids = $request->request->get('ids');
    if (!isset($ids)) {
      throw new BadRequestHttpException(t('No contextual ids specified.'));
    }

68 69 70 71 72
    $tokens = $request->request->get('tokens');
    if (!isset($tokens)) {
      throw new BadRequestHttpException(t('No contextual ID tokens specified.'));
    }

73
    $rendered = [];
74
    foreach ($ids as $key => $id) {
75
      if (!isset($tokens[$key]) || !hash_equals($tokens[$key], Crypt::hmacBase64($id, Settings::getHashSalt() . \Drupal::service('private_key')->get()))) {
76 77
        throw new BadRequestHttpException('Invalid contextual ID specified.');
      }
78
      $element = [
79 80
        '#type' => 'contextual_links',
        '#contextual_links' => _contextual_id_to_links($id),
81
      ];
82
      $rendered[$id] = $this->renderer->renderRoot($element);
83 84 85 86 87 88
    }

    return new JsonResponse($rendered);
  }

}