diff --git a/core/includes/common.inc b/core/includes/common.inc
index 5a90646..d59c936 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -2809,6 +2809,17 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) {
$current->postRenderCache = NestedArray::mergeDeep($current->postRenderCache, $parent->postRenderCache);
$stack->push($current);
};
+ /** @var \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver */
+ $controller_resolver = \Drupal::service('controller_resolver');
+ if (isset($elements['#access_callback'])) {
+ if (is_string($elements['#access_callback']) && strpos($elements['#access_callback'], '::') === FALSE) {
+ $callable = $controller_resolver->getControllerFromDefinition($elements['#access_callback']);
+ }
+ else {
+ $callable = $elements['#access_callback'];
+ }
+ $elements['#access'] = call_user_func($callable, $elements);
+ }
// Early-return nothing if user does not have access.
if (empty($elements) || (isset($elements['#access']) && !$elements['#access'])) {
@@ -2856,8 +2867,6 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) {
// Make any final changes to the element before it is rendered. This means
// that the $element or the children can be altered or corrected before the
// element is rendered into the final text.
- /** @var \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver */
- $controller_resolver = \Drupal::service('controller_resolver');
if (isset($elements['#pre_render'])) {
foreach ($elements['#pre_render'] as $callable) {
if (is_string($callable) && strpos($callable, '::') === FALSE) {
diff --git a/core/lib/Drupal/Core/Access/AccessManagerInterface.php b/core/lib/Drupal/Core/Access/AccessManagerInterface.php
index df88ba6..1f8fc6d 100644
--- a/core/lib/Drupal/Core/Access/AccessManagerInterface.php
+++ b/core/lib/Drupal/Core/Access/AccessManagerInterface.php
@@ -45,7 +45,7 @@
* @param array $parameters
* Optional array of values to substitute into the route path patern.
* @param \Drupal\Core\Session\AccountInterface $account
- * The current user.
+ * Run access checks for this account. Defaults to the current user.
* @param \Symfony\Component\HttpFoundation\Request $route_request
* Optional incoming request object. If not provided, one will be built
* using the route information and the current request from the container.
diff --git a/core/lib/Drupal/Core/Routing/RouteMatch.php b/core/lib/Drupal/Core/Routing/RouteMatch.php
index 0a66610..8b29958 100644
--- a/core/lib/Drupal/Core/Routing/RouteMatch.php
+++ b/core/lib/Drupal/Core/Routing/RouteMatch.php
@@ -159,7 +159,7 @@ public function createUrlObject(array $options = array()) {
/**
* {@inheritdoc}
*/
- public function access(AccountInterface $account) {
+ public function access(AccountInterface $account = NULL) {
return $this->getAccessManager()->checkNamedRoute($this->getRouteName(), $this->getRawParameters()->all(), $account);
}
diff --git a/core/lib/Drupal/Core/Routing/RouteMatchInterface.php b/core/lib/Drupal/Core/Routing/RouteMatchInterface.php
index ad51db1..35944f8 100644
--- a/core/lib/Drupal/Core/Routing/RouteMatchInterface.php
+++ b/core/lib/Drupal/Core/Routing/RouteMatchInterface.php
@@ -87,12 +87,12 @@ public function getRawParameters();
* Determines whether the route is accessible or not.
*
* @param \Drupal\Core\Session\AccountInterface $account
- * The current user.
+ * Run access checks for this account. Defaults to the current user.
*
* @return bool
* Returns TRUE if the user has access to the route, otherwise FALSE.
*/
- public function access(AccountInterface $account);
+ public function access(AccountInterface $account = NULL);
/**
* Creates a Url object from this route match.
diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php
index 368551e..e8eb800 100644
--- a/core/lib/Drupal/Core/Url.php
+++ b/core/lib/Drupal/Core/Url.php
@@ -388,6 +388,7 @@ public function toRenderArray() {
'#route_name' => $this->getRouteName(),
'#route_parameters' => $this->getRouteParameters(),
'#options' => $this->getOptions(),
+ '#access_callback' => array(get_class(), 'renderAccess'),
);
}
}
@@ -419,19 +420,32 @@ public function getInternalPath() {
* Determines whether the route is accessible or not.
*
* @param \Drupal\Core\Session\AccountInterface $account
- * The current user.
+ * Run access checks for this account. Defaults to the current user.
*
* @return bool
* Returns TRUE if the user has access to the url, otherwise FALSE.
*/
- public function access(AccountInterface $account) {
- return $this->getAccessManager()->checkNamedRoute($this->getRouteName(), $this->getRouteParameters(), $account);
+ public function access(AccountInterface $account = NULL) {
+ return $account->hasPermission('link to any page') || $this->accessManager()->checkNamedRoute($this->getRouteName(), $this->getRouteParameters(), $account);
+ }
+
+ /**
+ * Checks a Url render element against applicable access check services.
+ *
+ * @param array $element
+ * A render element as returned from \Drupal\Core\Url::toRenderArray().
+ *
+ * @return bool
+ * Returns TRUE if the current user has access to the url, otherwise FALSE.
+ */
+ public static function renderAccess(array $element) {
+ return (new static($element['#route_name'], $element['#route_parameters'], $element['#options']))->access();
}
/**
* @return \Drupal\Core\Access\AccessManagerInterface
*/
- protected function getAccessManager() {
+ protected function accessManager() {
if (!isset($this->accessManager)) {
$this->accessManager = \Drupal::service('access_manager');
}
diff --git a/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php b/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php
index 77e63e1..d9abc4d 100644
--- a/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php
+++ b/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php
@@ -15,6 +15,7 @@
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Component\Utility\Xss;
+use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -111,26 +112,26 @@ public function blockForm($form, FormStateInterface $form_state) {
$theme = $form_state['block_theme'];
// Get permissions.
- $administer_themes_access = $this->currentUser->hasPermission('administer themes');
- $administer_site_configuration_access = $this->currentUser->hasPermission('administer site configuration');
-
- if ($administer_themes_access) {
- // Get paths to theme settings pages.
- $appearance_settings_url = $this->urlGenerator->generateFromRoute('system.theme_settings');
- $theme_settings_url = $this->urlGenerator->generateFromRoute('system.theme_settings_theme', array('theme' => $theme));
+ $url_system_theme_settings = new Url('system.theme_settings');
+ $url_system_theme_settings_theme = new Url('system.theme_settings_theme', array('theme' => $theme));
+ if ($url_system_theme_settings->access() && $url_system_theme_settings_theme->access()) {
// Provide links to the Appearance Settings and Theme Settings pages
// if the user has access to administer themes.
- $site_logo_description = $this->t('Defined on the Appearance Settings or Theme Settings page.', array('@appearance' => $appearance_settings_url, '@theme' => $theme_settings_url));
+ $site_logo_description = $this->t('Defined on the Appearance Settings or Theme Settings page.', array(
+ '@appearance' => $url_system_theme_settings->toString(),
+ '@theme' => $url_system_theme_settings_theme->toString(),
+ ));
}
else {
// Explain that the user does not have access to the Appearance and Theme
// Settings pages.
$site_logo_description = $this->t('Defined on the Appearance or Theme Settings page. You do not have the appropriate permissions to change the site logo.');
}
- if ($administer_site_configuration_access) {
+ $url_system_site_information_settings = new Url('system.site_information_settings');
+ if ($url_system_site_information_settings->access()) {
// Get paths to settings pages.
- $site_information_url = $this->urlGenerator->generateFromRoute('system.site_information_settings');
+ $site_information_url = $url_system_site_information_settings->toString();
// Provide link to Site Information page if the user has access to
// administer site configuration.