DialogController.php 4.53 KB
Newer Older
1 2 3 4
<?php

/**
 * @file
5
 * Contains \Drupal\core\Controller\DialogController.
6 7
 */

8
namespace Drupal\core\Controller;
9 10 11 12

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenDialogCommand;
use Symfony\Component\HttpFoundation\Request;
13
use Symfony\Component\HttpKernel\HttpKernelInterface;
14 15 16 17

/**
 * Defines a default controller for dialog requests.
 */
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
class DialogController {

  /**
   * The HttpKernel object to use for subrequests.
   *
   * @var \Symfony\Component\HttpKernel\HttpKernelInterface
   */
  protected $httpKernel;

  /**
   * Constructs a new HtmlPageController.
   *
   * @param \Symfony\Component\HttpKernel\HttpKernelInterface $kernel
   */
  public function __construct(HttpKernelInterface $kernel) {
    $this->httpKernel = $kernel;
  }
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

  /**
   * Forwards request to a subrequest.
   *
   * @param \Symfony\Component\HttpFoundation\RequestRequest $request
   *   The request object.
   * @param callable $content
   *   The body content callable that contains the body region of this page.
   *
   * @return \Symfony\Component\HttpFoundation\Response
   *   A response object.
   */
  protected function forward(Request $request, $content) {
    // @todo When we have a Generator, we can replace the forward() call with
    // a render() call, which would handle ESI and hInclude as well.  That will
    // require an _internal route.  For examples, see:
    // https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing/internal.xml
    // https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Controller/InternalController.php
    $attributes = clone $request->attributes;
    // We need to clean up the derived information and such so that the
    // subrequest can be processed properly without leaking data through.
    $attributes->remove('system_path');

    // Remove the accept header so the subrequest does not end up back in this
    // controller.
    $request->headers->remove('accept');

62
    return $this->httpKernel->forward($content, $attributes->all(), $request->query->all());
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
  }

  /**
   * Displays content in a modal dialog.
   *
   * @param \Symfony\Component\HttpFoundation\RequestRequest $request
   *   The request object.
   * @param callable $_content
   *   The body content callable that contains the body region of this page.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   AjaxResponse to return the content wrapper in a modal dialog.
   */
  public function modal(Request $request, $_content) {
    return $this->dialog($request, $_content, TRUE);
  }

  /**
   * Displays content in a dialog.
   *
   * @param \Symfony\Component\HttpFoundation\RequestRequest $request
   *   The request object.
   * @param callable $_content
   *   The body content callable that contains the body region of this page.
   * @param bool $modal
   *   (optional) TRUE to render a modal dialog. Defaults to FALSE.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   AjaxResponse to return the content wrapper in a dialog.
   */
  public function dialog(Request $request, $_content, $modal = FALSE) {
    $subrequest = $this->forward($request, $_content);
    if ($subrequest->isOk()) {
      $content = $subrequest->getContent();
      // @todo Remove use of drupal_get_title() when
      //  http://drupal.org/node/1871596 is in.
      $title = drupal_get_title();
      $response = new AjaxResponse();
      // Fetch any modal options passed in from data-dialog-options.
      if (!($options = $request->request->get('dialogOptions'))) {
        $options = array();
      }
      // Set modal flag and re-use the modal ID.
      if ($modal) {
        $options['modal'] = TRUE;
        $target = '#drupal-modal';
      }
      else {
        // Generate the target wrapper for the dialog.
        if (isset($options['target'])) {
          // If the target was nominated in the incoming options, use that.
          $target = $options['target'];
          // Ensure the target includes the #.
          if (substr($target, 0, 1) != '#') {
            $target = '#' . $target;
          }
          // This shouldn't be passed on to jQuery.ui.dialog.
          unset($options['target']);
        }
        else {
          // Generate a target based on the controller.
          $target = '#drupal-dialog-' . drupal_html_id(drupal_clean_css_identifier(drupal_strtolower($_content)));
        }
      }
      $response->addCommand(new OpenDialogCommand($target, $title, $content, $options));
      return $response;
    }
    // An error occurred in the subrequest, return that.
    return $subrequest;
  }
}