DialogController.php 5.08 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

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenDialogCommand;
12
use Drupal\Core\Page\HtmlPage;
13
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\HttpFoundation\Response;
16 17 18 19

/**
 * Defines a default controller for dialog requests.
 */
20 21 22
class DialogController {

  /**
23
   * The controller resolver service.
24
   *
25
   * @var \Drupal\Core\Controller\ControllerResolverInterface
26
   */
27
  protected $controllerResolver;
28

29 30 31 32 33 34 35
  /**
   * The title resolver.
   *
   * @var \Drupal\Core\Controller\TitleResolver
   */
  protected $titleResolver;

36
  /**
37
   * Constructs a new DialogController.
38
   *
39 40
   * @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver
   *   The controller resolver service.
41 42
   * @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver
   *   The title resolver.
43
   */
44 45
  public function __construct(ControllerResolverInterface $controller_resolver, TitleResolverInterface $title_resolver) {
    $this->controllerResolver = $controller_resolver;
46
    $this->titleResolver = $title_resolver;
47
  }
48 49 50 51

  /**
   * Displays content in a modal dialog.
   *
52
   * @param \Symfony\Component\HttpFoundation\Request $request
53
   *   The request object.
54 55
   * @param mixed $_content
   *   A controller definition string, or a callable object/closure.
56 57 58 59
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   AjaxResponse to return the content wrapper in a modal dialog.
   */
60 61
  public function modal(Request $request, $_content) {
    return $this->dialog($request, $_content, TRUE);
62 63 64 65 66
  }

  /**
   * Displays content in a dialog.
   *
67
   * @param \Symfony\Component\HttpFoundation\Request $request
68
   *   The request object.
69 70
   * @param mixed $_content
   *   A controller definition string, or a callable object/closure.
71 72 73 74 75 76
   * @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.
   */
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
  public function dialog(Request $request, $_content, $modal = FALSE) {
    $page_content = $this->getContentResult($request, $_content);

    // Allow controllers to return a HtmlPage or a Response object directly.
    if ($page_content instanceof HtmlPage) {
      $page_content = $page_content->getContent();
    }
    if ($page_content instanceof Response) {
      $page_content = $page_content->getContent();
    }

    // Most controllers return a render array, but some return a string.
    if (!is_array($page_content)) {
      $page_content = array(
        '#markup' => $page_content,
      );
    }

    $content = drupal_render($page_content);

    // @todo Remove use of drupal_get_title() when
    //  http://drupal.org/node/1871596 is in.
    if (!$title = $this->titleResolver->getTitle($request, $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT))) {
      // @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']);
125 126
      }
      else {
127 128 129
        // Generate a target based on the route id.
        $route_name = $request->attributes->get(RouteObjectInterface::ROUTE_NAME);
        $target = '#' . drupal_html_id("drupal-dialog-$route_name");
130 131
      }
    }
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
    $response->addCommand(new OpenDialogCommand($target, $title, $content, $options));
    return $response;
  }

  /**
   * Returns the result of invoking the sub-controller.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   * @param mixed $controller_definition
   *   A controller definition string, or a callable object/closure.
   *
   * @return mixed
   *   The result of invoking the controller. Render arrays, strings, HtmlPage,
   *   and HtmlFragment objects are possible.
   */
  public function getContentResult(Request $request, $controller_definition) {
    if ($controller_definition instanceof \Closure) {
      $callable = $controller_definition;
    }
    else {
      $callable = $this->controllerResolver->getControllerFromDefinition($controller_definition);
    }
    $arguments = $this->controllerResolver->getArguments($request, $callable);
    $page_content = call_user_func_array($callable, $arguments);

    return $page_content;
159
  }
160

161
}