Skip to content
......@@ -301,9 +301,9 @@ public function getAdminPath($entity_type, $bundle) {
$admin_path = '';
$entity_info = $this->getDefinition($entity_type);
// Check for an entity type's admin base path.
if (isset($entity_info['route_base_path'])) {
// Replace any dynamic 'bundle' portion of the path with the actual bundle.
$admin_path = str_replace('{bundle}', $bundle, $entity_info['route_base_path']);
if (isset($entity_info['links']['admin-form'])) {
$route_parameters[$entity_info['bundle_entity_type']] = $bundle;
$admin_path = \Drupal::urlGenerator()->getPathFromRoute($entity_info['links']['admin-form'], $route_parameters);
}
return $admin_path;
......@@ -313,10 +313,11 @@ public function getAdminPath($entity_type, $bundle) {
* {@inheritdoc}
*/
public function getAdminRouteInfo($entity_type, $bundle) {
$entity_info = $this->getDefinition($entity_type);
return array(
'route_name' => "field_ui.overview_$entity_type",
'route_parameters' => array(
'bundle' => $bundle,
$entity_info['bundle_entity_type'] => $bundle,
)
);
}
......
......@@ -164,6 +164,11 @@ public function getViewBuilder($entity_type);
*
* @return string
* The administration path for an entity type bundle, if it exists.
*
* @deprecated since version 8.0
* System paths should not be used - use route names and parameters.
*
* @see self::getAdminRouteInfo()
*/
public function getAdminPath($entity_type, $bundle);
......
<?php
/**
* @file
* Contains \Drupal\Core\EventSubscriber\AjaxResponseSubscriber.
*/
namespace Drupal\Core\EventSubscriber;
use Drupal\Core\Ajax\AjaxResponse;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
class AjaxResponseSubscriber implements EventSubscriberInterface {
/**
* Renders the ajax commands right before preparing the result.
*
* @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
* The response event, which contains the possible AjaxResponse object.
*/
public function onResponse(FilterResponseEvent $event) {
$response = $event->getResponse();
if ($response instanceof AjaxResponse) {
$response->prepareResponse($event->getRequest());
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[KernelEvents::RESPONSE][] = array('onResponse', -100);
return $events;
}
}
......@@ -23,7 +23,6 @@ class SpecialAttributesRouteSubscriber extends RouteSubscriberBase {
*/
protected function alterRoutes(RouteCollection $collection, $module) {
$special_variables = array(
'_account',
'system_path',
'_maintenance',
'_legacy',
......
......@@ -178,7 +178,7 @@ public function setRequest(Request $request) {
* The current user.
*/
protected function currentUser() {
return $this->getRequest()->attributes->get('_account');
return \Drupal::currentUser();
}
/**
......
......@@ -478,21 +478,6 @@ public function retrieveForm($form_id, &$form_state) {
// Record the $form_id.
$form_state['build_info']['form_id'] = $form_id;
// Record the filepath of the include file containing the original form, so
// the form builder callbacks can be loaded when the form is being rebuilt
// from cache on a different path (such as 'system/ajax'). See
// self::getCache(). Don't do this in maintenance mode as Drupal may not be
// fully bootstrapped (i.e. during installation) in which case
// menu_get_item() is not available.
if (!isset($form_state['build_info']['files']['menu']) && !defined('MAINTENANCE_MODE')) {
$item = $this->menuGetItem();
if (!empty($item['include_file'])) {
// Do not use form_load_include() here, as the file is already loaded.
// Anyway, self::getCache() is able to handle filepaths too.
$form_state['build_info']['files']['menu'] = $item['include_file'];
}
}
// We save two copies of the incoming arguments: one for modules to use
// when mapping form ids to constructor functions, and another to pass to
// the constructor function itself.
......@@ -1701,15 +1686,6 @@ protected function drupalInstallationAttempted() {
return drupal_installation_attempted();
}
/**
* Wraps menu_get_item().
*
* @return array|bool
*/
protected function menuGetItem() {
return menu_get_item();
}
/**
* Wraps watchdog().
*/
......
......@@ -55,8 +55,6 @@ public function enhance(array $defaults, Request $request) {
$anonymous_user = drupal_anonymous_user();
$this->container->set('current_user', $anonymous_user, 'request');
// @todo Remove this in https://drupal.org/node/2073531
$request->attributes->set('_account', $anonymous_user);
// The global $user object is included for backward compatibility only
// and should be considered deprecated.
......
This diff is collapsed.
......@@ -84,6 +84,13 @@ public function setRequest(Request $request) {
);
}
/**
* {@inheritdoc}
*/
public function getActive() {
return $this->active;
}
/**
* {@inheritdoc}
*/
......
......@@ -71,4 +71,16 @@ interface LinkGeneratorInterface {
*/
public function generate($text, $route_name, array $parameters = array(), array $options = array());
/**
* Returns information for the currently active route.
*
* @return array
* An array of active route information, containing the following keys:
* - route_name: The currently active route_name
* - language: The current language
* - parameters: An array of request parameters and any query string
* parameters.
*/
public function getActive();
}
......@@ -8,16 +8,19 @@
namespace Drupal\Core\Utility;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\CacheCollector;
use Drupal\Core\DestructableInterface;
use Drupal\Core\Lock\LockBackendInterface;
/**
* Builds the run-time theme registry.
*
* Extends CacheArray to allow the theme registry to be accessed as a
* A cache collector to allow the theme registry to be accessed as a
* complete registry, while internally caching only the parts of the registry
* that are actually in use on the site. On cache misses the complete
* theme registry is loaded and used to update the run-time cache.
*/
class ThemeRegistry extends CacheArray {
class ThemeRegistry extends CacheCollector implements DestructableInterface {
/**
* Whether the partial registry can be persisted to the cache.
......@@ -38,35 +41,42 @@ class ThemeRegistry extends CacheArray {
*
* @param string $cid
* The cid for the array being cached.
* @param string $bin
* The bin to cache the array.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The cache backend.
* @param \Drupal\Core\Lock\LockBackendInterface $lock
* The lock backend.
* @param array $tags
* (optional) The tags to specify for the cache item.
* @param bool $modules_loaded
* Whether all modules have already been loaded.
*/
function __construct($cid, $bin, $tags, $modules_loaded = FALSE) {
function __construct($cid, CacheBackendInterface $cache, LockBackendInterface $lock, $tags = array(), $modules_loaded = FALSE) {
$this->cid = $cid;
$this->bin = $bin;
$this->cache = $cache;
$this->lock = $lock;
$this->tags = $tags;
$request = \Drupal::request();
$this->persistable = $modules_loaded && $request->isMethod('GET');
if ($this->persistable && $cached = cache($this->bin)->get($this->cid)) {
$data = $cached->data;
// @todo: Implement lazyload.
$this->cacheLoaded = TRUE;
if ($this->persistable && $cached = $this->cache->get($this->cid)) {
$this->storage = $cached->data;
}
else {
// If there is no runtime cache stored, fetch the full theme registry,
// but then initialize each value to NULL. This allows offsetExists()
// to function correctly on non-registered theme hooks without triggering
// a call to resolveCacheMiss().
$data = $this->initializeRegistry();
if ($this->persistable) {
$this->set($data);
$this->storage = $this->initializeRegistry();
foreach (array_keys($this->storage) as $key) {
$this->persist($key);
}
// RegistryTest::testRaceCondition() ensures that the cache entry is
// written on the initial construction of the theme registry.
$this->updateCache();
}
$this->storage = $data;
}
/**
......@@ -77,58 +87,73 @@ function __construct($cid, $bin, $tags, $modules_loaded = FALSE) {
* initialized to NULL.
*/
function initializeRegistry() {
$this->completeRegistry = theme_get_registry();
// @todo DIC this.
$this->completeRegistry = \Drupal::service('theme.registry')->get();
return array_fill_keys(array_keys($this->completeRegistry), NULL);
}
/**
* Overrides CacheArray::offsetExists().
* {@inheritdoc}
*/
public function offsetExists($offset) {
public function has($key) {
// Since the theme registry allows for theme hooks to be requested that
// are not registered, just check the existence of the key in the registry.
// Use array_key_exists() here since a NULL value indicates that the theme
// hook exists but has not yet been requested.
return array_key_exists($offset, $this->storage);
return array_key_exists($key, $this->storage);
}
/**
* Overrides CacheArray::offsetGet().
* {@inheritdoc}
*/
public function offsetGet($offset) {
public function get($key) {
// If the offset is set but empty, it is a registered theme hook that has
// not yet been requested. Offsets that do not exist at all were not
// registered in hook_theme().
if (isset($this->storage[$offset])) {
return $this->storage[$offset];
if (isset($this->storage[$key])) {
return $this->storage[$key];
}
elseif (array_key_exists($offset, $this->storage)) {
return $this->resolveCacheMiss($offset);
elseif (array_key_exists($key, $this->storage)) {
return $this->resolveCacheMiss($key);
}
}
/**
* Implements CacheArray::resolveCacheMiss().
* {@inheritdoc}
*/
public function resolveCacheMiss($offset) {
public function resolveCacheMiss($key) {
if (!isset($this->completeRegistry)) {
$this->completeRegistry = theme_get_registry();
$this->completeRegistry = \Drupal::service('theme.registry')->get();
}
$this->storage[$offset] = $this->completeRegistry[$offset];
$this->storage[$key] = $this->completeRegistry[$key];
if ($this->persistable) {
$this->persist($offset);
$this->persist($key);
}
return $this->storage[$offset];
return $this->storage[$key];
}
/**
* Overrides CacheArray::set().
* {@inheritdoc}
*/
public function set($data, $lock = TRUE) {
$lock_name = $this->cid . ':' . $this->bin;
if (!$lock || lock()->acquire($lock_name)) {
if ($cached = cache($this->bin)->get($this->cid)) {
protected function updateCache($lock = TRUE) {
if (!$this->persistable) {
return;
}
// @todo: Is the custom implementation necessary?
$data = array();
foreach ($this->keysToPersist as $offset => $persist) {
if ($persist) {
$data[$offset] = $this->storage[$offset];
}
}
if (empty($data)) {
return;
}
$lock_name = $this->cid . ':' . __CLASS__;
if (!$lock || $this->lock->acquire($lock_name)) {
if ($cached = $this->cache->get($this->cid)) {
// Use array merge instead of union so that filled in values in $data
// overwrite empty values in the current cache.
$data = array_merge($cached->data, $data);
......@@ -137,10 +162,11 @@ public function set($data, $lock = TRUE) {
$registry = $this->initializeRegistry();
$data = array_merge($registry, $data);
}
cache($this->bin)->set($this->cid, $data, CacheBackendInterface::CACHE_PERMANENT, $this->tags);
$this->cache->set($this->cid, $data, CacheBackendInterface::CACHE_PERMANENT, $this->tags);
if ($lock) {
lock()->release($lock_name);
$this->lock->release($lock_name);
}
}
}
}
......@@ -517,7 +517,11 @@ $(document).bind('state:disabled', function(e) {
$(document).bind('state:required', function(e) {
if (e.trigger) {
if (e.value) {
$(e.target).attr({ 'required': 'required', 'aria-required': 'aria-required' }).closest('.form-item, .form-wrapper').find('label').append(Drupal.theme('requiredMarker'));
var $label = $(e.target).attr({ 'required': 'required', 'aria-required': 'aria-required' }).closest('.form-item, .form-wrapper').find('label');
// Avoids duplicate required markers on initialization.
if (!$label.find('.form-required').length) {
$label.append(Drupal.theme('requiredMarker'));
}
}
else {
$(e.target).removeAttr('required aria-required').closest('.form-item, .form-wrapper').find('label .form-required').remove();
......
......@@ -64,5 +64,5 @@ function action_entity_info(&$entity_info) {
$entity_info['action']['controllers']['form']['edit'] = 'Drupal\action\ActionEditFormController';
$entity_info['action']['controllers']['form']['delete'] = 'Drupal\action\Form\ActionDeleteForm';
$entity_info['action']['controllers']['list'] = 'Drupal\action\ActionListController';
$entity_info['action']['links']['edit-form'] = 'admin/config/system/actions/configure/{action}';
$entity_info['action']['links']['edit-form'] = 'action.admin_configure';
}
......@@ -2,9 +2,7 @@
/**
* @file
* Provides views data and handlers for action.module.
*
* @ingroup views_module_handlers
* Provides views data for action.module.
*/
/**
......
views.field.bulk_form:
type: views_field
label: 'Bulk form'
mapping:
action_title:
type: label
label: 'Action title'
......@@ -113,6 +113,21 @@ public function testBulkForm() {
$this->drupalGet('test_bulk_form');
$this->assertNoOption('edit-action', 'node_make_sticky_action');
$this->assertNoOption('edit-action', 'node_make_unsticky_action');
// Check the default title.
$this->drupalGet('test_bulk_form');
$result = $this->xpath('//label[@for="edit-action"]');
$this->assertEqual('With selection', (string) $result[0]);
// Setup up a different bulk form title.
$view = views_get_view('test_bulk_form');
$display = &$view->storage->getDisplay('default');
$display['display_options']['fields']['action_bulk_form']['action_title'] = 'Test title';
$view->save();
$this->drupalGet('test_bulk_form');
$result = $this->xpath('//label[@for="edit-action"]');
$this->assertEqual('Test title', (string) $result[0]);
}
}
......@@ -3,8 +3,6 @@
/**
* @file
* Provides views data for aggregator.module.
*
* @ingroup views_module_handlers
*/
/**
......
......@@ -186,19 +186,23 @@ public function adminOverview() {
$links = array();
$links['edit'] = array(
'title' => $this->t('Edit'),
'href' => "admin/config/services/aggregator/edit/feed/$feed->fid",
'route_name' => 'aggregator.feed_edit',
'route_parameters' => array('aggregator_feed' => $feed->fid),
);
$links['delete'] = array(
'title' => $this->t('Delete'),
'href' => "admin/config/services/aggregator/delete/feed/$feed->fid",
'route_name' => 'aggregator.feed_delete',
'route_parameters' => array('aggregator_feed' => $feed->fid),
);
$links['remove'] = array(
'title' => $this->t('Remove items'),
'href' => "admin/config/services/aggregator/remove/$feed->fid",
'route_name' => 'aggregator.feed_items_delete',
'route_parameters' => array('aggregator_feed' => $feed->fid),
);
$links['update'] = array(
'title' => $this->t('Update items'),
'href' => "admin/config/services/aggregator/update/$feed->fid",
'route_name' => 'aggregator.feed_refresh',
'route_parameters' => array('aggregator_feed' => $feed->fid),
'query' => array('token' => drupal_get_token("aggregator/update/$feed->fid")),
);
$row[] = array(
......@@ -228,11 +232,13 @@ public function adminOverview() {
$links = array();
$links['edit'] = array(
'title' => $this->t('Edit'),
'href' => "admin/config/services/aggregator/edit/category/$category->cid",
'route_name' => 'aggregator.category_admin_edit',
'route_parameters' => array('cid' => $category->cid),
);
$links['delete'] = array(
'title' => $this->t('Delete'),
'href' => "admin/config/services/aggregator/delete/category/$category->cid",
'route_name' => 'aggregator.category_delete',
'route_parameters' => array('cid' => $category->cid),
);
$row[] = array(
'data' => array(
......
......@@ -63,7 +63,8 @@ public function buildForm(array $form, array &$form_state, $default_ip = '') {
$links = array();
$links['delete'] = array(
'title' => $this->t('delete'),
'href' => "admin/config/people/ban/delete/$ip->iid",
'route_name' => 'ban.delete',
'route_parameters' => array('ban_id' => $ip->iid),
);
$row[] = array(
'data' => array(
......
......@@ -36,10 +36,10 @@
* admin_permission = "administer blocks",
* base_table = "custom_block",
* revision_table = "custom_block_revision",
* route_base_path = "admin/structure/block/custom-blocks/manage/{bundle}",
* links = {
* "canonical" = "/block/{custom_block}",
* "edit-form" = "/block/{custom_block}"
* "canonical" = "custom_block.edit",
* "edit-form" = "custom_block.edit",
* "admin-form" = "custom_block.type_edit"
* },
* fieldable = TRUE,
* translatable = TRUE,
......@@ -52,7 +52,8 @@
* },
* bundle_keys = {
* "bundle" = "type"
* }
* },
* bundle_entity_type = "custom_block_type"
* )
*/
class CustomBlock extends ContentEntityBase implements CustomBlockInterface {
......