Beispiel #1
0
 /**
  * {@inheritdoc}
  */
 public function renderResponse(array $main_content, Request $request, RouteMatchInterface $route_match)
 {
     $json = [];
     $json['content'] = (string) $this->renderer->renderRoot($main_content);
     if (!empty($main_content['#title'])) {
         $json['title'] = (string) $main_content['#title'];
     } else {
         $json['title'] = (string) $this->titleResolver->getTitle($request, $route_match->getRouteObject());
     }
     $response = new CacheableJsonResponse($json, 200);
     $response->addCacheableDependency(CacheableMetadata::createFromRenderArray($main_content));
     return $response;
 }
 /**
  * Converts a render array into an HtmlFragment object.
  *
  * @param array|\Drupal\Core\Page\HtmlFragmentInterface|\Symfony\Component\HttpFoundation\Response $page_content
  *   The page content area to display.
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request object.
  *
  * @return \Drupal\Core\Page\HtmlPage
  *   A page object.
  *
  * @throws \InvalidArgumentException
  *   Thrown if the controller returns a string.
  */
 protected function createHtmlFragment($page_content, Request $request)
 {
     // Allow controllers to return a HtmlFragment or a Response object directly.
     if ($page_content instanceof HtmlFragment || $page_content instanceof Response) {
         return $page_content;
     }
     if (is_string($page_content)) {
         throw new \InvalidArgumentException('_content controllers are not allowed to return strings. You can return a render array, a html fragment or a response object.');
     }
     $fragment = $this->renderHtmlRenderer->render($page_content);
     if (!$fragment->getTitle() && ($route = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT))) {
         $fragment->setTitle($this->titleResolver->getTitle($request, $route), Title::PASS_THROUGH);
     }
     return $fragment;
 }
 /**
  * Converts a render array into an HtmlFragment object.
  *
  * @param array|string $page_content
  *   The page content area to display.
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request object.
  *
  * @return \Drupal\Core\Page\HtmlPage
  *   A page object.
  */
 protected function createHtmlFragment($page_content, Request $request)
 {
     // Allow controllers to return a HtmlFragment or a Response object directly.
     if ($page_content instanceof HtmlFragment || $page_content instanceof Response) {
         return $page_content;
     }
     if (!is_array($page_content)) {
         $page_content = ['#markup' => $page_content];
     }
     $fragment = $this->renderHtmlRenderer->render($page_content);
     if (!$fragment->getTitle() && ($route = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT))) {
         $fragment->setTitle($this->titleResolver->getTitle($request, $route), Title::PASS_THROUGH);
     }
     return $fragment;
 }
Beispiel #4
0
 /**
  * Processes a successful controller into an HTTP 200 response.
  *
  * Some controllers may not return a response object but simply the body of
  * one.  The VIEW event is called in that case, to allow us to mutate that
  * body into a Response object.  In particular we assume that the return
  * from an JSON-type response is a JSON string, so just wrap it into a
  * Response object.
  *
  * @param Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent $event
  *   The Event to process.
  */
 public function onView(GetResponseForControllerResultEvent $event)
 {
     $request = $event->getRequest();
     // For a master request, we process the result and wrap it as needed.
     // For a subrequest, all we want is the string value.  We assume that
     // is just an HTML string from a controller, so wrap that into a response
     // object.  The subrequest's response will get dissected and placed into
     // the larger page as needed.
     if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) {
         $method = 'on' . $this->negotiation->getContentType($request);
         if (method_exists($this, $method)) {
             $event->setResponse($this->{$method}($event));
         } else {
             $event->setResponse(new Response('Not Acceptable', 406));
         }
     } else {
         // This is a new-style Symfony-esque subrequest, which means we assume
         // the body is not supposed to be a complete page but just a page
         // fragment.
         $page_result = $event->getControllerResult();
         if ($page_result instanceof HtmlPage || $page_result instanceof Response) {
             return $page_result;
         }
         if (!is_array($page_result)) {
             $page_result = array('#markup' => $page_result);
         }
         // If no title was returned fall back to one defined in the route.
         if (!isset($page_result['#title'])) {
             $page_result['#title'] = $this->titleResolver->getTitle($request, $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT));
         }
         $event->setResponse(new Response(drupal_render_root($page_result)));
     }
 }
 /**
  * Prepares the HTML body: wraps the main content in #type 'page'.
  *
  * @param array $main_content
  *   The render array representing the main content.
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request object, for context.
  * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  *   The route match, for context.
  *
  * @return array
  *   An array with two values:
  *   0. A #type 'page' render array.
  *   1. The page title.
  *
  * @throws \LogicException
  *   If the selected display variant does not implement PageVariantInterface.
  */
 protected function prepare(array $main_content, Request $request, RouteMatchInterface $route_match)
 {
     // If the _controller result already is #type => page,
     // we have no work to do: The "main content" already is an entire "page"
     // (see html.html.twig).
     if (isset($main_content['#type']) && $main_content['#type'] === 'page') {
         $page = $main_content;
     } else {
         // Select the page display variant to be used to render this main content,
         // default to the built-in "simple page".
         $event = new PageDisplayVariantSelectionEvent('simple_page', $route_match);
         $this->eventDispatcher->dispatch(RenderEvents::SELECT_PAGE_DISPLAY_VARIANT, $event);
         $variant_id = $event->getPluginId();
         // We must render the main content now already, because it might provide a
         // title. We set its $is_root_call parameter to FALSE, to ensure
         // placeholders are not yet replaced. This is essentially "pre-rendering"
         // the main content, the "full rendering" will happen in
         // ::renderResponse().
         // @todo Remove this once https://www.drupal.org/node/2359901 lands.
         if (!empty($main_content)) {
             $this->renderer->executeInRenderContext(new RenderContext(), function () use(&$main_content) {
                 if (isset($main_content['#cache']['keys'])) {
                     // Retain #title, otherwise, dynamically generated titles would be
                     // missing for controllers whose entire returned render array is
                     // render cached.
                     $main_content['#cache_properties'][] = '#title';
                 }
                 return $this->renderer->render($main_content, FALSE);
             });
             $main_content = $this->renderCache->getCacheableRenderArray($main_content) + ['#title' => isset($main_content['#title']) ? $main_content['#title'] : NULL];
         }
         // Instantiate the page display, and give it the main content.
         $page_display = $this->displayVariantManager->createInstance($variant_id);
         if (!$page_display instanceof PageVariantInterface) {
             throw new \LogicException('Cannot render the main content for this page because the provided display variant does not implement PageVariantInterface.');
         }
         $page_display->setMainContent($main_content)->setConfiguration($event->getPluginConfiguration());
         // Generate a #type => page render array using the page display variant,
         // the page display will build the content for the various page regions.
         $page = array('#type' => 'page');
         $page += $page_display->build();
     }
     // $page is now fully built. Find all non-empty page regions, and add a
     // theme wrapper function that allows them to be consistently themed.
     $regions = \Drupal::theme()->getActiveTheme()->getRegions();
     foreach ($regions as $region) {
         if (!empty($page[$region])) {
             $page[$region]['#theme_wrappers'][] = 'region';
             $page[$region]['#region'] = $region;
         }
     }
     // Allow hooks to add attachments to $page['#attached'].
     $this->invokePageAttachmentHooks($page);
     // Determine the title: use the title provided by the main content if any,
     // otherwise get it from the routing information.
     $title = isset($main_content['#title']) ? $main_content['#title'] : $this->titleResolver->getTitle($request, $route_match->getRouteObject());
     return [$page, $title];
 }
Beispiel #6
0
 /**
  * {@inheritdoc}
  */
 public function renderResponse(array $main_content, Request $request, RouteMatchInterface $route_match)
 {
     $response = new AjaxResponse();
     // First render the main content, because it might provide a title.
     $content = drupal_render_root($main_content);
     // Attach the library necessary for using the OpenDialogCommand and set the
     // attachments for this Ajax response.
     $main_content['#attached']['library'][] = 'core/drupal.dialog.ajax';
     $response->setAttachments($main_content['#attached']);
     // Determine the title: use the title provided by the main content if any,
     // otherwise get it from the routing information.
     $title = isset($main_content['#title']) ? $main_content['#title'] : $this->titleResolver->getTitle($request, $route_match->getRouteObject());
     // Determine the dialog options and the target for the OpenDialogCommand.
     $options = $request->request->get('dialogOptions', array());
     $target = $this->determineTargetSelector($options, $route_match);
     $response->addCommand(new OpenDialogCommand($target, $title, $content, $options));
     return $response;
 }
 /**
  * {@inheritdoc}
  */
 public function blockContents()
 {
     $sharethis_config = $this->configFactory->get('sharethis.settings');
     $config = $this->configFactory->get('system.site');
     if ($sharethis_config->get('location') == 'block') {
         // First Get all of the options for sharethis widget from database.
         $data_options = $this->getOptions();
         $current_path = \Drupal::routeMatch()->getRouteName() ? Url::fromRouteMatch(\Drupal::routeMatch())->getInternalPath() : '';
         $path = isset($current_path) ? $current_path : '<front>';
         global $base_url;
         $path_obj = Url::fromUri($base_url . '/' . $path, array('absolute' => TRUE));
         $m_path = $path_obj->toString();
         $request = \Drupal::request();
         $route_match = \Drupal::routeMatch();
         $mtitle = $this->titleResolver->getTitle($request, $route_match->getRouteObject());
         $m_title = is_object($mtitle) ? $mtitle->getUntranslatedString() : $config->get('name');
         return $this->renderSpans($data_options, $m_title, $m_path);
     }
 }
 /**
  * {@inheritdoc}
  */
 public function render(array $output, $status_code = 200)
 {
     if (!isset($output['#title'])) {
         $output['#title'] = $this->titleResolver->getTitle(\Drupal::request(), \Drupal::routeMatch()->getRouteObject());
     }
     $page = new HtmlPage('', isset($output['#cache']) ? $output['#cache'] : array(), $output['#title']);
     $page_array = drupal_prepare_page($output);
     $page = $this->fragmentRenderer->preparePage($page, $page_array);
     $page->setBodyTop(drupal_render($page_array['page_top']));
     $page->setBodyBottom(drupal_render($page_array['page_bottom']));
     $page->setContent(drupal_render($page_array));
     $page->setStatusCode($status_code);
     return $page;
 }
 /**
  * Tests the breadcrumb for a user path.
  *
  * @covers ::build()
  * @covers ::getRequestForPath()
  */
 public function testBuildWithUserPath()
 {
     $this->context->expects($this->once())->method('getPathInfo')->will($this->returnValue('/user/1/edit'));
     $this->setupStubPathProcessor();
     $route_1 = new Route('/user/1');
     $this->requestMatcher->expects($this->exactly(1))->method('matchRequest')->will($this->returnCallback(function (Request $request) use($route_1) {
         if ($request->getPathInfo() == '/user/1') {
             return array(RouteObjectInterface::ROUTE_NAME => 'user_page', RouteObjectInterface::ROUTE_OBJECT => $route_1, '_raw_variables' => new ParameterBag(array()));
         }
     }));
     $this->setupAccessManagerToAllow();
     $this->titleResolver->expects($this->once())->method('getTitle')->with($this->anything(), $route_1)->will($this->returnValue('Admin'));
     $links = $this->builder->build($this->getMock('Drupal\\Core\\Routing\\RouteMatchInterface'));
     $this->assertEquals(array(0 => new Link('Home', new Url('<front>')), 1 => new Link('Admin', new Url('user_page'))), $links);
 }
 /**
  * {@inheritdoc}
  */
 public function build(RouteMatchInterface $route_match)
 {
     $breadcrumb = new Breadcrumb();
     $links = array();
     // General path-based breadcrumbs. Use the actual request path, prior to
     // resolving path aliases, so the breadcrumb can be defined by simply
     // creating a hierarchy of path aliases.
     $path = trim($this->context->getPathInfo(), '/');
     $path_elements = explode('/', $path);
     $exclude = array();
     // Don't show a link to the front-page path.
     $front = $this->config->get('page.front');
     $exclude[$front] = TRUE;
     // /user is just a redirect, so skip it.
     // @todo Find a better way to deal with /user.
     $exclude['/user'] = TRUE;
     // Because this breadcrumb builder is entirely path-based, vary by the
     // 'url.path' cache context.
     $breadcrumb->addCacheContexts(['url.path']);
     while (count($path_elements) > 1) {
         array_pop($path_elements);
         // Copy the path elements for up-casting.
         $route_request = $this->getRequestForPath('/' . implode('/', $path_elements), $exclude);
         if ($route_request) {
             $route_match = RouteMatch::createFromRequest($route_request);
             $access = $this->accessManager->check($route_match, $this->currentUser, NULL, TRUE);
             // The set of breadcrumb links depends on the access result, so merge
             // the access result's cacheability metadata.
             $breadcrumb = $breadcrumb->addCacheableDependency($access);
             if ($access->isAllowed()) {
                 $title = $this->titleResolver->getTitle($route_request, $route_match->getRouteObject());
                 if (!isset($title)) {
                     // Fallback to using the raw path component as the title if the
                     // route is missing a _title or _title_callback attribute.
                     $title = str_replace(array('-', '_'), ' ', Unicode::ucfirst(end($path_elements)));
                 }
                 $url = Url::fromRouteMatch($route_match);
                 $links[] = new Link($title, $url);
             }
         }
     }
     if ($path && '/' . $path != $front) {
         // Add the Home link, except for the front page.
         $links[] = Link::createFromRoute($this->t('Home'), '<front>');
     }
     return $breadcrumb->setLinks(array_reverse($links));
 }
 /**
  * {@inheritdoc}
  */
 public function build(RouteMatchInterface $route_match)
 {
     $links = array();
     // General path-based breadcrumbs. Use the actual request path, prior to
     // resolving path aliases, so the breadcrumb can be defined by simply
     // creating a hierarchy of path aliases.
     $path = trim($this->context->getPathInfo(), '/');
     $path_elements = explode('/', $path);
     $exclude = array();
     // Don't show a link to the front-page path.
     $front = $this->config->get('page.front');
     $exclude[$front] = TRUE;
     // /user is just a redirect, so skip it.
     // @todo Find a better way to deal with /user.
     $exclude['user'] = TRUE;
     while (count($path_elements) > 1) {
         array_pop($path_elements);
         // Copy the path elements for up-casting.
         $route_request = $this->getRequestForPath(implode('/', $path_elements), $exclude);
         if ($route_request) {
             $route_name = $route_request->attributes->get(RouteObjectInterface::ROUTE_NAME);
             // Note that the parameters don't really matter here since we're
             // passing in the request which already has the upcast attributes.
             $parameters = array();
             $access = $this->accessManager->checkNamedRoute($route_name, $parameters, $this->currentUser, $route_request);
             if ($access) {
                 $title = $this->titleResolver->getTitle($route_request, $route_request->attributes->get(RouteObjectInterface::ROUTE_OBJECT));
             }
             if ($access) {
                 if (!isset($title)) {
                     // Fallback to using the raw path component as the title if the
                     // route is missing a _title or _title_callback attribute.
                     $title = str_replace(array('-', '_'), ' ', Unicode::ucfirst(end($path_elements)));
                 }
                 // @todo Replace with a #type => link render element so that the alter
                 // hook can work with the actual data.
                 $links[] = $this->l($title, $route_request->attributes->get(RouteObjectInterface::ROUTE_NAME), $route_request->attributes->get('_raw_variables')->all(), array('html' => TRUE));
             }
         }
     }
     if ($path && $path != $front) {
         // Add the Home link, except for the front page.
         $links[] = $this->l($this->t('Home'), '<front>');
     }
     return array_reverse($links);
 }
 /**
  * Tests the breadcrumb for a user path.
  *
  * @covers ::build()
  * @covers ::getRequestForPath()
  */
 public function testBuildWithUserPath()
 {
     $this->context->expects($this->once())->method('getPathInfo')->will($this->returnValue('/user/1/edit'));
     $this->setupStubPathProcessor();
     $route_1 = new Route('/user/1');
     $this->requestMatcher->expects($this->exactly(1))->method('matchRequest')->will($this->returnCallback(function (Request $request) use($route_1) {
         if ($request->getPathInfo() == '/user/1') {
             return array(RouteObjectInterface::ROUTE_NAME => 'user_page', RouteObjectInterface::ROUTE_OBJECT => $route_1, '_raw_variables' => new ParameterBag(array()));
         }
     }));
     $link_user = '******';
     $link_front = '<a href="/">Home</a>';
     $this->linkGenerator->expects($this->at(0))->method('generate')->with('Admin', 'user_page', array(), array('html' => TRUE))->will($this->returnValue($link_user));
     $this->linkGenerator->expects($this->at(1))->method('generate')->with('Home', '<front>', array(), array())->will($this->returnValue($link_front));
     $this->setupAccessManagerWithTrue();
     $this->titleResolver->expects($this->once())->method('getTitle')->with($this->anything(), $route_1)->will($this->returnValue('Admin'));
     $links = $this->builder->build($this->getMock('Drupal\\Core\\Routing\\RouteMatchInterface'));
     $this->assertEquals(array(0 => '<a href="/">Home</a>', 1 => $link_user), $links);
 }
Beispiel #13
0
 /**
  * Builds a table row for the system modules page.
  *
  * @param array $modules
  *   The list existing modules.
  * @param \Drupal\Core\Extension\Extension $module
  *   The module for which to build the form row.
  * @param $distribution
  *
  * @return array
  *   The form row for the given module.
  */
 protected function buildRow(array $modules, Extension $module, $distribution)
 {
     // Set the basic properties.
     $row['#required'] = array();
     $row['#requires'] = array();
     $row['#required_by'] = array();
     $row['name']['#markup'] = $module->info['name'];
     $row['description']['#markup'] = $this->t($module->info['description']);
     $row['version']['#markup'] = $module->info['version'];
     // Generate link for module's help page, if there is one.
     $row['links']['help'] = array();
     if ($this->moduleHandler->moduleExists('help') && $module->status && in_array($module->getName(), $this->moduleHandler->getImplementations('help'))) {
         if ($this->moduleHandler->invoke($module->getName(), 'help', array('help.page.' . $module->getName(), $this->routeMatch))) {
             $row['links']['help'] = array('#type' => 'link', '#title' => $this->t('Help'), '#url' => Url::fromRoute('help.page', ['name' => $module->getName()]), '#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => $this->t('Help'))));
         }
     }
     // Generate link for module's permission, if the user has access to it.
     $row['links']['permissions'] = array();
     if ($module->status && \Drupal::currentUser()->hasPermission('administer permissions') && in_array($module->getName(), $this->moduleHandler->getImplementations('permission'))) {
         $row['links']['permissions'] = array('#type' => 'link', '#title' => $this->t('Permissions'), '#url' => Url::fromRoute('user.admin_permissions'), '#options' => array('fragment' => 'module-' . $module->getName(), 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => $this->t('Configure permissions'))));
     }
     // Generate link for module's configuration page, if it has one.
     $row['links']['configure'] = array();
     if ($module->status && isset($module->info['configure'])) {
         $route_parameters = isset($module->info['configure_parameters']) ? $module->info['configure_parameters'] : array();
         if ($this->accessManager->checkNamedRoute($module->info['configure'], $route_parameters, $this->currentUser)) {
             $links = $this->menuLinkManager->loadLinksByRoute($module->info['configure']);
             /** @var \Drupal\Core\Menu\MenuLinkInterface $link */
             $link = reset($links);
             // Most configure links have a corresponding menu link, though some just
             // have a route.
             if ($link) {
                 $description = $link->getDescription();
             } else {
                 $request = new Request();
                 $request->attributes->set('_route_name', $module->info['configure']);
                 $route_object = $this->routeProvider->getRouteByName($module->info['configure']);
                 $request->attributes->set('_route', $route_object);
                 $request->attributes->add($route_parameters);
                 $description = $this->titleResolver->getTitle($request, $route_object);
             }
             $row['links']['configure'] = array('#type' => 'link', '#title' => $this->t('Configure'), '#url' => Url::fromRoute($module->info['configure'], $route_parameters), '#options' => array('attributes' => array('class' => array('module-link', 'module-link-configure'), 'title' => $description)));
         }
     }
     // Present a checkbox for installing and indicating the status of a module.
     $row['enable'] = array('#type' => 'checkbox', '#title' => $this->t('Install'), '#default_value' => (bool) $module->status, '#disabled' => (bool) $module->status);
     // Disable the checkbox for required modules.
     if (!empty($module->info['required'])) {
         // Used when displaying modules that are required by the installation profile
         $row['enable']['#disabled'] = TRUE;
         $row['#required_by'][] = $distribution . (!empty($module->info['explanation']) ? ' (' . $module->info['explanation'] . ')' : '');
     }
     // Check the compatibilities.
     $compatible = TRUE;
     // Initialize an empty array of reasons why the module is incompatible. Add
     // each reason as a separate element of the array.
     $reasons = array();
     // Check the core compatibility.
     if ($module->info['core'] != \Drupal::CORE_COMPATIBILITY) {
         $compatible = FALSE;
         $reasons[] = $this->t('This version is not compatible with Drupal !core_version and should be replaced.', array('!core_version' => \Drupal::CORE_COMPATIBILITY));
     }
     // Ensure this module is compatible with the currently installed version of PHP.
     if (version_compare(phpversion(), $module->info['php']) < 0) {
         $compatible = FALSE;
         $required = $module->info['php'] . (substr_count($module->info['php'], '.') < 2 ? '.*' : '');
         $reasons[] = $this->t('This module requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $required, '!php_version' => phpversion()));
     }
     // If this module is not compatible, disable the checkbox.
     if (!$compatible) {
         $status = implode(' ', $reasons);
         $row['enable']['#disabled'] = TRUE;
         $row['description']['#markup'] = $status;
         $row['#attributes']['class'][] = 'incompatible';
     }
     // If this module requires other modules, add them to the array.
     foreach ($module->requires as $dependency => $version) {
         if (!isset($modules[$dependency])) {
             $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">missing</span>)', array('@module' => Unicode::ucfirst($dependency)));
             $row['enable']['#disabled'] = TRUE;
         } elseif (empty($modules[$dependency]->hidden)) {
             $name = $modules[$dependency]->info['name'];
             // Disable the module's checkbox if it is incompatible with the
             // dependency's version.
             if ($incompatible_version = drupal_check_incompatibility($version, str_replace(\Drupal::CORE_COMPATIBILITY . '-', '', $modules[$dependency]->info['version']))) {
                 $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">incompatible with</span> version @version)', array('@module' => $name . $incompatible_version, '@version' => $modules[$dependency]->info['version']));
                 $row['enable']['#disabled'] = TRUE;
             } elseif ($modules[$dependency]->info['core'] != \Drupal::CORE_COMPATIBILITY) {
                 $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">incompatible with</span> this version of Drupal core)', array('@module' => $name));
                 $row['enable']['#disabled'] = TRUE;
             } elseif ($modules[$dependency]->status) {
                 $row['#requires'][$dependency] = $this->t('@module', array('@module' => $name));
             } else {
                 $row['#requires'][$dependency] = $this->t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $name));
             }
         }
     }
     // If this module is required by other modules, list those, and then make it
     // impossible to disable this one.
     foreach ($module->required_by as $dependent => $version) {
         if (isset($modules[$dependent]) && empty($modules[$dependent]->info['hidden'])) {
             if ($modules[$dependent]->status == 1 && $module->status == 1) {
                 $row['#required_by'][$dependent] = $this->t('@module', array('@module' => $modules[$dependent]->info['name']));
                 $row['enable']['#disabled'] = TRUE;
             } else {
                 $row['#required_by'][$dependent] = $this->t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $modules[$dependent]->info['name']));
             }
         }
     }
     return $row;
 }